Fix problem with title bar
[fsviewer.git] / src / timestampWidget.c
blob569194fc12d4ee349f062b96eecd16ad2c3f9e3c
1 /***********************************************************************
2 Project: WMFileViewer
3 Filename: timestampWidget.c
4 Author: Charles Gamble
5 Original code by
6 Michael J. Mitchell <mitch@gw2.redback.com.au>
7 Purpose: Source file for a NeXT style timestamp widget.
8 $Id: timestampWidget.c,v 1.2 1999/01/13 22:46:22 gambcl Exp $
9 ***********************************************************************/
14 /* Header Files *******************************************************/
16 #include <X11/xpm.h>
17 #include <WINGs/WINGsP.h>
18 #include "timestampWidget.h"
19 #include "xpm/clk.xpm"
20 #include "xpm/led.xpm"
21 #include "xpm/month.xpm"
22 #include "xpm/date.xpm"
23 #include "xpm/weekday.xpm"
24 #include "xpm/year.xpm"
27 /* Definitions ********************************************************/
29 /****************************************************
30 * Define a debugging macro that can toggled on/off. *
31 ****************************************************/
33 /*#define DEBUG_WIDGET_CODE 1*/
34 #undef DEBUG_WIDGET_CODE
36 #ifdef DEBUG_WIDGET_CODE
37 #define DEBUG_PRINT(msg) fprintf(stderr, "TIMESTAMP_WIDGET: %s: %s\n", __FILE__, msg)
38 #else
39 #define DEBUG_PRINT(msg)
40 #endif
45 /* LED positions. */
47 static int twelve[5] = { 5, 14, 24, 28, 37 };
48 static int twfour[5] = { 4, 8, 17, 22, 31 };
50 static int ns_posx[11] = { 5, 5, 5, 5, 5, 45, 21, 21, 26, 31, 19 };
51 static int ns_posy[4] = { 7, 25, 34, 49 };
53 static int posx[11];
54 static int posy[4];
57 /* Year digit widths & positions. */
59 static int year_width[10] = { 5, 1, 4, 4, 5, 4, 5, 4, 5, 5 };
60 static int year_pos[10] = { 0, 5, 6, 10, 14, 19, 23, 28, 32, 37 };
63 static char LedColor[] = "LightSeaGreen";
68 /* Type Definitions **********************************************************/
70 typedef struct _XpmIcon
72 Pixmap pixmap;
73 Pixmap mask;
74 XpmAttributes attributes;
75 } XpmIcon;
78 typedef struct W_TimeStamp
80 /********************************************************
81 * These two fields must be present in all WINGs widgets *
82 * in this exact position. *
83 ********************************************************/
84 W_Class widgetClass;
85 WMView *view;
88 /******************************************************
89 * The fields below hold data specific to this widget. *
90 ******************************************************/
92 W_Pixmap *image;
93 XpmIcon *result;
94 XpmIcon asclock;
95 XpmIcon led;
96 XpmIcon month;
97 XpmIcon date;
98 XpmIcon year;
99 XpmIcon weekday;
100 XpmIcon asvisible;
101 GC gc;
102 WMColor *color;
103 time_t time;
105 struct flags
107 unsigned int blank: 1; /* No LED, Day, Date, Month or Year. */
108 unsigned int showAMPM: 1; /* Default value is 24h format.*/
109 unsigned int damaged: 1; /* Re-render? */
110 } flags;
111 } _TimeStamp;
116 /* Globals ************************************************************/
118 static char rcsid[] = "$Id: timestampWidget.c,v 1.2 1999/01/13 22:46:22 gambcl Exp $";
119 #ifdef DEBUG_WIDGET_CODE
120 static char debug_msg[1024];
121 #endif
124 /* Widget class ID. */
125 static W_Class timeStampWidgetClass = 0;
130 /* Local Prototypes ***************************************************/
132 static int InitClockResources(TimeStamp *timestamp);
133 static int GetXPM(TimeStamp *timestamp);
134 static void destroyTimeStamp(TimeStamp *timestamp);
135 static void handleEvents(XEvent *event, void *data);
136 static void paintTimeStamp(TimeStamp *timestamp);
137 static void setBackgroundColor(WMWidget *widget, WMColor *color);
138 /* static void resizeTimeStamp(WMWidget *widget, unsigned int width, unsigned int height); */
139 static void ASTwelve(TimeStamp *timestamp, struct tm *clk);
140 static void ASTwentyFour(TimeStamp *timestamp, struct tm *clk);
141 static void RenderASClock(TimeStamp *timestamp);
142 static void willResizeTimeStamp(W_ViewDelegate*, WMView*,
143 unsigned int*, unsigned int*);
146 /* Some procedures you might want to override. Don't forget to call */
147 /* the equivalent view procedure after (or before) doing your stuff. */
148 /* See the source for the other widgets to see how to use. */
149 /* You won't need to use this most of the time. */
150 static W_ViewDelegate _TimeStampViewDelegate = {
151 NULL,
152 NULL,
153 NULL,
154 NULL,
155 willResizeTimeStamp
158 /* static W_ViewProcedureTable _TimeStampViewProcedures = */
159 /* { */
160 /* setBackgroundColor, */
161 /* resizeTimeStamp, */
162 /* NULL */
163 /* }; */
168 /***********************************************************************
169 Name: InitTimeStamp
170 Purpose: Class initializer.
171 Must be called before creating any instances of the
172 TimeStamp widget.
173 Inputs: scrPtr - Pointer to a WMScreen.
174 Outputs: None.
175 Returns: A W_Class assigned to this widget by WINGs.
176 Status: Finished.
177 Errors: None known.
179 ***********************************************************************/
180 W_Class InitTimeStamp(WMScreen *scrPtr)
182 /* Register the widget with WINGs and get the widget class ID. */
183 if (!timeStampWidgetClass)
185 /* timeStampWidgetClass = W_RegisterUserWidget(&_TimeStampViewProcedures); */
186 timeStampWidgetClass = W_RegisterUserWidget();
188 DEBUG_PRINT("Inside InitTimeStamp()");
190 return timeStampWidgetClass;
196 /***********************************************************************
197 Name: CreateTimeStamp
198 Purpose: Creates an instance of the TimeStamp widget.
199 Inputs: parent - Parent WINGs widget.
200 Outputs: None.
201 Returns: An allocated TimeStamp structure on success,
202 NULL otherwise.
203 Status: Finished.
204 Errors: None known.
205 ***********************************************************************/
206 TimeStamp *CreateTimeStamp(WMWidget *parent)
208 W_Screen *scr;
209 TimeStamp *timestamp;
211 DEBUG_PRINT("Inside CreateTimeStamp()");
212 /* Allocate storage for a new instance. */
213 timestamp = wmalloc(sizeof(TimeStamp));
214 /* Initialize it. */
215 memset(timestamp, 0, sizeof(TimeStamp));
217 /* Set the class ID. */
218 timestamp->widgetClass = timeStampWidgetClass;
220 /* Create the view for our widget. Note: the Window for the view is */
221 /* only created after the view is realized with W_RealizeView() */
222 /* Consider the returned view as read-only. */
223 if (!(timestamp->view = W_CreateView(W_VIEW(parent))))
225 free(timestamp);
226 return ((TimeStamp *)NULL);
229 DEBUG_PRINT("Created View");
230 /* Always do this. */
231 timestamp->view->self = timestamp;
232 timestamp->view->delegate = &_TimeStampViewDelegate;
234 scr = timestamp->view->screen;
236 /* Create event handler. */
237 WMCreateEventHandler(timestamp->view,
238 ExposureMask | StructureNotifyMask, handleEvents, timestamp);
240 /* Default GC for paint. */
241 timestamp->color = WMGrayColor(scr);
242 timestamp->gc = WMColorGC(timestamp->color);
244 W_ResizeView(timestamp->view, TIMESTAMP_MIN_WIDTH, TIMESTAMP_MIN_HEIGHT);
245 DEBUG_PRINT("Resized View");
247 if (InitClockResources(timestamp) == -1)
249 wfatal("Unable to initialize Clock Resources");
251 DEBUG_PRINT("Done InitClockResources()");
253 /* Create XPMs. */
254 if (GetXPM(timestamp) == -1)
256 wfatal("Unable to initialize Clock Pixmaps");
258 DEBUG_PRINT("Done GetXPM()");
260 timestamp->flags.damaged = 1;
261 timestamp->result = &timestamp->asvisible;
263 return (timestamp);
269 /***********************************************************************
270 Name: InitClockResources
271 Purpose: Initialises some coordinate data used in painting the
272 timestamp.
273 Inputs: timestamp - The TimeStamp.
274 Outputs: None.
275 Returns: 0 for success, -1 otherwise.
276 Status: Finished.
277 Errors: None known.
278 ***********************************************************************/
279 static int InitClockResources(TimeStamp *timestamp)
281 int i;
283 /* Initialize LED positions. */
284 for (i = 0; i < 4; i++)
286 posy[i] = ns_posy[i];
289 for (i = 0; i < 11; i++)
291 posx[i] = ns_posx[i];
294 for (i = 0; i < 5; i++)
296 posx[i] += ((timestamp->flags.showAMPM)) ? twfour[i] : twelve[i];
299 return (0);
304 /***********************************************************************
305 Name: GetXPM
306 Purpose: Initialises the XPM data used for the calendar face
307 and digits.
308 Inputs: timestamp - The TimeStamp.
309 Outputs: Sets the Pixmap fields in the timestamp.
310 Returns: 0 for success, -1 otherwise.
311 Status: Finished.
312 Errors: None known.
313 ***********************************************************************/
314 static int GetXPM(TimeStamp *timestamp)
316 Display *dpy = timestamp->view->screen->display;
317 Colormap cmap;
318 XColor col;
319 char brightLED[22];
320 char darkLED[22];
321 char greyStr[22];
322 int greyR = 0, greyG = 0, greyB = 0;
324 /* Get the default colourmap ID for this screen. */
325 cmap = DefaultColormap(dpy, DefaultScreen(dpy));
327 /* Get the RGB values for the LED colour. */
328 if (!XParseColor(dpy, cmap, LedColor, &col))
330 /* Could not resolve colour. */
331 return (-1);
334 /* Replace the 'bright' colour in the LED pixmap with our new one. */
335 sprintf(brightLED, ". c #%04X%04X%04X", col.red, col.green, col.blue);
336 led_xpm[2] = brightLED;
338 /* Now make a darker version and do the same. */
339 col.red = (col.red / 10) * 3;
340 col.green = (col.green / 10) * 3;
341 col.blue = (col.blue / 10) * 3;
342 sprintf(darkLED, "X c #%04X%04X%04X", col.red, col.green, col.blue);
343 led_xpm[3] = darkLED;
346 /* Perform a bit of colour surgery on the clk.xpm and year.xpm to replace */
347 /* the transparent colour "None" with the background grey colour. */
349 greyR = WMRedComponentOfColor(WMGrayColor(timestamp->view->screen));
350 greyG = WMGreenComponentOfColor(WMGrayColor(timestamp->view->screen));
351 greyB = WMBlueComponentOfColor(WMGrayColor(timestamp->view->screen));
353 greyR >>= 8;
354 greyG >>= 8;
355 greyB >>= 8;
357 sprintf(greyStr, ". c #%02X%02X%02X", greyR, greyG, greyB);
358 clk_xpm[1] = greyStr;
359 year_xpm[1] = greyStr;
362 /* Load the background image into 'asclock'. */
363 timestamp->asclock.attributes.valuemask = (XpmReturnPixels | XpmReturnExtensions | XpmSize);
364 if (XpmCreatePixmapFromData(dpy, DefaultRootWindow(dpy), clk_xpm, &timestamp->asclock.pixmap, &timestamp->asclock.mask, &timestamp->asclock.attributes) != XpmSuccess)
366 return (-1);
369 /* Load the background image into 'asvisible'. */
370 timestamp->asvisible.attributes.valuemask = (XpmReturnPixels | XpmReturnExtensions | XpmSize);
371 if (XpmCreatePixmapFromData(dpy, DefaultRootWindow(dpy), clk_xpm, &timestamp->asvisible.pixmap, &timestamp->asvisible.mask, &timestamp->asvisible.attributes) != XpmSuccess)
373 XFreePixmap(dpy, timestamp->asclock.pixmap);
374 XFreePixmap(dpy, timestamp->asclock.mask);
376 return (-1);
379 /* Load the LED digits image. */
380 timestamp->led.attributes.valuemask = (XpmReturnPixels | XpmReturnExtensions | XpmSize);
381 if (XpmCreatePixmapFromData(dpy, DefaultRootWindow(dpy), led_xpm, &timestamp->led.pixmap, &timestamp->led.mask, &timestamp->led.attributes) != XpmSuccess)
383 XFreePixmap(dpy, timestamp->asclock.pixmap);
384 XFreePixmap(dpy, timestamp->asclock.mask);
386 XFreePixmap(dpy, timestamp->asvisible.pixmap);
387 XFreePixmap(dpy, timestamp->asvisible.mask);
389 return (-1);
392 /* Load the month names image. */
393 timestamp->month.attributes.valuemask = (XpmReturnPixels | XpmReturnExtensions | XpmSize);
394 if (XpmCreatePixmapFromData(dpy, DefaultRootWindow(dpy), month_xpm, &timestamp->month.pixmap, &timestamp->month.mask, &timestamp->month.attributes) != XpmSuccess)
396 XFreePixmap(dpy, timestamp->asclock.pixmap);
397 XFreePixmap(dpy, timestamp->asclock.mask);
399 XFreePixmap(dpy, timestamp->asvisible.pixmap);
400 XFreePixmap(dpy, timestamp->asvisible.mask);
402 XFreePixmap(dpy, timestamp->led.pixmap);
403 XFreePixmap(dpy, timestamp->led.mask);
405 return (-1);
408 /* Load the date digits image. */
409 timestamp->date.attributes.valuemask = (XpmReturnPixels | XpmReturnExtensions | XpmSize);
410 if (XpmCreatePixmapFromData(dpy, DefaultRootWindow(dpy), date_xpm, &timestamp->date.pixmap, &timestamp->date.mask, &timestamp->date.attributes) != XpmSuccess)
412 XFreePixmap(dpy, timestamp->asclock.pixmap);
413 XFreePixmap(dpy, timestamp->asclock.mask);
415 XFreePixmap(dpy, timestamp->asvisible.pixmap);
416 XFreePixmap(dpy, timestamp->asvisible.mask);
418 XFreePixmap(dpy, timestamp->led.pixmap);
419 XFreePixmap(dpy, timestamp->led.mask);
421 XFreePixmap(dpy, timestamp->month.pixmap);
422 XFreePixmap(dpy, timestamp->month.mask);
424 return (-1);
427 /* Load the weekday names image. */
428 timestamp->weekday.attributes.valuemask = (XpmReturnPixels | XpmReturnExtensions | XpmSize);
429 if (XpmCreatePixmapFromData(dpy, DefaultRootWindow(dpy), weekday_xpm, &timestamp->weekday.pixmap, &timestamp->weekday.mask, &timestamp->weekday.attributes) != XpmSuccess)
431 XFreePixmap(dpy, timestamp->asclock.pixmap);
432 XFreePixmap(dpy, timestamp->asclock.mask);
434 XFreePixmap(dpy, timestamp->asvisible.pixmap);
435 XFreePixmap(dpy, timestamp->asvisible.mask);
437 XFreePixmap(dpy, timestamp->led.pixmap);
438 XFreePixmap(dpy, timestamp->led.mask);
440 XFreePixmap(dpy, timestamp->month.pixmap);
441 XFreePixmap(dpy, timestamp->month.mask);
443 XFreePixmap(dpy, timestamp->date.pixmap);
444 XFreePixmap(dpy, timestamp->date.mask);
446 return (-1);
449 /* Load the year digits image. */
450 timestamp->year.attributes.valuemask = (XpmReturnPixels | XpmReturnExtensions | XpmSize);
451 if (XpmCreatePixmapFromData(dpy, DefaultRootWindow(dpy), year_xpm, &timestamp->year.pixmap, &timestamp->year.mask, &timestamp->year.attributes) != XpmSuccess)
453 XFreePixmap(dpy, timestamp->asclock.pixmap);
454 XFreePixmap(dpy, timestamp->asclock.mask);
456 XFreePixmap(dpy, timestamp->asvisible.pixmap);
457 XFreePixmap(dpy, timestamp->asvisible.mask);
459 XFreePixmap(dpy, timestamp->led.pixmap);
460 XFreePixmap(dpy, timestamp->led.mask);
462 XFreePixmap(dpy, timestamp->month.pixmap);
463 XFreePixmap(dpy, timestamp->month.mask);
465 XFreePixmap(dpy, timestamp->date.pixmap);
466 XFreePixmap(dpy, timestamp->date.mask);
468 XFreePixmap(dpy, timestamp->weekday.pixmap);
469 XFreePixmap(dpy, timestamp->weekday.mask);
471 return (-1);
474 return (0);
480 /***********************************************************************
481 Name: destroyTimeStamp
482 Purpose: Releases the XPM data and other resources used by
483 TimeStamp.
484 Inputs: timestamp - The TimeStamp.
485 Outputs: None.
486 Returns: Nothing.
487 Status: Finished.
488 Errors: None known.
489 ***********************************************************************/
490 static void destroyTimeStamp(TimeStamp *timestamp)
492 Display *dpy = timestamp->view->screen->display;
494 DEBUG_PRINT("Inside destroyTimeStamp()");
495 if (timestamp->asclock.pixmap != (Pixmap) None)
497 XFreePixmap(dpy, timestamp->asclock.pixmap);
498 DEBUG_PRINT("Released asclock.pixmap");
501 if (timestamp->asclock.mask != (Pixmap) None)
503 XFreePixmap(dpy, timestamp->asclock.mask);
504 DEBUG_PRINT("Released asclock.mask");
507 if (timestamp->led.pixmap != (Pixmap) None)
509 XFreePixmap(dpy, timestamp->led.pixmap);
510 DEBUG_PRINT("Released led.pixmap");
513 if (timestamp->led.mask != (Pixmap) None)
515 XFreePixmap(dpy, timestamp->led.mask);
516 DEBUG_PRINT("Released led.mask");
519 if (timestamp->month.pixmap != (Pixmap) None)
521 XFreePixmap(dpy, timestamp->month.pixmap);
522 DEBUG_PRINT("Released month.pixmap");
525 if (timestamp->month.mask != (Pixmap) None)
527 XFreePixmap(dpy, timestamp->month.mask);
528 DEBUG_PRINT("Released month.mask");
531 if (timestamp->date.pixmap != (Pixmap) None)
533 XFreePixmap(dpy, timestamp->date.pixmap);
534 DEBUG_PRINT("Released date.pixmap");
537 if (timestamp->date.mask != (Pixmap) None)
539 XFreePixmap(dpy, timestamp->date.mask);
540 DEBUG_PRINT("Released date.mask");
543 if (timestamp->weekday.pixmap != (Pixmap) None)
545 XFreePixmap(dpy, timestamp->weekday.pixmap);
546 DEBUG_PRINT("Released weekday.pixmap");
549 if (timestamp->weekday.mask != (Pixmap) None)
551 XFreePixmap(dpy, timestamp->weekday.mask);
552 DEBUG_PRINT("Released weekday.mask");
555 if (timestamp->asvisible.pixmap != (Pixmap) None)
557 XFreePixmap(dpy, timestamp->asvisible.pixmap);
558 DEBUG_PRINT("Released asvisible.pixmap");
561 if (timestamp->asvisible.mask != (Pixmap) None)
563 XFreePixmap(dpy, timestamp->asvisible.mask);
564 DEBUG_PRINT("Released asvisible.mask");
567 if (timestamp->year.pixmap != (Pixmap) None)
569 XFreePixmap(dpy, timestamp->year.pixmap);
570 DEBUG_PRINT("Released year.pixmap");
573 if (timestamp->year.mask != (Pixmap) None)
575 XFreePixmap(dpy, timestamp->year.mask);
576 DEBUG_PRINT("Released year.mask");
578 DEBUG_PRINT("Released XPMs");
580 free((void *) timestamp);
581 DEBUG_PRINT("Released TimeStamp");
587 /***********************************************************************
588 Name: handleEvents
589 Purpose: Handles events delivered to the TimeStamp widget.
590 Inputs: event - The XEvent.
591 data - Pointer to the TimeStamp structure for this event.
592 Outputs: None.
593 Returns: Nothing.
594 Status: Finished.
595 Errors: None known.
596 ***********************************************************************/
597 static void handleEvents(XEvent *event, void *data)
599 TimeStamp *timestamp = (TimeStamp *) data;
601 switch (event->type)
603 case Expose:
604 DEBUG_PRINT("Caught an Expose event");
605 if (event->xexpose.count)
607 break;
610 if (timestamp->view->flags.realized)
612 /* We need to repaint. */
613 paintTimeStamp(timestamp);
615 break;
617 case DestroyNotify:
618 DEBUG_PRINT("Caught a DestroyNotify event");
619 destroyTimeStamp(timestamp);
620 break;
627 /***********************************************************************
628 Name: paintTimeStamp
629 Purpose: Handles repainting of the widget.
630 Inputs: timestamp - The TimeStamp.
631 Outputs: None.
632 Returns: Nothing.
633 Status: Finished.
634 Errors: None known.
635 ***********************************************************************/
636 static void paintTimeStamp(TimeStamp *timestamp)
638 Display *dpy = timestamp->view->screen->display;
639 W_Screen *scr = timestamp->view->screen;
640 int offset = 0;
642 if (!(timestamp->view->flags.realized))
644 /* Widget is not realized yet so just return. */
645 return;
648 DEBUG_PRINT("Inside paintTimeStamp()");
649 /* Does the image need re-creating? */
650 if (timestamp->flags.damaged)
652 /* Yes - So re-create it now. */
653 RenderASClock(timestamp);
655 /* Now turn new image into a WMPixmap ready for us to paint. */
656 if (!(timestamp->image = WMCreatePixmapFromXPixmaps(scr,
657 timestamp->result->pixmap,
658 timestamp->result->mask,
659 TIMESTAMP_MIN_WIDTH,
660 TIMESTAMP_MIN_HEIGHT,
661 DefaultDepth(dpy, DefaultScreen(dpy)))))
663 /* Error whilst trying to convert. */
664 wfatal("Unable to Create Clock Image");
666 DEBUG_PRINT("Created new image");
669 /* Paint the image. */
670 if (timestamp->image)
672 W_PaintTextAndImage(timestamp->view,
673 False,
674 timestamp->color,
675 scr->normalFont,
676 WRFlat,
677 NULL,
678 WACenter,
679 timestamp->image,
680 WIPImageOnly,
681 timestamp->color,
682 offset);
683 DEBUG_PRINT("Painted image");
686 /* Reset 'damaged' flag back to 0. */
687 timestamp->flags.damaged = 0;
693 /***********************************************************************
694 Name: setBackgroundColor
695 Purpose: Sets the background colour of the widget.
696 Inputs: widget - A pointer to the TimeStamp.
697 color - The new colour.
698 Outputs: None.
699 Returns: Nothing.
700 Status: Finished.
701 Errors: None known.
702 ***********************************************************************/
703 static void setBackgroundColor(WMWidget *widget, WMColor *color)
705 TimeStamp *timestamp = (TimeStamp *) widget;
707 WMSetColorInGC(color, timestamp->gc);
709 W_SetViewBackgroundColor(timestamp->view, color);
711 if (timestamp->view->flags.realized)
713 paintTimeStamp(timestamp);
720 /***********************************************************************
721 Name: resizeTimeStamp
722 Purpose: Resizes the widget.
723 Inputs: widget - A pointer to the TimeStamp.
724 width - The new width.
725 height - The new height.
726 Outputs: None.
727 Returns: Nothing.
728 Status: Finished.
729 Errors: None known.
730 ***********************************************************************/
731 static void willResizeTimeStamp(W_ViewDelegate *self, WMView *view,
732 unsigned int *width, unsigned int *height)
734 TimeStamp *timestamp = (TimeStamp *) view->self;
736 /* Check the width. */
737 /* if (*width < TIMESTAMP_MIN_WIDTH) */
738 /* { */
739 /* *width = TIMESTAMP_MIN_WIDTH; */
740 /* } */
742 /* Check the height. */
743 /* if (*height < TIMESTAMP_MIN_HEIGHT) */
744 /* { */
745 /* *height = TIMESTAMP_MIN_HEIGHT; */
746 /* } */
748 /* Resize the widget. */
749 /* W_ResizeView(timestamp->view, *width, *height); */
750 if (timestamp->view->flags.realized)
752 /* Redraw the widget. */
753 paintTimeStamp(timestamp);
757 /* static void resizeTimeStamp(WMWidget *widget, unsigned int width, unsigned int height) */
758 /* { */
759 /* TimeStamp *timestamp = (TimeStamp *) widget; */
761 /* Check the width. */
762 /* if (width < TIMESTAMP_MIN_WIDTH) */
763 /* { */
764 /* width = TIMESTAMP_MIN_WIDTH; */
765 /* } */
767 /* Check the height. */
768 /* if (height < TIMESTAMP_MIN_HEIGHT) */
769 /* { */
770 /* height = TIMESTAMP_MIN_HEIGHT; */
771 /* } */
773 /* Resize the widget. */
774 /* W_ResizeView(timestamp->view, width, height); */
775 /* if (timestamp->view->flags.realized) */
776 /* { */
777 /* Redraw the widget. */
778 /* paintTimeStamp(timestamp); */
779 /* } */
780 /* } */
785 /***********************************************************************
786 Name: SetTimeStampBlank
787 Purpose: Sets the TimeStamp to a blank display.
788 Inputs: timestamp - The TimeStamp.
789 blank - Toggle flag.
790 Outputs: None.
791 Returns: Nothing.
792 Status: Finished.
793 Errors: None known.
794 ***********************************************************************/
795 void SetTimeStampBlank(TimeStamp *timestamp, Bool blank)
797 unsigned int Blank;
799 CHECK_CLASS(timestamp, timeStampWidgetClass);
801 Blank = (blank == True) ? 1 : 0;
803 if (Blank == timestamp->flags.blank)
805 /* Status is already set, so return. */
806 return;
809 timestamp->flags.blank = Blank;
810 timestamp->flags.damaged = 1;
812 if (timestamp->view->flags.realized)
814 paintTimeStamp(timestamp);
821 /***********************************************************************
822 Name: SetTimeStampWithTimeT
823 Purpose: Sets the TimeStamp using a time_t value.
824 Inputs: timestamp - The TimeStamp.
825 time - The time value.
826 Outputs: None.
827 Returns: Nothing.
828 Status: Finished.
829 Errors: None known.
830 ***********************************************************************/
831 void SetTimeStampWithTimeT(TimeStamp *timestamp, time_t time)
833 CHECK_CLASS(timestamp, timeStampWidgetClass);
835 timestamp->time = time;
836 timestamp->flags.damaged = 1;
838 if (timestamp->view->flags.realized)
840 paintTimeStamp(timestamp);
847 /***********************************************************************
848 Name: SetTimeStampWithTimeTM
849 Purpose: Sets the TimeStamp using a 'struct tm' value.
850 Inputs: timestamp - The TimeStamp.
851 time - The time value.
852 Outputs: None.
853 Returns: Nothing.
854 Status: Finished.
855 Errors: None known.
856 ***********************************************************************/
857 void SetTimeStampWithTimeTM(TimeStamp *timestamp, struct tm *time)
859 CHECK_CLASS(timestamp, timeStampWidgetClass);
861 timestamp->time = mktime(time);
862 timestamp->flags.damaged = 1;
864 if (timestamp->view->flags.realized)
866 paintTimeStamp(timestamp);
873 /******************************************************************************
874 Name: SetTwentyFour
875 Purpose: Sets the TimeStamp into 24 or 12 hour mode.
876 Inputs: timestamp - The TimeStamp.
877 twentyfour - Toggle flag.
878 Outputs: None.
879 Returns: Nothing.
880 Status: Finished.
881 Errors: None known.
882 ******************************************************************************/
883 void SetTwentyFour(TimeStamp *timestamp, Bool twentyfour)
885 CHECK_CLASS(timestamp, timeStampWidgetClass);
887 timestamp->flags.showAMPM = (twentyfour == True) ? 0 : 1;
888 /* Re-calculate LED positions. */
889 InitClockResources(timestamp);
890 timestamp->flags.damaged = 1;
892 if (timestamp->view->flags.realized)
894 paintTimeStamp(timestamp);
901 /***********************************************************************
902 Name: ASTwelve
903 Purpose: Draws the TimeStamp LED in 12 hour mode.
904 Inputs: timestamp - The TimeStamp.
905 clk - The time to set.
906 Outputs: None.
907 Returns: Nothing.
908 Status: Finished.
909 Errors: None known.
910 ***********************************************************************/
911 static void ASTwelve(TimeStamp *timestamp, struct tm *clk)
913 Display *dpy = timestamp->view->screen->display;
914 int thishour;
916 DEBUG_PRINT("Inside ASTwelve()");
917 /* Convert hour to 12 hour format. */
918 thishour = clk->tm_hour % 12;
919 if (!thishour)
921 thishour = 12;
924 if (clk->tm_hour >= 12)
926 /* PM */
927 XCopyArea(dpy,
928 timestamp->led.pixmap, /* src */
929 timestamp->asvisible.pixmap, /* dest */
930 timestamp->gc, /* use GC */
931 107, 5, /* src_x, src_y */
932 11, 6, /* width, height */
933 posx[5], posy[0] + 5); /* dest_x, dest_y */
935 else
937 /* AM */
938 XCopyArea(dpy,
939 timestamp->led.pixmap,
940 timestamp->asvisible.pixmap,
941 timestamp->gc,
942 94, 5,
943 12, 6,
944 posx[5], posy[0] + 5);
947 /* Do we need a leading '1' digit for the hour? */
948 if (thishour > 9)
950 /* Yes. */
951 XCopyArea(dpy,
952 timestamp->led.pixmap,
953 timestamp->asvisible.pixmap,
954 timestamp->gc,
955 13, 0,
956 5, 11,
957 posx[0], posy[0]);
960 /* Second digit of the hour. */
961 XCopyArea(dpy,
962 timestamp->led.pixmap,
963 timestamp->asvisible.pixmap,
964 timestamp->gc,
965 9 * (thishour % 10), 0,
966 9, 11,
967 posx[1], posy[0]);
969 /* Minute, drawn first, so am/pm won't be overwritten. */
970 XCopyArea(dpy,
971 timestamp->led.pixmap,
972 timestamp->asvisible.pixmap,
973 timestamp->gc,
974 9 * (clk->tm_min / 10), 0,
975 9, 11,
976 posx[3], posy[0]);
978 XCopyArea(dpy,
979 timestamp->led.pixmap,
980 timestamp->asvisible.pixmap,
981 timestamp->gc,
982 9 * (clk->tm_min % 10), 0,
983 9, 11,
984 posx[4], posy[0]);
990 /***********************************************************************
991 Name: ASTwentyFour
992 Purpose: Draws the TimeStamp LED in 24 hour mode.
993 Inputs: timestamp - The TimeStamp.
994 clk - The time to set.
995 Outputs: None.
996 Returns: Nothing.
997 Status: Finished.
998 Errors: None known.
999 ***********************************************************************/
1000 static void ASTwentyFour(TimeStamp *timestamp, struct tm *clk)
1002 Display *dpy = timestamp->view->screen->display;
1004 DEBUG_PRINT("Inside ASTwentyFour()");
1006 /* Draw the first digit for the hour. */
1007 XCopyArea(dpy,
1008 timestamp->led.pixmap,
1009 timestamp->asvisible.pixmap,
1010 timestamp->gc,
1011 9 * (clk->tm_hour / 10), 0,
1012 9, 11,
1013 posx[0], posy[0]);
1015 /* Draw the second digit for the hour. */
1016 XCopyArea(dpy,
1017 timestamp->led.pixmap,
1018 timestamp->asvisible.pixmap,
1019 timestamp->gc,
1020 9 * (clk->tm_hour % 10), 0,
1021 9, 11,
1022 posx[1], posy[0]);
1024 /* Draw the first digit for the minute. */
1025 XCopyArea(dpy,
1026 timestamp->led.pixmap,
1027 timestamp->asvisible.pixmap,
1028 timestamp->gc,
1029 9 * (clk->tm_min / 10), 0,
1030 9, 11,
1031 posx[3], posy[0]);
1033 /* Draw the second digit for the minute. */
1034 XCopyArea(dpy,
1035 timestamp->led.pixmap,
1036 timestamp->asvisible.pixmap,
1037 timestamp->gc,
1038 9 * (clk->tm_min % 10), 0,
1039 9, 11,
1040 posx[4], posy[0]);
1046 /***********************************************************************
1047 Name: RenderASClock
1048 Purpose: Draws the TimeStamp widget.
1049 Inputs: timestamp - The TimeStamp.
1050 Outputs: None.
1051 Returns: Nothing.
1052 Status: Finished.
1053 Errors: None known.
1054 ***********************************************************************/
1055 static void RenderASClock(TimeStamp *timestamp)
1057 Display *dpy = timestamp->view->screen->display;
1058 struct tm *clk;
1059 int year;
1060 char yearStr[5];
1061 int digit, i;
1062 int yearWidth, yearOffset;
1065 DEBUG_PRINT("Inside RenderASClock()");
1067 timestamp->result = &timestamp->asvisible;
1069 clk = localtime(&timestamp->time);
1071 /* Copy the calendar background image. */
1072 XCopyArea(dpy,
1073 timestamp->asclock.pixmap,
1074 timestamp->asvisible.pixmap,
1075 timestamp->gc,
1076 0, 0,
1077 TIMESTAMP_MIN_WIDTH, TIMESTAMP_MIN_HEIGHT,
1078 0, 0);
1080 /* If we are in 'blank' mode then that's all we have to do. */
1081 if (timestamp->flags.blank)
1083 return;
1086 /* Draw LED in 12 or 24 hour mode as appropriate. */
1087 if (timestamp->flags.showAMPM)
1089 ASTwelve(timestamp, clk);
1091 else
1093 ASTwentyFour(timestamp, clk);
1096 /* Month. */
1097 XCopyArea(dpy,
1098 timestamp->month.pixmap,
1099 timestamp->asvisible.pixmap,
1100 timestamp->gc,
1101 0, 6 * (clk->tm_mon),
1102 22, 6,
1103 posx[10], posy[3]);
1105 /* Date. */
1106 if (clk->tm_mday > 9)
1108 /* We need two digits for the date. */
1109 XCopyArea(dpy,
1110 timestamp->date.pixmap,
1111 timestamp->asvisible.pixmap,
1112 timestamp->gc,
1113 9 * ((clk->tm_mday / 10 + 9) % 10), 0,
1114 9, 13,
1115 posx[7], posy[2]);
1117 XCopyArea(dpy,
1118 timestamp->date.pixmap,
1119 timestamp->asvisible.pixmap,
1120 timestamp->gc,
1121 9 * ((clk->tm_mday % 10 + 9) % 10), 0,
1122 9, 13,
1123 posx[9], posy[2]);
1125 else
1127 /* Single digit date. */
1128 XCopyArea(dpy,
1129 timestamp->date.pixmap,
1130 timestamp->asvisible.pixmap,
1131 timestamp->gc,
1132 9 * (clk->tm_mday - 1), 0,
1133 9, 13,
1134 posx[8], posy[2]);
1137 /* WeekDay. */
1138 XCopyArea(dpy,
1139 timestamp->weekday.pixmap,
1140 timestamp->asvisible.pixmap,
1141 timestamp->gc,
1142 0, 6 * ((clk->tm_wday + 6) % 7),
1143 21, 7,
1144 posx[6], posy[1]);
1146 /* Copy LED colon. */
1147 XCopyArea(dpy,
1148 timestamp->led.pixmap,
1149 timestamp->asvisible.pixmap,
1150 timestamp->gc,
1151 90, 0,
1152 3, 11,
1153 posx[2], posy[0]);
1155 /* Year. */
1156 year = 1900 + clk->tm_year;
1157 if (year < 0 || year > 9999)
1159 wwarning("Year field out of range for TimeStamp widget - %d.\n", year);
1161 else
1163 /* Create a string of the year. */
1164 sprintf(yearStr, "%04d", year);
1166 /* Calculate the width of the year label in pixels. */
1167 yearWidth = 0;
1168 for (i = 0; i < 4; i++)
1170 digit = yearStr[i] - '0';
1171 yearWidth += year_width[digit];
1173 /* Add on 3 pixels for the gaps in between the digits. */
1174 yearWidth += 3;
1176 /* Draw the four digits. */
1177 yearOffset = 0;
1178 for (i = 0; i < 4; i++)
1180 digit = yearStr[i] - '0';
1181 XCopyArea(dpy,
1182 timestamp->year.pixmap, /* src */
1183 timestamp->asvisible.pixmap, /* dest */
1184 timestamp->gc, /* use GC */
1185 year_pos[digit], 0, /* src_x, src_y */
1186 year_width[digit], 5, /* width, height */
1187 ((TIMESTAMP_MIN_WIDTH-yearWidth)/2)+yearOffset, 63); /* dest_x, dest_y */
1188 yearOffset += (year_width[digit]+1);
1194 /* End Of File - timestampWidget.c ************************************/