/* -*- Mode: C; tab-width: 4 -*- */ /* toneclock --- Screenhack inspired by Peter Schat's toneclock */ #if 0 static const char sccsid[] = "@(#)toneclock.c 5.00 2004/09/16 xlockmore"; #endif /*- * Copyright (c) 2004 by Jouk Jansen * * 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 DEFAULTS "*delay: 60000 \n" \ "*count: -20 \n" \ "*cycles: 200 \n" \ "*size: -1000 \n" \ "*ncolors: 64 \n" \ "*fullrandom: True \n" \ "*verbose: False \n" \ # define free_toneclock 0 # define reshape_toneclock 0 # define toneclock_handle_event 0 #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"} }; ENTRYPOINT 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 { 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_screen(ModeInfo *mi, toneclockstruct *tclock) { Display *display = MI_DISPLAY(mi); if (tclock == NULL) { return; } 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) { #ifdef STANDALONE Screen *screen = MI_SCREENPTR(mi); #endif if (tclock->ncolors && !tclock->no_colors) free_colors( #ifdef STANDALONE screen, #else display, #endif 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 tclock = NULL; } #ifndef STANDALONE extern char *background; extern char *foreground; #endif ENTRYPOINT void init_toneclock(ModeInfo * mi) { Display *display = MI_DISPLAY(mi); Window window = MI_WINDOW(mi); int i, size_hour, istart; toneclockstruct *tclock; /* initialize */ MI_INIT(mi, toneclocks); tclock = &toneclocks[MI_SCREEN(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_screen(mi, 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_screen(mi, 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_screen(mi, tclock); return; } if (MI_IS_INSTALL(mi) && MI_NPIXELS(mi) > 2) { #ifdef STANDALONE Screen *screen = MI_SCREENPTR(mi); #endif /* Set up colour map */ if (tclock->colors != NULL) { if (tclock->ncolors && !tclock->no_colors) free_colors( #ifdef STANDALONE screen, #else display, #endif 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_screen(mi, tclock); return; } tclock->cycle_p = has_writable_cells( #ifdef STANDALONE screen, MI_VISUAL(mi) #else mi #endif ); 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 screen, MI_VISUAL(mi), tclock->cmap, tclock->colors, &tclock->ncolors, True, True, &tclock->cycle_p, True #else mi, tclock->cmap, tclock->colors, &tclock->ncolors, True, True, &tclock->cycle_p #endif ); else if (!(LRAND() % 2)) make_uniform_colormap( #ifdef STANDALONE screen, MI_VISUAL(mi), tclock->cmap, tclock->colors, &tclock->ncolors, True, &tclock->cycle_p, True #else mi, tclock->cmap, tclock->colors, &tclock->ncolors, True, &tclock->cycle_p #endif ); else make_smooth_colormap( #ifdef STANDALONE screen, MI_VISUAL(mi), tclock->cmap, tclock->colors, &tclock->ncolors, True, &tclock->cycle_p, True #else mi, tclock->cmap, tclock->colors, &tclock->ncolors, True, &tclock->cycle_p #endif ); } 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); } ENTRYPOINT 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_screen(mi, 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( #ifdef STANDALONE MI_SCREENPTR(mi), #else display, #endif 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); } ENTRYPOINT void release_toneclock(ModeInfo * mi) { if (toneclocks != NULL) { int screen; for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) free_toneclock_screen(mi, &toneclocks[screen]); free(toneclocks); toneclocks = (toneclockstruct *) NULL; } } #ifndef STANDALONE ENTRYPOINT 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 } #endif XSCREENSAVER_MODULE ("Toneclock", toneclock) #endif /* MODE_toneclock */