2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: Encaps.c /main/10 1996/10/30 11:10:16 drk $ */
24 /************************************<+>*************************************
25 ****************************************************************************
29 * COMPONENT_NAME: Desktop File Manager (dtfile)
31 * Description: Source file for the dialog encapsulation functions.
33 * FUNCTIONS: DataChangeCallback
35 * DialogStructureNotifyHandler
36 * IntDialogGetResources
37 * IntDialogPutResources
43 * _DtDialogGetResources
44 * _DtDialogPutResources
45 * _DtDimensionToString
46 * _DtEncapSetWorkSpaceHints
48 * _DtGetDefaultDialogData
50 * _DtGetDialogInstance
53 * _DtGetResourceDialogData
55 * _DtInitializeEncapsulation
65 * _DtXmStringTableToString
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.
75 ****************************************************************************
76 ************************************<+>*************************************/
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>
94 #include <Dt/DtNlUtils.h>
103 #include <DtXinerama.h>
106 #define MAX_NAME_LIST_SIZE 25
107 #define MAX_RESOURCE_LENGTH 256
110 /* Cache array handling defines, structure, and global statics */
112 #define INCREMENT_SIZE 10
115 typedef struct _Dialog
118 Widget dialog_widget;
120 DialogData * dialog_data;
121 DialogChangedProc change;
122 XtPointer change_client_data;
123 DialogClosedProc close;
124 XtPointer close_client_data;
125 struct _Dialog * next;
132 Dialog * dialog_list;
134 Boolean destroyPopups;
137 extern int filter_dialog,mod_attr_dialog;
139 static ClassSet * class_set = NULL;
140 static int class_set_size = 0;
141 static int num_classes = 0;
142 static int NumberOfDialogMapped = 0;
144 static char * resourceBuf = NULL;
145 static int commonResourceCount = 5;
146 static DialogResource commonResources[] =
148 { "displayed", XmRBoolean, sizeof(Boolean),
149 XtOffset(DialogInstanceDataPtr, displayed),
150 (caddr_t) False, _DtBooleanToString },
152 { "x", XmRPosition, sizeof(Position),
153 XtOffset(DialogInstanceDataPtr, x),
154 (caddr_t) 0, _DtPositionToString},
156 { "y", XmRPosition, sizeof(Position),
157 XtOffset(DialogInstanceDataPtr, y),
158 (caddr_t) 0, _DtPositionToString },
160 { "width", XmRHorizontalDimension, sizeof(Dimension),
161 XtOffset(DialogInstanceDataPtr, width),
162 (caddr_t) 0, _DtDimensionToString },
164 { "height", XmRVerticalDimension, sizeof(Dimension),
165 XtOffset(DialogInstanceDataPtr, height),
166 (caddr_t) 0, _DtDimensionToString },
169 static Widget encap_parent_shell;
171 extern int file_mgr_dialog;
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.
182 int initialTimeoutLength = 180000; /* 3 minutes, in milliseconds */
183 int activeTimeoutLength = 30000; /* 30 seconds, in milliseconds */
184 int idleTimeoutLength = 900000; /* 15 minutes, in milliseconds */
186 #define TIMER_STARTUP_STATE 0
187 #define TIMER_ACTIVE_STATE 1
188 #define TIMER_IDLE_STATE 2
190 static int timerState = TIMER_STARTUP_STATE;
191 static XtIntervalId timerId = 0;
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.
201 int topPositionOffset = 20;
204 /******** Static Function Declarations ********/
206 static void DialogStructureNotifyHandler(
208 XtPointer client_data,
210 static void SetIconifyState(
213 static void DataChangeCallback(
215 XtPointer client_data,
216 XtPointer call_data) ;
217 static void DataCloseCallback(
219 XtPointer client_data,
220 XtPointer call_data) ;
221 static void TimerEvent(
224 static void IntDialogGetResources(
225 XrmDatabase database,
227 DialogResource *resource,
230 XrmQuark stringQuark) ;
231 static void IntDialogPutResources(
236 DialogResource *resource) ;
238 static Boolean GetXineramaScreenDimensions(
239 Widget w,int *xorg, int *yorg, int *width,int *height);
240 #endif /* USE_XINERAMA */
242 /******** End Static Function Declarations ********/
246 /************************************************************************
248 * _DtInitializeEncapsulation
249 * This function is used to initialize the dialog encapsulation.
251 ************************************************************************/
254 _DtInitializeEncapsulation(
262 /* Create an application shell that will never be */
263 /* displayed that is used as a parent of all of the */
264 /* dialog created. */
266 encap_parent_shell = XtAppCreateShell (name, class,
267 applicationShellWidgetClass,
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);
277 /* Get a timer going that is used for auto creation of dialogs. */
279 timerState = TIMER_STARTUP_STATE;
280 timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(encap_parent_shell),
281 initialTimeoutLength, (XtTimerCallbackProc)
282 TimerEvent, (caddr_t) encap_parent_shell);
284 /* Allocate a buffer for writing out resource values */
285 resourceBuf = XtMalloc(20);
291 /************************************************************************
294 * This function is used to register a dialog class with the
295 * encapsulation functions.
297 ************************************************************************/
301 DialogClass *dialog_class,
303 Boolean destroyPopups )
306 /* Allocate additional dialog cache space if needed */
308 if (num_classes == class_set_size)
310 class_set_size += INCREMENT_SIZE;
312 (ClassSet *) XtRealloc ((char *)class_set,
313 sizeof (ClassSet) * class_set_size);
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;
323 return (num_classes - 1);
329 /************************************************************************
332 * This function is used to get a structure containing the
333 * current dialog data for a particular dialog instance.
335 ************************************************************************/
339 DialogData *dialog_data )
343 DialogData * new_data;
345 dialog = class_set[dialog_data->type].dialog_list;
347 while (dialog != NULL)
349 if (dialog->dialog_data == dialog_data)
351 new_data = (DialogData *) XtMalloc (sizeof (DialogData));
353 new_data->type = dialog->dialog_data->type;
354 new_data->data = NULL;
355 if (class_set[new_data->type].class->get_values)
358 (*(class_set[new_data->type].class->get_values)) (dialog->dialog);
364 dialog = dialog->next;
373 /************************************************************************
375 * _DtGetDefaultDialogData
376 * This function is used to get a structure containing the
377 * default data for a particular dialog type.
379 ************************************************************************/
382 _DtGetDefaultDialogData(
387 DialogData * dialog_data;
389 dialog_data = (DialogData *) XtMalloc (sizeof (DialogData));
391 dialog_data->type = dialog_type;
392 dialog_data->data = (*(class_set[dialog_type].class->get_default_values))();
394 return (dialog_data);
400 /************************************************************************
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.
406 ************************************************************************/
409 _DtGetResourceDialogData(
411 XrmDatabase data_base,
415 DialogData * dialog_data;
417 dialog_data = (DialogData *) XtMalloc (sizeof (DialogData));
419 dialog_data->type = dialog_type;
420 dialog_data->data = (*(class_set[dialog_type].class->get_resource_values))
421 (data_base, name_list);
423 return (dialog_data);
429 /************************************************************************
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.
437 ************************************************************************/
443 DialogData *dialog_data,
444 DialogChangedProc change_proc,
445 XtPointer change_data,
446 DialogClosedProc close_proc,
447 XtPointer close_data,
449 Boolean iconify_state,
452 XClassHint * classHints )
457 DialogInstanceData * instance_data;
460 Boolean doCenter = False;
461 Boolean doParentRelativePositioning = False;
462 int availableDialogCount;
465 /* See if there is a cached, unused dialog of the correct type. */
467 dialog_type = dialog_data->type;
472 Dialog * availableDialog;
474 availableDialog = class_set[dialog_type].dialog_list;
475 availableDialogCount = 0;
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
483 while (availableDialog != NULL)
485 if (availableDialog->in_use == False)
488 dialog = availableDialog;
490 availableDialogCount++;
492 availableDialog = availableDialog->next;
498 dialog = (Dialog *) XtMalloc (sizeof (Dialog));
500 (*(class_set[dialog_type].class->create))
501 (XtDisplay (encap_parent_shell), encap_parent_shell,
502 &(dialog->dialog_widget), &dialog->dialog);
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.
509 if(dialog_type == file_mgr_dialog)
510 UpdateHeaders(dialog->dialog, dialog_data->data, False);
512 /* Add the change and close callbacks into the dialog */
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);
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);
522 dialog->next = class_set[dialog_type].dialog_list;
523 class_set[dialog_type].dialog_list = dialog;
527 if(dialog_type == mod_attr_dialog)
529 ModAttrRec *mr = (ModAttrRec *)dialog->dialog;
530 ResetFlag(NULL,mr->ok);
531 ResetFlag(NULL,mr->cancel);
533 else if(dialog_type == filter_dialog)
535 FilterRec *fr = (FilterRec *)dialog->dialog;
536 ResetFlag(NULL,fr->ok);
537 ResetFlag(NULL,fr->close);
541 if ((!ignoreCache) && (class_set[dialog_type].cache) &&
542 (availableDialogCount < 1) && (timerState == TIMER_IDLE_STATE))
545 * We need to reset the cache building timer, so that it gets kicked
546 * off quickly, instead of after the longer idle delay.
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);
558 * Set pointer to top dialog data in child of the shell.
559 * This is needed to get help to work.
562 top_rec = dialog->dialog;
563 XtSetArg(args[0], XmNuserData, top_rec);
564 XtSetValues(dialog->dialog_widget, args, 1);
566 /* Need to add the map callback in relation to the parent */
567 if (class_set[dialog_type].class->map)
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.
574 if (map_parent == NULL)
577 (*(class_set[dialog_type].class->map)) (map_parent, dialog->dialog);
581 /* Set the dialog structure fields to the parameter data. */
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;
591 instance_data = (DialogInstanceData *) dialog_data->data;
593 /* If a special title has been specified, we need to set it now */
596 XtSetArg(args[0], XmNtitle, title);
597 XtSetValues(XtParent(dialog->dialog_widget), args, 1);
600 /* If this is a top level shell, get it realized */
602 if (XtIsSubclass (XtParent (dialog->dialog_widget),
603 applicationShellWidgetClass))
605 if (XtIsRealized (XtParent (dialog->dialog_widget)) == False)
607 if (instance_data->displayed == True)
609 (void) sprintf (geometry, "=%dx%d+%d+%d",
610 instance_data->width, instance_data->height,
611 instance_data->x, instance_data->y);
613 XtSetArg (args[0], XmNgeometry, geometry);
614 XtSetValues (XtParent (dialog->dialog_widget), args, 1);
616 else if ((instance_data->width != 0) && (instance_data->height != 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);
624 /* Toggle mappedWhenManaged to false */
625 XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), False);
626 XtRealizeWidget (XtParent(dialog->dialog_widget));
628 /* Set the proper workspaces if needed */
629 _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
631 /* Set any application-specified class hints for the window */
634 XSetClassHint(XtDisplay(dialog->dialog_widget),
635 XtWindow(XtParent(dialog->dialog_widget)),
639 /* Set the iconify state */
640 SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
643 XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), True);
644 XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
645 XSync(XtDisplay(dialog->dialog_widget), False);
650 if (instance_data->displayed == True)
652 WMShellWidget wm = (WMShellWidget)XtParent(dialog->dialog_widget);
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);
661 else if ((instance_data->width != 0) && (instance_data->height != 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);
669 /* Set the proper workspaces if needed */
670 _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
672 /* Set any application-specified class hints for the window */
675 XSetClassHint(XtDisplay(dialog->dialog_widget),
676 XtWindow(XtParent(dialog->dialog_widget)),
680 /* Set the iconify state */
681 SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
684 XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
689 if (instance_data->displayed == True)
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);
701 XtSetArg (args[0], XmNdefaultPosition, False);
702 XtSetValues (dialog->dialog_widget, args, 1);
704 XtRealizeWidget (dialog->dialog_widget);
708 /* Position relative to the parent dialog */
710 * Must be done after the set_values call, since the dialog
711 * may get forced to a different size.
713 doParentRelativePositioning = True;
717 /* Center in the display */
719 * Must be done after the set_values call, since the dialog
720 * may get forced to a different size.
727 * Dialogs with no controlling parent window, need to have their
728 * own workspace perperty set, if some workspaces have been requested.
730 if ((parent == NULL) && workspaces)
731 _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
735 /* Set Values onto the dialog to set it to the correct data. */
737 (*(class_set[dialog_data->type].class->set_values))
738 (dialog->dialog, dialog_data->data);
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.
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);
757 else if (doParentRelativePositioning)
759 XtSetArg (args[0], XmNx,
761 (Dimension)(parent->core.width - dialog->dialog_widget->core.width) / (Dimension)2);
762 XtSetArg (args[1], XmNy,
764 (Dimension)(parent->core.height - dialog->dialog_widget->core.height) / (Dimension)2);
765 XtSetValues (XtParent(dialog->dialog_widget), args, 2);
769 /* Fix up the transient-for windowing information so that */
770 /* the window manager will shuffle and iconify as a group */
774 if (XtIsRealized(parent))
776 XSetTransientForHint (XtDisplay (parent),
777 XtWindow (XtParent (dialog->dialog_widget)),
783 if (!XtIsSubclass (XtParent (dialog->dialog_widget),
784 applicationShellWidgetClass))
786 XSetTransientForHint (XtDisplay (encap_parent_shell),
787 XtWindow (XtParent (dialog->dialog_widget)),
788 XtWindow (encap_parent_shell));
793 /* Display the dialogs, application shells are displayed above. */
795 if (!(XtIsSubclass (XtParent (dialog->dialog_widget),
796 applicationShellWidgetClass)))
798 XtManageChild (dialog->dialog_widget);
802 /* Set the dialog instance data to indicate that the dialog */
805 ((DialogInstanceData *) (dialog_data->data))->displayed = True;
808 /* Give the dialog a chance to set its focus widget, if necessary */
810 if (class_set[dialog_data->type].class->set_focus)
812 (*(class_set[dialog_data->type].class->set_focus))
813 (dialog->dialog, dialog_data->data);
818 XtAddEventHandler( XtParent( dialog->dialog_widget ),
821 (XtEventHandler)DialogStructureNotifyHandler,
828 /************************************************************************
831 * This function is used to undisplay a dialog.
833 ************************************************************************/
837 DialogData *dialog_data,
838 Boolean call_callbacks )
842 DialogData * new_data;
847 /* Find the dialog and then hide it. */
849 dialog = class_set[dialog_data->type].dialog_list;
851 while (dialog != NULL)
853 if ((dialog->dialog_data &&
854 dialog->dialog_data == dialog_data) && dialog->in_use == True)
858 /* Free up any dialogs attached to the dialog widget */
860 if(class_set[dialog_data->type].destroyPopups)
862 core = (CorePart *) (XtParent (dialog->dialog_widget));
864 for (i = core->num_popups - 1; i >= 0; i--)
865 XtDestroyWidget (core->popup_list[i]);
869 /* Get the dialog down, invoke the close callbacks, and */
870 /* take it out of use. */
872 if (XtIsSubclass (XtParent (dialog->dialog_widget),
873 applicationShellWidgetClass))
875 ShellWidget shell_widget;
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.
887 shell_widget = (ShellWidget) XtParent(dialog->dialog_widget);
888 shell_widget->shell.popped_up = True;
890 XtPopdown ((Widget)shell_widget);
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.
905 dialog->dialog_widget->core.managed = True;
906 XtUnmanageChild (dialog->dialog_widget);
910 /* Set the dialog data to hidden */
912 ((DialogInstanceData *) (dialog->dialog_data->data))->displayed = False;
915 if (call_callbacks && dialog->close)
917 new_data = (DialogData *) XtMalloc (sizeof (DialogData));
919 new_data->type = dialog->dialog_data->type;
920 new_data->data = NULL;
921 if (class_set[new_data->type].class->get_values)
924 (*(class_set[new_data->type].class->get_values))(dialog->dialog);
927 dialog->in_use = False;
929 ((DialogInstanceData *) (new_data->data))->displayed = False;
932 (dialog->close_client_data, dialog->dialog_data, new_data);
936 dialog->in_use = False;
937 ((DialogInstanceData *) (dialog->dialog_data->data))->displayed = False;
943 dialog = dialog->next;
950 /************************************************************************
953 * This function is used return the shell widget of a dialog that
954 * is currently displayed.
956 ************************************************************************/
960 DialogData *dialog_data )
966 /* Find the dialog and then return the shell. */
968 dialog = class_set[dialog_data->type].dialog_list;
970 while (dialog != NULL)
972 if (dialog->dialog_data == dialog_data)
973 return (dialog->dialog_widget);
975 dialog = dialog->next;
984 /************************************************************************
986 * _DtGetDialogInstance
987 * This function is used return the dialog instance structure
988 * of a currently in use dialog.
990 ************************************************************************/
993 _DtGetDialogInstance(
994 DialogData *dialog_data )
1000 /* Find the dialog and then return the instance */
1002 dialog = class_set[dialog_data->type].dialog_list;
1004 while (dialog != NULL)
1006 if (dialog->dialog_data && dialog->dialog_data == dialog_data)
1007 return (dialog->dialog);
1009 dialog = dialog->next;
1018 /************************************************************************
1020 * _DtGetInstanceData
1021 * This function is used return the dialog data structure contained
1022 * within the cache structure referenced by instance.
1024 ************************************************************************/
1028 XtPointer instance )
1035 /* Find the dialog and then return the instance */
1037 for (i = 0; i < num_classes; i++)
1039 dialog = class_set[i].dialog_list;
1041 while (dialog != NULL)
1043 if (dialog->dialog == instance && dialog->in_use == True)
1044 return (dialog->dialog_data);
1046 dialog = dialog->next;
1056 /************************************************************************
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.
1063 ************************************************************************/
1067 DialogData *dialog_data )
1073 /* Find the dialog and then return the instance */
1075 dialog = class_set[dialog_data->type].dialog_list;
1077 while (dialog != NULL)
1079 if (dialog->in_use && dialog->dialog_data == dialog_data)
1082 dialog = dialog->next;
1091 /************************************************************************
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.
1097 ************************************************************************/
1101 DialogData *dialog_data,
1106 if (dialog_data != NULL)
1107 (*(class_set[dialog_data->type].class->write_resource_values))
1108 (dialog_data, fd, name_list);
1114 /************************************************************************
1117 * This function is used to free up the data space allocated
1120 ************************************************************************/
1124 DialogData *dialog_data )
1127 if (dialog_data != NULL)
1129 (*(class_set[dialog_data->type].class->free_values)) (dialog_data->data);
1130 XtFree ((char *) dialog_data);
1138 /************************************************************************
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.
1146 ************************************************************************/
1149 _DtDialogGetResources(
1150 XrmDatabase database,
1154 DialogResource *resources,
1155 int resource_count )
1158 XrmName xrmName[MAX_NAME_LIST_SIZE];
1159 XrmQuark stringQuark;
1163 /* Build the quarkified name list from name_list and dialog_name */
1164 /* provided by the calling procedure. */
1167 if (name_list != NULL)
1169 while (name_list[nameCount] != NULL)
1171 xrmName[nameCount] = XrmStringToQuark (name_list[nameCount]);
1177 xrmName[nameCount] = XrmStringToQuark (dialog_name);
1181 xrmName[nameCount + 2] = 0;
1182 stringQuark = XrmStringToQuark (XmRString);
1185 /* Load the common dialog size/position resources */
1186 for (i = 0; i < resource_count; i++)
1188 IntDialogGetResources(database, base, resources + i, xrmName, nameCount,
1193 * Load the dialog specific resources. If no value found, use the default.
1195 for (i = 0; i < commonResourceCount; i++)
1197 IntDialogGetResources(database, base, commonResources + i, xrmName,
1198 nameCount, stringQuark);
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.
1210 IntDialogGetResources(
1211 XrmDatabase database,
1213 DialogResource *resource,
1216 XrmQuark stringQuark )
1219 XrmRepresentation repType;
1221 XrmValue convertedValue;
1228 xrmName[nameCount + 1] = XrmStringToQuark (resource->name);
1230 if (XrmQGetResource (database, xrmName, xrmName, &repType, &value))
1232 if (repType == stringQuark)
1233 if (strcmp (resource->type, XmRString) != 0)
1235 XtConvert (encap_parent_shell, XmRString, &value,
1236 resource->type, &convertedValue);
1240 *((char **)(base + resource->offset)) = (char *)value.addr;
1244 convertedValue.addr = NULL;
1248 convertedValue.addr = NULL;
1251 /* Set the converted value address pointer and value to */
1252 /* the proper default value if the addr is NULL. */
1254 if (convertedValue.addr == NULL)
1256 if (resource->size == sizeof(char))
1258 charVal = (char)(XtArgVal)resource->default_value;
1259 convertedValue.addr = (caddr_t) &charVal;
1261 else if (resource->size == sizeof(short))
1263 shortVal = (short)(XtArgVal)resource->default_value;
1264 convertedValue.addr = (caddr_t) &shortVal;
1266 else if (resource->size == sizeof(int))
1268 intVal = (int)(XtArgVal)resource->default_value;
1269 convertedValue.addr = (caddr_t) &intVal;
1273 longVal = (long)(XtArgVal)resource->default_value;
1274 convertedValue.addr = (caddr_t) &longVal;
1279 /* Stuff the converted value into the calling functions */
1280 /* structure according to the size of the piece of data. */
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);
1289 *((long *)(base + resource->offset)) = *((long *)convertedValue.addr);
1295 /************************************************************************
1297 * _DtDialogPutResources
1298 * This function writes a resource set to a file.
1300 ************************************************************************/
1303 _DtDialogPutResources(
1308 DialogResource *resources,
1313 DialogInstanceData * dialogInstanceData;
1316 * Write out the common dialog size/position resources, only if the
1317 * dialog is currently displayed.
1319 dialogInstanceData = (DialogInstanceData *)base;
1320 if (dialogInstanceData->displayed)
1322 for (i = 0; i < commonResourceCount; i++)
1324 IntDialogPutResources(fd, nameList, dialogName, base,
1325 commonResources + i);
1330 * Loop through the dialog specific resources, write the name list and
1333 for (i = 0; i < resourceCount; i++)
1334 IntDialogPutResources( fd, nameList, dialogName, base, resources + i);
1339 * This internal function does the real work involved in writing a single
1340 * resource out to a session file.
1344 IntDialogPutResources(
1349 DialogResource *resource )
1352 static char outBuf[MAX_RESOURCE_LENGTH];
1357 (void) strcat (outBuf, "*");
1360 if (nameList != NULL)
1362 while (nameList[nameCount] != NULL)
1364 (void) strcat (outBuf, nameList[nameCount]);
1365 (void) strcat (outBuf, ".");
1370 if (dialogName != NULL)
1372 (void) strcat (outBuf, dialogName);
1373 (void) strcat (outBuf, ".");
1376 (void) strcat (outBuf, resource->name);
1377 (void) strcat (outBuf, ": ");
1379 (*(resource->write_resource))
1380 (fd, (XtPointer) (base + resource->offset), outBuf);
1385 /************************************************************************
1386 ************************************************************************
1388 * Internal functions
1390 ************************************************************************
1391 ************************************************************************/
1394 /************************************************************************
1396 * _DtEncapSetWorkSpaceHints
1397 * This function sets a given shell to a given set(s) of
1400 ************************************************************************/
1402 _DtEncapSetWorkSpaceHints(
1408 Atom * workspace_atoms = NULL;
1409 int num_workspaces=0;
1415 ptr = DtStrchr (workspaces, '*');
1417 if (ptr != NULL) *ptr = '\0';
1419 workspace_atoms = (Atom *) XtRealloc ((char *)workspace_atoms,
1420 sizeof (Atom) * (num_workspaces + 1));
1422 workspace_atoms[num_workspaces] =
1423 XmInternAtom (XtDisplay(shell), workspaces, True);
1430 workspaces = ptr + 1;
1432 } while (ptr != NULL);
1434 DtWsmSetWorkspacesOccupied (XtDisplay(shell), XtWindow (shell), workspace_atoms,
1437 XtFree ((char *) workspace_atoms);
1438 workspace_atoms = NULL;
1444 Screen *currentScreen;
1446 char *workspace_name;
1449 * Since no specific workspaces were specified, we will force the
1450 * dialog to the current workspace.
1452 screen = XDefaultScreen(XtDisplay(shell));
1453 currentScreen = XScreenOfDisplay(XtDisplay(shell), screen);
1454 rootWindow = RootWindowOfScreen(currentScreen);
1456 if(DtWsmGetCurrentWorkspace(XtDisplay(shell), rootWindow, &pCurrent) ==
1459 DtWsmSetWorkspacesOccupied(XtDisplay(shell), XtWindow (shell), &pCurrent, 1);
1464 /************************************************************************
1467 * This function sets a given shell to a given iconify state.
1468 * (e.g. Mapped or iconified)
1470 ************************************************************************/
1482 /* add the iconify hint to the current shell */
1483 XtSetArg(args[0], XmNinitialState, IconicState);
1484 XtSetValues(shell, args, 1);
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);
1497 /************************************************************************
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
1504 ************************************************************************/
1510 XtPointer client_data,
1511 XtPointer call_data )
1514 Dialog * dialog = (Dialog *) client_data;
1515 DialogData * new_data;
1517 new_data = (DialogData *) XtMalloc (sizeof (DialogData));
1519 new_data->type = dialog->dialog_data->type;
1520 new_data->data = NULL;
1521 if (class_set[new_data->type].class->get_values)
1523 new_data->data = (*(class_set[new_data->type].class->get_values))
1529 (dialog->change_client_data, dialog->dialog_data, new_data, call_data);
1535 /************************************************************************
1538 * This callback is invoked from a dialog upon an action on the
1539 * dialog that means the dialog has been closed.
1541 ************************************************************************/
1547 XtPointer client_data,
1548 XtPointer call_data )
1552 Dialog * dialog = (Dialog *) client_data;
1554 if(RecheckFlag(NULL,widget)) /* cancel flag already set, just return */
1556 _DtHideDialog (dialog->dialog_data, True);
1562 /************************************************************************
1565 * This action function is called upon the encapsulations
1566 * timeout going off. Its function is to precreate and destroy
1569 ************************************************************************/
1580 Dialog * prev_dialog;
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. */
1588 for (i = 0; i < num_classes; i++)
1590 dialog = class_set[i].dialog_list;
1592 /* Only attempt to cache dialogs requesting this feature */
1593 if (!class_set[i].cache)
1596 while (dialog != NULL)
1597 if (dialog->in_use == False)
1600 dialog = dialog->next;
1604 dialog = (Dialog *) XtMalloc (sizeof (Dialog));
1606 (*(class_set[i].class->create))
1607 (XtDisplay (encap_parent_shell), encap_parent_shell,
1608 &(dialog->dialog_widget), &dialog->dialog);
1611 /* Add the change and close callbacks into the dialog */
1613 if (class_set[i].class->install_change_callback)
1614 (*(class_set[i].class->install_change_callback))
1615 (dialog->dialog, DataChangeCallback, (XtPointer)dialog);
1617 if (class_set[i].class->install_close_callback)
1618 (*(class_set[i].class->install_close_callback))
1619 (dialog->dialog, DataCloseCallback, (XtPointer)dialog);
1622 dialog->next = class_set[i].dialog_list;
1623 class_set[i].dialog_list = dialog;
1625 dialog->in_use = False;
1627 timerState = TIMER_ACTIVE_STATE;
1628 timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(widget),
1629 activeTimeoutLength,
1630 (XtTimerCallbackProc) TimerEvent,
1631 (XtPointer) widget);
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. */
1641 for (i = 0; i < num_classes; i++)
1643 dialog = class_set[i].dialog_list;
1646 while (dialog != NULL)
1648 if (dialog->in_use == False)
1651 dialog = dialog->next;
1656 dialog = class_set[i].dialog_list;
1658 if (dialog->in_use == False)
1659 class_set[i].dialog_list = dialog->next;
1662 prev_dialog = class_set[i].dialog_list;
1663 dialog = dialog->next;
1665 while (dialog->in_use == True)
1667 prev_dialog = dialog;
1668 dialog = dialog->next;
1671 prev_dialog->next = dialog->next;
1674 (*(class_set[i].class->destroy)) (dialog->dialog);
1675 XtFree ((char *) dialog);
1682 timerState = TIMER_IDLE_STATE;
1683 timerId = XtAppAddTimeOut(XtWidgetToApplicationContext(widget),
1685 (XtTimerCallbackProc)TimerEvent,
1692 /************************************************************************
1693 ************************************************************************
1695 * Externed Type to String Converters and writers
1697 ************************************************************************
1698 ************************************************************************/
1707 (void) sprintf (resourceBuf, "%d", *value);
1708 _DtStringToString( fd, &resourceBuf, out_buf );
1720 (void) sprintf (resourceBuf, "%d", *value);
1721 _DtStringToString( fd, &resourceBuf, out_buf );
1727 _DtPositionToString(
1733 (void) sprintf (resourceBuf, "%d", *value);
1734 _DtStringToString( fd, &resourceBuf, out_buf );
1740 _DtDimensionToString(
1746 (void) sprintf (resourceBuf, "%d", *value);
1747 _DtStringToString( fd, &resourceBuf, out_buf );
1765 _DtStringToString( fd, (char **)&buf, out_buf );
1770 _DtXmStringToString(
1776 char *out_value = NULL;
1780 out_value = (char *) _XmStringUngenerate(*value, XmFONTLIST_DEFAULT_TAG,
1781 XmCHARSET_TEXT, XmCHARSET_TEXT);
1782 if ( out_value != NULL)
1784 if (strlen (out_value) != 0)
1786 (void) write (fd, out_value, strlen (out_value));
1787 _DtStringToString( fd, &out_value, out_buf );
1789 XtFree ((char *) out_value);
1797 _DtXmStringTableToString(
1799 XmStringTable *value,
1804 char *out_value = NULL;
1805 Boolean first = True;
1807 if ((value != NULL) && (*value != NULL))
1810 while ((*value)[i] != NULL)
1812 out_value = (char *)_XmStringUngenerate((*value)[i],
1813 XmFONTLIST_DEFAULT_TAG,
1814 XmCHARSET_TEXT, XmCHARSET_TEXT);
1815 if ( out_value != NULL)
1819 (void) write (fd, out_buf, strlen (out_buf));
1823 (void) write (fd, ", ", strlen (", "));
1825 (void) write (fd, out_value, strlen (out_value));
1827 XtFree ((char *) out_value);
1835 (void) write (fd, "\n", strlen ("\n"));
1847 if (*value == NULL || strlen (*value) == 0)
1851 (void) write (fd, out_buf, strlen (out_buf));
1852 (void) write (fd, *value, strlen (*value));
1853 (void) write (fd, "\n", strlen ("\n"));
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.
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;
1881 int xOrg=0, yOrg=0; /* Xinerama screen origin */
1883 /* get x, y offsets for the parent's window frame */
1884 extData = _XmGetWidgetExtData(parent, XmSHELL_EXTENSION);
1887 vendorExt = (XmVendorShellExtObject)extData->widget;
1888 xOffset = vendorExt->vendor.xOffset;
1889 yOffset = vendorExt->vendor.yOffset;
1892 xOffset = yOffset = 0;
1895 if(!GetXineramaScreenDimensions(parent,&xOrg,&yOrg,&sWidth,&sHeight)){
1896 sHeight = HeightOfScreen(XtScreen(parent));
1897 sWidth = WidthOfScreen(XtScreen(parent));
1900 /* get size/position of screen, parent, and widget */
1901 sHeight = HeightOfScreen(XtScreen(parent));
1902 sWidth = WidthOfScreen(XtScreen(parent));
1903 #endif /* USE_XINERAMA */
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;
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.
1918 space = sWidth - (pX + pWidth + myWidth);
1920 if (sHeight - (pY + pHeight + myHeight) > space)
1923 space = sHeight - (pY + pHeight + myHeight);
1926 if (pX - myWidth > space)
1929 space = pX - myWidth;
1932 if (pY - myHeight > space)
1935 space = pY - myHeight;
1938 /* Given relative positioning, determine x, y coordinates for the child */
1943 *newX = pX + pWidth + 5;
1944 *newY = pY + (pHeight - myHeight)/2;
1948 *newX = pX + (pWidth - myWidth)/2;
1949 *newY = pY + pHeight + 5;
1953 *newX = pX - myWidth - 5;
1954 *newY = pY + (pHeight - myHeight)/2;
1958 *newX = pX + (pWidth - myWidth)/2;
1959 *newY = pY - myHeight - 5;
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
1971 if ((*newX >= (sWidth - 10)) || (*newX < 0))
1972 *newX = sWidth - myWidth + 5;
1973 if ((*newY >= (sHeight - 10)) || (*newY < 0))
1974 *newY = (sHeight - myHeight) / 2;
1985 XtPointer client_data,
1986 XtPointer call_data )
1990 Position newX, newY;
1992 parent = (Widget)client_data;
1996 _DtChildPosition(w, parent, &newX, &newY);
1997 XtSetArg(args[0], XmNx, newX);
1998 XtSetArg(args[1], XmNy, newY);
1999 XtSetValues(w, args, 2);
2004 /************************************************************************
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.
2012 ************************************************************************/
2019 DialogData *dialog_data,
2020 DialogChangedProc change_proc,
2021 XtPointer change_data,
2022 DialogClosedProc close_proc,
2023 XtPointer close_data,
2025 Boolean iconify_state,
2026 Boolean ignoreCache,
2028 XClassHint * classHints )
2033 DialogInstanceData * instance_data;
2036 Boolean doCenter = False;
2037 Boolean doParentRelativePositioning = False;
2038 int availableDialogCount;
2041 /* See if there is a cached, unused dialog of the correct type. */
2043 dialog_type = dialog_data->type;
2048 Dialog * availableDialog;
2050 availableDialog = class_set[dialog_type].dialog_list;
2051 availableDialogCount = 0;
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
2059 while (availableDialog != NULL)
2061 if (availableDialog->in_use == False)
2064 dialog = availableDialog;
2066 availableDialogCount++;
2068 availableDialog = availableDialog->next;
2074 dialog = (Dialog *) XtMalloc (sizeof (Dialog));
2076 (*(class_set[dialog_type].class->create))
2077 (XtDisplay (encap_parent_shell), encap_parent_shell,
2078 &(dialog->dialog_widget), &dialog->dialog);
2080 /* Add the change and close callbacks into the dialog */
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);
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);
2090 dialog->next = class_set[dialog_type].dialog_list;
2091 class_set[dialog_type].dialog_list = dialog;
2095 * Set pointer to top dialog data in child of the shell.
2096 * This is needed to get help to work.
2098 if (top_rec == NULL)
2099 top_rec = dialog->dialog;
2100 XtSetArg(args[0], XmNuserData, top_rec);
2101 XtSetValues(dialog->dialog_widget, args, 1);
2103 /* Set the dialog structure fields to the parameter data. */
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;
2112 /* If a special title has been specified, we need to set it now */
2115 XtSetArg(args[0], XmNtitle, title);
2116 XtSetValues(XtParent(dialog->dialog_widget), args, 1);
2121 /************************************************************************
2123 * _DtShowBuiltDialog
2124 * This functions is used to display an instance of a dialog which
2125 * has already been built with _DtBuildDialog.
2127 ************************************************************************/
2133 DialogData *dialog_data,
2135 Boolean iconify_state,
2136 XClassHint * classHints )
2141 DialogInstanceData * instance_data;
2144 Boolean doCenter = False;
2145 Boolean doParentRelativePositioning = False;
2146 int availableDialogCount;
2149 dialog_type = dialog_data->type;
2151 /* Find the dialog */
2152 dialog = class_set[dialog_data->type].dialog_list;
2153 while (dialog != NULL)
2155 if (dialog->dialog_data == dialog_data)
2158 dialog = dialog->next;
2161 /* Need to add the map callback in relation to the parent */
2162 if (class_set[dialog_type].class->map)
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.
2169 if (map_parent == NULL)
2170 map_parent = parent;
2172 (*(class_set[dialog_type].class->map)) (map_parent, dialog->dialog);
2175 instance_data = (DialogInstanceData *) dialog_data->data;
2177 /* If this is a top level shell, get it realized */
2178 if (XtIsSubclass (XtParent (dialog->dialog_widget),
2179 applicationShellWidgetClass))
2181 if (XtIsRealized (XtParent (dialog->dialog_widget)) == False)
2183 if (instance_data->displayed == True)
2185 (void) sprintf (geometry, "=%dx%d+%d+%d",
2186 instance_data->width, instance_data->height,
2187 instance_data->x, instance_data->y);
2189 XtSetArg (args[0], XmNgeometry, geometry);
2190 XtSetValues (XtParent (dialog->dialog_widget), args, 1);
2192 else if ((instance_data->width != 0) && (instance_data->height != 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);
2200 /* Toggle mappedWhenManaged to false */
2201 XtSetMappedWhenManaged(XtParent (dialog->dialog_widget), False);
2202 XtRealizeWidget (XtParent(dialog->dialog_widget));
2204 /* Set the proper workspaces if needed */
2205 _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
2207 /* Set any application-specified class hints for the window */
2210 XSetClassHint(XtDisplay(dialog->dialog_widget),
2211 XtWindow(XtParent(dialog->dialog_widget)),
2215 /* Set the iconify state */
2216 SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
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);
2226 if (instance_data->displayed == True)
2228 WMShellWidget wm = (WMShellWidget)XtParent(dialog->dialog_widget);
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);
2237 else if ((instance_data->width != 0) && (instance_data->height != 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);
2245 /* Set the proper workspaces if needed */
2246 _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
2248 /* Set any application-specified class hints for the window */
2251 XSetClassHint(XtDisplay(dialog->dialog_widget),
2252 XtWindow(XtParent(dialog->dialog_widget)),
2256 /* Set the iconify state */
2257 SetIconifyState(XtParent(dialog->dialog_widget), iconify_state);
2259 /* Map the window */
2260 XtPopup (XtParent (dialog->dialog_widget), XtGrabNone);
2265 if (instance_data->displayed == True)
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);
2277 XtSetArg (args[0], XmNdefaultPosition, False);
2278 XtSetValues (dialog->dialog_widget, args, 1);
2280 XtRealizeWidget (dialog->dialog_widget);
2284 /* Position relative to the parent dialog */
2286 * Must be done after the set_values call, since the dialog
2287 * may get forced to a different size.
2289 doParentRelativePositioning = True;
2293 /* Center in the display */
2295 * Must be done after the set_values call, since the dialog
2296 * may get forced to a different size.
2303 * Dialogs with no controlling parent window, need to have their
2304 * own workspace perperty set, if some workspaces have been requested.
2306 if ((parent == NULL) && workspaces)
2307 _DtEncapSetWorkSpaceHints(XtParent(dialog->dialog_widget), workspaces);
2311 /* Set Values onto the dialog to set it to the correct data. */
2313 (*(class_set[dialog_data->type].class->set_values))
2314 (dialog->dialog, dialog_data->data);
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.
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);
2333 else if (doParentRelativePositioning)
2335 XtSetArg (args[0], XmNx,
2337 (Dimension)(parent->core.width - dialog->dialog_widget->core.width) / (Dimension)2);
2338 XtSetArg (args[1], XmNy,
2340 (Dimension)(parent->core.height - dialog->dialog_widget->core.height) / (Dimension)2);
2341 XtSetValues (XtParent(dialog->dialog_widget), args, 2);
2345 /* Fix up the transient-for windowing information so that */
2346 /* the window manager will shuffle and iconify as a group */
2350 if (XtIsRealized(parent))
2352 XSetTransientForHint (XtDisplay (parent),
2353 XtWindow (XtParent (dialog->dialog_widget)),
2359 if (!XtIsSubclass (XtParent (dialog->dialog_widget),
2360 applicationShellWidgetClass))
2362 XSetTransientForHint (XtDisplay (encap_parent_shell),
2363 XtWindow (XtParent (dialog->dialog_widget)),
2364 XtWindow (encap_parent_shell));
2369 /* Display the dialogs, application shells are displayed above. */
2371 if (!(XtIsSubclass (XtParent (dialog->dialog_widget),
2372 applicationShellWidgetClass)))
2374 XtManageChild (dialog->dialog_widget);
2378 /* Set the dialog instance data to indicate that the dialog */
2381 ((DialogInstanceData *) (dialog_data->data))->displayed = True;
2384 /* Give the dialog a chance to set its focus widget, if necessary */
2386 if (class_set[dialog_data->type].class->set_focus)
2388 (*(class_set[dialog_data->type].class->set_focus))
2389 (dialog->dialog, dialog_data->data);
2396 DialogStructureNotifyHandler(
2398 XtPointer client_data,
2401 if( event->type == MapNotify )
2403 if( NumberOfDialogMapped == 0 )
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;
2419 XtRemoveTimeOut( timerId );
2421 timerId = XtAppAddTimeOut( XtWidgetToApplicationContext( w ),
2423 (XtTimerCallbackProc)TimerEvent,
2427 ++NumberOfDialogMapped;
2429 else if( event->type == UnmapNotify )
2431 if( NumberOfDialogMapped )
2432 --NumberOfDialogMapped;
2434 if( NumberOfDialogMapped == 0 )
2438 XtRemoveTimeOut( timerId );
2448 XtPointer client_data,
2451 Dialog * dialog = (Dialog *) client_data;
2453 ChangeDirectoryToParent(dialog->change_client_data, directory);
2458 DialogData *dialog_data)
2460 Dialog *dialog,**headptr;
2461 headptr = &class_set[dialog_data->type].dialog_list;
2464 while (dialog != NULL)
2466 if (dialog->dialog_data == dialog_data)
2468 *headptr = dialog->next;
2469 XtFree((char *) dialog);
2472 headptr = &(dialog->next);
2479 * Retrieve dimensions of the Xinerama screen the given widget resides on.
2480 * Returns True on success, False otherwise.
2482 static Boolean GetXineramaScreenDimensions(
2483 Widget w, int *org_x, int *org_y, int *s_width, int *s_height)
2485 DtXineramaInfo_t *dt_xi;
2486 unsigned int wx, wy;
2487 unsigned int i, sx, sy, sw, sh;
2489 while (w && !XtIsShell(w))
2495 if (!(dt_xi=_DtXineramaInit(XtDisplay(w)))) return False;
2497 for (i=0; i<dt_xi->numscreens; i++){
2498 if (!_DtXineramaGetScreen(dt_xi,i,&sw,&sh,&sx,&sy))
2501 if (wx>=sx && wx<(sx+sw) && wy>=sy && wy<(sy+sh))
2515 #endif /* USE_XINERAMA */