dtcalc: change from obsoleted MAXFLOAT to FLT_MAX from std C
[oweals/cde.git] / cde / lib / DtWidget / Icon.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: Icon.c /main/20 1999/09/08 10:44:52 mgreess $
24  *
25  * (c) Copyright 1996 Digital Equipment Corporation.
26  * (c) Copyright 1990,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:           Icon.c
37 ***
38 ***     project:        MotifPlus Widgets
39 ***
40 ***     description:    Source code for DtIconGadget class.
41 ***     
42 ***-------------------------------------------------------------------*/
43
44
45 /*-------------------------------------------------------------
46 **      Include Files
47 */
48
49 #include <stdio.h>
50 #ifdef __apollo
51 #include <sys/types.h>
52 #endif
53 #include <sys/stat.h>
54 #include <X11/Xatom.h>
55 #include <Xm/XmP.h>
56 #include <Xm/CacheP.h>
57 #include <Xm/ManagerP.h>
58 #include <Xm/PrimitiveP.h>
59 #include <Xm/DrawP.h>
60 #include <Dt/IconP.h>
61 #include <Dt/MacrosP.h>
62 #include <Dt/DtMsgsP.h>
63 #include <Dt/Dnd.h>
64 #include "DtWidgetI.h"
65 #include "DtSvcInternal.h"
66
67 #include <Xm/XmPrivate.h>  /* Motif _XmEnterGadget and friends */
68
69 /*-------------------------------------------------------------
70 **      Public Interface
71 **-------------------------------------------------------------
72 */
73
74 WidgetClass     dtIconGadgetClass;
75
76 #define Min(x, y)    (((x) < (y)) ? (x) : (y))
77 #define Max(x, y)    (((x) > (y)) ? (x) : (y))
78 #define Limit(x, lim)  (((lim) == 0 || (x) <= (lim))? (x): (lim))
79
80 /*-------------------------------------------------------------
81 **      Forward Declarations
82 */
83
84 extern void     _DtRegisterNewConverters ( void );
85 extern char *   _XmExtObjAlloc(int size);
86 extern void     _XmExtObjFree(XtPointer element);
87 extern void     _XmSelectColorDefault ( Widget, int, XrmValue * );
88 /* From XmP.h */
89 extern void _XmExtImportArgs( Widget w, ArgList args, Cardinal *num_args);
90 /* From TravActI.h */
91 extern void _XmEnterGadget( Widget wid, XEvent *event, String*,Cardinal*);
92
93 #define SPACING_DEFAULT         2
94 #define MARGIN_DEFAULT          2
95 #define UNSPECIFIED_DIMENSION   9999
96 #define UNSPECIFIED_CHAR        255
97
98 #define WARN_ALIGNMENT          _DtMsgIcon_0000
99 #define WARN_BEHAVIOR           _DtMsgIcon_0001
100 #define WARN_FILL_MODE          _DtMsgIcon_0002
101 #define WARN_PIXMAP_POSITION    _DtMsgIcon_0003
102 #define WARN_MARGIN             _DtMsgIcon_0004
103 #define WARN_SHADOW_TYPE        _DtMsgIcon_0005
104
105
106 #define MgrParent(g) ((XmManagerWidget) (XmIsManager(XtParent(g)) ? (XtParent(g)) : (XtParent(XtParent(g)))))
107
108 /********    Private Function Declarations    ********/
109
110 extern void _DtIconRegisterDropsite(
111                         Widget w) ;
112
113 /********    End Private Function Declarations    ********/
114
115
116 /********    Static Function Declarations    ********/
117
118 static int IconCacheCompare( 
119                         XtPointer A,
120                         XtPointer B) ;
121
122 static void ReCacheIcon_r( 
123                         DtIconCacheObjPart *cache,
124                         DtIconGadget g);
125
126 static void GetDefaultBackground( 
127                         Widget g,
128                         int offset,
129                         XrmValue *value) ;
130 static void GetDefaultForeground( 
131                         Widget g,
132                         int offset,
133                         XrmValue *value) ;
134 static void GetDefaultFillMode( 
135                         Widget w,
136                         int offset,
137                         XrmValue *value) ;
138 static void GetSpacing( 
139                         Widget w,
140                         int offset,
141                         XtArgVal *value) ;
142 static void GetString( 
143                         Widget w,
144                         int offset,
145                         XtArgVal *value) ;
146 static void IconEventHandler( 
147                         Widget w,
148                         XtPointer client_data,
149                         XButtonEvent *event) ;
150 static void ClickTimeout( 
151                         Widget w,
152                         XtIntervalId *id) ;
153 static void IconArm( 
154                         Widget w,
155                         XEvent *event) ;
156 static void IconDisarm( 
157                         Widget w,
158                         XEvent *event) ;
159 static void IconActivate( 
160                         Widget w,
161                         XEvent *event) ;
162 static void IconDrag( 
163                         Widget w,
164                         XEvent *event) ;
165 static void IconPopup( 
166                         Widget w,
167                         XEvent *event) ;
168 static void IconEnter( 
169                         Widget w,
170                         XEvent *event) ;
171 static void IconLeave( 
172                         Widget w,
173                         XEvent *event) ;
174 static void ClassInitialize( void ) ;
175 static void SecondaryObjectCreate( 
176                         Widget req,
177                         Widget new_w,
178                         ArgList args,
179                         Cardinal *num_args) ;
180 static void InitializePosthook( 
181                         Widget req,
182                         Widget new,
183                         ArgList args,
184                         Cardinal *num_args) ;
185 static Boolean SetValuesPrehook( 
186                         Widget oldParent,
187                         Widget refParent,
188                         Widget newParent,
189                         ArgList args,
190                         Cardinal *num_args) ;
191 static void GetValuesPrehook( 
192                         Widget newParent,
193                         ArgList args,
194                         Cardinal *num_args) ;
195 static void GetValuesPosthook( 
196                         Widget new,
197                         ArgList args,
198                         Cardinal *num_args) ;
199 static Boolean SetValuesPosthook( 
200                         Widget current,
201                         Widget req,
202                         Widget new,
203                         ArgList args,
204                         Cardinal *num_args) ;
205 static void QualifyIconLocalCache( 
206                         DtIconGadget g,
207                         DtIconCacheObjPart *cache);
208 static void Initialize( 
209                         Widget request_w,
210                         Widget new_w) ;
211 static void Destroy( 
212                         Widget w) ;
213 static void Resize( 
214                         Widget w) ;
215 static void Redisplay( 
216                         Widget w,
217                         XEvent *event,
218                         Region region) ;
219 static Boolean SetValues( 
220                         Widget current_w,
221                         Widget request_w,
222                         Widget new_w) ;
223 static void BorderHighlight(
224                         DtIconGadget g) ;
225 static void BorderUnhighlight(
226                         DtIconGadget g) ;
227 static void ArmAndActivate( 
228                         Widget w,
229                         XEvent *event) ;
230 static void InputDispatch( 
231                         Widget w,
232                         XButtonEvent *event,
233                         Mask event_mask) ;
234 static Boolean VisualChange( 
235                         Widget w,
236                         Widget current_w,
237                         Widget new_w) ;
238 static void GetSize( 
239                         DtIconGadget g,
240                         Dimension *w,
241                         Dimension *h) ;
242 static void GetPositions( 
243                         DtIconGadget g,
244                         Position w,
245                         Position h,
246                         Dimension h_t,
247                         Dimension s_t,
248                         Position *pix_x,
249                         Position *pix_y,
250                         Position *str_x,
251                         Position *str_y) ;
252 static void Draw( 
253                         DtIconGadget g,
254                         Drawable drawable,
255                         Position x,
256                         Position y,
257                         Dimension w,
258                         Dimension h,
259                         Dimension h_t,
260                         Dimension s_t,
261                         unsigned char s_type,
262                         unsigned char fill_mode) ;
263 static void CallCallback( 
264                         DtIconGadget g,
265                         XtCallbackList cb,
266                         int reason,
267                         XEvent *event) ;
268 static void UpdateGCs( 
269                         DtIconGadget g) ;
270 static Cardinal GetIconClassSecResData( 
271                         WidgetClass class,
272                         XmSecondaryResourceData **data_rtn) ;
273 static XtPointer GetIconClassResBase( 
274                         Widget widget,
275                         XtPointer client_data) ;
276 static Boolean LoadPixmap( 
277                         DtIconGadget new,
278                         String pixmap) ;
279 static void ClassPartInitialize ( WidgetClass   wc);
280 static void HighlightBorder( Widget w );
281 static void UnhighlightBorder( Widget w );
282
283 /********    End Static Function Declarations    ********/
284
285 /*      External Cache Procs
286 */
287 extern void _XmCacheDelete( XtPointer data );
288 extern void _XmCacheCopy( XtPointer src, XtPointer dest, size_t size );
289 extern Cardinal _XmSecondaryResourceData( XmBaseClassExt, XmSecondaryResourceData **, 
290                           XtPointer, String, String, XmResourceBaseProc);
291 extern XtPointer _XmCachePart( XmCacheClassPartPtr cp, XtPointer cpart, size_t  size );
292
293 \f
294 /*-------------------------------------------------------------
295 **      Resource List
296 */
297 #define I_Offset(field) \
298         XtOffset (DtIconGadget, icon.field)
299
300 #define I_Cache_Offset(field) \
301         XtOffset (DtIconCacheObject, icon_cache.field)
302
303 static XtResource resources[] = 
304 {
305         {
306                 XmNset,
307                 XmCSet, XmRBoolean, sizeof (Boolean),
308                 I_Offset (set), XmRImmediate, (XtPointer) False
309         },
310         {
311                 XmNshadowType,
312                 XmCShadowType, XmRShadowType, sizeof (unsigned char),
313                 I_Offset (shadow_type),
314                 XmRImmediate, (XtPointer) XmSHADOW_ETCHED_OUT
315         },
316         {
317                 XmNborderType,
318                 XmCBorderType, XmRBorderType, sizeof (unsigned char),
319                 I_Offset (border_type),
320                 XmRImmediate, (XtPointer) DtRECTANGLE
321         },
322         {
323                 XmNcallback,
324                 XmCCallback, XmRCallback, sizeof (XtCallbackList),
325                 I_Offset (callback), XmRImmediate, (XtPointer) NULL
326         },
327         {
328                 XmNfontList,
329                 XmCFontList, XmRFontList, sizeof (XmFontList),
330                 I_Offset (font_list), XmRString, "Fixed"
331         },
332         {
333                 XmNimageName,
334                 XmCString, XmRString, sizeof (XmString),
335                 I_Offset (image_name), XmRImmediate, (XtPointer) NULL
336         },
337         {
338                 XmNpixmap,
339                 XmCPixmap, XmRPixmap, sizeof (Pixmap),
340                 I_Offset (pixmap),
341                 XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
342         },
343         {
344                 XmNstring,
345                 XmCXmString, XmRXmString, sizeof (XmString),
346                 I_Offset (string),
347                 XmRImmediate, (XtPointer) XmUNSPECIFIED_STRING
348         },
349         {
350                 XmNpixmapForeground,
351                 XmCForeground, XmRPixel, sizeof (Pixel),
352                 I_Offset (pixmap_foreground),
353                 XmRCallProc, (XtPointer) GetDefaultForeground
354         },
355         {
356                 XmNpixmapBackground,
357                 XmCBackground, XmRPixel, sizeof (Pixel),
358                 I_Offset (pixmap_background),
359                 XmRCallProc, (XtPointer) GetDefaultBackground
360         },
361         {
362                 XmNmaxPixmapWidth,
363                 XmCMaxWidth, XmRHorizontalDimension, sizeof (Dimension),
364                 I_Offset (max_pixmap_width), XmRImmediate, (XtPointer) 0
365         },
366         {
367                 XmNmaxPixmapHeight,
368                 XmCMaxHeight, XmRVerticalDimension, sizeof (Dimension),
369                 I_Offset (max_pixmap_height), XmRImmediate, (XtPointer) 0
370         },
371         {
372                 XmNunderline,
373                 XmCUnderline, XmRBoolean, sizeof (Boolean),
374                 I_Offset (underline), XmRImmediate, (XtPointer) False
375         },
376         {
377                 XmNdropSiteOperations, XmCDropSiteOperations,
378                 XmRDropSiteOperations, sizeof(unsigned char),
379                 I_Offset(operations), XmRImmediate, (XtPointer) XmDROP_NOOP
380         },
381         {
382                 XmNdropCallback,
383                 XmCDropCallback, XmRCallback, sizeof (XtCallbackList),
384                 I_Offset (drop_callback), XmRImmediate, (XtPointer) NULL
385         }
386 };
387
388
389 static XtResource cache_resources[] =
390 {
391         {
392                 XmNbehavior,
393                 XmCBehavior, XmRBehavior, sizeof (unsigned char),
394                 I_Cache_Offset (behavior),
395                 XmRImmediate, (XtPointer) XmICON_BUTTON
396         },
397         {
398                 XmNrecomputeSize,
399                 XmCRecomputeSize, XmRBoolean, sizeof (Boolean),
400                 I_Cache_Offset (recompute_size), XmRImmediate, (XtPointer) True
401         },
402         {
403                 "drawShadow",
404                 "DrawShadow", XmRBoolean, sizeof (Boolean),
405                 I_Cache_Offset (draw_shadow), XmRImmediate, (XtPointer) False
406         },
407         {
408                 XmNfillOnArm,
409                 XmCFillOnArm, XmRBoolean, sizeof (Boolean),
410                 I_Cache_Offset (fill_on_arm), XmRImmediate, (XtPointer) True
411         },
412         {
413                 XmNforeground,
414                 XmCForeground, XmRPixel, sizeof (Pixel),
415                 I_Cache_Offset (foreground),
416                 XmRCallProc, (XtPointer) GetDefaultForeground
417         },
418         {
419                 XmNbackground,
420                 XmCBackground, XmRPixel, sizeof (Pixel),
421                 I_Cache_Offset (background),
422                 XmRCallProc, (XtPointer) GetDefaultBackground
423         },
424         {
425                 XmNarmColor,
426                 XmCArmColor, XmRPixel, sizeof (Pixel),
427                 I_Cache_Offset (arm_color),
428                 XmRCallProc, (XtPointer) _XmSelectColorDefault
429         },
430         {
431                 XmNspacing,
432                 XmCSpacing, XmRHorizontalDimension, sizeof (Dimension),
433                 I_Cache_Offset (spacing),
434                 XmRImmediate, (XtPointer) UNSPECIFIED_DIMENSION
435         },
436         {
437                 XmNmarginHeight,
438                 XmCMarginHeight, XmRVerticalDimension, sizeof (Dimension),
439                 I_Cache_Offset (margin_height),
440                 XmRImmediate, (XtPointer) UNSPECIFIED_DIMENSION
441         },
442         {
443                 XmNmarginWidth,
444                 XmCMarginWidth, XmRHorizontalDimension, sizeof (Dimension),
445                 I_Cache_Offset (margin_width),
446                 XmRImmediate, (XtPointer) UNSPECIFIED_DIMENSION
447         },
448         {
449                 XmNpixmapPosition,
450                 XmCPixmapPosition, XmRPixmapPosition, sizeof (unsigned char),
451                 I_Cache_Offset (pixmap_position),
452                 XmRImmediate, (XtPointer) UNSPECIFIED_CHAR
453         },
454         {
455                 XmNstringPosition,
456                 XmCStringPosition, XmRStringPosition, sizeof (unsigned char),
457                 I_Cache_Offset (string_position),
458                 XmRImmediate, (XtPointer) UNSPECIFIED_CHAR
459         },
460         {
461                 XmNalignment,
462                 XmCAlignment, XmRAlignment, sizeof (unsigned char),
463                 I_Cache_Offset (alignment),
464                 XmRImmediate, (XtPointer) XmALIGNMENT_BEGINNING
465         },
466         {
467                 XmNfillMode,
468                 XmCFillMode, XmRFillMode, sizeof (unsigned char),
469                 I_Cache_Offset (fill_mode),
470                 XmRCallProc, (XtPointer) GetDefaultFillMode
471         }
472 };
473
474
475 static XmSyntheticResource syn_resources[] =
476 {
477         {
478                 XmNstring, sizeof (XmString),
479                 I_Offset (string), GetString,
480                 (XmImportProc) NULL
481         },
482 };
483
484
485 static XmSyntheticResource cache_syn_resources[] =
486 {
487         {
488                 XmNspacing, sizeof (Dimension),
489                 I_Cache_Offset (spacing), GetSpacing,
490                 (XmImportProc) NULL
491         },
492         {
493                 XmNmarginWidth, sizeof (Dimension),
494                 I_Cache_Offset (margin_width),
495                 XmeFromHorizontalPixels, 
496                 (XmImportProc)XmeToHorizontalPixels
497         },
498         {
499                 XmNmarginHeight, sizeof (Dimension),
500                 I_Cache_Offset (margin_height),
501                 XmeFromVerticalPixels, 
502                 (XmImportProc)XmeToVerticalPixels, 
503         }
504 };
505
506 #undef  I_Offset
507 #undef  I_Cache_Offset
508         
509 \f
510 /*-------------------------------------------------------------
511 **      Cache Class Record
512 */
513
514 static XmCacheClassPart IconClassCachePart = {
515         {NULL, 0, 0},            /* head of class cache list */
516         _XmCacheCopy,           /* Copy routine         */
517         _XmCacheDelete,         /* Delete routine       */
518         IconCacheCompare,       /* Comparison routine   */
519 };
520
521 /*-------------------------------------------------------------
522 **      Base Class Extension Record
523 */
524 static XmBaseClassExtRec       iconBaseClassExtRec = {
525     NULL,                                     /* Next extension       */
526     NULLQUARK,                                /* record type XmQmotif */
527     XmBaseClassExtVersion,                    /* version              */
528     sizeof(XmBaseClassExtRec),                /* size                 */
529     XmInheritInitializePrehook,               /* initialize prehook   */
530     SetValuesPrehook,                         /* set_values prehook   */
531     InitializePosthook,                       /* initialize posthook  */
532     SetValuesPosthook,                        /* set_values posthook  */
533     (WidgetClass)&dtIconCacheObjClassRec,     /* secondary class      */
534     (XtInitProc)SecondaryObjectCreate,        /* creation proc        */
535     (XmGetSecResDataFunc) GetIconClassSecResData,    /* getSecResData */
536     {0},                                      /* fast subclass        */
537     GetValuesPrehook,                         /* get_values prehook   */
538     GetValuesPosthook,                        /* get_values posthook  */
539     NULL,                                     /* classPartInitPrehook */
540     NULL,                                     /* classPartInitPosthook*/
541     NULL,                                     /* ext_resources        */
542     NULL,                                     /* compiled_ext_resources*/
543     0,                                        /* num_ext_resources    */
544     FALSE,                                    /* use_sub_resources    */
545     XmInheritWidgetNavigable,                 /* widgetNavigable      */
546     XmInheritFocusChange,                     /* focusChange          */
547 };
548
549 /*-------------------------------------------------------------
550 **      Icon Cache Object Class Record
551 */
552 externaldef (dticoncacheobjclassrec)
553 DtIconCacheObjClassRec dtIconCacheObjClassRec =
554 {
555   {
556       /* superclass         */    (WidgetClass) &xmExtClassRec,
557       /* class_name         */    "DtIcon",
558       /* widget_size        */    sizeof(DtIconCacheObjRec),
559       /* class_initialize   */    NULL,
560       /* chained class init */    NULL,
561       /* class_inited       */    False,
562       /* initialize         */    NULL,
563       /* initialize hook    */    NULL,
564       /* realize            */    NULL,
565       /* actions            */    NULL,
566       /* num_actions        */    0,
567       /* resources          */    cache_resources,
568       /* num_resources      */    XtNumber(cache_resources),
569       /* xrm_class          */    NULLQUARK,
570       /* compress_motion    */    False,
571       /* compress_exposure  */    False,
572       /* compress enter/exit*/    False,
573       /* visible_interest   */    False,
574       /* destroy            */    NULL,
575       /* resize             */    NULL,
576       /* expose             */    NULL,
577       /* set_values         */    NULL,
578       /* set values hook    */    NULL,
579       /* set values almost  */    NULL,
580       /* get values hook    */    NULL,
581       /* accept_focus       */    NULL,
582       /* version            */    XtVersion,
583       /* callback offsetlst */    NULL,
584       /* default trans      */    NULL,
585       /* query geo proc     */    NULL,
586       /* display accelerator*/    NULL,
587       /* extension record   */    NULL,
588    },
589
590    {
591       /* synthetic resources */   cache_syn_resources,
592       /* num_syn_resources   */   XtNumber(cache_syn_resources),
593       /* extension           */   NULL,
594    },
595 };
596
597 /*-------------------------------------------------------------
598 **      Class Record
599 */
600 externaldef (dticonclassrec)
601 DtIconClassRec dtIconClassRec =
602 {
603         /*      Core Part
604         */
605         {       
606                 (WidgetClass) &xmGadgetClassRec, /* superclass          */
607                 "DtIcon",                       /* class_name           */
608                 sizeof (DtIconRec),             /* widget_size          */
609                 ClassInitialize,                /* class_initialize     */
610                 ClassPartInitialize,            /* class_part_initialize*/
611                 False,                          /* class_inited         */
612                 (XtInitProc) Initialize,        /* initialize           */
613                 NULL,                           /* initialize_hook      */
614                 NULL,                           /* realize              */
615                 NULL,                           /* actions              */
616                 0,                              /* num_actions          */
617                 resources,                      /* resources            */
618                 XtNumber (resources),           /* num_resources        */
619                 NULLQUARK,                      /* xrm_class            */
620                 True,                           /* compress_motion      */
621                 True,                           /* compress_exposure    */
622                 True,                           /* compress_enterleave  */
623                 False,                          /* visible_interest     */      
624                 (XtWidgetProc) Destroy,         /* destroy              */      
625                 (XtWidgetProc) Resize,          /* resize               */
626                 (XtExposeProc) Redisplay,       /* expose               */      
627                 (XtSetValuesFunc) SetValues,    /* set_values           */      
628                 NULL,                           /* set_values_hook      */
629                 XtInheritSetValuesAlmost,       /* set_values_almost    */
630                 NULL,                           /* get_values_hook      */
631                 NULL,                           /* accept_focus         */      
632                 XtVersion,                      /* version              */
633                 NULL,                           /* callback private     */
634                 NULL,                           /* tm_table             */
635                 NULL,                           /* query_geometry       */
636                 NULL,                           /* display_accelerator  */
637                 (XtPointer)&iconBaseClassExtRec,/* extension            */
638         },
639
640         /*      XmGadget Part
641         */
642         {
643         (XtWidgetProc)  BorderHighlight,        /* border_highlight     */
644         (XtWidgetProc)  BorderUnhighlight,      /* border_unhighlight   */
645         (XtActionProc)  ArmAndActivate,         /* arm_and_activate     */
646         (XmWidgetDispatchProc)  InputDispatch,  /* input_dispatch       */
647         (XmVisualChangeProc)    VisualChange,   /* visual_change        */
648                 syn_resources,                  /* get_resources        */
649                 XtNumber (syn_resources),       /* num_get_resources    */
650                 &IconClassCachePart,            /* class_cache_part     */
651                 NULL,                           /* extension            */
652         },
653
654         /*      DtIconGadget Part
655         */
656         {
657                 GetSize,                        /* get_size             */
658                 GetPositions,                   /* get_positions        */
659                 Draw,                           /* draw                 */
660                 CallCallback,                   /* call_callback        */
661                 UpdateGCs,                      /* update_gcs           */
662                 True,                           /* optimize_redraw      */
663                 NULL,                           /* class_cache_part     */
664                 NULL,                           /* extension            */
665         }
666 };
667
668
669 externaldef (dticongadgetclass) WidgetClass dtIconGadgetClass = (WidgetClass) &dtIconClassRec;
670
671 \f
672 /*-------------------------------------------------------------
673 **      Private Functions
674 **-------------------------------------------------------------
675 */
676
677 /************************************************************************
678  *
679  *  The border highlighting and unhighlighting routines.
680  *
681  *  These routines were originally in Obsolete.c but can not depend
682  *  on these routines to live forever. Therefore, copied into my
683  *  own space.
684  *
685  ************************************************************************/
686
687 static void
688 HighlightBorder(
689         Widget w )
690 {
691   XtWidgetProc border_highlight;
692
693   if (XmIsPrimitive(w)) {
694     _DtProcessLock();
695     border_highlight = xmPrimitiveClassRec.primitive_class.border_highlight;
696     _DtProcessUnlock();
697     (*border_highlight) (w);
698   } else if (XmIsGadget(w)) {
699     _DtProcessLock();
700     border_highlight = xmGadgetClassRec.gadget_class.border_highlight;
701     _DtProcessUnlock();
702     (*border_highlight) (w);
703   }
704 }
705
706 static void
707 UnhighlightBorder(
708         Widget w )
709 {
710   XtWidgetProc border_unhighlight;
711
712   if (XmIsPrimitive(w)) {
713     _DtProcessLock();
714     border_unhighlight = xmPrimitiveClassRec.primitive_class.border_unhighlight;
715     _DtProcessUnlock();
716     (*border_unhighlight) (w);
717   } else if (XmIsGadget(w)) {
718     _DtProcessLock();
719     border_unhighlight = xmGadgetClassRec.gadget_class.border_unhighlight;
720     _DtProcessUnlock();
721     (*border_unhighlight) (w);
722   }
723 }
724
725
726 \f
727 /*-------------------------------------------------------------
728 **      GetMaskGC
729 **              Get normal and background graphics contexts.
730 */
731 static GC
732 GetMaskGC(
733         DtIconGadget g,
734           Position x, 
735           Position y)
736 {
737     if (G_Mask(g) != XmUNSPECIFIED_PIXMAP) {
738
739         XSetClipOrigin(XtDisplay(g),
740                        G_ClipGC(g),
741                        x, y);
742         return G_ClipGC(g);
743     }
744     else {
745         return G_NormalGC(g);
746     }
747 }
748
749 /*-------------------------------------------------------------
750 **      GetDefaultBackground
751 **              Copy background pixel from Manager parent.
752 */
753 /* ARGSUSED */
754 static void 
755 GetDefaultBackground(
756         Widget g,
757         int offset,
758         XrmValue *value )
759 {
760         static Pixel            pixel;
761         XmManagerWidget         parent = (XmManagerWidget) XtParent (g);
762
763         value->addr = (XtPointer) &pixel;
764         value->size = sizeof (Pixel);
765
766         if (XmIsManager ((Widget) parent))
767                 pixel = M_Background (parent);
768         else
769                 XmeGetDefaultPixel (g, XmBACKGROUND, offset, value);
770 }
771
772
773 /*-------------------------------------------------------------
774 **      GetDefaultForeground
775 **              Copy foreground pixel from Manager parent.
776 */
777 static void 
778 GetDefaultForeground(
779         Widget g,
780         int offset,
781         XrmValue *value )
782 {
783         static Pixel            pixel;
784         XmManagerWidget         parent = (XmManagerWidget) XtParent (g);
785
786         value->addr = (XtPointer) &pixel;
787         value->size = sizeof (Pixel);
788
789         if (XmIsManager ((Widget) parent))
790                 pixel = M_Foreground (parent);
791         else
792                 XmeGetDefaultPixel (g, XmFOREGROUND, offset, value);
793 }
794
795
796 \f
797 /*-------------------------------------------------------------
798 **      GetDefaultFillMode
799 **              Get default fill mode.
800 */
801 /* ARGSUSED */
802 static void 
803 GetDefaultFillMode(
804         Widget w,
805         int offset,
806         XrmValue *value )
807 {
808         static unsigned char    fill_mode;
809         DtIconGadget    g =     (DtIconGadget) w;
810
811         value->addr = (XtPointer) &fill_mode;
812         value->size = sizeof (unsigned char);
813
814         if (G_ShadowThickness (g) == 0)
815                 fill_mode = XmFILL_PARENT;
816         else
817                 fill_mode = XmFILL_SELF;
818 }
819
820
821 /*-------------------------------------------------------------
822 **      GetSpacing
823 **              Convert from pixels to horizontal or vertical units.
824 */
825 static void 
826 GetSpacing(
827         Widget w,
828         int offset,
829         XtArgVal *value )
830 {
831         DtIconCacheObject icon_co = (DtIconCacheObject) w;
832
833         if (G_CachePixmapPosition (icon_co) == XmPIXMAP_TOP ||
834             G_CachePixmapPosition (icon_co) == XmPIXMAP_BOTTOM ||
835             G_CachePixmapPosition (icon_co) == XmPIXMAP_MIDDLE)
836                 XmeFromVerticalPixels ((Widget)icon_co, offset, value);
837         else
838                 XmeFromHorizontalPixels ((Widget)icon_co, offset, value);
839 }
840
841
842 \f
843 /*-------------------------------------------------------------
844 **      GetString
845 **              Convert string from internal to external form.
846 */
847 /* ARGSUSED */
848 static void 
849 GetString(
850         Widget w,
851         int offset,
852         XtArgVal *value )
853 {
854         DtIconGadget    g =     (DtIconGadget) w;
855         XmString        string;
856
857         string = XmStringCopy (G_String (g));
858
859         *value = (XtArgVal) string;
860 }
861
862
863 /*-------------------------------------------------------------
864 **      IconEventHandler
865 **              Event handler for middle button events.
866 */
867 /* ARGSUSED */
868 static void 
869 IconEventHandler(
870         Widget w,
871         XtPointer client_data,
872         XButtonEvent *event )
873 {
874         DtIconGadget            g =     NULL;
875
876         g = (DtIconGadget) XmObjectAtPoint (w, event->x, event->y);
877         
878         if (!g || !DtIsIcon ((Widget)g))
879                 return;
880
881         if (event->button == Button2 || event->button == Button3)
882         {
883                 if (event->type == ButtonPress)
884                         InputDispatch ((Widget) g, event, XmARM_EVENT);
885                 else if (event->type == ButtonRelease)
886                         InputDispatch ((Widget) g, event, XmACTIVATE_EVENT);
887         }
888 }
889
890
891 \f
892 /*-------------------------------------------------------------
893 **      ClickTimeout
894 **              Clear Click flags.
895 */
896 /* ARGSUSED */
897 static void 
898 ClickTimeout(
899         Widget w,
900         XtIntervalId *id )
901 {
902         DtIconGadget    g =     (DtIconGadget) w;
903         Time            last_time, end_time;
904
905         if (! G_Armed (g))
906         {
907                 G_ClickTimerID (g) = 0;
908                 XtFree ((char *)G_ClickEvent (g));
909                 G_ClickEvent (g) = NULL;
910                 return;
911         }
912
913         last_time = XtLastTimestampProcessed (XtDisplay (g));
914                 /*
915                  * fix for bug# 4504
916                  */
917         if( G_ClickEvent (g) == NULL) return;
918
919         end_time = G_ClickEvent (g) -> time + (Time)
920                                 XtGetMultiClickTime (XtDisplay (g)); 
921
922 /*      Sync and reset timer if server interval may not have elapsed.
923 */
924         if ((last_time < end_time) && G_Sync (g))
925         {
926                 G_Sync (g) = False;
927                 XSync (XtDisplay (g), False);
928                 G_ClickTimerID (g) = 
929                         XtAppAddTimeOut (XtWidgetToApplicationContext ((Widget)g),
930                                         (unsigned long) 50, 
931                                         (XtTimerCallbackProc)ClickTimeout, 
932                                         (XtPointer) g);
933         }
934 /*      Handle Select action.
935 */
936         else
937         {
938                 CallCallbackProc call_callback;
939                 XtExposeProc expose;
940
941                 _DtProcessLock();
942                 expose = XtCoreProc(w, expose);
943                 call_callback = C_CallCallback(XtClass(w));
944                 _DtProcessUnlock();
945
946                 G_ClickTimerID (g) = 0;
947                 G_Armed (g) = False;
948                 (*call_callback) (g, G_Callback (g), XmCR_SELECT,
949                                   (XEvent *)G_ClickEvent (g));
950
951                 if ((G_Behavior (g) == XmICON_DRAG) &&
952                     (G_ShadowThickness (g) == 0))
953                 {
954                    /* Do nothing */
955                 }
956                 else
957                    (*expose) ((Widget)g, (XEvent*)G_ClickEvent (g), NULL);
958                 XtFree ((char *)G_ClickEvent (g));
959                 G_ClickEvent (g) = NULL;
960         }
961 }
962
963
964 \f
965 /*-------------------------------------------------------------
966 **      Action Procs
967 **-------------------------------------------------------------
968 */
969
970 /*-------------------------------------------------------------
971 **      IconArm
972 **              Handle Arm action.
973 */
974 static void 
975 IconArm(
976         Widget w,
977         XEvent *event )
978 {
979         DtIconGadget    g =     (DtIconGadget) w;
980
981         if (G_Armed (g) || G_Behavior (g) == XmICON_LABEL)
982                 return;
983
984         G_Armed (g) = True;
985
986         if (G_Behavior (g) == XmICON_DRAG)
987           {
988             CallCallbackProc call_callback;
989
990             _DtProcessLock();
991             call_callback = C_CallCallback(XtClass(g));
992             _DtProcessUnlock();
993             (*call_callback) (g, G_Callback (g), XmCR_ARM, event);
994           }
995
996         if ((G_Behavior (g) == XmICON_DRAG) &&
997             (G_ShadowThickness (g) == 0))
998         {
999            /* Do nothing */
1000         }
1001         else
1002           {
1003             XtExposeProc expose;
1004
1005             _DtProcessLock();
1006             expose = XtCoreProc(w, expose);
1007             _DtProcessUnlock();
1008             (*expose) ((Widget)g, event, NULL);
1009           }
1010 }
1011
1012
1013 \f
1014 /*-------------------------------------------------------------
1015 **      IconDisarm
1016 **              Handle Disarm action.
1017 */
1018 static void 
1019 IconDisarm(
1020         Widget w,
1021         XEvent *event )
1022 {
1023         DtIconGadget    g =     (DtIconGadget) w;
1024
1025         if (! G_Armed (g) || G_Behavior (g) == XmICON_LABEL)
1026                 return;
1027
1028         G_Armed (g) = False;
1029
1030 if (G_Behavior (g) == XmICON_DRAG)
1031         {
1032           CallCallbackProc call_callback;
1033           XtExposeProc expose;
1034
1035           _DtProcessLock();
1036           call_callback = C_CallCallback(XtClass(g));
1037           expose = XtCoreProc(w, expose);
1038           _DtProcessUnlock();
1039           (*call_callback) (g, G_Callback (g), XmCR_DISARM, event);
1040           (*expose) ((Widget)g, event, NULL);
1041         }
1042 }
1043
1044
1045 \f
1046 /*-------------------------------------------------------------
1047 **      IconActivate
1048 **              Handle Activate action.
1049 */
1050 static void 
1051 IconActivate(
1052         Widget w,
1053         XEvent *event )
1054 {
1055         DtIconGadget            g =     (DtIconGadget) w;
1056         unsigned long           delay;
1057         XButtonEvent *          b_event = (XButtonEvent *) event;
1058         CallCallbackProc        call_callback;
1059         XtExposeProc            expose;
1060
1061         if (! G_Armed (g))
1062                 return;
1063
1064         _DtProcessLock();
1065         call_callback = C_CallCallback(XtClass(g));
1066         expose = XtCoreProc(w, expose);
1067         _DtProcessUnlock();
1068         if (G_Behavior (g) == XmICON_BUTTON)
1069         {
1070                 G_Armed (g) = False;
1071                 (*call_callback) (g, G_Callback (g), XmCR_ACTIVATE, event);
1072                 (*expose) ((Widget)g, event, NULL);
1073         }
1074
1075         else if (G_Behavior (g) == XmICON_TOGGLE)
1076         {
1077                 G_Armed (g) = False;
1078                 G_Set (g) = ! G_Set (g);
1079                 (*call_callback) (g, G_Callback (g), XmCR_VALUE_CHANGED, event);
1080         }
1081
1082         else if (G_Behavior (g) == XmICON_DRAG)
1083         {
1084                 if (G_ClickTimerID (g))
1085                 {
1086                         G_ClickTimerID (g) = 0;
1087                         XtFree ((char *)G_ClickEvent (g));
1088                         G_ClickEvent (g) = NULL;
1089                         G_Armed (g) = False;
1090                         (*call_callback) (g, G_Callback (g),
1091                                         XmCR_DEFAULT_ACTION, event);
1092                 }
1093                 else
1094                 {
1095                         if(event->type==KeyPress){
1096                                 G_Armed(g)=False;
1097                                 (*call_callback)(g,G_Callback(g),XmCR_SELECT,event);
1098                         }else{
1099                                 delay = (unsigned long)
1100                                         XtGetMultiClickTime (XtDisplay (g));
1101                                 G_ClickEvent (g) = (XButtonEvent *)
1102                                         XtMalloc (sizeof (XButtonEvent));
1103                                 *(G_ClickEvent (g)) = *b_event;
1104                                 G_Sync (g) = True;
1105                                 G_ClickTimerID (g) =
1106                                         XtAppAddTimeOut (
1107                                                 XtWidgetToApplicationContext ((Widget)g),
1108                                                 delay, (XtTimerCallbackProc)ClickTimeout,
1109                                                 (XtPointer) g);
1110                         }
1111                 }
1112
1113                 if (G_ShadowThickness (g) > 0)
1114                    (*expose) ((Widget)g, event, NULL);
1115         }
1116 }
1117
1118
1119 \f
1120 /*-------------------------------------------------------------
1121 **      IconDrag
1122 **              Handle Drag action.
1123 */
1124 static void 
1125 IconDrag(
1126         Widget w,
1127         XEvent *event )
1128 {
1129         DtIconGadget    g =     (DtIconGadget) w;
1130
1131         if (G_Behavior (g) == XmICON_DRAG)
1132           {
1133             CallCallbackProc call_callback;
1134
1135             _DtProcessLock();
1136             call_callback = C_CallCallback(XtClass(w));
1137             _DtProcessUnlock();
1138             (*call_callback) (g, G_Callback (g), XmCR_DRAG, event);
1139           }
1140 }
1141
1142
1143 /*-------------------------------------------------------------
1144 **      IconPopup
1145 **            Handle button 3 - popup's
1146 */
1147 static void
1148 IconPopup(
1149         Widget w,
1150         XEvent *event )
1151 {
1152         DtIconGadget   g =     (DtIconGadget) w;
1153         CallCallbackProc        call_callback;
1154
1155         _DtProcessLock();
1156         call_callback = C_CallCallback(XtClass(w));
1157         _DtProcessUnlock();
1158         (*call_callback) (g, G_Callback (g), XmCR_POPUP, event);
1159 }
1160
1161
1162 \f
1163 /*-------------------------------------------------------------
1164 **      IconEnter
1165 **              Handle Enter action.
1166 */
1167 static void 
1168 IconEnter(
1169         Widget w,
1170         XEvent *event )
1171 {
1172         DtIconGadget    g =     (DtIconGadget) w;
1173
1174         _XmEnterGadget (w, (XEvent *)event,
1175                                  (String *)NULL,(Cardinal *)0);
1176
1177         if (G_Armed (g))
1178                 {
1179                 if ((G_Behavior (g) == XmICON_BUTTON) ||
1180                     (G_Behavior (g) == XmICON_TOGGLE))
1181                   {
1182                     XtExposeProc expose;
1183                     _DtProcessLock();
1184                     expose = XtCoreProc(w, expose);
1185                     _DtProcessUnlock();
1186                     (*expose) ((Widget)g, event, NULL);
1187                   }
1188                 }
1189 }
1190
1191
1192 /*-------------------------------------------------------------
1193 **      IconLeave
1194 **              Handle Leave action.
1195 */
1196 static void 
1197 IconLeave(
1198         Widget w,
1199         XEvent *event )
1200 {
1201         DtIconGadget    g =     (DtIconGadget) w;
1202
1203         _XmLeaveGadget (w, (XEvent *)event,
1204                                (String *)NULL,  (Cardinal *)0);
1205         if (G_Armed (g))
1206         {
1207         if ((G_Behavior (g) == XmICON_BUTTON) ||
1208             (G_Behavior (g) == XmICON_TOGGLE))
1209                 {
1210                   XtExposeProc expose;
1211
1212                   _DtProcessLock();
1213                   expose = XtCoreProc(w, expose);
1214                   _DtProcessUnlock();
1215
1216                   G_Armed (g) = False;
1217                   (*expose) ((Widget)g, event, NULL);
1218                   G_Armed (g) = True;
1219                 }
1220         }
1221 }
1222
1223
1224 \f
1225 /*-------------------------------------------------------------
1226 **      Core Procs
1227 **-------------------------------------------------------------
1228 */
1229
1230 /*-------------------------------------------------------------
1231 **      ClassInitialize
1232 **              Initialize gadget class.
1233 */
1234 static void 
1235 ClassInitialize( void )
1236 {
1237         _DtRegisterNewConverters ();
1238
1239         iconBaseClassExtRec.record_type = XmQmotif;
1240 }
1241
1242 /*-------------------------------------------------------------
1243 **      ClassPartInitialize
1244 **              Initialize gadget class part.
1245 */
1246 static void
1247 ClassPartInitialize (
1248         WidgetClass     wc)
1249 {
1250         DtIconGadgetClass ic =  (DtIconGadgetClass) wc;
1251         DtIconGadgetClass super = (DtIconGadgetClass) ic->rect_class.superclass;
1252
1253         if (C_GetSize (ic) == DtInheritGetSize)
1254                 C_GetSize (ic) = C_GetSize (super);
1255         if (C_GetPositions (ic) == DtInheritGetPositions)
1256                 C_GetPositions (ic) = C_GetPositions (super);
1257         if (C_Draw (ic) == DtInheritDraw)
1258                 C_Draw (ic) = C_Draw (super);
1259         if (C_CallCallback (ic) == DtInheritCallCallback)
1260                 C_CallCallback (ic) = C_CallCallback (super);
1261         if (C_UpdateGCs (ic) == DtInheritUpdateGCs)
1262                 C_UpdateGCs (ic) = C_UpdateGCs (super);
1263 }
1264
1265 /*-------------------------------------------------------------
1266 **      Cache Procs
1267 **-------------------------------------------------------------
1268 */
1269
1270 /*-------------------------------------------------------------
1271 **      IconCacheCompare
1272 **
1273 */
1274 static int 
1275 IconCacheCompare(
1276         XtPointer A,
1277         XtPointer B )
1278 {
1279    DtIconCacheObjPart *icon_inst = (DtIconCacheObjPart *) A ;
1280    DtIconCacheObjPart *icon_cache_inst = (DtIconCacheObjPart *) B ;
1281
1282    if ((icon_inst->fill_on_arm == icon_cache_inst->fill_on_arm) &&
1283        (icon_inst->recompute_size== icon_cache_inst->recompute_size) &&
1284        (icon_inst->pixmap_position== icon_cache_inst->pixmap_position) &&
1285        (icon_inst->string_position== icon_cache_inst->string_position) &&
1286        (icon_inst->alignment == icon_cache_inst->alignment) &&
1287        (icon_inst->behavior == icon_cache_inst->behavior) &&
1288        (icon_inst->draw_shadow == icon_cache_inst->draw_shadow) &&
1289        (icon_inst->fill_mode == icon_cache_inst->fill_mode) &&
1290        (icon_inst->margin_width== icon_cache_inst->margin_width) &&
1291        (icon_inst->margin_height== icon_cache_inst->margin_height) &&
1292        (icon_inst->string_height== icon_cache_inst->string_height) &&
1293        (icon_inst->spacing== icon_cache_inst->spacing) &&
1294        (icon_inst->foreground== icon_cache_inst->foreground) &&
1295        (icon_inst->background== icon_cache_inst->background) &&
1296        (icon_inst->arm_color== icon_cache_inst->arm_color))
1297        return 1;
1298    else
1299        return 0;
1300
1301 }
1302
1303
1304 /*-------------------------------------------------------------
1305 **      SecondaryObjectCreate
1306 **
1307 */
1308 static void 
1309 SecondaryObjectCreate(
1310         Widget req,
1311         Widget new_w,
1312         ArgList args,
1313         Cardinal *num_args )
1314 {
1315     XmBaseClassExt              *cePtr;
1316     XmWidgetExtData             extData;
1317     WidgetClass                 wc;
1318     Cardinal                    size;
1319     XtPointer                   newSec, reqSec;
1320     XtResourceList              resources;
1321     Cardinal                    num_resources;
1322
1323     _DtProcessLock();
1324     cePtr = _XmGetBaseClassExtPtr(XtClass(new_w), XmQmotif);
1325     wc = (*cePtr)->secondaryObjectClass;
1326     if (NULL == wc) return;
1327     size = wc->core_class.widget_size;
1328     resources = wc->core_class.resources;
1329     num_resources = wc->core_class.num_resources;
1330
1331     newSec = _XmExtObjAlloc(size);
1332     reqSec = _XmExtObjAlloc(size);
1333     _DtProcessUnlock();
1334
1335     /*
1336      * fetch the resources in superclass to subclass order
1337      */
1338
1339     XtGetSubresources(new_w, newSec, NULL, NULL, 
1340                       resources, num_resources, args, *num_args );
1341
1342     extData = (XmWidgetExtData) XtCalloc(sizeof(XmWidgetExtDataRec), 1);
1343     extData->widget = (Widget)newSec;
1344     extData->reqWidget = (Widget)reqSec;
1345
1346     ((DtIconCacheObject)newSec)->ext.extensionType = XmCACHE_EXTENSION;
1347     ((DtIconCacheObject)newSec)->ext.logicalParent = new_w;
1348
1349     _XmPushWidgetExtData(new_w, extData,
1350                          ((DtIconCacheObject)newSec)->ext.extensionType);
1351     memcpy(reqSec, newSec, size);
1352
1353     /*
1354      * fill out cache pointers
1355      */
1356     Icon_Cache(new_w) = &(((DtIconCacheObject)extData->widget)->icon_cache);
1357     Icon_Cache(req) = &(((DtIconCacheObject)extData->reqWidget)->icon_cache);
1358
1359 }
1360
1361 \f
1362 /*-------------------------------------------------------------
1363 **      InitializePostHook
1364 **
1365 */
1366 /* ARGSUSED */
1367 static void 
1368 InitializePosthook(
1369         Widget req,
1370         Widget new,
1371         ArgList args,
1372         Cardinal *num_args )
1373 {
1374     XmWidgetExtData     ext;
1375     DtIconGadget lw = (DtIconGadget)new;
1376
1377     /*
1378      * - register parts in cache.
1379      * - update cache pointers
1380      * - and free req
1381      */
1382
1383     _DtProcessLock();
1384     Icon_Cache(lw) = (DtIconCacheObjPart *)
1385            _XmCachePart( Icon_ClassCachePart(lw),
1386                          (XtPointer) Icon_Cache(lw),
1387                          sizeof(DtIconCacheObjPart));
1388
1389     /*
1390      * might want to break up into per-class work that gets explicitly
1391      * chained. For right now, each class has to replicate all
1392      * superclass logic in hook routine
1393      */
1394
1395     /*     * free the req subobject used for comparisons
1396      */
1397     _XmPopWidgetExtData((Widget) lw, &ext, XmCACHE_EXTENSION);
1398     _XmExtObjFree((XtPointer)ext->widget);
1399     _XmExtObjFree((XtPointer)ext->reqWidget);
1400     _DtProcessUnlock();
1401     XtFree( (char *) ext);
1402 }
1403
1404 /*-------------------------------------------------------------
1405 **      SetValuesPrehook
1406 **
1407 */
1408 /* ARGSUSED */
1409 static Boolean 
1410 SetValuesPrehook(
1411         Widget oldParent,
1412         Widget refParent,
1413         Widget newParent,
1414         ArgList args,
1415         Cardinal *num_args )
1416 {
1417     XmWidgetExtData             extData;
1418     XmBaseClassExt              *cePtr;
1419     WidgetClass                 ec;
1420     DtIconCacheObject          newSec, reqSec;
1421     Cardinal                    size;
1422     XtResourceList              resources;
1423     Cardinal                    num_resources;
1424
1425     _DtProcessLock();
1426     cePtr = _XmGetBaseClassExtPtr(XtClass(newParent), XmQmotif);
1427     ec = (*cePtr)->secondaryObjectClass;
1428     size = ec->core_class.widget_size;
1429     resources = ec->core_class.resources;
1430     num_resources = ec->core_class.num_resources;
1431
1432     /* allocate copies and fill from cache */
1433     newSec = (DtIconCacheObject) _XmExtObjAlloc(size);
1434     reqSec = (DtIconCacheObject) _XmExtObjAlloc(size);
1435     _DtProcessUnlock();
1436
1437     newSec->object.self = (Widget)newSec;
1438     newSec->object.widget_class = ec;
1439     newSec->object.parent = XtParent(newParent);
1440     newSec->object.xrm_name = newParent->core.xrm_name;
1441     newSec->object.being_destroyed = False;
1442     newSec->object.destroy_callbacks = NULL;
1443     newSec->object.constraints = NULL;
1444
1445     newSec->ext.logicalParent = newParent;
1446     newSec->ext.extensionType = XmCACHE_EXTENSION;
1447
1448     memcpy(&(newSec->icon_cache),
1449            Icon_Cache(newParent),
1450            sizeof(DtIconCacheObjPart));
1451
1452     extData = (XmWidgetExtData) XtCalloc(sizeof(XmWidgetExtDataRec), 1);
1453     extData->widget = (Widget)newSec;
1454     extData->reqWidget = (Widget)reqSec;
1455     _XmPushWidgetExtData(newParent, extData, XmCACHE_EXTENSION);
1456
1457     _XmGadgetImportSecondaryArgs(newParent, args, num_args);
1458     XtSetSubvalues((XtPointer)newSec, resources, num_resources,
1459                    args, *num_args);
1460
1461     _XmExtImportArgs((Widget)newSec, args, num_args);
1462
1463     memcpy((XtPointer)reqSec, (XtPointer)newSec, size);
1464
1465     Icon_Cache(newParent) = &(((DtIconCacheObject)newSec)->icon_cache);
1466     Icon_Cache(refParent) =
1467                         &(((DtIconCacheObject)extData->reqWidget)->icon_cache);
1468
1469     return FALSE;
1470 }
1471
1472 \f
1473 /*-------------------------------------------------------------
1474 **      GetValuesPrehook
1475 **
1476 */
1477 static void 
1478 GetValuesPrehook(
1479         Widget newParent,
1480         ArgList args,
1481         Cardinal *num_args )
1482 {
1483     XmWidgetExtData             extData;
1484     XmBaseClassExt              *cePtr;
1485     WidgetClass                 ec;
1486     DtIconCacheObject          newSec;
1487     Cardinal                    size;
1488     XtResourceList              resources;
1489     Cardinal                    num_resources;
1490
1491     _DtProcessLock();
1492     cePtr = _XmGetBaseClassExtPtr(XtClass(newParent), XmQmotif);
1493     ec = (*cePtr)->secondaryObjectClass;
1494     size = ec->core_class.widget_size;
1495     resources = ec->core_class.resources;
1496     num_resources = ec->core_class.num_resources;
1497
1498     newSec = (DtIconCacheObject)_XmExtObjAlloc(size);
1499     _DtProcessUnlock();
1500
1501     newSec->object.self = (Widget)newSec;
1502     newSec->object.widget_class = ec;
1503     newSec->object.parent = XtParent(newParent);
1504     newSec->object.xrm_name = newParent->core.xrm_name;
1505     newSec->object.being_destroyed = False;
1506     newSec->object.destroy_callbacks = NULL;
1507     newSec->object.constraints = NULL;
1508
1509     newSec->ext.logicalParent = newParent;
1510     newSec->ext.extensionType = XmCACHE_EXTENSION;
1511
1512     memcpy( &(newSec->icon_cache),
1513             Icon_Cache(newParent),
1514             sizeof(DtIconCacheObjPart));
1515
1516     extData = (XmWidgetExtData) XtCalloc(sizeof(XmWidgetExtDataRec), 1);
1517     extData->widget = (Widget)newSec;
1518     _XmPushWidgetExtData(newParent, extData, XmCACHE_EXTENSION);
1519
1520     XtGetSubvalues((XtPointer)newSec, resources, num_resources,
1521                    args, *num_args);
1522
1523     _XmExtGetValuesHook((Widget)newSec, args, num_args);
1524 }
1525
1526
1527
1528 /*-------------------------------------------------------------
1529 **      GetValuesPosthook
1530 **
1531 */
1532 /* ARGSUSED */
1533 static void 
1534 GetValuesPosthook(
1535         Widget new,
1536         ArgList args,
1537         Cardinal *num_args )
1538 {
1539  XmWidgetExtData             ext;
1540
1541  _XmPopWidgetExtData(new, &ext, XmCACHE_EXTENSION);
1542
1543  _DtProcessLock();
1544  _XmExtObjFree((XtPointer)ext->widget);
1545  _DtProcessUnlock();
1546
1547  XtFree((char *)ext);
1548 }
1549
1550
1551
1552 /*-------------------------------------------------------------
1553 **      SetValuesPosthook
1554 **
1555 */
1556 /* ARGSUSED */
1557 static Boolean 
1558 SetValuesPosthook(
1559         Widget current,
1560         Widget req,
1561         Widget new,
1562         ArgList args,
1563         Cardinal *num_args )
1564 {
1565     XmWidgetExtData             ext;
1566
1567     /*
1568      * - register parts in cache.
1569      * - update cache pointers
1570      * - and free req
1571      */
1572
1573
1574       /* assign if changed! */
1575       _DtProcessLock();
1576       if (!IconCacheCompare((XtPointer)Icon_Cache(new),
1577                             (XtPointer)Icon_Cache(current)))
1578
1579       {
1580          _XmCacheDelete((XtPointer) Icon_Cache(current)); /* delete the old one */
1581           Icon_Cache(new) = (DtIconCacheObjPart *)
1582               _XmCachePart(Icon_ClassCachePart(new),
1583                            (XtPointer) Icon_Cache(new),
1584                            sizeof(DtIconCacheObjPart));
1585       } else
1586           Icon_Cache(new) = Icon_Cache(current);
1587
1588       _XmPopWidgetExtData(new, &ext, XmCACHE_EXTENSION);
1589
1590       _XmExtObjFree((XtPointer)ext->widget);
1591       _XmExtObjFree((XtPointer)ext->reqWidget);
1592       _DtProcessUnlock();
1593
1594       XtFree((char *)ext);
1595
1596       return FALSE;
1597 }
1598
1599 \f
1600 /*--------------------------------------------------------------------------
1601 **      QualifyIconLocalCache
1602 **              Checks to see if local cache is set up
1603 */
1604 static void 
1605 QualifyIconLocalCache(DtIconGadget g, DtIconCacheObjPart *local_cache)
1606 {
1607   _DtProcessLock();
1608   ClassCacheCopy(Icon_ClassCachePart(g))((XtPointer) Icon_Cache(g),
1609                                          (XtPointer) local_cache,
1610                                          sizeof(DtIconCacheObjPart));
1611   _DtProcessUnlock();
1612 }
1613
1614 /************************************************************************
1615  *
1616  * ReCacheIcon_r()
1617  * Check to see if ReCaching is necessary as a result of fields having
1618  * been set by a mananger widget. This routine is called by the
1619  * manager widget in their SetValues after a change is made to any
1620  * of Icon's cached fields.
1621  *
1622  ************************************************************************/
1623
1624 static void 
1625 ReCacheIcon_r(DtIconCacheObjPart *local_cache, DtIconGadget g)
1626 {
1627   if (!IconCacheCompare( (XtPointer)local_cache, (XtPointer)Icon_Cache(g)))
1628     {
1629       _DtProcessLock();
1630       _XmCacheDelete( (XtPointer) Icon_Cache(g));   /* delete the old one */
1631       Icon_Cache(g) = (DtIconCacheObjPart *)
1632         _XmCachePart(Icon_ClassCachePart(g), 
1633                      (XtPointer) local_cache,
1634                      sizeof(DtIconCacheObjPart)); 
1635       _DtProcessUnlock();
1636     }
1637 }
1638
1639
1640 /*********************************************************************
1641  *
1642  *  GetParentBackgroundGC
1643  *      Get the graphics context used for erasing their highlight border.
1644  *
1645  *********************************************************************/
1646 static void
1647 GetParentBackgroundGC(
1648         DtIconGadget g )
1649 {
1650    XGCValues values;
1651    XtGCMask  valueMask;
1652    Widget    parent = XtParent((Widget)g);
1653
1654    valueMask = GCForeground | GCBackground;
1655    values.foreground = parent->core.background_pixel;
1656
1657    if (XmIsManager(parent))
1658
1659       values.background = ((XmManagerWidget) parent)->manager.foreground;
1660    else
1661       values.background = ((XmPrimitiveWidget) parent)->primitive.foreground;
1662
1663    if ((parent->core.background_pixmap != None) &&
1664        (parent->core.background_pixmap != XmUNSPECIFIED_PIXMAP))
1665    {
1666       valueMask |= GCFillStyle | GCTile;
1667       values.fill_style = FillTiled;
1668       values.tile = parent->core.background_pixmap;
1669    }
1670
1671    G_SavedParentBG(g) = parent->core.background_pixel;
1672
1673    G_ParentBackgroundGC(g) = XtGetGC (parent, valueMask, &values);
1674 }
1675
1676 \f
1677 /*-------------------------------------------------------------
1678 **      Initialize
1679 **              Initialize a new gadget instance.
1680 */
1681 static void 
1682 Initialize(
1683         Widget request_w,
1684         Widget new_w )
1685 {
1686         DtIconGadget    request =       (DtIconGadget) request_w,
1687                         new =           (DtIconGadget) new_w;
1688         Window          root;
1689         int             int_x = 0, int_y = 0;
1690         unsigned int    int_w = 0, int_h = 0,
1691                         int_bw, depth;
1692         Dimension       w, h;
1693         EventMask       mask;
1694         String          name = NULL;
1695         UpdateGCsProc   update_gcs;
1696
1697         G_Sync (new) = False;
1698
1699 /*      Validate behavior.
1700 */
1701         if (G_Behavior (new) != XmICON_LABEL &&
1702             G_Behavior (new) != XmICON_BUTTON &&
1703             G_Behavior (new) != XmICON_TOGGLE &&
1704             G_Behavior (new) != XmICON_DRAG)
1705         {
1706                 XmeWarning ((Widget)new, WARN_BEHAVIOR);
1707                 G_Behavior (new) = XmICON_BUTTON;
1708         }
1709
1710 /*      Set the input mask for events handled by Manager.
1711 */
1712         G_EventMask (new) = (XmARM_EVENT | XmACTIVATE_EVENT |
1713                         XmMULTI_ARM_EVENT | XmMULTI_ACTIVATE_EVENT |
1714                         XmHELP_EVENT | XmFOCUS_IN_EVENT | XmKEY_EVENT |
1715                         XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT);
1716
1717 /*      Add event handler for icon events.
1718 */
1719         if (G_Behavior (new) == XmICON_DRAG)
1720         {
1721                 mask = ButtonPressMask|ButtonReleaseMask;
1722                 XtAddEventHandler (XtParent (new), mask, False,
1723                                 (XtEventHandler) IconEventHandler, 0);
1724         }
1725
1726         G_ClickTimerID (new) = 0;
1727         G_ClickEvent (new) = NULL;
1728
1729         G_Armed (new) = False;
1730
1731         G_Mask (new) = None;
1732
1733         if (G_Pixmap (new) == XmUNSPECIFIED_PIXMAP)
1734                 G_Pixmap (new) = None;
1735
1736         if (G_ImageName (new) || G_Pixmap (new))
1737         {
1738                 if (G_ImageName (new))
1739                 {
1740
1741 /*      Try to get pixmap from image name.
1742 */
1743                         G_Pixmap (new) = 
1744                                 XmGetPixmap (XtScreen (new), G_ImageName (new),
1745                                         G_PixmapForeground (new),
1746                                         G_PixmapBackground (new));
1747                         if (G_Pixmap (new) != XmUNSPECIFIED_PIXMAP) 
1748                           {
1749                               name = G_ImageName (new);
1750                               G_Mask (new) = 
1751                                 _DtGetMask(XtScreen (new), G_ImageName
1752                                            (new));
1753                           }
1754                         else
1755                         {
1756 /* warning? */                          
1757                                 name = NULL;
1758                                 G_Pixmap (new) = None;
1759                         }
1760                 }
1761
1762 /*      Update width and height; copy image name.
1763 */
1764                 if (G_Pixmap (new))
1765                 {
1766                         XGetGeometry (XtDisplay (new), G_Pixmap (new),
1767                                 &root, &int_x, &int_y, &int_w, &int_h,
1768                                 &int_bw, &depth);
1769                 }
1770                 if (name)
1771                 {
1772                         G_ImageName (new) = XtNewString(name);
1773                 }
1774                 else
1775                         G_ImageName (new) = NULL;
1776         }
1777         G_PixmapWidth(new) = Limit((Dimension) int_w, G_MaxPixmapWidth(new));
1778         G_PixmapHeight(new) = Limit((Dimension) int_h, G_MaxPixmapHeight(new));
1779
1780 /*      Validate fill mode.
1781 */
1782         if (G_FillMode (new) != XmFILL_NONE &&
1783             G_FillMode (new) != XmFILL_PARENT &&
1784             G_FillMode (new) != XmFILL_TRANSPARENT &&
1785             G_FillMode (new) != XmFILL_SELF)
1786         {
1787                 XmeWarning ((Widget)new, WARN_FILL_MODE);
1788                 if (G_ShadowThickness (new) > 0)
1789                         G_FillMode (new) = XmFILL_SELF;
1790                 else
1791                         G_FillMode (new) = XmFILL_PARENT;
1792         }
1793
1794 /*      Validate pixmap position.
1795 */
1796         if (G_StringPosition (new) != UNSPECIFIED_CHAR)
1797                 G_PixmapPosition (new) = G_StringPosition (new);
1798
1799         if (G_PixmapPosition (new) == UNSPECIFIED_CHAR)
1800                 G_PixmapPosition (new) = XmPIXMAP_LEFT;
1801         else if (G_PixmapPosition (new) != XmPIXMAP_LEFT &&
1802                  G_PixmapPosition (new) != XmPIXMAP_RIGHT &&
1803                  G_PixmapPosition (new) != XmPIXMAP_TOP &&
1804                  G_PixmapPosition (new) != XmPIXMAP_BOTTOM &&
1805                  G_PixmapPosition (new) != XmPIXMAP_MIDDLE)
1806         {
1807                 XmeWarning ((Widget)new, WARN_PIXMAP_POSITION);
1808                 G_PixmapPosition (new) = XmPIXMAP_LEFT;
1809         }
1810         G_StringPosition (new) = G_PixmapPosition (new);
1811
1812 /*      Validate alignment.
1813 */
1814         if (G_Alignment (new) != XmALIGNMENT_BEGINNING &&
1815             G_Alignment (new) != XmALIGNMENT_CENTER &&
1816             G_Alignment (new) != XmALIGNMENT_END)
1817         {
1818                 XmeWarning ((Widget)new, WARN_ALIGNMENT);
1819                 G_Alignment (new) = XmALIGNMENT_BEGINNING;
1820         }
1821
1822 /*      Validate shadow type.
1823 */
1824         if (G_ShadowType (new) != XmSHADOW_IN &&
1825             G_ShadowType (new) != XmSHADOW_OUT &&
1826             G_ShadowType (new) != XmSHADOW_ETCHED_IN &&
1827             G_ShadowType (new) != XmSHADOW_ETCHED_OUT)
1828         {
1829                 XmeWarning ((Widget)new, WARN_SHADOW_TYPE);
1830                 if (G_Behavior (new) == XmICON_BUTTON)
1831                         G_ShadowType (new) = XmSHADOW_OUT;
1832                 else if (G_Behavior (new) == XmICON_TOGGLE)
1833                         G_ShadowType (new) = (G_Set (new))
1834                                 ? XmSHADOW_ETCHED_IN : XmSHADOW_ETCHED_OUT;
1835         }
1836
1837 /*      Copy fontlist.
1838 */
1839         if (G_FontList (new) == NULL)
1840                 G_FontList (new) =
1841                         XmeGetDefaultRenderTable ((Widget)new, XmBUTTON_FONTLIST);
1842         G_FontList (new) = XmFontListCopy (G_FontList (new));
1843
1844         if (G_String (new) == XmUNSPECIFIED_STRING)
1845                 G_String (new) = (_XmString) NULL;
1846        
1847         if (G_String (new))
1848         {
1849                 G_String (new) = XmStringCopy (G_String (new));
1850                 XmStringExtent (G_FontList (new), G_String (new),
1851                                         &w, &h);
1852                 if (G_Underline(new))
1853                    h++;
1854         }
1855         else
1856                 w = h = 0;
1857
1858         G_StringWidth (new) = w;
1859         G_StringHeight (new) = h;
1860
1861 /*      Convert margins to pixel units.
1862 */
1863         if (G_UnitType (new) != XmPIXELS)
1864         {
1865                 G_MarginWidth (new) = 
1866                         XmeToHorizontalPixels ((Widget)new, G_UnitType (new),
1867                                         (XtArgVal *)((long)G_MarginWidth (new)));
1868                 G_MarginHeight (new) = 
1869                         XmeToVerticalPixels ((Widget)new, G_UnitType (new),
1870                                         (XtArgVal *)((long)G_MarginHeight (new)));
1871         }
1872
1873 /*      Check for unspecified margins.
1874 */
1875         if (G_MarginWidth (request) == UNSPECIFIED_DIMENSION)
1876                 G_MarginWidth (new) = MARGIN_DEFAULT;
1877         if (G_MarginHeight (request) == UNSPECIFIED_DIMENSION)
1878                 G_MarginHeight (new) = MARGIN_DEFAULT;
1879
1880 /*      Convert spacing.
1881 */
1882         if (G_Spacing (new) == UNSPECIFIED_DIMENSION)
1883         {
1884                 G_Spacing (new) = G_StringHeight (new) / 5;
1885                 if (G_Spacing (new) < SPACING_DEFAULT)
1886                         G_Spacing (new) = SPACING_DEFAULT;
1887         }
1888         else if (G_Spacing (new) && G_UnitType (new) != XmPIXELS)
1889         {
1890                 G_Spacing (new) = 
1891                         (G_PixmapPosition (new) == XmPIXMAP_LEFT ||
1892                          G_PixmapPosition (new) == XmPIXMAP_RIGHT)
1893                         ? XmeToHorizontalPixels ((Widget)new, G_UnitType (new),
1894                                         (XtArgVal *)((long)G_Spacing (new)))
1895                         : XmeToVerticalPixels ((Widget)new, G_UnitType (new),
1896                                         (XtArgVal *)((long)G_Spacing (new)));
1897         }
1898
1899 /*      Set width and height.
1900 */
1901         if (G_Width (request) == 0 || G_Height (request) == 0)
1902         {
1903                 GetSizeProc get_size;
1904
1905                 _DtProcessLock();
1906                 get_size = C_GetSize(XtClass(new));
1907                 _DtProcessUnlock();
1908                 (*get_size) (new, &w, &h);
1909
1910                 if (G_Width (request) == 0)
1911                         G_Width (new) = w;
1912                 if (G_Height (request) == 0)
1913                         G_Height (new) = h;
1914         }
1915
1916 /*      Get graphics contexts.
1917 */
1918         G_NormalGC (new) = NULL;
1919         G_ClipGC (new) = NULL;
1920         G_BackgroundGC (new) = NULL;
1921         G_ArmedGC (new) = NULL;
1922         G_ArmedBackgroundGC (new) = NULL;
1923         _DtProcessLock();
1924         update_gcs = C_UpdateGCs(XtClass(new));
1925         _DtProcessUnlock();
1926         (*update_gcs) (new);
1927
1928         GetParentBackgroundGC(new);
1929
1930         if (G_Operations(new) != XmDROP_NOOP) {
1931            _DtIconRegisterDropsite(new_w);
1932         }
1933 }
1934
1935
1936 \f
1937 /*-------------------------------------------------------------
1938 **      Destroy
1939 **              Release resources allocated for gadget.
1940 */
1941 static void 
1942 Destroy(
1943         Widget w )
1944 {
1945         DtIconGadget    g =     (DtIconGadget) w;
1946         XmManagerWidget mw = (XmManagerWidget) XtParent(g);
1947
1948         if (G_ClickTimerID (g))
1949                 XtRemoveTimeOut (G_ClickTimerID (g));
1950
1951         XtFree ((char *)G_ClickEvent (g));
1952
1953         if (G_String (g) != NULL)
1954                 XmStringFree (G_String (g));
1955
1956         if (G_ImageName (g) != NULL)
1957         {
1958                 XtFree (G_ImageName (g));
1959                 if (G_Mask (g) != XmUNSPECIFIED_PIXMAP)
1960                   XmDestroyPixmap (XtScreen(w),G_Mask (g));
1961                 XmDestroyPixmap (XtScreen(w),G_Pixmap (g));
1962         }
1963
1964         XmFontListFree (G_FontList (g));
1965
1966         _DtProcessLock();
1967         _XmCacheDelete((XtPointer) Icon_Cache(w));
1968         _DtProcessUnlock();
1969
1970         XtReleaseGC ((Widget)mw, G_NormalGC (g));
1971         XtReleaseGC ((Widget)mw, G_ClipGC (g));
1972         XtReleaseGC ((Widget)mw, G_BackgroundGC (g));
1973         XtReleaseGC ((Widget)mw, G_ArmedGC (g));
1974         XtReleaseGC ((Widget)mw, G_ArmedBackgroundGC (g));
1975
1976 /* remove event handler if last Icon in parent? */
1977 }
1978
1979
1980 \f
1981 /*-------------------------------------------------------------
1982 **      Resize
1983 **              Set clip rect?
1984 */
1985 /* ARGSUSED */
1986 static void 
1987 Resize(
1988         Widget w )
1989 {
1990 }
1991
1992
1993 /*-------------------------------------------------------------
1994 **      Redisplay
1995 **              Redisplay gadget.
1996 */
1997 /* ARGSUSED */
1998 static void 
1999 Redisplay(
2000         Widget w,
2001         XEvent *event,
2002         Region region )
2003 {
2004         DtIconGadget    g =             (DtIconGadget) w;
2005         Dimension       s_t =           G_ShadowThickness (g);
2006         unsigned char   fill_mode =     G_FillMode (g);
2007         DrawProc        draw;
2008
2009         if (! XtIsManaged (w))
2010                 return;
2011
2012 /*      Draw gadget to window.
2013 */
2014         _DtProcessLock();
2015         draw = C_Draw(XtClass(g));
2016         _DtProcessUnlock();
2017         (*draw) (g, XtWindow (g), G_X (g), G_Y (g), G_Width (g), G_Height (g),
2018                  G_HighlightThickness (g), s_t, G_ShadowType (g), fill_mode);
2019
2020 /*      Draw highlight if highlighted.
2021 */
2022         if (G_Highlighted (g))
2023                 BorderHighlight( (DtIconGadget)g );
2024 }
2025
2026
2027 \f
2028 /*-------------------------------------------------------------
2029 **      SetValues
2030 **              
2031 */
2032 /* ARGSUSED */
2033 static Boolean 
2034 SetValues(
2035         Widget current_w,
2036         Widget request_w,
2037         Widget new_w )
2038 {
2039         DtIconGadget    current =       (DtIconGadget) current_w,
2040                         new =           (DtIconGadget) new_w;
2041
2042         Window          root;
2043         int             int_x = 0, int_y = 0;
2044         unsigned int    int_w = 0, int_h = 0,
2045                         int_bw, depth;
2046         Dimension       w, h;
2047         Boolean         new_image_name = False,
2048                         redraw_flag = False,
2049                         draw_pixmap = False,
2050                         draw_string = False,
2051                         draw_shadow = False;
2052         Dimension       h_t = G_HighlightThickness (new),
2053                         s_t = G_ShadowThickness (new),
2054                         p_x, p_y, s_x, s_y;
2055         String          name = NULL;
2056         Boolean         optimize_redraw = False;
2057
2058 /*      If unchanged, reuse old image name
2059 */
2060         if (G_ImageName (current) != G_ImageName (new) &&
2061             G_ImageName (new) &&
2062             G_ImageName (current) &&
2063             strcmp(G_ImageName (current), G_ImageName (new)) == 0)
2064         {
2065                 G_ImageName (new) = G_ImageName (current);
2066         }
2067
2068 /*      Validate behavior
2069 */
2070         if (G_Behavior (new) != G_Behavior (current))
2071         {
2072                 if (G_Behavior (new) != XmICON_LABEL &&
2073                     G_Behavior (new) != XmICON_BUTTON &&
2074                     G_Behavior (new) != XmICON_TOGGLE &&
2075                     G_Behavior (new) != XmICON_DRAG)
2076                 {
2077                         XmeWarning ((Widget)new, WARN_BEHAVIOR);
2078                         G_Behavior (new) = G_Behavior (current);
2079                 }
2080
2081                 if (G_Behavior (new) == XmICON_DRAG)
2082                 {
2083                         EventMask       mask;
2084
2085                         mask = ButtonPressMask|ButtonReleaseMask;
2086                         XtAddEventHandler (XtParent (new), mask, False,
2087                                         (XtEventHandler) IconEventHandler, 0);
2088                 }
2089         }
2090
2091 /*      Reset the interesting input types.
2092 */
2093         G_EventMask (new) |= (XmARM_EVENT | XmACTIVATE_EVENT |
2094                         XmMULTI_ARM_EVENT | XmMULTI_ACTIVATE_EVENT |
2095                         XmHELP_EVENT | XmFOCUS_IN_EVENT | XmKEY_EVENT |
2096                         XmFOCUS_OUT_EVENT | XmENTER_EVENT | XmLEAVE_EVENT);
2097
2098 /*      Check for new image name.
2099 */
2100         if (G_ImageName (new) && (G_ImageName (current) != G_ImageName (new)))
2101                 new_image_name = True;
2102
2103 /*      Validate shadow type.
2104 */
2105         if ((G_ShadowType (new) != G_ShadowType (current)) ||
2106             (G_Behavior (new) == XmICON_TOGGLE &&
2107              G_Set (new) != G_Set (current)))
2108         {
2109                 if (G_ShadowType (new) != XmSHADOW_IN &&
2110                     G_ShadowType (new) != XmSHADOW_OUT &&
2111                     G_ShadowType (new) != XmSHADOW_ETCHED_IN &&
2112                     G_ShadowType (new) != XmSHADOW_ETCHED_OUT)
2113                 {
2114                         XmeWarning ((Widget)new, WARN_SHADOW_TYPE);
2115                         G_ShadowType (new) = G_ShadowType (current); 
2116                 }
2117
2118 /*      Disallow change if conflict with set or armed state.
2119 */
2120                 else if (((G_Behavior (new) == XmICON_TOGGLE) &&
2121                           ((G_Set (new) && ! G_Armed (new)) ||
2122                            (! G_Set (new) && G_Armed (new)))) ||
2123                          ((G_Behavior (new) == XmICON_BUTTON) &&
2124                           (G_Armed (new))))
2125                 {
2126                         if (G_ShadowType (new) == XmSHADOW_OUT)
2127                                 G_ShadowType (new) = XmSHADOW_IN;
2128                         else if (G_ShadowType (new) == XmSHADOW_ETCHED_OUT)
2129                                 G_ShadowType (new) = XmSHADOW_ETCHED_IN;
2130                 }
2131                 else if (((G_Behavior (new) == XmICON_TOGGLE) &&
2132                           ((G_Set (new) && G_Armed (new)) ||
2133                            (! G_Set (new) && ! G_Armed (new)))) ||
2134                          ((G_Behavior (new) == XmICON_BUTTON) &&
2135                           (! G_Armed (new))))
2136                 {
2137                         if (G_ShadowType (new) == XmSHADOW_IN)
2138                                 G_ShadowType (new) = XmSHADOW_OUT;
2139                         else if (G_ShadowType (new) == XmSHADOW_ETCHED_IN)
2140                                 G_ShadowType (new) = XmSHADOW_ETCHED_OUT;
2141                 }
2142
2143                 if (G_ShadowType (new) != G_ShadowType (current))
2144                         draw_shadow = True;
2145         }
2146
2147 /*      Validate alignment.
2148 */
2149         if (G_Alignment (new) != G_Alignment (current))
2150         {
2151                 if (G_Alignment (new) != XmALIGNMENT_BEGINNING &&
2152                     G_Alignment (new) != XmALIGNMENT_CENTER &&
2153                     G_Alignment (new) != XmALIGNMENT_END)
2154                 {
2155                         XmeWarning ((Widget)new, WARN_ALIGNMENT);
2156                         G_Alignment (new) = G_Alignment (current);
2157                 }
2158                 else
2159                         redraw_flag = True;
2160         }
2161
2162
2163 /*      Validate fill mode.
2164 */
2165         if (G_FillMode (new) != G_FillMode (current))
2166         {
2167                 if (G_FillMode (new) != XmFILL_NONE &&
2168                     G_FillMode (new) != XmFILL_PARENT &&
2169                     G_FillMode (new) != XmFILL_TRANSPARENT &&
2170                     G_FillMode (new) != XmFILL_SELF)
2171                 {
2172                         XmeWarning ((Widget)new, WARN_FILL_MODE);
2173                         G_FillMode (new) = G_FillMode (current);
2174                 }
2175         }
2176
2177 /*      Validate pixmap position.
2178 */
2179         if (G_StringPosition (new) != G_StringPosition (current))
2180                 G_PixmapPosition (new) = G_StringPosition (new);
2181
2182         if (G_PixmapPosition (new) != G_PixmapPosition (current))
2183         {
2184                 if (G_PixmapPosition (new) != XmPIXMAP_LEFT &&
2185                     G_PixmapPosition (new) != XmPIXMAP_RIGHT &&
2186                     G_PixmapPosition (new) != XmPIXMAP_TOP &&
2187                     G_PixmapPosition (new) != XmPIXMAP_BOTTOM &&
2188                     G_PixmapPosition (new) != XmPIXMAP_MIDDLE)
2189                 {
2190                         XmeWarning ((Widget)new, WARN_PIXMAP_POSITION);
2191                         G_PixmapPosition (new) = G_PixmapPosition (current); 
2192                 }
2193                 else
2194                         redraw_flag = True;
2195
2196                 G_StringPosition (new) = G_PixmapPosition (new);
2197         }
2198
2199 /*      Update pixmap if pixmap foreground or background changed.
2200 */
2201         if (G_PixmapForeground (current) != G_PixmapForeground (new) ||
2202             G_PixmapBackground (current) != G_PixmapBackground (new))
2203         {
2204                 if (G_Pixmap (current) == G_Pixmap (new) &&
2205                     (G_ImageName (new) != NULL) &&
2206                     (! new_image_name))
2207                 {
2208                         draw_pixmap = True;
2209                         if (G_Mask(new) != XmUNSPECIFIED_PIXMAP) 
2210                           XmDestroyPixmap( XtScreen(new), G_Mask(current));
2211                         XmDestroyPixmap (XtScreen(new),G_Pixmap (current));
2212                         G_Pixmap (new) = 
2213                                 XmGetPixmap (XtScreen (new), G_ImageName (new),
2214                                         G_PixmapForeground (new),
2215                                         G_PixmapBackground (new));
2216                         if (G_Pixmap(new) != XmUNSPECIFIED_PIXMAP) 
2217                           G_Mask (new) = 
2218                             _DtGetMask(XtScreen (new), G_ImageName (new));
2219                 }
2220         }
2221
2222
2223 /*      Check for change in image name.
2224 */
2225         if (new_image_name)
2226         {
2227
2228 /*      Try to get pixmap from image name.
2229 */
2230                 if (G_ImageName (current) != NULL) 
2231                   {
2232                       if (G_Mask(new) != XmUNSPECIFIED_PIXMAP)
2233                         XmDestroyPixmap (XtScreen(new),G_Mask(current));
2234                       XmDestroyPixmap (XtScreen(new),G_Pixmap (current));
2235                   }
2236                 G_Pixmap (new) = 
2237                         XmGetPixmap (XtScreen (new), G_ImageName (new),
2238                                 G_PixmapForeground (new),
2239                                 G_PixmapBackground (new));
2240
2241                 if (G_Pixmap (new) != XmUNSPECIFIED_PIXMAP)
2242                 {
2243                     G_Mask(new) = (Pixmap)_DtGetMask(XtScreen(new), G_ImageName(new));
2244                     XGetGeometry (XtDisplay (new), G_Pixmap (new),
2245                                   &root, &int_x, &int_y, &int_w, &int_h,
2246                                   &int_bw, &depth);
2247                     name = G_ImageName (new);
2248                     w = Limit((Dimension) int_w, G_MaxPixmapWidth(new));
2249                     h = Limit((Dimension) int_h, G_MaxPixmapHeight(new));
2250                 }
2251                 else
2252                 {
2253                         name = NULL;
2254                         G_Pixmap (new) = None;
2255                         w = 0;
2256                         h = 0;
2257                 }
2258
2259 /*      If resetting to current image name, then reuse old copy.
2260 */
2261                 if (name && G_ImageName (current)
2262                     && (! strcmp (G_ImageName (new), G_ImageName (current))))
2263                 {
2264                         G_ImageName (new) = G_ImageName (current);
2265                         name = G_ImageName (current);
2266                 }
2267                 else 
2268                 {
2269                     if (name)
2270                       G_ImageName (new) = XtNewString(name);
2271                     else
2272                       G_ImageName (new) = NULL;
2273                     if (G_ImageName (current))
2274                       XtFree (G_ImageName (current));
2275                 }
2276
2277                 if (G_Pixmap (new) != G_Pixmap (current))
2278                 {
2279                         if ((G_Pixmap (new) != None) &&
2280                             (G_PixmapWidth (new) == w) &&
2281                             (G_PixmapHeight (new) == h))
2282                         {
2283                                 draw_pixmap = True;
2284                         }
2285                         else
2286                         {
2287                                 redraw_flag = True;
2288                                 G_PixmapWidth (new) = w;
2289                                 G_PixmapHeight (new) = h;
2290                         }
2291                 }
2292         }
2293
2294 /*      Release image name and pixmap if name set to null.
2295 */
2296         else if (G_Pixmap (new) == G_Pixmap (current))
2297         {
2298                 if ((G_ImageName (current) != NULL) && 
2299                     (G_ImageName (new) == NULL))
2300                 {
2301                         redraw_flag = True;
2302                         XtFree (G_ImageName (current));
2303                         if (G_Mask(new) != XmUNSPECIFIED_PIXMAP)
2304                           XmDestroyPixmap (XtScreen(new),G_Mask (current));
2305                         XmDestroyPixmap (XtScreen(new),G_Pixmap (current));
2306                         G_Pixmap (new) = None;                  
2307                         G_PixmapWidth (new) = 0;
2308                         G_PixmapHeight (new) = 0;
2309                 }
2310         }
2311
2312 /*      Process change in pixmap.
2313 */
2314         else if (G_Pixmap (new) != G_Pixmap (current)) 
2315         {
2316                 if (G_Pixmap (new))
2317                 {
2318                         XGetGeometry (XtDisplay (new), G_Pixmap (new), &root,
2319                                         &int_x, &int_y, &int_w, &int_h,
2320                                         &int_bw, &depth);
2321                         w = Limit((Dimension) int_w, G_MaxPixmapWidth(new));
2322                         h = Limit((Dimension) int_h, G_MaxPixmapHeight(new));
2323                 }
2324                 else
2325                 {
2326                         if (G_ImageName (current) != NULL)
2327                         {
2328                                 XtFree (G_ImageName (current));
2329                                 if (G_Mask(new) != XmUNSPECIFIED_PIXMAP)
2330                                   XmDestroyPixmap (XtScreen(new),G_Mask (current));
2331                                 XmDestroyPixmap (XtScreen(new),G_Pixmap (current));
2332                                 G_ImageName (new) = NULL;
2333                         }
2334                         w = h = 0;
2335                 }
2336
2337                 if (G_Pixmap (new) &&
2338                     (G_PixmapWidth (new) == w) &&
2339                     (G_PixmapHeight (new) == h))
2340                 {
2341                         draw_pixmap = True;
2342                 }
2343                 else
2344                 {
2345                         redraw_flag = True;
2346                         G_PixmapWidth (new) = w;
2347                         G_PixmapHeight (new) = h;
2348                 }
2349         }
2350
2351         if( ( G_MaxPixmapWidth(new) != G_MaxPixmapWidth(current)) ||
2352              (G_MaxPixmapHeight(new) != G_MaxPixmapHeight(current)) )
2353         {
2354                 if (G_Pixmap (new))
2355                 {
2356                         XGetGeometry (XtDisplay (new), G_Pixmap (new), &root,
2357                                         &int_x, &int_y, &int_w, &int_h,
2358                                         &int_bw, &depth);
2359                         w = Limit((Dimension) int_w, G_MaxPixmapWidth(new));
2360                         h = Limit((Dimension) int_h, G_MaxPixmapHeight(new));
2361                 }
2362                 else
2363                 {
2364                         w = h = 0;
2365                 }
2366
2367                 if (G_Pixmap (new) &&
2368                     (G_PixmapWidth (new) == w) &&
2369                     (G_PixmapHeight (new) == h))
2370                 {
2371                         draw_pixmap = True;
2372                 }
2373                 else
2374                 {
2375                         redraw_flag = True;
2376                         G_PixmapWidth (new) = w;
2377                         G_PixmapHeight (new) = h;
2378                 }
2379         }
2380
2381                         
2382 /*      Update GCs if foreground, background or mask changed.
2383 */
2384         if (G_Foreground (current) != G_Foreground (new) ||
2385             G_Background (current) != G_Background (new) ||
2386             ((G_Mask (current) != G_Mask(new)) &&
2387              (G_Pixmap (current) != G_Pixmap (new))) ||
2388             G_ArmColor (current) != G_ArmColor (new))
2389         {
2390                 UpdateGCsProc update_gcs;
2391                 if (G_ShadowThickness (new) > 0 &&
2392                     G_Behavior(new) != XmICON_DRAG &&
2393                     G_Background (current) != G_Background (new))
2394                         redraw_flag = True;
2395                 else
2396                         draw_string = True;
2397                 _DtProcessLock();
2398                 update_gcs = C_UpdateGCs(XtClass(new));
2399                 _DtProcessUnlock();
2400                 (*update_gcs) (new);
2401         }
2402
2403 /*      Convert dimensions to pixel units.
2404 */
2405         if (G_UnitType (new) != XmPIXELS)
2406         {
2407                 G_MarginWidth (new) = 
2408                         XmeToHorizontalPixels ((Widget)new, G_UnitType (new),
2409                                         (XtArgVal *)((long)G_MarginWidth (new)));
2410                 G_MarginHeight (new) = 
2411                         XmeToVerticalPixels ((Widget)new, G_UnitType (new),
2412                                         (XtArgVal *)((long)G_MarginHeight (new)));
2413         }
2414
2415 /*      Convert spacing.
2416 */
2417         if (G_UnitType (new) != G_UnitType (current) &&
2418             G_UnitType (new) != XmPIXELS)
2419         {
2420                 G_Spacing (new) = 
2421                         (G_PixmapPosition (new) == XmPIXMAP_LEFT ||
2422                          G_PixmapPosition (new) == XmPIXMAP_RIGHT)
2423                         ? XmeToHorizontalPixels ((Widget)new, G_UnitType (new),
2424                                         (XtArgVal *)((long)G_Spacing (new)))
2425                         : XmeToVerticalPixels ((Widget)new, G_UnitType (new),
2426                                         (XtArgVal *)((long)G_Spacing (new)));
2427         }
2428
2429 /*      Process change in string or font list.
2430 */
2431
2432         if (G_String (new) != G_String (current) ||
2433             G_FontList (new) != G_FontList (current) ||
2434             G_Underline (new) != G_Underline (current))
2435         {
2436                 if (G_FontList (new) != G_FontList (current))
2437                 {
2438                         if (G_FontList (new) == NULL)
2439                                 G_FontList (new) = G_FontList (current);
2440                         else
2441                         {
2442                                 XmFontListFree (G_FontList (current));
2443                                 G_FontList (new) =
2444                                         XmFontListCopy (G_FontList (new));
2445                         }
2446                 }
2447                 if (G_String (new))
2448                 {
2449                         if (G_String (new) != G_String (current))
2450                         {
2451                                 if (G_String (current))
2452                                         XmStringFree (G_String (current));
2453                                 G_String (new) =
2454                                         XmStringCopy (G_String (new));
2455                         }
2456
2457                         XmStringExtent (G_FontList (new), G_String (new),
2458                                         &w, &h);
2459                         if (G_Underline(new))
2460                            h++;
2461                 }
2462                 else
2463                         w = h = 0;
2464
2465                 G_StringWidth (new) = w;
2466                 G_StringHeight (new) = h;
2467
2468                 G_Spacing (new) = (Dimension) G_StringHeight (new) / 5;
2469                 if (G_Spacing (new) < SPACING_DEFAULT)
2470                         G_Spacing (new) = SPACING_DEFAULT;
2471
2472                 if ((G_String (new) != NULL) &&
2473                     (G_StringWidth (new) == G_StringWidth (current)) &&
2474                     (G_StringHeight (new) == G_StringHeight (current)))
2475                         draw_string = True;
2476                 else
2477                         redraw_flag = True;
2478         }
2479
2480 /*      Check for other changes requiring redraw.
2481 */
2482         if (G_HighlightThickness (new) != G_HighlightThickness (current) ||
2483             G_ShadowThickness (new) != G_ShadowThickness (current) ||
2484             G_MarginWidth (new) != G_MarginWidth (current) ||
2485             G_MarginHeight (new) != G_MarginHeight (current) ||
2486             G_Spacing (new) != G_Spacing (current))
2487         {
2488                 redraw_flag = True;
2489         }
2490
2491 /*      Update size.
2492 */
2493         if (!(redraw_flag ||
2494               (G_RecomputeSize (new) && ! G_RecomputeSize (current))))
2495           {
2496             _DtProcessLock();
2497             optimize_redraw = C_OptimizeRedraw(XtClass(new));
2498             _DtProcessUnlock();
2499           }
2500
2501         if (redraw_flag ||
2502             (G_RecomputeSize (new) && ! G_RecomputeSize (current)))
2503         {
2504                 if (G_RecomputeSize (new) &&
2505                     (G_Width (current) == G_Width (new) ||
2506                      G_Height (current) == G_Height (new)))
2507                 {
2508                         GetSizeProc get_size;
2509
2510                         _DtProcessLock();
2511                         get_size = C_GetSize(XtClass(new));
2512                         _DtProcessUnlock();
2513                         (*get_size) (new, &w, &h);
2514
2515                         if (G_Width (current) == G_Width (new))
2516                                 G_Width (new) = w;
2517                         if (G_Height (current) == G_Height (new))
2518                                 G_Height (new) = h;
2519                 }
2520         }
2521
2522 /*      Set redraw flag if this class doesn't optimize redraw.
2523 */
2524         else if (! optimize_redraw)
2525         {
2526                 if (draw_shadow || draw_pixmap || draw_string)
2527                         redraw_flag = True;
2528         }       
2529
2530 /*      Optimize redraw if managed.
2531 */
2532         else if (XtIsManaged (new_w) && XtIsRealized(new_w))
2533         {
2534 /*      Get string and pixmap positions if necessary.
2535 */
2536                 if ((draw_pixmap && G_Pixmap (new)) ||
2537                     (draw_string && G_String (new)))
2538                 {
2539                         GetPositionProc get_positions;
2540
2541                         _DtProcessLock();
2542                         get_positions = C_GetPositions(XtClass(new));
2543                         _DtProcessUnlock();
2544                         (*get_positions) (new, G_Width (new), G_Height (new),
2545                                 h_t, G_ShadowThickness (new),
2546                                 (Position *)&p_x, (Position *)&p_y, 
2547                                 (Position *)&s_x, (Position *)&s_y);
2548                 }
2549 /*      Copy pixmap, clip if necessary.
2550 */
2551                 if (draw_pixmap && G_Pixmap (new) &&
2552                     G_Pixmap (new) != XmUNSPECIFIED_PIXMAP)
2553                   {
2554                       w = ((unsigned) (p_x + s_t + h_t) >= G_Width (new))
2555                         ? 0 : Min ((unsigned)G_PixmapWidth (new),
2556                                    G_Width (new) - p_x - s_t - h_t);
2557                       h = ((unsigned) (p_y + s_t + h_t) >= G_Height (new))
2558                         ? 0 : Min ((unsigned)G_PixmapHeight (new),
2559                                    G_Height (new) - p_y - s_t - h_t);
2560                       if (w > 0 && h > 0) {
2561                           XCopyArea 
2562                             (XtDisplay (new), G_Pixmap (new), XtWindow (new),
2563                              GetMaskGC(new, G_X(new) + p_x, G_Y(new) + p_y),
2564                              0, 0,
2565                              w, h, G_X (new) + p_x, G_Y (new) + p_y);
2566                       }
2567                 }
2568 /*      Draw string with normal or armed background; clip if necessary.
2569 */
2570                 if (draw_string && G_String (new))
2571                 {
2572                         GC              gc;
2573                         XRectangle      clip;
2574                         unsigned char   behavior = G_Behavior (new);
2575
2576                         if ((behavior == XmICON_BUTTON ||
2577                              behavior == XmICON_DRAG) &&
2578                             G_FillOnArm (new) && G_Armed (new))
2579                                 gc = G_ArmedGC (new);
2580                         else if (behavior == XmICON_TOGGLE &&
2581                                  G_FillOnArm (new) &&
2582                                  ((G_Armed (new) && !G_Set (new)) ||
2583                                   (!G_Armed (new) && G_Set (new))))
2584                                 gc = G_ArmedGC (new);
2585                         else
2586                                 gc = G_NormalGC (new);
2587
2588                         clip.x = G_X (new) + s_x;
2589                         clip.y = G_Y (new) + s_y;
2590                         clip.width = (s_x + s_t + h_t >= 
2591                                       (unsigned)G_Width (new))
2592                                 ? 0 : Min ((unsigned)G_StringWidth (new),
2593                                            G_Width (new) - s_x - s_t - h_t);
2594                         clip.height = (s_y + s_t + h_t >= 
2595                                        (unsigned)G_Height (new))
2596                                 ? 0 : Min ((unsigned)G_StringHeight (new),
2597                                            G_Height (new) - s_y - s_t - h_t);
2598                         if (clip.width > 0 && clip.height > 0)
2599                         {
2600                                 XmStringDrawImage (XtDisplay (new),
2601                                          XtWindow (new), G_FontList (new),
2602                                         G_String (new), gc,
2603                                         G_X (new) + s_x, G_Y (new) + s_y,
2604                                         clip.width, XmALIGNMENT_CENTER,
2605                                         XmSTRING_DIRECTION_L_TO_R, &clip);
2606
2607                                 if (G_Underline(new))
2608                                 {
2609                                    XmStringDrawUnderline (XtDisplay (new),
2610                                             XtWindow (new), G_FontList (new),
2611                                            G_String (new), gc,
2612                                            G_X (new) + s_x, G_Y (new) + s_y,
2613                                            clip.width, XmALIGNMENT_CENTER,
2614                                            XmSTRING_DIRECTION_L_TO_R, &clip,
2615                                            G_String(new));
2616                                 }
2617                         }
2618                 }
2619 /*      Draw shadow.
2620 */
2621                 if (draw_shadow && G_DrawShadow(new))
2622                 {
2623                    if(G_BorderType(new) == DtRECTANGLE || !G_Pixmap(new))
2624                      XmeDrawShadows(XtDisplay(new), XtWindow(new),
2625                                     M_TopShadowGC(MgrParent(new)),
2626                                     M_BottomShadowGC(MgrParent(new)),
2627                                     G_X(new) + h_t, G_Y(new) + h_t,
2628                                     G_Width(new) - 2*h_t, G_Height(new) - 2*h_t,
2629                                     G_ShadowThickness(new), G_ShadowType(new));
2630                    else
2631                      {
2632                        CallCallbackProc call_callback;
2633                        _DtProcessLock();
2634                        call_callback = C_CallCallback(XtClass(new));
2635                        _DtProcessUnlock();
2636                        (*call_callback) (new, G_Callback (new),
2637                                                     XmCR_SHADOW, NULL);
2638                      }
2639                 }
2640         }
2641
2642         if (G_Operations(current) != G_Operations(new)) {
2643            if (G_Operations(current) == XmDROP_NOOP){
2644               _DtIconRegisterDropsite(new_w);
2645            } else {
2646               if (G_Operations(new) == XmDROP_NOOP)
2647                  DtDndDropUnregister(new_w);
2648               else {
2649                  Arg args[1];
2650
2651                  XtSetArg(args[0], XmNdropSiteOperations, G_Operations(new));
2652                  XmDropSiteUpdate(new_w, args, 1);
2653               }
2654            }
2655         }
2656
2657         return (redraw_flag);
2658 }
2659
2660
2661 \f
2662 /*-------------------------------------------------------------
2663 **      Gadget Procs
2664 **-------------------------------------------------------------
2665 */
2666
2667 /*-------------------------------------------------------------
2668 **      BorderHighlight
2669 **
2670 */
2671 static void 
2672 BorderHighlight( DtIconGadget g)
2673 {
2674    register int width;
2675    register int height;
2676    CallCallbackProc call_callback;
2677
2678    width = g->rectangle.width;
2679    height = g->rectangle.height;
2680
2681    if (width == 0 || height == 0) return;
2682
2683    if (g->gadget.highlight_thickness == 0) return;
2684
2685    g->gadget.highlighted = True;
2686    g->gadget.highlight_drawn = True;
2687
2688    if(G_BorderType(g) == DtRECTANGLE || !G_Pixmap(g))
2689       HighlightBorder ((Widget)g);
2690
2691    _DtProcessLock();
2692    call_callback = C_CallCallback(XtClass(g));
2693    _DtProcessUnlock();
2694    (*call_callback) (g, G_Callback (g), XmCR_HIGHLIGHT, NULL);
2695 }
2696
2697 /*-------------------------------------------------------------
2698 **      BorderUnhighlight
2699 **
2700 */
2701 static void 
2702 BorderUnhighlight( DtIconGadget g)
2703 {
2704
2705    register int window_width;
2706    register int window_height;
2707    register int highlight_width;
2708    CallCallbackProc     call_callback;
2709
2710    window_width = g->rectangle.width;
2711    window_height = g->rectangle.height;
2712
2713    if (window_width == 0 || window_height == 0) return;
2714
2715    highlight_width = g->gadget.highlight_thickness;
2716    if (highlight_width == 0) return;
2717
2718    g->gadget.highlighted = False;
2719    g->gadget.highlight_drawn = False;
2720
2721    if(G_BorderType(g) == DtRECTANGLE || !G_Pixmap(g))
2722       UnhighlightBorder ((Widget)g);
2723
2724    _DtProcessLock();
2725    call_callback = C_CallCallback(XtClass(g));
2726    _DtProcessUnlock();
2727    (*call_callback) (g, G_Callback (g), XmCR_UNHIGHLIGHT, NULL);
2728 }
2729
2730 /*-------------------------------------------------------------
2731 **      ArmAndActivate
2732 **              Invoke Activate.
2733 */
2734 static void 
2735 ArmAndActivate(
2736         Widget w,
2737         XEvent *event )
2738 {
2739         IconArm (w, event);
2740         IconActivate (w, event);
2741 }
2742
2743
2744 \f
2745 /*-------------------------------------------------------------
2746 **      InputDispatch
2747 **              Process event dispatched from parent or event handler.
2748 */
2749 static void 
2750 InputDispatch(
2751         Widget w,
2752         XButtonEvent *event,
2753         Mask event_mask )
2754 {
2755         DtIconGadget    g =     (DtIconGadget) w;
2756
2757         if (event_mask & XmARM_EVENT || event_mask & XmMULTI_ARM_EVENT)
2758                 if (event->button == Button2)
2759                         IconDrag (w, (XEvent*) event);  
2760                 else if (event->button == Button3)
2761                         IconPopup (w, (XEvent*) event);
2762                 else
2763                         IconArm (w, (XEvent*) event);
2764         else if (event_mask & XmACTIVATE_EVENT ||
2765                  event_mask & XmMULTI_ACTIVATE_EVENT)
2766         {
2767                 if (event->button == Button3)
2768                         ;
2769                 else if (event->x >= G_X (g) &&
2770                          event->x <= G_X (g) + (int)G_Width (g) &&
2771                          event->y >= G_Y (g) &&
2772                          event->y <= G_Y (g) + (int)G_Height (g))
2773                         IconActivate (w, (XEvent*) event);
2774                 else
2775                         IconDisarm (w, (XEvent*) event);
2776         }
2777         else if (event_mask & XmHELP_EVENT)
2778                 _XmSocorro (w, (XEvent *)event,NULL,NULL);
2779         else if (event_mask & XmENTER_EVENT)
2780                 IconEnter (w, (XEvent *)event);
2781         else if (event_mask & XmLEAVE_EVENT)
2782                 IconLeave (w, (XEvent *)event);
2783         else if (event_mask & XmFOCUS_IN_EVENT)
2784                 _XmFocusInGadget (w, (XEvent *)event,NULL,NULL);
2785         else if (event_mask & XmFOCUS_OUT_EVENT)
2786                 _XmFocusOutGadget (w, (XEvent *)event,NULL,NULL);
2787 }
2788
2789
2790 \f
2791 /*-------------------------------------------------------------
2792 **      VisualChange
2793 **              Update GCs when parent visuals change.
2794 */
2795 static Boolean 
2796 VisualChange(
2797         Widget w,
2798         Widget current_w,
2799         Widget new_w )
2800 {
2801     XmManagerWidget             current =       (XmManagerWidget) current_w;
2802     XmManagerWidget             new =           (XmManagerWidget) new_w;
2803     DtIconGadget                g =             (DtIconGadget) w;
2804     Boolean                     update =        False;
2805     DtIconCacheObjPart          local_cache;
2806     UpdateGCsProc               update_gcs;
2807     
2808     QualifyIconLocalCache(g, &local_cache);
2809     /*  If foreground or background was the same as the parent, and parent
2810      ** foreground or background has changed, then update gcs and pixmap.
2811      */
2812     /* (can't really tell if explicitly set to be same as parent!
2813      **  -- could add flags set in dynamic default procs for fg and bg)
2814      */
2815     if (G_Foreground (g) == M_Foreground (current) &&
2816         M_Foreground (current) != M_Foreground (new))
2817       {
2818           local_cache.foreground = M_Foreground (new);
2819           update = True;
2820       }
2821     
2822     if (G_Background (g) == M_Background (current) &&
2823         M_Background (current) != M_Background (new))
2824       {
2825           local_cache.background = M_Background (new);
2826           update = True;
2827       }
2828     
2829     if (G_PixmapForeground (g) == M_Foreground (current) &&
2830         M_Foreground (current) != M_Foreground (new))
2831       {
2832           G_PixmapForeground(g) =  M_Foreground (new);
2833           update = True;
2834       }
2835     
2836     if (G_PixmapBackground (g) == M_Background (current) &&
2837         M_Background (current) != M_Background (new))
2838       {
2839           G_PixmapBackground(g) = M_Background (new);
2840           update = True;
2841       }
2842     
2843     if (update)
2844       {
2845           ReCacheIcon_r(&local_cache, g);
2846           _DtProcessLock();
2847           update_gcs = C_UpdateGCs(XtClass(g));
2848           _DtProcessUnlock();
2849           (*update_gcs) (g);
2850           
2851           if (G_ImageName (g) != NULL)
2852             {
2853                 if (G_Mask(g) != XmUNSPECIFIED_PIXMAP)
2854                   XmDestroyPixmap (XtScreen(g),G_Mask(g));
2855                 XmDestroyPixmap (XtScreen(w),G_Pixmap (g));
2856                 G_Pixmap (g) = 
2857                   XmGetPixmap (XtScreen (g), G_ImageName (g),
2858                                G_PixmapForeground (g),
2859                                G_PixmapBackground (g));
2860                 if (G_Pixmap (g) != XmUNSPECIFIED_PIXMAP)
2861                   G_Mask(g) = (Pixmap)_DtGetMask(XtScreen(g), G_ImageName(g));
2862                 return (True);
2863             }
2864           else
2865             return (False);
2866       }
2867       return (False);
2868 }
2869
2870 \f
2871 /*-------------------------------------------------------------
2872 **      Icon Procs
2873 **-------------------------------------------------------------
2874 */
2875
2876 /*-------------------------------------------------------------
2877 **      GetSize
2878 **              Compute size.
2879 */
2880 static void 
2881 GetSize(
2882         DtIconGadget g,
2883         Dimension *w,
2884         Dimension *h )
2885 {
2886         Dimension       s_t = G_ShadowThickness (g),
2887                         h_t = G_HighlightThickness (g),
2888                         p_w = G_PixmapWidth (g),
2889                         p_h = G_PixmapHeight (g),
2890                         m_w = G_MarginWidth (g),
2891                         m_h = G_MarginHeight (g),
2892                         s_w = G_StringWidth (g),
2893                         s_h = G_StringHeight (g),
2894                         v_pad = 2 * (s_t + h_t + m_h),
2895                         h_pad = 2 * (s_t + h_t + m_w),
2896                         spacing = G_Spacing (g);
2897         
2898         if (((p_w == 0) && (p_h == 0)) || ((s_w == 0) && (s_h == 0)))
2899                 spacing = 0;
2900
2901 /*      Get width and height.
2902 */
2903         switch ((int) G_PixmapPosition (g))
2904         {
2905                 case XmPIXMAP_TOP:
2906                 case XmPIXMAP_BOTTOM:
2907                         *w = Max (p_w, s_w) + h_pad;
2908                         *h = p_h + s_h + v_pad + spacing;
2909                         break;
2910                 case XmPIXMAP_LEFT:
2911                 case XmPIXMAP_RIGHT:
2912                         *w = p_w + s_w + h_pad + spacing;
2913                         *h = Max (p_h, s_h) + v_pad;
2914                         break;
2915                 case XmPIXMAP_MIDDLE:
2916                         *w = Max (p_w, s_w) + h_pad;
2917                         *h = Max (p_h, s_h) + v_pad;
2918                         break;
2919                 default:
2920                         break;
2921         }
2922 }
2923
2924
2925 \f
2926 /*-------------------------------------------------------------
2927 **      GetPositions
2928 **              Get positions of string and pixmap.
2929 */
2930 static void 
2931 GetPositions(
2932         DtIconGadget g,
2933         Position w,
2934         Position h,
2935         Dimension h_t,
2936         Dimension s_t,
2937         Position *pix_x,
2938         Position *pix_y,
2939         Position *str_x,
2940         Position *str_y )
2941 {
2942         Dimension       p_w =           G_PixmapWidth (g),
2943                         p_h =           G_PixmapHeight (g),
2944                         s_w =           G_StringWidth (g),
2945                         s_h =           G_StringHeight (g),
2946                         m_w =           G_MarginWidth (g),
2947                         m_h =           G_MarginHeight (g),
2948                         spacing =       G_Spacing (g),
2949                         h_pad =         s_t + h_t + m_w,
2950                         v_pad =         s_t + h_t + m_h,
2951                         width =         w - 2 * h_pad,
2952                         height =        h - 2 * v_pad;
2953         Position        p_x =           h_pad,
2954                         p_y =           v_pad,
2955                         s_x =           h_pad,
2956                         s_y =           v_pad;
2957         unsigned char   align =         G_Alignment (g);
2958
2959         if (((p_w == 0) && (p_h == 0)) || ((s_w == 0) && (s_h == 0)))
2960                 spacing = 0;
2961
2962 /*      Set positions
2963 */
2964         switch ((int) G_PixmapPosition (g))
2965         {
2966                 case XmPIXMAP_TOP:
2967                         if (align == XmALIGNMENT_CENTER)
2968                         {
2969                                 if (p_w && width > p_w)
2970                                         p_x += (width - p_w)/2U;
2971                                 if (s_w && width > s_w)
2972                                         s_x += (width - s_w)/2U;
2973                         }
2974                         else if (align == XmALIGNMENT_END)
2975                         {
2976                                 if (p_w && width > p_w)
2977                                         p_x += width - p_w;
2978                                 if (s_w && width > s_w)
2979                                         s_x += width - s_w;
2980                         }
2981                         if (p_h && ((unsigned)height > p_h + s_h + spacing))
2982                                 p_y += (height - p_h - s_h - spacing)/2U;
2983                         if (p_h)
2984                                 s_y = p_y + p_h + spacing;
2985                         else
2986                                 s_y += (height - s_h)/2U;
2987                         break;
2988                 case XmPIXMAP_BOTTOM:
2989                         if (align == XmALIGNMENT_CENTER)
2990                         {
2991                                 if (p_w && width > p_w)
2992                                         p_x += (width - p_w)/2U;
2993                                 if (s_w && width > s_w)
2994                                         s_x += (width - s_w)/2U;
2995                         }
2996                         else if (align == XmALIGNMENT_END)
2997                         {
2998                                 if (p_w && width > p_w)
2999                                         p_x += width - p_w;
3000                                 if (s_w && width > s_w)
3001                                         s_x += width - s_w;
3002                         }
3003                         if (s_h && ((unsigned)height > p_h + s_h + spacing))
3004                                 s_y += (height - p_h - s_h - spacing)/2U;
3005                         if (s_h)
3006                                 p_y = s_y + s_h + spacing;
3007                         else
3008                                 p_y += (height - s_h)/2U;
3009                         break;
3010                 case XmPIXMAP_LEFT:
3011                         if (p_h && height > p_h)
3012                                 p_y += (height - p_h)/2U;
3013                         s_x += p_w + spacing;
3014                         if (s_h && height > s_h)
3015                                 s_y += (height - s_h)/2U;
3016                         break;
3017                 case XmPIXMAP_RIGHT:
3018                         if (s_h && height > s_h)
3019                                 s_y += (height - s_h)/2U;
3020                         p_x += s_w + spacing;
3021                         if (p_h && height > p_h)
3022                                 p_y += (height - p_h)/2U;
3023                         break;
3024                 case XmPIXMAP_MIDDLE:
3025                         if (p_w && width > p_w)
3026                            p_x += (width - p_w)/2U;
3027                         if (s_w && width > s_w)
3028                            s_x += (width - s_w)/2U;
3029                         if (s_h && height > s_h)
3030                                 s_y += (height - s_h)/2U;
3031                         if (p_h && height > p_h)
3032                                 p_y += (height - p_h)/2U;
3033                         break;
3034                 default:
3035                         break;
3036         }
3037
3038         *pix_x = p_x;
3039         *pix_y = p_y;
3040         *str_x = s_x;
3041         *str_y = s_y;
3042 }
3043
3044
3045 \f
3046 /*-------------------------------------------------------------
3047 **      Draw
3048 **              Draw gadget to drawable.
3049 */
3050 /* ARGSUSED */
3051 static void 
3052 Draw(
3053         DtIconGadget g,
3054         Drawable drawable,
3055         Position x,
3056         Position y,
3057         Dimension w,
3058         Dimension h,
3059         Dimension h_t,
3060         Dimension s_t,
3061         unsigned char s_type,
3062         unsigned char fill_mode )
3063 {
3064         XmManagerWidget mgr =   (XmManagerWidget) XtParent (g);
3065         Display *       d =     XtDisplay (g);
3066         GC              gc;
3067         XRectangle      clip;
3068         Position        p_x, p_y, s_x, s_y;
3069         Dimension       width, height;
3070         unsigned char   behavior =      G_Behavior (g);
3071         Position        adj_x, adj_y;
3072         int             rec_width=0,begin=0,diff=0;
3073         GetPositionProc get_positions;
3074
3075 /*      Fill with icon or manager background or arm color.
3076 */
3077         if (G_SavedParentBG(g) != XtParent(g)->core.background_pixel) {
3078          XtReleaseGC((Widget)mgr, G_ParentBackgroundGC(g));
3079          GetParentBackgroundGC(g);
3080         }
3081
3082         if (fill_mode == XmFILL_SELF)
3083         {
3084                 if ((behavior == XmICON_BUTTON || behavior == XmICON_DRAG) &&
3085                      G_FillOnArm (g) && G_Armed (g))
3086                         gc = G_ArmedBackgroundGC (g);
3087                 else if (behavior == XmICON_TOGGLE && G_FillOnArm (g) &&
3088                          ((G_Armed (g) && !G_Set (g)) ||
3089                           (!G_Armed (g) && G_Set (g))))
3090                         gc = G_ArmedBackgroundGC (g);
3091                 else
3092                         gc = G_BackgroundGC (g);
3093         }
3094         else if (fill_mode == XmFILL_PARENT)
3095                 gc = G_ParentBackgroundGC (g);
3096
3097         if ((fill_mode == XmFILL_SELF) || (fill_mode == XmFILL_PARENT))
3098                 XFillRectangle (d, drawable, gc, x + h_t, y + h_t,
3099                                 w - 2 * h_t, h - 2 * h_t);
3100
3101 /*      Get pixmap and string positions.
3102 */
3103         _DtProcessLock();
3104         get_positions = C_GetPositions(XtClass(g));
3105         _DtProcessUnlock();
3106         (*get_positions) (g, w, h, h_t, s_t, &p_x, &p_y, &s_x, &s_y);
3107
3108 /*      Copy pixmap.
3109 */
3110         if (G_Pixmap (g))
3111         {
3112                 width = (p_x + s_t + h_t >= (unsigned)G_Width (g))
3113                         ? 0 : Min ((unsigned)G_PixmapWidth (g),
3114                                    G_Width (g) - p_x - s_t - h_t);
3115                 height = (p_y + s_t + h_t >= (unsigned)G_Height (g))
3116                         ? 0 : Min ((unsigned)G_PixmapHeight (g),
3117                                    G_Height (g) - p_y - s_t - h_t);
3118                 if (width > 0 && height > 0)
3119                   {
3120                       if (fill_mode == XmFILL_TRANSPARENT)
3121                         {
3122                             adj_x = s_t + h_t + G_MarginWidth(g);
3123                             adj_y = s_t + h_t + G_MarginHeight(g);
3124                             switch (G_PixmapPosition(g))
3125                             {
3126                                case XmPIXMAP_TOP:
3127                                case XmPIXMAP_BOTTOM:
3128                                   XFillRectangle(d, drawable, 
3129                                                  G_ParentBackgroundGC(g),
3130                                                  x + p_x - adj_x, 
3131                                                  y + p_y - adj_y,
3132                                                  width + (2 * adj_y),
3133                                                  height + (2 * adj_x) -
3134                                                                  (s_t + h_t));
3135                                   break;
3136                                case XmPIXMAP_LEFT:
3137                                case XmPIXMAP_RIGHT:
3138                                   XFillRectangle(d, drawable, 
3139                                                  G_ParentBackgroundGC(g),
3140                                                  x + p_x - adj_x, 
3141                                                  y + p_y - adj_y,
3142                                                  width + (2 * adj_y) -
3143                                                                  (s_t + h_t),
3144                                                  height + (2 * adj_x));
3145                                   break;
3146                                case XmPIXMAP_MIDDLE:
3147                                   XFillRectangle(d, drawable, 
3148                                                  G_ParentBackgroundGC(g),
3149                                                  x + p_x - adj_x, 
3150                                                  y + p_y - adj_y,
3151                                                  width + (2 * adj_y),
3152                                                  height + (2 * adj_x));
3153                                   break;
3154                             }
3155                         }
3156                       XCopyArea (d, G_Pixmap (g), drawable, 
3157                                  GetMaskGC(g, x + p_x, y + p_y),
3158                                  0, 0, width, height, x + p_x, y + p_y);
3159                   }
3160         }
3161
3162 /*      Draw string.
3163 */
3164         if ((behavior == XmICON_BUTTON || behavior == XmICON_DRAG) &&
3165              G_FillOnArm (g) && G_Armed (g))
3166                 gc = G_ArmedGC (g);
3167         else if (behavior == XmICON_TOGGLE && G_FillOnArm (g) &&
3168                  ((G_Armed (g) && !G_Set (g)) ||
3169                   (!G_Armed (g) && G_Set (g))))
3170                 gc = G_ArmedGC (g);
3171         else
3172                 gc = G_NormalGC (g);
3173
3174         if (G_String (g))
3175         {
3176                 clip.x = x + s_x;
3177                 clip.y = y + s_y;
3178                 switch (G_PixmapPosition(g))
3179                 {
3180                    case XmPIXMAP_TOP:
3181                    case XmPIXMAP_BOTTOM:
3182                       clip.width = (s_x + s_t + h_t >= (unsigned)G_Width (g))
3183                               ? 0 : Min ((unsigned)G_StringWidth (g),
3184                                          G_Width (g) - s_x);
3185                       clip.height = (s_y + s_t + h_t >= (unsigned)G_Height (g))
3186                               ? 0 : Min ((unsigned)G_StringHeight (g),
3187                                          G_Height (g) - s_y - s_t - h_t);
3188                       break;
3189                    case XmPIXMAP_LEFT:
3190                    case XmPIXMAP_RIGHT:
3191                       clip.width = (s_x + s_t + h_t >= (unsigned)G_Width (g))
3192                               ? 0 : Min ((unsigned)G_StringWidth (g),
3193                                          G_Width (g) - s_x - s_t - h_t);
3194                       clip.height = (s_y + s_t + h_t >= (unsigned)G_Height (g))
3195                               ? 0 : Min ((unsigned)G_StringHeight (g),
3196                                          G_Height (g) - s_y);
3197                       break;
3198                    case XmPIXMAP_MIDDLE:
3199                       clip.width = (s_x + s_t + h_t >= (unsigned)G_Width (g))
3200                               ? 0 : Min ((unsigned)G_StringWidth (g),
3201                                          G_Width (g) - s_x);
3202                       clip.height = (s_y + s_t + h_t >= (unsigned)G_Height (g))
3203                               ? 0 : Min ((unsigned)G_StringHeight (g),
3204                                          G_Height (g) - s_y);
3205                       break;
3206                    default:
3207                      /* Unknown alignment */
3208                      clip.width = 0;
3209                      clip.height = 0;
3210                  }
3211                 if (clip.width > 0 && clip.height > 0)
3212                 {
3213                         if (fill_mode == XmFILL_TRANSPARENT)
3214                         {
3215                            adj_x = s_t + h_t + G_MarginWidth(g);
3216                            adj_y = s_t + h_t + G_MarginHeight(g);
3217                            switch (G_PixmapPosition(g))
3218                            {
3219                               case XmPIXMAP_TOP:
3220                               case XmPIXMAP_BOTTOM:
3221                                  XFillRectangle(d, drawable, 
3222                                                 G_ParentBackgroundGC(g),
3223                                                 clip.x - adj_x, 
3224                                                 clip.y - adj_y + s_t + h_t,
3225                                                 clip.width + (2 * adj_y),
3226                                                 clip.height + (2 * adj_x) - 
3227                                                                 (s_t + h_t));
3228                                  break;
3229                               case XmPIXMAP_RIGHT:
3230                               case XmPIXMAP_LEFT:
3231                                 begin = clip.x - adj_x + s_t + h_t;
3232                                 rec_width = clip.width + (2 * adj_y) 
3233                                                              -(s_t + h_t);
3234                                 if (G_PixmapPosition(g) == XmPIXMAP_LEFT &&
3235                                     begin > (int) (x + p_x) && 
3236                                     begin < (int) (x + p_x + width))
3237                                 {
3238                                    /*
3239                                     * XmPIXMAP_LEFT -- the rectangle starts
3240                                     * inside the pixmap
3241                                     */
3242                                         diff = x+p_x+width - begin;
3243                                         begin+=diff;
3244                                         rec_width-=diff;
3245                                 }
3246                                 else if(G_PixmapPosition(g) == XmPIXMAP_RIGHT &&
3247                                     (rec_width+begin) > (x+p_x))
3248                                 {
3249                                     /*
3250                                      * PIXMAP_RIGHT -- rectangle drawn into
3251                                      * the pixmap
3252                                      */
3253                                         diff = ( rec_width + begin) - (x+p_x);
3254                                         rec_width-=diff;
3255                                 }
3256
3257                                  XFillRectangle(d, drawable, 
3258                                                 G_ParentBackgroundGC(g),
3259                                                 begin, 
3260                                                 clip.y - adj_y,
3261                                                 rec_width,
3262                                                 clip.height + (2 * adj_x));
3263                                  break;
3264                               case XmPIXMAP_MIDDLE:
3265                                  XFillRectangle(d, drawable, 
3266                                                 G_ParentBackgroundGC(g),
3267                                                 clip.x - adj_x,
3268                                                 clip.y - adj_y,
3269                                                 clip.width + (2 * adj_y),
3270                                                 clip.height + (2 * adj_x));
3271                                  break;
3272                             }
3273                         }
3274
3275                         XmStringDrawImage (d, drawable, G_FontList (g),
3276                                 G_String (g), gc, x + s_x, y + s_y,
3277                                 clip.width, XmALIGNMENT_BEGINNING,
3278                                 XmSTRING_DIRECTION_L_TO_R, &clip);
3279
3280                         if (G_Underline(g))
3281                         {
3282                            XmStringDrawUnderline (d, drawable, G_FontList (g),
3283                                 G_String (g), gc, x + s_x, y + s_y,
3284                                 clip.width, XmALIGNMENT_BEGINNING,
3285                                 XmSTRING_DIRECTION_L_TO_R, &clip,
3286                                 G_String(g));
3287                         }
3288                 }
3289         }
3290
3291         /* Potentially fill the area between the label and the pixmap */
3292         if ((fill_mode == XmFILL_TRANSPARENT) && G_Pixmap(g) && G_String(g) &&
3293            (height > 0) && (width > 0) && (clip.width > 0) && (clip.height > 0))
3294         {
3295            switch (G_PixmapPosition(g))
3296            {
3297               case XmPIXMAP_TOP:
3298                       XFillRectangle(d, drawable, G_ParentBackgroundGC(g),
3299                                      x + Max(s_x, p_x), y + p_y + height,
3300                                      Min(clip.width, width),
3301                                      s_y - (p_y + height));
3302                       break;
3303
3304               case XmPIXMAP_BOTTOM:
3305                       XFillRectangle(d, drawable, G_ParentBackgroundGC(g),
3306                                      x + Max(s_x, p_x), y + s_y + clip.height,
3307                                      Min(clip.width, width),
3308                                      p_y - (s_y + clip.height));
3309                       break;
3310
3311               case XmPIXMAP_RIGHT:
3312                       XFillRectangle(d, drawable, G_ParentBackgroundGC(g),
3313                                      x + s_x + clip.width, y + Max(s_y, p_y),
3314                                      p_x - (s_x + clip.width),
3315                                      Min(clip.height, height));
3316                       break;
3317               case XmPIXMAP_LEFT:
3318                       XFillRectangle(d, drawable, G_ParentBackgroundGC(g),
3319                                      x + p_x + width, y + Max(s_y, p_y),
3320                                      s_x - (p_x + width),
3321                                      Min(clip.height, height));
3322                       break;
3323               case XmPIXMAP_MIDDLE:
3324                       XFillRectangle(d, drawable, G_ParentBackgroundGC(g),
3325                                      x + Max(s_x, p_x), y + Max(s_y, p_y),
3326                                      Min(clip.width, width),
3327                                      Min(clip.height, height));
3328                       break;
3329            }
3330         }
3331
3332
3333 /*      Draw shadow.
3334 */
3335         if (G_ShadowThickness (g) > 0 && G_DrawShadow(g)){
3336            if(G_BorderType(g) == DtRECTANGLE || !G_Pixmap(g))
3337                 {
3338                   unsigned char shadow_type;
3339
3340                   if (((G_Behavior (g) == XmICON_BUTTON) && G_Armed (g)) ||
3341                       ((G_Behavior (g) == XmICON_TOGGLE) &&
3342                        ((!G_Set (g) && G_Armed (g)) ||
3343                        (G_Set (g) && !G_Armed (g)))))
3344                     shadow_type = XmSHADOW_IN;
3345                   else
3346                     shadow_type = XmSHADOW_OUT;
3347
3348                   XmeDrawShadows(d, drawable, 
3349                                  M_TopShadowGC(MgrParent(g)),
3350                                  M_BottomShadowGC(MgrParent(g)),
3351                                  x + h_t, y + h_t, w - 2*h_t, h - 2*h_t,
3352                                  s_t, shadow_type);
3353                 }
3354            else
3355              {
3356                CallCallbackProc call_callback;
3357                _DtProcessLock();
3358                call_callback = C_CallCallback(XtClass(g));
3359                _DtProcessUnlock();
3360                (*call_callback) (g, G_Callback (g), XmCR_SHADOW, NULL);
3361              }
3362         }
3363 }
3364
3365
3366 \f
3367 /*-------------------------------------------------------------
3368 **      CallCallback
3369 **              Call callback, if any, with reason and event.
3370 */
3371 static void 
3372 CallCallback(
3373         DtIconGadget g,
3374         XtCallbackList cb,
3375         int reason,
3376         XEvent *event )
3377 {
3378         DtIconCallbackStruct    cb_data;
3379
3380         if (cb != NULL)
3381         {
3382                 cb_data.reason = reason;
3383                 cb_data.event = event;
3384                 cb_data.set = G_Set (g);
3385                 XtCallCallbackList ((Widget) g, cb, &cb_data);
3386         }
3387 }
3388
3389
3390
3391
3392 \f
3393 /*-------------------------------------------------------------
3394 **      UpdateGCs
3395 **              Get normal and background graphics contexts.
3396 **              Use standard mask to maximize caching opportunities.
3397 */
3398 static void 
3399 UpdateGCs(
3400         DtIconGadget g )
3401 {
3402         XGCValues       values;
3403         XtGCMask        value_mask;
3404         XmManagerWidget mw = (XmManagerWidget) XtParent(g);
3405         XFontStruct *   font;
3406
3407         if (G_NormalGC (g))
3408                 XtReleaseGC ((Widget)mw, G_NormalGC (g));
3409         if (G_ClipGC (g))
3410                 XtReleaseGC ((Widget)mw, G_ClipGC (g));
3411         if (G_BackgroundGC (g))
3412                 XtReleaseGC ((Widget)mw, G_BackgroundGC (g));
3413         if (G_ArmedGC (g))
3414                 XtReleaseGC ((Widget)mw, G_ArmedGC (g));
3415         if (G_ArmedBackgroundGC (g))
3416                 XtReleaseGC ((Widget)mw, G_ArmedBackgroundGC (g));
3417
3418 /*      Get normal GC.
3419 */
3420         value_mask = GCForeground | GCBackground | GCFillStyle;
3421         values.foreground = G_Foreground (g);
3422         values.background = G_Background (g);
3423         values.fill_style = FillSolid;
3424         if (XmeRenderTableGetDefaultFont(G_FontList (g), &font)) {
3425            value_mask |= GCFont;
3426            values.font = font->fid;
3427         }
3428         G_NormalGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
3429
3430 /*      Get background GC.
3431 */
3432         values.foreground = G_Background (g);
3433         values.background = G_Foreground (g);
3434         G_BackgroundGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
3435
3436 /*      Get armed GC.
3437 */
3438         values.foreground = G_Foreground (g);
3439         values.background = G_ArmColor (g);
3440         G_ArmedGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
3441
3442 /*      Get armed background GC.
3443 */
3444         values.foreground = G_ArmColor (g);
3445         values.background = G_Background (g);
3446         G_ArmedBackgroundGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
3447
3448         if (G_Mask(g) != XmUNSPECIFIED_PIXMAP) {
3449             value_mask |= GCClipMask;
3450             values.clip_mask = G_Mask(g);
3451             values.foreground = G_Foreground (g);
3452             values.background = G_Background (g);
3453             G_ClipGC (g) = XtGetGC ((Widget)mw, value_mask, &values);
3454         }
3455         else
3456           G_ClipGC (g) = NULL;
3457 }
3458
3459
3460 /*-------------------------------------------------------------
3461 **      GetIconClassSecResData ( )
3462 **              Class function to be called to copy secondary resource
3463 **              for external use.  i.e. copy the cached resources and
3464 **              send it back.
3465 **-------------------------------------------------------------
3466 */
3467 /* ARGSUSED */
3468 static Cardinal 
3469 GetIconClassSecResData(
3470         WidgetClass class,
3471         XmSecondaryResourceData **data_rtn )
3472 {   int arrayCount = 0;
3473     XmBaseClassExt  bcePtr;
3474     String  resource_class, resource_name;
3475     XtPointer  client_data;
3476
3477     _DtProcessLock();
3478     bcePtr = &( iconBaseClassExtRec);
3479     client_data = NULL;
3480     resource_class = NULL;
3481     resource_name = NULL;
3482     arrayCount =
3483       _XmSecondaryResourceData ( bcePtr, data_rtn, client_data,
3484                                 resource_name, resource_class,
3485                             (XmResourceBaseProc) (GetIconClassResBase));
3486     _DtProcessUnlock();
3487
3488     return (arrayCount);
3489 }
3490
3491
3492 /*-------------------------------------------------------------
3493 **      GetIconClassResBase ()
3494 **              return the address of the base of resources.
3495 **              - Not yet implemented.
3496 **-------------------------------------------------------------
3497 */
3498 /* ARGSUSED */
3499 static XtPointer 
3500 GetIconClassResBase(
3501         Widget widget,
3502         XtPointer client_data )
3503 {   XtPointer  widgetSecdataPtr;
3504     int  icon_cache_size = sizeof (DtIconCacheObjPart);
3505     char *cp;
3506
3507     widgetSecdataPtr = (XtPointer) (XtMalloc ( icon_cache_size +1));
3508
3509     if (widgetSecdataPtr)
3510       { 
3511         cp = (char *) widgetSecdataPtr;
3512
3513 #ifndef SVR4
3514         bcopy ( (char *) ( Icon_Cache(widget)), (char *) cp, icon_cache_size);
3515 #else
3516         memmove ( (char *)cp , (char *) ( Icon_Cache(widget)), icon_cache_size);
3517 #endif
3518       }
3519
3520     return (widgetSecdataPtr);
3521 }
3522
3523
3524 \f
3525 /*-------------------------------------------------------------
3526 **      Public Entry Points
3527 **-------------------------------------------------------------
3528 */
3529
3530 /*-------------------------------------------------------------
3531 **      _DtCreateIcon
3532 **              Create a new gadget instance.
3533 **-------------------------------------------------------------
3534 */
3535 Widget 
3536 _DtCreateIcon(
3537         Widget parent,
3538         String name,
3539         ArgList arglist,
3540         Cardinal argcount )
3541 {
3542         return (XtCreateWidget (name, dtIconGadgetClass, 
3543                         parent, arglist, argcount));
3544 }
3545
3546
3547 \f
3548 /*-------------------------------------------------------------
3549 **      _DtIconGetState
3550 **              Return state of Icon.
3551 **-------------------------------------------------------------
3552 */
3553 Boolean 
3554 _DtIconGetState(
3555         Widget w )
3556 {
3557         DtIconGadget g =        (DtIconGadget) w;
3558
3559         return (G_Set (g));
3560 }
3561
3562
3563 /*-------------------------------------------------------------
3564 **      _DtIconSetState
3565 **              Set state of Icon.
3566 **-------------------------------------------------------------
3567 */
3568 void 
3569 _DtIconSetState(
3570         Widget w,
3571         Boolean state,
3572         Boolean notify )
3573 {
3574         DtIconGadget g =        (DtIconGadget) w;
3575         CallCallbackProc        call_callback;
3576         XtExposeProc            expose;
3577
3578         if (G_Behavior (g) != XmICON_TOGGLE || state == G_Set (g))
3579                 return;
3580
3581         _DtProcessLock();
3582         call_callback = C_CallCallback(XtClass(g));
3583         expose = XtCoreProc(w, expose);
3584         _DtProcessUnlock();
3585
3586         G_Set (g) = state;
3587         (*expose) ((Widget)g, NULL, NULL);
3588
3589         if (notify)
3590           {
3591             (*call_callback) (g, G_Callback (g), XmCR_VALUE_CHANGED, NULL);
3592           }
3593 }
3594
3595
3596 \f
3597 /*-------------------------------------------------------------
3598 **      _DtIconDraw
3599 **              Render gadget to drawable without highlight.
3600 **-------------------------------------------------------------
3601 */
3602 Drawable 
3603 _DtIconDraw(
3604         Widget widget,
3605         Drawable drawable,
3606         Position x,
3607         Position y,
3608         Boolean fill )
3609 {
3610         DtIconGadget    g =             (DtIconGadget) widget;
3611         Dimension       h_t =           G_HighlightThickness (g),
3612                         w =             G_Width (g) - 2 * h_t,
3613                         h =             G_Height (g) - 2 * h_t;
3614         unsigned char   fill_mode;
3615         DrawProc        draw;
3616
3617         if (!drawable || drawable == XmUNSPECIFIED_PIXMAP)
3618                 drawable = (Drawable)
3619                         XCreatePixmap (XtDisplay (g),
3620                                 RootWindowOfScreen (XtScreen (g)),
3621                                 w, h, DefaultDepthOfScreen (XtScreen (g)));
3622
3623         fill_mode = (fill) ? XmFILL_SELF : XmFILL_PARENT;
3624         
3625         _DtProcessLock();
3626         draw = C_Draw(XtClass(g));
3627         _DtProcessUnlock();
3628         (*draw) (g, drawable, x, y, w, h,
3629                  0, G_ShadowThickness (g), G_ShadowType (g), fill_mode);
3630
3631         return (drawable);
3632 }
3633
3634
3635 \f
3636 /***************************************************************************/
3637
3638
3639 /*
3640  * Load the specified pixmap.
3641  */
3642
3643 static Boolean 
3644 LoadPixmap(
3645         DtIconGadget new,
3646         String pixmap )
3647
3648 {
3649    unsigned int int_h, int_w;
3650    Screen *s = XtScreen(new);
3651    Pixmap pm = XmGetPixmap(s, pixmap, G_PixmapForeground(new),
3652                            G_PixmapBackground(new));
3653    Pixmap mask;
3654
3655    if (pm == XmUNSPECIFIED_PIXMAP)
3656       return(True);
3657
3658    mask = XmeGetMask(s, pixmap);
3659
3660    G_Pixmap(new) = pm;
3661    G_Mask(new) = mask;
3662    G_ImageName(new) = XtNewString(pixmap);
3663
3664    XmeGetPixmapData(s, pm, NULL, NULL, NULL, NULL, NULL, NULL, &int_w, &int_h);
3665    G_PixmapWidth(new) = Limit((Dimension)int_w, G_MaxPixmapWidth(new));
3666    G_PixmapHeight(new) = Limit((Dimension)int_h, G_MaxPixmapWidth(new));
3667    return(False);
3668 }
3669
3670
3671 \f
3672 Widget 
3673 _DtDuplicateIcon(
3674         Widget parent,
3675         Widget widget,
3676         XmString string,
3677         String pixmap,
3678         XtPointer user_data,
3679         Boolean underline )
3680 {
3681    DtIconGadget gadget;
3682    int size;
3683    DtIconGadget new;
3684    Dimension h, w;
3685    DtIconCacheObjPart local_cache;
3686    XtWidgetProc insert_child;
3687    GetSizeProc get_size;
3688
3689    /* Create the new instance structure */
3690    gadget = (DtIconGadget) widget;
3691    _DtProcessLock();
3692    size = XtClass(gadget)->core_class.widget_size;
3693    _DtProcessUnlock();
3694    new = (DtIconGadget)XtMalloc(size);
3695
3696    /* Copy the master into the duplicate */
3697
3698 #ifndef       SVR4
3699    bcopy((char *)gadget, (char *)new, (int)size);
3700 #else
3701    memmove((char *)new, (char *)gadget, (int)size);
3702 #endif
3703
3704    _DtProcessLock();
3705    insert_child = 
3706      ((CompositeWidgetClass)XtClass(parent))->composite_class.insert_child;
3707    get_size = C_GetSize(XtClass(new));
3708    Icon_Cache(new) = (DtIconCacheObjPart *)
3709                        _XmCachePart(Icon_ClassCachePart(new),
3710                                     (XtPointer) Icon_Cache(new),
3711                                     sizeof(DtIconCacheObjPart));
3712    _DtProcessUnlock();
3713
3714    /* Certain fields need to be updated */
3715    new->object.parent = parent;
3716    new->object.self = (Widget)new;
3717    G_FontList(new) = XmFontListCopy(G_FontList(gadget));
3718
3719    /* Certain fields should not be inherited by the clone */
3720    new->object.destroy_callbacks = NULL;
3721    new->object.constraints = NULL;
3722    new->gadget.help_callback = NULL;
3723    new->icon.drop_callback = NULL;
3724    new->rectangle.managed = False;
3725    G_Callback(new) = NULL;
3726
3727    /* Set the user_data field */
3728    new->gadget.user_data = user_data;
3729
3730    /* Process the optional pixmap name */
3731    if ((pixmap == NULL) || LoadPixmap(new, pixmap))
3732    {
3733       /* No pixmap to load */
3734       G_ImageName(new) = NULL;
3735       G_Pixmap(new) = None;
3736       G_PixmapWidth(new) = 0;
3737       G_PixmapHeight(new) = 0;
3738    }
3739
3740    /* Process the required label string */
3741    G_String(new) = XmStringCopy(string);
3742    XmStringExtent(G_FontList(new), G_String(new), &w, &h);
3743    G_Underline(new) = underline;
3744    if (G_Underline(new))
3745       h++;
3746    G_StringWidth(new) = w;
3747    QualifyIconLocalCache(new, &local_cache);
3748    local_cache.string_height = h;
3749
3750    ReCacheIcon_r(&local_cache, new);
3751
3752    /* Get copies of the GC's */
3753    G_NormalGC(new) = NULL;
3754    G_BackgroundGC(new) = NULL;
3755    G_ArmedGC(new) = NULL;
3756    G_ArmedBackgroundGC(new) = NULL;
3757    G_ClipGC(new) = NULL;
3758    UpdateGCs(new);
3759
3760    /* Size the gadget */
3761    (*get_size) (new, &w, &h);
3762    G_Width(new) = w;
3763    G_Height(new) = h;
3764
3765    /* Insert the duplicate into the parent's child list */
3766    (*insert_child) ((Widget)new);
3767
3768    return ((Widget) new);
3769 }
3770
3771
3772 Boolean 
3773 _DtIconSelectInTitle(
3774         Widget widget,
3775         Position pt_x,
3776         Position pt_y )
3777
3778 {
3779    DtIconGadget g =     (DtIconGadget) widget;
3780    Position     x, y;
3781    Dimension    w, h, h_t, s_t;
3782    XRectangle   clip;
3783    Position     p_x, p_y, s_x, s_y;
3784    GetPositionProc      get_positions;
3785
3786    h_t = 0;
3787    s_t = G_ShadowThickness(g);
3788    x = G_X(g);
3789    y = G_Y(g);
3790    w = G_Width (g); 
3791    h = G_Height (g);
3792    _DtProcessLock();
3793    get_positions = C_GetPositions(XtClass(g));
3794    _DtProcessUnlock();
3795    (*get_positions) (g, w, h, h_t, s_t, &p_x, &p_y, &s_x, &s_y);
3796
3797    if (G_String (g))
3798    {
3799       clip.x = x + s_x;
3800       clip.y = y + s_y;
3801       clip.width = (s_x + s_t + h_t >= (unsigned)G_Width (g))
3802          ? 0 : Min ((unsigned)G_StringWidth (g), 
3803                     G_Width (g) - s_x - s_t - h_t);
3804       clip.height = (s_y + s_t + h_t >= (unsigned)G_Height (g))
3805          ? 0 : Min ((unsigned)G_StringHeight (g), 
3806                     G_Height (g) - s_y - s_t - h_t);
3807       if (clip.width <= 0 || clip.height <= 0)
3808          return(False);
3809       else
3810       {
3811          if ((pt_x >= clip.x) && 
3812              (pt_y >= clip.y) &&
3813              ((unsigned)pt_x <= clip.x + clip.width) && 
3814              ((unsigned)pt_y <= clip.y + clip.height))
3815             return(True);
3816          else
3817             return(False);
3818       }
3819    }
3820    else
3821       return(False);
3822 }
3823
3824
3825 /*
3826  * Thread-safe variant of _DtIconGetTextExtent.
3827  */
3828 void 
3829 _DtIconGetTextExtent_r(Widget widget,
3830                        XRectangle *clip)
3831 {
3832    DtIconGadget g =     (DtIconGadget) widget;
3833    Position     x, y;
3834    Dimension    w, h, h_t, s_t;
3835    Position     p_x, p_y, s_x, s_y;
3836    GetPositionProc      get_positions;
3837
3838    h_t = 0;
3839    s_t = G_ShadowThickness(g);
3840    x = G_X(g);
3841    y = G_Y(g);
3842    w = G_Width (g); 
3843    h = G_Height (g);
3844    _DtProcessLock();
3845    get_positions = C_GetPositions(XtClass(g));
3846    _DtProcessUnlock();
3847    (*get_positions) (g, w, h, h_t, s_t, &p_x, &p_y, &s_x, &s_y);
3848
3849    if (G_String (g))
3850    {
3851       clip->x = x + s_x;
3852       clip->y = y + s_y;
3853       clip->width = (s_x + s_t + h_t >= (unsigned)G_Width (g))
3854          ? 0 : Min ((unsigned)G_StringWidth (g), 
3855                     G_Width (g) - s_x - s_t - h_t);
3856       clip->height = (s_y + s_t + h_t >= (unsigned)G_Height (g))
3857          ? 0 : Min ((unsigned)G_StringHeight (g), 
3858                     G_Height (g) - s_y - s_t - h_t);
3859
3860       if (clip->width <= 0)
3861          clip->width = 0;
3862
3863       if (clip->height <= 0)
3864          clip->height = 0;
3865    }
3866    else
3867    {
3868       clip->x = 0;
3869       clip->y = 0;
3870       clip->height = 0;
3871       clip->width = 0;
3872    }
3873 }
3874
3875
3876 /*
3877  * Returns a pointer to a static storage area; must not be freed.
3878  * This interface is deprecated in favor of _DtIconGetTextExtent_r.
3879  */
3880
3881 XRectangle * 
3882 _DtIconGetTextExtent(
3883         Widget widget )
3884
3885 {
3886    static XRectangle    clip;
3887
3888    _DtIconGetTextExtent_r(widget, &clip);
3889
3890    return(&clip);
3891 }
3892 \f
3893 /*-------------------------------------------------------------
3894 **      _DtIconGetIconRects
3895 **              Returns rects occupied by label and pixmap
3896 */
3897 void 
3898 _DtIconGetIconRects(
3899         DtIconGadget g,
3900         unsigned char *flags,
3901         XRectangle *rect1,
3902         XRectangle *rect2 )
3903
3904 {
3905    Position     p_x, p_y, s_x, s_y;
3906    Dimension    width, height;
3907    Position     adj_x, adj_y;
3908    Dimension    h_t, s_t;
3909    GetPositionProc      get_positions;
3910    
3911    h_t = G_HighlightThickness(g);
3912    s_t = G_ShadowThickness(g);
3913
3914    adj_x = G_MarginWidth(g);
3915    adj_y = G_MarginHeight(g);
3916    _DtProcessLock();
3917    get_positions = C_GetPositions(XtClass(g));
3918    _DtProcessUnlock();
3919    (*get_positions) (g, G_Width(g), G_Height(g), h_t, s_t, &p_x, &p_y, &s_x, &s_y);
3920    *flags = 0;
3921
3922    if (G_Pixmap (g))
3923    {
3924       width = (p_x + s_t + h_t >= (unsigned)G_Width (g)) ? 0 : 
3925                  Min ((unsigned)G_PixmapWidth (g), 
3926                       G_Width (g) - p_x - s_t - h_t);
3927       height = (p_y + s_t + h_t >= (unsigned)G_Height (g)) ? 0 : 
3928                  Min ((unsigned)G_PixmapHeight (g), 
3929                       G_Height (g) - p_y - s_t - h_t);
3930       if (width > 0 && height > 0)
3931       {
3932          rect1->x = G_X(g) + p_x - adj_x; 
3933          rect1->y = G_Y(g) + p_y - adj_y;
3934          rect1->width = width + (2 * adj_y);
3935          rect1->height = height + (2 * adj_x);
3936          *flags |= XmPIXMAP_RECT;
3937       }
3938    }
3939
3940    if (G_String(g))
3941    {
3942       width = (s_x + s_t + h_t >= (unsigned)G_Width (g)) ? 0 : 
3943         Min ((unsigned)G_StringWidth (g), G_Width (g) - s_x - s_t - h_t);
3944       height = (s_y + s_t + h_t >= (unsigned)G_Height (g)) ? 0 : 
3945         Min ((unsigned)G_StringHeight (g), G_Height (g) - s_y - s_t - h_t);
3946       if (width > 0 && height > 0)
3947       {
3948          rect2->x = G_X(g) + s_x - adj_x;
3949          rect2->y = G_Y(g) + s_y - adj_y;
3950          rect2->width = width + (2 * adj_y);
3951          rect2->height = height + (2 * adj_x);
3952          *flags |= XmLABEL_RECT;
3953       }
3954    }
3955 }
3956
3957 /* ARGSUSED */
3958 /* Do animation when everything is completed.
3959  * Note: DropDestroy callback is the only notification after the melt has
3960  * been completed.
3961  */
3962 static void
3963 AnimateCallback(
3964     Widget      w,
3965     XtPointer   clientData,
3966     XtPointer   callData )
3967 {
3968   DtIconGadget g = (DtIconGadget) w;
3969
3970   if (G_DropCallback(g)) {
3971      XtCallCallbackList(w, G_DropCallback(g), callData);
3972   }
3973 }
3974
3975 /* ARGSUSED */
3976 static void
3977 TransferCallback(
3978         Widget w,
3979         XtPointer clientData,
3980         XtPointer callData )
3981 {
3982   DtDndTransferCallback call_data = (DtDndTransferCallback) callData;
3983   DtIconGadget g = (DtIconGadget) w;
3984
3985   call_data->x += G_X(g);
3986   call_data->y += G_Y(g);
3987
3988   if (G_DropCallback(g)) {
3989      XtCallCallbackList(w, G_DropCallback(g), callData);
3990   }
3991 }
3992
3993 /*-------------------------------------------------------------
3994 **      _DtIconRegisterDropsite
3995 **              Registers the Icon as a dropsite.
3996 */
3997 void 
3998 _DtIconRegisterDropsite(
3999         Widget w)
4000
4001 {
4002     XtCallbackRec transferCB[] = { {TransferCallback, NULL}, {NULL, NULL} };
4003     XtCallbackRec animateCB[] = { {AnimateCallback, NULL}, {NULL, NULL} };
4004     DtIconGadget g =    (DtIconGadget) w;
4005     XRectangle rects[2];
4006     unsigned char flags;
4007     int numRects = 0;
4008     Arg args[5];
4009     Cardinal n;
4010
4011     _DtIconGetIconRects(g, &flags, &rects[0], &rects[1]);
4012
4013     if (flags & XmPIXMAP_RECT) {
4014         rects[0].x -= G_X(g);
4015         rects[0].y -= G_Y(g);
4016         numRects++;
4017     }
4018
4019     if (flags & XmLABEL_RECT) {
4020         rects[1].x -= G_X(g);
4021         rects[1].y -= G_Y(g);
4022        if (!numRects) rects[0] = rects[1];
4023        numRects++;
4024     }
4025
4026     n = 0;
4027     if (numRects) {
4028         XtSetArg(args[n], XmNdropRectangles, rects); n++;
4029         XtSetArg(args[n], XmNnumDropRectangles, numRects); n++;
4030     }
4031     XtSetArg(args[n], XmNanimationStyle, XmDRAG_UNDER_SHADOW_IN); n++;
4032     XtSetArg(args[n], DtNtextIsBuffer, True); n++;
4033     XtSetArg(args[n], DtNdropAnimateCallback, animateCB); n++;
4034
4035     DtDndDropRegister(w, DtDND_FILENAME_TRANSFER|DtDND_BUFFER_TRANSFER,
4036         G_Operations(g), transferCB,
4037         args, n);
4038 }