Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / lib / DtWidget / Control.c
1 /* $TOG: Control.c /main/18 1997/04/22 11:40:14 mgreess $
2  *
3  * (c) Copyright 1996 Digital Equipment Corporation.
4  * (c) Copyright 1992,1996 Hewlett-Packard Company.
5  * (c) Copyright 1996 International Business Machines Corp.
6  * (c) Copyright 1996 Sun Microsystems, Inc.
7  * (c) Copyright 1996 Novell, Inc. 
8  * (c) Copyright 1996 FUJITSU LIMITED.
9  * (c) Copyright 1996 Hitachi.
10  */
11
12 /**---------------------------------------------------------------------
13 ***     
14 ***     file:           Control.c
15 ***
16 ***     project:        MotifPlus Widgets
17 ***
18 ***     description:    Source code for DtControl class.
19 ***     
20 ***-------------------------------------------------------------------*/
21
22
23 /*-------------------------------------------------------------
24 **      Include Files
25 */
26
27 #include <stdio.h>
28 #ifdef __apollo
29 #include <sys/types.h>           /* needed for sys/stat.h on bsd4.3 */
30 #else
31 #include <stdlib.h>
32 #endif
33 #include <sys/stat.h>
34 #define X_INCLUDE_STRING_H
35 #define X_INCLUDE_TIME_H
36 #define XOS_USE_XT_LOCKING
37 #include <X11/Xos_r.h>
38 #include <Xm/GadgetP.h>
39 #include <Xm/DrawP.h>
40 #include <Dt/Control.h>
41 #include <Dt/ControlP.h>
42 #include <Xm/ManagerP.h>
43 #include <Dt/MacrosP.h>
44 #include <langinfo.h>
45 #include "DtWidgetI.h"
46
47
48 /********    Public Function Declarations    ********/
49
50 extern Widget _DtCreateControl( 
51                         Widget parent,
52                         String name,
53                         ArgList arglist,
54                         int argcount) ;
55
56 /********    End Public Function Declarations    ********/
57
58 /********    Static Function Declarations    ********/
59
60 static void ClickTimeout( 
61                         XtPointer client_data,
62                         XtIntervalId *id) ;
63 static void BusyTimeout( 
64                         XtPointer client_data,
65                         XtIntervalId *id) ;
66 static void DateTimeout( 
67                         XtPointer client_data,
68                         XtIntervalId *id) ;
69 static void PushAnimationTimeout( 
70                         XtPointer client_data,
71                         XtIntervalId *id) ;
72 static void DropAnimationTimeout( 
73                         XtPointer client_data,
74                         XtIntervalId *id) ;
75 static void FileCheckTimeout( 
76                         XtPointer client_data,
77                         XtIntervalId *id) ;
78 static void CheckFile( 
79                         DtControlGadget g) ;
80 static void ClassInitialize( void ) ;
81 static void ClassPartInitialize(
82                         WidgetClass cl) ;
83
84 static void Destroy (Widget);
85
86 static void Initialize( 
87                         Widget request_w,
88                         Widget new_w) ;
89 static Boolean SetValues(
90                         Widget current_w,
91                         Widget request_w,
92                         Widget new_w) ;
93 static void GetSize( 
94                         DtControlGadget g,
95                         Dimension *w,
96                         Dimension *h) ;
97 static void GetPositions( 
98                         DtControlGadget g,
99                         Position w,
100                         Position h,
101                         Dimension h_t,
102                         Dimension s_t,
103                         Position *pix_x,
104                         Position *pix_y,
105                         Position *str_x,
106                         Position *str_y) ;
107 static void Draw( 
108                         DtControlGadget g,
109                         Drawable drawable,
110                         Position x,
111                         Position y,
112                         Dimension w,
113                         Dimension h,
114                         Dimension h_t,
115                         Dimension s_t,
116                         unsigned char s_type,
117                         unsigned char fill_mode) ;
118 static void CallCallback( 
119                         DtControlGadget g,
120                         XtCallbackList cb,
121                         int reason,
122                         XEvent *event) ;
123 static void UpdateGCs( 
124                         DtControlGadget g) ;
125 static void ReplaceJPDate(
126                         char *date,
127                         char *jpstr,
128                         int wday) ;
129
130 /********    End Static Function Declarations    ********/
131
132
133 /*-------------------------------------------------------------
134 **      Public Interface
135 **-------------------------------------------------------------
136 */
137
138 WidgetClass     dtControlGadgetClass;
139
140
141 #define UNSPECIFIED_DIMENSION   9999
142 #define UNSPECIFIED_CHAR        255
143
144 #ifdef _SUN_OS
145 static const char _DtMsgIndicator_0000[] = "/var/mail/";
146 #elif defined(__osf__)
147 static const char _DtMsgIndicator_0000[] = "/usr/spool/mail/";
148 #else
149 static const char _DtMsgIndicator_0000[] = "/usr/mail/";
150 #endif
151
152 #define MAIL_DIR        _DtMsgIndicator_0000
153 #define Min(x, y)    (((x) < (y)) ? (x) : (y))
154 #define Max(x, y)    (((x) > (y)) ? (x) : (y))
155
156 #define G_Width(r)              (r -> rectangle.width)
157 #define G_Height(r)             (r -> rectangle.height)
158 \f
159 /*-------------------------------------------------------------
160 **      Resource List
161 */
162 #define R_Offset(field) \
163         XtOffset (DtControlGadget, control.field)
164 static XtResource resources[] = 
165 {
166         {
167                 "_do_update",
168                 XmCBoolean, XmRBoolean, sizeof (Boolean),
169                 R_Offset (_do_update), XmRImmediate, (XtPointer) FALSE
170         },
171         {
172                 XmNuseEmbossedText,
173                 XmCBoolean, XmRBoolean, sizeof (Boolean),
174                 R_Offset (use_embossed_text), XmRImmediate, (XtPointer) TRUE
175         },
176         {
177                 XmNpushFunction,
178                 XmCPushFunction, XmRFunction, sizeof (XtPointer),
179                 R_Offset (push_function),
180                 XmRImmediate, (XtPointer) NULL
181         },
182         {
183                 XmNpushArgument,
184                 XmCPushArgument, XmRPointer, sizeof (XtPointer),
185                 R_Offset (push_argument),
186                 XmRImmediate, (XtPointer) NULL
187         },
188         {
189                 XmNdropAction,
190                 XmCDropAction, XmRString, sizeof (String),
191                 R_Offset (drop_action),
192                 XmRImmediate, (XtPointer) NULL
193         },
194         {
195                 "pushAction",
196                 "PushAction", XmRString, sizeof (String),
197                 R_Offset (push_action),
198                 XmRImmediate, (XtPointer) NULL
199         },
200         {
201                 XmNformat,
202                 XmCFormat, XmRString, sizeof (String),
203                 R_Offset (format),
204                 XmRImmediate, (XtPointer) "%b%n%e"
205         },
206         {
207                 XmNformatJP,
208                 XmCFormatJP, XmRString, sizeof (String),
209                 R_Offset (format_jp),
210                 XmRImmediate, (XtPointer) NULL
211         },
212         {
213                 XmNsubpanel,
214                 XmCSubpanel, XmRWidget, sizeof (Widget),
215                 R_Offset (subpanel),
216                 XmRImmediate, (XtPointer) NULL
217         },
218         {
219                 XmNcontrolType,
220                 XmCControlType, XmRControlType, sizeof (unsigned char),
221                 R_Offset (control_type),
222                 XmRImmediate, (XtPointer) XmCONTROL_NONE
223         },
224         {
225                 XmNfileName,
226                 XmCString, XmRString, sizeof (XmString),
227                 R_Offset (file_name), XmRImmediate, (XtPointer) NULL
228         },
229         {
230                 XmNalternateImage,
231                 XmCAlternateImage, XmRString, sizeof (String),
232                 R_Offset (alt_image), XmRImmediate, (XtPointer) NULL
233         },
234         {
235                 XmNchime,
236                 XmCBoolean, XmRBoolean, sizeof (Boolean),
237                 R_Offset (chime), XmRImmediate, (XtPointer) FALSE
238         },
239         {
240                 XmNclientTimeoutInterval,
241                 XmCInterval, XmRInt, sizeof (int),
242                 R_Offset (max_blink_time), XmRImmediate, (XtPointer) 10000
243         },
244         {
245                 XmNwaitingBlinkRate,
246                 XmCInterval, XmRInt, sizeof (int),
247                 R_Offset (blink_time), XmRImmediate, (XtPointer) 500
248         },
249         {
250                 XmNmonitorTime,
251                 XmCInterval, XmRInt, sizeof (int),
252                 R_Offset (monitor_time), XmRImmediate, (XtPointer) 30000
253         },
254         {
255                 XmNpushButtonClickTime,
256                 XmCInterval, XmRInt, sizeof (int),
257                 R_Offset (click_time), 
258                 XmRImmediate, (XtPointer) 1000
259         },
260         {
261                 XmNuseLabelAdjustment,
262                 XmCBoolean, XmRBoolean, sizeof (Boolean),
263                 R_Offset (use_label_adj), XmRImmediate, (XtPointer) TRUE
264         }
265 };
266 #undef  R_Offset
267
268
269 static XmBaseClassExtRec       controlBaseClassExtRec = {
270     NULL,                                     /* Next extension       */
271     NULLQUARK,                                /* record type XmQmotif */
272     XmBaseClassExtVersion,                    /* version              */
273     sizeof(XmBaseClassExtRec),                /* size                 */
274     XmInheritInitializePrehook,               /* initialize prehook   */
275     XmInheritSetValuesPrehook,                /* set_values prehook   */
276     XmInheritInitializePosthook,              /* initialize posthook  */
277     XmInheritSetValuesPosthook,               /* set_values posthook  */
278     (WidgetClass)&dtControlCacheObjClassRec,  /* secondary class      */
279     XmInheritSecObjectCreate,                 /* creation proc        */
280     XmInheritGetSecResData,                   /* getSecResData        */
281     {0},                                      /* fast subclass        */
282     XmInheritGetValuesPrehook,                /* get_values prehook   */
283     XmInheritGetValuesPosthook,               /* get_values posthook  */
284     NULL,                                     /* classPartInitPrehook */
285     NULL,                                     /* classPartInitPosthook*/
286     NULL,                                     /* ext_resources        */
287     NULL,                                     /* compiled_ext_resources*/
288     0,                                        /* num_ext_resources    */
289     FALSE,                                    /* use_sub_resources    */
290     XmInheritWidgetNavigable,                 /* widgetNavigable      */
291     XmInheritFocusChange,                     /* focusChange          */
292 };
293
294 /* ext rec static initialization */
295 externaldef (xmcontrolcacheobjclassrec)
296 DtControlCacheObjClassRec dtControlCacheObjClassRec =
297 {
298   {
299       /* superclass         */    (WidgetClass) &xmExtClassRec,
300       /* class_name         */    "DtControl",
301       /* widget_size        */    sizeof(DtControlCacheObjRec),
302       /* class_initialize   */    NULL,
303       /* chained class init */    NULL,
304       /* class_inited       */    False,
305       /* initialize         */    NULL,
306       /* initialize hook    */    NULL,
307       /* realize            */    NULL,
308       /* actions            */    NULL,
309       /* num_actions        */    0,
310       /* resources          */    NULL,
311       /* num_resources      */    0,
312       /* xrm_class          */    NULLQUARK,
313       /* compress_motion    */    False,
314       /* compress_exposure  */    False,
315       /* compress enter/exit*/    False,
316       /* visible_interest   */    False,
317       /* destroy            */    NULL,
318       /* resize             */    NULL,
319       /* expose             */    NULL,
320       /* set_values         */    NULL,
321       /* set values hook    */    NULL,
322       /* set values almost  */    NULL,
323       /* get values hook    */    NULL,
324       /* accept_focus       */    NULL,
325       /* version            */    XtVersion,
326       /* callback offsetlst */    NULL,
327       /* default trans      */    NULL,
328       /* query geo proc     */    NULL,
329       /* display accelerator*/    NULL,
330       /* extension record   */    (XtPointer)NULL,
331    },
332
333    {
334       /* synthetic resources */   NULL,
335       /* num_syn_resources   */   0,
336       /* extension           */   NULL,
337    }
338 };
339         
340 \f
341 /*-------------------------------------------------------------
342 **      Class Record
343 */
344 DtControlClassRec dtControlClassRec =
345 {
346         /*      Core Part
347         */
348         {       
349                 (WidgetClass) &dtIconClassRec, /* superclass            */
350                 "Control",                      /* class_name           */
351                 sizeof (DtControlRec),          /* widget_size          */
352                 ClassInitialize,                /* class_initialize     */
353                 ClassPartInitialize,            /* class_part_initialize*/
354                 False,                          /* class_inited         */
355                 (XtInitProc) Initialize,        /* initialize           */
356                 NULL,                           /* initialize_hook      */
357                 NULL,                           /* realize              */
358                 NULL,                           /* actions              */
359                 0,                              /* num_actions          */
360                 resources,                      /* resources            */
361                 XtNumber (resources),           /* num_resources        */
362
363                 NULLQUARK,                      /* xrm_class            */
364                 True,                           /* compress_motion      */
365                 True,                           /* compress_exposure    */
366                 True,                           /* compress_enterleave  */
367                 False,                          /* visible_interest     */      
368                 Destroy,                        /* destroy              */      
369                 XtInheritResize,                /* resize               */
370                 XtInheritExpose,                /* expose               */      
371                 (XtSetValuesFunc)SetValues,     /* set_values           */      
372                 NULL,                           /* set_values_hook      */
373                 XtInheritSetValuesAlmost,       /* set_values_almost    */
374                 NULL,                           /* get_values_hook      */
375                 NULL,                           /* accept_focus         */      
376                 XtVersion,                      /* version              */
377                 NULL,                           /* callback private     */
378                 NULL,                           /* tm_table             */
379                 NULL,                           /* query_geometry       */
380                 NULL,                           /* display_accelerator  */
381                 (XtPointer)&controlBaseClassExtRec, /* extension        */
382
383         },
384
385         /*      XmGadget Part
386         */
387         {
388 (XtWidgetProc)  XmInheritBorderHighlight,       /* border_highlight     */
389 (XtWidgetProc)  XmInheritBorderUnhighlight,     /* border_unhighlight   */
390 (XtActionProc)  XmInheritArmAndActivate,        /* arm_and_activate     */
391 (XmWidgetDispatchProc)  XmInheritInputDispatch, /* input_dispatch       */
392 (XmVisualChangeProc)    XmInheritVisualChange,  /* visual_change        */
393                 NULL,                           /* get_resources        */
394                 0,                              /* num_get_resources    */
395                 XmInheritCachePart,             /* class_cache_part     */
396                 NULL,                           /* extension            */
397         },
398
399         /*      DtIcon Part
400         */
401         {
402 (GetSizeProc)   GetSize,                        /* get_size             */
403 (GetPositionProc)       GetPositions,                   /* get_positions        */
404 (DrawProc)      Draw,                           /* draw                 */
405 (CallCallbackProc)      CallCallback,                   /* call_callback        */
406 (UpdateGCsProc) UpdateGCs,                      /* update_gcs           */
407                 True,                           /* optimize_redraw      */
408                 NULL,                           /* class_cache_part     */
409                 NULL,                           /* extension            */
410         },
411
412         /*      DtControl Part
413         */
414         {
415                 NULL,                           /* class_cache_part     */
416                 NULL,                           /* extension            */
417         }
418 };
419
420
421 WidgetClass dtControlGadgetClass = (WidgetClass) &dtControlClassRec;
422
423
424 \f
425 /*-------------------------------------------------------------
426 **      Private Functions
427 **-------------------------------------------------------------
428 */
429
430 /*-------------------------------------------------------------
431 **      FileCheckTimeout
432 **              Check for change in file, reset timeout.
433 **              An XtTimerCallbackProc.
434 */
435 static void
436 FileCheckTimeout(
437         XtPointer client_data,
438         XtIntervalId *id )
439 {
440         DtControlGadget g = (DtControlGadget) client_data;
441         XtAppContext            app_context =
442                         XtWidgetToApplicationContext ((Widget) g);
443
444         CheckFile (g);
445
446         G_MonitorTimer (g) = 
447                 XtAppAddTimeOut (app_context, G_MonitorTime (g),
448                                 FileCheckTimeout, (XtPointer) g);
449 }
450
451
452 /*-------------------------------------------------------------
453 **      CheckFile
454 **              Check for change in file size
455 */
456 static void 
457 CheckFile(
458         DtControlGadget g )
459 {
460   Boolean               result;
461   Boolean               file_changed;
462   long          file_size = 0;
463   struct stat   stat_buf;
464   
465   if (stat (G_FileName (g), &stat_buf) == 0)
466     {
467       file_size = stat_buf.st_size;
468     }
469   
470   switch (G_ControlType (g))
471     {
472     case XmCONTROL_MONITOR:
473       file_changed = (file_size == 0) ? False : True;
474       break;
475
476     case XmCONTROL_MAIL:
477       if (file_size == 0)
478         file_changed = False;
479       else if (stat_buf.st_atime > stat_buf.st_mtime)
480         file_changed = False;
481       else if (file_size == G_FileSize (g))
482         file_changed = G_FileChanged (g);
483       else if (file_size > G_FileSize (g))
484         file_changed = True;
485       else
486         file_changed = False;
487       break;
488     }
489   
490   G_FileSize (g) = file_size;
491   if (file_changed != G_FileChanged (g))
492     {
493       XtExposeProc expose;
494       CallCallbackProc call_callback;
495
496       _DtProcessLock();
497       expose = XtCoreProc((Widget)g, expose);
498       call_callback = C_CallCallback(XtClass(g));
499       _DtProcessUnlock();
500
501       G_FileChanged (g) = file_changed;
502       (*call_callback) ((DtIconGadget) g, G_Callback (g), XmCR_MONITOR, NULL);
503       (*expose)((Widget)g, NULL, NULL);
504       XmUpdateDisplay ((Widget) g);
505     }
506 }
507
508
509 \f
510 /*-------------------------------------------------------------
511 **      ClickTimeout
512 **              An XtTimerCallbackProc.
513 **              
514 */
515 static void
516 ClickTimeout(
517         XtPointer client_data,
518         XtIntervalId *id )
519 {
520   DtControlGadget       g =     (DtControlGadget) client_data;
521
522   G_ClickTimer (g) = 0;
523 }
524
525
526 \f
527 /*-------------------------------------------------------------
528 **      BusyTimeout
529 **              Switch pixmap.
530 **              An XtTimerCallbackProc.
531 */
532 static void
533 BusyTimeout(
534         XtPointer client_data,
535         XtIntervalId *id )
536 {
537   DtControlGadget       g =     (DtControlGadget) client_data;
538   XtAppContext          app_context = XtWidgetToApplicationContext((Widget) g);
539   XtExposeProc          expose;
540   CallCallbackProc      call_callback;
541   
542   _DtProcessLock();
543   expose = XtCoreProc((Widget)g, expose);
544   call_callback = C_CallCallback(XtClass((Widget)g));
545   _DtProcessUnlock();
546   
547   if ((G_Busy (g) > 0) && (G_BlinkElapsed (g) < G_MaxBlinkTime (g)))
548     {
549       G_Set (g) = ! G_Set (g);
550       G_BlinkTimer (g) = 
551         XtAppAddTimeOut (app_context, G_BlinkTime (g),
552                          BusyTimeout, (XtPointer) g);
553       G_BlinkElapsed (g) += G_BlinkTime (g);
554     }
555   else
556     {
557       G_Set (g) = False;
558       G_BlinkTimer (g) = NULL;
559       G_BlinkElapsed (g) = 0;
560       G_Busy (g) = 0;
561       (*call_callback) ((DtIconGadget) g, G_Callback (g), XmCR_BUSY_STOP, NULL);
562     }
563   
564   (*expose) ((Widget) g, NULL, False);
565 }
566
567
568 \f
569 /*-------------------------------------------------------------
570 **      DateTimeout
571 **              Update date strings.
572 **              An XtTimerCallbackProc.
573 */
574 static void
575 DateTimeout(
576         XtPointer client_data,
577         XtIntervalId *id )
578 {
579   DtControlGadget       g =     (DtControlGadget) client_data;
580   XtAppContext          app_context =
581     XtWidgetToApplicationContext ((Widget) g);
582   char                  sTime[128];
583   _Xltimeparams         localtime_buf;
584   struct tm             *timeptr;
585   time_t                tse;
586   String                s1, s2, s3;
587   unsigned long         tilMidnight;
588   Boolean               old_format = False;
589   XtExposeProc          expose;
590   
591   /*    Get time string.
592    */
593   tse = time (NULL);
594   timeptr = _XLocaltime(&tse, localtime_buf);
595   strftime ((char*) sTime, 128, G_Format (g), timeptr);
596   if (g->control.format_jp != NULL && strlen(g->control.format_jp) != 0)
597     ReplaceJPDate(sTime, g->control.format_jp, timeptr->tm_wday);
598
599   /*    Break time string between date and day of week.
600    */
601   s1 = sTime;
602   s2 = strchr (sTime, '\n');
603   
604   if (s2 == NULL)
605     s3 = NULL;
606   else
607     {
608       s3 = strchr (s2+1, '\n');
609
610       if (s3 != NULL)
611         {
612           s2[0] = ' ';
613           s2 = s3;
614         }
615         
616       s2[0] = '\0';
617       s2++;
618     }
619   
620   /*    Create date string.
621    */
622   if (s1 != NULL)
623     {
624       if (s2 == NULL)
625         {
626           XmStringFree(G_String(g));
627           G_String (g) = XmStringCreate (s1, XmFONTLIST_DEFAULT_TAG);
628           XmStringExtent (G_FontList (g), G_String (g),
629                           &(G_StringWidth (g)), &(G_StringHeight (g)));
630
631           if (G_AltString (g) != NULL)
632             {
633               XmStringFree (G_AltString (g));
634               G_AltString (g) = NULL;
635               G_AltStringHeight (g) = 0;
636               G_AltStringWidth (g) = 0;
637             }
638         }
639       else
640         {
641           if (!G_UseLabelAdjustment (g))
642             {
643               /* swap s1 and s2 */
644               s3 = s1;
645               s1 = s2;
646               s2 = s3;
647             }
648           if (G_AltString (g) != NULL)
649             XmStringFree (G_AltString (g));
650           G_AltString (g) =  XmStringCreate (s1, XmFONTLIST_DEFAULT_TAG);
651           XmStringExtent (G_FontList (g), G_AltString (g),
652                           &(G_AltStringWidth (g)), &(G_AltStringHeight (g)));
653           XmStringFree(G_String(g));
654           G_String (g) = XmStringCreate (s2, XmFONTLIST_DEFAULT_TAG);
655           XmStringExtent (G_FontList (g), G_String (g),
656                           &(G_StringWidth (g)), &(G_StringHeight (g)));
657         }
658     }
659
660   /*    Update display.
661    */
662   _DtProcessLock();
663   expose = XtCoreProc((Widget)g, expose);
664   _DtProcessUnlock();
665   (*expose) ((Widget) g, NULL, False);
666   XmUpdateDisplay ((Widget) g);
667   
668   /*    Compute milliseconds until midnight:
669    *        a. compute current time in seconds
670    *        b. subtract that from number of seconds in a day.
671    *        c. multiply by 1000 to get milliseconds.
672    *    Add timeout.
673    */
674   tilMidnight = 1000 * (86400 - ((3600 * timeptr->tm_hour) +
675                                  (60 * timeptr->tm_min) +
676                                  (timeptr->tm_sec)));
677   
678   if (G_Format (g) != NULL)
679     {
680       G_DateTimer (g) = 
681         XtAppAddTimeOut (app_context, tilMidnight, 
682                          DateTimeout, (XtPointer) g);
683     }
684   else
685     {
686       G_DateTimer (g) = 0;
687     }
688 }
689
690
691 \f
692 /*-------------------------------------------------------------
693 **      Action Procs
694 **-------------------------------------------------------------
695 */
696
697
698 \f
699 /*-------------------------------------------------------------
700 **      Core Procs
701 **-------------------------------------------------------------
702 */
703
704 \f
705 /*-------------------------------------------------------------
706 **      ClassInitialize
707 */
708
709 static void
710 ClassInitialize( void )
711 {
712   controlBaseClassExtRec.record_type = XmQmotif;
713 }
714
715 \f
716 /*-------------------------------------------------------------
717 **      ClassPartInitialize
718 */
719
720 static void
721 ClassPartInitialize(
722         WidgetClass cl )
723 {
724     dtControlCacheObjClassRec.object_class.resources =
725                                  dtIconCacheObjClassRec.object_class.resources;
726
727     dtControlCacheObjClassRec.object_class.num_resources =
728                          dtIconCacheObjClassRec.object_class.num_resources;
729 }
730
731
732 \f
733 /*-------------------------------------------------------------
734 **      Initialize
735 **              Initialize a new gadget instance.
736 */
737 static void 
738 Initialize(
739         Widget request_w,
740         Widget new_w )
741 {
742   DtControlGadget       request = (DtControlGadget) request_w,
743   new = (DtControlGadget) new_w;
744   XmManagerWidget               mw = (XmManagerWidget) XtParent (new);
745   XtAppContext  app_context =
746     XtWidgetToApplicationContext (new_w);
747   String                str;
748   int           file_name_size;                         
749   XrmValue      pixVal;
750   UpdateGCsProc update_gcs;
751   
752   G_MonitorTimer (new) = 0;
753   G_ClickTimer (new) = 0;
754   G_DateTimer (new) = 0;
755   G_BlinkTimer (new) = 0;
756   G_PushAnimationTimer (new) = 0;
757   G_DropAnimationTimer (new) = 0;
758   
759   G_FileSize (new) = 0;
760   G_FileChanged (new) = False;
761   
762   G_Busy (new) = 0;
763   G_AltString (new) = NULL;
764   G_AltStringWidth (new) = 0;
765   G_AltStringHeight (new) = 0;
766   
767   /*    Initialize animation data.
768    */
769   G_NumPushImages (new) = 0;
770   G_MaxPushImages (new) = 0;
771   G_PushImagePosition (new) = 0;
772   G_PushDelays (new) = NULL;
773   G_PushPixmaps (new) = NULL;
774   G_PushMasks (new) = NULL;
775   
776   G_NumDropImages (new) = 0;
777   G_MaxDropImages (new) = 0;
778   G_DropImagePosition (new) = 0;
779   G_DropDelays (new) = NULL;
780   G_DropPixmaps (new) = NULL;
781   G_DropMasks (new) = NULL;
782   
783   /*    Copy drop argument.
784    */
785   if (G_DropAction (new) != NULL)
786     {
787       String    str = G_DropAction (new);
788       G_DropAction (new) = XtMalloc (strlen (str) + 1);
789       strcpy (G_DropAction (new), str);
790     }
791   
792   if (G_PushAction (new) != NULL)
793     {
794       String    str = G_PushAction (new);
795       G_PushAction (new) = XtMalloc (strlen (str) + 1);
796       strcpy (G_PushAction (new), str);
797     }
798   
799   /*    Validate control type.
800    */
801   if (G_ControlType (new) != XmCONTROL_NONE &&
802       G_ControlType (new) != XmCONTROL_SWITCH &&
803       G_ControlType (new) != XmCONTROL_BUTTON &&
804       G_ControlType (new) != XmCONTROL_BLANK &&
805       G_ControlType (new) != XmCONTROL_DATE &&
806       G_ControlType (new) != XmCONTROL_BUSY &&
807       G_ControlType (new) != XmCONTROL_CLIENT &&
808       G_ControlType (new) != XmCONTROL_MAIL &&
809       G_ControlType (new) != XmCONTROL_MONITOR)
810     {
811       G_ControlType (new) == XmCONTROL_NONE;
812     }
813   
814   if (G_ControlType (new) == XmCONTROL_SWITCH)
815     G_ShadowType (new) = (G_Set (new)) ? XmSHADOW_IN : XmSHADOW_OUT;
816   
817   if ( ((G_ControlType (new) == XmCONTROL_MONITOR) ||
818         (G_ControlType (new) == XmCONTROL_MAIL) ||
819         (G_ControlType (new) == XmCONTROL_BUSY)) &&
820       (G_AltImage (new) != NULL))
821     {
822
823       /*        Copy string or default to user mail directory.
824        */
825       if ((G_ControlType (new) == XmCONTROL_MONITOR) ||
826           (G_ControlType (new) == XmCONTROL_MAIL))
827         {
828           if (G_FileName (new) == NULL)
829             {
830               if (G_ControlType (new) == XmCONTROL_MAIL)
831                 {
832                   if ((str = getenv ("MAIL")) == NULL)
833                     {
834                       str = getenv ("LOGNAME");
835                       G_FileName (new) = 
836                         XtMalloc (strlen (MAIL_DIR) + strlen (str) + 1);
837                       strcpy (G_FileName (new), MAIL_DIR);
838                       strcat (G_FileName (new), str);
839                     }
840                   else
841                     {
842                       G_FileName (new) = XtMalloc (strlen (str) + 1);
843                       strcpy (G_FileName (new), str);
844                     }
845                 }
846             }
847           else
848             {
849               str = G_FileName (new);
850               G_FileName (new) = XtMalloc (strlen (str) + 1);
851               strcpy (G_FileName (new), str);
852             }
853
854           G_FileChanged (new) = False;
855         }
856         
857       /*        Get alternate pixmap and mask.
858        */
859       G_AltPix (new) =
860         XmGetPixmap (XtScreen (new), G_AltImage (new),
861                      G_PixmapForeground (new),
862                      G_PixmapBackground (new));
863       G_AltMask (new) =
864         _DtGetMask (XtScreen (new), G_AltImage (new));
865       G_AltImage (new) = NULL;
866
867       if ((G_AltPix (new) != XmUNSPECIFIED_PIXMAP) &&
868           ((G_ControlType (new) == XmCONTROL_MONITOR) ||
869            (G_ControlType (new) == XmCONTROL_MAIL)))
870         {
871           CheckFile (new);
872           G_MonitorTimer (new) =
873             XtAppAddTimeOut (app_context, G_MonitorTime (new),
874                              FileCheckTimeout, (XtPointer) new);
875         }
876
877       /*        Check for Control state change.
878        */
879     }
880   else
881     {
882       G_AltPix (new) = XmUNSPECIFIED_PIXMAP;
883       G_AltMask (new) = XmUNSPECIFIED_PIXMAP;
884       G_MonitorTimer (new) = 0;
885     }
886   
887   if (G_ControlType (new) == XmCONTROL_DATE)
888     {
889       Dimension w, h;
890
891       DateTimeout ((XtPointer) new_w, NULL);
892
893       if (G_Width (request) == 0 || G_Height (request) == 0)
894         {
895           GetSizeProc get_size;
896
897           _DtProcessLock();
898           get_size = C_GetSize(XtClass(new));
899           _DtProcessUnlock();
900           (*get_size) ((DtIconGadget) new, &w, &h);
901           if (G_Width (request) == 0)
902             G_Width (new) = w;
903           if (G_Height (request) == 0)
904             G_Height (new) = h;
905         }
906     }
907   
908   G_ArmedGC (new) = NULL;
909   
910   G_TopShadowGC (new) = NULL;
911   G_BottomShadowGC (new) = NULL;
912   G__DoUpdate (new) = True;
913   _DtProcessLock();
914   update_gcs = C_UpdateGCs(XtClass(new));
915   _DtProcessUnlock();
916   (*update_gcs) ((DtIconGadget) new);
917   G__DoUpdate (new) = False;
918 }
919
920
921 \f
922 /*-------------------------------------------------------------
923 **      Destroy
924 **              Release resources allocated for gadget.
925 */
926
927 static void 
928 Destroy(
929         Widget w )
930 {
931   DtControlGadget       g =     (DtControlGadget) w;
932   
933   if (G_FileName (g) != NULL)
934     XtFree (G_FileName (g));
935   
936   if (G_NumPushImages (g) > 0)
937     {
938       XtFree ((char*) G_PushDelays (g));
939       XtFree ((char*) G_PushPixmaps (g));
940       XtFree ((char*) G_PushMasks (g));
941     }
942   if (G_NumDropImages (g) > 0)
943     {
944       XtFree ((char*) G_DropDelays (g));
945       XtFree ((char*) G_DropPixmaps (g));
946       XtFree ((char*) G_DropMasks (g));
947     }
948   if (G_DropAction (g) != NULL)
949     XtFree (G_DropAction (g));
950   if (G_PushAction (g) != NULL)
951     XtFree (G_PushAction (g));
952   
953   if (G_AltString (g) != NULL)
954     XmStringFree (G_AltString (g));
955   
956   if (G_ClickTimer (g))
957     XtRemoveTimeOut (G_ClickTimer (g));
958   if (G_BlinkTimer (g))
959     XtRemoveTimeOut (G_BlinkTimer (g));
960   if (G_MonitorTimer (g))
961     XtRemoveTimeOut (G_MonitorTimer (g));
962   if (G_DateTimer (g))
963     XtRemoveTimeOut (G_DateTimer (g));
964   if (G_PushAnimationTimer (g))
965     XtRemoveTimeOut (G_PushAnimationTimer (g));
966   if (G_DropAnimationTimer (g))
967     XtRemoveTimeOut (G_DropAnimationTimer (g));
968 }
969
970
971 \f
972 /*-------------------------------------------------------------
973 **      SetValues
974 **              
975 */
976 static Boolean 
977 SetValues(
978         Widget current_w,
979         Widget request_w,
980         Widget new_w )
981 {
982
983
984     DtControlGadget     request_c =     (DtControlGadget) request_w,
985                         current_c =     (DtControlGadget) current_w,
986                         new_c =         (DtControlGadget) new_w;
987 #if 0
988         String          file_name =     G_FileName (new);
989         int             file_name_size;                         
990         Boolean         redraw_flag =   False;
991 #endif /*  0 */
992
993     if (strcmp(G_Format(new_c),G_Format(current_c)) &&
994         G_ControlType (new_c) == XmCONTROL_DATE)
995     {
996        if (G_DateTimer (new_c))
997           XtRemoveTimeOut (G_DateTimer (new_c));
998
999        if (G_Format(new_c) != NULL)
1000           DateTimeout ((XtPointer) new_w, NULL);
1001     }
1002
1003     if (G_ImageName (new_c) && (G_ImageName (current_c) != G_ImageName (new_c)))
1004        return True;
1005
1006     return False;
1007
1008 #if 0
1009
1010 /*      Copy drop argument.
1011 */
1012 if (G_DropAction (new) != G_DropAction (current))
1013     {
1014     String      str = G_DropAction (new);
1015     if (G_DropAction (current) != NULL)
1016         XtFree (G_DropAction (current));
1017     G_DropAction (new) = XtMalloc (strlen (str) + 1);
1018     strcpy (G_DropAction (new), str);
1019     }
1020
1021 if (G_PushAction (new) != G_PushAction (current))
1022     {
1023     String    str = G_PushAction (new);
1024     if (G_PushAction (current) != NULL)
1025       XtFree (G_PushAction (current));
1026     G_PushAction (new) = XtMalloc (strlen (str) + 1);
1027     strcpy (G_PushAction (new), str);
1028     }
1029
1030 /*      Copy string or default to user mail directory.
1031 */
1032 if ((G_ControlType (new) == XmCONTROL_MONITOR) ||
1033     (G_ControlType (new) == XmCONTROL_MAIL))
1034     {
1035         if (G_FileName (new) != G_FileName (current))
1036         {
1037                 if (G_FileName (current) != NULL)
1038                         XtFree (G_FileName (current));
1039                 if (G_FileName (new) != NULL)
1040                 {
1041                         file_name_size = strlen (G_FileName (new));
1042                         G_FileName (new) = XtMalloc (file_name_size);
1043                         strcpy (G_FileName (new), file_name);
1044                 }
1045         }
1046     }
1047
1048         return (redraw_flag);
1049 #endif /* 0 */
1050 }
1051
1052 \f
1053 /*-------------------------------------------------------------
1054 **      Gadget Procs
1055 **-------------------------------------------------------------
1056 */
1057
1058
1059 /*-------------------------------------------------------------
1060 **      Icon Procs
1061 **-------------------------------------------------------------
1062 */
1063
1064 /*-------------------------------------------------------------
1065 **      GetSize
1066 **              Compute size.
1067 */
1068 static void 
1069 GetSize(
1070         DtControlGadget g,
1071         Dimension *w,
1072         Dimension *h )
1073 {
1074   Dimension     s_t = G_ShadowThickness (g);
1075   Dimension     h_t = G_HighlightThickness (g);
1076   Dimension     p_w = G_PixmapWidth (g);
1077   Dimension     p_h = G_PixmapHeight (g);
1078   Dimension     m_w = G_MarginWidth (g);
1079   Dimension     m_h = G_MarginHeight (g);
1080   Dimension     s_w = G_StringWidth (g);
1081   Dimension     s_h = G_StringHeight (g);
1082   Dimension     v_pad = 2 * (s_t + h_t + m_h);
1083   Dimension     h_pad = 2 * (s_t + h_t + m_w);
1084   Dimension     spacing = G_Spacing (g);
1085   
1086   if (((p_w == 0) && (p_h == 0)) || ((s_w == 0) && (s_h == 0)))
1087     spacing = 0;
1088   
1089   if (G_ControlType (g) == XmCONTROL_DATE)
1090     {
1091       /*    Adjust size based on second date string.
1092        */
1093       if ( (G_StringWidth (g) > 0) &&
1094           (G_AltStringWidth (g) > G_StringWidth (g)) )
1095         s_w = G_AltStringWidth (g);
1096       if ( (G_StringWidth (g) > 0) && (G_AltStringWidth (g) > 0) )
1097         s_h += spacing + G_AltStringHeight (g);
1098     }
1099   else
1100     {
1101       /*    Add left and right spacing for string.
1102        */
1103       if (s_w > 0)
1104         s_w += 4;
1105     }
1106   
1107   /*    Get width and height.
1108    */
1109   switch ((int) G_PixmapPosition (g))
1110     {
1111     case XmPIXMAP_TOP:
1112     case XmPIXMAP_BOTTOM:
1113       *w = Max (p_w, s_w) + h_pad;
1114       *h = p_h + s_h + v_pad + spacing;
1115       break;
1116     case XmPIXMAP_LEFT:
1117     case XmPIXMAP_RIGHT:
1118       *w = p_w + s_w + h_pad + spacing;
1119       *h = Max (p_h, s_h) + v_pad;
1120       break;
1121     case XmPIXMAP_MIDDLE:
1122       *w = Max (p_w, s_w) + h_pad;
1123       *h = Max (p_h, s_h) + v_pad;
1124       break;
1125     }
1126 }
1127
1128
1129 \f
1130 /*-------------------------------------------------------------
1131 **      GetPositions
1132 **              Get positions of string and pixmap.
1133 */
1134 static void 
1135 GetPositions(
1136         DtControlGadget g,
1137         Position w,
1138         Position h,
1139         Dimension h_t,
1140         Dimension s_t,
1141         Position *pix_x,
1142         Position *pix_y,
1143         Position *str_x,
1144         Position *str_y )
1145 {
1146         Dimension       p_w =           G_PixmapWidth (g),
1147                         p_h =           G_PixmapHeight (g),
1148                         s_w =           G_StringWidth (g),
1149                         s_h =           G_StringHeight (g),
1150                         m_w =           G_MarginWidth (g),
1151                         m_h =           G_MarginHeight (g),
1152                         spacing =       G_Spacing (g),
1153                         h_pad =         s_t + h_t + m_w,
1154                         v_pad =         s_t + h_t + m_h,
1155                         width =         w - 2 * h_pad,
1156                         height =        h - 2 * v_pad;
1157         Position        p_x =           h_pad,
1158                         p_y =           v_pad,
1159                         s_x =           h_pad,
1160                         s_y =           v_pad;
1161         unsigned char   align =         G_Alignment (g);
1162
1163         if (((p_w == 0) && (p_h == 0)) || ((s_w == 0) && (s_h == 0)))
1164                 spacing = 0;
1165
1166 /*      Set positions
1167 */
1168         switch ((int) G_PixmapPosition (g))
1169         {
1170                 case XmPIXMAP_TOP:
1171                         if (align == XmALIGNMENT_CENTER)
1172                         {
1173                                 if (p_w && width > p_w)
1174                                         p_x += (width - p_w)/2U;
1175                                 if (s_w && width > s_w)
1176                                         s_x += (width - s_w)/2U;
1177                         }
1178                         else if (align == XmALIGNMENT_END)
1179                         {
1180                                 if (p_w && width > p_w)
1181                                         p_x += width - p_w;
1182                                 if (s_w && width > s_w)
1183                                         s_x += width - s_w;
1184                         }
1185                         if (p_h && ((unsigned)height > (p_h + s_h + spacing)))
1186                                 p_y += (height - p_h - s_h - spacing)/2U;
1187                         if (p_h)
1188                                 s_y = p_y + p_h + spacing;
1189                         else
1190                                 s_y += (height - s_h)/2U;
1191                         break;
1192                 case XmPIXMAP_BOTTOM:
1193                         if (align == XmALIGNMENT_CENTER)
1194                         {
1195                                 if (p_w && width > p_w)
1196                                         p_x += (width - p_w)/2U;
1197                                 if (s_w && width > s_w)
1198                                         s_x += (width - s_w)/2U;
1199                         }
1200                         else if (align == XmALIGNMENT_END)
1201                         {
1202                                 if (p_w && width > p_w)
1203                                         p_x += width - p_w;
1204                                 if (s_w && width > s_w)
1205                                         s_x += width - s_w;
1206                         }
1207                         if (s_h && ((unsigned)height > (p_h + s_h + spacing)))
1208                                 s_y += (height - p_h - s_h - spacing)/2U;
1209                         if (s_h)
1210                                 p_y = s_y + s_h + spacing;
1211                         else
1212                                 p_y += (height - p_h)/2U;
1213                         break;
1214                 case XmPIXMAP_LEFT:
1215                         if (p_h && height > p_h)
1216                                 p_y += (height - p_h)/2U;
1217                         s_x += p_w + spacing;
1218                         if (s_h && height > s_h)
1219                                 s_y += (height - s_h)/2U;
1220 /*
1221                         if (p_w && width > p_w + spacing + s_w)
1222                                 p_x += (width - p_w - spacing - s_w)/2;
1223                         if (s_w && width > p_w + spacing + s_w)
1224                                 s_x += (width - p_w - spacing - s_w)/2;
1225 */
1226                         break;
1227                 case XmPIXMAP_RIGHT:
1228                         if (s_h && height > s_h)
1229                                 s_y += (height - s_h)/2U;
1230                         p_x += s_w + spacing;
1231                         if (p_w && ((unsigned)width > (p_w + spacing + s_w)))
1232                                 p_x += (width - p_w - spacing - s_w)/2U;
1233                         if (s_w && ((unsigned)width > (p_w + spacing + s_w)))
1234                                 s_x += (width - p_w - spacing - s_w)/2U;
1235                         if (p_h && height > p_h)
1236                                 p_y += (height - p_h)/2U;
1237                         break;
1238                 case XmPIXMAP_MIDDLE:
1239                         if (p_w && width > p_w)
1240                            p_x += (width - p_w)/2U;
1241                         if (s_w && width > s_w)
1242                            s_x += (width - s_w)/2U;
1243                         if (s_h && height > s_h)
1244                                 s_y += (height - s_h)/2U;
1245                         if (p_h && height > p_h)
1246                                 p_y += (height - p_h)/2U;
1247                         break;
1248         }
1249
1250         *pix_x = p_x;
1251         *pix_y = p_y;
1252         *str_x = s_x;
1253         *str_y = s_y;
1254 }
1255
1256
1257 \f
1258 /*-------------------------------------------------------------
1259 **      Draw
1260 **              Draw gadget to drawable.
1261 */
1262 static void 
1263 Draw(
1264         DtControlGadget g,
1265         Drawable drawable,
1266         Position x,
1267         Position y,
1268         Dimension w,
1269         Dimension h,
1270         Dimension h_t,
1271         Dimension s_t,
1272         unsigned char s_type,
1273         unsigned char fill_mode )
1274 {
1275   XmManagerWidget       mgr =   (XmManagerWidget) XtParent (g);
1276   Display *             d =     XtDisplay (g);
1277   GC                    gc, gcTS, gcBS;
1278   XRectangle            clip;
1279   Position              p_x, p_y, s_x, s_y;
1280   Dimension             width = 0, height = 0;
1281   unsigned char         behavior =      G_Behavior (g);
1282   Position              adj_x, adj_y;
1283   Pixmap                pix;
1284   Pixmap                mask;
1285   int                   index;
1286   Dimension             left = 0, right = 0, top = 0, bottom = 0;
1287   Dimension             v_pad;
1288   Boolean               bClearArea = False;
1289   Boolean               bClearShadow = False;
1290   Boolean               bMono;
1291   GetPositionProc       get_positions;
1292   
1293   bMono = (((G_Foreground (g) == BlackPixelOfScreen (XtScreen (g))) ||
1294             (G_Foreground (g) == WhitePixelOfScreen (XtScreen (g)))) &&
1295            ((G_Background (g) == BlackPixelOfScreen (XtScreen (g))) ||
1296             (G_Background (g) == WhitePixelOfScreen (XtScreen (g)))) );
1297   
1298   /*    Select gc to fill background.
1299    */
1300   if (G_ControlType (g) == XmCONTROL_SWITCH)
1301     gc = bMono ? M_BackgroundGC (mgr) : G_BackgroundGC (g);
1302   else if ((G_Armed (g)) && (fill_mode != XmFILL_PARENT))
1303     gc = G_ArmedBackgroundGC (g);
1304   else
1305     gc = M_BackgroundGC (mgr); 
1306   
1307   if ((fill_mode != XmFILL_NONE) && (fill_mode != XmFILL_TRANSPARENT))
1308     bClearArea = True;
1309   
1310   /*    Select pixmap and mask.
1311    */
1312   if (G_Pixmap (g))
1313     {
1314       /*        Terminate animation sequence.
1315        */
1316       if (G_PushImagePosition (g) > G_NumPushImages (g))
1317         G_PushImagePosition (g) = 0;
1318       if (G_DropImagePosition (g) > G_NumDropImages (g))
1319         G_DropImagePosition (g) = 0;
1320
1321       /*        Use animation image.
1322        */
1323       if (G_PushImagePosition (g) > 0)
1324         {
1325           index = (G_PushImagePosition (g)) - 1;    
1326           if ((index == 0) || (bMono))
1327             bClearArea = True;
1328           else
1329             bClearArea = False;
1330           pix = G_PushPixmaps (g)[index];
1331           mask = G_PushMasks (g)[index];
1332           ++G_PushImagePosition (g);
1333         }
1334       else if (G_DropImagePosition (g) > 0)
1335         {
1336           index = G_DropImagePosition (g) - 1;
1337           if (bMono)
1338             bClearArea = True;
1339           else
1340             bClearArea = False;
1341           pix = G_DropPixmaps (g)[index];
1342           mask = G_DropMasks (g)[index];
1343           ++G_DropImagePosition (g);
1344         }
1345
1346       /*        Use alternate image.
1347        */
1348       else if ( ( ((G_ControlType (g) == XmCONTROL_MONITOR) ||
1349                    (G_ControlType (g) == XmCONTROL_MAIL)) &&
1350                  (G_AltPix (g) != XmUNSPECIFIED_PIXMAP) &&
1351                  G_FileChanged (g) ) ||
1352                ( (G_ControlType (g) == XmCONTROL_BUSY) &&
1353                 (G_AltPix (g) != XmUNSPECIFIED_PIXMAP) &&
1354                 G_Busy (g) && G_Set (g)) )
1355         {
1356           pix = G_AltPix (g);
1357           mask = G_AltMask (g);
1358         }
1359
1360       /*        Use normal image.
1361        */
1362       else
1363         {
1364           pix = G_Pixmap (g);
1365           mask = G_Mask (g);
1366         }
1367     }
1368   
1369   if (bClearShadow)
1370     {
1371       /*        Erase shadow - top, left, right, bottom.
1372        */
1373       XFillRectangle (d, drawable, gc, x + h_t, y + h_t,
1374                       w - 2 * h_t, s_t);
1375       XFillRectangle (d, drawable, gc, x + h_t, y + h_t + s_t,
1376                       s_t, h - 2 * (h_t + s_t));
1377       XFillRectangle (d, drawable, gc, x + w - h_t - s_t, y + h_t + s_t,
1378                       s_t, h - 2 * (h_t + s_t));
1379       XFillRectangle (d, drawable, gc, x + h_t, y + h - h_t - s_t,
1380                       w - 2 * h_t, s_t);
1381     }
1382   else if (bClearArea)
1383     /*  Fill background.
1384      */
1385     XFillRectangle (d, drawable, gc, x + h_t, y + h_t,
1386                     w - 2 * h_t, h - 2 * h_t);
1387   
1388   
1389   /*    Get pixmap and string positions.
1390    */
1391   _DtProcessLock();
1392   get_positions = C_GetPositions(XtClass(g));
1393   _DtProcessUnlock();
1394   (*get_positions) ((DtIconGadget) g, w, h, h_t, s_t, &p_x, &p_y, &s_x, &s_y);
1395   
1396   /*    Select and display pixmap.
1397    */
1398   if (G_Pixmap (g))
1399     {
1400
1401       /*        Compute display region.
1402        */
1403       if ((width == 0) && (height == 0))
1404         {          
1405           width = ((unsigned)(p_x + s_t + h_t) >= G_Width (g))
1406             ? 0 : Min ((unsigned)G_PixmapWidth (g),
1407                        G_Width (g) - p_x - s_t - h_t);
1408           height = ((unsigned)(p_y + s_t + h_t) >= G_Height (g))
1409             ? 0 : Min ((unsigned)G_PixmapHeight (g),
1410                        G_Height (g) - p_y - s_t - h_t);
1411         }
1412       /*        Update clip gc.
1413        */
1414       if (mask != XmUNSPECIFIED_PIXMAP)
1415         {
1416           gc = G_ClipGC (g);
1417           XSetClipMask (XtDisplay(g), gc, mask);
1418           XSetClipOrigin (XtDisplay(g), gc, x + p_x, y + p_y);
1419         }
1420       else
1421         gc = G_NormalGC (g);
1422         
1423       /*        Paint pixmap.
1424        */
1425       if ((width > 0 && height > 0) &&
1426           (gc != NULL) && (pix != XmUNSPECIFIED_PIXMAP))
1427         XCopyArea (d, pix, drawable, gc, 0, 0,
1428                    width, height, x + p_x, y + p_y);
1429     }
1430   
1431   /*    Draw string.
1432    */
1433   clip.x = x + h_t + s_t;
1434   clip.y = y + h_t + s_t;
1435   clip.width = G_Width (g) - (2 * (h_t + s_t));
1436   clip.height = G_Height (g) - (2 * (h_t + s_t));
1437   
1438   if ((G_String (g)) && (clip.width > 0 && clip.height > 0))
1439     {
1440       if (G_ControlType (g) == XmCONTROL_DATE)
1441         {
1442           if ( (G_StringHeight (g) > 0) && (G_AltStringHeight (g) > 0) )
1443             {
1444               unsigned pad_factor;
1445
1446               if (G_UseLabelAdjustment (g))
1447                 pad_factor = 3;
1448               else
1449                 pad_factor = 4;
1450
1451               v_pad = ((unsigned)G_Height(g) >
1452                        (G_StringHeight(g) + G_AltStringHeight(g))) ?
1453                          (G_Height (g) - G_StringHeight (g) - 
1454                           G_AltStringHeight (g)) / pad_factor : 0;
1455               s_y = (2 * v_pad);
1456             }
1457
1458           if (bMono)
1459             {
1460               XmStringDrawImage (d, drawable, G_FontList (g), G_String (g),
1461                                  G_NormalGC (g), x + s_x, y + s_y,
1462                                  clip.width, XmALIGNMENT_BEGINNING,
1463                                  XmSTRING_DIRECTION_L_TO_R, &clip);
1464             }
1465           else
1466             {
1467               if (G_UseEmbossedText (g))
1468                 XmStringDraw (d, drawable, G_FontList (g), G_String (g),
1469                               G_BottomShadowGC (g), x + s_x + 1, y + s_y + 1,
1470                               clip.width, XmALIGNMENT_BEGINNING,
1471                               XmSTRING_DIRECTION_L_TO_R, &clip);
1472               XmStringDraw (d, drawable, G_FontList (g), G_String (g),
1473                             G_NormalGC (g), x + s_x, y + s_y,
1474                             clip.width, XmALIGNMENT_BEGINNING,
1475                             XmSTRING_DIRECTION_L_TO_R, &clip);
1476             }
1477
1478           if (G_Width (g) > G_AltStringWidth (g))
1479             s_x = (G_Width (g) - G_AltStringWidth (g)) / 2U;
1480
1481           if (G_UseLabelAdjustment (g))
1482             s_y = ((G_Height (g) - G_AltStringWidth (g)) + 5);
1483           else
1484             s_y += G_StringHeight (g);
1485
1486           if (bMono)
1487             {
1488               XmStringDrawImage (d, drawable, G_FontList (g),
1489                                  G_AltString (g),
1490                                  G_NormalGC (g), x + s_x, y + s_y,
1491                                  clip.width, XmALIGNMENT_BEGINNING,
1492                                  XmSTRING_DIRECTION_L_TO_R, &clip);
1493             }
1494           else
1495             {
1496               if (G_UseEmbossedText (g))
1497                 XmStringDraw (d, drawable, G_FontList (g),
1498                               G_AltString (g),
1499                               G_BottomShadowGC (g), x + s_x + 1, y + s_y + 1,
1500                               clip.width, XmALIGNMENT_BEGINNING,
1501                               XmSTRING_DIRECTION_L_TO_R, &clip);
1502               XmStringDraw (d, drawable, G_FontList (g),
1503                             G_AltString (g),
1504                             G_NormalGC (g), x + s_x, y + s_y,
1505                             clip.width, XmALIGNMENT_BEGINNING,
1506                             XmSTRING_DIRECTION_L_TO_R, &clip);
1507             }
1508         }
1509       else
1510         {
1511           if (bMono)
1512             {
1513               if ((s_x - 2U) >= (h_t + s_t))
1514                 XFillRectangle (d, drawable, G_ArmedBackgroundGC (g),
1515                                 x + s_x - 2, y + s_y,
1516                                 2, G_StringHeight (g));
1517               XmStringDrawImage (d, drawable, G_FontList (g), G_String (g),
1518                                  G_NormalGC (g), x + s_x, y + s_y,
1519                                  clip.width, XmALIGNMENT_BEGINNING,
1520                                  XmSTRING_DIRECTION_L_TO_R, &clip);
1521               if ((s_x + G_StringWidth (g) + 2U) <= (G_Width (g) - h_t - s_t))
1522                 XFillRectangle (d, drawable, G_ArmedBackgroundGC (g),
1523                                 x + s_x + G_StringWidth (g), y + s_y,
1524                                 2, G_StringHeight (g));
1525             }
1526           else
1527             {
1528               if (G_UseEmbossedText (g))
1529                 XmStringDraw (d, drawable, G_FontList (g), G_String (g),
1530                               G_BottomShadowGC (g), x + s_x + 1, y + s_y + 1,
1531                               clip.width, XmALIGNMENT_BEGINNING,
1532                               XmSTRING_DIRECTION_L_TO_R, &clip);
1533               XmStringDraw (d, drawable, G_FontList (g), G_String (g),
1534                             G_NormalGC (g), x + s_x, y + s_y,
1535                             clip.width, XmALIGNMENT_BEGINNING,
1536                             XmSTRING_DIRECTION_L_TO_R, &clip);
1537             }
1538         }
1539     }
1540   
1541   /*    Draw shadow.
1542    */
1543   switch (G_ControlType (g))
1544     {
1545     case XmCONTROL_BLANK:
1546     case XmCONTROL_DATE:
1547       break;
1548
1549     case XmCONTROL_CLIENT:
1550       /*        Get insets.
1551        */
1552       if (bMono)
1553         /*      Use black and white.
1554          */
1555         {
1556           if (G_Foreground (g) == WhitePixelOfScreen (XtScreen (g)))
1557             {
1558               gcTS = G_BackgroundGC (g);
1559               gcBS = G_NormalGC (g);
1560             }
1561           else
1562             {
1563               gcBS = G_BackgroundGC (g);
1564               gcTS = G_NormalGC (g);
1565             }
1566         }
1567       else
1568         {
1569           gcTS = M_BottomShadowGC (mgr);
1570           gcBS = M_TopShadowGC (mgr);
1571         }
1572       /*        Drop inner shadow if secondary since no fill.
1573        */
1574       XmeDrawShadows (d, drawable, gcTS, gcBS, 
1575                       x + left - s_t, y + top - s_t,
1576                       w - left - right + (2 * s_t),
1577                       h - top - bottom + (2 * s_t),
1578                       s_t, XmSHADOW_ETCHED_OUT);
1579       break;
1580
1581     default:
1582     case XmCONTROL_BUTTON:
1583     case XmCONTROL_MONITOR:
1584     case XmCONTROL_MAIL:
1585       switch (G_Behavior (g))
1586         {
1587         case XmICON_BUTTON:
1588           if (G_Armed (g))
1589             XmeDrawShadows(d, drawable, 
1590                            M_TopShadowGC(mgr), M_BottomShadowGC(mgr),
1591                            x + h_t, y + h_t,
1592                            w - 2*h_t, h - 2*h_t, s_t, XmSHADOW_IN);
1593           break;
1594         case XmICON_TOGGLE:
1595           if ( (G_Armed (g) && !G_Set (g)) ||
1596               (!G_Armed (g) && G_Set (g)) )
1597             XmeDrawShadows(d, drawable, 
1598                            M_TopShadowGC(mgr), M_BottomShadowGC(mgr),
1599                            x + h_t, y + h_t,
1600                            w - 2*h_t, h - 2*h_t, s_t, XmSHADOW_IN);
1601           break;
1602         }
1603       break;
1604     case XmCONTROL_SWITCH:
1605       if (!G_FillOnArm (g))
1606         {
1607           gcTS = G_BottomShadowGC (g);
1608           gcBS = G_TopShadowGC (g);
1609         }
1610       else
1611         {
1612           if (G_Foreground (g) == WhitePixelOfScreen (XtScreen (g)))
1613             {
1614               gcTS = G_BackgroundGC (g);
1615               gcBS = G_NormalGC (g);
1616             }
1617           else
1618             {
1619               gcTS = G_NormalGC (g);
1620               gcBS = G_BackgroundGC (g);
1621             }
1622         }
1623       XmeDrawShadows (d, drawable, gcTS, gcBS,
1624                       x + h_t, y + h_t, w - 2*h_t, h - 2*h_t, 1,
1625                       XmSHADOW_OUT);
1626
1627       ++x;  ++y;  w -= 2;  h -= 2;  --s_t;
1628       if (s_t > 0)
1629         {
1630           if ( (G_Armed (g) && !G_Set (g)) ||
1631               (!G_Armed (g) && G_Set (g)) )
1632             {
1633               gcTS = G_BottomShadowGC (g);
1634               gcBS = G_TopShadowGC (g);
1635             }
1636           else
1637             {
1638               gcTS = G_TopShadowGC (g);
1639               gcBS = G_BottomShadowGC (g);
1640             }
1641           XmeDrawShadows (d, drawable, gcTS, gcBS,
1642                           x + h_t, y + h_t, w - 2*h_t, h - 2*h_t, s_t,
1643                           XmSHADOW_OUT);
1644         }
1645       break;
1646     }
1647 }
1648
1649
1650 /*-------------------------------------------------------------
1651 **      CallCallback
1652 **              Call callback, if any, with reason and event.
1653 */
1654 static void 
1655 CallCallback(
1656         DtControlGadget g,
1657         XtCallbackList cb,
1658         int reason,
1659         XEvent *event )
1660 {
1661   DtControlCallbackStruct       cb_data;
1662   XtAppContext  app_context = XtWidgetToApplicationContext ((Widget) g);
1663   
1664   if ((reason == XmCR_ACTIVATE) && (G_Behavior (g) == XmICON_BUTTON))
1665     {
1666       if (G_ClickTimer (g) != 0)
1667         return;
1668       else
1669         G_ClickTimer (g) = 
1670           XtAppAddTimeOut (app_context, G_ClickTime (g),
1671                            ClickTimeout, (XtPointer) g);
1672     }
1673   
1674   if (cb != NULL)
1675     {
1676       cb_data.reason = reason;
1677       cb_data.event = event;
1678       cb_data.control_type = G_ControlType (g);
1679       cb_data.set = G_Set (g);
1680       cb_data.push_function = G_PushFunction (g);
1681       cb_data.push_argument = G_PushArgument (g);
1682       cb_data.subpanel = G_Subpanel (g);
1683       cb_data.file_size = G_FileSize (g);
1684       XtCallCallbackList ((Widget) g, cb, &cb_data);
1685
1686     }
1687 }
1688
1689
1690 \f
1691 /*-------------------------------------------------------------
1692 **      UpdateGCs
1693 **              Get normal and background graphics contexts.
1694 **              Use standard mask to maximize caching opportunities.
1695 */
1696 static void 
1697 UpdateGCs(
1698         DtControlGadget g )
1699 {
1700   XGCValues             values;
1701   XtGCMask              value_mask;
1702   XmManagerWidget       mw = (XmManagerWidget) XtParent(g);
1703   XFontStruct *         font;
1704   Boolean               font_rtn;
1705   
1706   if (!G__DoUpdate (g))
1707     return;
1708   
1709   if (G_NormalGC (g))
1710     XtReleaseGC ((Widget)mw, G_NormalGC (g));
1711   if (G_ClipGC (g))
1712     XtReleaseGC ((Widget)mw, G_ClipGC (g));
1713   if (G_BackgroundGC (g))
1714     XtReleaseGC ((Widget)mw, G_BackgroundGC (g));
1715   if (G_ArmedBackgroundGC (g))
1716     XtReleaseGC ((Widget)mw, G_ArmedBackgroundGC (g));
1717   if (G_TopShadowGC (g))
1718     XtReleaseGC ((Widget)mw, G_TopShadowGC (g));
1719   if (G_BottomShadowGC (g))
1720     XtReleaseGC ((Widget)mw, G_BottomShadowGC (g));
1721   
1722   /*    Get normal GC.
1723    */
1724   font_rtn = XmeRenderTableGetDefaultFont (G_FontList (g), &font);
1725   value_mask = GCForeground | GCBackground | GCFont | GCFillStyle;
1726   if (G_UseEmbossedText (g))
1727     values.foreground = WhitePixelOfScreen (XtScreen (g));
1728   else
1729     values.foreground = G_Foreground (g);
1730   values.background = G_Background (g);
1731   
1732   values.fill_style = FillSolid;
1733   values.font = font->fid;
1734   G_NormalGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
1735   
1736   /*    Get top shadow GC.
1737    */
1738   if (G_ControlType (g) == XmCONTROL_SWITCH)
1739     values.foreground = G_PixmapBackground (g);
1740   else
1741     values.foreground = mw -> manager.top_shadow_color;
1742   values.background = G_Background (g);
1743   G_TopShadowGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
1744   
1745   /*    Get bottom shadow GC.
1746    */
1747   if (G_ControlType (g) == XmCONTROL_SWITCH)
1748     values.foreground = G_PixmapForeground (g);
1749   else
1750     values.foreground = mw -> manager.bottom_shadow_color;
1751   values.background = G_Background (g);
1752   G_BottomShadowGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
1753   
1754   /*    Get background GC.
1755    */
1756   values.foreground = G_Background (g);
1757   values.background = G_Foreground (g);
1758   G_BackgroundGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
1759   
1760   /*    Get armed background GC.
1761    */
1762   values.foreground = G_ArmColor (g);
1763   values.background = G_Background (g);
1764   G_ArmedBackgroundGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
1765   
1766   /*    Get Clip GC
1767    */
1768   if (G_Mask(g) != XmUNSPECIFIED_PIXMAP)
1769     {
1770       value_mask |= GCClipMask;
1771       values.clip_mask = G_Mask(g);
1772     }
1773   values.foreground = G_Foreground (g);
1774   values.background = G_Background (g);
1775   G_ClipGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
1776 }
1777
1778 \f
1779 /*-------------------------------------------------------------
1780 **      Public Entry Points
1781 **-------------------------------------------------------------
1782 */
1783
1784
1785 /*-------------------------------------------------------------
1786 **      Push Animation Timeout
1787 **              An XtTimerCallbackProc.
1788 */
1789 static void 
1790 PushAnimationTimeout(
1791         XtPointer client_data,
1792         XtIntervalId *id )
1793 {
1794   DtControlGadget       g = (DtControlGadget) client_data;
1795   XtAppContext          app_context = XtWidgetToApplicationContext ((Widget) g);
1796   XtExposeProc          expose;
1797   
1798   if ((G_PushImagePosition (g) > 0) &&
1799       (G_PushImagePosition (g) <= G_NumPushImages (g)))
1800     {
1801       G_PushAnimationTimer (g) = 
1802         XtAppAddTimeOut (app_context,
1803                          G_PushDelays (g)[G_PushImagePosition (g) - 1],
1804                          PushAnimationTimeout, (XtPointer) g);
1805     }
1806   if (G_PushImagePosition (g) > 1)
1807     {
1808       _DtProcessLock();
1809       expose = XtCoreProc((Widget)g, expose);
1810       _DtProcessUnlock();
1811       (*expose) ((Widget) g, NULL, NULL);
1812     }
1813 }
1814
1815
1816 /*-------------------------------------------------------------
1817 **      _DtControlDoPushAnimation
1818 **              Do Push animation.
1819 **-------------------------------------------------------------
1820 */
1821 void 
1822 _DtControlDoPushAnimation(
1823         Widget w )
1824 {
1825   DtControlGadget        g = (DtControlGadget) w;
1826   XtAppContext           app_context = XtWidgetToApplicationContext (w);
1827   
1828   if ((G_NumPushImages (g) > 0) && (G_PushImagePosition (g) == 0))
1829     {
1830       G_PushImagePosition (g) = 1;
1831       PushAnimationTimeout ((XtPointer) g, NULL);
1832     }
1833 }
1834
1835
1836 /*-------------------------------------------------------------
1837 **      _DtControlAddPushAnimationImage
1838 **              Add Push animation image.
1839 **-------------------------------------------------------------
1840 */
1841 void 
1842 _DtControlAddPushAnimationImage(
1843         Widget w,
1844         String image,
1845         int delay )
1846 {
1847   DtControlGadget        g = (DtControlGadget) w;
1848   XmManagerWidget        mw = (XmManagerWidget) XtParent (w);
1849   int                    i;
1850   XGCValues              values;
1851   XtGCMask               value_mask;
1852   
1853   /*    Allocate blocks of animation data.
1854    */
1855   if (G_NumPushImages (g) == G_MaxPushImages (g))
1856     {
1857       G_MaxPushImages (g) += NUM_LIST_ITEMS;
1858       G_PushDelays (g) = (int*)
1859         XtRealloc ((char*) G_PushDelays (g),
1860                    G_MaxPushImages (g) *sizeof (int));
1861       G_PushPixmaps (g) = (Pixmap*)
1862         XtRealloc ((char*) G_PushPixmaps (g),
1863                    G_MaxPushImages (g) *sizeof (Pixmap));
1864       G_PushMasks (g) = (Pixmap*)
1865         XtRealloc ((char*) G_PushMasks (g),
1866                    G_MaxPushImages (g) *sizeof (Pixmap));
1867     }
1868   
1869   /*    Allocate animation image.
1870    */
1871   i = G_NumPushImages (g)++;
1872   G_PushDelays (g)[i] = delay;
1873   G_PushPixmaps (g)[i] = XmGetPixmap (XtScreen (g), image,
1874                                       G_PixmapForeground (g), 
1875                                       G_PixmapBackground (g));
1876   G_PushMasks (g)[i] = _DtGetMask (XtScreen (g), image);
1877 }
1878
1879
1880 /*-------------------------------------------------------------
1881 **      Drop Animation Timeout
1882 **              An XtTimerCallbackProc.
1883 */
1884 static void
1885 DropAnimationTimeout(
1886         XtPointer client_data,
1887         XtIntervalId *id )
1888 {
1889   DtControlGadget       g = (DtControlGadget) client_data;
1890   XtAppContext  app_context = XtWidgetToApplicationContext ((Widget) g);
1891   XtExposeProc  expose;
1892   
1893   if ((G_DropImagePosition (g) > 0) &&
1894       (G_DropImagePosition (g) <= G_NumDropImages (g)))
1895     {
1896       G_DropAnimationTimer (g) = 
1897         XtAppAddTimeOut (app_context,
1898                          G_DropDelays (g)[G_DropImagePosition (g) - 1],
1899                          DropAnimationTimeout, (XtPointer) g);
1900     }
1901   
1902   _DtProcessLock();
1903   expose = XtCoreProc((Widget)g, expose);
1904   _DtProcessUnlock();
1905   (*expose) ((Widget) g, NULL, NULL);
1906 }
1907
1908
1909 /*-------------------------------------------------------------
1910 **      _DtControlDoDropAnimation
1911 **              Do drop animation.
1912 **-------------------------------------------------------------
1913 */
1914 void 
1915 _DtControlDoDropAnimation(
1916         Widget w )
1917 {
1918   DtControlGadget        g = (DtControlGadget) w;
1919   XtAppContext           app_context = XtWidgetToApplicationContext (w);
1920   
1921   if ((G_NumDropImages (g) > 0) && (G_DropImagePosition (g) == 0))
1922     {
1923       G_DropImagePosition (g) = 1;
1924       DropAnimationTimeout ((XtPointer) g, NULL);
1925     }
1926 }
1927
1928
1929 /*-------------------------------------------------------------
1930 **      _DtControlAddDropAnimationImage
1931 **              Add drop animation image.
1932 **-------------------------------------------------------------
1933 */
1934 void 
1935 _DtControlAddDropAnimationImage(
1936         Widget w,
1937         String image,
1938         int delay )
1939 {
1940   DtControlGadget        g = (DtControlGadget) w;
1941   XmManagerWidget        mw = (XmManagerWidget) XtParent (w);
1942   int                    i;
1943   XGCValues              values;
1944   XtGCMask               value_mask;
1945   
1946   /*    Allocate blocks of animation data.
1947    */
1948   if (G_NumDropImages (g) == G_MaxDropImages (g))
1949     {
1950       G_MaxDropImages (g) += NUM_LIST_ITEMS;
1951       G_DropDelays (g) = (int*)
1952         XtRealloc ((char*) G_DropDelays (g),
1953                    G_MaxDropImages (g) *sizeof (int));
1954       G_DropPixmaps (g) = (Pixmap*)
1955         XtRealloc ((char*) G_DropPixmaps (g),
1956                    G_MaxDropImages (g) *sizeof (Pixmap));
1957       G_DropMasks (g) = (Pixmap*)
1958         XtRealloc ((char*) G_DropMasks (g),
1959                    G_MaxDropImages (g) *sizeof (Pixmap));
1960     }
1961   
1962   /*    Allocate animation image.
1963    */
1964   i = G_NumDropImages (g)++;
1965   G_DropDelays (g)[i] = delay;
1966   G_DropPixmaps (g)[i] = XmGetPixmap (XtScreen (g), image,
1967                                       G_PixmapForeground (g), 
1968                                       G_PixmapBackground (g));
1969   G_DropMasks (g)[i] = _DtGetMask (XtScreen (g), image);
1970 }
1971
1972
1973 /*-------------------------------------------------------------
1974 **      _DtControlSetFileChanged
1975 **              Set file changed.
1976 **-------------------------------------------------------------
1977 */
1978 void 
1979 _DtControlSetFileChanged(
1980         Widget w,
1981         Boolean b )
1982 {
1983   DtControlGadget       g = (DtControlGadget) w;
1984   XtExposeProc          expose;
1985   
1986   if ((G_ControlType (g) == XmCONTROL_MONITOR) ||
1987       (G_ControlType (g) == XmCONTROL_MAIL))
1988     {
1989       G_FileChanged (g) = b;
1990       _DtProcessLock();
1991       expose = XtCoreProc((Widget)g, expose);
1992       _DtProcessUnlock();
1993       (*expose) ((Widget) g, NULL, False);
1994     }
1995 }
1996
1997
1998 /*-------------------------------------------------------------
1999 **      _DtControlSetBusy
2000 **              Set busy.
2001 **-------------------------------------------------------------
2002 */
2003 void 
2004 _DtControlSetBusy(
2005         Widget w,
2006         Boolean b )
2007 {
2008   DtControlGadget        g = (DtControlGadget) w;
2009   
2010   if (G_ControlType (g) != XmCONTROL_BUSY)
2011     return;
2012   
2013   if (b)
2014     {
2015       G_BlinkElapsed (g) = 0;
2016       ++ G_Busy (g);
2017       if (G_Busy (g) == 1)
2018         {
2019           CallCallbackProc call_callback;
2020
2021           _DtProcessLock();
2022           call_callback = C_CallCallback(XtClass(g));
2023           _DtProcessUnlock();
2024           (*call_callback) ((DtIconGadget) g, G_Callback (g), XmCR_BUSY_START,
2025                             NULL);
2026           BusyTimeout ((XtPointer) w, NULL);
2027         }
2028     }
2029   else
2030     {
2031       if (G_Busy (g) > 0)
2032         --G_Busy (g);
2033     }
2034 }
2035
2036
2037 /*-------------------------------------------------------------
2038 **      _DtCreateControl
2039 **              Create a new gadget instance.
2040 **-------------------------------------------------------------
2041 */
2042 Widget 
2043 _DtCreateControl(
2044         Widget parent,
2045         String name,
2046         ArgList arglist,
2047         int argcount )
2048 {
2049         return (XtCreateWidget (name, dtControlGadgetClass, 
2050                         parent, arglist, argcount));
2051 }
2052
2053 static void
2054 ReplaceJPDate(char *date, char *jpstr, int wday)
2055 {
2056     char *s, *rp, *sp;
2057     char *p = NULL;
2058     char abday[5];
2059     char newdate[128];
2060     int i, j;
2061     size_t k;
2062     _Xstrtokparams strtok_buf;
2063
2064     s = (char *)malloc((strlen(jpstr) + 1) * sizeof(char));
2065     strcpy(s, jpstr);
2066     for(p = _XStrtok(s, ",", strtok_buf), i = 0; 
2067         p != NULL && i < wday ;
2068         p = _XStrtok(NULL, ",", strtok_buf), i++)
2069       /* EMPTY */;
2070     if(p == NULL) {
2071         free(s);
2072         return;
2073     }
2074     strcpy(abday, nl_langinfo(ABDAY_1 + wday));
2075     if((rp = strstr(date, abday)) != NULL) {
2076         for(i = 0, j = 0, sp = date; date[j] != '\0'; sp++) {
2077             if(sp == rp) {
2078                 for(k = 0; k < strlen(p); k++)
2079                     newdate[i++] = p[k];
2080                 j += strlen(abday);
2081             }
2082             else
2083                 newdate[i++] = date[j++];
2084         }
2085         newdate[i] = '\0';
2086         strcpy(date, newdate);
2087     }
2088     free(s);
2089     return;
2090 }
2091
2092 char
2093 _DtControlGetMonitorState(Widget w)
2094 {
2095     DtControlGadget      g = (DtControlGadget) w;
2096
2097     if (G_FileChanged (g))
2098        return(DtMONITOR_ON);
2099     else
2100        return(DtMONITOR_OFF);
2101 }