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