libDtSearch: Coverity 86579
[oweals/cde.git] / cde / programs / dtfile / Encaps.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: Encaps.c /main/10 1996/10/30 11:10:16 drk $ */
24 /************************************<+>*************************************
25  ****************************************************************************
26  *
27  *   FILE:           Encaps.c
28  *
29  *   COMPONENT_NAME: Desktop File Manager (dtfile)
30  *
31  *   Description:    Source file for the dialog encapsulation functions.
32  *
33  *   FUNCTIONS: DataChangeCallback
34  *              DataCloseCallback
35  *              DialogStructureNotifyHandler
36  *              IntDialogGetResources
37  *              IntDialogPutResources
38  *              SetIconifyState
39  *              TimerEvent
40  *              _DtBooleanToString
41  *              _DtBuildDialog
42  *              _DtChildPosition
43  *              _DtDialogGetResources
44  *              _DtDialogPutResources
45  *              _DtDimensionToString
46  *              _DtEncapSetWorkSpaceHints
47  *              _DtFreeDialogData
48  *              _DtGetDefaultDialogData
49  *              _DtGetDialogData
50  *              _DtGetDialogInstance
51  *              _DtGetDialogShell
52  *              _DtGetInstanceData
53  *              _DtGetResourceDialogData
54  *              _DtHideDialog
55  *              _DtInitializeEncapsulation
56  *              _DtInstallDialog
57  *              _DtIntToString
58  *              _DtIsDialogShowing
59  *              _DtPositionToString
60  *              _DtShortToString
61  *              _DtShowBuiltDialog
62  *              _DtShowDialog
63  *              _DtStringToString
64  *              _DtWriteDialogData
65  *              _DtXmStringTableToString
66  *              _DtXmStringToString
67  *              _DtmapCB
68  *              _DtChangeTo
69  *
70  *   (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
71  *   (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
72  *   (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
73  *   (c) Copyright 1993, 1994, 1995 Novell, Inc.
74  *
75  ****************************************************************************
76  ************************************<+>*************************************/
77
78
79 #include <string.h>
80 #include <Xm/XmP.h>
81 #include <Xm/Xm.h>
82 #include <Xm/BulletinB.h>
83 #include <Xm/AtomMgr.h>
84 #include <Xm/MwmUtil.h>
85 #include <Xm/VendorSEP.h>
86 #include <Xm/XmPrivate.h> /* _XmStringUngenerate, _XmGetWidgetExtData */
87 #include <X11/ShellP.h>
88 #include <X11/Shell.h>
89 #include <X11/Xutil.h>
90 #include <X11/Xatom.h>
91 #include <X11/Intrinsic.h>
92
93 #include <Dt/Wsm.h>
94 #include <Dt/DtNlUtils.h>
95
96 #include "Encaps.h"
97 #include "Desktop.h"
98 #include "Filter.h"
99 #include "FileMgr.h"
100 #include "Main.h"
101 #include "ModAttr.h"
102 #ifdef USE_XINERAMA
103 #include <DtXinerama.h>
104 #endif
105
106 #define MAX_NAME_LIST_SIZE      25
107 #define MAX_RESOURCE_LENGTH     256
108
109
110 /*  Cache array handling defines, structure, and global statics  */
111
112 #define INCREMENT_SIZE  10
113
114
115 typedef struct _Dialog
116 {
117    Boolean                 in_use;
118    Widget                  dialog_widget;
119    XtPointer               dialog;
120    DialogData            * dialog_data;
121    DialogChangedProc       change;
122    XtPointer               change_client_data;
123    DialogClosedProc        close;
124    XtPointer               close_client_data;
125    struct _Dialog        * next;
126 } Dialog;
127
128
129 typedef struct
130 {
131    DialogClass * class;
132    Dialog      * dialog_list;
133    Boolean       cache;
134    Boolean       destroyPopups;
135 } ClassSet;
136
137 extern int filter_dialog,mod_attr_dialog;
138
139 static ClassSet * class_set = NULL;
140 static int class_set_size = 0;
141 static int num_classes = 0;
142 static int NumberOfDialogMapped = 0;
143
144 static char * resourceBuf = NULL;
145 static int commonResourceCount = 5;
146 static DialogResource commonResources[] =
147 {
148    { "displayed", XmRBoolean, sizeof(Boolean),
149      XtOffset(DialogInstanceDataPtr, displayed),
150      (caddr_t) False, _DtBooleanToString },
151
152    { "x", XmRPosition, sizeof(Position),
153      XtOffset(DialogInstanceDataPtr, x),
154      (caddr_t) 0, _DtPositionToString},
155
156    { "y", XmRPosition, sizeof(Position),
157       XtOffset(DialogInstanceDataPtr, y),
158       (caddr_t) 0, _DtPositionToString },
159
160    { "width", XmRHorizontalDimension, sizeof(Dimension),
161      XtOffset(DialogInstanceDataPtr, width),
162      (caddr_t) 0, _DtDimensionToString },
163
164    { "height", XmRVerticalDimension, sizeof(Dimension),
165       XtOffset(DialogInstanceDataPtr, height),
166       (caddr_t) 0, _DtDimensionToString },
167 };
168
169 static Widget encap_parent_shell;
170
171 extern int file_mgr_dialog;
172
173 /*  Timer globals */
174 /*
175  * initialTimeoutLength is used to specify how long to wait before initially
176  *    kicking of the building of the dialog cache.
177  * activeTimeoutLength is used to specify how long to wait after adding
178  *    a dialog to the cache, before adding the next dialog.
179  * idleTimeoutLength is used to specify how long to wait after all dialogs
180  *    have been built, and the cache is full.
181  */
182 int initialTimeoutLength = 180000;      /* 3 minutes, in milliseconds */
183 int activeTimeoutLength = 30000;        /* 30 seconds, in milliseconds */
184 int idleTimeoutLength = 900000;         /* 15 minutes, in milliseconds */
185
186 #define TIMER_STARTUP_STATE  0
187 #define TIMER_ACTIVE_STATE   1
188 #define TIMER_IDLE_STATE     2
189
190 static int timerState = TIMER_STARTUP_STATE;
191 static XtIntervalId timerId = 0;
192
193
194 /*
195  * This global is used when positioning a dialog ABOVE (not below) its
196  * parent window.  The 'y' position is defined to be the 'y' position
197  * of the parent, minus the 'height' of the dialog, minus the value
198  * assigned to 'topPositionOffset'; this allows the application to control
199  * how much, if any, of the parent's title bar is covered.
200  */
201 int topPositionOffset = 20;
202
203
204 /********    Static Function Declarations    ********/
205
206 static void DialogStructureNotifyHandler(
207                         Widget w,
208                         XtPointer client_data,
209                         XEvent *event );
210 static void SetIconifyState(
211                         Widget shell,
212                         Boolean iconify) ;
213 static void DataChangeCallback(
214                         Widget widget,
215                         XtPointer client_data,
216                         XtPointer call_data) ;
217 static void DataCloseCallback(
218                         Widget widget,
219                         XtPointer client_data,
220                         XtPointer call_data) ;
221 static void TimerEvent(
222                         Widget widget,
223                         XtIntervalId *id) ;
224 static void IntDialogGetResources(
225                         XrmDatabase database,
226                         char *base,
227                         DialogResource *resource,
228                         XrmName *xrmName,
229                         int nameCount,
230                         XrmQuark stringQuark) ;
231 static void IntDialogPutResources(
232                         int fd,
233                         char **nameList,
234                         char *dialogName,
235                         char *base,
236                         DialogResource *resource) ;
237 #ifdef USE_XINERAMA
238 static Boolean GetXineramaScreenDimensions(
239         Widget w,int *xorg, int *yorg, int *width,int *height);
240 #endif /* USE_XINERAMA */
241
242 /********    End Static Function Declarations    ********/
243
244
245
246 /************************************************************************
247  *
248  *  _DtInitializeEncapsulation
249  *      This function is used to initialize the dialog encapsulation.
250  *
251  ************************************************************************/
252
253 void
254 _DtInitializeEncapsulation(
255         Display *display,
256         char *name,
257         char *class )
258
259 {
260    Arg args[5];
261
262    /*  Create an application shell that will never be    */
263    /*  displayed that is used as a parent of all of the  */
264    /*  dialog created.                                   */
265
266    encap_parent_shell = XtAppCreateShell (name, class,
267                                     applicationShellWidgetClass,
268                                     display, NULL, 0);
269
270    /* Supposedly required to be ICCCM complient */
271    XtSetArg(args[0], XmNmappedWhenManaged, False);
272    XtSetArg(args[1], XmNwidth, 1);
273    XtSetArg(args[2], XmNheight, 1);
274    XtSetValues(encap_parent_shell, args, 3);
275    XtRealizeWidget(encap_parent_shell);
276
277    /*  Get a timer going that is used for auto creation of dialogs.  */
278
279    timerState = TIMER_STARTUP_STATE;
280    timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(encap_parent_shell),
281                              initialTimeoutLength, (XtTimerCallbackProc)
282                              TimerEvent, (caddr_t) encap_parent_shell);
283
284    /* Allocate a buffer for writing out resource values */
285    resourceBuf = XtMalloc(20);
286 }
287
288
289
290
291 /************************************************************************
292  *
293  *  _DtInstallDialog
294  *      This function is used to register a dialog class with the
295  *      encapsulation functions.
296  *
297  ************************************************************************/
298
299 int
300 _DtInstallDialog(
301         DialogClass *dialog_class,
302         Boolean cache,
303         Boolean destroyPopups )
304
305 {
306    /*  Allocate additional dialog cache space if needed  */
307
308    if (num_classes == class_set_size)
309    {
310       class_set_size += INCREMENT_SIZE;
311       class_set =
312          (ClassSet *) XtRealloc ((char *)class_set,
313                                  sizeof (ClassSet) * class_set_size);
314    }
315
316    class_set[num_classes].class = dialog_class;
317    class_set[num_classes].dialog_list = NULL;
318    class_set[num_classes].cache = cache;
319    class_set[num_classes].destroyPopups = destroyPopups;
320
321    num_classes++;
322
323    return (num_classes - 1);
324 }
325
326
327
328
329 /************************************************************************
330  *
331  *  _DtGetDialogData
332  *      This function is used to get a structure containing the
333  *      current dialog data for a particular dialog instance.
334  *
335  ************************************************************************/
336
337 DialogData *
338 _DtGetDialogData(
339         DialogData *dialog_data )
340
341 {
342    Dialog * dialog;
343    DialogData * new_data;
344
345    dialog = class_set[dialog_data->type].dialog_list;
346
347    while (dialog != NULL)
348    {
349       if (dialog->dialog_data == dialog_data)
350       {
351          new_data = (DialogData *) XtMalloc (sizeof (DialogData));
352
353          new_data->type = dialog->dialog_data->type;
354          new_data->data = NULL;
355          if (class_set[new_data->type].class->get_values)
356          {
357             new_data->data =
358               (*(class_set[new_data->type].class->get_values)) (dialog->dialog);
359          }
360
361          return (new_data);
362       }
363
364       dialog = dialog->next;
365    }
366
367    return (NULL);
368 }
369
370
371
372
373 /************************************************************************
374  *
375  *  _DtGetDefaultDialogData
376  *      This function is used to get a structure containing the
377  *      default data for a particular dialog type.
378  *
379  ************************************************************************/
380
381 DialogData *
382 _DtGetDefaultDialogData(
383         int dialog_type )
384
385
386 {
387    DialogData * dialog_data;
388
389    dialog_data = (DialogData *) XtMalloc (sizeof (DialogData));
390
391    dialog_data->type = dialog_type;
392    dialog_data->data = (*(class_set[dialog_type].class->get_default_values))();
393
394    return (dialog_data);
395 }
396
397
398
399
400 /************************************************************************
401  *
402  *  _DtGetResourceDialogData
403  *      This function is used to get a structure containing the
404  *      data for a particular dialog type from a resource data base.
405  *
406  ************************************************************************/
407
408 DialogData *
409 _DtGetResourceDialogData(
410         int dialog_type,
411         XrmDatabase data_base,
412         char **name_list )
413
414 {
415    DialogData * dialog_data;
416
417    dialog_data = (DialogData *) XtMalloc (sizeof (DialogData));
418
419    dialog_data->type = dialog_type;
420    dialog_data->data = (*(class_set[dialog_type].class->get_resource_values))
421                           (data_base, name_list);
422
423    return (dialog_data);
424 }
425
426
427
428
429 /************************************************************************
430  *
431  *  _DtShowDialog
432  *      This functions is used to display an instance of a dialog with
433  *      the provided data.  The functions and data to be set back to
434  *      the application upon change or close of the dialog is also
435  *      provided as parameters.
436  *
437  ************************************************************************/
438 void
439 _DtShowDialog(
440         Widget parent,
441         Widget map_parent,
442         XtPointer top_rec,
443         DialogData *dialog_data,
444         DialogChangedProc change_proc,
445         XtPointer change_data,
446         DialogClosedProc close_proc,
447         XtPointer close_data,
448         char *workspaces,
449         Boolean iconify_state,
450         Boolean ignoreCache,
451         char * title,
452         XClassHint * classHints )
453
454 {
455    Dialog * dialog;
456    int dialog_type, n;
457    DialogInstanceData * instance_data;
458    char geometry[40];
459    Arg args[5];
460    Boolean doCenter = False;
461    Boolean doParentRelativePositioning = False;
462    int availableDialogCount;
463
464
465    /*  See if there is a cached, unused dialog of the correct type.  */
466
467    dialog_type = dialog_data->type;
468    dialog = NULL;
469
470    if (!ignoreCache)
471    {
472       Dialog * availableDialog;
473
474       availableDialog = class_set[dialog_type].dialog_list;
475       availableDialogCount = 0;
476
477       /*
478        * In addition to looking for an available dialog in the cache to use,
479        * we also want to count up the number of unused dialogs in the cache.
480        * This lets us know it we need to restart the timer, to again build
481        * up the cache.
482        */
483       while (availableDialog != NULL)
484       {
485          if (availableDialog->in_use == False)
486          {
487             if (dialog == NULL)
488                dialog = availableDialog;
489             else
490                availableDialogCount++;
491          }
492          availableDialog = availableDialog->next;
493       }
494    }
495
496    if (dialog == NULL)
497    {
498       dialog = (Dialog *) XtMalloc (sizeof (Dialog));
499
500       (*(class_set[dialog_type].class->create))
501          (XtDisplay (encap_parent_shell), encap_parent_shell,
502          &(dialog->dialog_widget), &dialog->dialog);
503
504       /* if this is a File Manager view we want to update the headers
505        * (i.e icon_path, current_directory, status_line), now so that they
506        * don't get managed up front.  This is to make the Application
507        * Manager (toolbox) happy.
508        */
509       if(dialog_type == file_mgr_dialog)
510          UpdateHeaders(dialog->dialog, dialog_data->data, False);
511
512       /*  Add the change and close callbacks into the dialog  */
513
514       if (class_set[dialog_type].class->install_change_callback)
515          (*(class_set[dialog_type].class->install_change_callback))
516             (dialog->dialog, DataChangeCallback, (XtPointer)dialog);
517
518       if (class_set[dialog_type].class->install_close_callback)
519          (*(class_set[dialog_type].class->install_close_callback))
520             (dialog->dialog, DataCloseCallback, (XtPointer)dialog);
521
522       dialog->next = class_set[dialog_type].dialog_list;
523       class_set[dialog_type].dialog_list = dialog;
524    }
525    else
526    {
527       if(dialog_type == mod_attr_dialog)
528       {
529         ModAttrRec *mr = (ModAttrRec *)dialog->dialog;
530         ResetFlag(NULL,mr->ok);
531         ResetFlag(NULL,mr->cancel);
532       }
533       else if(dialog_type == filter_dialog)
534       {
535         FilterRec *fr = (FilterRec *)dialog->dialog;
536         ResetFlag(NULL,fr->ok);
537         ResetFlag(NULL,fr->close);
538       }
539    }
540
541    if ((!ignoreCache) && (class_set[dialog_type].cache) &&
542        (availableDialogCount < 1) && (timerState == TIMER_IDLE_STATE))
543    {
544       /*
545        * We need to reset the cache building timer, so that it gets kicked
546        * off quickly, instead of after the longer idle delay.
547        */
548       if (timerId)
549         XtRemoveTimeOut(timerId);
550       timerState = TIMER_ACTIVE_STATE;
551       timerId = XtAppAddTimeOut(
552                  XtWidgetToApplicationContext(encap_parent_shell),
553                  activeTimeoutLength, (XtTimerCallbackProc) TimerEvent,
554                  (XtPointer) encap_parent_shell);
555    }
556
557    /*
558     * Set pointer to top dialog data in child of the shell.
559     * This is needed to get help to work.
560     */
561    if (top_rec == NULL)
562       top_rec = dialog->dialog;
563    XtSetArg(args[0], XmNuserData, top_rec);
564    XtSetValues(dialog->dialog_widget, args, 1);
565
566    /* Need to add the map callback in relation to the parent */
567    if (class_set[dialog_type].class->map)
568    {
569       /*
570        * The map_parent parameter gives us the ability to position
571        * the dialog relative to a window which is not the transientFor
572        * parent.  This is used for the audio preview dialog.
573        */
574       if (map_parent == NULL)
575          map_parent = parent;
576
577       (*(class_set[dialog_type].class->map)) (map_parent, dialog->dialog);
578    }
579
580
581    /*  Set the dialog structure fields to the parameter data.  */
582
583    dialog->in_use = True;
584    dialog->dialog_data = dialog_data;
585    dialog->change = change_proc;
586    dialog->change_client_data = change_data;
587    dialog->close = close_proc;
588    dialog->close_client_data = close_data;
589
590
591    instance_data = (DialogInstanceData *) dialog_data->data;
592
593    /* If a special title has been specified, we need to set it now */
594    if (title)
595    {
596       XtSetArg(args[0], XmNtitle, title);
597       XtSetValues(XtParent(dialog->dialog_widget), args, 1);
598    }
599
600    /*  If this is a top level shell, get it realized  */
601
602    if (XtIsSubclass (XtParent (dialog->dialog_widget),
603                      applicationShellWidgetClass))
604    {
605       if (XtIsRealized (XtParent (dialog->dialog_widget)) == False)
606       {
607          if (instance_data->displayed == True)
608          {
609             (void) sprintf (geometry, "=%dx%d+%d+%d",
610                             instance_data->width, instance_data->height,
611                             instance_data->x, instance_data->y);
612
613             XtSetArg (args[0], XmNgeometry, geometry);
614             XtSetValues (XtParent (dialog->dialog_widget), args, 1);
615          }
616          else if ((instance_data->width != 0) && (instance_data->height != 0))
617          {
618             n=0;
619             XtSetArg (args[n], XmNwidth, instance_data->width); n++;
620             XtSetArg (args[n], XmNheight, instance_data->height); n++;
621             XtSetValues (XtParent (dialog->dialog_widget), args, n);
622          }
623
624          /* Toggle mappedWhenManaged to false */
625          XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), False);
626          XtRealizeWidget (XtParent(dialog->dialog_widget));
627
628          /* Set the proper workspaces if needed */
629          _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
630
631          /* Set any application-specified class hints for the window */
632          if (classHints)
633          {
634             XSetClassHint(XtDisplay(dialog->dialog_widget),
635                           XtWindow(XtParent(dialog->dialog_widget)),
636                           classHints);
637          }
638
639          /* Set the iconify state */
640          SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
641
642          /* Map the window */
643          XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), True);
644          XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
645          XSync(XtDisplay(dialog->dialog_widget), False);
646
647       }
648       else
649       {
650          if (instance_data->displayed == True)
651          {
652             WMShellWidget wm = (WMShellWidget)XtParent(dialog->dialog_widget);
653
654             wm->wm.size_hints.flags |= USPosition;
655             XtSetArg (args[0], XmNx, instance_data->x);
656             XtSetArg (args[1], XmNy, instance_data->y);
657             XtSetArg (args[2], XmNwidth, instance_data->width);
658             XtSetArg (args[3], XmNheight, instance_data->height);
659             XtSetValues (XtParent (dialog->dialog_widget), args, 4);
660          }
661          else if ((instance_data->width != 0) && (instance_data->height != 0))
662          {
663             n=0;
664             XtSetArg (args[n], XmNwidth, instance_data->width); n++;
665             XtSetArg (args[n], XmNheight, instance_data->height); n++;
666             XtSetValues (XtParent (dialog->dialog_widget), args, n);
667          }
668
669          /* Set the proper workspaces if needed */
670          _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
671
672          /* Set any application-specified class hints for the window */
673          if (classHints)
674          {
675             XSetClassHint(XtDisplay(dialog->dialog_widget),
676                           XtWindow(XtParent(dialog->dialog_widget)),
677                           classHints);
678          }
679
680          /* Set the iconify state */
681          SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
682
683          /* Map the window */
684          XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
685       }
686    }
687    else
688    {
689       if (instance_data->displayed == True)
690       {
691          XtSetArg (args[0], XmNx, instance_data->x);
692          XtSetArg (args[1], XmNy, instance_data->y);
693          XtSetArg (args[2], XmNwidth, instance_data->width);
694          XtSetArg (args[3], XmNheight, instance_data->height);
695          XtSetArg (args[4], XmNdefaultPosition, False);
696          XtSetValues (dialog->dialog_widget, args, 5);
697          XtRealizeWidget (dialog->dialog_widget);
698       }
699       else
700       {
701          XtSetArg (args[0], XmNdefaultPosition, False);
702          XtSetValues (dialog->dialog_widget, args, 1);
703
704          XtRealizeWidget (dialog->dialog_widget);
705
706          if (parent)
707          {
708             /* Position relative to the parent dialog */
709             /*
710              * Must be done after the set_values call, since the dialog
711              * may get forced to a different size.
712              */
713             doParentRelativePositioning = True;
714          }
715          else
716          {
717             /* Center in the display */
718             /*
719              * Must be done after the set_values call, since the dialog
720              * may get forced to a different size.
721              */
722             doCenter = True;
723          }
724       }
725
726       /*
727        * Dialogs with no controlling parent window, need to have their
728        * own workspace perperty set, if some workspaces have been requested.
729        */
730       if ((parent == NULL) && workspaces)
731          _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
732    }
733
734
735    /*  Set Values onto the dialog to set it to the correct data.  */
736
737    (*(class_set[dialog_data->type].class->set_values))
738       (dialog->dialog, dialog_data->data);
739
740    /*
741     * These two adjustments MUST be done AFTER the dialog's SetValues()
742     * procedure is called.  This is due to the fact that the setvalues
743     * may cause the dialog size to change, and since both of the following
744     * positioning algorithms are dependent upon the dialog size, we want
745     * to make sure that the correct size is used.
746     */
747    if (doCenter)
748    {
749       XtSetArg (args[0], XmNx,
750           (Dimension)(WidthOfScreen(XtScreen(dialog->dialog_widget)) -
751            dialog->dialog_widget->core.width) / (Dimension)2);
752       XtSetArg (args[1], XmNy,
753           (Dimension)(HeightOfScreen(XtScreen(dialog->dialog_widget)) -
754            dialog->dialog_widget->core.height) / (Dimension)2);
755       XtSetValues (dialog->dialog_widget, args, 2);
756    }
757    else if (doParentRelativePositioning)
758    {
759       XtSetArg (args[0], XmNx,
760           parent->core.x +
761           (Dimension)(parent->core.width - dialog->dialog_widget->core.width) / (Dimension)2);
762       XtSetArg (args[1], XmNy,
763           parent->core.y +
764           (Dimension)(parent->core.height - dialog->dialog_widget->core.height) / (Dimension)2);
765       XtSetValues (XtParent(dialog->dialog_widget), args, 2);
766    }
767
768
769    /*  Fix up the transient-for windowing information so that  */
770    /*  the window manager will shuffle and iconify as a group  */
771
772    if (parent != NULL)
773    {
774       if (XtIsRealized(parent))
775       {
776          XSetTransientForHint (XtDisplay (parent),
777                             XtWindow (XtParent (dialog->dialog_widget)),
778                             XtWindow (parent));
779       }
780    }
781    else
782    {
783       if (!XtIsSubclass (XtParent (dialog->dialog_widget),
784                                      applicationShellWidgetClass))
785       {
786          XSetTransientForHint (XtDisplay (encap_parent_shell),
787                             XtWindow (XtParent (dialog->dialog_widget)),
788                             XtWindow (encap_parent_shell));
789       }
790    }
791
792
793    /*  Display the dialogs, application shells are displayed above.  */
794
795    if (!(XtIsSubclass (XtParent (dialog->dialog_widget),
796                        applicationShellWidgetClass)))
797    {
798       XtManageChild (dialog->dialog_widget);
799    }
800
801
802    /*  Set the dialog instance data to indicate that the dialog  */
803    /*  is displayed.                                             */
804
805    ((DialogInstanceData *) (dialog_data->data))->displayed = True;
806
807
808    /* Give the dialog a chance to set its focus widget, if necessary */
809
810    if (class_set[dialog_data->type].class->set_focus)
811    {
812       (*(class_set[dialog_data->type].class->set_focus))
813          (dialog->dialog, dialog_data->data);
814    }
815
816
817
818    XtAddEventHandler( XtParent( dialog->dialog_widget ),
819                       StructureNotifyMask,
820                       False,
821                       (XtEventHandler)DialogStructureNotifyHandler,
822                       NULL );
823 }
824
825
826
827
828 /************************************************************************
829  *
830  *  _DtHideDialog
831  *      This function is used to undisplay a dialog.
832  *
833  ************************************************************************/
834
835 void
836 _DtHideDialog(
837         DialogData *dialog_data,
838         Boolean call_callbacks )
839
840 {
841    Dialog * dialog;
842    DialogData * new_data;
843    CorePart * core;
844    int i;
845
846
847    /*  Find the dialog and then hide it.  */
848
849    dialog = class_set[dialog_data->type].dialog_list;
850
851    while (dialog != NULL)
852    {
853        if ((dialog->dialog_data &&
854             dialog->dialog_data == dialog_data) && dialog->in_use == True)
855
856       {
857
858          /*  Free up any dialogs attached to the dialog widget  */
859
860          if(class_set[dialog_data->type].destroyPopups)
861          {
862             core = (CorePart *) (XtParent (dialog->dialog_widget));
863
864             for (i = core->num_popups - 1; i >= 0; i--)
865                XtDestroyWidget (core->popup_list[i]);
866          }
867
868
869          /*  Get the dialog down, invoke the close callbacks, and  */
870          /*  take it out of use.                                   */
871
872          if (XtIsSubclass (XtParent (dialog->dialog_widget),
873                            applicationShellWidgetClass))
874          {
875             ShellWidget shell_widget;
876
877             /*
878              * If we had been iconified, then our popped_up flag will
879              * have been cleared by the vendor shell.  When we call
880              * XtPopdown(), it will see that we are no longer popped
881              * up, and will not notify the window manager that our
882              * icon should be removed; this can cause a subsequent
883              * core dump if the user later tries to deiconify the window.
884              * This fix should not be necessary once the toolkit is
885              * fixed to properly track the shell's state.
886              */
887             shell_widget = (ShellWidget) XtParent(dialog->dialog_widget);
888             shell_widget->shell.popped_up = True;
889
890             XtPopdown ((Widget)shell_widget);
891          }
892          else
893          {
894             /*
895              * The following is for the condition described above.  However,
896              * for a dialog shell, what happens it that the 'managed' flag
897              * was set to 'False' when the windows were iconified (apparently
898              * by the dialog shell), and when we tell the intrinsics to
899              * really unmanage the child, it thinks it already has, so
900              * nothing happens; as a result, the dialog shell is left with
901              * its 'popped_up' flag set to 'True'.  The next time we try
902              * to post this dialog, the intrinsics think that it is already
903              * up, so it does nothing.
904              */
905             dialog->dialog_widget->core.managed = True;
906             XtUnmanageChild (dialog->dialog_widget);
907          }
908
909
910          /*  Set the dialog data to hidden  */
911
912          ((DialogInstanceData *) (dialog->dialog_data->data))->displayed = False;
913
914
915          if (call_callbacks && dialog->close)
916          {
917             new_data = (DialogData *) XtMalloc (sizeof (DialogData));
918
919             new_data->type = dialog->dialog_data->type;
920             new_data->data = NULL;
921             if (class_set[new_data->type].class->get_values)
922             {
923                new_data->data =
924                (*(class_set[new_data->type].class->get_values))(dialog->dialog);
925             }
926
927             dialog->in_use = False;
928             if (new_data->data)
929                ((DialogInstanceData *) (new_data->data))->displayed = False;
930
931             (*(dialog->close))
932                   (dialog->close_client_data, dialog->dialog_data, new_data);
933          }
934          else
935          {
936             dialog->in_use = False;
937             ((DialogInstanceData *) (dialog->dialog_data->data))->displayed = False;
938          }
939
940          break;
941       }
942
943       dialog = dialog->next;
944    }
945 }
946
947
948
949
950 /************************************************************************
951  *
952  *  _DtGetDialogShell
953  *      This function is used return the shell widget of a dialog that
954  *      is currently displayed.
955  *
956  ************************************************************************/
957
958 Widget
959 _DtGetDialogShell(
960         DialogData *dialog_data )
961
962 {
963    Dialog * dialog;
964
965
966    /*  Find the dialog and then return the shell.  */
967
968    dialog = class_set[dialog_data->type].dialog_list;
969
970    while (dialog != NULL)
971    {
972       if (dialog->dialog_data == dialog_data)
973          return (dialog->dialog_widget);
974       else
975          dialog = dialog->next;
976    }
977
978    return (NULL);
979 }
980
981
982
983
984 /************************************************************************
985  *
986  *  _DtGetDialogInstance
987  *      This function is used return the dialog instance structure
988  *      of a currently in use dialog.
989  *
990  ************************************************************************/
991
992 XtPointer
993 _DtGetDialogInstance(
994         DialogData *dialog_data )
995
996 {
997    Dialog * dialog;
998
999
1000    /*  Find the dialog and then return the instance  */
1001
1002    dialog = class_set[dialog_data->type].dialog_list;
1003
1004    while (dialog != NULL)
1005    {
1006       if (dialog->dialog_data && dialog->dialog_data == dialog_data)
1007          return (dialog->dialog);
1008       else
1009          dialog = dialog->next;
1010    }
1011
1012    return (NULL);
1013 }
1014
1015
1016
1017
1018 /************************************************************************
1019  *
1020  *  _DtGetInstanceData
1021  *      This function is used return the dialog data structure contained
1022  *      within the cache structure referenced by instance.
1023  *
1024  ************************************************************************/
1025
1026 DialogData *
1027 _DtGetInstanceData(
1028         XtPointer instance )
1029
1030 {
1031    int i;
1032    Dialog * dialog;
1033
1034
1035    /*  Find the dialog and then return the instance  */
1036
1037    for (i = 0; i < num_classes; i++)
1038    {
1039       dialog = class_set[i].dialog_list;
1040
1041       while (dialog != NULL)
1042       {
1043          if (dialog->dialog == instance && dialog->in_use == True)
1044             return (dialog->dialog_data);
1045          else
1046             dialog = dialog->next;
1047       }
1048    }
1049
1050    return (NULL);
1051 }
1052
1053
1054
1055
1056 /************************************************************************
1057  *
1058  *  _DtIsDialogShowing
1059  *      This function is used return a boolean indicating whether the
1060  *      a dialog is displayed which contains the dialog data.
1061  *      of a currently in use dialog.
1062  *
1063  ************************************************************************/
1064
1065 Boolean
1066 _DtIsDialogShowing(
1067         DialogData *dialog_data )
1068
1069 {
1070    Dialog * dialog;
1071
1072
1073    /*  Find the dialog and then return the instance  */
1074
1075    dialog = class_set[dialog_data->type].dialog_list;
1076
1077    while (dialog != NULL)
1078    {
1079       if (dialog->in_use && dialog->dialog_data == dialog_data)
1080          return (True);
1081       else
1082          dialog = dialog->next;
1083    }
1084
1085    return (False);
1086 }
1087
1088
1089
1090
1091 /************************************************************************
1092  *
1093  *  _DtWriteDialogData
1094  *      This function is used to write, as resources, the data
1095  *      for a dialog contained in dialog_data to the open file fd.
1096  *
1097  ************************************************************************/
1098
1099 void
1100 _DtWriteDialogData(
1101         DialogData *dialog_data,
1102         int fd,
1103         char **name_list )
1104
1105 {
1106    if (dialog_data != NULL)
1107       (*(class_set[dialog_data->type].class->write_resource_values))
1108          (dialog_data, fd, name_list);
1109 }
1110
1111
1112
1113
1114 /************************************************************************
1115  *
1116  *  _DtFreeDialogData
1117  *      This function is used to free up the data space allocated
1118  *      by a dialog.
1119  *
1120  ************************************************************************/
1121
1122 void
1123 _DtFreeDialogData(
1124         DialogData *dialog_data )
1125
1126 {
1127    if (dialog_data != NULL)
1128    {
1129       (*(class_set[dialog_data->type].class->free_values)) (dialog_data->data);
1130       XtFree ((char *) dialog_data);
1131        dialog_data = NULL;
1132    }
1133 }
1134
1135
1136
1137
1138 /************************************************************************
1139  *
1140  *  _DtDialogGetResources
1141  *      This function accesses data_base to extract the resource set
1142  *      described by the resoruces array.  Resources values are
1143  *      converted to the proper type and defaults are used if not
1144  *      data is found in the resource data base.
1145  *
1146  ************************************************************************/
1147
1148 void
1149 _DtDialogGetResources(
1150         XrmDatabase database,
1151         char **name_list,
1152         char *dialog_name,
1153         char *base,
1154         DialogResource *resources,
1155         int resource_count )
1156
1157 {
1158    XrmName xrmName[MAX_NAME_LIST_SIZE];
1159    XrmQuark stringQuark;
1160    int nameCount;
1161    int i;
1162
1163    /*  Build the quarkified name list from name_list and dialog_name  */
1164    /*  provided by the calling procedure.                             */
1165
1166    nameCount = 0;
1167    if (name_list != NULL)
1168    {
1169       while (name_list[nameCount] != NULL)
1170       {
1171          xrmName[nameCount] =  XrmStringToQuark (name_list[nameCount]);
1172          nameCount++;
1173       }
1174    }
1175
1176    if (dialog_name)
1177       xrmName[nameCount] = XrmStringToQuark (dialog_name);
1178    else
1179       nameCount--;
1180
1181    xrmName[nameCount + 2] = 0;
1182    stringQuark = XrmStringToQuark (XmRString);
1183
1184
1185    /* Load the common dialog size/position resources */
1186    for (i = 0; i < resource_count; i++)
1187    {
1188       IntDialogGetResources(database, base, resources + i, xrmName, nameCount,
1189                             stringQuark);
1190    }
1191
1192    /*
1193     * Load the dialog specific resources. If no value found, use the default.
1194     */
1195    for (i = 0; i < commonResourceCount; i++)
1196    {
1197       IntDialogGetResources(database, base, commonResources + i, xrmName,
1198                             nameCount, stringQuark);
1199    }
1200 }
1201
1202
1203 /*
1204  * This internal function does the real work of loading a single resource
1205  * value.  If the value is not found in the resource database, then the
1206  * specified default value is used.
1207  */
1208
1209 static void
1210 IntDialogGetResources(
1211         XrmDatabase database,
1212         char *base,
1213         DialogResource *resource,
1214         XrmName *xrmName,
1215         int nameCount,
1216         XrmQuark stringQuark )
1217
1218 {
1219    XrmRepresentation repType;
1220    XrmValue value;
1221    XrmValue convertedValue;
1222    char  charVal;
1223    short shortVal;
1224    int   intVal;
1225    long  longVal;
1226
1227    {
1228       xrmName[nameCount + 1] = XrmStringToQuark (resource->name);
1229
1230       if (XrmQGetResource (database, xrmName, xrmName, &repType, &value))
1231       {
1232          if (repType == stringQuark)
1233             if (strcmp (resource->type, XmRString) != 0)
1234             {
1235                XtConvert (encap_parent_shell, XmRString, &value,
1236                                       resource->type, &convertedValue);
1237             }
1238             else
1239             {
1240                *((char **)(base + resource->offset)) = (char *)value.addr;
1241                return;
1242             }
1243          else
1244             convertedValue.addr = NULL;
1245
1246       }
1247       else
1248          convertedValue.addr = NULL;
1249
1250
1251       /*  Set the converted value address pointer and value to  */
1252       /*  the proper default value if the addr is NULL.         */
1253
1254       if (convertedValue.addr == NULL)
1255       {
1256          if (resource->size == sizeof(char))
1257          {
1258             charVal = (char)(XtArgVal)resource->default_value;
1259             convertedValue.addr = (caddr_t) &charVal;
1260          }
1261          else if (resource->size == sizeof(short))
1262          {
1263             shortVal = (short)(XtArgVal)resource->default_value;
1264             convertedValue.addr = (caddr_t) &shortVal;
1265          }
1266          else if (resource->size == sizeof(int))
1267          {
1268             intVal = (int)(XtArgVal)resource->default_value;
1269             convertedValue.addr = (caddr_t) &intVal;
1270          }
1271          else
1272          {
1273             longVal = (long)(XtArgVal)resource->default_value;
1274             convertedValue.addr = (caddr_t) &longVal;
1275          }
1276       }
1277
1278
1279       /*  Stuff the converted value into the calling functions   */
1280       /*  structure according to the size of the piece of data.  */
1281
1282       if (resource->size == sizeof(char))
1283          *((char *)(base + resource->offset)) = *((char *)convertedValue.addr);
1284       else if (resource->size == sizeof(short))
1285          *((short *)(base + resource->offset))= *((short *)convertedValue.addr);
1286       else if (resource->size == sizeof(int))
1287          *((int *)(base + resource->offset))= *((int *)convertedValue.addr);
1288       else
1289          *((long *)(base + resource->offset)) = *((long *)convertedValue.addr);
1290    }
1291 }
1292
1293
1294
1295 /************************************************************************
1296  *
1297  *  _DtDialogPutResources
1298  *      This function writes a resource set to a file.
1299  *
1300  ************************************************************************/
1301
1302 void
1303 _DtDialogPutResources(
1304         int fd,
1305         char **nameList,
1306         char *dialogName,
1307         char *base,
1308         DialogResource *resources,
1309         int resourceCount )
1310
1311 {
1312    int i;
1313    DialogInstanceData * dialogInstanceData;
1314
1315    /*
1316     * Write out the common dialog size/position resources, only if the
1317     * dialog is currently displayed.
1318     */
1319    dialogInstanceData = (DialogInstanceData *)base;
1320    if (dialogInstanceData->displayed)
1321    {
1322       for (i = 0; i < commonResourceCount; i++)
1323       {
1324          IntDialogPutResources(fd, nameList, dialogName, base,
1325                                commonResources + i);
1326       }
1327    }
1328
1329    /*
1330     *  Loop through the dialog specific resources, write the name list and
1331     *  resource name.
1332     */
1333    for (i = 0; i < resourceCount; i++)
1334       IntDialogPutResources( fd, nameList, dialogName, base, resources + i);
1335 }
1336
1337
1338 /*
1339  * This internal function does the real work involved in writing a single
1340  * resource out to a session file.
1341  */
1342
1343 static void
1344 IntDialogPutResources(
1345         int fd,
1346         char **nameList,
1347         char *dialogName,
1348         char *base,
1349         DialogResource *resource )
1350
1351 {
1352    static char outBuf[MAX_RESOURCE_LENGTH];
1353    int nameCount;
1354
1355    outBuf[0] = '\0';
1356
1357    (void) strcat (outBuf, "*");
1358
1359    nameCount = 0;
1360    if (nameList != NULL)
1361    {
1362       while (nameList[nameCount] != NULL)
1363       {
1364          (void) strcat (outBuf, nameList[nameCount]);
1365          (void) strcat (outBuf, ".");
1366          nameCount++;
1367       }
1368    }
1369
1370    if (dialogName != NULL)
1371    {
1372       (void) strcat (outBuf, dialogName);
1373       (void) strcat (outBuf, ".");
1374    }
1375
1376    (void) strcat (outBuf, resource->name);
1377    (void) strcat (outBuf, ":    ");
1378
1379    (*(resource->write_resource))
1380       (fd, (XtPointer) (base + resource->offset), outBuf);
1381 }
1382
1383
1384
1385 /************************************************************************
1386  ************************************************************************
1387  *
1388  *      Internal functions
1389  *
1390  ************************************************************************
1391  ************************************************************************/
1392
1393
1394 /************************************************************************
1395  *
1396  *  _DtEncapSetWorkSpaceHints
1397  *      This function sets a given shell to a given set(s) of
1398  *   workspaces.
1399  *
1400  ************************************************************************/
1401 void
1402 _DtEncapSetWorkSpaceHints(
1403         Widget shell,
1404         char *workspaces )
1405
1406 {
1407    char * ptr;
1408    Atom * workspace_atoms = NULL;
1409    int num_workspaces=0;
1410
1411    if (workspaces)
1412    {
1413       do
1414       {
1415          ptr = DtStrchr (workspaces, '*');
1416
1417          if (ptr != NULL) *ptr = '\0';
1418
1419          workspace_atoms = (Atom *) XtRealloc ((char *)workspace_atoms,
1420                            sizeof (Atom) * (num_workspaces + 1));
1421
1422          workspace_atoms[num_workspaces] =
1423                            XmInternAtom (XtDisplay(shell), workspaces, True);
1424
1425          num_workspaces++;
1426
1427          if (ptr != NULL)
1428          {
1429             *ptr = '*';
1430             workspaces = ptr + 1;
1431          }
1432       } while (ptr != NULL);
1433
1434       DtWsmSetWorkspacesOccupied (XtDisplay(shell), XtWindow (shell), workspace_atoms,
1435                            num_workspaces);
1436
1437       XtFree ((char *) workspace_atoms);
1438       workspace_atoms = NULL;
1439    }
1440    else
1441    {
1442       Window   rootWindow;
1443       Atom     pCurrent;
1444       Screen   *currentScreen;
1445       int      screen;
1446       char     *workspace_name;
1447
1448       /*
1449        * Since no specific workspaces were specified, we will force the
1450        * dialog to the current workspace.
1451        */
1452       screen = XDefaultScreen(XtDisplay(shell));
1453       currentScreen = XScreenOfDisplay(XtDisplay(shell), screen);
1454       rootWindow = RootWindowOfScreen(currentScreen);
1455
1456       if(DtWsmGetCurrentWorkspace(XtDisplay(shell), rootWindow, &pCurrent) ==
1457                                Success)
1458       {
1459          DtWsmSetWorkspacesOccupied(XtDisplay(shell), XtWindow (shell), &pCurrent, 1);
1460       }
1461    }
1462 }
1463
1464 /************************************************************************
1465  *
1466  *  SetIconifyState
1467  *      This function sets a given shell to a given iconify state.
1468  *  (e.g. Mapped or iconified)
1469  *
1470  ************************************************************************/
1471 static void
1472 SetIconifyState(
1473         Widget shell,
1474         Boolean iconify )
1475
1476 {
1477    Arg       args[1];
1478    XWMHints   *wmhints;
1479
1480    if (iconify)
1481    {
1482      /* add the iconify hint to the current shell */
1483      XtSetArg(args[0], XmNinitialState, IconicState);
1484      XtSetValues(shell, args, 1);
1485    }
1486    else
1487    {
1488      /* Remove the iconify hint from the current shell */
1489      wmhints = XGetWMHints(XtDisplay(shell), XtWindow(shell));
1490      wmhints->flags |= IconWindowHint;
1491      wmhints->initial_state = NormalState;
1492      XSetWMHints(XtDisplay(shell), XtWindow(shell), wmhints);
1493      XFree(wmhints);
1494    }
1495
1496 }
1497 /************************************************************************
1498  *
1499  *  DataChangeCallback
1500  *      This callback is invoked from a dialog upon an action on the
1501  *      dialog that means that the data within the dialog has been
1502  *      changed.
1503  *
1504  ************************************************************************/
1505
1506 /*ARGSUSED*/
1507 static void
1508 DataChangeCallback(
1509         Widget widget,
1510         XtPointer client_data,
1511         XtPointer call_data )
1512
1513 {
1514    Dialog * dialog = (Dialog *) client_data;
1515    DialogData * new_data;
1516
1517    new_data = (DialogData *) XtMalloc (sizeof (DialogData));
1518
1519    new_data->type = dialog->dialog_data->type;
1520    new_data->data = NULL;
1521    if (class_set[new_data->type].class->get_values)
1522    {
1523       new_data->data = (*(class_set[new_data->type].class->get_values))
1524                           (dialog->dialog);
1525    }
1526
1527    if (dialog->change)
1528       (*(dialog->change))
1529          (dialog->change_client_data, dialog->dialog_data, new_data, call_data);
1530 }
1531
1532
1533
1534
1535 /************************************************************************
1536  *
1537  *  DataCloseCallback
1538  *      This callback is invoked from a dialog upon an action on the
1539  *      dialog that means the dialog has been closed.
1540  *
1541  ************************************************************************/
1542
1543 /*ARGSUSED*/
1544 static void
1545 DataCloseCallback(
1546         Widget widget,
1547         XtPointer client_data,
1548         XtPointer call_data )
1549
1550
1551 {
1552    Dialog * dialog = (Dialog *) client_data;
1553
1554    if(RecheckFlag(NULL,widget)) /* cancel flag already set, just return */
1555        return;
1556    _DtHideDialog (dialog->dialog_data, True);
1557 }
1558
1559
1560
1561
1562 /************************************************************************
1563  *
1564  *  TimerEvent
1565  *      This action function is called upon the encapsulations
1566  *      timeout going off.  Its function is to precreate and destroy
1567  *      extra dialogs.
1568  *
1569  ************************************************************************/
1570
1571 /* ARGSUSED */
1572 static void
1573 TimerEvent(
1574         Widget widget,
1575         XtIntervalId *id )
1576
1577 {
1578    int i;
1579    Dialog * dialog;
1580    Dialog * prev_dialog;
1581    int count;
1582
1583
1584    /*  First pass through the dialog set to see if any  */
1585    /*  need to be created.  This is based on having 0   */
1586    /*  not in use dialogs of each type.                 */
1587
1588    for (i = 0; i < num_classes; i++)
1589    {
1590       dialog = class_set[i].dialog_list;
1591
1592       /* Only attempt to cache dialogs requesting this feature */
1593       if (!class_set[i].cache)
1594          continue;
1595
1596       while (dialog != NULL)
1597          if (dialog->in_use == False)
1598             break;
1599          else
1600             dialog = dialog->next;
1601
1602       if (dialog == NULL)
1603       {
1604          dialog = (Dialog *) XtMalloc (sizeof (Dialog));
1605
1606          (*(class_set[i].class->create))
1607             (XtDisplay (encap_parent_shell), encap_parent_shell,
1608             &(dialog->dialog_widget), &dialog->dialog);
1609
1610
1611          /*  Add the change and close callbacks into the dialog  */
1612
1613          if (class_set[i].class->install_change_callback)
1614             (*(class_set[i].class->install_change_callback))
1615                (dialog->dialog, DataChangeCallback, (XtPointer)dialog);
1616
1617          if (class_set[i].class->install_close_callback)
1618             (*(class_set[i].class->install_close_callback))
1619                (dialog->dialog, DataCloseCallback, (XtPointer)dialog);
1620
1621
1622          dialog->next = class_set[i].dialog_list;
1623          class_set[i].dialog_list = dialog;
1624
1625          dialog->in_use = False;
1626
1627          timerState = TIMER_ACTIVE_STATE;
1628          timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(widget),
1629                                    activeTimeoutLength,
1630                                    (XtTimerCallbackProc) TimerEvent,
1631                                    (XtPointer) widget);
1632
1633          return;
1634       }
1635    }
1636
1637
1638    /*  Pass through the dialog set to see if any need to be destroyed    */
1639    /*  This is based on having more than 1 not in use dialog of a type.  */
1640
1641    for (i = 0; i < num_classes; i++)
1642    {
1643       dialog = class_set[i].dialog_list;
1644       count = 0;
1645
1646       while (dialog != NULL)
1647       {
1648          if (dialog->in_use == False)
1649             count++;
1650
1651          dialog = dialog->next;
1652       }
1653
1654       if (count > 1)
1655       {
1656          dialog = class_set[i].dialog_list;
1657
1658          if (dialog->in_use == False)
1659             class_set[i].dialog_list = dialog->next;
1660          else
1661          {
1662             prev_dialog = class_set[i].dialog_list;
1663             dialog = dialog->next;
1664
1665             while (dialog->in_use == True)
1666             {
1667               prev_dialog = dialog;
1668               dialog = dialog->next;
1669             }
1670
1671             prev_dialog->next = dialog->next;
1672          }
1673
1674          (*(class_set[i].class->destroy)) (dialog->dialog);
1675          XtFree ((char *) dialog);
1676           dialog = NULL;
1677
1678          break;
1679       }
1680    }
1681
1682    timerState = TIMER_IDLE_STATE;
1683    timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(widget),
1684                              idleTimeoutLength,
1685                              (XtTimerCallbackProc)TimerEvent,
1686                              (XtPointer)widget);
1687 }
1688
1689
1690
1691
1692 /************************************************************************
1693  ************************************************************************
1694  *
1695  *  Externed Type to String Converters and writers
1696  *
1697  ************************************************************************
1698  ************************************************************************/
1699
1700 void
1701 _DtIntToString(
1702         int fd,
1703         int *value,
1704         char *out_buf )
1705
1706 {
1707    (void) sprintf (resourceBuf, "%d", *value);
1708    _DtStringToString( fd, &resourceBuf, out_buf );
1709 }
1710
1711
1712 void
1713 _DtShortToString(
1714         int fd,
1715         short *value,
1716         char *out_buf )
1717
1718
1719 {
1720    (void) sprintf (resourceBuf, "%d", *value);
1721    _DtStringToString( fd, &resourceBuf, out_buf );
1722 }
1723
1724
1725
1726 void
1727 _DtPositionToString(
1728         int fd,
1729         Position *value,
1730         char *out_buf )
1731
1732 {
1733    (void) sprintf (resourceBuf, "%d", *value);
1734    _DtStringToString( fd, &resourceBuf, out_buf );
1735 }
1736
1737
1738
1739 void
1740 _DtDimensionToString(
1741         int fd,
1742         Dimension *value,
1743         char *out_buf )
1744
1745 {
1746    (void) sprintf (resourceBuf, "%d", *value);
1747    _DtStringToString( fd, &resourceBuf, out_buf );
1748 }
1749
1750
1751
1752 void
1753 _DtBooleanToString(
1754         int fd,
1755         Boolean *value,
1756         char *out_buf )
1757
1758 {
1759    char * buf;
1760
1761    if (*value == True)
1762       buf = "True";
1763    else
1764       buf = "False";
1765    _DtStringToString( fd, (char **)&buf, out_buf );
1766 }
1767
1768
1769 void
1770 _DtXmStringToString(
1771         int fd,
1772         XmString *value,
1773         char *out_buf )
1774
1775 {
1776    char *out_value = NULL;
1777
1778    if (*value != NULL)
1779    {
1780        out_value = (char *) _XmStringUngenerate(*value, XmFONTLIST_DEFAULT_TAG,
1781                                                 XmCHARSET_TEXT, XmCHARSET_TEXT);
1782        if ( out_value != NULL)
1783        {
1784            if (strlen (out_value) != 0)
1785            {
1786                (void) write (fd, out_value, strlen (out_value));
1787                _DtStringToString( fd, &out_value, out_buf );
1788
1789                XtFree ((char *) out_value);
1790            }
1791        }
1792    }
1793 }
1794
1795
1796 void
1797 _DtXmStringTableToString(
1798         int fd,
1799         XmStringTable *value,
1800         char *out_buf )
1801
1802 {
1803    int i;
1804    char *out_value = NULL;
1805    Boolean first = True;
1806
1807    if ((value != NULL) && (*value != NULL))
1808    {
1809       i = 0;
1810       while ((*value)[i] != NULL)
1811       {
1812           out_value = (char *)_XmStringUngenerate((*value)[i],
1813                                                   XmFONTLIST_DEFAULT_TAG,
1814                                                   XmCHARSET_TEXT, XmCHARSET_TEXT);
1815           if ( out_value != NULL)
1816           {
1817               if (first)
1818               {
1819                   (void) write (fd, out_buf, strlen (out_buf));
1820                   first = False;
1821               }
1822               else
1823                   (void) write (fd, ", ", strlen (", "));
1824
1825               (void) write (fd, out_value, strlen (out_value));
1826
1827               XtFree ((char *) out_value);
1828               out_value = NULL;
1829           }
1830
1831           i++;
1832       }
1833
1834       if (first == False)
1835           (void) write (fd, "\n", strlen ("\n"));
1836    }
1837 }
1838
1839
1840 void
1841 _DtStringToString(
1842         int fd,
1843         char **value,
1844         char *out_buf )
1845
1846 {
1847    if (*value == NULL || strlen (*value) == 0)
1848       ;
1849    else
1850    {
1851       (void) write (fd, out_buf, strlen (out_buf));
1852       (void) write (fd, *value, strlen (*value));
1853       (void) write (fd, "\n", strlen ("\n"));
1854    }
1855 }
1856
1857
1858 /*
1859  * _DtChildPosition:
1860  *   Choose a position for a popup window ("child") so that the main
1861  *   window ("parent") is not obscured.  The child will be positioned
1862  *   to the right, below, left, or above the parent, depending on where
1863  *   there is the most space.
1864  */
1865
1866 void
1867 _DtChildPosition(
1868          Widget w,
1869          Widget parent,
1870          Position *newX,
1871          Position *newY)
1872 {
1873    Position pY, pX;
1874    XmVendorShellExtObject vendorExt;
1875    XmWidgetExtData        extData;
1876    int xOffset, yOffset;
1877    int pHeight, myHeight, sHeight;
1878    int pWidth, myWidth, sWidth;
1879    enum { posRight, posBelow, posLeft, posAbove } pos;
1880    int space;
1881    int xOrg=0, yOrg=0; /* Xinerama screen origin */
1882
1883    /* get x, y offsets for the parent's window frame */
1884    extData = _XmGetWidgetExtData(parent, XmSHELL_EXTENSION);
1885    if (extData)
1886    {
1887      vendorExt = (XmVendorShellExtObject)extData->widget;
1888      xOffset = vendorExt->vendor.xOffset;
1889      yOffset = vendorExt->vendor.yOffset;
1890    }
1891    else
1892      xOffset = yOffset = 0;
1893
1894    #ifdef USE_XINERAMA
1895    if(!GetXineramaScreenDimensions(parent,&xOrg,&yOrg,&sWidth,&sHeight)){
1896       sHeight = HeightOfScreen(XtScreen(parent));
1897       sWidth = WidthOfScreen(XtScreen(parent));
1898    }
1899    #else
1900    /* get size/position of screen, parent, and widget */
1901    sHeight = HeightOfScreen(XtScreen(parent));
1902    sWidth = WidthOfScreen(XtScreen(parent));
1903    #endif /* USE_XINERAMA */
1904
1905    pX = XtX(parent) - xOffset - xOrg;
1906    pY = XtY(parent) - yOffset - yOrg;
1907    pHeight = XtHeight(parent) + yOffset + xOffset;
1908    pWidth = XtWidth(parent) + 2*xOffset;
1909    myHeight = XtHeight(w) + yOffset + xOffset;
1910    myWidth = XtWidth(w) + 2*xOffset;
1911
1912    /*
1913     * Determine how much space would be left if the child was positioned
1914     * to the right, below, left, or above the parent.  Choose the child
1915     * positioning so that the maximum space is left.
1916     */
1917    pos = posRight;
1918    space = sWidth - (pX + pWidth + myWidth);
1919
1920    if (sHeight - (pY + pHeight + myHeight) > space)
1921    {
1922       pos = posBelow;
1923       space = sHeight - (pY + pHeight + myHeight);
1924    }
1925
1926    if (pX - myWidth > space)
1927    {
1928       pos = posLeft;
1929       space = pX - myWidth;
1930    }
1931
1932    if (pY - myHeight > space)
1933    {
1934       pos = posAbove;
1935       space = pY - myHeight;
1936    }
1937
1938    /* Given relative positioning, determine x, y coordinates for the child */
1939
1940    switch (pos)
1941    {
1942      case posRight:
1943        *newX = pX + pWidth + 5;
1944        *newY = pY + (pHeight - myHeight)/2;
1945        break;
1946
1947      case posBelow:
1948        *newX = pX + (pWidth - myWidth)/2;
1949        *newY = pY + pHeight + 5;
1950        break;
1951
1952      case posLeft:
1953        *newX = pX - myWidth - 5;
1954        *newY = pY + (pHeight - myHeight)/2;
1955        break;
1956
1957      case posAbove:
1958        *newX = pX + (pWidth - myWidth)/2;
1959        *newY = pY - myHeight - 5;
1960        break;
1961    }
1962
1963    /*
1964     * The above calculations may put the dialog offscreen so one
1965     * last check must be made.  One way this can happen is if the
1966     * parent has been resized to fill almost the entire screen.
1967     * This can also happen if the parent has been maximized
1968     * and the window manager has its 'positionOnScreen' resource
1969     * set to False.
1970     */
1971    if ((*newX >= (sWidth -  10)) || (*newX < 0))
1972       *newX = sWidth - myWidth + 5;
1973    if ((*newY >= (sHeight - 10)) || (*newY < 0))
1974       *newY = (sHeight - myHeight) / 2;
1975
1976         *newX+=xOrg;
1977         *newY+=yOrg;
1978 }
1979
1980
1981 /* ARGSUSED */
1982 void
1983 _DtmapCB(
1984          Widget w,
1985          XtPointer client_data,
1986          XtPointer call_data )
1987 {
1988    Arg         args[2];
1989    Widget      parent;
1990    Position newX, newY;
1991
1992    parent = (Widget)client_data;
1993
1994    if (parent)
1995    {
1996       _DtChildPosition(w, parent, &newX, &newY);
1997       XtSetArg(args[0], XmNx, newX);
1998       XtSetArg(args[1], XmNy, newY);
1999       XtSetValues(w, args, 2);
2000    }
2001 }
2002
2003
2004 /************************************************************************
2005  *
2006  *  _DtBuildDialog
2007  *      This functions is used to build an instance of a dialog with
2008  *      the provided data but not display it.  The functions and data
2009  *      to be set back to the application upon change or close of the
2010  *      dialog is also provided as parameters.
2011  *
2012  ************************************************************************/
2013
2014 void
2015 _DtBuildDialog(
2016         Widget parent,
2017         Widget map_parent,
2018         XtPointer top_rec,
2019         DialogData *dialog_data,
2020         DialogChangedProc change_proc,
2021         XtPointer change_data,
2022         DialogClosedProc close_proc,
2023         XtPointer close_data,
2024         char *workspaces,
2025         Boolean iconify_state,
2026         Boolean ignoreCache,
2027         char * title,
2028         XClassHint * classHints )
2029
2030 {
2031    Dialog * dialog;
2032    int dialog_type, n;
2033    DialogInstanceData * instance_data;
2034    char geometry[40];
2035    Arg args[5];
2036    Boolean doCenter = False;
2037    Boolean doParentRelativePositioning = False;
2038    int availableDialogCount;
2039
2040
2041    /*  See if there is a cached, unused dialog of the correct type.  */
2042
2043    dialog_type = dialog_data->type;
2044    dialog = NULL;
2045
2046    if (!ignoreCache)
2047    {
2048       Dialog * availableDialog;
2049
2050       availableDialog = class_set[dialog_type].dialog_list;
2051       availableDialogCount = 0;
2052
2053       /*
2054        * In addition to looking for an available dialog in the cache to use,
2055        * we also want to count up the number of unused dialogs in the cache.
2056        * This lets us know it we need to restart the timer, to again build
2057        * up the cache.
2058        */
2059       while (availableDialog != NULL)
2060       {
2061          if (availableDialog->in_use == False)
2062          {
2063             if (dialog == NULL)
2064                dialog = availableDialog;
2065             else
2066                availableDialogCount++;
2067          }
2068          availableDialog = availableDialog->next;
2069       }
2070    }
2071
2072    if (dialog == NULL)
2073    {
2074       dialog = (Dialog *) XtMalloc (sizeof (Dialog));
2075
2076       (*(class_set[dialog_type].class->create))
2077          (XtDisplay (encap_parent_shell), encap_parent_shell,
2078          &(dialog->dialog_widget), &dialog->dialog);
2079
2080       /*  Add the change and close callbacks into the dialog  */
2081
2082       if (class_set[dialog_type].class->install_change_callback)
2083          (*(class_set[dialog_type].class->install_change_callback))
2084             (dialog->dialog, DataChangeCallback, (XtPointer)dialog);
2085
2086       if (class_set[dialog_type].class->install_close_callback)
2087          (*(class_set[dialog_type].class->install_close_callback))
2088             (dialog->dialog, DataCloseCallback, (XtPointer)dialog);
2089
2090       dialog->next = class_set[dialog_type].dialog_list;
2091       class_set[dialog_type].dialog_list = dialog;
2092    }
2093
2094    /*
2095     * Set pointer to top dialog data in child of the shell.
2096     * This is needed to get help to work.
2097     */
2098    if (top_rec == NULL)
2099       top_rec = dialog->dialog;
2100    XtSetArg(args[0], XmNuserData, top_rec);
2101    XtSetValues(dialog->dialog_widget, args, 1);
2102
2103    /*  Set the dialog structure fields to the parameter data.  */
2104
2105    dialog->in_use = True;
2106    dialog->dialog_data = dialog_data;
2107    dialog->change = change_proc;
2108    dialog->change_client_data = change_data;
2109    dialog->close = close_proc;
2110    dialog->close_client_data = close_data;
2111
2112    /* If a special title has been specified, we need to set it now */
2113    if (title)
2114    {
2115       XtSetArg(args[0], XmNtitle, title);
2116       XtSetValues(XtParent(dialog->dialog_widget), args, 1);
2117    }
2118 }
2119
2120
2121 /************************************************************************
2122  *
2123  *  _DtShowBuiltDialog
2124  *      This functions is used to display an instance of a dialog which
2125  *      has already been built with _DtBuildDialog.
2126  *
2127  ************************************************************************/
2128
2129 void
2130 _DtShowBuiltDialog(
2131         Widget parent,
2132         Widget map_parent,
2133         DialogData *dialog_data,
2134         char *workspaces,
2135         Boolean iconify_state,
2136         XClassHint * classHints )
2137
2138 {
2139    Dialog * dialog;
2140    int dialog_type, n;
2141    DialogInstanceData * instance_data;
2142    char geometry[40];
2143    Arg args[5];
2144    Boolean doCenter = False;
2145    Boolean doParentRelativePositioning = False;
2146    int availableDialogCount;
2147
2148
2149    dialog_type = dialog_data->type;
2150
2151    /*  Find the dialog */
2152    dialog = class_set[dialog_data->type].dialog_list;
2153    while (dialog != NULL)
2154    {
2155       if (dialog->dialog_data == dialog_data)
2156          break;
2157       else
2158          dialog = dialog->next;
2159    }
2160
2161    /* Need to add the map callback in relation to the parent */
2162    if (class_set[dialog_type].class->map)
2163    {
2164       /*
2165        * The map_parent parameter gives us the ability to position
2166        * the dialog relative to a window which is not the transientFor
2167        * parent.  This is used for the audio preview dialog.
2168        */
2169       if (map_parent == NULL)
2170          map_parent = parent;
2171
2172       (*(class_set[dialog_type].class->map)) (map_parent, dialog->dialog);
2173    }
2174
2175    instance_data = (DialogInstanceData *) dialog_data->data;
2176
2177    /*  If this is a top level shell, get it realized  */
2178    if (XtIsSubclass (XtParent (dialog->dialog_widget),
2179                      applicationShellWidgetClass))
2180    {
2181       if (XtIsRealized (XtParent (dialog->dialog_widget)) == False)
2182       {
2183          if (instance_data->displayed == True)
2184          {
2185             (void) sprintf (geometry, "=%dx%d+%d+%d",
2186                             instance_data->width, instance_data->height,
2187                             instance_data->x, instance_data->y);
2188
2189             XtSetArg (args[0], XmNgeometry, geometry);
2190             XtSetValues (XtParent (dialog->dialog_widget), args, 1);
2191          }
2192          else if ((instance_data->width != 0) && (instance_data->height != 0))
2193          {
2194             n=0;
2195             XtSetArg (args[n], XmNwidth, instance_data->width); n++;
2196             XtSetArg (args[n], XmNheight, instance_data->height); n++;
2197             XtSetValues (XtParent (dialog->dialog_widget), args, n);
2198          }
2199
2200          /* Toggle mappedWhenManaged to false */
2201          XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), False);
2202          XtRealizeWidget (XtParent(dialog->dialog_widget));
2203
2204          /* Set the proper workspaces if needed */
2205          _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
2206
2207          /* Set any application-specified class hints for the window */
2208          if (classHints)
2209          {
2210             XSetClassHint(XtDisplay(dialog->dialog_widget),
2211                           XtWindow(XtParent(dialog->dialog_widget)),
2212                           classHints);
2213          }
2214
2215          /* Set the iconify state */
2216          SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
2217
2218          /* Map the window */
2219          XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), True);
2220          XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
2221          XSync(XtDisplay(dialog->dialog_widget), False);
2222
2223       }
2224       else
2225       {
2226          if (instance_data->displayed == True)
2227          {
2228             WMShellWidget wm = (WMShellWidget)XtParent(dialog->dialog_widget);
2229
2230             wm->wm.size_hints.flags |= USPosition;
2231             XtSetArg (args[0], XmNx, instance_data->x);
2232             XtSetArg (args[1], XmNy, instance_data->y);
2233             XtSetArg (args[2], XmNwidth, instance_data->width);
2234             XtSetArg (args[3], XmNheight, instance_data->height);
2235             XtSetValues (XtParent (dialog->dialog_widget), args, 4);
2236          }
2237          else if ((instance_data->width != 0) && (instance_data->height != 0))
2238          {
2239             n=0;
2240             XtSetArg (args[n], XmNwidth, instance_data->width); n++;
2241             XtSetArg (args[n], XmNheight, instance_data->height); n++;
2242             XtSetValues (XtParent (dialog->dialog_widget), args, n);
2243          }
2244
2245          /* Set the proper workspaces if needed */
2246          _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
2247
2248          /* Set any application-specified class hints for the window */
2249          if (classHints)
2250          {
2251             XSetClassHint(XtDisplay(dialog->dialog_widget),
2252                           XtWindow(XtParent(dialog->dialog_widget)),
2253                           classHints);
2254          }
2255
2256          /* Set the iconify state */
2257          SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
2258
2259          /* Map the window */
2260          XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
2261       }
2262    }
2263    else
2264    {
2265       if (instance_data->displayed == True)
2266       {
2267          XtSetArg (args[0], XmNx, instance_data->x);
2268          XtSetArg (args[1], XmNy, instance_data->y);
2269          XtSetArg (args[2], XmNwidth, instance_data->width);
2270          XtSetArg (args[3], XmNheight, instance_data->height);
2271          XtSetArg (args[4], XmNdefaultPosition, False);
2272          XtSetValues (dialog->dialog_widget, args, 5);
2273          XtRealizeWidget (dialog->dialog_widget);
2274       }
2275       else
2276       {
2277          XtSetArg (args[0], XmNdefaultPosition, False);
2278          XtSetValues (dialog->dialog_widget, args, 1);
2279
2280          XtRealizeWidget (dialog->dialog_widget);
2281
2282          if (parent)
2283          {
2284             /* Position relative to the parent dialog */
2285             /*
2286              * Must be done after the set_values call, since the dialog
2287              * may get forced to a different size.
2288              */
2289             doParentRelativePositioning = True;
2290          }
2291          else
2292          {
2293             /* Center in the display */
2294             /*
2295              * Must be done after the set_values call, since the dialog
2296              * may get forced to a different size.
2297              */
2298             doCenter = True;
2299          }
2300       }
2301
2302       /*
2303        * Dialogs with no controlling parent window, need to have their
2304        * own workspace perperty set, if some workspaces have been requested.
2305        */
2306       if ((parent == NULL) && workspaces)
2307          _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
2308    }
2309
2310
2311    /*  Set Values onto the dialog to set it to the correct data.  */
2312
2313    (*(class_set[dialog_data->type].class->set_values))
2314       (dialog->dialog, dialog_data->data);
2315
2316    /*
2317     * These two adjustments MUST be done AFTER the dialog's SetValues()
2318     * procedure is called.  This is due to the fact that the setvalues
2319     * may cause the dialog size to change, and since both of the following
2320     * positioning algorithms are dependent upon the dialog size, we want
2321     * to make sure that the correct size is used.
2322     */
2323    if (doCenter)
2324    {
2325       XtSetArg (args[0], XmNx,
2326           (Dimension)(WidthOfScreen(XtScreen(dialog->dialog_widget)) -
2327            dialog->dialog_widget->core.width) / (Dimension)2);
2328       XtSetArg (args[1], XmNy,
2329           (Dimension)(HeightOfScreen(XtScreen(dialog->dialog_widget)) -
2330            dialog->dialog_widget->core.height) / (Dimension)2);
2331       XtSetValues (dialog->dialog_widget, args, 2);
2332    }
2333    else if (doParentRelativePositioning)
2334    {
2335       XtSetArg (args[0], XmNx,
2336           parent->core.x +
2337           (Dimension)(parent->core.width - dialog->dialog_widget->core.width) / (Dimension)2);
2338       XtSetArg (args[1], XmNy,
2339           parent->core.y +
2340           (Dimension)(parent->core.height - dialog->dialog_widget->core.height) / (Dimension)2);
2341       XtSetValues (XtParent(dialog->dialog_widget), args, 2);
2342    }
2343
2344
2345    /*  Fix up the transient-for windowing information so that  */
2346    /*  the window manager will shuffle and iconify as a group  */
2347
2348    if (parent != NULL)
2349    {
2350       if (XtIsRealized(parent))
2351       {
2352          XSetTransientForHint (XtDisplay (parent),
2353                             XtWindow (XtParent (dialog->dialog_widget)),
2354                             XtWindow (parent));
2355       }
2356    }
2357    else
2358    {
2359       if (!XtIsSubclass (XtParent (dialog->dialog_widget),
2360                                      applicationShellWidgetClass))
2361       {
2362          XSetTransientForHint (XtDisplay (encap_parent_shell),
2363                             XtWindow (XtParent (dialog->dialog_widget)),
2364                             XtWindow (encap_parent_shell));
2365       }
2366    }
2367
2368
2369    /*  Display the dialogs, application shells are displayed above.  */
2370
2371    if (!(XtIsSubclass (XtParent (dialog->dialog_widget),
2372                        applicationShellWidgetClass)))
2373    {
2374       XtManageChild (dialog->dialog_widget);
2375    }
2376
2377
2378    /*  Set the dialog instance data to indicate that the dialog  */
2379    /*  is displayed.                                             */
2380
2381    ((DialogInstanceData *) (dialog_data->data))->displayed = True;
2382
2383
2384    /* Give the dialog a chance to set its focus widget, if necessary */
2385
2386    if (class_set[dialog_data->type].class->set_focus)
2387    {
2388       (*(class_set[dialog_data->type].class->set_focus))
2389          (dialog->dialog, dialog_data->data);
2390    }
2391 }
2392
2393
2394
2395 static void
2396 DialogStructureNotifyHandler(
2397        Widget w,
2398        XtPointer client_data,
2399        XEvent *event )
2400 {
2401   if( event->type == MapNotify )
2402   {
2403     if( NumberOfDialogMapped == 0 )
2404     {
2405       int timeOut;
2406
2407       if( timerState == TIMER_STARTUP_STATE )
2408         timeOut = initialTimeoutLength;
2409       else if( timerState == TIMER_ACTIVE_STATE )
2410         timeOut = activeTimeoutLength;
2411       else if( timerState == TIMER_IDLE_STATE )
2412         timeOut = idleTimeoutLength;
2413       else
2414         timeOut = 0;
2415
2416       if( timeOut )
2417       {
2418         if( timerId )
2419           XtRemoveTimeOut( timerId );
2420
2421         timerId = XtAppAddTimeOut( XtWidgetToApplicationContext( w ),
2422                                    timeOut,
2423                                    (XtTimerCallbackProc)TimerEvent,
2424                                    (XtPointer)w );
2425       }
2426     }
2427     ++NumberOfDialogMapped;
2428   }
2429   else if( event->type == UnmapNotify )
2430   {
2431     if( NumberOfDialogMapped )
2432       --NumberOfDialogMapped;
2433
2434     if( NumberOfDialogMapped == 0 )
2435     {
2436       if( timerId )
2437       {
2438         XtRemoveTimeOut( timerId );
2439         timerId = 0;
2440       }
2441     }
2442   }
2443 }
2444
2445
2446 void
2447 _DtChangeTo(
2448          XtPointer client_data,
2449          char  *directory)
2450 {
2451    Dialog * dialog = (Dialog *) client_data;
2452
2453    ChangeDirectoryToParent(dialog->change_client_data, directory);
2454 }
2455
2456 void
2457 _DtFreeDialog(
2458          DialogData  *dialog_data)
2459 {
2460    Dialog *dialog,**headptr;
2461    headptr = &class_set[dialog_data->type].dialog_list;
2462    dialog = *headptr;
2463
2464    while (dialog != NULL)
2465    {
2466       if (dialog->dialog_data == dialog_data)
2467       {
2468         *headptr = dialog->next;
2469         XtFree((char *) dialog);
2470         break;
2471       }
2472       headptr = &(dialog->next);
2473       dialog = *headptr;
2474    }
2475 }
2476
2477 #ifdef USE_XINERAMA
2478 /*
2479  * Retrieve dimensions of the Xinerama screen the given widget resides on.
2480  * Returns True on success, False otherwise.
2481  */
2482 static Boolean GetXineramaScreenDimensions(
2483         Widget w, int *org_x, int *org_y, int *s_width, int *s_height)
2484 {
2485         DtXineramaInfo_t *dt_xi;
2486         unsigned int wx, wy;
2487         unsigned int i, sx, sy, sw, sh;
2488
2489         while (w && !XtIsShell(w))
2490             w=XtParent (w);
2491
2492         wx=XtX(w);
2493         wy=XtY(w);
2494
2495         if (!(dt_xi=_DtXineramaInit(XtDisplay(w)))) return False;
2496
2497         for (i=0; i<dt_xi->numscreens; i++){
2498                 if (!_DtXineramaGetScreen(dt_xi,i,&sw,&sh,&sx,&sy))
2499                     break;
2500
2501                 if (wx>=sx && wx<(sx+sw) && wy>=sy && wy<(sy+sh))
2502                 {
2503                         *s_width=(int)sw;
2504                         *s_height=(int)sh;
2505                         *org_x=(int)sx;
2506                         *org_y=(int)sy;
2507                         free(dt_xi);
2508                         return True;
2509                 }
2510         }
2511
2512         free(dt_xi);
2513         return False;
2514 }
2515 #endif /* USE_XINERAMA */