home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume10 / xchrom / part01 / Xchrom.c < prev    next >
C/C++ Source or Header  |  1990-12-07  |  12KB  |  391 lines

  1. /*
  2.  * Xchrom.c -- a CHROMACHRON clock widget. implementation module.
  3.  * Copyright (c) Olaf Heimburger 1990
  4.  * Last edited: Tue Nov  6 11:16:24 1990 by olafh (Olaf Heimburger) on GECKO
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <math.h>
  9. #include <X11/IntrinsicP.h>
  10. #include <X11/Xos.h>
  11. #include <X11/StringDefs.h>
  12. #include "XchromP.h"
  13.  
  14. static void Initialize (), Resize (), Realize (), Destroy (),
  15.     Redisplay (), Timeout (), GetGC (), GetColorGC (), ShowTime ();
  16.  
  17. static Boolean SetValues ();
  18.  
  19. static Dimension winWidth = MINWIDTH;
  20. static Dimension winHeight = MINHEIGHT;
  21. static int sOffset = STARTCORNER;
  22. static int mOffset = MASKOFFSET;
  23. static int tOffset = 0; /* believe system clock */
  24.  
  25. static int sliceAngles[NUMFIELDS] = {
  26.      75, /* twelve */
  27.      45, /* one */
  28.      15, /* two */
  29.     345, /* three */
  30.     315, /* four */
  31.     285, /* five */
  32.     255, /* six */
  33.     225, /* seven */
  34.     195, /* eight */
  35.     165, /* nine */
  36.     135, /* ten */
  37.     105, /* eleven */
  38. };
  39.  
  40. static XtResource resources[] = {
  41.     { XtNwidth, XtCWidth, XtRDimension, sizeof (Dimension),
  42.     XtOffset (Widget, core.width), XtRDimension, (caddr_t)&winWidth },
  43.     { XtNheight, XtCHeight, XtRDimension, sizeof (Dimension),
  44.     XtOffset (Widget, core.height), XtRDimension, (caddr_t)&winHeight },
  45.     { XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
  46.         XtOffset (XchromWidget, xchrom.foreground), XtRString,
  47.       XtDefaultForeground},
  48.     { XtNstartOffset, XtCStartOffset, XtRInt, sizeof (int),
  49.     XtOffset (XchromWidget, xchrom.startOffset), XtRInt,
  50.       (caddr_t)&sOffset},
  51.     { XtNmaskOffset, XtCMaskOffset, XtRInt, sizeof (int),
  52.     XtOffset (XchromWidget, xchrom.maskOffset), XtRInt, (caddr_t)&mOffset},
  53.     { XtNtimeOffset, XtCTimeOffset, XtRInt, sizeof (int),
  54.     XtOffset (XchromWidget, xchrom.timeOffset), XtRInt, (caddr_t)&tOffset},
  55.     { XtNtwelveOClock, XtCTwelveOClock, XtRPixel, sizeof (Pixel),
  56.         XtOffset (XchromWidget, xchrom.color[0]), XtRString, "Yellow"},
  57.     { XtNoneOClock, XtCOneOClock, XtRPixel, sizeof (Pixel),
  58.         XtOffset (XchromWidget, xchrom.color[1]), XtRString, "Orange"},
  59.     { XtNtwoOClock, XtCTwoOClock, XtRPixel, sizeof (Pixel),
  60.         XtOffset (XchromWidget, xchrom.color[2]), XtRString, "Pink"},
  61.     { XtNthreeOClock, XtCThreeOClock, XtRPixel, sizeof (Pixel),
  62.         XtOffset (XchromWidget, xchrom.color[3]), XtRString, "Red"},
  63.     { XtNfourOClock, XtCFourOClock, XtRPixel, sizeof (Pixel),
  64.         XtOffset (XchromWidget, xchrom.color[4]), XtRString, "LightPink"},
  65.     { XtNfiveOClock, XtCFiveOClock, XtRPixel, sizeof (Pixel),
  66.         XtOffset (XchromWidget, xchrom.color[5]), XtRString, "Violet"},
  67.     { XtNsixOClock, XtCSixOClock, XtRPixel, sizeof (Pixel),
  68.         XtOffset (XchromWidget, xchrom.color[6]), XtRString, "RoyalBlue"},
  69.     { XtNsevenOClock, XtCSevenOClock, XtRPixel, sizeof (Pixel),
  70.         XtOffset (XchromWidget, xchrom.color[7]), XtRString, "DarkGreen"},
  71.     { XtNeightOClock, XtCEightOClock, XtRPixel, sizeof (Pixel),
  72.         XtOffset (XchromWidget, xchrom.color[8]), XtRString, "Turquoise"},
  73.     { XtNnineOClock, XtCNineOClock, XtRPixel, sizeof (Pixel),
  74.         XtOffset (XchromWidget, xchrom.color[9]), XtRString, "Brown"},
  75.     { XtNtenOClock, XtCTenOClock, XtRPixel, sizeof (Pixel),
  76.         XtOffset (XchromWidget, xchrom.color[10]), XtRString, "LightYellow"},
  77.     { XtNelevenOClock, XtCElevenOClock, XtRPixel, sizeof (Pixel),
  78.         XtOffset (XchromWidget, xchrom.color[11]), XtRString, "Wheat"},
  79. };
  80.  
  81. XchromClassRec xchromClassRec = {
  82.     { /* core fields */
  83.     /* superclass        */    &widgetClassRec,
  84.     /* class_name        */    "Xchrom",
  85.     /* widget_size        */    sizeof (XchromRec),
  86.     /* class_initialize        */    NULL,
  87.     /* class_part_initialize    */    NULL,
  88.     /* class_inited        */    FALSE,
  89.     /* initialize        */    Initialize,
  90.     /* initialize_hook        */    NULL,
  91.     /* realize            */    Realize,
  92.     /* actions            */    NULL,
  93.     /* num_actions        */    0,
  94.     /* resources        */    resources,
  95.     /* resource_count        */    XtNumber (resources),
  96.     /* xrm_class        */    NULL,
  97.     /* compress_motion        */    TRUE,
  98.     /* compress_exposure    */    TRUE,
  99.     /* compress_enterleave    */    TRUE,
  100.     /* visible_interest        */    FALSE,
  101.     /* destroy            */    Destroy,
  102.     /* resize            */    Resize,
  103.     /* expose            */    Redisplay,
  104.     /* set_values        */    SetValues,
  105.     /* set_values_hook        */    NULL,
  106.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  107.     /* get_values_hook        */    NULL,
  108.     /* accept_focus        */    NULL,
  109.     /* version            */    XtVersion,
  110.     /* callback_private        */    NULL,
  111.     /* tm_table            */    NULL,
  112.     /* query_geometry        */    NULL,
  113.     }
  114. };
  115.  
  116. WidgetClass xchromWidgetClass = (WidgetClass) &xchromClassRec;
  117.  
  118. /* ARGSUSED */
  119. static void Initialize (request, new)
  120.     XchromWidget   request;
  121.     XchromWidget   new;
  122. {
  123.     if (new) {
  124.     int i;
  125.     new->xchrom.intervalId = None;
  126.     new->xchrom.wdwPixmap = new->xchrom.colorPixmap = None;
  127.     /*
  128.      * initialize the color table
  129.      */
  130.     for (i = 0; i < NUMFIELDS; ++i) {
  131.         GetColorGC (new, i);
  132.     }
  133.     /*
  134.      * Initialize the angles for the slices.
  135.      */
  136.     for (i = 0; i < NUMFIELDS; ++i) {
  137.         new->xchrom.slices[i].angle1 = (short)(sliceAngles[i] * XARCMAGIC);
  138.         new->xchrom.slices[i].angle2 = (short)(SLICEANGLE * XARCMAGIC);
  139.     }
  140.     new->xchrom.slices[SLICEMASK].angle1 = STARTDEGREES * XARCMAGIC;
  141.     new->xchrom.slices[SLICEMASK].angle2 = MASKDEGREES * XARCMAGIC;
  142.     new->xchrom.slices[SLICEMASK].x =
  143.         new->xchrom.slices[SLICEMASK].y =
  144.         new->xchrom.startOffset + new->xchrom.maskOffset;
  145.     new->xchrom.minOffset = new->xchrom.timeOffset % 60;
  146.     new->xchrom.hourOffset = new->xchrom.timeOffset / 60;
  147.     }
  148.     GetGC (new);
  149. }
  150.  
  151. static void GetColorGC (w, i)
  152.     XchromWidget w;
  153.     int i;
  154. {
  155.     if (w && i >= 0 && i < NUMFIELDS) {
  156.     XGCValues gcv;
  157.     XtGCMask mask = GCForeground | GCBackground | GCFunction;
  158.     gcv.background = WhitePixel (XtDisplay (w),
  159.                      DefaultScreen (XtDisplay (w)));
  160.     gcv.function = GXcopy;
  161.     gcv.foreground = w->xchrom.color[i];
  162.     w->xchrom.colors[i] = XtGetGC ((Widget)w, mask, &gcv);
  163.     }
  164. }
  165.  
  166. static void GetGC (w)
  167.     XchromWidget w;
  168. {
  169.     if (w) {
  170.     XGCValues gcv;
  171.     XtGCMask mask = GCForeground | GCBackground | GCFunction;
  172.     gcv.background = w->core.background_pixel;
  173.     gcv.foreground = w->xchrom.foreground;
  174.     gcv.function = GXcopy;
  175.     w->xchrom.colors[BACKCOLOR] = XtGetGC ((Widget)w, mask, &gcv);
  176.     }
  177. }
  178.  
  179. static void CreatePixmaps (w)
  180.     XchromWidget w;
  181. {
  182.     if (w) {
  183.     /*
  184.      * Create the pixmap's and clear 'em.
  185.      */
  186.     Display *dpy = XtDisplay (w);
  187.     Window win = XtWindow (w);
  188.     GC tmpGC;
  189.     XGCValues gcv;
  190.     XtGCMask mask = GCForeground | GCBackground | GCFunction;
  191.     if (w->xchrom.colorPixmap != None) {
  192.         XFreePixmap (dpy, w->xchrom.colorPixmap);
  193.     }
  194.     if (w->xchrom.wdwPixmap != None) {
  195.         XFreePixmap (dpy, w->xchrom.wdwPixmap);
  196.     }
  197.     gcv.foreground = WhitePixel (dpy, DefaultScreen (dpy));
  198.     gcv.background = BlackPixel (dpy, DefaultScreen (dpy));
  199.     gcv.function = GXcopy;
  200.     tmpGC = XtGetGC (w, mask, &gcv);
  201.     w->xchrom.colorPixmap =
  202.         XCreatePixmap (dpy, win, w->xchrom.arcSize, w->xchrom.arcSize,
  203.                DefaultDepth (dpy, DefaultScreen (dpy)));
  204.     XFillRectangle (dpy, w->xchrom.colorPixmap, tmpGC, 0, 0,
  205.             w->xchrom.arcSize, w->xchrom.arcSize);
  206.     w->xchrom.wdwPixmap =
  207.         XCreatePixmap (dpy, win, w->core.width, w->core.height,
  208.                DefaultDepth (dpy, DefaultScreen (dpy)));
  209.     XFillRectangle (dpy, w->xchrom.wdwPixmap, tmpGC, 0, 0, w->core.width,
  210.             w->core.height);
  211.     XtReleaseGC (w, tmpGC);
  212.     }
  213. }
  214.  
  215. static void Realize (w, valueMask, attrs)
  216.     Widget w;
  217.     XtValueMask *valueMask;
  218.     XSetWindowAttributes *attrs;
  219. {
  220.     *valueMask |= CWBitGravity;
  221.     attrs->bit_gravity = ForgetGravity;
  222.     XtCreateWindow(w, InputOutput, (Visual*)CopyFromParent, *valueMask,
  223.            attrs);
  224.     Resize(w);
  225. }
  226.  
  227. static void Destroy (w)
  228.     XchromWidget w;
  229. {
  230.     int n;
  231.     
  232.     if (w->xchrom.intervalId) {
  233.     XtRemoveTimeOut (w->xchrom.intervalId);
  234.     }
  235.     for (n = 0; n < NUMFIELDS + 1; ++n) {
  236.     XtReleaseGC (w, w->xchrom.colors[n]);
  237.     }
  238.     if (w->xchrom.colorPixmap) {
  239.     XFreePixmap (XtDisplay (w), w->xchrom.colorPixmap);
  240.     }
  241.     if (w->xchrom.wdwPixmap) {
  242.     XFreePixmap (XtDisplay (w), w->xchrom.wdwPixmap);
  243.     }
  244. }
  245.  
  246. /* ARGSUSED */
  247. static void Resize (w)
  248.     XchromWidget w;
  249. {
  250.     if (XtIsRealized (w)) {
  251.     Display *dpy = XtDisplay (w);
  252.     int width = w->core.width;
  253.     int height = w->core.height;
  254.     /*
  255.      * Get the minimum size of the square
  256.      */
  257.     w->xchrom.squareSize =
  258.         ((width > height) ? height : width) - (w->xchrom.startOffset * 2);
  259.     if (w->xchrom.squareSize > 0) {
  260.         XRectangle rect;
  261.         int i = 0;
  262.         int halfSize = w->xchrom.squareSize / 2;
  263.         w->xchrom.arcSize =
  264.         ((int)sqrt ((float)((halfSize * halfSize)
  265.                     + (halfSize * halfSize))) * 2) + 3;
  266.         w->xchrom.offset =
  267.         (int)((w->xchrom.arcSize - w->xchrom.squareSize) / 2);
  268.         CreatePixmaps (w);
  269.         /*
  270.          * Fill the color pixmap
  271.          */
  272.         for (i = 0; i < NUMFIELDS; ++i) {
  273.         w->xchrom.slices[i].x = w->xchrom.slices[i].y = 0;
  274.         w->xchrom.slices[i].width = w->xchrom.slices[i].height =
  275.             w->xchrom.arcSize;
  276.         XFillArcs (dpy, w->xchrom.colorPixmap, w->xchrom.colors[i],
  277.                &w->xchrom.slices[i], 1);
  278.         }
  279.         /*
  280.          * Fill the background
  281.          */
  282.         rect.x = 0;
  283.         rect.y = 0;
  284.         rect.width = width;
  285.         rect.height = height;
  286.         XFillRectangles (dpy, w->xchrom.wdwPixmap,
  287.                  w->xchrom.colors[BACKCOLOR], &rect, 1);
  288.         /*
  289.          * Set the slice mask size.
  290.          */
  291.         w->xchrom.slices[SLICEMASK].width =
  292.         w->xchrom.slices[SLICEMASK].height =
  293.             w->xchrom.squareSize - (w->xchrom.maskOffset * 2);
  294.     }
  295.     }
  296. }
  297.  
  298. /* ARGSUSED */
  299. static void Redisplay (w)
  300.     XchromWidget w;
  301. {
  302.     if (XtIsRealized (w)) {
  303.     long t = time (0);
  304.     if (w->xchrom.intervalId != None) {
  305.         XtRemoveTimeOut (w->xchrom.intervalId);
  306.         w->xchrom.intervalId = NULL;
  307.     }
  308.     ShowTime (w);
  309.     w->xchrom.intervalId =
  310.         XtAddTimeOut ((unsigned long)(60 - (t % 60)) * 1000, Timeout, w);
  311.     }
  312. }
  313.  
  314. static void ShowTime (w)
  315.     XchromWidget w;
  316. {
  317.     long t = time (0);
  318.     register struct tm *lTime = localtime (&t);
  319.  
  320.     /*
  321.      * Clear the previous slice mask.
  322.      */
  323.     XCopyArea (XtDisplay (w), w->xchrom.colorPixmap, w->xchrom.wdwPixmap,
  324.            w->xchrom.colors[BACKCOLOR], w->xchrom.offset, w->xchrom.offset,
  325.            w->xchrom.squareSize, w->xchrom.squareSize,
  326.            w->xchrom.startOffset, w->xchrom.startOffset);
  327.     /*
  328.      * Calculate current position of slice mask
  329.      */
  330.     if (lTime) {
  331.     int min = lTime->tm_min + w->xchrom.minOffset;
  332.     int hour = (lTime->tm_hour + w->xchrom.hourOffset) % NUMFIELDS;
  333.     if (w->xchrom.savedHour != hour || w->xchrom.savedMin != min) {
  334.         w->xchrom.slices[SLICEMASK].angle1 =
  335.         (sliceAngles[hour] + SLICEANGLE) * XARCMAGIC;
  336.         /*
  337.          * Display every minute. (0.5 degrees per minute)
  338.          */
  339.         w->xchrom.slices[SLICEMASK].angle1 -= (min) * (int)(XARCMAGIC / 2);
  340.         w->xchrom.savedHour = hour;
  341.         w->xchrom.savedMin = min;
  342.     }
  343.     }
  344.     /*
  345.      * Draw slice mask.
  346.      */
  347.     XFillArcs (XtDisplay (w), w->xchrom.wdwPixmap, w->xchrom.colors[BACKCOLOR],
  348.            &w->xchrom.slices[SLICEMASK], 1);
  349.     /*
  350.      * Finally, show the result.
  351.      */
  352.     XCopyArea (XtDisplay (w), w->xchrom.wdwPixmap, XtWindow (w),
  353.            w->xchrom.colors[BACKCOLOR], 0, 0, w->core.width,
  354.            w->core.height, 0, 0);
  355.     XFlush (XtDisplay (w));
  356. }
  357.  
  358. static void Timeout (w, id)
  359.     XchromWidget w;
  360.     XtIntervalId *id;
  361. {
  362.     ShowTime (w);
  363.     w->xchrom.intervalId = XtAddTimeOut (60000, Timeout, w);
  364. }
  365.  
  366. /* ARGSUSED */
  367. static Boolean SetValues (current, request, new)
  368.     XchromWidget current, request, new;
  369. {
  370.     Boolean redraw = False;
  371.     int i;
  372.     if (new->xchrom.foreground != current->xchrom.foreground
  373.     ||  new->core.background_pixel != current->core.background_pixel) {
  374.     XtReleaseGC (current, current->xchrom.colors[BACKCOLOR]);
  375.     GetGC (new);
  376.     redraw = True;
  377.     }
  378.     for (i = 0; i < NUMFIELDS; ++i) {
  379.     if (new->xchrom.color[i] != current->xchrom.color[i]) {
  380.         printf ("color %d changed\n", i);
  381.         XtReleaseGC (current, current->xchrom.colors[i]);
  382.         GetColorGC (new, i);
  383.         redraw = True;
  384.     }
  385.     }
  386.     if (redraw) {
  387.     Resize (new); /* pixmaps need to be redrawn */
  388.     }
  389.     return redraw;
  390. }
  391.