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