Add GNU LGPL headers to all .c .C and .h files
[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 <Dt/Control.h>
63 #include <Dt/ControlP.h>
64 #include <Xm/ManagerP.h>
65 #include <Dt/MacrosP.h>
66 #include <langinfo.h>
67 #include "DtWidgetI.h"
68
69
70 /********    Public Function Declarations    ********/
71
72 extern Widget _DtCreateControl( 
73                         Widget parent,
74                         String name,
75                         ArgList arglist,
76                         int argcount) ;
77
78 /********    End Public Function Declarations    ********/
79
80 /********    Static Function Declarations    ********/
81
82 static void ClickTimeout( 
83                         XtPointer client_data,
84                         XtIntervalId *id) ;
85 static void BusyTimeout( 
86                         XtPointer client_data,
87                         XtIntervalId *id) ;
88 static void DateTimeout( 
89                         XtPointer client_data,
90                         XtIntervalId *id) ;
91 static void PushAnimationTimeout( 
92                         XtPointer client_data,
93                         XtIntervalId *id) ;
94 static void DropAnimationTimeout( 
95                         XtPointer client_data,
96                         XtIntervalId *id) ;
97 static void FileCheckTimeout( 
98                         XtPointer client_data,
99                         XtIntervalId *id) ;
100 static void CheckFile( 
101                         DtControlGadget g) ;
102 static void ClassInitialize( void ) ;
103 static void ClassPartInitialize(
104                         WidgetClass cl) ;
105
106 static void Destroy (Widget);
107
108 static void Initialize( 
109                         Widget request_w,
110                         Widget new_w) ;
111 static Boolean SetValues(
112                         Widget current_w,
113                         Widget request_w,
114                         Widget new_w) ;
115 static void GetSize( 
116                         DtControlGadget g,
117                         Dimension *w,
118                         Dimension *h) ;
119 static void GetPositions( 
120                         DtControlGadget g,
121                         Position w,
122                         Position h,
123                         Dimension h_t,
124                         Dimension s_t,
125                         Position *pix_x,
126                         Position *pix_y,
127                         Position *str_x,
128                         Position *str_y) ;
129 static void Draw( 
130                         DtControlGadget g,
131                         Drawable drawable,
132                         Position x,
133                         Position y,
134                         Dimension w,
135                         Dimension h,
136                         Dimension h_t,
137                         Dimension s_t,
138                         unsigned char s_type,
139                         unsigned char fill_mode) ;
140 static void CallCallback( 
141                         DtControlGadget g,
142                         XtCallbackList cb,
143                         int reason,
144                         XEvent *event) ;
145 static void UpdateGCs( 
146                         DtControlGadget g) ;
147 static void ReplaceJPDate(
148                         char *date,
149                         char *jpstr,
150                         int wday) ;
151
152 /********    End Static Function Declarations    ********/
153
154
155 /*-------------------------------------------------------------
156 **      Public Interface
157 **-------------------------------------------------------------
158 */
159
160 WidgetClass     dtControlGadgetClass;
161
162
163 #define UNSPECIFIED_DIMENSION   9999
164 #define UNSPECIFIED_CHAR        255
165
166 #ifdef _SUN_OS
167 static const char _DtMsgIndicator_0000[] = "/var/mail/";
168 #elif defined(__osf__)
169 static const char _DtMsgIndicator_0000[] = "/usr/spool/mail/";
170 #else
171 static const char _DtMsgIndicator_0000[] = "/usr/mail/";
172 #endif
173
174 #define MAIL_DIR        _DtMsgIndicator_0000
175 #define Min(x, y)    (((x) < (y)) ? (x) : (y))
176 #define Max(x, y)    (((x) > (y)) ? (x) : (y))
177
178 #define G_Width(r)              (r -> rectangle.width)
179 #define G_Height(r)             (r -> rectangle.height)
180 \f
181 /*-------------------------------------------------------------
182 **      Resource List
183 */
184 #define R_Offset(field) \
185         XtOffset (DtControlGadget, control.field)
186 static XtResource resources[] = 
187 {
188         {
189                 "_do_update",
190                 XmCBoolean, XmRBoolean, sizeof (Boolean),
191                 R_Offset (_do_update), XmRImmediate, (XtPointer) FALSE
192         },
193         {
194                 XmNuseEmbossedText,
195                 XmCBoolean, XmRBoolean, sizeof (Boolean),
196                 R_Offset (use_embossed_text), XmRImmediate, (XtPointer) TRUE
197         },
198         {
199                 XmNpushFunction,
200                 XmCPushFunction, XmRFunction, sizeof (XtPointer),
201                 R_Offset (push_function),
202                 XmRImmediate, (XtPointer) NULL
203         },
204         {
205                 XmNpushArgument,
206                 XmCPushArgument, XmRPointer, sizeof (XtPointer),
207                 R_Offset (push_argument),
208                 XmRImmediate, (XtPointer) NULL
209         },
210         {
211                 XmNdropAction,
212                 XmCDropAction, XmRString, sizeof (String),
213                 R_Offset (drop_action),
214                 XmRImmediate, (XtPointer) NULL
215         },
216         {
217                 "pushAction",
218                 "PushAction", XmRString, sizeof (String),
219                 R_Offset (push_action),
220                 XmRImmediate, (XtPointer) NULL
221         },
222         {
223                 XmNformat,
224                 XmCFormat, XmRString, sizeof (String),
225                 R_Offset (format),
226                 XmRImmediate, (XtPointer) "%b%n%e"
227         },
228         {
229                 XmNformatJP,
230                 XmCFormatJP, XmRString, sizeof (String),
231                 R_Offset (format_jp),
232                 XmRImmediate, (XtPointer) NULL
233         },
234         {
235                 XmNsubpanel,
236                 XmCSubpanel, XmRWidget, sizeof (Widget),
237                 R_Offset (subpanel),
238                 XmRImmediate, (XtPointer) NULL
239         },
240         {
241                 XmNcontrolType,
242                 XmCControlType, XmRControlType, sizeof (unsigned char),
243                 R_Offset (control_type),
244                 XmRImmediate, (XtPointer) XmCONTROL_NONE
245         },
246         {
247                 XmNfileName,
248                 XmCString, XmRString, sizeof (XmString),
249                 R_Offset (file_name), XmRImmediate, (XtPointer) NULL
250         },
251         {
252                 XmNalternateImage,
253                 XmCAlternateImage, XmRString, sizeof (String),
254                 R_Offset (alt_image), XmRImmediate, (XtPointer) NULL
255         },
256         {
257                 XmNchime,
258                 XmCBoolean, XmRBoolean, sizeof (Boolean),
259                 R_Offset (chime), XmRImmediate, (XtPointer) FALSE
260         },
261         {
262                 XmNclientTimeoutInterval,
263                 XmCInterval, XmRInt, sizeof (int),
264                 R_Offset (max_blink_time), XmRImmediate, (XtPointer) 10000
265         },
266         {
267                 XmNwaitingBlinkRate,
268                 XmCInterval, XmRInt, sizeof (int),
269                 R_Offset (blink_time), XmRImmediate, (XtPointer) 500
270         },
271         {
272                 XmNmonitorTime,
273                 XmCInterval, XmRInt, sizeof (int),
274                 R_Offset (monitor_time), XmRImmediate, (XtPointer) 30000
275         },
276         {
277                 XmNpushButtonClickTime,
278                 XmCInterval, XmRInt, sizeof (int),
279                 R_Offset (click_time), 
280                 XmRImmediate, (XtPointer) 1000
281         },
282         {
283                 XmNuseLabelAdjustment,
284                 XmCBoolean, XmRBoolean, sizeof (Boolean),
285                 R_Offset (use_label_adj), XmRImmediate, (XtPointer) TRUE
286         }
287 };
288 #undef  R_Offset
289
290
291 static XmBaseClassExtRec       controlBaseClassExtRec = {
292     NULL,                                     /* Next extension       */
293     NULLQUARK,                                /* record type XmQmotif */
294     XmBaseClassExtVersion,                    /* version              */
295     sizeof(XmBaseClassExtRec),                /* size                 */
296     XmInheritInitializePrehook,               /* initialize prehook   */
297     XmInheritSetValuesPrehook,                /* set_values prehook   */
298     XmInheritInitializePosthook,              /* initialize posthook  */
299     XmInheritSetValuesPosthook,               /* set_values posthook  */
300     (WidgetClass)&dtControlCacheObjClassRec,  /* secondary class      */
301     XmInheritSecObjectCreate,                 /* creation proc        */
302     XmInheritGetSecResData,                   /* getSecResData        */
303     {0},                                      /* fast subclass        */
304     XmInheritGetValuesPrehook,                /* get_values prehook   */
305     XmInheritGetValuesPosthook,               /* get_values posthook  */
306     NULL,                                     /* classPartInitPrehook */
307     NULL,                                     /* classPartInitPosthook*/
308     NULL,                                     /* ext_resources        */
309     NULL,                                     /* compiled_ext_resources*/
310     0,                                        /* num_ext_resources    */
311     FALSE,                                    /* use_sub_resources    */
312     XmInheritWidgetNavigable,                 /* widgetNavigable      */
313     XmInheritFocusChange,                     /* focusChange          */
314 };
315
316 /* ext rec static initialization */
317 externaldef (xmcontrolcacheobjclassrec)
318 DtControlCacheObjClassRec dtControlCacheObjClassRec =
319 {
320   {
321       /* superclass         */    (WidgetClass) &xmExtClassRec,
322       /* class_name         */    "DtControl",
323       /* widget_size        */    sizeof(DtControlCacheObjRec),
324       /* class_initialize   */    NULL,
325       /* chained class init */    NULL,
326       /* class_inited       */    False,
327       /* initialize         */    NULL,
328       /* initialize hook    */    NULL,
329       /* realize            */    NULL,
330       /* actions            */    NULL,
331       /* num_actions        */    0,
332       /* resources          */    NULL,
333       /* num_resources      */    0,
334       /* xrm_class          */    NULLQUARK,
335       /* compress_motion    */    False,
336       /* compress_exposure  */    False,
337       /* compress enter/exit*/    False,
338       /* visible_interest   */    False,
339       /* destroy            */    NULL,
340       /* resize             */    NULL,
341       /* expose             */    NULL,
342       /* set_values         */    NULL,
343       /* set values hook    */    NULL,
344       /* set values almost  */    NULL,
345       /* get values hook    */    NULL,
346       /* accept_focus       */    NULL,
347       /* version            */    XtVersion,
348       /* callback offsetlst */    NULL,
349       /* default trans      */    NULL,
350       /* query geo proc     */    NULL,
351       /* display accelerator*/    NULL,
352       /* extension record   */    (XtPointer)NULL,
353    },
354
355    {
356       /* synthetic resources */   NULL,
357       /* num_syn_resources   */   0,
358       /* extension           */   NULL,
359    }
360 };
361         
362 \f
363 /*-------------------------------------------------------------
364 **      Class Record
365 */
366 DtControlClassRec dtControlClassRec =
367 {
368         /*      Core Part
369         */
370         {       
371                 (WidgetClass) &dtIconClassRec, /* superclass            */
372                 "Control",                      /* class_name           */
373                 sizeof (DtControlRec),          /* widget_size          */
374                 ClassInitialize,                /* class_initialize     */
375                 ClassPartInitialize,            /* class_part_initialize*/
376                 False,                          /* class_inited         */
377                 (XtInitProc) Initialize,        /* initialize           */
378                 NULL,                           /* initialize_hook      */
379                 NULL,                           /* realize              */
380                 NULL,                           /* actions              */
381                 0,                              /* num_actions          */
382                 resources,                      /* resources            */
383                 XtNumber (resources),           /* num_resources        */
384
385                 NULLQUARK,                      /* xrm_class            */
386                 True,                           /* compress_motion      */
387                 True,                           /* compress_exposure    */
388                 True,                           /* compress_enterleave  */
389                 False,                          /* visible_interest     */      
390                 Destroy,                        /* destroy              */      
391                 XtInheritResize,                /* resize               */
392                 XtInheritExpose,                /* expose               */      
393                 (XtSetValuesFunc)SetValues,     /* set_values           */      
394                 NULL,                           /* set_values_hook      */
395                 XtInheritSetValuesAlmost,       /* set_values_almost    */
396                 NULL,                           /* get_values_hook      */
397                 NULL,                           /* accept_focus         */      
398                 XtVersion,                      /* version              */
399                 NULL,                           /* callback private     */
400                 NULL,                           /* tm_table             */
401                 NULL,                           /* query_geometry       */
402                 NULL,                           /* display_accelerator  */
403                 (XtPointer)&controlBaseClassExtRec, /* extension        */
404
405         },
406
407         /*      XmGadget Part
408         */
409         {
410 (XtWidgetProc)  XmInheritBorderHighlight,       /* border_highlight     */
411 (XtWidgetProc)  XmInheritBorderUnhighlight,     /* border_unhighlight   */
412 (XtActionProc)  XmInheritArmAndActivate,        /* arm_and_activate     */
413 (XmWidgetDispatchProc)  XmInheritInputDispatch, /* input_dispatch       */
414 (XmVisualChangeProc)    XmInheritVisualChange,  /* visual_change        */
415                 NULL,                           /* get_resources        */
416                 0,                              /* num_get_resources    */
417                 XmInheritCachePart,             /* class_cache_part     */
418                 NULL,                           /* extension            */
419         },
420
421         /*      DtIcon Part
422         */
423         {
424 (GetSizeProc)   GetSize,                        /* get_size             */
425 (GetPositionProc)       GetPositions,                   /* get_positions        */
426 (DrawProc)      Draw,                           /* draw                 */
427 (CallCallbackProc)      CallCallback,                   /* call_callback        */
428 (UpdateGCsProc) UpdateGCs,                      /* update_gcs           */
429                 True,                           /* optimize_redraw      */
430                 NULL,                           /* class_cache_part     */
431                 NULL,                           /* extension            */
432         },
433
434         /*      DtControl Part
435         */
436         {
437                 NULL,                           /* class_cache_part     */
438                 NULL,                           /* extension            */
439         }
440 };
441
442
443 WidgetClass dtControlGadgetClass = (WidgetClass) &dtControlClassRec;
444
445
446 \f
447 /*-------------------------------------------------------------
448 **      Private Functions
449 **-------------------------------------------------------------
450 */
451
452 /*-------------------------------------------------------------
453 **      FileCheckTimeout
454 **              Check for change in file, reset timeout.
455 **              An XtTimerCallbackProc.
456 */
457 static void
458 FileCheckTimeout(
459         XtPointer client_data,
460         XtIntervalId *id )
461 {
462         DtControlGadget g = (DtControlGadget) client_data;
463         XtAppContext            app_context =
464                         XtWidgetToApplicationContext ((Widget) g);
465
466         CheckFile (g);
467
468         G_MonitorTimer (g) = 
469                 XtAppAddTimeOut (app_context, G_MonitorTime (g),
470                                 FileCheckTimeout, (XtPointer) g);
471 }
472
473
474 /*-------------------------------------------------------------
475 **      CheckFile
476 **              Check for change in file size
477 */
478 static void 
479 CheckFile(
480         DtControlGadget g )
481 {
482   Boolean               result;
483   Boolean               file_changed;
484   long          file_size = 0;
485   struct stat   stat_buf;
486   
487   if (stat (G_FileName (g), &stat_buf) == 0)
488     {
489       file_size = stat_buf.st_size;
490     }
491   
492   switch (G_ControlType (g))
493     {
494     case XmCONTROL_MONITOR:
495       file_changed = (file_size == 0) ? False : True;
496       break;
497
498     case XmCONTROL_MAIL:
499       if (file_size == 0)
500         file_changed = False;
501       else if (stat_buf.st_atime > stat_buf.st_mtime)
502         file_changed = False;
503       else if (file_size == G_FileSize (g))
504         file_changed = G_FileChanged (g);
505       else if (file_size > G_FileSize (g))
506         file_changed = True;
507       else
508         file_changed = False;
509       break;
510     }
511   
512   G_FileSize (g) = file_size;
513   if (file_changed != G_FileChanged (g))
514     {
515       XtExposeProc expose;
516       CallCallbackProc call_callback;
517
518       _DtProcessLock();
519       expose = XtCoreProc((Widget)g, expose);
520       call_callback = C_CallCallback(XtClass(g));
521       _DtProcessUnlock();
522
523       G_FileChanged (g) = file_changed;
524       (*call_callback) ((DtIconGadget) g, G_Callback (g), XmCR_MONITOR, NULL);
525       (*expose)((Widget)g, NULL, NULL);
526       XmUpdateDisplay ((Widget) g);
527     }
528 }
529
530
531 \f
532 /*-------------------------------------------------------------
533 **      ClickTimeout
534 **              An XtTimerCallbackProc.
535 **              
536 */
537 static void
538 ClickTimeout(
539         XtPointer client_data,
540         XtIntervalId *id )
541 {
542   DtControlGadget       g =     (DtControlGadget) client_data;
543
544   G_ClickTimer (g) = 0;
545 }
546
547
548 \f
549 /*-------------------------------------------------------------
550 **      BusyTimeout
551 **              Switch pixmap.
552 **              An XtTimerCallbackProc.
553 */
554 static void
555 BusyTimeout(
556         XtPointer client_data,
557         XtIntervalId *id )
558 {
559   DtControlGadget       g =     (DtControlGadget) client_data;
560   XtAppContext          app_context = XtWidgetToApplicationContext((Widget) g);
561   XtExposeProc          expose;
562   CallCallbackProc      call_callback;
563   
564   _DtProcessLock();
565   expose = XtCoreProc((Widget)g, expose);
566   call_callback = C_CallCallback(XtClass((Widget)g));
567   _DtProcessUnlock();
568   
569   if ((G_Busy (g) > 0) && (G_BlinkElapsed (g) < G_MaxBlinkTime (g)))
570     {
571       G_Set (g) = ! G_Set (g);
572       G_BlinkTimer (g) = 
573         XtAppAddTimeOut (app_context, G_BlinkTime (g),
574                          BusyTimeout, (XtPointer) g);
575       G_BlinkElapsed (g) += G_BlinkTime (g);
576     }
577   else
578     {
579       G_Set (g) = False;
580       G_BlinkTimer (g) = NULL;
581       G_BlinkElapsed (g) = 0;
582       G_Busy (g) = 0;
583       (*call_callback) ((DtIconGadget) g, G_Callback (g), XmCR_BUSY_STOP, NULL);
584     }
585   
586   (*expose) ((Widget) g, NULL, False);
587 }
588
589
590 \f
591 /*-------------------------------------------------------------
592 **      DateTimeout
593 **              Update date strings.
594 **              An XtTimerCallbackProc.
595 */
596 static void
597 DateTimeout(
598         XtPointer client_data,
599         XtIntervalId *id )
600 {
601   DtControlGadget       g =     (DtControlGadget) client_data;
602   XtAppContext          app_context =
603     XtWidgetToApplicationContext ((Widget) g);
604   char                  sTime[128];
605   _Xltimeparams         localtime_buf;
606   struct tm             *timeptr;
607   time_t                tse;
608   String                s1, s2, s3;
609   unsigned long         tilMidnight;
610   Boolean               old_format = False;
611   XtExposeProc          expose;
612   
613   /*    Get time string.
614    */
615   tse = time (NULL);
616   timeptr = _XLocaltime(&tse, localtime_buf);
617   strftime ((char*) sTime, 128, G_Format (g), timeptr);
618   if (g->control.format_jp != NULL && strlen(g->control.format_jp) != 0)
619     ReplaceJPDate(sTime, g->control.format_jp, timeptr->tm_wday);
620
621   /*    Break time string between date and day of week.
622    */
623   s1 = sTime;
624   s2 = strchr (sTime, '\n');
625   
626   if (s2 == NULL)
627     s3 = NULL;
628   else
629     {
630       s3 = strchr (s2+1, '\n');
631
632       if (s3 != NULL)
633         {
634           s2[0] = ' ';
635           s2 = s3;
636         }
637         
638       s2[0] = '\0';
639       s2++;
640     }
641   
642   /*    Create date string.
643    */
644   if (s1 != NULL)
645     {
646       if (s2 == NULL)
647         {
648           XmStringFree(G_String(g));
649           G_String (g) = XmStringCreate (s1, XmFONTLIST_DEFAULT_TAG);
650           XmStringExtent (G_FontList (g), G_String (g),
651                           &(G_StringWidth (g)), &(G_StringHeight (g)));
652
653           if (G_AltString (g) != NULL)
654             {
655               XmStringFree (G_AltString (g));
656               G_AltString (g) = NULL;
657               G_AltStringHeight (g) = 0;
658               G_AltStringWidth (g) = 0;
659             }
660         }
661       else
662         {
663           if (!G_UseLabelAdjustment (g))
664             {
665               /* swap s1 and s2 */
666               s3 = s1;
667               s1 = s2;
668               s2 = s3;
669             }
670           if (G_AltString (g) != NULL)
671             XmStringFree (G_AltString (g));
672           G_AltString (g) =  XmStringCreate (s1, XmFONTLIST_DEFAULT_TAG);
673           XmStringExtent (G_FontList (g), G_AltString (g),
674                           &(G_AltStringWidth (g)), &(G_AltStringHeight (g)));
675           XmStringFree(G_String(g));
676           G_String (g) = XmStringCreate (s2, XmFONTLIST_DEFAULT_TAG);
677           XmStringExtent (G_FontList (g), G_String (g),
678                           &(G_StringWidth (g)), &(G_StringHeight (g)));
679         }
680     }
681
682   /*    Update display.
683    */
684   _DtProcessLock();
685   expose = XtCoreProc((Widget)g, expose);
686   _DtProcessUnlock();
687   (*expose) ((Widget) g, NULL, False);
688   XmUpdateDisplay ((Widget) g);
689   
690   /*    Compute milliseconds until midnight:
691    *        a. compute current time in seconds
692    *        b. subtract that from number of seconds in a day.
693    *        c. multiply by 1000 to get milliseconds.
694    *    Add timeout.
695    */
696   tilMidnight = 1000 * (86400 - ((3600 * timeptr->tm_hour) +
697                                  (60 * timeptr->tm_min) +
698                                  (timeptr->tm_sec)));
699   
700   if (G_Format (g) != NULL)
701     {
702       G_DateTimer (g) = 
703         XtAppAddTimeOut (app_context, tilMidnight, 
704                          DateTimeout, (XtPointer) g);
705     }
706   else
707     {
708       G_DateTimer (g) = 0;
709     }
710 }
711
712
713 \f
714 /*-------------------------------------------------------------
715 **      Action Procs
716 **-------------------------------------------------------------
717 */
718
719
720 \f
721 /*-------------------------------------------------------------
722 **      Core Procs
723 **-------------------------------------------------------------
724 */
725
726 \f
727 /*-------------------------------------------------------------
728 **      ClassInitialize
729 */
730
731 static void
732 ClassInitialize( void )
733 {
734   controlBaseClassExtRec.record_type = XmQmotif;
735 }
736
737 \f
738 /*-------------------------------------------------------------
739 **      ClassPartInitialize
740 */
741
742 static void
743 ClassPartInitialize(
744         WidgetClass cl )
745 {
746     dtControlCacheObjClassRec.object_class.resources =
747                                  dtIconCacheObjClassRec.object_class.resources;
748
749     dtControlCacheObjClassRec.object_class.num_resources =
750                          dtIconCacheObjClassRec.object_class.num_resources;
751 }
752
753
754 \f
755 /*-------------------------------------------------------------
756 **      Initialize
757 **              Initialize a new gadget instance.
758 */
759 static void 
760 Initialize(
761         Widget request_w,
762         Widget new_w )
763 {
764   DtControlGadget       request = (DtControlGadget) request_w,
765   new = (DtControlGadget) new_w;
766   XmManagerWidget               mw = (XmManagerWidget) XtParent (new);
767   XtAppContext  app_context =
768     XtWidgetToApplicationContext (new_w);
769   String                str;
770   int           file_name_size;                         
771   XrmValue      pixVal;
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     }
908   
909   if (G_ControlType (new) == XmCONTROL_DATE)
910     {
911       Dimension w, h;
912
913       DateTimeout ((XtPointer) new_w, NULL);
914
915       if (G_Width (request) == 0 || G_Height (request) == 0)
916         {
917           GetSizeProc get_size;
918
919           _DtProcessLock();
920           get_size = C_GetSize(XtClass(new));
921           _DtProcessUnlock();
922           (*get_size) ((DtIconGadget) new, &w, &h);
923           if (G_Width (request) == 0)
924             G_Width (new) = w;
925           if (G_Height (request) == 0)
926             G_Height (new) = h;
927         }
928     }
929   
930   G_ArmedGC (new) = NULL;
931   
932   G_TopShadowGC (new) = NULL;
933   G_BottomShadowGC (new) = NULL;
934   G__DoUpdate (new) = True;
935   _DtProcessLock();
936   update_gcs = C_UpdateGCs(XtClass(new));
937   _DtProcessUnlock();
938   (*update_gcs) ((DtIconGadget) new);
939   G__DoUpdate (new) = False;
940 }
941
942
943 \f
944 /*-------------------------------------------------------------
945 **      Destroy
946 **              Release resources allocated for gadget.
947 */
948
949 static void 
950 Destroy(
951         Widget w )
952 {
953   DtControlGadget       g =     (DtControlGadget) w;
954   
955   if (G_FileName (g) != NULL)
956     XtFree (G_FileName (g));
957   
958   if (G_NumPushImages (g) > 0)
959     {
960       XtFree ((char*) G_PushDelays (g));
961       XtFree ((char*) G_PushPixmaps (g));
962       XtFree ((char*) G_PushMasks (g));
963     }
964   if (G_NumDropImages (g) > 0)
965     {
966       XtFree ((char*) G_DropDelays (g));
967       XtFree ((char*) G_DropPixmaps (g));
968       XtFree ((char*) G_DropMasks (g));
969     }
970   if (G_DropAction (g) != NULL)
971     XtFree (G_DropAction (g));
972   if (G_PushAction (g) != NULL)
973     XtFree (G_PushAction (g));
974   
975   if (G_AltString (g) != NULL)
976     XmStringFree (G_AltString (g));
977   
978   if (G_ClickTimer (g))
979     XtRemoveTimeOut (G_ClickTimer (g));
980   if (G_BlinkTimer (g))
981     XtRemoveTimeOut (G_BlinkTimer (g));
982   if (G_MonitorTimer (g))
983     XtRemoveTimeOut (G_MonitorTimer (g));
984   if (G_DateTimer (g))
985     XtRemoveTimeOut (G_DateTimer (g));
986   if (G_PushAnimationTimer (g))
987     XtRemoveTimeOut (G_PushAnimationTimer (g));
988   if (G_DropAnimationTimer (g))
989     XtRemoveTimeOut (G_DropAnimationTimer (g));
990 }
991
992
993 \f
994 /*-------------------------------------------------------------
995 **      SetValues
996 **              
997 */
998 static Boolean 
999 SetValues(
1000         Widget current_w,
1001         Widget request_w,
1002         Widget new_w )
1003 {
1004
1005
1006     DtControlGadget     request_c =     (DtControlGadget) request_w,
1007                         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   unsigned char         behavior =      G_Behavior (g);
1304   Position              adj_x, adj_y;
1305   Pixmap                pix;
1306   Pixmap                mask;
1307   int                   index;
1308   Dimension             left = 0, right = 0, top = 0, bottom = 0;
1309   Dimension             v_pad;
1310   Boolean               bClearArea = False;
1311   Boolean               bClearShadow = False;
1312   Boolean               bMono;
1313   GetPositionProc       get_positions;
1314   
1315   bMono = (((G_Foreground (g) == BlackPixelOfScreen (XtScreen (g))) ||
1316             (G_Foreground (g) == WhitePixelOfScreen (XtScreen (g)))) &&
1317            ((G_Background (g) == BlackPixelOfScreen (XtScreen (g))) ||
1318             (G_Background (g) == WhitePixelOfScreen (XtScreen (g)))) );
1319   
1320   /*    Select gc to fill background.
1321    */
1322   if (G_ControlType (g) == XmCONTROL_SWITCH)
1323     gc = bMono ? M_BackgroundGC (mgr) : G_BackgroundGC (g);
1324   else if ((G_Armed (g)) && (fill_mode != XmFILL_PARENT))
1325     gc = G_ArmedBackgroundGC (g);
1326   else
1327     gc = M_BackgroundGC (mgr); 
1328   
1329   if ((fill_mode != XmFILL_NONE) && (fill_mode != XmFILL_TRANSPARENT))
1330     bClearArea = True;
1331   
1332   /*    Select pixmap and mask.
1333    */
1334   if (G_Pixmap (g))
1335     {
1336       /*        Terminate animation sequence.
1337        */
1338       if (G_PushImagePosition (g) > G_NumPushImages (g))
1339         G_PushImagePosition (g) = 0;
1340       if (G_DropImagePosition (g) > G_NumDropImages (g))
1341         G_DropImagePosition (g) = 0;
1342
1343       /*        Use animation image.
1344        */
1345       if (G_PushImagePosition (g) > 0)
1346         {
1347           index = (G_PushImagePosition (g)) - 1;    
1348           if ((index == 0) || (bMono))
1349             bClearArea = True;
1350           else
1351             bClearArea = False;
1352           pix = G_PushPixmaps (g)[index];
1353           mask = G_PushMasks (g)[index];
1354           ++G_PushImagePosition (g);
1355         }
1356       else if (G_DropImagePosition (g) > 0)
1357         {
1358           index = G_DropImagePosition (g) - 1;
1359           if (bMono)
1360             bClearArea = True;
1361           else
1362             bClearArea = False;
1363           pix = G_DropPixmaps (g)[index];
1364           mask = G_DropMasks (g)[index];
1365           ++G_DropImagePosition (g);
1366         }
1367
1368       /*        Use alternate image.
1369        */
1370       else if ( ( ((G_ControlType (g) == XmCONTROL_MONITOR) ||
1371                    (G_ControlType (g) == XmCONTROL_MAIL)) &&
1372                  (G_AltPix (g) != XmUNSPECIFIED_PIXMAP) &&
1373                  G_FileChanged (g) ) ||
1374                ( (G_ControlType (g) == XmCONTROL_BUSY) &&
1375                 (G_AltPix (g) != XmUNSPECIFIED_PIXMAP) &&
1376                 G_Busy (g) && G_Set (g)) )
1377         {
1378           pix = G_AltPix (g);
1379           mask = G_AltMask (g);
1380         }
1381
1382       /*        Use normal image.
1383        */
1384       else
1385         {
1386           pix = G_Pixmap (g);
1387           mask = G_Mask (g);
1388         }
1389     }
1390   
1391   if (bClearShadow)
1392     {
1393       /*        Erase shadow - top, left, right, bottom.
1394        */
1395       XFillRectangle (d, drawable, gc, x + h_t, y + h_t,
1396                       w - 2 * h_t, s_t);
1397       XFillRectangle (d, drawable, gc, x + h_t, y + h_t + s_t,
1398                       s_t, h - 2 * (h_t + s_t));
1399       XFillRectangle (d, drawable, gc, x + w - h_t - s_t, y + h_t + s_t,
1400                       s_t, h - 2 * (h_t + s_t));
1401       XFillRectangle (d, drawable, gc, x + h_t, y + h - h_t - s_t,
1402                       w - 2 * h_t, s_t);
1403     }
1404   else if (bClearArea)
1405     /*  Fill background.
1406      */
1407     XFillRectangle (d, drawable, gc, x + h_t, y + h_t,
1408                     w - 2 * h_t, h - 2 * h_t);
1409   
1410   
1411   /*    Get pixmap and string positions.
1412    */
1413   _DtProcessLock();
1414   get_positions = C_GetPositions(XtClass(g));
1415   _DtProcessUnlock();
1416   (*get_positions) ((DtIconGadget) g, w, h, h_t, s_t, &p_x, &p_y, &s_x, &s_y);
1417   
1418   /*    Select and display pixmap.
1419    */
1420   if (G_Pixmap (g))
1421     {
1422
1423       /*        Compute display region.
1424        */
1425       if ((width == 0) && (height == 0))
1426         {          
1427           width = ((unsigned)(p_x + s_t + h_t) >= G_Width (g))
1428             ? 0 : Min ((unsigned)G_PixmapWidth (g),
1429                        G_Width (g) - p_x - s_t - h_t);
1430           height = ((unsigned)(p_y + s_t + h_t) >= G_Height (g))
1431             ? 0 : Min ((unsigned)G_PixmapHeight (g),
1432                        G_Height (g) - p_y - s_t - h_t);
1433         }
1434       /*        Update clip gc.
1435        */
1436       if (mask != XmUNSPECIFIED_PIXMAP)
1437         {
1438           gc = G_ClipGC (g);
1439           XSetClipMask (XtDisplay(g), gc, mask);
1440           XSetClipOrigin (XtDisplay(g), gc, x + p_x, y + p_y);
1441         }
1442       else
1443         gc = G_NormalGC (g);
1444         
1445       /*        Paint pixmap.
1446        */
1447       if ((width > 0 && height > 0) &&
1448           (gc != NULL) && (pix != XmUNSPECIFIED_PIXMAP))
1449         XCopyArea (d, pix, drawable, gc, 0, 0,
1450                    width, height, x + p_x, y + p_y);
1451     }
1452   
1453   /*    Draw string.
1454    */
1455   clip.x = x + h_t + s_t;
1456   clip.y = y + h_t + s_t;
1457   clip.width = G_Width (g) - (2 * (h_t + s_t));
1458   clip.height = G_Height (g) - (2 * (h_t + s_t));
1459   
1460   if ((G_String (g)) && (clip.width > 0 && clip.height > 0))
1461     {
1462       if (G_ControlType (g) == XmCONTROL_DATE)
1463         {
1464           if ( (G_StringHeight (g) > 0) && (G_AltStringHeight (g) > 0) )
1465             {
1466               unsigned pad_factor;
1467
1468               if (G_UseLabelAdjustment (g))
1469                 pad_factor = 3;
1470               else
1471                 pad_factor = 4;
1472
1473               v_pad = ((unsigned)G_Height(g) >
1474                        (G_StringHeight(g) + G_AltStringHeight(g))) ?
1475                          (G_Height (g) - G_StringHeight (g) - 
1476                           G_AltStringHeight (g)) / pad_factor : 0;
1477               s_y = (2 * v_pad);
1478             }
1479
1480           if (bMono)
1481             {
1482               XmStringDrawImage (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           else
1488             {
1489               if (G_UseEmbossedText (g))
1490                 XmStringDraw (d, drawable, G_FontList (g), G_String (g),
1491                               G_BottomShadowGC (g), x + s_x + 1, y + s_y + 1,
1492                               clip.width, XmALIGNMENT_BEGINNING,
1493                               XmSTRING_DIRECTION_L_TO_R, &clip);
1494               XmStringDraw (d, drawable, G_FontList (g), G_String (g),
1495                             G_NormalGC (g), x + s_x, y + s_y,
1496                             clip.width, XmALIGNMENT_BEGINNING,
1497                             XmSTRING_DIRECTION_L_TO_R, &clip);
1498             }
1499
1500           if (G_Width (g) > G_AltStringWidth (g))
1501             s_x = (G_Width (g) - G_AltStringWidth (g)) / 2U;
1502
1503           if (G_UseLabelAdjustment (g))
1504             s_y = ((G_Height (g) - G_AltStringWidth (g)) + 5);
1505           else
1506             s_y += G_StringHeight (g);
1507
1508           if (bMono)
1509             {
1510               XmStringDrawImage (d, drawable, G_FontList (g),
1511                                  G_AltString (g),
1512                                  G_NormalGC (g), x + s_x, y + s_y,
1513                                  clip.width, XmALIGNMENT_BEGINNING,
1514                                  XmSTRING_DIRECTION_L_TO_R, &clip);
1515             }
1516           else
1517             {
1518               if (G_UseEmbossedText (g))
1519                 XmStringDraw (d, drawable, G_FontList (g),
1520                               G_AltString (g),
1521                               G_BottomShadowGC (g), x + s_x + 1, y + s_y + 1,
1522                               clip.width, XmALIGNMENT_BEGINNING,
1523                               XmSTRING_DIRECTION_L_TO_R, &clip);
1524               XmStringDraw (d, drawable, G_FontList (g),
1525                             G_AltString (g),
1526                             G_NormalGC (g), x + s_x, y + s_y,
1527                             clip.width, XmALIGNMENT_BEGINNING,
1528                             XmSTRING_DIRECTION_L_TO_R, &clip);
1529             }
1530         }
1531       else
1532         {
1533           if (bMono)
1534             {
1535               if ((s_x - 2U) >= (h_t + s_t))
1536                 XFillRectangle (d, drawable, G_ArmedBackgroundGC (g),
1537                                 x + s_x - 2, y + s_y,
1538                                 2, G_StringHeight (g));
1539               XmStringDrawImage (d, drawable, G_FontList (g), G_String (g),
1540                                  G_NormalGC (g), x + s_x, y + s_y,
1541                                  clip.width, XmALIGNMENT_BEGINNING,
1542                                  XmSTRING_DIRECTION_L_TO_R, &clip);
1543               if ((s_x + G_StringWidth (g) + 2U) <= (G_Width (g) - h_t - s_t))
1544                 XFillRectangle (d, drawable, G_ArmedBackgroundGC (g),
1545                                 x + s_x + G_StringWidth (g), y + s_y,
1546                                 2, G_StringHeight (g));
1547             }
1548           else
1549             {
1550               if (G_UseEmbossedText (g))
1551                 XmStringDraw (d, drawable, G_FontList (g), G_String (g),
1552                               G_BottomShadowGC (g), x + s_x + 1, y + s_y + 1,
1553                               clip.width, XmALIGNMENT_BEGINNING,
1554                               XmSTRING_DIRECTION_L_TO_R, &clip);
1555               XmStringDraw (d, drawable, G_FontList (g), G_String (g),
1556                             G_NormalGC (g), x + s_x, y + s_y,
1557                             clip.width, XmALIGNMENT_BEGINNING,
1558                             XmSTRING_DIRECTION_L_TO_R, &clip);
1559             }
1560         }
1561     }
1562   
1563   /*    Draw shadow.
1564    */
1565   switch (G_ControlType (g))
1566     {
1567     case XmCONTROL_BLANK:
1568     case XmCONTROL_DATE:
1569       break;
1570
1571     case XmCONTROL_CLIENT:
1572       /*        Get insets.
1573        */
1574       if (bMono)
1575         /*      Use black and white.
1576          */
1577         {
1578           if (G_Foreground (g) == WhitePixelOfScreen (XtScreen (g)))
1579             {
1580               gcTS = G_BackgroundGC (g);
1581               gcBS = G_NormalGC (g);
1582             }
1583           else
1584             {
1585               gcBS = G_BackgroundGC (g);
1586               gcTS = G_NormalGC (g);
1587             }
1588         }
1589       else
1590         {
1591           gcTS = M_BottomShadowGC (mgr);
1592           gcBS = M_TopShadowGC (mgr);
1593         }
1594       /*        Drop inner shadow if secondary since no fill.
1595        */
1596       XmeDrawShadows (d, drawable, gcTS, gcBS, 
1597                       x + left - s_t, y + top - s_t,
1598                       w - left - right + (2 * s_t),
1599                       h - top - bottom + (2 * s_t),
1600                       s_t, XmSHADOW_ETCHED_OUT);
1601       break;
1602
1603     default:
1604     case XmCONTROL_BUTTON:
1605     case XmCONTROL_MONITOR:
1606     case XmCONTROL_MAIL:
1607       switch (G_Behavior (g))
1608         {
1609         case XmICON_BUTTON:
1610           if (G_Armed (g))
1611             XmeDrawShadows(d, drawable, 
1612                            M_TopShadowGC(mgr), M_BottomShadowGC(mgr),
1613                            x + h_t, y + h_t,
1614                            w - 2*h_t, h - 2*h_t, s_t, XmSHADOW_IN);
1615           break;
1616         case XmICON_TOGGLE:
1617           if ( (G_Armed (g) && !G_Set (g)) ||
1618               (!G_Armed (g) && G_Set (g)) )
1619             XmeDrawShadows(d, drawable, 
1620                            M_TopShadowGC(mgr), M_BottomShadowGC(mgr),
1621                            x + h_t, y + h_t,
1622                            w - 2*h_t, h - 2*h_t, s_t, XmSHADOW_IN);
1623           break;
1624         }
1625       break;
1626     case XmCONTROL_SWITCH:
1627       if (!G_FillOnArm (g))
1628         {
1629           gcTS = G_BottomShadowGC (g);
1630           gcBS = G_TopShadowGC (g);
1631         }
1632       else
1633         {
1634           if (G_Foreground (g) == WhitePixelOfScreen (XtScreen (g)))
1635             {
1636               gcTS = G_BackgroundGC (g);
1637               gcBS = G_NormalGC (g);
1638             }
1639           else
1640             {
1641               gcTS = G_NormalGC (g);
1642               gcBS = G_BackgroundGC (g);
1643             }
1644         }
1645       XmeDrawShadows (d, drawable, gcTS, gcBS,
1646                       x + h_t, y + h_t, w - 2*h_t, h - 2*h_t, 1,
1647                       XmSHADOW_OUT);
1648
1649       ++x;  ++y;  w -= 2;  h -= 2;  --s_t;
1650       if (s_t > 0)
1651         {
1652           if ( (G_Armed (g) && !G_Set (g)) ||
1653               (!G_Armed (g) && G_Set (g)) )
1654             {
1655               gcTS = G_BottomShadowGC (g);
1656               gcBS = G_TopShadowGC (g);
1657             }
1658           else
1659             {
1660               gcTS = G_TopShadowGC (g);
1661               gcBS = G_BottomShadowGC (g);
1662             }
1663           XmeDrawShadows (d, drawable, gcTS, gcBS,
1664                           x + h_t, y + h_t, w - 2*h_t, h - 2*h_t, s_t,
1665                           XmSHADOW_OUT);
1666         }
1667       break;
1668     }
1669 }
1670
1671
1672 /*-------------------------------------------------------------
1673 **      CallCallback
1674 **              Call callback, if any, with reason and event.
1675 */
1676 static void 
1677 CallCallback(
1678         DtControlGadget g,
1679         XtCallbackList cb,
1680         int reason,
1681         XEvent *event )
1682 {
1683   DtControlCallbackStruct       cb_data;
1684   XtAppContext  app_context = XtWidgetToApplicationContext ((Widget) g);
1685   
1686   if ((reason == XmCR_ACTIVATE) && (G_Behavior (g) == XmICON_BUTTON))
1687     {
1688       if (G_ClickTimer (g) != 0)
1689         return;
1690       else
1691         G_ClickTimer (g) = 
1692           XtAppAddTimeOut (app_context, G_ClickTime (g),
1693                            ClickTimeout, (XtPointer) g);
1694     }
1695   
1696   if (cb != NULL)
1697     {
1698       cb_data.reason = reason;
1699       cb_data.event = event;
1700       cb_data.control_type = G_ControlType (g);
1701       cb_data.set = G_Set (g);
1702       cb_data.push_function = G_PushFunction (g);
1703       cb_data.push_argument = G_PushArgument (g);
1704       cb_data.subpanel = G_Subpanel (g);
1705       cb_data.file_size = G_FileSize (g);
1706       XtCallCallbackList ((Widget) g, cb, &cb_data);
1707
1708     }
1709 }
1710
1711
1712 \f
1713 /*-------------------------------------------------------------
1714 **      UpdateGCs
1715 **              Get normal and background graphics contexts.
1716 **              Use standard mask to maximize caching opportunities.
1717 */
1718 static void 
1719 UpdateGCs(
1720         DtControlGadget g )
1721 {
1722   XGCValues             values;
1723   XtGCMask              value_mask;
1724   XmManagerWidget       mw = (XmManagerWidget) XtParent(g);
1725   XFontStruct *         font;
1726   Boolean               font_rtn;
1727   
1728   if (!G__DoUpdate (g))
1729     return;
1730   
1731   if (G_NormalGC (g))
1732     XtReleaseGC ((Widget)mw, G_NormalGC (g));
1733   if (G_ClipGC (g))
1734     XtReleaseGC ((Widget)mw, G_ClipGC (g));
1735   if (G_BackgroundGC (g))
1736     XtReleaseGC ((Widget)mw, G_BackgroundGC (g));
1737   if (G_ArmedBackgroundGC (g))
1738     XtReleaseGC ((Widget)mw, G_ArmedBackgroundGC (g));
1739   if (G_TopShadowGC (g))
1740     XtReleaseGC ((Widget)mw, G_TopShadowGC (g));
1741   if (G_BottomShadowGC (g))
1742     XtReleaseGC ((Widget)mw, G_BottomShadowGC (g));
1743   
1744   /*    Get normal GC.
1745    */
1746   font_rtn = XmeRenderTableGetDefaultFont (G_FontList (g), &font);
1747   value_mask = GCForeground | GCBackground | GCFont | GCFillStyle;
1748   if (G_UseEmbossedText (g))
1749     values.foreground = WhitePixelOfScreen (XtScreen (g));
1750   else
1751     values.foreground = G_Foreground (g);
1752   values.background = G_Background (g);
1753   
1754   values.fill_style = FillSolid;
1755   values.font = font->fid;
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   XtAppContext           app_context = XtWidgetToApplicationContext (w);
1849   
1850   if ((G_NumPushImages (g) > 0) && (G_PushImagePosition (g) == 0))
1851     {
1852       G_PushImagePosition (g) = 1;
1853       PushAnimationTimeout ((XtPointer) g, NULL);
1854     }
1855 }
1856
1857
1858 /*-------------------------------------------------------------
1859 **      _DtControlAddPushAnimationImage
1860 **              Add Push animation image.
1861 **-------------------------------------------------------------
1862 */
1863 void 
1864 _DtControlAddPushAnimationImage(
1865         Widget w,
1866         String image,
1867         int delay )
1868 {
1869   DtControlGadget        g = (DtControlGadget) w;
1870   XmManagerWidget        mw = (XmManagerWidget) XtParent (w);
1871   int                    i;
1872   XGCValues              values;
1873   XtGCMask               value_mask;
1874   
1875   /*    Allocate blocks of animation data.
1876    */
1877   if (G_NumPushImages (g) == G_MaxPushImages (g))
1878     {
1879       G_MaxPushImages (g) += NUM_LIST_ITEMS;
1880       G_PushDelays (g) = (int*)
1881         XtRealloc ((char*) G_PushDelays (g),
1882                    G_MaxPushImages (g) *sizeof (int));
1883       G_PushPixmaps (g) = (Pixmap*)
1884         XtRealloc ((char*) G_PushPixmaps (g),
1885                    G_MaxPushImages (g) *sizeof (Pixmap));
1886       G_PushMasks (g) = (Pixmap*)
1887         XtRealloc ((char*) G_PushMasks (g),
1888                    G_MaxPushImages (g) *sizeof (Pixmap));
1889     }
1890   
1891   /*    Allocate animation image.
1892    */
1893   i = G_NumPushImages (g)++;
1894   G_PushDelays (g)[i] = delay;
1895   G_PushPixmaps (g)[i] = XmGetPixmap (XtScreen (g), image,
1896                                       G_PixmapForeground (g), 
1897                                       G_PixmapBackground (g));
1898   G_PushMasks (g)[i] = _DtGetMask (XtScreen (g), image);
1899 }
1900
1901
1902 /*-------------------------------------------------------------
1903 **      Drop Animation Timeout
1904 **              An XtTimerCallbackProc.
1905 */
1906 static void
1907 DropAnimationTimeout(
1908         XtPointer client_data,
1909         XtIntervalId *id )
1910 {
1911   DtControlGadget       g = (DtControlGadget) client_data;
1912   XtAppContext  app_context = XtWidgetToApplicationContext ((Widget) g);
1913   XtExposeProc  expose;
1914   
1915   if ((G_DropImagePosition (g) > 0) &&
1916       (G_DropImagePosition (g) <= G_NumDropImages (g)))
1917     {
1918       G_DropAnimationTimer (g) = 
1919         XtAppAddTimeOut (app_context,
1920                          G_DropDelays (g)[G_DropImagePosition (g) - 1],
1921                          DropAnimationTimeout, (XtPointer) g);
1922     }
1923   
1924   _DtProcessLock();
1925   expose = XtCoreProc((Widget)g, expose);
1926   _DtProcessUnlock();
1927   (*expose) ((Widget) g, NULL, NULL);
1928 }
1929
1930
1931 /*-------------------------------------------------------------
1932 **      _DtControlDoDropAnimation
1933 **              Do drop animation.
1934 **-------------------------------------------------------------
1935 */
1936 void 
1937 _DtControlDoDropAnimation(
1938         Widget w )
1939 {
1940   DtControlGadget        g = (DtControlGadget) w;
1941   XtAppContext           app_context = XtWidgetToApplicationContext (w);
1942   
1943   if ((G_NumDropImages (g) > 0) && (G_DropImagePosition (g) == 0))
1944     {
1945       G_DropImagePosition (g) = 1;
1946       DropAnimationTimeout ((XtPointer) g, NULL);
1947     }
1948 }
1949
1950
1951 /*-------------------------------------------------------------
1952 **      _DtControlAddDropAnimationImage
1953 **              Add drop animation image.
1954 **-------------------------------------------------------------
1955 */
1956 void 
1957 _DtControlAddDropAnimationImage(
1958         Widget w,
1959         String image,
1960         int delay )
1961 {
1962   DtControlGadget        g = (DtControlGadget) w;
1963   XmManagerWidget        mw = (XmManagerWidget) XtParent (w);
1964   int                    i;
1965   XGCValues              values;
1966   XtGCMask               value_mask;
1967   
1968   /*    Allocate blocks of animation data.
1969    */
1970   if (G_NumDropImages (g) == G_MaxDropImages (g))
1971     {
1972       G_MaxDropImages (g) += NUM_LIST_ITEMS;
1973       G_DropDelays (g) = (int*)
1974         XtRealloc ((char*) G_DropDelays (g),
1975                    G_MaxDropImages (g) *sizeof (int));
1976       G_DropPixmaps (g) = (Pixmap*)
1977         XtRealloc ((char*) G_DropPixmaps (g),
1978                    G_MaxDropImages (g) *sizeof (Pixmap));
1979       G_DropMasks (g) = (Pixmap*)
1980         XtRealloc ((char*) G_DropMasks (g),
1981                    G_MaxDropImages (g) *sizeof (Pixmap));
1982     }
1983   
1984   /*    Allocate animation image.
1985    */
1986   i = G_NumDropImages (g)++;
1987   G_DropDelays (g)[i] = delay;
1988   G_DropPixmaps (g)[i] = XmGetPixmap (XtScreen (g), image,
1989                                       G_PixmapForeground (g), 
1990                                       G_PixmapBackground (g));
1991   G_DropMasks (g)[i] = _DtGetMask (XtScreen (g), image);
1992 }
1993
1994
1995 /*-------------------------------------------------------------
1996 **      _DtControlSetFileChanged
1997 **              Set file changed.
1998 **-------------------------------------------------------------
1999 */
2000 void 
2001 _DtControlSetFileChanged(
2002         Widget w,
2003         Boolean b )
2004 {
2005   DtControlGadget       g = (DtControlGadget) w;
2006   XtExposeProc          expose;
2007   
2008   if ((G_ControlType (g) == XmCONTROL_MONITOR) ||
2009       (G_ControlType (g) == XmCONTROL_MAIL))
2010     {
2011       G_FileChanged (g) = b;
2012       _DtProcessLock();
2013       expose = XtCoreProc((Widget)g, expose);
2014       _DtProcessUnlock();
2015       (*expose) ((Widget) g, NULL, False);
2016     }
2017 }
2018
2019
2020 /*-------------------------------------------------------------
2021 **      _DtControlSetBusy
2022 **              Set busy.
2023 **-------------------------------------------------------------
2024 */
2025 void 
2026 _DtControlSetBusy(
2027         Widget w,
2028         Boolean b )
2029 {
2030   DtControlGadget        g = (DtControlGadget) w;
2031   
2032   if (G_ControlType (g) != XmCONTROL_BUSY)
2033     return;
2034   
2035   if (b)
2036     {
2037       G_BlinkElapsed (g) = 0;
2038       ++ G_Busy (g);
2039       if (G_Busy (g) == 1)
2040         {
2041           CallCallbackProc call_callback;
2042
2043           _DtProcessLock();
2044           call_callback = C_CallCallback(XtClass(g));
2045           _DtProcessUnlock();
2046           (*call_callback) ((DtIconGadget) g, G_Callback (g), XmCR_BUSY_START,
2047                             NULL);
2048           BusyTimeout ((XtPointer) w, NULL);
2049         }
2050     }
2051   else
2052     {
2053       if (G_Busy (g) > 0)
2054         --G_Busy (g);
2055     }
2056 }
2057
2058
2059 /*-------------------------------------------------------------
2060 **      _DtCreateControl
2061 **              Create a new gadget instance.
2062 **-------------------------------------------------------------
2063 */
2064 Widget 
2065 _DtCreateControl(
2066         Widget parent,
2067         String name,
2068         ArgList arglist,
2069         int argcount )
2070 {
2071         return (XtCreateWidget (name, dtControlGadgetClass, 
2072                         parent, arglist, argcount));
2073 }
2074
2075 static void
2076 ReplaceJPDate(char *date, char *jpstr, int wday)
2077 {
2078     char *s, *rp, *sp;
2079     char *p = NULL;
2080     char abday[5];
2081     char newdate[128];
2082     int i, j;
2083     size_t k;
2084     _Xstrtokparams strtok_buf;
2085
2086     s = (char *)malloc((strlen(jpstr) + 1) * sizeof(char));
2087     strcpy(s, jpstr);
2088     for(p = _XStrtok(s, ",", strtok_buf), i = 0; 
2089         p != NULL && i < wday ;
2090         p = _XStrtok(NULL, ",", strtok_buf), i++)
2091       /* EMPTY */;
2092     if(p == NULL) {
2093         free(s);
2094         return;
2095     }
2096     strcpy(abday, nl_langinfo(ABDAY_1 + wday));
2097     if((rp = strstr(date, abday)) != NULL) {
2098         for(i = 0, j = 0, sp = date; date[j] != '\0'; sp++) {
2099             if(sp == rp) {
2100                 for(k = 0; k < strlen(p); k++)
2101                     newdate[i++] = p[k];
2102                 j += strlen(abday);
2103             }
2104             else
2105                 newdate[i++] = date[j++];
2106         }
2107         newdate[i] = '\0';
2108         strcpy(date, newdate);
2109     }
2110     free(s);
2111     return;
2112 }
2113
2114 char
2115 _DtControlGetMonitorState(Widget w)
2116 {
2117     DtControlGadget      g = (DtControlGadget) w;
2118
2119     if (G_FileChanged (g))
2120        return(DtMONITOR_ON);
2121     else
2122        return(DtMONITOR_OFF);
2123 }