home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume14 / xchrom / part01 / Xchrom-1.6 / Xchrom.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-26  |  12.8 KB  |  417 lines

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