824 lines
24 KiB
C
824 lines
24 KiB
C
|
/* -*- Mode: C; tab-width: 4 -*- */
|
||
|
/* toneclock --- Screenhack inspired by Peter Schat's toneclock
|
||
|
*/
|
||
|
|
||
|
#if !defined( lint ) && !defined( SABER )
|
||
|
static const char sccsid[] = "@(#)toneclock.c 5.00 2004/09/16 xlockmore";
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/*-
|
||
|
* Copyright (c) 2004 by Jouk Jansen <joukj@hrem.stm.tudelft.nl>
|
||
|
*
|
||
|
* Permission to use, copy, modify, and distribute this software and its
|
||
|
* documentation for any purpose and without fee is hereby granted,
|
||
|
* provided that the above copyright notice appear in all copies and that
|
||
|
* both that copyright notice and this permission notice appear in
|
||
|
* supporting documentation.
|
||
|
*
|
||
|
* This file is provided AS IS with no warranties of any kind. The author
|
||
|
* shall have no liability with respect to the infringement of copyrights,
|
||
|
* trade secrets or any patents by this file or any part thereof. In no
|
||
|
* event will the author be liable for any lost revenue or profits or
|
||
|
* other special, indirect and consequential damages.
|
||
|
*
|
||
|
* The author should like to be notified if changes have been made to the
|
||
|
* routine. Response will only be guaranteed when a VMS version of the
|
||
|
* program is available.
|
||
|
*
|
||
|
* Toneclock. Peter Schat (1937-2003) was a Dutch composer. Het invented
|
||
|
* the toneclock, a garphical representation of the tonesystem.
|
||
|
*
|
||
|
* Revision History:
|
||
|
* 20-Dec-2004: Initial release
|
||
|
* 23-Dec-2004: -size determines size of the clock
|
||
|
* -original ignores all options and displays original clock
|
||
|
* -pulsate make the clock pulsating
|
||
|
* 24-Dec-2004: -fill num
|
||
|
* polygon filling chance implemented
|
||
|
* 04-Jan-2005: -move allow moving for small clocks
|
||
|
* 16-Feb-2005: -Number of hours according to "count" option
|
||
|
* -Random polygons
|
||
|
*
|
||
|
*/
|
||
|
#if 0
|
||
|
#define NO_DBUF
|
||
|
#endif
|
||
|
#ifdef STANDALONE
|
||
|
#define MODE_toneclock
|
||
|
#define PROGCLASS "toneclock"
|
||
|
#define HACK_INIT init_toneclock
|
||
|
#define HACK_DRAW draw_toneclock
|
||
|
#define toneclock_opts xlockmore_opts
|
||
|
#define DEFAULTS "*delay: 60000 \n" \
|
||
|
"*count: -20 \n" \
|
||
|
"*cycles: 200 \n" \
|
||
|
"*size: -1000 \n" \
|
||
|
"*ncolors: 64 \n" \
|
||
|
"*fullrandom: True \n" \
|
||
|
"*verbose: False \n"
|
||
|
#include "xlockmore.h" /* in xscreensaver distribution */
|
||
|
#else /* STANDALONE */
|
||
|
#include "xlock.h" /* in xlockmore distribution */
|
||
|
#include "color.h"
|
||
|
#endif /* STANDALONE */
|
||
|
|
||
|
#ifdef MODE_toneclock
|
||
|
|
||
|
#define DEF_NUM_hour 12
|
||
|
|
||
|
#define DEF_CYCLE "True"
|
||
|
#define DEF_ORIGINAL "False"
|
||
|
#define DEF_PULSATING "False"
|
||
|
#define DEF_MOVE "True"
|
||
|
#define DEF_FILL "0"
|
||
|
|
||
|
static Bool cycle_p , original , pulsating , move_clock;
|
||
|
static int fill;
|
||
|
|
||
|
static XrmOptionDescRec opts[] =
|
||
|
{
|
||
|
{(char *) "-fill", (char *) "tomecloc.fill", XrmoptionSepArg, (caddr_t) NULL},
|
||
|
{(char *) "-cycle", (char *) ".toneclock.cycle", XrmoptionNoArg, (caddr_t) "on"},
|
||
|
{(char *) "+cycle", (char *) ".toneclock.cycle", XrmoptionNoArg, (caddr_t) "off"},
|
||
|
{(char *) "-original", (char *) ".toneclock.original", XrmoptionNoArg, (caddr_t) "on"},
|
||
|
{(char *) "+original", (char *) ".toneclock.original", XrmoptionNoArg, (caddr_t) "off"},
|
||
|
{(char *) "-move", (char *) ".toneclock.move", XrmoptionNoArg, (caddr_t) "on"},
|
||
|
{(char *) "+move", (char *) ".toneclock.move", XrmoptionNoArg, (caddr_t) "off"},
|
||
|
{(char *) "-pulsating", (char *) ".toneclock.pulsating", XrmoptionNoArg, (caddr_t) "on"},
|
||
|
{(char *) "+pulsating", (char *) ".toneclock.pulsating", XrmoptionNoArg, (caddr_t) "off"}
|
||
|
};
|
||
|
|
||
|
static argtype vars[] =
|
||
|
{
|
||
|
{(void *) & fill, (char *) "fill", (char *) "Fill", (char *) DEF_FILL, t_Int},
|
||
|
{(void *) & cycle_p, (char *) "cycle", (char *) "Cycle", (char *) DEF_CYCLE, t_Bool},
|
||
|
{(void *) & original, (char *) "original", (char *) "Original", (char *) DEF_ORIGINAL, t_Bool},
|
||
|
{(void *) & move_clock, (char *) "move", (char *) "Move", (char *) DEF_MOVE, t_Bool},
|
||
|
{(void *) & pulsating, (char *) "pulsating", (char *) "Pulsating", (char *) DEF_PULSATING, t_Bool}
|
||
|
};
|
||
|
static OptionStruct desc[] =
|
||
|
{
|
||
|
{(char *) "-fill num", (char *) "polygon filling chance in %"},
|
||
|
{(char *) "-/+cycle", (char *) "turn on/off colour cycling"},
|
||
|
{(char *) "-/+original", (char *) "turn on/off displaying original clock only"},
|
||
|
{(char *) "-/+move", (char *) "turn on/off moving small clocks"},
|
||
|
{(char *) "-/+pulsating", (char *) "turn on/off pulsating clock"}
|
||
|
};
|
||
|
|
||
|
ModeSpecOpt toneclock_opts =
|
||
|
{sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
|
||
|
|
||
|
#ifdef USE_MODULES
|
||
|
ModStruct toneclock_description =
|
||
|
{"toneclock", "init_toneclock", "draw_toneclock", "release_toneclock",
|
||
|
"refresh_toneclock", "init_toneclock", (char *) NULL, &toneclock_opts,
|
||
|
60000, -20, 200, -1000, 64, 1.0, "",
|
||
|
"Shows Peter Schat's toneclock", 0, NULL};
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#define PI_RAD (M_PI / 180.0)
|
||
|
|
||
|
typedef struct {
|
||
|
unsigned long colour;
|
||
|
float angle, velocity , radius;
|
||
|
int num_point , num_point1;
|
||
|
int* point_numbers;
|
||
|
Bool draw;
|
||
|
} toneclockhour;
|
||
|
|
||
|
typedef struct {
|
||
|
ModeInfo *mi;
|
||
|
Pixmap dbuf;
|
||
|
GC dbuf_gc;
|
||
|
GC gc;
|
||
|
Colormap cmap;
|
||
|
XColor *colors;
|
||
|
Bool painted;
|
||
|
int win_width, win_height, num_hour, x0, y0 , fill;
|
||
|
float angle , velocity , radius , phase , ph_vel;
|
||
|
float vx , vy , anglex , angley , max_radius;
|
||
|
int a_x , a_y;
|
||
|
int ncolors;
|
||
|
Bool cycle_p, mono_p, no_colors, original, pulsating , moving;
|
||
|
Bool randomhour;
|
||
|
unsigned long blackpixel, whitepixel, fg, bg;
|
||
|
int direction;
|
||
|
int hexadecimal_clock[512];
|
||
|
toneclockhour *hour;
|
||
|
|
||
|
} toneclockstruct;
|
||
|
|
||
|
static int original_clock[12][16] = {
|
||
|
{ 1 , 1 , 5 , 9 , 2 , 2 , 6 , 10 , 3 , 3 , 7 , 11 , 4 , 4 , 8 , 12 } ,
|
||
|
{ 1 , 1 , 2 , 3 , 4 , 4 , 5 , 6 , 7 , 7 , 8 , 9 , 10 , 10 , 11 , 12 } ,
|
||
|
{ 1 , 1 , 2 , 4 , 3 , 3 , 5 , 6 , 7 , 7 , 8 , 10 , 9 , 9 , 11 , 12 } ,
|
||
|
{ 1 , 1 , 2 , 5 , 3 , 3 , 4 , 7 , 6 , 6 , 9 , 10 , 8 , 8 , 11 , 12 } ,
|
||
|
{ 1 , 1 , 2 , 6 , 3 , 3 , 4 , 8 , 5 , 5 , 9 , 10 , 7 , 7 , 11 , 12 } ,
|
||
|
{ 1 , 1 , 2 , 7 , 3 , 3 , 8 , 9 , 4 , 4 , 5 , 10 , 6 , 6 , 11 , 12 } ,
|
||
|
{ 1 , 1 , 3 , 5 , 2 , 2 , 10 , 12 , 4 , 4 , 6 , 8 , 7 , 7 , 9 , 11 } ,
|
||
|
{ 1 , 1 , 3 , 6 , 2 , 2 , 4 , 11 , 5 , 5 , 8 , 10 , 7 , 7 , 9 , 12 } ,
|
||
|
{ 1 , 1 , 3 , 7 , 2 , 2 , 4 , 8 , 5 , 5 , 10 , 11 , 6 , 6 , 10 , 12 } ,
|
||
|
{ 1 , 1 , 3 , 8 , 2 , 2 , 7 , 9 , 4 , 4 , 6 , 11 , 5 , 5 , 10 , 12 } ,
|
||
|
{ 1 , 4 , 7 , 10 , 2 , 5 , 8 , 11 , 3 , 6 , 9 , 12 , 1 , 1 , 1 , 1 } ,
|
||
|
{ 1 , 1 , 4 , 8 , 2 , 2 , 7 , 11 , 3 , 3 , 6 , 10 , 5 , 5 , 9 , 12 }
|
||
|
};
|
||
|
|
||
|
static toneclockstruct *toneclocks = (toneclockstruct *) NULL;
|
||
|
|
||
|
static void
|
||
|
toneclock_drawhour(ModeInfo * mi, toneclockhour * hour0 ,
|
||
|
int x0 , int y0 )
|
||
|
{
|
||
|
Display *display = MI_DISPLAY(mi);
|
||
|
toneclockstruct *tclock;
|
||
|
int i;
|
||
|
#ifdef NO_DBUF
|
||
|
Window drawable = MI_WINDOW(mi);
|
||
|
#else
|
||
|
#define drawable (Drawable) tclock->dbuf
|
||
|
#endif
|
||
|
tclock = &toneclocks[MI_SCREEN(mi)];
|
||
|
|
||
|
for (i = 0; i < hour0->num_point1; i = i + 4)
|
||
|
{
|
||
|
int x , y , x1 , y1 , x2 , y2 , x3 , y3;
|
||
|
|
||
|
x = (int) (hour0->radius * sin( hour0->angle + PI_RAD *
|
||
|
hour0->point_numbers[ i ] * 360.0 /
|
||
|
hour0->num_point ) ) + x0;
|
||
|
y = (int) (hour0->radius * cos( hour0->angle + PI_RAD *
|
||
|
hour0->point_numbers[ i ] * 360.0 /
|
||
|
hour0->num_point ) ) + y0;
|
||
|
x1 = (int) (hour0->radius * sin( hour0->angle + PI_RAD *
|
||
|
hour0->point_numbers[ i + 1 ] * 360.0 /
|
||
|
hour0->num_point ) ) + x0;
|
||
|
y1 = (int) (hour0->radius * cos( hour0->angle + PI_RAD *
|
||
|
hour0->point_numbers[ i + 1 ] * 360.0 /
|
||
|
hour0->num_point ) ) + y0;
|
||
|
x2 = (int) (hour0->radius * sin( hour0->angle + PI_RAD *
|
||
|
hour0->point_numbers[ i + 2 ] * 360.0 /
|
||
|
hour0->num_point ) ) + x0;
|
||
|
y2 = (int) (hour0->radius * cos( hour0->angle + PI_RAD *
|
||
|
hour0->point_numbers[ i + 2 ] * 360.0 /
|
||
|
hour0->num_point ) ) + y0;
|
||
|
x3 = (int) (hour0->radius * sin( hour0->angle + PI_RAD *
|
||
|
hour0->point_numbers[ i + 3 ] * 360.0 /
|
||
|
hour0->num_point ) ) + x0;
|
||
|
y3 = (int) (hour0->radius * cos( hour0->angle + PI_RAD *
|
||
|
hour0->point_numbers[ i + 3 ] * 360.0 /
|
||
|
hour0->num_point ) ) + y0;
|
||
|
if ( hour0->draw )
|
||
|
{
|
||
|
XDrawLine(display, drawable, tclock->gc, x , y , x1 , y1 );
|
||
|
XDrawLine(display, drawable, tclock->gc, x1 , y1 , x2 , y2 );
|
||
|
XDrawLine(display, drawable, tclock->gc, x2 , y2 , x3 , y3 );
|
||
|
XDrawLine(display, drawable, tclock->gc, x , y , x3 , y3 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
XPoint xy[4];
|
||
|
|
||
|
xy[0].x = x;
|
||
|
xy[0].y = y;
|
||
|
xy[1].x = x1;
|
||
|
xy[1].y = y1;
|
||
|
xy[2].x = x2;
|
||
|
xy[2].y = y2;
|
||
|
xy[3].x = x3;
|
||
|
xy[3].y = y3;
|
||
|
XFillPolygon(display, drawable, tclock->gc, xy, 4 , Convex,
|
||
|
CoordModeOrigin);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
free_hour(toneclockstruct *tclock)
|
||
|
{
|
||
|
if (tclock->hour != NULL) {
|
||
|
free(tclock->hour);
|
||
|
tclock->hour = (toneclockhour *) NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
free_toneclock(Display *display, toneclockstruct *tclock)
|
||
|
{
|
||
|
ModeInfo *mi = tclock->mi;
|
||
|
|
||
|
if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
|
||
|
MI_WHITE_PIXEL(mi) = tclock->whitepixel;
|
||
|
MI_BLACK_PIXEL(mi) = tclock->blackpixel;
|
||
|
#ifndef STANDALONE
|
||
|
MI_FG_PIXEL(mi) = tclock->fg;
|
||
|
MI_BG_PIXEL(mi) = tclock->bg;
|
||
|
#endif
|
||
|
if (tclock->colors != NULL) {
|
||
|
if (tclock->ncolors && !tclock->no_colors)
|
||
|
free_colors(display, tclock->cmap, tclock->colors, tclock->ncolors);
|
||
|
free(tclock->colors);
|
||
|
tclock->colors = (XColor *) NULL;
|
||
|
}
|
||
|
if (tclock->cmap != None) {
|
||
|
XFreeColormap(display, tclock->cmap);
|
||
|
tclock->cmap = None;
|
||
|
}
|
||
|
}
|
||
|
if (tclock->gc != None) {
|
||
|
XFreeGC(display, tclock->gc);
|
||
|
tclock->gc = None;
|
||
|
}
|
||
|
free_hour(tclock);
|
||
|
#ifndef NO_DBUF
|
||
|
if (tclock->dbuf != None) {
|
||
|
XFreePixmap(display, tclock->dbuf);
|
||
|
tclock->dbuf = None;
|
||
|
}
|
||
|
if (tclock->dbuf_gc != None) {
|
||
|
XFreeGC(display, tclock->dbuf_gc);
|
||
|
tclock->dbuf_gc = None;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#ifndef STANDALONE
|
||
|
extern char *background;
|
||
|
extern char *foreground;
|
||
|
#endif
|
||
|
|
||
|
void
|
||
|
init_toneclock(ModeInfo * mi)
|
||
|
{
|
||
|
Display *display = MI_DISPLAY(mi);
|
||
|
Window window = MI_WINDOW(mi);
|
||
|
int i, size_hour, istart;
|
||
|
toneclockstruct *tclock;
|
||
|
|
||
|
/* initialize */
|
||
|
if (toneclocks == NULL) {
|
||
|
if ((toneclocks = (toneclockstruct *) calloc(MI_NUM_SCREENS(mi),
|
||
|
sizeof (toneclockstruct))) == NULL)
|
||
|
return;
|
||
|
}
|
||
|
tclock = &toneclocks[MI_SCREEN(mi)];
|
||
|
tclock->mi = mi;
|
||
|
|
||
|
if (tclock->gc == None) {
|
||
|
if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
|
||
|
XColor color;
|
||
|
|
||
|
#ifndef STANDALONE
|
||
|
tclock->fg = MI_FG_PIXEL(mi);
|
||
|
tclock->bg = MI_BG_PIXEL(mi);
|
||
|
#endif
|
||
|
tclock->blackpixel = MI_BLACK_PIXEL(mi);
|
||
|
tclock->whitepixel = MI_WHITE_PIXEL(mi);
|
||
|
if ((tclock->cmap = XCreateColormap(display, window,
|
||
|
MI_VISUAL(mi), AllocNone)) == None) {
|
||
|
free_toneclock(display, tclock);
|
||
|
return;
|
||
|
}
|
||
|
XSetWindowColormap(display, window, tclock->cmap);
|
||
|
(void) XParseColor(display, tclock->cmap, "black", &color);
|
||
|
(void) XAllocColor(display, tclock->cmap, &color);
|
||
|
MI_BLACK_PIXEL(mi) = color.pixel;
|
||
|
(void) XParseColor(display, tclock->cmap, "white", &color);
|
||
|
(void) XAllocColor(display, tclock->cmap, &color);
|
||
|
MI_WHITE_PIXEL(mi) = color.pixel;
|
||
|
#ifndef STANDALONE
|
||
|
(void) XParseColor(display, tclock->cmap, background, &color);
|
||
|
(void) XAllocColor(display, tclock->cmap, &color);
|
||
|
MI_BG_PIXEL(mi) = color.pixel;
|
||
|
(void) XParseColor(display, tclock->cmap, foreground, &color);
|
||
|
(void) XAllocColor(display, tclock->cmap, &color);
|
||
|
MI_FG_PIXEL(mi) = color.pixel;
|
||
|
#endif
|
||
|
tclock->colors = (XColor *) NULL;
|
||
|
tclock->ncolors = 0;
|
||
|
}
|
||
|
if ((tclock->gc = XCreateGC(display, MI_WINDOW(mi),
|
||
|
(unsigned long) 0, (XGCValues *) NULL)) == None) {
|
||
|
free_toneclock(display, tclock);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
/* Clear Display */
|
||
|
MI_CLEARWINDOW(mi);
|
||
|
tclock->painted = False;
|
||
|
XSetFunction(display, tclock->gc, GXxor);
|
||
|
|
||
|
|
||
|
/*Set up toneclock data */
|
||
|
if (MI_IS_FULLRANDOM(mi)) {
|
||
|
if (NRAND(10))
|
||
|
tclock->original = False;
|
||
|
else
|
||
|
tclock->original = True;
|
||
|
} else {
|
||
|
tclock->original = original;
|
||
|
}
|
||
|
tclock->direction = (LRAND() & 1) ? 1 : -1;
|
||
|
tclock->win_width = MI_WIDTH(mi);
|
||
|
tclock->win_height = MI_HEIGHT(mi);
|
||
|
if (tclock->hour != NULL)
|
||
|
free_hour(tclock);
|
||
|
if ( tclock->original )
|
||
|
{
|
||
|
tclock->num_hour = 12;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tclock->num_hour = MI_COUNT(mi);
|
||
|
}
|
||
|
tclock->x0 = tclock->win_width / 2;
|
||
|
tclock->y0 = tclock->win_height / 2;
|
||
|
if (tclock->num_hour == 0) {
|
||
|
tclock->num_hour = DEF_NUM_hour;
|
||
|
} else if (tclock->num_hour < 0) {
|
||
|
tclock->num_hour = NRAND(-tclock->num_hour) + 1;
|
||
|
}
|
||
|
if ( tclock->num_hour < 12 )
|
||
|
istart = NRAND( 12 - tclock->num_hour );
|
||
|
else
|
||
|
istart = 0;
|
||
|
if ((tclock->hour = (toneclockhour *) calloc(tclock->num_hour,
|
||
|
sizeof (toneclockhour))) == NULL) {
|
||
|
free_toneclock(display, tclock);
|
||
|
return;
|
||
|
}
|
||
|
if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
|
||
|
/* Set up colour map */
|
||
|
if (tclock->colors != NULL) {
|
||
|
if (tclock->ncolors && !tclock->no_colors)
|
||
|
free_colors(display, tclock->cmap, tclock->colors, tclock->ncolors);
|
||
|
free(tclock->colors);
|
||
|
tclock->colors = (XColor *) NULL;
|
||
|
}
|
||
|
tclock->ncolors = MI_NCOLORS(mi);
|
||
|
if (tclock->ncolors < 2)
|
||
|
tclock->ncolors = 2;
|
||
|
if (tclock->ncolors <= 2)
|
||
|
tclock->mono_p = True;
|
||
|
else
|
||
|
tclock->mono_p = False;
|
||
|
|
||
|
if (tclock->mono_p)
|
||
|
tclock->colors = (XColor *) NULL;
|
||
|
else
|
||
|
if ((tclock->colors = (XColor *) malloc(sizeof (*tclock->colors) *
|
||
|
(tclock->ncolors + 1))) == NULL) {
|
||
|
free_toneclock(display, tclock);
|
||
|
return;
|
||
|
}
|
||
|
tclock->cycle_p = has_writable_cells(mi);
|
||
|
if (tclock->cycle_p) {
|
||
|
if (MI_IS_FULLRANDOM(mi)) {
|
||
|
if (!NRAND(8))
|
||
|
tclock->cycle_p = False;
|
||
|
else
|
||
|
tclock->cycle_p = True;
|
||
|
} else {
|
||
|
tclock->cycle_p = cycle_p;
|
||
|
}
|
||
|
}
|
||
|
if (!tclock->mono_p) {
|
||
|
if (!(LRAND() % 10))
|
||
|
make_random_colormap(
|
||
|
#ifdef STANDALONE
|
||
|
MI_DISPLAY(mi), MI_WINDOW(mi),
|
||
|
#else
|
||
|
mi,
|
||
|
#endif
|
||
|
tclock->cmap, tclock->colors, &tclock->ncolors,
|
||
|
True, True, &tclock->cycle_p);
|
||
|
else if (!(LRAND() % 2))
|
||
|
make_uniform_colormap(
|
||
|
#ifdef STANDALONE
|
||
|
MI_DISPLAY(mi), MI_WINDOW(mi),
|
||
|
#else
|
||
|
mi,
|
||
|
#endif
|
||
|
tclock->cmap, tclock->colors, &tclock->ncolors,
|
||
|
True, &tclock->cycle_p);
|
||
|
else
|
||
|
make_smooth_colormap(
|
||
|
#ifdef STANDALONE
|
||
|
MI_DISPLAY(mi), MI_WINDOW(mi),
|
||
|
#else
|
||
|
mi,
|
||
|
#endif
|
||
|
tclock->cmap, tclock->colors, &tclock->ncolors,
|
||
|
True, &tclock->cycle_p);
|
||
|
}
|
||
|
XInstallColormap(display, tclock->cmap);
|
||
|
if (tclock->ncolors < 2) {
|
||
|
tclock->ncolors = 2;
|
||
|
tclock->no_colors = True;
|
||
|
} else
|
||
|
tclock->no_colors = False;
|
||
|
if (tclock->ncolors <= 2)
|
||
|
tclock->mono_p = True;
|
||
|
|
||
|
if (tclock->mono_p)
|
||
|
tclock->cycle_p = False;
|
||
|
|
||
|
}
|
||
|
#ifndef NO_DBUF
|
||
|
if (tclock->dbuf != None)
|
||
|
XFreePixmap(display, tclock->dbuf);
|
||
|
tclock->dbuf = XCreatePixmap(display, window,
|
||
|
tclock->win_width,
|
||
|
tclock->win_height,
|
||
|
MI_DEPTH(mi));
|
||
|
/* Allocation checked */
|
||
|
if (tclock->dbuf != None) {
|
||
|
XGCValues gcv;
|
||
|
|
||
|
gcv.foreground = 0;
|
||
|
gcv.background = 0;
|
||
|
gcv.graphics_exposures = False;
|
||
|
gcv.function = GXcopy;
|
||
|
|
||
|
if (tclock->dbuf_gc != None)
|
||
|
XFreeGC(display, tclock->dbuf_gc);
|
||
|
if ((tclock->dbuf_gc = XCreateGC(display, (Drawable) tclock->dbuf,
|
||
|
GCForeground | GCBackground | GCGraphicsExposures | GCFunction,
|
||
|
&gcv)) == None) {
|
||
|
XFreePixmap(display, tclock->dbuf);
|
||
|
tclock->dbuf = None;
|
||
|
} else {
|
||
|
XFillRectangle(display, (Drawable) tclock->dbuf, tclock->dbuf_gc,
|
||
|
0, 0, tclock->win_width, tclock->win_height);
|
||
|
XSetBackground(display, MI_GC(mi), MI_BLACK_PIXEL(mi));
|
||
|
XSetFunction(display, MI_GC(mi), GXcopy);
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
tclock->angle = NRAND(360) * PI_RAD;
|
||
|
tclock->velocity = (NRAND(7) - 3) * PI_RAD;
|
||
|
size_hour = MIN( tclock->win_width , tclock->win_height) / 3;
|
||
|
tclock->pulsating = False;
|
||
|
tclock->moving = False;
|
||
|
tclock->anglex = 0.0;
|
||
|
tclock->angley = 0.0;
|
||
|
tclock->fill = 0;
|
||
|
tclock->radius = size_hour;
|
||
|
tclock->max_radius =0.0;
|
||
|
if ( ( !tclock->original && NRAND( 15 ) == 3 ) || tclock->num_hour > 12 )
|
||
|
tclock->randomhour = True;
|
||
|
else
|
||
|
tclock->randomhour = False;
|
||
|
if ( !tclock->original && tclock->win_width > 20 )
|
||
|
{
|
||
|
if ( abs( MI_SIZE(mi) ) > size_hour ) {
|
||
|
if ( MI_SIZE( mi ) < 0 )
|
||
|
{
|
||
|
size_hour = -size_hour;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
size_hour = MI_SIZE(mi);
|
||
|
}
|
||
|
if ( size_hour < 0 )
|
||
|
{
|
||
|
tclock->radius = MIN(NRAND( size_hour - 10) + 10,
|
||
|
tclock->radius );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tclock->radius = MIN( size_hour , tclock->radius );
|
||
|
}
|
||
|
if ( MI_IS_FULLRANDOM( mi ) )
|
||
|
{
|
||
|
if ( NRAND(2) )
|
||
|
tclock->pulsating = True;
|
||
|
else
|
||
|
tclock->pulsating = False;
|
||
|
tclock->fill = NRAND( 101 );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tclock->pulsating = pulsating;
|
||
|
tclock->fill = fill;
|
||
|
}
|
||
|
}
|
||
|
tclock->phase = 0.0;
|
||
|
if ( tclock->pulsating )
|
||
|
tclock->ph_vel = (NRAND(7) - 3) * PI_RAD;
|
||
|
for (i = 0; i < tclock->num_hour; i++) {
|
||
|
toneclockhour *hour0;
|
||
|
|
||
|
hour0 = &tclock->hour[i];
|
||
|
if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
|
||
|
if (tclock->ncolors > 2)
|
||
|
hour0->colour = NRAND(tclock->ncolors - 2) + 2;
|
||
|
else
|
||
|
hour0->colour = 1; /* Just in case */
|
||
|
XSetForeground(display, tclock->gc, tclock->colors[hour0->colour].pixel);
|
||
|
} else {
|
||
|
if (MI_NPIXELS(mi) > 2)
|
||
|
hour0->colour = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)));
|
||
|
else
|
||
|
hour0->colour = 1; /*Xor'red so WHITE may not be appropriate */
|
||
|
XSetForeground(display, tclock->gc, hour0->colour);
|
||
|
}
|
||
|
hour0->angle = NRAND(360) * PI_RAD;
|
||
|
hour0->velocity = (NRAND(7) - 3) * PI_RAD;
|
||
|
hour0->radius = tclock->radius / 5.0;
|
||
|
tclock->max_radius = MAX( tclock->max_radius , hour0->radius );
|
||
|
hour0->num_point = 12;
|
||
|
hour0->num_point1 = 16;
|
||
|
if ( tclock->randomhour )
|
||
|
{
|
||
|
int j;
|
||
|
|
||
|
hour0->point_numbers = tclock->hexadecimal_clock + i *
|
||
|
hour0->num_point1;
|
||
|
if ( NRAND( 14 ) == 4 )
|
||
|
{
|
||
|
for (j = 0; j < ( hour0->num_point1 / 4 ) - 1 ; j++)
|
||
|
{
|
||
|
hour0->point_numbers[ j * 4 ] = NRAND( 12 ) + 1;
|
||
|
hour0->point_numbers[ j * 4 + 1 ] = NRAND( 12 )
|
||
|
+ 1;
|
||
|
hour0->point_numbers[ j * 4 + 2 ] = NRAND( 12 )
|
||
|
+ 1;
|
||
|
hour0->point_numbers[ j * 4 + 3 ] = NRAND( 12 )
|
||
|
+ 1;
|
||
|
}
|
||
|
hour0->point_numbers[ hour0->num_point1 / 4 ] = 1;
|
||
|
hour0->point_numbers[ 1 + hour0->num_point1 / 4 ] =
|
||
|
1;
|
||
|
hour0->point_numbers[ 2 + hour0->num_point1 / 4 ] =
|
||
|
1;
|
||
|
hour0->point_numbers[ 3 + hour0->num_point1 / 4 ] =
|
||
|
1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (j = 0; j < hour0->num_point1 / 4 ; j++)
|
||
|
{
|
||
|
hour0->point_numbers[ j * 4 ] = NRAND( 12 ) + 1;
|
||
|
hour0->point_numbers[ j * 4 + 1 ] =
|
||
|
hour0->point_numbers[ j * 4 ];
|
||
|
hour0->point_numbers[ j * 4 + 2 ] = NRAND( 12 )
|
||
|
+ 1;
|
||
|
hour0->point_numbers[ j * 4 + 3 ] = NRAND( 12 )
|
||
|
+ 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
hour0->point_numbers = original_clock[i+istart];
|
||
|
if ( NRAND( 100 ) >= tclock->fill )
|
||
|
hour0->draw = True;
|
||
|
else
|
||
|
hour0->draw = False;
|
||
|
#ifdef NO_DBUF
|
||
|
{
|
||
|
int x0 , y0;
|
||
|
|
||
|
x0 = (int) (tclock->radius * sin( -tclock->angle - PI_RAD * i *
|
||
|
360.0 / tclock->num_hour ) *
|
||
|
0.5 * ( 1 + cos( tclock->phase ) ) + tclock->x0 +
|
||
|
tclock->a_x * sin( tclock->anglex ) );
|
||
|
y0 = (int) (tclock->radius * cos( -tclock->angle - PI_RAD * i *
|
||
|
360.0 / tclock->num_hour ) *
|
||
|
0.5 * ( 1 + cos( tclock->phase ) ) + tclock->y0 +
|
||
|
tclock->a_y * sin( tclock->angley ) );
|
||
|
toneclock_drawhour(mi , hour0 , x0 , y0 );
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
tclock->a_x = 0;
|
||
|
tclock->a_y = 0;
|
||
|
if ( !tclock->original && tclock->win_width > 20 )
|
||
|
{
|
||
|
if ( tclock->radius < MIN( tclock->win_width , tclock->win_height) /
|
||
|
4 )
|
||
|
{
|
||
|
if ( MI_IS_FULLRANDOM( mi ) )
|
||
|
{
|
||
|
if ( NRAND(2) )
|
||
|
tclock->moving = True;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tclock->moving = move_clock;
|
||
|
}
|
||
|
if ( tclock->moving )
|
||
|
{
|
||
|
tclock->a_x = (int) floor( ( tclock->win_width / 2 ) - 1.05 *
|
||
|
( tclock->radius + tclock->max_radius )
|
||
|
);
|
||
|
tclock->a_y = (int) floor( ( tclock->win_height / 2 ) - 1.05 *
|
||
|
( tclock->radius + tclock->max_radius )
|
||
|
);
|
||
|
tclock->vx = (NRAND(15) - 7) * PI_RAD;
|
||
|
tclock->vy = (NRAND(15) - 7) * PI_RAD;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
XFlush(display);
|
||
|
XSetFunction(display, tclock->gc, GXcopy);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
draw_toneclock(ModeInfo * mi)
|
||
|
{
|
||
|
Display *display = MI_DISPLAY(mi);
|
||
|
Window window = MI_WINDOW(mi);
|
||
|
int i;
|
||
|
toneclockstruct *tclock;
|
||
|
|
||
|
if (toneclocks == NULL)
|
||
|
return;
|
||
|
tclock = &toneclocks[MI_SCREEN(mi)];
|
||
|
if (tclock->hour == NULL)
|
||
|
return;
|
||
|
|
||
|
if (tclock->no_colors) {
|
||
|
free_toneclock(display, tclock);
|
||
|
init_toneclock(mi);
|
||
|
return;
|
||
|
}
|
||
|
XSetFunction(display, tclock->gc, GXxor);
|
||
|
#ifndef NO_DBUF
|
||
|
XSetForeground(display,tclock->dbuf_gc,MI_BLACK_PIXEL(mi));
|
||
|
XFillRectangle(display, (Drawable) tclock->dbuf, tclock->dbuf_gc,
|
||
|
0, 0, tclock->win_width, tclock->win_height);
|
||
|
#endif
|
||
|
tclock->painted = True;
|
||
|
MI_IS_DRAWN(mi) = True;
|
||
|
/* Rotate colours */
|
||
|
if (tclock->cycle_p) {
|
||
|
rotate_colors(display, tclock->cmap, tclock->colors, tclock->ncolors,
|
||
|
tclock->direction);
|
||
|
if (!(LRAND() % 1000))
|
||
|
tclock->direction = -tclock->direction;
|
||
|
}
|
||
|
for (i = 0; i < tclock->num_hour; i++) {
|
||
|
toneclockhour *hour0;
|
||
|
int x0 , y0;
|
||
|
|
||
|
x0 = (int) (tclock->radius * sin( -tclock->angle - PI_RAD * i *
|
||
|
360.0 / tclock->num_hour ) *
|
||
|
0.5 * ( 1 + cos( tclock->phase ) ) + tclock->x0 +
|
||
|
tclock->a_x * sin( tclock->anglex ) );
|
||
|
y0 = (int) (tclock->radius * cos( -tclock->angle - PI_RAD * i *
|
||
|
360.0 / tclock->num_hour ) *
|
||
|
0.5 * ( 1 + cos( tclock->phase ) ) + tclock->y0 +
|
||
|
tclock->a_y * sin( tclock->angley ) );
|
||
|
hour0 = &tclock->hour[i];
|
||
|
if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
|
||
|
XSetForeground(display, tclock->gc, tclock->colors[hour0->colour].pixel);
|
||
|
} else {
|
||
|
XSetForeground(display, tclock->gc, hour0->colour);
|
||
|
}
|
||
|
toneclock_drawhour(mi, hour0 , x0 , y0);
|
||
|
hour0->velocity += ((float) NRAND(1001) - 500.0) / 200000.0;
|
||
|
hour0->angle += hour0->velocity;
|
||
|
}
|
||
|
tclock->velocity += ((float) NRAND(1001) - 500.0) / 200000.0;
|
||
|
tclock->angle += tclock->velocity;
|
||
|
if ( tclock->pulsating )
|
||
|
tclock->phase += tclock->ph_vel;
|
||
|
if ( tclock->moving )
|
||
|
{
|
||
|
tclock->anglex += tclock->vx;
|
||
|
tclock->angley += tclock->vy;
|
||
|
}
|
||
|
#ifdef NO_DBUF
|
||
|
for (i = 0; i < tclock->num_hour; i++) {
|
||
|
toneclockhour *hour0;
|
||
|
int x0 , y0;
|
||
|
|
||
|
x0 = (int) (tclock->radius * sin( -tclock->angle - PI_RAD * i *
|
||
|
360.0 / tclock->num_hour ) *
|
||
|
0.5 * ( 1 + cos( tclock->phase ) ) + tclock->x0 +
|
||
|
tclock->a_x * sin( tclock->anglex ) );
|
||
|
y0 = (int) (tclock->radius * cos( -tclock->angle - PI_RAD * i *
|
||
|
360.0 / tclock->num_hour ) *
|
||
|
0.5 * ( 1 + cos( tclock->phase ) ) + tclock->y0 +
|
||
|
tclock->a_y * sin( tclock->angley ) );
|
||
|
hour0 = &tclock->hour[i];
|
||
|
if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
|
||
|
XSetForeground(display, tclock->gc, tclock->colors[hour0->colour].pixel);
|
||
|
} else {
|
||
|
XSetForeground(display, tclock->gc, hour0->colour);
|
||
|
}
|
||
|
toneclock_drawhour(mi, hour0 , x0 , y0);
|
||
|
}
|
||
|
#else
|
||
|
XFlush(display);
|
||
|
XCopyArea (display, (Drawable) tclock->dbuf, window, tclock->dbuf_gc, 0, 0,
|
||
|
tclock->win_width, tclock->win_height, 0, 0);
|
||
|
XFlush(display);
|
||
|
XSetForeground(display,tclock->dbuf_gc,MI_BLACK_PIXEL(mi));
|
||
|
XFillRectangle(display, (Drawable) tclock->dbuf, tclock->dbuf_gc,
|
||
|
0, 0, tclock->win_width, tclock->win_height);
|
||
|
#endif
|
||
|
XSetFunction(display, tclock->gc, GXcopy);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
refresh_toneclock(ModeInfo * mi)
|
||
|
{
|
||
|
toneclockstruct *tclock;
|
||
|
|
||
|
if (toneclocks == NULL)
|
||
|
return;
|
||
|
tclock = &toneclocks[MI_SCREEN(mi)];
|
||
|
if (tclock->hour == NULL)
|
||
|
return;
|
||
|
|
||
|
if (!tclock->painted)
|
||
|
return;
|
||
|
MI_CLEARWINDOW(mi);
|
||
|
#ifdef NO_DBUF
|
||
|
{
|
||
|
Display *display = MI_DISPLAY(mi);
|
||
|
int i;
|
||
|
|
||
|
XSetFunction(display, tclock->gc, GXxor);
|
||
|
for (i = 0; i < tclock->num_hour; i++) {
|
||
|
toneclockhour *hour0;
|
||
|
int x0 , y0;
|
||
|
|
||
|
x0 = (int) (tclock->radius * sin( -tclock->angle - PI_RAD * i *
|
||
|
360.0 / tclock->num_hour ) +
|
||
|
tclock->x0 + tclock->a_x * sin( tclock->anglex ) );
|
||
|
y0 = (int) (tclock->radius * cos( -tclock->angle - PI_RAD * i *
|
||
|
360.0 / tclock->num_hour ) +
|
||
|
tclock->y0 + tclock->a_y * sin( tclock->angley ) );
|
||
|
hour0 = &tclock->hour[i];
|
||
|
if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) {
|
||
|
XSetForeground(display, tclock->gc, tclock->colors[hour0->colour].pixel);
|
||
|
} else {
|
||
|
XSetForeground(display, tclock->gc, hour0->colour);
|
||
|
}
|
||
|
toneclock_drawhour(mi, hour0 , x0 , y0 );
|
||
|
}
|
||
|
XSetFunction(display, tclock->gc, GXcopy);
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void
|
||
|
release_toneclock(ModeInfo * mi)
|
||
|
{
|
||
|
if (toneclocks != NULL) {
|
||
|
int screen;
|
||
|
|
||
|
for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++)
|
||
|
free_toneclock(MI_DISPLAY(mi), &toneclocks[screen]);
|
||
|
free(toneclocks);
|
||
|
toneclocks = (toneclockstruct *) NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif /* MODE_toneclock */
|