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