home *** CD-ROM | disk | FTP | other *** search
- /*
- * Xchrom.c -- a CHROMACHRON clock widget. implementation module.
- * Copyright (c) Olaf Heimburger 1990
- * Last edited: Tue Nov 6 11:16:24 1990 by olafh (Olaf Heimburger) on GECKO
- */
-
- #include <stdio.h>
- #include <math.h>
- #include <X11/IntrinsicP.h>
- #include <X11/Xos.h>
- #include <X11/StringDefs.h>
- #include "XchromP.h"
-
- static void Initialize (), Resize (), Realize (), Destroy (),
- Redisplay (), Timeout (), GetGC (), GetColorGC (), ShowTime ();
-
- static Boolean SetValues ();
-
- static Dimension winWidth = MINWIDTH;
- static Dimension winHeight = MINHEIGHT;
- static int sOffset = STARTCORNER;
- static int mOffset = MASKOFFSET;
- static int tOffset = 0; /* believe system clock */
-
- static int sliceAngles[NUMFIELDS] = {
- 75, /* twelve */
- 45, /* one */
- 15, /* two */
- 345, /* three */
- 315, /* four */
- 285, /* five */
- 255, /* six */
- 225, /* seven */
- 195, /* eight */
- 165, /* nine */
- 135, /* ten */
- 105, /* eleven */
- };
-
- static XtResource resources[] = {
- { XtNwidth, XtCWidth, XtRDimension, sizeof (Dimension),
- XtOffset (Widget, core.width), XtRDimension, (caddr_t)&winWidth },
- { XtNheight, XtCHeight, XtRDimension, sizeof (Dimension),
- XtOffset (Widget, core.height), XtRDimension, (caddr_t)&winHeight },
- { XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.foreground), XtRString,
- XtDefaultForeground},
- { XtNstartOffset, XtCStartOffset, XtRInt, sizeof (int),
- XtOffset (XchromWidget, xchrom.startOffset), XtRInt,
- (caddr_t)&sOffset},
- { XtNmaskOffset, XtCMaskOffset, XtRInt, sizeof (int),
- XtOffset (XchromWidget, xchrom.maskOffset), XtRInt, (caddr_t)&mOffset},
- { XtNtimeOffset, XtCTimeOffset, XtRInt, sizeof (int),
- XtOffset (XchromWidget, xchrom.timeOffset), XtRInt, (caddr_t)&tOffset},
- { XtNtwelveOClock, XtCTwelveOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[0]), XtRString, "Yellow"},
- { XtNoneOClock, XtCOneOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[1]), XtRString, "Orange"},
- { XtNtwoOClock, XtCTwoOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[2]), XtRString, "Pink"},
- { XtNthreeOClock, XtCThreeOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[3]), XtRString, "Red"},
- { XtNfourOClock, XtCFourOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[4]), XtRString, "LightPink"},
- { XtNfiveOClock, XtCFiveOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[5]), XtRString, "Violet"},
- { XtNsixOClock, XtCSixOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[6]), XtRString, "RoyalBlue"},
- { XtNsevenOClock, XtCSevenOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[7]), XtRString, "DarkGreen"},
- { XtNeightOClock, XtCEightOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[8]), XtRString, "Turquoise"},
- { XtNnineOClock, XtCNineOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[9]), XtRString, "Brown"},
- { XtNtenOClock, XtCTenOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[10]), XtRString, "LightYellow"},
- { XtNelevenOClock, XtCElevenOClock, XtRPixel, sizeof (Pixel),
- XtOffset (XchromWidget, xchrom.color[11]), XtRString, "Wheat"},
- };
-
- XchromClassRec xchromClassRec = {
- { /* core fields */
- /* superclass */ &widgetClassRec,
- /* class_name */ "Xchrom",
- /* widget_size */ sizeof (XchromRec),
- /* class_initialize */ NULL,
- /* class_part_initialize */ NULL,
- /* class_inited */ FALSE,
- /* initialize */ Initialize,
- /* initialize_hook */ NULL,
- /* realize */ Realize,
- /* actions */ NULL,
- /* num_actions */ 0,
- /* resources */ resources,
- /* resource_count */ XtNumber (resources),
- /* xrm_class */ NULL,
- /* compress_motion */ TRUE,
- /* compress_exposure */ TRUE,
- /* compress_enterleave */ TRUE,
- /* visible_interest */ FALSE,
- /* destroy */ Destroy,
- /* resize */ Resize,
- /* expose */ Redisplay,
- /* set_values */ SetValues,
- /* set_values_hook */ NULL,
- /* set_values_almost */ XtInheritSetValuesAlmost,
- /* get_values_hook */ NULL,
- /* accept_focus */ NULL,
- /* version */ XtVersion,
- /* callback_private */ NULL,
- /* tm_table */ NULL,
- /* query_geometry */ NULL,
- }
- };
-
- WidgetClass xchromWidgetClass = (WidgetClass) &xchromClassRec;
-
- /* ARGSUSED */
- static void Initialize (request, new)
- XchromWidget request;
- XchromWidget new;
- {
- if (new) {
- int i;
- new->xchrom.intervalId = None;
- new->xchrom.wdwPixmap = new->xchrom.colorPixmap = None;
- /*
- * initialize the color table
- */
- for (i = 0; i < NUMFIELDS; ++i) {
- GetColorGC (new, i);
- }
- /*
- * Initialize the angles for the slices.
- */
- for (i = 0; i < NUMFIELDS; ++i) {
- new->xchrom.slices[i].angle1 = (short)(sliceAngles[i] * XARCMAGIC);
- new->xchrom.slices[i].angle2 = (short)(SLICEANGLE * XARCMAGIC);
- }
- new->xchrom.slices[SLICEMASK].angle1 = STARTDEGREES * XARCMAGIC;
- new->xchrom.slices[SLICEMASK].angle2 = MASKDEGREES * XARCMAGIC;
- new->xchrom.slices[SLICEMASK].x =
- new->xchrom.slices[SLICEMASK].y =
- new->xchrom.startOffset + new->xchrom.maskOffset;
- new->xchrom.minOffset = new->xchrom.timeOffset % 60;
- new->xchrom.hourOffset = new->xchrom.timeOffset / 60;
- }
- GetGC (new);
- }
-
- static void GetColorGC (w, i)
- XchromWidget w;
- int i;
- {
- if (w && i >= 0 && i < NUMFIELDS) {
- XGCValues gcv;
- XtGCMask mask = GCForeground | GCBackground | GCFunction;
- gcv.background = WhitePixel (XtDisplay (w),
- DefaultScreen (XtDisplay (w)));
- gcv.function = GXcopy;
- gcv.foreground = w->xchrom.color[i];
- w->xchrom.colors[i] = XtGetGC ((Widget)w, mask, &gcv);
- }
- }
-
- static void GetGC (w)
- XchromWidget w;
- {
- if (w) {
- XGCValues gcv;
- XtGCMask mask = GCForeground | GCBackground | GCFunction;
- gcv.background = w->core.background_pixel;
- gcv.foreground = w->xchrom.foreground;
- gcv.function = GXcopy;
- w->xchrom.colors[BACKCOLOR] = XtGetGC ((Widget)w, mask, &gcv);
- }
- }
-
- static void CreatePixmaps (w)
- XchromWidget w;
- {
- if (w) {
- /*
- * Create the pixmap's and clear 'em.
- */
- Display *dpy = XtDisplay (w);
- Window win = XtWindow (w);
- GC tmpGC;
- XGCValues gcv;
- XtGCMask mask = GCForeground | GCBackground | GCFunction;
- if (w->xchrom.colorPixmap != None) {
- XFreePixmap (dpy, w->xchrom.colorPixmap);
- }
- if (w->xchrom.wdwPixmap != None) {
- XFreePixmap (dpy, w->xchrom.wdwPixmap);
- }
- gcv.foreground = WhitePixel (dpy, DefaultScreen (dpy));
- gcv.background = BlackPixel (dpy, DefaultScreen (dpy));
- gcv.function = GXcopy;
- tmpGC = XtGetGC (w, mask, &gcv);
- w->xchrom.colorPixmap =
- XCreatePixmap (dpy, win, w->xchrom.arcSize, w->xchrom.arcSize,
- DefaultDepth (dpy, DefaultScreen (dpy)));
- XFillRectangle (dpy, w->xchrom.colorPixmap, tmpGC, 0, 0,
- w->xchrom.arcSize, w->xchrom.arcSize);
- w->xchrom.wdwPixmap =
- XCreatePixmap (dpy, win, w->core.width, w->core.height,
- DefaultDepth (dpy, DefaultScreen (dpy)));
- XFillRectangle (dpy, w->xchrom.wdwPixmap, tmpGC, 0, 0, w->core.width,
- w->core.height);
- XtReleaseGC (w, tmpGC);
- }
- }
-
- static void Realize (w, valueMask, attrs)
- Widget w;
- XtValueMask *valueMask;
- XSetWindowAttributes *attrs;
- {
- *valueMask |= CWBitGravity;
- attrs->bit_gravity = ForgetGravity;
- XtCreateWindow(w, InputOutput, (Visual*)CopyFromParent, *valueMask,
- attrs);
- Resize(w);
- }
-
- static void Destroy (w)
- XchromWidget w;
- {
- int n;
-
- if (w->xchrom.intervalId) {
- XtRemoveTimeOut (w->xchrom.intervalId);
- }
- for (n = 0; n < NUMFIELDS + 1; ++n) {
- XtReleaseGC (w, w->xchrom.colors[n]);
- }
- if (w->xchrom.colorPixmap) {
- XFreePixmap (XtDisplay (w), w->xchrom.colorPixmap);
- }
- if (w->xchrom.wdwPixmap) {
- XFreePixmap (XtDisplay (w), w->xchrom.wdwPixmap);
- }
- }
-
- /* ARGSUSED */
- static void Resize (w)
- XchromWidget w;
- {
- if (XtIsRealized (w)) {
- Display *dpy = XtDisplay (w);
- int width = w->core.width;
- int height = w->core.height;
- /*
- * Get the minimum size of the square
- */
- w->xchrom.squareSize =
- ((width > height) ? height : width) - (w->xchrom.startOffset * 2);
- if (w->xchrom.squareSize > 0) {
- XRectangle rect;
- int i = 0;
- int halfSize = w->xchrom.squareSize / 2;
- w->xchrom.arcSize =
- ((int)sqrt ((float)((halfSize * halfSize)
- + (halfSize * halfSize))) * 2) + 3;
- w->xchrom.offset =
- (int)((w->xchrom.arcSize - w->xchrom.squareSize) / 2);
- CreatePixmaps (w);
- /*
- * Fill the color pixmap
- */
- for (i = 0; i < NUMFIELDS; ++i) {
- w->xchrom.slices[i].x = w->xchrom.slices[i].y = 0;
- w->xchrom.slices[i].width = w->xchrom.slices[i].height =
- w->xchrom.arcSize;
- XFillArcs (dpy, w->xchrom.colorPixmap, w->xchrom.colors[i],
- &w->xchrom.slices[i], 1);
- }
- /*
- * Fill the background
- */
- rect.x = 0;
- rect.y = 0;
- rect.width = width;
- rect.height = height;
- XFillRectangles (dpy, w->xchrom.wdwPixmap,
- w->xchrom.colors[BACKCOLOR], &rect, 1);
- /*
- * Set the slice mask size.
- */
- w->xchrom.slices[SLICEMASK].width =
- w->xchrom.slices[SLICEMASK].height =
- w->xchrom.squareSize - (w->xchrom.maskOffset * 2);
- }
- }
- }
-
- /* ARGSUSED */
- static void Redisplay (w)
- XchromWidget w;
- {
- if (XtIsRealized (w)) {
- long t = time (0);
- if (w->xchrom.intervalId != None) {
- XtRemoveTimeOut (w->xchrom.intervalId);
- w->xchrom.intervalId = NULL;
- }
- ShowTime (w);
- w->xchrom.intervalId =
- XtAddTimeOut ((unsigned long)(60 - (t % 60)) * 1000, Timeout, w);
- }
- }
-
- static void ShowTime (w)
- XchromWidget w;
- {
- long t = time (0);
- register struct tm *lTime = localtime (&t);
-
- /*
- * Clear the previous slice mask.
- */
- XCopyArea (XtDisplay (w), w->xchrom.colorPixmap, w->xchrom.wdwPixmap,
- w->xchrom.colors[BACKCOLOR], w->xchrom.offset, w->xchrom.offset,
- w->xchrom.squareSize, w->xchrom.squareSize,
- w->xchrom.startOffset, w->xchrom.startOffset);
- /*
- * Calculate current position of slice mask
- */
- if (lTime) {
- int min = lTime->tm_min + w->xchrom.minOffset;
- int hour = (lTime->tm_hour + w->xchrom.hourOffset) % NUMFIELDS;
- if (w->xchrom.savedHour != hour || w->xchrom.savedMin != min) {
- w->xchrom.slices[SLICEMASK].angle1 =
- (sliceAngles[hour] + SLICEANGLE) * XARCMAGIC;
- /*
- * Display every minute. (0.5 degrees per minute)
- */
- w->xchrom.slices[SLICEMASK].angle1 -= (min) * (int)(XARCMAGIC / 2);
- w->xchrom.savedHour = hour;
- w->xchrom.savedMin = min;
- }
- }
- /*
- * Draw slice mask.
- */
- XFillArcs (XtDisplay (w), w->xchrom.wdwPixmap, w->xchrom.colors[BACKCOLOR],
- &w->xchrom.slices[SLICEMASK], 1);
- /*
- * Finally, show the result.
- */
- XCopyArea (XtDisplay (w), w->xchrom.wdwPixmap, XtWindow (w),
- w->xchrom.colors[BACKCOLOR], 0, 0, w->core.width,
- w->core.height, 0, 0);
- XFlush (XtDisplay (w));
- }
-
- static void Timeout (w, id)
- XchromWidget w;
- XtIntervalId *id;
- {
- ShowTime (w);
- w->xchrom.intervalId = XtAddTimeOut (60000, Timeout, w);
- }
-
- /* ARGSUSED */
- static Boolean SetValues (current, request, new)
- XchromWidget current, request, new;
- {
- Boolean redraw = False;
- int i;
- if (new->xchrom.foreground != current->xchrom.foreground
- || new->core.background_pixel != current->core.background_pixel) {
- XtReleaseGC (current, current->xchrom.colors[BACKCOLOR]);
- GetGC (new);
- redraw = True;
- }
- for (i = 0; i < NUMFIELDS; ++i) {
- if (new->xchrom.color[i] != current->xchrom.color[i]) {
- printf ("color %d changed\n", i);
- XtReleaseGC (current, current->xchrom.colors[i]);
- GetColorGC (new, i);
- redraw = True;
- }
- }
- if (redraw) {
- Resize (new); /* pixmaps need to be redrawn */
- }
- return redraw;
- }
-