home *** CD-ROM | disk | FTP | other *** search
/ Practical Programming in Tcl & Tk (4th Edition) / TCLBOOK4.BIN / pc / exsource.old / 47_14.c < prev    next >
Text File  |  2003-04-15  |  3KB  |  109 lines

  1. /*
  2.  * Example 47-14
  3.  * The ClockDisplay procedure.
  4.  */
  5.  
  6. static void
  7. ClockDisplay(ClientData clientData)
  8. {
  9.     Clock *clockPtr = (Clock *)clientData;
  10.     Tk_Window tkwin = clockPtr->tkwin;
  11.     GC gc;                            /* Graphics Context for highlight */
  12.     Tk_TextLayout layout;                            /* Text measurement state */
  13.     Pixmap pixmap;                            /* Temporary drawing area */
  14.     int offset, x, y;                            /* Coordinates */
  15.     int width, height;                            /* Size */
  16.     struct tm *tmPtr;                            /* Time info split into fields */
  17.     struct timeval tv;                            /* BSD-style time value */
  18.  
  19.     /*
  20.      * Make sure the clock still exists
  21.      * and is mapped onto the display before painting.
  22.      */
  23.     clockPtr->flags &= ~(REDRAW_PENDING|TICKING);
  24.     if ((clockPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
  25.         return;
  26.     }
  27.     /*
  28.      * Format the time into a string.
  29.      * localtime chops up the time into fields.
  30.      * strftime formats the fields into a string.
  31.      */
  32.     gettimeofday(&tv, NULL);
  33.     tmPtr = localtime(&tv.tv_sec);
  34.     strftime(clockPtr->clock, clockPtr->numChars+1, 
  35.         clockPtr->format, tmPtr);
  36.     /*
  37.      * To avoid flicker when the display is updated, the new
  38.      * image is painted in an offscreen pixmap and then 
  39.      * copied onto the display in one operation. Allocate the
  40.      * pixmap and paint its background.
  41.      */
  42.     pixmap = Tk_GetPixmap(clockPtr->display,
  43.         Tk_WindowId(tkwin), Tk_Width(tkwin),
  44.         Tk_Height(tkwin), Tk_Depth(tkwin));
  45.     Tk_Fill3DRectangle(tkwin, pixmap, 
  46.         clockPtr->background, 0, 0, Tk_Width(tkwin),
  47.         Tk_Height(tkwin), 0, TK_RELIEF_FLAT);
  48.  
  49.     /*
  50.      * Paint the text first.
  51.      */
  52.     layout = Tk_ComputeTextLayout(clockPtr->tkfont, 
  53.         clockPtr->clock, clockPtr->numChars, 0,
  54.         TK_JUSTIFY_CENTER, 0, &width, &height);
  55.     x = (Tk_Width(tkwin) - width)/2;
  56.     y = (Tk_Height(tkwin) - height)/2;
  57.     Tk_DrawTextLayout(clockPtr->display, pixmap,
  58.         clockPtr->textGC, layout, x, y, 0, -1);
  59.  
  60.     /*
  61.      * Display the borders, so they overwrite any of the
  62.      * text that extends to the edge of the display.
  63.      */
  64.     if (clockPtr->relief != TK_RELIEF_FLAT) {
  65.         Tk_Draw3DRectangle(tkwin, pixmap,
  66.             clockPtr->background,
  67.             clockPtr->highlightWidth,
  68.             clockPtr->highlightWidth,
  69.             Tk_Width(tkwin) - 2*clockPtr->highlightWidth,
  70.             Tk_Height(tkwin) - 2*clockPtr->highlightWidth,
  71.             clockPtr->borderWidth, clockPtr->relief);
  72.     }
  73.     if (clockPtr->highlightWidth != 0) {
  74.         GC gc;
  75.  
  76.         /*
  77.          * This GC is associated with the color, and Tk caches
  78.          * the GC until the color is freed. Hence no freeGC.
  79.          */
  80.  
  81.         if (clockPtr->flags & GOT_FOCUS) {
  82.             gc = Tk_GCForColor(clockPtr->highlight, pixmap);
  83.         } else {
  84.             gc = Tk_GCForColor(clockPtr->highlightBg, pixmap);
  85.         }
  86.         Tk_DrawFocusHighlight(tkwin, gc, 
  87.             clockPtr->highlightWidth, pixmap);
  88.     }
  89.     /*
  90.      * Copy the information from the off-screen pixmap onto
  91.      * the screen, then delete the pixmap.
  92.      */
  93.     
  94.     XCopyArea(clockPtr->display, pixmap, Tk_WindowId(tkwin),
  95.         clockPtr->textGC, 0, 0, Tk_Width(tkwin),
  96.         Tk_Height(tkwin), 0, 0);
  97.     Tk_FreePixmap(clockPtr->display, pixmap);
  98.  
  99.     /*
  100.      * Queue another call to ourselves. The rate at which
  101.      * this is done could be optimized.
  102.      */
  103.     clockPtr->token = Tk_CreateTimerHandler(1000, 
  104.         ClockDisplay, (ClientData)clockPtr);
  105.     clockPtr->flags |= TICKING;
  106. }
  107.  
  108.  
  109.