1444c061aSmrg/***********************************************************
2fdf6a26fSmrgCopyright (c) 1993, Oracle and/or its affiliates.
31477040fSmrg
41477040fSmrgPermission is hereby granted, free of charge, to any person obtaining a
51477040fSmrgcopy of this software and associated documentation files (the "Software"),
61477040fSmrgto deal in the Software without restriction, including without limitation
71477040fSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense,
81477040fSmrgand/or sell copies of the Software, and to permit persons to whom the
91477040fSmrgSoftware is furnished to do so, subject to the following conditions:
101477040fSmrg
111477040fSmrgThe above copyright notice and this permission notice (including the next
121477040fSmrgparagraph) shall be included in all copies or substantial portions of the
131477040fSmrgSoftware.
141477040fSmrg
151477040fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161477040fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171477040fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181477040fSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191477040fSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201477040fSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211477040fSmrgDEALINGS IN THE SOFTWARE.
221477040fSmrg
231477040fSmrgCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24444c061aSmrg
25444c061aSmrg                        All Rights Reserved
26444c061aSmrg
27444c061aSmrgPermission to use, copy, modify, and distribute this software and its
28444c061aSmrgdocumentation for any purpose and without fee is hereby granted,
29444c061aSmrgprovided that the above copyright notice appear in all copies and that
30444c061aSmrgboth that copyright notice and this permission notice appear in
311477040fSmrgsupporting documentation, and that the name of Digital not be
32444c061aSmrgused in advertising or publicity pertaining to distribution of the
33444c061aSmrgsoftware without specific, written prior permission.
34444c061aSmrg
35444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41444c061aSmrgSOFTWARE.
42444c061aSmrg
43444c061aSmrg******************************************************************/
44444c061aSmrg
45444c061aSmrg/*
46444c061aSmrg
47444c061aSmrgCopyright 1987, 1988, 1994, 1998  The Open Group
48444c061aSmrg
49444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
50444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
51444c061aSmrgthe above copyright notice appear in all copies and that both that
52444c061aSmrgcopyright notice and this permission notice appear in supporting
53444c061aSmrgdocumentation.
54444c061aSmrg
55444c061aSmrgThe above copyright notice and this permission notice shall be included in
56444c061aSmrgall copies or substantial portions of the Software.
57444c061aSmrg
58444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
61444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64444c061aSmrg
65444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
66444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
67444c061aSmrgin this Software without prior written authorization from The Open Group.
68444c061aSmrg
69444c061aSmrg*/
70444c061aSmrg
71444c061aSmrg#ifndef DEFAULT_WM_TIMEOUT
72444c061aSmrg#define DEFAULT_WM_TIMEOUT 5000
73444c061aSmrg#endif
74444c061aSmrg
75444c061aSmrg#ifdef HAVE_CONFIG_H
76444c061aSmrg#include <config.h>
77444c061aSmrg#endif
78444c061aSmrg#include "IntrinsicI.h"
79444c061aSmrg#include "StringDefs.h"
80444c061aSmrg#include "Shell.h"
81444c061aSmrg#include "ShellP.h"
82444c061aSmrg#include "ShellI.h"
83444c061aSmrg#include "Vendor.h"
84444c061aSmrg#include "VendorP.h"
85444c061aSmrg#include <X11/Xatom.h>
86444c061aSmrg#include <X11/Xlocale.h>
87444c061aSmrg#include <X11/ICE/ICElib.h>
88444c061aSmrg#include <stdio.h>
89444c061aSmrg#include <stdlib.h>
90339a7c43Smrg#include <unistd.h>
91444c061aSmrg
92444c061aSmrg#ifdef EDITRES
93444c061aSmrg#include <X11/Xmu/Editres.h>
94444c061aSmrg#endif
95444c061aSmrg
9635525df4Smrg#ifdef WIN32
9735525df4Smrg#include <process.h>		/* for getpid() */
9835525df4Smrg#endif
9935525df4Smrg
100444c061aSmrg/***************************************************************************
101444c061aSmrg *
102444c061aSmrg * Note: per the Xt spec, the Shell geometry management assumes in
103444c061aSmrg * several places that there is only one managed child.  This is
104444c061aSmrg * *not* a bug.  Any subclass that assumes otherwise is broken.
105444c061aSmrg *
106444c061aSmrg ***************************************************************************/
107444c061aSmrg
108444c061aSmrg#define BIGSIZE ((Dimension)32767)
109444c061aSmrg
110444c061aSmrg/***************************************************************************
111444c061aSmrg *
112444c061aSmrg * Default values for resource lists
113444c061aSmrg *
114444c061aSmrg ***************************************************************************/
115444c061aSmrg
116444c061aSmrgstatic void _XtShellDepth(Widget, int, XrmValue *);
117444c061aSmrgstatic void _XtShellColormap(Widget, int, XrmValue *);
118444c061aSmrgstatic void _XtShellAncestorSensitive(Widget, int, XrmValue *);
119444c061aSmrgstatic void _XtTitleEncoding(Widget, int, XrmValue *);
120444c061aSmrg
121444c061aSmrg/***************************************************************************
122444c061aSmrg *
123444c061aSmrg * Shell class record
124444c061aSmrg *
125444c061aSmrg ***************************************************************************/
126444c061aSmrg
127a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(ShellRec, x))
128a3bd7f05Smrg/* *INDENT-OFF* */
129444c061aSmrgstatic XtResource shellResources[]=
130444c061aSmrg{
131a3bd7f05Smrg    {XtNx, XtCPosition, XtRPosition, sizeof(Position),
132a3bd7f05Smrg        Offset(core.x), XtRImmediate, (XtPointer)BIGSIZE},
133a3bd7f05Smrg    {XtNy, XtCPosition, XtRPosition, sizeof(Position),
134a3bd7f05Smrg        Offset(core.y), XtRImmediate, (XtPointer)BIGSIZE},
135a3bd7f05Smrg    { XtNdepth, XtCDepth, XtRInt, sizeof(int),
136a3bd7f05Smrg        Offset(core.depth), XtRCallProc, (XtPointer) _XtShellDepth},
137a3bd7f05Smrg    { XtNcolormap, XtCColormap, XtRColormap, sizeof(Colormap),
138a3bd7f05Smrg        Offset(core.colormap), XtRCallProc, (XtPointer) _XtShellColormap},
139a3bd7f05Smrg    { XtNancestorSensitive, XtCSensitive, XtRBoolean, sizeof(Boolean),
140a3bd7f05Smrg        Offset(core.ancestor_sensitive), XtRCallProc,
141a3bd7f05Smrg        (XtPointer) _XtShellAncestorSensitive},
142a3bd7f05Smrg    { XtNallowShellResize, XtCAllowShellResize, XtRBoolean,
143a3bd7f05Smrg        sizeof(Boolean), Offset(shell.allow_shell_resize),
144a3bd7f05Smrg        XtRImmediate, (XtPointer)False},
145a3bd7f05Smrg    { XtNgeometry, XtCGeometry, XtRString, sizeof(String),
146a3bd7f05Smrg        Offset(shell.geometry), XtRString, (XtPointer)NULL},
147a3bd7f05Smrg    { XtNcreatePopupChildProc, XtCCreatePopupChildProc, XtRFunction,
148a3bd7f05Smrg        sizeof(XtCreatePopupChildProc), Offset(shell.create_popup_child_proc),
149a3bd7f05Smrg        XtRFunction, NULL},
150a3bd7f05Smrg    { XtNsaveUnder, XtCSaveUnder, XtRBoolean, sizeof(Boolean),
151a3bd7f05Smrg        Offset(shell.save_under), XtRImmediate, (XtPointer)False},
152a3bd7f05Smrg    { XtNpopupCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
153a3bd7f05Smrg        Offset(shell.popup_callback), XtRCallback, (XtPointer) NULL},
154a3bd7f05Smrg    { XtNpopdownCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
155a3bd7f05Smrg        Offset(shell.popdown_callback), XtRCallback, (XtPointer) NULL},
156a3bd7f05Smrg    { XtNoverrideRedirect, XtCOverrideRedirect,
157a3bd7f05Smrg        XtRBoolean, sizeof(Boolean), Offset(shell.override_redirect),
158a3bd7f05Smrg        XtRImmediate, (XtPointer)False},
159a3bd7f05Smrg    { XtNvisual, XtCVisual, XtRVisual, sizeof(Visual*),
160a3bd7f05Smrg        Offset(shell.visual), XtRImmediate, (XtPointer)CopyFromParent}
161444c061aSmrg};
162a3bd7f05Smrg/* *INDENT-ON* */
163444c061aSmrg
164444c061aSmrgstatic void ClassPartInitialize(WidgetClass);
165444c061aSmrgstatic void Initialize(Widget, Widget, ArgList, Cardinal *);
166444c061aSmrgstatic void Realize(Widget, Mask *, XSetWindowAttributes *);
167444c061aSmrgstatic void Resize(Widget);
168a3bd7f05Smrgstatic Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
169a3bd7f05Smrgstatic void GetValuesHook(Widget, ArgList, Cardinal *);
170444c061aSmrgstatic void ChangeManaged(Widget);
171a3bd7f05Smrgstatic XtGeometryResult GeometryManager(Widget, XtWidgetGeometry *,
172a3bd7f05Smrg                                        XtWidgetGeometry *);
173a3bd7f05Smrgstatic XtGeometryResult RootGeometryManager(Widget gw,
174a3bd7f05Smrg                                            XtWidgetGeometry *request,
175a3bd7f05Smrg                                            XtWidgetGeometry *reply);
176444c061aSmrgstatic void Destroy(Widget);
177444c061aSmrg
178a3bd7f05Smrg/* *INDENT-OFF* */
179444c061aSmrgstatic ShellClassExtensionRec shellClassExtRec = {
180444c061aSmrg    NULL,
181444c061aSmrg    NULLQUARK,
182444c061aSmrg    XtShellExtensionVersion,
183444c061aSmrg    sizeof(ShellClassExtensionRec),
184444c061aSmrg    RootGeometryManager
185444c061aSmrg};
186444c061aSmrg
187444c061aSmrgexternaldef(shellclassrec) ShellClassRec shellClassRec = {
188444c061aSmrg  {   /* Core */
189a3bd7f05Smrg    /* superclass            */ (WidgetClass) &compositeClassRec,
190a3bd7f05Smrg    /* class_name            */ "Shell",
191a3bd7f05Smrg    /* size                  */ sizeof(ShellRec),
192a3bd7f05Smrg    /* Class Initializer     */ NULL,
193a3bd7f05Smrg    /* class_part_initialize */ ClassPartInitialize,
194a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
195a3bd7f05Smrg    /* initialize            */ Initialize,
196a3bd7f05Smrg    /* initialize_notify     */ NULL,
197a3bd7f05Smrg    /* realize               */ Realize,
198a3bd7f05Smrg    /* actions               */ NULL,
199a3bd7f05Smrg    /* num_actions           */ 0,
200a3bd7f05Smrg    /* resources             */ shellResources,
201a3bd7f05Smrg    /* resource_count        */ XtNumber(shellResources),
202a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
203a3bd7f05Smrg    /* compress_motion       */ FALSE,
204a3bd7f05Smrg    /* compress_exposure     */ TRUE,
205a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
206a3bd7f05Smrg    /* visible_interest      */ FALSE,
207a3bd7f05Smrg    /* destroy               */ Destroy,
208a3bd7f05Smrg    /* resize                */ Resize,
209a3bd7f05Smrg    /* expose                */ NULL,
210a3bd7f05Smrg    /* set_values            */ SetValues,
211a3bd7f05Smrg    /* set_values_hook       */ NULL,
212a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
213a3bd7f05Smrg    /* get_values_hook       */ GetValuesHook,
214a3bd7f05Smrg    /* accept_focus          */ NULL,
215a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
216a3bd7f05Smrg    /* callback offsets      */ NULL,
217a3bd7f05Smrg    /* tm_table              */ NULL,
218a3bd7f05Smrg    /* query_geometry        */ NULL,
219a3bd7f05Smrg    /* display_accelerator   */ NULL,
220a3bd7f05Smrg    /* extension             */ NULL
221444c061aSmrg  },{ /* Composite */
222a3bd7f05Smrg    /* geometry_manager      */ GeometryManager,
223a3bd7f05Smrg    /* change_managed        */ ChangeManaged,
224a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
225a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
226a3bd7f05Smrg    /* extension             */ NULL
227444c061aSmrg  },{ /* Shell */
228a3bd7f05Smrg    /* extension             */ (XtPointer)&shellClassExtRec
229444c061aSmrg  }
230444c061aSmrg};
231a3bd7f05Smrg/* *INDENT-ON* */
232444c061aSmrg
233a3bd7f05Smrgexternaldef(shellwidgetclass)
234a3bd7f05SmrgWidgetClass shellWidgetClass = (WidgetClass) (&shellClassRec);
235444c061aSmrg
236444c061aSmrg/***************************************************************************
237444c061aSmrg *
238444c061aSmrg * OverrideShell class record
239444c061aSmrg *
240444c061aSmrg ***************************************************************************/
241444c061aSmrg
242a3bd7f05Smrg/* *INDENT-OFF* */
243a3bd7f05Smrgstatic XtResource overrideResources[] =
244444c061aSmrg{
245a3bd7f05Smrg    { XtNoverrideRedirect, XtCOverrideRedirect,
246a3bd7f05Smrg        XtRBoolean, sizeof(Boolean), Offset(shell.override_redirect),
247a3bd7f05Smrg        XtRImmediate, (XtPointer)True},
248a3bd7f05Smrg    { XtNsaveUnder, XtCSaveUnder, XtRBoolean, sizeof(Boolean),
249a3bd7f05Smrg        Offset(shell.save_under), XtRImmediate, (XtPointer)True},
250444c061aSmrg};
251444c061aSmrg
252444c061aSmrgexternaldef(overrideshellclassrec) OverrideShellClassRec overrideShellClassRec = {
253444c061aSmrg  {
254a3bd7f05Smrg    /* superclass            */ (WidgetClass) &shellClassRec,
255a3bd7f05Smrg    /* class_name            */ "OverrideShell",
256a3bd7f05Smrg    /* size                  */ sizeof(OverrideShellRec),
257a3bd7f05Smrg    /* Class Initializer     */ NULL,
258a3bd7f05Smrg    /* class_part_initialize */ NULL,
259a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
260a3bd7f05Smrg    /* initialize            */ NULL,
261a3bd7f05Smrg    /* initialize_notify     */ NULL,
262a3bd7f05Smrg    /* realize               */ XtInheritRealize,
263a3bd7f05Smrg    /* actions               */ NULL,
264a3bd7f05Smrg    /* num_actions           */ 0,
265a3bd7f05Smrg    /* resources             */ overrideResources,
266a3bd7f05Smrg    /* resource_count        */ XtNumber(overrideResources),
267a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
268a3bd7f05Smrg    /* compress_motion       */ FALSE,
269a3bd7f05Smrg    /* compress_exposure     */ TRUE,
270a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
271a3bd7f05Smrg    /* visible_interest      */ FALSE,
272a3bd7f05Smrg    /* destroy               */ NULL,
273a3bd7f05Smrg    /* resize                */ XtInheritResize,
274a3bd7f05Smrg    /* expose                */ NULL,
275a3bd7f05Smrg    /* set_values            */ NULL,
276a3bd7f05Smrg    /* set_values_hook       */ NULL,
277a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
278a3bd7f05Smrg    /* get_values_hook       */ NULL,
279a3bd7f05Smrg    /* accept_focus          */ NULL,
280a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
281a3bd7f05Smrg    /* callback offsets      */ NULL,
282a3bd7f05Smrg    /* tm_table              */ NULL,
283a3bd7f05Smrg    /* query_geometry        */ NULL,
284a3bd7f05Smrg    /* display_accelerator   */ NULL,
285a3bd7f05Smrg    /* extension             */ NULL
286444c061aSmrg  },{
287a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
288a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
289a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
290a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
291a3bd7f05Smrg    /* extension             */ NULL
292444c061aSmrg  },{
293a3bd7f05Smrg    /* extension             */ NULL
294444c061aSmrg  },{
295a3bd7f05Smrg    /* extension             */ NULL
296444c061aSmrg  }
297444c061aSmrg};
298a3bd7f05Smrg/* *INDENT-ON* */
299444c061aSmrg
300a3bd7f05Smrgexternaldef(overrideshellwidgetclass)
301a3bd7f05SmrgWidgetClass overrideShellWidgetClass = (WidgetClass) (&overrideShellClassRec);
302444c061aSmrg
303444c061aSmrg/***************************************************************************
304444c061aSmrg *
305444c061aSmrg * WMShell class record
306444c061aSmrg *
307444c061aSmrg ***************************************************************************/
308444c061aSmrg
309444c061aSmrg#undef Offset
310a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(WMShellRec, x))
311444c061aSmrg
312444c061aSmrgstatic int default_unspecified_shell_int = XtUnspecifiedShellInt;
313a3bd7f05Smrg
314444c061aSmrg/*
315444c061aSmrg * Warning, casting XtUnspecifiedShellInt (which is -1) to an (XtPointer)
316444c061aSmrg * can result is loss of bits on some machines (i.e. crays)
317444c061aSmrg */
318444c061aSmrg
319a3bd7f05Smrg/* *INDENT-OFF* */
320a3bd7f05Smrgstatic XtResource wmResources[] =
321a3bd7f05Smrg{
322a3bd7f05Smrg    { XtNtitle, XtCTitle, XtRString, sizeof(String),
323a3bd7f05Smrg        Offset(wm.title), XtRString, NULL},
324a3bd7f05Smrg    { XtNtitleEncoding, XtCTitleEncoding, XtRAtom, sizeof(Atom),
325a3bd7f05Smrg        Offset(wm.title_encoding),
326a3bd7f05Smrg        XtRCallProc, (XtPointer) _XtTitleEncoding},
327a3bd7f05Smrg    { XtNwmTimeout, XtCWmTimeout, XtRInt, sizeof(int),
328a3bd7f05Smrg        Offset(wm.wm_timeout), XtRImmediate,(XtPointer)DEFAULT_WM_TIMEOUT},
329a3bd7f05Smrg    { XtNwaitForWm, XtCWaitForWm, XtRBoolean, sizeof(Boolean),
330a3bd7f05Smrg        Offset(wm.wait_for_wm), XtRImmediate, (XtPointer)True},
331a3bd7f05Smrg    { XtNtransient, XtCTransient, XtRBoolean, sizeof(Boolean),
332a3bd7f05Smrg        Offset(wm.transient), XtRImmediate, (XtPointer)False},
333444c061aSmrg/* size_hints minus things stored in core */
334a3bd7f05Smrg    { XtNbaseWidth, XtCBaseWidth, XtRInt, sizeof(int),
335a3bd7f05Smrg        Offset(wm.base_width),
336a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
337a3bd7f05Smrg    { XtNbaseHeight, XtCBaseHeight, XtRInt, sizeof(int),
338a3bd7f05Smrg        Offset(wm.base_height),
339a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
340a3bd7f05Smrg    { XtNwinGravity, XtCWinGravity, XtRGravity, sizeof(int),
341a3bd7f05Smrg        Offset(wm.win_gravity),
342a3bd7f05Smrg        XtRGravity, (XtPointer) &default_unspecified_shell_int},
343a3bd7f05Smrg    { XtNminWidth, XtCMinWidth, XtRInt, sizeof(int),
344a3bd7f05Smrg        Offset(wm.size_hints.min_width),
345a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
346a3bd7f05Smrg    { XtNminHeight, XtCMinHeight, XtRInt, sizeof(int),
347a3bd7f05Smrg        Offset(wm.size_hints.min_height),
348a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
349a3bd7f05Smrg    { XtNmaxWidth, XtCMaxWidth, XtRInt, sizeof(int),
350a3bd7f05Smrg        Offset(wm.size_hints.max_width),
351a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
352a3bd7f05Smrg    { XtNmaxHeight, XtCMaxHeight, XtRInt, sizeof(int),
353a3bd7f05Smrg        Offset(wm.size_hints.max_height),
354a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
355a3bd7f05Smrg    { XtNwidthInc, XtCWidthInc, XtRInt, sizeof(int),
356a3bd7f05Smrg        Offset(wm.size_hints.width_inc),
357a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
358a3bd7f05Smrg    { XtNheightInc, XtCHeightInc, XtRInt, sizeof(int),
359a3bd7f05Smrg        Offset(wm.size_hints.height_inc),
360a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
361a3bd7f05Smrg    { XtNminAspectX, XtCMinAspectX, XtRInt, sizeof(int),
362a3bd7f05Smrg        Offset(wm.size_hints.min_aspect.x),
363a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
364a3bd7f05Smrg    { XtNminAspectY, XtCMinAspectY, XtRInt, sizeof(int),
365a3bd7f05Smrg        Offset(wm.size_hints.min_aspect.y),
366a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
367a3bd7f05Smrg    { XtNmaxAspectX, XtCMaxAspectX, XtRInt, sizeof(int),
368a3bd7f05Smrg        Offset(wm.size_hints.max_aspect.x),
369a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
370a3bd7f05Smrg    { XtNmaxAspectY, XtCMaxAspectY, XtRInt, sizeof(int),
371a3bd7f05Smrg        Offset(wm.size_hints.max_aspect.y),
372a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
373444c061aSmrg/* wm_hints */
374a3bd7f05Smrg    { XtNinput, XtCInput, XtRBool, sizeof(Bool),
375a3bd7f05Smrg        Offset(wm.wm_hints.input), XtRImmediate, (XtPointer)False},
376a3bd7f05Smrg    { XtNinitialState, XtCInitialState, XtRInitialState, sizeof(int),
377a3bd7f05Smrg        Offset(wm.wm_hints.initial_state),
378a3bd7f05Smrg        XtRImmediate, (XtPointer)NormalState},
379a3bd7f05Smrg    { XtNiconPixmap, XtCIconPixmap, XtRBitmap, sizeof(Pixmap),
380a3bd7f05Smrg        Offset(wm.wm_hints.icon_pixmap), XtRPixmap, NULL},
381a3bd7f05Smrg    { XtNiconWindow, XtCIconWindow, XtRWindow, sizeof(Window),
382a3bd7f05Smrg        Offset(wm.wm_hints.icon_window), XtRWindow,   (XtPointer) NULL},
383a3bd7f05Smrg    { XtNiconX, XtCIconX, XtRInt, sizeof(int),
384a3bd7f05Smrg        Offset(wm.wm_hints.icon_x),
385a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
386a3bd7f05Smrg    { XtNiconY, XtCIconY, XtRInt, sizeof(int),
387a3bd7f05Smrg        Offset(wm.wm_hints.icon_y),
388a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
389a3bd7f05Smrg    { XtNiconMask, XtCIconMask, XtRBitmap, sizeof(Pixmap),
390a3bd7f05Smrg        Offset(wm.wm_hints.icon_mask), XtRPixmap, NULL},
391a3bd7f05Smrg    { XtNwindowGroup, XtCWindowGroup, XtRWindow, sizeof(Window),
392a3bd7f05Smrg        Offset(wm.wm_hints.window_group),
393a3bd7f05Smrg        XtRImmediate, (XtPointer)XtUnspecifiedWindow},
394a3bd7f05Smrg    { XtNclientLeader, XtCClientLeader, XtRWidget, sizeof(Widget),
395a3bd7f05Smrg        Offset(wm.client_leader), XtRWidget, NULL},
396a3bd7f05Smrg    { XtNwindowRole, XtCWindowRole, XtRString, sizeof(String),
397a3bd7f05Smrg        Offset(wm.window_role), XtRString, (XtPointer) NULL},
398a3bd7f05Smrg    { XtNurgency, XtCUrgency, XtRBoolean, sizeof(Boolean),
399a3bd7f05Smrg        Offset(wm.urgency), XtRImmediate, (XtPointer) False}
400444c061aSmrg};
401a3bd7f05Smrg/* *INDENT-ON* */
402444c061aSmrg
403a3bd7f05Smrgstatic void
404a3bd7f05SmrgWMInitialize(Widget, Widget, ArgList, Cardinal *);
405a3bd7f05Smrgstatic Boolean
406a3bd7f05SmrgWMSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
407a3bd7f05Smrgstatic void
408a3bd7f05SmrgWMDestroy(Widget);
409444c061aSmrg
410a3bd7f05Smrg/* *INDENT-OFF* */
411444c061aSmrgexternaldef(wmshellclassrec) WMShellClassRec wmShellClassRec = {
412444c061aSmrg  {
413a3bd7f05Smrg    /* superclass            */ (WidgetClass) &shellClassRec,
414a3bd7f05Smrg    /* class_name            */ "WMShell",
415a3bd7f05Smrg    /* size                  */ sizeof(WMShellRec),
416a3bd7f05Smrg    /* Class Initializer     */ NULL,
417a3bd7f05Smrg    /* class_part_initialize */ NULL,
418a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
419a3bd7f05Smrg    /* initialize            */ WMInitialize,
420a3bd7f05Smrg    /* initialize_notify     */ NULL,
421a3bd7f05Smrg    /* realize               */ XtInheritRealize,
422a3bd7f05Smrg    /* actions               */ NULL,
423a3bd7f05Smrg    /* num_actions           */ 0,
424a3bd7f05Smrg    /* resources             */ wmResources,
425a3bd7f05Smrg    /* resource_count        */ XtNumber(wmResources),
426a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
427a3bd7f05Smrg    /* compress_motion       */ FALSE,
428a3bd7f05Smrg    /* compress_exposure     */ TRUE,
429a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
430a3bd7f05Smrg    /* visible_interest      */ FALSE,
431a3bd7f05Smrg    /* destroy               */ WMDestroy,
432a3bd7f05Smrg    /* resize                */ XtInheritResize,
433a3bd7f05Smrg    /* expose                */ NULL,
434a3bd7f05Smrg    /* set_values            */ WMSetValues,
435a3bd7f05Smrg    /* set_values_hook       */ NULL,
436a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
437a3bd7f05Smrg    /* get_values_hook       */ NULL,
438a3bd7f05Smrg    /* accept_focus          */ NULL,
439a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
440a3bd7f05Smrg    /* callback offsets      */ NULL,
441a3bd7f05Smrg    /* tm_table              */ NULL,
442a3bd7f05Smrg    /* query_geometry        */ NULL,
443a3bd7f05Smrg    /* display_accelerator   */ NULL,
444a3bd7f05Smrg    /* extension             */ NULL
445444c061aSmrg  },{
446a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
447a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
448a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
449a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
450a3bd7f05Smrg    /* extension             */ NULL
451444c061aSmrg  },{
452a3bd7f05Smrg    /* extension             */ NULL
453444c061aSmrg  },{
454a3bd7f05Smrg    /* extension             */ NULL
455444c061aSmrg  }
456444c061aSmrg};
457a3bd7f05Smrg/* *INDENT-ON* */
458444c061aSmrg
459a3bd7f05Smrgexternaldef(wmshellwidgetclass)
460a3bd7f05SmrgWidgetClass wmShellWidgetClass = (WidgetClass) (&wmShellClassRec);
461444c061aSmrg
462444c061aSmrg/***************************************************************************
463444c061aSmrg *
464444c061aSmrg * TransientShell class record
465444c061aSmrg *
466444c061aSmrg ***************************************************************************/
467444c061aSmrg
468444c061aSmrg#undef Offset
469a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(TransientShellRec, x))
470444c061aSmrg
471a3bd7f05Smrg/* *INDENT-OFF* */
472444c061aSmrgstatic XtResource transientResources[]=
473444c061aSmrg{
474a3bd7f05Smrg    { XtNtransient, XtCTransient, XtRBoolean, sizeof(Boolean),
475a3bd7f05Smrg        Offset(wm.transient), XtRImmediate, (XtPointer)True},
476a3bd7f05Smrg    { XtNtransientFor, XtCTransientFor, XtRWidget, sizeof(Widget),
477a3bd7f05Smrg        Offset(transient.transient_for), XtRWidget, NULL},
478a3bd7f05Smrg    { XtNsaveUnder, XtCSaveUnder, XtRBoolean, sizeof(Boolean),
479a3bd7f05Smrg        Offset(shell.save_under), XtRImmediate, (XtPointer)True},
480444c061aSmrg};
481a3bd7f05Smrg/* *INDENT-ON* */
482444c061aSmrg
483a3bd7f05Smrgstatic void
484a3bd7f05SmrgTransientRealize(Widget, Mask *, XSetWindowAttributes *);
485a3bd7f05Smrgstatic Boolean
486a3bd7f05SmrgTransientSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
487444c061aSmrg
488a3bd7f05Smrg/* *INDENT-OFF* */
489444c061aSmrgexternaldef(transientshellclassrec) TransientShellClassRec transientShellClassRec = {
490444c061aSmrg  {
491a3bd7f05Smrg    /* superclass            */ (WidgetClass) &vendorShellClassRec,
492a3bd7f05Smrg    /* class_name            */ "TransientShell",
493a3bd7f05Smrg    /* size                  */ sizeof(TransientShellRec),
494a3bd7f05Smrg    /* Class Initializer     */ NULL,
495a3bd7f05Smrg    /* class_part_initialize */ NULL,
496a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
497a3bd7f05Smrg    /* initialize            */ NULL,
498a3bd7f05Smrg    /* initialize_notify     */ NULL,
499a3bd7f05Smrg    /* realize               */ TransientRealize,
500a3bd7f05Smrg    /* actions               */ NULL,
501a3bd7f05Smrg    /* num_actions           */ 0,
502a3bd7f05Smrg    /* resources             */ transientResources,
503a3bd7f05Smrg    /* resource_count        */ XtNumber(transientResources),
504a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
505a3bd7f05Smrg    /* compress_motion       */ FALSE,
506a3bd7f05Smrg    /* compress_exposure     */ TRUE,
507a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
508a3bd7f05Smrg    /* visible_interest      */ FALSE,
509a3bd7f05Smrg    /* destroy               */ NULL,
510a3bd7f05Smrg    /* resize                */ XtInheritResize,
511a3bd7f05Smrg    /* expose                */ NULL,
512a3bd7f05Smrg    /* set_values            */ TransientSetValues,
513a3bd7f05Smrg    /* set_values_hook       */ NULL,
514a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
515a3bd7f05Smrg    /* get_values_hook       */ NULL,
516a3bd7f05Smrg    /* accept_focus          */ NULL,
517a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
518a3bd7f05Smrg    /* callback offsets      */ NULL,
519a3bd7f05Smrg    /* tm_table              */ XtInheritTranslations,
520a3bd7f05Smrg    /* query_geometry        */ NULL,
521a3bd7f05Smrg    /* display_accelerator   */ NULL,
522a3bd7f05Smrg    /* extension             */ NULL
523444c061aSmrg  },{
524a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
525a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
526a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
527a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
528a3bd7f05Smrg    /* extension             */ NULL
529444c061aSmrg  },{
530a3bd7f05Smrg    /* extension             */ NULL
531444c061aSmrg  },{
532a3bd7f05Smrg    /* extension             */ NULL
533444c061aSmrg  },{
534a3bd7f05Smrg    /* extension             */ NULL
535444c061aSmrg  },{
536a3bd7f05Smrg    /* extension             */ NULL
537444c061aSmrg  }
538444c061aSmrg};
539a3bd7f05Smrg/* *INDENT-ON* */
540444c061aSmrg
541a3bd7f05Smrgexternaldef(transientshellwidgetclass)
542a3bd7f05SmrgWidgetClass transientShellWidgetClass = (WidgetClass) (&transientShellClassRec);
543444c061aSmrg
544444c061aSmrg/***************************************************************************
545444c061aSmrg *
546444c061aSmrg * TopLevelShell class record
547444c061aSmrg *
548444c061aSmrg ***************************************************************************/
549444c061aSmrg
550444c061aSmrg#undef Offset
551a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(TopLevelShellRec, x))
552444c061aSmrg
553a3bd7f05Smrg/* *INDENT-OFF* */
554444c061aSmrgstatic XtResource topLevelResources[]=
555444c061aSmrg{
556a3bd7f05Smrg    { XtNiconName, XtCIconName, XtRString, sizeof(String),
557a3bd7f05Smrg        Offset(topLevel.icon_name), XtRString, (XtPointer) NULL},
558a3bd7f05Smrg    { XtNiconNameEncoding, XtCIconNameEncoding, XtRAtom, sizeof(Atom),
559a3bd7f05Smrg        Offset(topLevel.icon_name_encoding),
560a3bd7f05Smrg        XtRCallProc, (XtPointer) _XtTitleEncoding},
561a3bd7f05Smrg    { XtNiconic, XtCIconic, XtRBoolean, sizeof(Boolean),
562a3bd7f05Smrg        Offset(topLevel.iconic), XtRImmediate, (XtPointer)False}
563444c061aSmrg};
564a3bd7f05Smrg/* *INDENT-ON* */
565444c061aSmrg
566a3bd7f05Smrgstatic void
567a3bd7f05SmrgTopLevelInitialize(Widget, Widget, ArgList, Cardinal *);
568a3bd7f05Smrgstatic Boolean
569a3bd7f05SmrgTopLevelSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
570a3bd7f05Smrgstatic void
571a3bd7f05SmrgTopLevelDestroy(Widget);
572444c061aSmrg
573a3bd7f05Smrg/* *INDENT-OFF* */
574444c061aSmrgexternaldef(toplevelshellclassrec) TopLevelShellClassRec topLevelShellClassRec = {
575444c061aSmrg  {
576a3bd7f05Smrg    /* superclass            */ (WidgetClass) &vendorShellClassRec,
577a3bd7f05Smrg    /* class_name            */ "TopLevelShell",
578a3bd7f05Smrg    /* size                  */ sizeof(TopLevelShellRec),
579a3bd7f05Smrg    /* Class Initializer     */ NULL,
580a3bd7f05Smrg    /* class_part_initialize */ NULL,
581a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
582a3bd7f05Smrg    /* initialize            */ TopLevelInitialize,
583a3bd7f05Smrg    /* initialize_notify     */ NULL,
584a3bd7f05Smrg    /* realize               */ XtInheritRealize,
585a3bd7f05Smrg    /* actions               */ NULL,
586a3bd7f05Smrg    /* num_actions           */ 0,
587a3bd7f05Smrg    /* resources             */ topLevelResources,
588a3bd7f05Smrg    /* resource_count        */ XtNumber(topLevelResources),
589a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
590a3bd7f05Smrg    /* compress_motion       */ FALSE,
591a3bd7f05Smrg    /* compress_exposure     */ TRUE,
592a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
593a3bd7f05Smrg    /* visible_interest      */ FALSE,
594a3bd7f05Smrg    /* destroy               */ TopLevelDestroy,
595a3bd7f05Smrg    /* resize                */ XtInheritResize,
596a3bd7f05Smrg    /* expose                */ NULL,
597a3bd7f05Smrg    /* set_values            */ TopLevelSetValues,
598a3bd7f05Smrg    /* set_values_hook       */ NULL,
599a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
600a3bd7f05Smrg    /* get_values_hook       */ NULL,
601a3bd7f05Smrg    /* accept_focus          */ NULL,
602a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
603a3bd7f05Smrg    /* callback offsets      */ NULL,
604a3bd7f05Smrg    /* tm_table              */ XtInheritTranslations,
605a3bd7f05Smrg    /* query_geometry        */ NULL,
606a3bd7f05Smrg    /* display_accelerator   */ NULL,
607a3bd7f05Smrg    /* extension             */ NULL
608444c061aSmrg  },{
609a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
610a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
611a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
612a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
613a3bd7f05Smrg    /* extension             */ NULL
614444c061aSmrg  },{
615a3bd7f05Smrg    /* extension             */ NULL
616444c061aSmrg  },{
617a3bd7f05Smrg    /* extension             */ NULL
618444c061aSmrg  },{
619a3bd7f05Smrg    /* extension             */ NULL
620444c061aSmrg  },{
621a3bd7f05Smrg    /* extension             */ NULL
622444c061aSmrg  }
623444c061aSmrg};
624a3bd7f05Smrg/* *INDENT-ON* */
625444c061aSmrg
626a3bd7f05Smrgexternaldef(toplevelshellwidgetclass)
627a3bd7f05SmrgWidgetClass topLevelShellWidgetClass = (WidgetClass) (&topLevelShellClassRec);
628444c061aSmrg
629444c061aSmrg/***************************************************************************
630444c061aSmrg *
631444c061aSmrg * ApplicationShell class record
632444c061aSmrg *
633444c061aSmrg ***************************************************************************/
634444c061aSmrg
635444c061aSmrg#undef Offset
636a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(ApplicationShellRec, x))
637444c061aSmrg
638a3bd7f05Smrg/* *INDENT-OFF* */
639444c061aSmrgstatic XtResource applicationResources[]=
640444c061aSmrg{
641444c061aSmrg    {XtNargc, XtCArgc, XtRInt, sizeof(int),
642a3bd7f05Smrg          Offset(application.argc), XtRImmediate, (XtPointer)0},
643444c061aSmrg    {XtNargv, XtCArgv, XtRStringArray, sizeof(String*),
644a3bd7f05Smrg          Offset(application.argv), XtRPointer, (XtPointer) NULL}
645444c061aSmrg};
646a3bd7f05Smrg/* *INDENT-ON* */
647444c061aSmrg#undef Offset
648444c061aSmrg
649a3bd7f05Smrgstatic void
650a3bd7f05SmrgApplicationInitialize(Widget, Widget, ArgList, Cardinal *);
651a3bd7f05Smrgstatic void
652a3bd7f05SmrgApplicationDestroy(Widget);
653a3bd7f05Smrgstatic Boolean
654a3bd7f05SmrgApplicationSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
655a3bd7f05Smrgstatic void
656a3bd7f05SmrgApplicationShellInsertChild(Widget);
657444c061aSmrg
658a3bd7f05Smrg/* *INDENT-OFF* */
659444c061aSmrgstatic CompositeClassExtensionRec compositeClassExtension = {
660a3bd7f05Smrg    /* next_extension        */ NULL,
661a3bd7f05Smrg    /* record_type           */ NULLQUARK,
662a3bd7f05Smrg    /* version               */ XtCompositeExtensionVersion,
663a3bd7f05Smrg    /* record_size           */ sizeof(CompositeClassExtensionRec),
664a3bd7f05Smrg    /* accepts_objects       */ TRUE,
665444c061aSmrg    /* allows_change_managed_set */ FALSE
666444c061aSmrg};
667444c061aSmrg
668444c061aSmrgexternaldef(applicationshellclassrec) ApplicationShellClassRec applicationShellClassRec = {
669444c061aSmrg  {
670a3bd7f05Smrg    /* superclass            */ (WidgetClass) &topLevelShellClassRec,
671a3bd7f05Smrg    /* class_name            */ "ApplicationShell",
672a3bd7f05Smrg    /* size                  */ sizeof(ApplicationShellRec),
673a3bd7f05Smrg    /* Class Initializer     */ NULL,
674a3bd7f05Smrg    /* class_part_initialize*/  NULL,
675a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
676a3bd7f05Smrg    /* initialize            */ ApplicationInitialize,
677a3bd7f05Smrg    /* initialize_notify     */ NULL,
678a3bd7f05Smrg    /* realize               */ XtInheritRealize,
679a3bd7f05Smrg    /* actions               */ NULL,
680a3bd7f05Smrg    /* num_actions           */ 0,
681a3bd7f05Smrg    /* resources             */ applicationResources,
682a3bd7f05Smrg    /* resource_count        */ XtNumber(applicationResources),
683a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
684a3bd7f05Smrg    /* compress_motion       */ FALSE,
685a3bd7f05Smrg    /* compress_exposure     */ TRUE,
686a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
687a3bd7f05Smrg    /* visible_interest      */ FALSE,
688a3bd7f05Smrg    /* destroy               */ ApplicationDestroy,
689a3bd7f05Smrg    /* resize                */ XtInheritResize,
690a3bd7f05Smrg    /* expose                */ NULL,
691a3bd7f05Smrg    /* set_values            */ ApplicationSetValues,
692a3bd7f05Smrg    /* set_values_hook       */ NULL,
693a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
694a3bd7f05Smrg    /* get_values_hook       */ NULL,
695a3bd7f05Smrg    /* accept_focus          */ NULL,
696a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
697a3bd7f05Smrg    /* callback offsets      */ NULL,
698a3bd7f05Smrg    /* tm_table              */ XtInheritTranslations,
699a3bd7f05Smrg    /* query_geometry        */ NULL,
700a3bd7f05Smrg    /* display_accelerator   */ NULL,
701a3bd7f05Smrg    /* extension             */ NULL
702444c061aSmrg  },{
703a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
704a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
705a3bd7f05Smrg    /* insert_child          */ ApplicationShellInsertChild,
706a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
707a3bd7f05Smrg    /* extension             */ (XtPointer)&compositeClassExtension
708444c061aSmrg  },{
709a3bd7f05Smrg    /* extension             */ NULL
710444c061aSmrg  },{
711a3bd7f05Smrg    /* extension             */ NULL
712444c061aSmrg  },{
713a3bd7f05Smrg    /* extension             */ NULL
714444c061aSmrg  },{
715a3bd7f05Smrg    /* extension             */ NULL
716444c061aSmrg  },{
717a3bd7f05Smrg    /* extension             */ NULL
718444c061aSmrg  }
719444c061aSmrg};
720a3bd7f05Smrg/* *INDENT-ON* */
721444c061aSmrg
722a3bd7f05Smrgexternaldef(applicationshellwidgetclass)
723a3bd7f05SmrgWidgetClass applicationShellWidgetClass =
724a3bd7f05Smrg    (WidgetClass) (&applicationShellClassRec);
725444c061aSmrg
726444c061aSmrg/***************************************************************************
727444c061aSmrg *
728444c061aSmrg * SessionShell class record
729444c061aSmrg *
730444c061aSmrg ***************************************************************************/
731444c061aSmrg
732444c061aSmrg#undef Offset
733a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(SessionShellRec, x))
734444c061aSmrg
735a3bd7f05Smrg/* *INDENT-OFF* */
736444c061aSmrgstatic XtResource sessionResources[]=
737444c061aSmrg{
738444c061aSmrg#ifndef XT_NO_SM
739444c061aSmrg {XtNconnection, XtCConnection, XtRSmcConn, sizeof(SmcConn),
740444c061aSmrg       Offset(session.connection), XtRSmcConn, (XtPointer) NULL},
741444c061aSmrg#endif
742444c061aSmrg {XtNsessionID, XtCSessionID, XtRString, sizeof(String),
743444c061aSmrg       Offset(session.session_id), XtRString, (XtPointer) NULL},
744444c061aSmrg {XtNrestartCommand, XtCRestartCommand, XtRCommandArgArray, sizeof(String*),
745444c061aSmrg       Offset(session.restart_command), XtRPointer, (XtPointer) NULL},
746444c061aSmrg {XtNcloneCommand, XtCCloneCommand, XtRCommandArgArray, sizeof(String*),
747444c061aSmrg       Offset(session.clone_command), XtRPointer, (XtPointer) NULL},
748444c061aSmrg {XtNdiscardCommand, XtCDiscardCommand, XtRCommandArgArray, sizeof(String*),
749444c061aSmrg       Offset(session.discard_command), XtRPointer, (XtPointer) NULL},
750444c061aSmrg {XtNresignCommand, XtCResignCommand, XtRCommandArgArray, sizeof(String*),
751444c061aSmrg       Offset(session.resign_command), XtRPointer, (XtPointer) NULL},
752444c061aSmrg {XtNshutdownCommand, XtCShutdownCommand, XtRCommandArgArray, sizeof(String*),
753444c061aSmrg       Offset(session.shutdown_command), XtRPointer, (XtPointer) NULL},
754444c061aSmrg {XtNenvironment, XtCEnvironment, XtREnvironmentArray, sizeof(String*),
755444c061aSmrg       Offset(session.environment), XtRPointer, (XtPointer) NULL},
756444c061aSmrg {XtNcurrentDirectory, XtCCurrentDirectory, XtRDirectoryString, sizeof(String),
757444c061aSmrg       Offset(session.current_dir), XtRString, (XtPointer) NULL},
758444c061aSmrg {XtNprogramPath, XtCProgramPath, XtRString, sizeof(String),
759444c061aSmrg      Offset(session.program_path), XtRString, (XtPointer) NULL},
760444c061aSmrg {XtNrestartStyle, XtCRestartStyle, XtRRestartStyle, sizeof(unsigned char),
761444c061aSmrg      Offset(session.restart_style), XtRImmediate,
762444c061aSmrg      (XtPointer) SmRestartIfRunning},
763444c061aSmrg {XtNjoinSession, XtCJoinSession, XtRBoolean, sizeof(Boolean),
764444c061aSmrg       Offset(session.join_session), XtRImmediate, (XtPointer) True},
765444c061aSmrg {XtNsaveCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
766444c061aSmrg       Offset(session.save_callbacks), XtRCallback, (XtPointer) NULL},
767444c061aSmrg {XtNinteractCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
768444c061aSmrg       Offset(session.interact_callbacks), XtRCallback, (XtPointer)NULL},
769444c061aSmrg {XtNcancelCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
770444c061aSmrg       Offset(session.cancel_callbacks), XtRCallback, (XtPointer) NULL},
771444c061aSmrg {XtNsaveCompleteCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
772444c061aSmrg       Offset(session.save_complete_callbacks), XtRCallback, (XtPointer) NULL},
773444c061aSmrg {XtNdieCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
774444c061aSmrg       Offset(session.die_callbacks), XtRCallback, (XtPointer) NULL},
775444c061aSmrg {XtNerrorCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
776444c061aSmrg       Offset(session.error_callbacks), XtRCallback, (XtPointer) NULL}
777444c061aSmrg};
778a3bd7f05Smrg/* *INDENT-ON* */
779444c061aSmrg#undef Offset
780444c061aSmrg
781a3bd7f05Smrgstatic void
782a3bd7f05SmrgSessionInitialize(Widget, Widget, ArgList, Cardinal *);
783a3bd7f05Smrgstatic void
784a3bd7f05SmrgSessionDestroy(Widget);
785a3bd7f05Smrgstatic Boolean
786a3bd7f05SmrgSessionSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
787444c061aSmrg
788a3bd7f05Smrg/* *INDENT-OFF* */
789444c061aSmrgstatic CompositeClassExtensionRec sessionCompositeClassExtension = {
790a3bd7f05Smrg    /* next_extension        */ NULL,
791a3bd7f05Smrg    /* record_type           */ NULLQUARK,
792a3bd7f05Smrg    /* version               */ XtCompositeExtensionVersion,
793a3bd7f05Smrg    /* record_size           */ sizeof(CompositeClassExtensionRec),
794a3bd7f05Smrg    /* accepts_objects       */ TRUE,
795444c061aSmrg    /* allows_change_managed_set */ FALSE
796444c061aSmrg};
797444c061aSmrg
798444c061aSmrgexternaldef(sessionshellclassrec) SessionShellClassRec sessionShellClassRec = {
799444c061aSmrg  {
800a3bd7f05Smrg    /* superclass            */ (WidgetClass) &applicationShellClassRec,
801a3bd7f05Smrg    /* class_name            */ "SessionShell",
802a3bd7f05Smrg    /* size                  */ sizeof(SessionShellRec),
803a3bd7f05Smrg    /* Class Initializer     */ NULL,
804a3bd7f05Smrg    /* class_part_initialize */ NULL,
805a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
806a3bd7f05Smrg    /* initialize            */ SessionInitialize,
807a3bd7f05Smrg    /* initialize_notify     */ NULL,
808a3bd7f05Smrg    /* realize               */ XtInheritRealize,
809a3bd7f05Smrg    /* actions               */ NULL,
810a3bd7f05Smrg    /* num_actions           */ 0,
811a3bd7f05Smrg    /* resources             */ sessionResources,
812a3bd7f05Smrg    /* resource_count        */ XtNumber(sessionResources),
813a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
814a3bd7f05Smrg    /* compress_motion       */ FALSE,
815a3bd7f05Smrg    /* compress_exposure     */ TRUE,
816a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
817a3bd7f05Smrg    /* visible_interest      */ FALSE,
818a3bd7f05Smrg    /* destroy               */ SessionDestroy,
819a3bd7f05Smrg    /* resize                */ XtInheritResize,
820a3bd7f05Smrg    /* expose                */ NULL,
821a3bd7f05Smrg    /* set_values            */ SessionSetValues,
822a3bd7f05Smrg    /* set_values_hook       */ NULL,
823a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
824a3bd7f05Smrg    /* get_values_hook       */ NULL,
825a3bd7f05Smrg    /* accept_focus          */ NULL,
826a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
827a3bd7f05Smrg    /* callback offsets      */ NULL,
828a3bd7f05Smrg    /* tm_table              */ XtInheritTranslations,
829a3bd7f05Smrg    /* query_geometry        */ NULL,
830a3bd7f05Smrg    /* display_accelerator   */ NULL,
831a3bd7f05Smrg    /* extension             */ NULL
832444c061aSmrg  },{
833a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
834a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
835a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
836a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
837a3bd7f05Smrg    /* extension             */ (XtPointer)&sessionCompositeClassExtension
838444c061aSmrg  },{
839a3bd7f05Smrg    /* extension             */ NULL
840444c061aSmrg  },{
841a3bd7f05Smrg    /* extension             */ NULL
842444c061aSmrg  },{
843a3bd7f05Smrg    /* extension             */ NULL
844444c061aSmrg  },{
845a3bd7f05Smrg    /* extension             */ NULL
846444c061aSmrg  },{
847a3bd7f05Smrg    /* extension             */ NULL
848444c061aSmrg  },{
849a3bd7f05Smrg    /* extension             */ NULL
850444c061aSmrg  }
851444c061aSmrg};
852a3bd7f05Smrg/* *INDENT-ON* */
853444c061aSmrg
854a3bd7f05Smrgexternaldef(sessionshellwidgetclass)
855a3bd7f05SmrgWidgetClass sessionShellWidgetClass = (WidgetClass) (&sessionShellClassRec);
856444c061aSmrg
857444c061aSmrg/****************************************************************************
858444c061aSmrg * Whew!
859444c061aSmrg ****************************************************************************/
860444c061aSmrg
861a3bd7f05Smrgstatic void
862a3bd7f05SmrgComputeWMSizeHints(WMShellWidget w, XSizeHints *hints)
863444c061aSmrg{
864444c061aSmrg    register long flags;
865a3bd7f05Smrg
866444c061aSmrg    hints->flags = flags = w->wm.size_hints.flags;
867444c061aSmrg#define copy(field) hints->field = w->wm.size_hints.field
868444c061aSmrg    if (flags & (USPosition | PPosition)) {
869a3bd7f05Smrg        copy(x);
870a3bd7f05Smrg        copy(y);
871444c061aSmrg    }
872444c061aSmrg    if (flags & (USSize | PSize)) {
873a3bd7f05Smrg        copy(width);
874a3bd7f05Smrg        copy(height);
875444c061aSmrg    }
876444c061aSmrg    if (flags & PMinSize) {
877a3bd7f05Smrg        copy(min_width);
878a3bd7f05Smrg        copy(min_height);
879444c061aSmrg    }
880444c061aSmrg    if (flags & PMaxSize) {
881a3bd7f05Smrg        copy(max_width);
882a3bd7f05Smrg        copy(max_height);
883444c061aSmrg    }
884444c061aSmrg    if (flags & PResizeInc) {
885a3bd7f05Smrg        copy(width_inc);
886a3bd7f05Smrg        copy(height_inc);
887444c061aSmrg    }
888444c061aSmrg    if (flags & PAspect) {
889a3bd7f05Smrg        copy(min_aspect.x);
890a3bd7f05Smrg        copy(min_aspect.y);
891a3bd7f05Smrg        copy(max_aspect.x);
892a3bd7f05Smrg        copy(max_aspect.y);
893444c061aSmrg    }
894444c061aSmrg#undef copy
895444c061aSmrg#define copy(field) hints->field = w->wm.field
896444c061aSmrg    if (flags & PBaseSize) {
897a3bd7f05Smrg        copy(base_width);
898a3bd7f05Smrg        copy(base_height);
899444c061aSmrg    }
900444c061aSmrg    if (flags & PWinGravity)
901a3bd7f05Smrg        copy(win_gravity);
902444c061aSmrg#undef copy
903444c061aSmrg}
904444c061aSmrg
905a3bd7f05Smrgstatic void
906a3bd7f05Smrg_SetWMSizeHints(WMShellWidget w)
907444c061aSmrg{
908444c061aSmrg    XSizeHints *size_hints = XAllocSizeHints();
909444c061aSmrg
910a3bd7f05Smrg    if (size_hints == NULL)
911a3bd7f05Smrg        _XtAllocError("XAllocSizeHints");
912444c061aSmrg    ComputeWMSizeHints(w, size_hints);
913a3bd7f05Smrg    XSetWMNormalHints(XtDisplay((Widget) w), XtWindow((Widget) w), size_hints);
914a3bd7f05Smrg    XFree((char *) size_hints);
915444c061aSmrg}
916444c061aSmrg
917a3bd7f05Smrgstatic ShellClassExtension
918a3bd7f05Smrg_FindClassExtension(WidgetClass widget_class)
919444c061aSmrg{
920444c061aSmrg    ShellClassExtension ext;
921a3bd7f05Smrg
922a3bd7f05Smrg    for (ext = (ShellClassExtension) ((ShellWidgetClass) widget_class)
923a3bd7f05Smrg         ->shell_class.extension;
924a3bd7f05Smrg         ext != NULL && ext->record_type != NULLQUARK;
925a3bd7f05Smrg         ext = (ShellClassExtension) ext->next_extension);
926444c061aSmrg
927444c061aSmrg    if (ext != NULL) {
928a3bd7f05Smrg        if (ext->version == XtShellExtensionVersion
929a3bd7f05Smrg            && ext->record_size == sizeof(ShellClassExtensionRec)) {
930a3bd7f05Smrg            /* continue */
931a3bd7f05Smrg        }
932a3bd7f05Smrg        else {
933a3bd7f05Smrg            String params[1];
934a3bd7f05Smrg            Cardinal num_params = 1;
935a3bd7f05Smrg
936a3bd7f05Smrg            params[0] = widget_class->core_class.class_name;
937a3bd7f05Smrg            XtErrorMsg("invalidExtension", "shellClassPartInitialize",
938a3bd7f05Smrg                       XtCXtToolkitError,
939a3bd7f05Smrg                       "widget class %s has invalid ShellClassExtension record",
940a3bd7f05Smrg                       params, &num_params);
941a3bd7f05Smrg        }
942444c061aSmrg    }
943444c061aSmrg    return ext;
944444c061aSmrg}
945444c061aSmrg
946a3bd7f05Smrgstatic void
947a3bd7f05SmrgClassPartInitialize(WidgetClass widget_class)
948444c061aSmrg{
949444c061aSmrg    ShellClassExtension ext = _FindClassExtension(widget_class);
950a3bd7f05Smrg
951444c061aSmrg    if (ext != NULL) {
952a3bd7f05Smrg        if (ext->root_geometry_manager == XtInheritRootGeometryManager) {
953a3bd7f05Smrg            ext->root_geometry_manager =
954a3bd7f05Smrg                _FindClassExtension(widget_class->core_class.superclass)
955a3bd7f05Smrg                ->root_geometry_manager;
956a3bd7f05Smrg        }
957a3bd7f05Smrg    }
958a3bd7f05Smrg    else {
959a3bd7f05Smrg        /* if not found, spec requires XtInheritRootGeometryManager */
960a3bd7f05Smrg        XtPointer *extP
961a3bd7f05Smrg            = &((ShellWidgetClass) widget_class)->shell_class.extension;
962a3bd7f05Smrg        ext = XtNew(ShellClassExtensionRec);
963fdf6a26fSmrg        (void) memcpy(ext,
964fdf6a26fSmrg                      _FindClassExtension(widget_class->core_class.superclass),
965fdf6a26fSmrg                      sizeof(ShellClassExtensionRec));
966a3bd7f05Smrg        ext->next_extension = *extP;
967a3bd7f05Smrg        *extP = (XtPointer) ext;
968a3bd7f05Smrg    }
969a3bd7f05Smrg}
970444c061aSmrg
971a3bd7f05Smrgstatic void EventHandler(Widget wid, XtPointer closure, XEvent *event,
972a3bd7f05Smrg                         Boolean *continue_to_dispatch);
973a3bd7f05Smrgstatic void _popup_set_prop(ShellWidget);
974444c061aSmrg
975a3bd7f05Smrgstatic void
976a3bd7f05SmrgXtCopyDefaultDepth(Widget widget, int offset _X_UNUSED, XrmValue *value)
977444c061aSmrg{
978a3bd7f05Smrg    value->addr = (XPointer) (&DefaultDepthOfScreen(XtScreenOfObject(widget)));
979444c061aSmrg}
980444c061aSmrg
981a3bd7f05Smrgstatic void
982a3bd7f05Smrg_XtShellDepth(Widget widget, int closure, XrmValue *value)
983444c061aSmrg{
984a3bd7f05Smrg    if (widget->core.parent == NULL)
985a3bd7f05Smrg        XtCopyDefaultDepth(widget, closure, value);
986a3bd7f05Smrg    else
987a3bd7f05Smrg        _XtCopyFromParent(widget, closure, value);
988444c061aSmrg}
989444c061aSmrg
990a3bd7f05Smrgstatic void
991a3bd7f05SmrgXtCopyDefaultColormap(Widget widget, int offset _X_UNUSED, XrmValue *value)
992444c061aSmrg{
993a3bd7f05Smrg    value->addr =
994a3bd7f05Smrg        (XPointer) (&DefaultColormapOfScreen(XtScreenOfObject(widget)));
995444c061aSmrg}
996444c061aSmrg
997a3bd7f05Smrgstatic void
998a3bd7f05Smrg_XtShellColormap(Widget widget, int closure, XrmValue *value)
999444c061aSmrg{
1000a3bd7f05Smrg    if (widget->core.parent == NULL)
1001a3bd7f05Smrg        XtCopyDefaultColormap(widget, closure, value);
1002a3bd7f05Smrg    else
1003a3bd7f05Smrg        _XtCopyFromParent(widget, closure, value);
1004444c061aSmrg}
1005444c061aSmrg
1006a3bd7f05Smrgstatic void
1007a3bd7f05Smrg_XtShellAncestorSensitive(Widget widget, int closure, XrmValue *value)
1008444c061aSmrg{
100935525df4Smrg    static Boolean true_value = True;
1010a3bd7f05Smrg
1011a3bd7f05Smrg    if (widget->core.parent == NULL)
101235525df4Smrg        value->addr = (XPointer) (&true_value);
1013a3bd7f05Smrg    else
1014a3bd7f05Smrg        _XtCopyFromParent(widget, closure, value);
1015444c061aSmrg}
1016444c061aSmrg
1017a3bd7f05Smrgstatic void
1018a3bd7f05Smrg_XtTitleEncoding(Widget widget, int offset _X_UNUSED, XrmValue *value)
1019444c061aSmrg{
1020444c061aSmrg    static Atom atom;
1021a3bd7f05Smrg
1022a3bd7f05Smrg    if (XtWidgetToApplicationContext(widget)->langProcRec.proc)
1023a3bd7f05Smrg        atom = None;
1024a3bd7f05Smrg    else
1025a3bd7f05Smrg        atom = XA_STRING;
1026444c061aSmrg    value->addr = (XPointer) &atom;
1027444c061aSmrg}
1028444c061aSmrg
1029a3bd7f05Smrgstatic void
1030a3bd7f05SmrgInitialize(Widget req _X_UNUSED,
1031a3bd7f05Smrg           Widget new,
1032a3bd7f05Smrg           ArgList args _X_UNUSED,
1033a3bd7f05Smrg           Cardinal *num_args _X_UNUSED)
1034444c061aSmrg{
1035a3bd7f05Smrg    ShellWidget w = (ShellWidget) new;
1036444c061aSmrg
1037a3bd7f05Smrg    w->shell.popped_up = FALSE;
1038a3bd7f05Smrg    w->shell.client_specified = _XtShellNotReparented | _XtShellPositionValid;
1039444c061aSmrg
1040a3bd7f05Smrg    if (w->core.x == BIGSIZE) {
1041a3bd7f05Smrg        w->core.x = 0;
1042a3bd7f05Smrg        if (w->core.y == BIGSIZE)
1043a3bd7f05Smrg            w->core.y = 0;
1044a3bd7f05Smrg    }
1045a3bd7f05Smrg    else {
1046a3bd7f05Smrg        if (w->core.y == BIGSIZE)
1047a3bd7f05Smrg            w->core.y = 0;
1048a3bd7f05Smrg        else
1049a3bd7f05Smrg            w->shell.client_specified |= _XtShellPPositionOK;
1050a3bd7f05Smrg    }
1051444c061aSmrg
1052a3bd7f05Smrg    XtAddEventHandler(new, (EventMask) StructureNotifyMask,
1053a3bd7f05Smrg                      TRUE, EventHandler, (XtPointer) NULL);
1054444c061aSmrg
1055444c061aSmrg#ifdef EDITRES
1056a3bd7f05Smrg    XtAddEventHandler(new, (EventMask) 0, TRUE, _XEditResCheckMessages, NULL);
1057444c061aSmrg#endif
1058444c061aSmrg}
1059444c061aSmrg
1060a3bd7f05Smrgstatic void
1061a3bd7f05SmrgWMInitialize(Widget req _X_UNUSED,
1062a3bd7f05Smrg             Widget new,
1063a3bd7f05Smrg             ArgList args _X_UNUSED,
1064a3bd7f05Smrg             Cardinal *num_args _X_UNUSED)
1065444c061aSmrg{
1066a3bd7f05Smrg    WMShellWidget w = (WMShellWidget) new;
1067a3bd7f05Smrg    TopLevelShellWidget tls = (TopLevelShellWidget) new;        /* maybe */
1068444c061aSmrg
1069a3bd7f05Smrg    if (w->wm.title == NULL) {
1070a3bd7f05Smrg        if (XtIsTopLevelShell(new) &&
1071a3bd7f05Smrg            tls->topLevel.icon_name != NULL &&
1072a3bd7f05Smrg            strlen(tls->topLevel.icon_name) != 0) {
1073a3bd7f05Smrg            w->wm.title = XtNewString(tls->topLevel.icon_name);
1074a3bd7f05Smrg        }
1075a3bd7f05Smrg        else {
1076a3bd7f05Smrg            w->wm.title = XtNewString(w->core.name);
1077a3bd7f05Smrg        }
1078a3bd7f05Smrg    }
1079a3bd7f05Smrg    else {
1080a3bd7f05Smrg        w->wm.title = XtNewString(w->wm.title);
1081a3bd7f05Smrg    }
1082a3bd7f05Smrg    w->wm.size_hints.flags = 0;
1083a3bd7f05Smrg    w->wm.wm_hints.flags = 0;
1084a3bd7f05Smrg    if (w->wm.window_role)
1085a3bd7f05Smrg        w->wm.window_role = XtNewString(w->wm.window_role);
1086444c061aSmrg}
1087444c061aSmrg
1088a3bd7f05Smrgstatic void
1089a3bd7f05SmrgTopLevelInitialize(Widget req _X_UNUSED,
1090a3bd7f05Smrg                   Widget new,
1091a3bd7f05Smrg                   ArgList args _X_UNUSED,
1092a3bd7f05Smrg                   Cardinal *num_args _X_UNUSED)
1093444c061aSmrg{
1094a3bd7f05Smrg    TopLevelShellWidget w = (TopLevelShellWidget) new;
1095444c061aSmrg
1096a3bd7f05Smrg    if (w->topLevel.icon_name == NULL) {
1097a3bd7f05Smrg        w->topLevel.icon_name = XtNewString(w->core.name);
1098a3bd7f05Smrg    }
1099a3bd7f05Smrg    else {
1100a3bd7f05Smrg        w->topLevel.icon_name = XtNewString(w->topLevel.icon_name);
1101a3bd7f05Smrg    }
1102444c061aSmrg
1103a3bd7f05Smrg    if (w->topLevel.iconic)
1104a3bd7f05Smrg        w->wm.wm_hints.initial_state = IconicState;
1105444c061aSmrg}
1106444c061aSmrg
11070568f49bSmrgstatic _XtString *NewArgv(int, _XtString *);
11080568f49bSmrgstatic _XtString *NewStringArray(_XtString *);
11090568f49bSmrgstatic void FreeStringArray(_XtString *);
1110444c061aSmrg
1111a3bd7f05Smrgstatic void
1112a3bd7f05SmrgApplicationInitialize(Widget req _X_UNUSED,
1113a3bd7f05Smrg                      Widget new,
1114a3bd7f05Smrg                      ArgList args _X_UNUSED,
1115a3bd7f05Smrg                      Cardinal *num_args _X_UNUSED)
1116444c061aSmrg{
1117a3bd7f05Smrg    ApplicationShellWidget w = (ApplicationShellWidget) new;
1118444c061aSmrg
1119444c061aSmrg    if (w->application.argc > 0)
1120a3bd7f05Smrg        w->application.argv = NewArgv(w->application.argc, w->application.argv);
1121444c061aSmrg}
1122444c061aSmrg
1123444c061aSmrg#define XtSaveInactive 0
1124444c061aSmrg#define XtSaveActive   1
1125444c061aSmrg#define XtInteractPending    2
1126444c061aSmrg#define XtInteractActive     3
1127444c061aSmrg
1128a3bd7f05Smrg#define XtCloneCommandMask      (1L<<0)
1129a3bd7f05Smrg#define XtCurrentDirectoryMask  (1L<<1)
1130a3bd7f05Smrg#define XtDiscardCommandMask    (1L<<2)
1131a3bd7f05Smrg#define XtEnvironmentMask       (1L<<3)
1132a3bd7f05Smrg#define XtProgramMask           (1L<<4)
1133a3bd7f05Smrg#define XtResignCommandMask     (1L<<5)
1134a3bd7f05Smrg#define XtRestartCommandMask    (1L<<6)
1135a3bd7f05Smrg#define XtRestartStyleHintMask  (1L<<7)
1136a3bd7f05Smrg#define XtShutdownCommandMask   (1L<<8)
1137444c061aSmrg
1138444c061aSmrgstatic void JoinSession(SessionShellWidget);
1139a3bd7f05Smrgstatic void SetSessionProperties(SessionShellWidget, Boolean, unsigned long,
1140a3bd7f05Smrg                                 unsigned long);
1141444c061aSmrgstatic void StopManagingSession(SessionShellWidget, SmcConn);
1142444c061aSmrg
1143444c061aSmrgtypedef struct _XtSaveYourselfRec {
1144444c061aSmrg    XtSaveYourself next;
1145a3bd7f05Smrg    int save_type;
1146a3bd7f05Smrg    int interact_style;
1147a3bd7f05Smrg    Boolean shutdown;
1148a3bd7f05Smrg    Boolean fast;
1149a3bd7f05Smrg    Boolean cancel_shutdown;
1150a3bd7f05Smrg    int phase;
1151a3bd7f05Smrg    int interact_dialog_type;
1152a3bd7f05Smrg    Boolean request_cancel;
1153a3bd7f05Smrg    Boolean request_next_phase;
1154a3bd7f05Smrg    Boolean save_success;
1155a3bd7f05Smrg    int save_tokens;
1156a3bd7f05Smrg    int interact_tokens;
1157444c061aSmrg} XtSaveYourselfRec;
1158444c061aSmrg
1159a3bd7f05Smrgstatic void
1160a3bd7f05SmrgSessionInitialize(Widget req _X_UNUSED,
1161a3bd7f05Smrg                  Widget new,
1162a3bd7f05Smrg                  ArgList args _X_UNUSED,
1163a3bd7f05Smrg                  Cardinal *num_args _X_UNUSED)
1164444c061aSmrg{
1165444c061aSmrg#ifndef XT_NO_SM
1166a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) new;
1167a3bd7f05Smrg
1168a3bd7f05Smrg    if (w->session.session_id)
1169a3bd7f05Smrg        w->session.session_id = XtNewString(w->session.session_id);
1170a3bd7f05Smrg    if (w->session.restart_command)
1171a3bd7f05Smrg        w->session.restart_command = NewStringArray(w->session.restart_command);
1172a3bd7f05Smrg    if (w->session.clone_command)
1173a3bd7f05Smrg        w->session.clone_command = NewStringArray(w->session.clone_command);
1174a3bd7f05Smrg    if (w->session.discard_command)
1175a3bd7f05Smrg        w->session.discard_command = NewStringArray(w->session.discard_command);
1176a3bd7f05Smrg    if (w->session.resign_command)
1177a3bd7f05Smrg        w->session.resign_command = NewStringArray(w->session.resign_command);
1178a3bd7f05Smrg    if (w->session.shutdown_command)
1179a3bd7f05Smrg        w->session.shutdown_command =
1180a3bd7f05Smrg            NewStringArray(w->session.shutdown_command);
1181a3bd7f05Smrg    if (w->session.environment)
1182a3bd7f05Smrg        w->session.environment = NewStringArray(w->session.environment);
1183a3bd7f05Smrg    if (w->session.current_dir)
1184a3bd7f05Smrg        w->session.current_dir = XtNewString(w->session.current_dir);
1185a3bd7f05Smrg    if (w->session.program_path)
1186a3bd7f05Smrg        w->session.program_path = XtNewString(w->session.program_path);
1187444c061aSmrg
1188444c061aSmrg    w->session.checkpoint_state = XtSaveInactive;
1189444c061aSmrg    w->session.input_id = 0;
1190444c061aSmrg    w->session.save = NULL;
1191444c061aSmrg
1192444c061aSmrg    if ((w->session.join_session) &&
1193a3bd7f05Smrg        (w->application.argv || w->session.restart_command))
1194a3bd7f05Smrg        JoinSession(w);
1195444c061aSmrg
1196444c061aSmrg    if (w->session.connection)
1197a3bd7f05Smrg        SetSessionProperties(w, True, 0L, 0L);
1198a3bd7f05Smrg#endif                          /* !XT_NO_SM */
1199444c061aSmrg}
1200444c061aSmrg
1201a3bd7f05Smrgstatic void
1202a3bd7f05SmrgResize(Widget w)
1203444c061aSmrg{
1204a3bd7f05Smrg    register ShellWidget sw = (ShellWidget) w;
1205444c061aSmrg    Widget childwid;
1206444c061aSmrg    Cardinal i;
1207a3bd7f05Smrg
1208a3bd7f05Smrg    for (i = 0; i < sw->composite.num_children; i++) {
1209444c061aSmrg        if (XtIsManaged(sw->composite.children[i])) {
1210a3bd7f05Smrg            childwid = sw->composite.children[i];
1211a3bd7f05Smrg            XtResizeWidget(childwid, sw->core.width, sw->core.height,
1212444c061aSmrg                           childwid->core.border_width);
1213a3bd7f05Smrg            break;              /* can only be one managed child */
1214444c061aSmrg        }
1215444c061aSmrg    }
1216444c061aSmrg}
1217444c061aSmrg
1218444c061aSmrgstatic void GetGeometry(Widget, Widget);
1219444c061aSmrg
1220a3bd7f05Smrgstatic void
1221a3bd7f05SmrgRealize(Widget wid, Mask *vmask, XSetWindowAttributes *attr)
1222a3bd7f05Smrg{
1223a3bd7f05Smrg    ShellWidget w = (ShellWidget) wid;
1224a3bd7f05Smrg    Mask mask = *vmask;
1225a3bd7f05Smrg
1226a3bd7f05Smrg    if (!(w->shell.client_specified & _XtShellGeometryParsed)) {
1227a3bd7f05Smrg        /* we'll get here only if there was no child the first
1228a3bd7f05Smrg           time we were realized.  If the shell was Unrealized
1229a3bd7f05Smrg           and then re-Realized, we probably don't want to
1230a3bd7f05Smrg           re-evaluate the defaults anyway.
1231a3bd7f05Smrg         */
1232a3bd7f05Smrg        GetGeometry(wid, (Widget) NULL);
1233a3bd7f05Smrg    }
1234a3bd7f05Smrg    else if (w->core.background_pixmap == XtUnspecifiedPixmap) {
1235a3bd7f05Smrg        /* I attempt to inherit my child's background to avoid screen flash
1236a3bd7f05Smrg         * if there is latency between when I get resized and when my child
1237a3bd7f05Smrg         * is resized.  Background=None is not satisfactory, as I want the
1238a3bd7f05Smrg         * user to get immediate feedback on the new dimensions (most
1239a3bd7f05Smrg         * particularly in the case of a non-reparenting wm).  It is
1240a3bd7f05Smrg         * especially important to have the server clear any old cruft
1241a3bd7f05Smrg         * from the display when I am resized larger.
1242a3bd7f05Smrg         */
1243a3bd7f05Smrg        register Widget *childP = w->composite.children;
1244a3bd7f05Smrg        int i;
1245a3bd7f05Smrg
1246a3bd7f05Smrg        for (i = (int) w->composite.num_children; i; i--, childP++) {
1247a3bd7f05Smrg            if (XtIsWidget(*childP) && XtIsManaged(*childP)) {
1248a3bd7f05Smrg                if ((*childP)->core.background_pixmap != XtUnspecifiedPixmap) {
1249a3bd7f05Smrg                    mask &= (unsigned long) (~(CWBackPixel));
1250a3bd7f05Smrg                    mask |= CWBackPixmap;
1251a3bd7f05Smrg                    attr->background_pixmap =
1252a3bd7f05Smrg                        w->core.background_pixmap =
1253a3bd7f05Smrg                        (*childP)->core.background_pixmap;
1254a3bd7f05Smrg                }
1255a3bd7f05Smrg                else {
1256a3bd7f05Smrg                    attr->background_pixel =
1257a3bd7f05Smrg                        w->core.background_pixel =
1258a3bd7f05Smrg                        (*childP)->core.background_pixel;
1259a3bd7f05Smrg                }
1260a3bd7f05Smrg                break;
1261a3bd7f05Smrg            }
1262a3bd7f05Smrg        }
1263a3bd7f05Smrg    }
1264a3bd7f05Smrg
1265a3bd7f05Smrg    if (w->shell.save_under) {
1266a3bd7f05Smrg        mask |= CWSaveUnder;
1267a3bd7f05Smrg        attr->save_under = TRUE;
1268a3bd7f05Smrg    }
1269a3bd7f05Smrg    if (w->shell.override_redirect) {
1270a3bd7f05Smrg        mask |= CWOverrideRedirect;
1271a3bd7f05Smrg        attr->override_redirect = TRUE;
1272a3bd7f05Smrg    }
1273a3bd7f05Smrg    if (wid->core.width == 0 || wid->core.height == 0) {
1274a3bd7f05Smrg        Cardinal count = 1;
1275a3bd7f05Smrg
1276a3bd7f05Smrg        XtErrorMsg("invalidDimension", "shellRealize", XtCXtToolkitError,
1277a3bd7f05Smrg                   "Shell widget %s has zero width and/or height",
1278a3bd7f05Smrg                   &wid->core.name, &count);
1279a3bd7f05Smrg    }
1280a3bd7f05Smrg    wid->core.window = XCreateWindow(XtDisplay(wid),
1281a3bd7f05Smrg                                     wid->core.screen->root, (int) wid->core.x,
1282a3bd7f05Smrg                                     (int) wid->core.y,
1283a3bd7f05Smrg                                     (unsigned int) wid->core.width,
1284a3bd7f05Smrg                                     (unsigned int) wid->core.height,
1285a3bd7f05Smrg                                     (unsigned int) wid->core.border_width,
1286a3bd7f05Smrg                                     (int) wid->core.depth,
1287a3bd7f05Smrg                                     (unsigned int) InputOutput,
1288a3bd7f05Smrg                                     w->shell.visual, mask, attr);
1289a3bd7f05Smrg
1290a3bd7f05Smrg    _popup_set_prop(w);
1291a3bd7f05Smrg}
1292a3bd7f05Smrg
1293a3bd7f05Smrgstatic void
1294a3bd7f05Smrg_SetTransientForHint(TransientShellWidget w, Boolean delete)
1295444c061aSmrg{
1296444c061aSmrg    Window window_group;
1297444c061aSmrg
1298444c061aSmrg    if (w->wm.transient) {
1299a3bd7f05Smrg        if (w->transient.transient_for != NULL
1300a3bd7f05Smrg            && XtIsRealized(w->transient.transient_for))
1301a3bd7f05Smrg            window_group = XtWindow(w->transient.transient_for);
1302a3bd7f05Smrg        else if ((window_group = w->wm.wm_hints.window_group)
1303a3bd7f05Smrg                 == XtUnspecifiedWindowGroup) {
1304a3bd7f05Smrg            if (delete)
1305a3bd7f05Smrg                XDeleteProperty(XtDisplay((Widget) w),
1306a3bd7f05Smrg                                XtWindow((Widget) w), XA_WM_TRANSIENT_FOR);
1307a3bd7f05Smrg            return;
1308a3bd7f05Smrg        }
1309444c061aSmrg
1310a3bd7f05Smrg        XSetTransientForHint(XtDisplay((Widget) w),
1311a3bd7f05Smrg                             XtWindow((Widget) w), window_group);
1312444c061aSmrg    }
1313444c061aSmrg}
1314444c061aSmrg
1315a3bd7f05Smrgstatic void
1316a3bd7f05SmrgTransientRealize(Widget w, Mask *vmask, XSetWindowAttributes *attr)
1317444c061aSmrg{
1318444c061aSmrg    XtRealizeProc realize;
1319444c061aSmrg
1320444c061aSmrg    LOCK_PROCESS;
1321444c061aSmrg    realize =
1322a3bd7f05Smrg        transientShellWidgetClass->core_class.superclass->core_class.realize;
1323444c061aSmrg    UNLOCK_PROCESS;
1324444c061aSmrg    (*realize) (w, vmask, attr);
1325444c061aSmrg
1326a3bd7f05Smrg    _SetTransientForHint((TransientShellWidget) w, False);
1327444c061aSmrg}
1328444c061aSmrg
1329a3bd7f05Smrgstatic Widget
1330a3bd7f05SmrgGetClientLeader(Widget w)
1331444c061aSmrg{
1332a3bd7f05Smrg    while ((!XtIsWMShell(w) || !((WMShellWidget) w)->wm.client_leader)
1333a3bd7f05Smrg           && w->core.parent)
1334a3bd7f05Smrg        w = w->core.parent;
1335444c061aSmrg
1336444c061aSmrg    /* ASSERT: w is a WMshell with client_leader set, or w has no parent */
1337444c061aSmrg
1338a3bd7f05Smrg    if (XtIsWMShell(w) && ((WMShellWidget) w)->wm.client_leader)
1339a3bd7f05Smrg        w = ((WMShellWidget) w)->wm.client_leader;
1340444c061aSmrg    return w;
1341444c061aSmrg}
1342444c061aSmrg
1343a3bd7f05Smrgstatic void
1344a3bd7f05SmrgEvaluateWMHints(WMShellWidget w)
1345a3bd7f05Smrg{
1346a3bd7f05Smrg    XWMHints *hintp = &w->wm.wm_hints;
1347a3bd7f05Smrg
1348a3bd7f05Smrg    hintp->flags = StateHint | InputHint;
1349a3bd7f05Smrg
1350a3bd7f05Smrg    if (hintp->icon_x == XtUnspecifiedShellInt)
1351a3bd7f05Smrg        hintp->icon_x = -1;
1352a3bd7f05Smrg    else
1353a3bd7f05Smrg        hintp->flags |= IconPositionHint;
1354a3bd7f05Smrg
1355a3bd7f05Smrg    if (hintp->icon_y == XtUnspecifiedShellInt)
1356a3bd7f05Smrg        hintp->icon_y = -1;
1357a3bd7f05Smrg    else
1358a3bd7f05Smrg        hintp->flags |= IconPositionHint;
1359a3bd7f05Smrg
1360a3bd7f05Smrg    if (hintp->icon_pixmap != None)
1361a3bd7f05Smrg        hintp->flags |= IconPixmapHint;
1362a3bd7f05Smrg    if (hintp->icon_mask != None)
1363a3bd7f05Smrg        hintp->flags |= IconMaskHint;
1364a3bd7f05Smrg    if (hintp->icon_window != None)
1365a3bd7f05Smrg        hintp->flags |= IconWindowHint;
1366a3bd7f05Smrg
1367a3bd7f05Smrg    if (hintp->window_group == XtUnspecifiedWindow) {
1368a3bd7f05Smrg        if (w->core.parent) {
1369a3bd7f05Smrg            Widget p;
1370a3bd7f05Smrg
1371a3bd7f05Smrg            for (p = w->core.parent; p->core.parent; p = p->core.parent);
1372a3bd7f05Smrg            if (XtIsRealized(p)) {
1373a3bd7f05Smrg                hintp->window_group = XtWindow(p);
1374a3bd7f05Smrg                hintp->flags |= WindowGroupHint;
1375a3bd7f05Smrg            }
1376a3bd7f05Smrg        }
1377a3bd7f05Smrg    }
1378a3bd7f05Smrg    else if (hintp->window_group != XtUnspecifiedWindowGroup)
1379a3bd7f05Smrg        hintp->flags |= WindowGroupHint;
1380a3bd7f05Smrg
1381a3bd7f05Smrg    if (w->wm.urgency)
1382a3bd7f05Smrg        hintp->flags |= XUrgencyHint;
1383a3bd7f05Smrg}
1384a3bd7f05Smrg
1385a3bd7f05Smrgstatic void
1386a3bd7f05SmrgEvaluateSizeHints(WMShellWidget w)
1387a3bd7f05Smrg{
1388a3bd7f05Smrg    struct _OldXSizeHints *sizep = &w->wm.size_hints;
1389a3bd7f05Smrg
1390a3bd7f05Smrg    sizep->x = w->core.x;
1391a3bd7f05Smrg    sizep->y = w->core.y;
1392a3bd7f05Smrg    sizep->width = w->core.width;
1393a3bd7f05Smrg    sizep->height = w->core.height;
1394a3bd7f05Smrg
1395a3bd7f05Smrg    if (sizep->flags & USSize) {
1396a3bd7f05Smrg        if (sizep->flags & PSize)
1397a3bd7f05Smrg            sizep->flags &= ~PSize;
1398a3bd7f05Smrg    }
1399a3bd7f05Smrg    else
1400a3bd7f05Smrg        sizep->flags |= PSize;
1401a3bd7f05Smrg
1402a3bd7f05Smrg    if (sizep->flags & USPosition) {
1403a3bd7f05Smrg        if (sizep->flags & PPosition)
1404a3bd7f05Smrg            sizep->flags &= ~PPosition;
1405a3bd7f05Smrg    }
1406a3bd7f05Smrg    else if (w->shell.client_specified & _XtShellPPositionOK)
1407a3bd7f05Smrg        sizep->flags |= PPosition;
1408a3bd7f05Smrg
1409a3bd7f05Smrg    if (sizep->min_aspect.x != XtUnspecifiedShellInt
1410a3bd7f05Smrg        || sizep->min_aspect.y != XtUnspecifiedShellInt
1411a3bd7f05Smrg        || sizep->max_aspect.x != XtUnspecifiedShellInt
1412a3bd7f05Smrg        || sizep->max_aspect.y != XtUnspecifiedShellInt) {
1413a3bd7f05Smrg        sizep->flags |= PAspect;
1414a3bd7f05Smrg    }
1415a3bd7f05Smrg    if (sizep->flags & PBaseSize
1416a3bd7f05Smrg        || w->wm.base_width != XtUnspecifiedShellInt
1417a3bd7f05Smrg        || w->wm.base_height != XtUnspecifiedShellInt) {
1418a3bd7f05Smrg        sizep->flags |= PBaseSize;
1419a3bd7f05Smrg        if (w->wm.base_width == XtUnspecifiedShellInt)
1420a3bd7f05Smrg            w->wm.base_width = 0;
1421a3bd7f05Smrg        if (w->wm.base_height == XtUnspecifiedShellInt)
1422a3bd7f05Smrg            w->wm.base_height = 0;
1423a3bd7f05Smrg    }
1424a3bd7f05Smrg    if (sizep->flags & PResizeInc
1425a3bd7f05Smrg        || sizep->width_inc != XtUnspecifiedShellInt
1426a3bd7f05Smrg        || sizep->height_inc != XtUnspecifiedShellInt) {
1427a3bd7f05Smrg        if (sizep->width_inc < 1)
1428a3bd7f05Smrg            sizep->width_inc = 1;
1429a3bd7f05Smrg        if (sizep->height_inc < 1)
1430a3bd7f05Smrg            sizep->height_inc = 1;
1431a3bd7f05Smrg        sizep->flags |= PResizeInc;
1432a3bd7f05Smrg    }
1433a3bd7f05Smrg    if (sizep->flags & PMaxSize
1434a3bd7f05Smrg        || sizep->max_width != XtUnspecifiedShellInt
1435a3bd7f05Smrg        || sizep->max_height != XtUnspecifiedShellInt) {
1436a3bd7f05Smrg        sizep->flags |= PMaxSize;
1437a3bd7f05Smrg        if (sizep->max_width == XtUnspecifiedShellInt)
1438a3bd7f05Smrg            sizep->max_width = BIGSIZE;
1439a3bd7f05Smrg        if (sizep->max_height == XtUnspecifiedShellInt)
1440a3bd7f05Smrg            sizep->max_height = BIGSIZE;
1441a3bd7f05Smrg    }
1442a3bd7f05Smrg    if (sizep->flags & PMinSize
1443a3bd7f05Smrg        || sizep->min_width != XtUnspecifiedShellInt
1444a3bd7f05Smrg        || sizep->min_height != XtUnspecifiedShellInt) {
1445a3bd7f05Smrg        sizep->flags |= PMinSize;
1446a3bd7f05Smrg        if (sizep->min_width == XtUnspecifiedShellInt)
1447a3bd7f05Smrg            sizep->min_width = 1;
1448a3bd7f05Smrg        if (sizep->min_height == XtUnspecifiedShellInt)
1449a3bd7f05Smrg            sizep->min_height = 1;
1450a3bd7f05Smrg    }
1451a3bd7f05Smrg}
1452a3bd7f05Smrg
1453a3bd7f05Smrgstatic void
1454a3bd7f05Smrg_popup_set_prop(ShellWidget w)
1455a3bd7f05Smrg{
1456a3bd7f05Smrg    Widget p;
1457a3bd7f05Smrg    WMShellWidget wmshell = (WMShellWidget) w;
1458a3bd7f05Smrg    TopLevelShellWidget tlshell = (TopLevelShellWidget) w;
1459a3bd7f05Smrg    ApplicationShellWidget appshell = (ApplicationShellWidget) w;
1460a3bd7f05Smrg    XTextProperty icon_name;
1461a3bd7f05Smrg    XTextProperty window_name;
1462a3bd7f05Smrg    char **argv;
1463a3bd7f05Smrg    int argc;
1464a3bd7f05Smrg    XSizeHints *size_hints;
1465a3bd7f05Smrg    Window window_group;
1466a3bd7f05Smrg    XClassHint classhint;
1467a3bd7f05Smrg    Boolean copied_iname, copied_wname;
1468a3bd7f05Smrg
1469a3bd7f05Smrg    if (!XtIsWMShell((Widget) w) || w->shell.override_redirect)
1470a3bd7f05Smrg        return;
1471a3bd7f05Smrg
1472a3bd7f05Smrg    if ((size_hints = XAllocSizeHints()) == NULL)
1473a3bd7f05Smrg        _XtAllocError("XAllocSizeHints");
1474a3bd7f05Smrg
1475a3bd7f05Smrg    copied_iname = copied_wname = False;
1476a3bd7f05Smrg    if (wmshell->wm.title_encoding == None &&
1477a3bd7f05Smrg        XmbTextListToTextProperty(XtDisplay((Widget) w),
1478a3bd7f05Smrg                                  (char **) &wmshell->wm.title,
1479a3bd7f05Smrg                                  1, XStdICCTextStyle,
1480a3bd7f05Smrg                                  &window_name) >= Success) {
1481a3bd7f05Smrg        copied_wname = True;
1482a3bd7f05Smrg    }
1483a3bd7f05Smrg    else {
1484a3bd7f05Smrg        window_name.value = (unsigned char *) wmshell->wm.title;
1485a3bd7f05Smrg        window_name.encoding = wmshell->wm.title_encoding ?
1486a3bd7f05Smrg            wmshell->wm.title_encoding : XA_STRING;
1487a3bd7f05Smrg        window_name.format = 8;
1488a3bd7f05Smrg        window_name.nitems = strlen((char *) window_name.value);
1489a3bd7f05Smrg    }
1490a3bd7f05Smrg
1491a3bd7f05Smrg    if (XtIsTopLevelShell((Widget) w)) {
1492a3bd7f05Smrg        if (tlshell->topLevel.icon_name_encoding == None &&
1493a3bd7f05Smrg            XmbTextListToTextProperty(XtDisplay((Widget) w),
1494a3bd7f05Smrg                                      (char **) &tlshell->topLevel.icon_name,
1495a3bd7f05Smrg                                      1, XStdICCTextStyle,
1496a3bd7f05Smrg                                      &icon_name) >= Success) {
1497a3bd7f05Smrg            copied_iname = True;
1498a3bd7f05Smrg        }
1499a3bd7f05Smrg        else {
1500a3bd7f05Smrg            icon_name.value = (unsigned char *) tlshell->topLevel.icon_name;
1501a3bd7f05Smrg            icon_name.encoding = tlshell->topLevel.icon_name_encoding ?
1502a3bd7f05Smrg                tlshell->topLevel.icon_name_encoding : XA_STRING;
1503a3bd7f05Smrg            icon_name.format = 8;
1504a3bd7f05Smrg            icon_name.nitems = strlen((char *) icon_name.value);
1505a3bd7f05Smrg        }
1506a3bd7f05Smrg    }
1507a3bd7f05Smrg
1508a3bd7f05Smrg    EvaluateWMHints(wmshell);
1509a3bd7f05Smrg    EvaluateSizeHints(wmshell);
1510a3bd7f05Smrg    ComputeWMSizeHints(wmshell, size_hints);
1511a3bd7f05Smrg
1512a3bd7f05Smrg    if (wmshell->wm.transient && !XtIsTransientShell((Widget) w)
1513a3bd7f05Smrg        && (window_group = wmshell->wm.wm_hints.window_group)
1514a3bd7f05Smrg        != XtUnspecifiedWindowGroup) {
1515a3bd7f05Smrg
1516a3bd7f05Smrg        XSetTransientForHint(XtDisplay((Widget) w),
1517a3bd7f05Smrg                             XtWindow((Widget) w), window_group);
1518a3bd7f05Smrg    }
1519a3bd7f05Smrg
1520a3bd7f05Smrg    classhint.res_name = (_XtString) w->core.name;
1521a3bd7f05Smrg    /* For the class, look up to the top of the tree */
1522a3bd7f05Smrg    for (p = (Widget) w; p->core.parent != NULL; p = p->core.parent);
1523a3bd7f05Smrg    if (XtIsApplicationShell(p)) {
1524a3bd7f05Smrg        classhint.res_class = ((ApplicationShellWidget) p)->application.class;
1525a3bd7f05Smrg    }
1526a3bd7f05Smrg    else {
1527a3bd7f05Smrg        LOCK_PROCESS;
1528a3bd7f05Smrg        classhint.res_class = (_XtString) XtClass(p)->core_class.class_name;
1529a3bd7f05Smrg        UNLOCK_PROCESS;
1530a3bd7f05Smrg    }
1531a3bd7f05Smrg
1532a3bd7f05Smrg    if (XtIsApplicationShell((Widget) w)
1533a3bd7f05Smrg        && (argc = appshell->application.argc) != -1)
1534a3bd7f05Smrg        argv = (char **) appshell->application.argv;
1535a3bd7f05Smrg    else {
1536a3bd7f05Smrg        argv = NULL;
1537a3bd7f05Smrg        argc = 0;
1538a3bd7f05Smrg    }
1539a3bd7f05Smrg
1540a3bd7f05Smrg    XSetWMProperties(XtDisplay((Widget) w), XtWindow((Widget) w),
1541a3bd7f05Smrg                     &window_name,
1542a3bd7f05Smrg                     (XtIsTopLevelShell((Widget) w)) ? &icon_name : NULL,
1543a3bd7f05Smrg                     argv, argc, size_hints, &wmshell->wm.wm_hints, &classhint);
1544a3bd7f05Smrg    XFree((char *) size_hints);
1545a3bd7f05Smrg    if (copied_wname)
1546a3bd7f05Smrg        XFree((XPointer) window_name.value);
1547a3bd7f05Smrg    if (copied_iname)
1548a3bd7f05Smrg        XFree((XPointer) icon_name.value);
1549a3bd7f05Smrg
1550a3bd7f05Smrg    LOCK_PROCESS;
1551a3bd7f05Smrg    if (XtWidgetToApplicationContext((Widget) w)->langProcRec.proc) {
1552a3bd7f05Smrg        char *locale = setlocale(LC_CTYPE, (char *) NULL);
1553a3bd7f05Smrg
1554a3bd7f05Smrg        if (locale)
1555a3bd7f05Smrg            XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1556a3bd7f05Smrg                            XInternAtom(XtDisplay((Widget) w),
1557a3bd7f05Smrg                                        "WM_LOCALE_NAME", False),
1558a3bd7f05Smrg                            XA_STRING, 8, PropModeReplace,
1559a3bd7f05Smrg                            (unsigned char *) locale, (int) strlen(locale));
1560a3bd7f05Smrg    }
1561a3bd7f05Smrg    UNLOCK_PROCESS;
1562a3bd7f05Smrg
1563a3bd7f05Smrg    p = GetClientLeader((Widget) w);
1564a3bd7f05Smrg    if (XtWindow(p))
1565a3bd7f05Smrg        XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1566a3bd7f05Smrg                        XInternAtom(XtDisplay((Widget) w),
1567a3bd7f05Smrg                                    "WM_CLIENT_LEADER", False),
1568a3bd7f05Smrg                        XA_WINDOW, 32, PropModeReplace,
1569a3bd7f05Smrg                        (unsigned char *) (&(p->core.window)), 1);
1570444c061aSmrg#ifndef XT_NO_SM
1571a3bd7f05Smrg    if (p == (Widget) w) {
1572a3bd7f05Smrg        for (; p->core.parent != NULL; p = p->core.parent);
1573a3bd7f05Smrg        if (XtIsSubclass(p, sessionShellWidgetClass)) {
1574a3bd7f05Smrg            String sm_client_id = ((SessionShellWidget) p)->session.session_id;
1575a3bd7f05Smrg
1576a3bd7f05Smrg            if (sm_client_id != NULL) {
1577a3bd7f05Smrg                XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1578a3bd7f05Smrg                                XInternAtom(XtDisplay((Widget) w),
1579a3bd7f05Smrg                                            "SM_CLIENT_ID", False),
1580a3bd7f05Smrg                                XA_STRING, 8, PropModeReplace,
1581a3bd7f05Smrg                                (unsigned char *) sm_client_id,
1582a3bd7f05Smrg                                (int) strlen(sm_client_id));
1583a3bd7f05Smrg            }
1584a3bd7f05Smrg        }
1585a3bd7f05Smrg    }
1586a3bd7f05Smrg#endif                          /* !XT_NO_SM */
1587a3bd7f05Smrg
1588a3bd7f05Smrg    if (wmshell->wm.window_role)
1589a3bd7f05Smrg        XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1590a3bd7f05Smrg                        XInternAtom(XtDisplay((Widget) w),
1591a3bd7f05Smrg                                    "WM_WINDOW_ROLE", False),
1592a3bd7f05Smrg                        XA_STRING, 8, PropModeReplace,
1593a3bd7f05Smrg                        (unsigned char *) wmshell->wm.window_role,
1594a3bd7f05Smrg                        (int) strlen(wmshell->wm.window_role));
1595a3bd7f05Smrg}
1596a3bd7f05Smrg
1597a3bd7f05Smrgstatic void
1598a3bd7f05SmrgEventHandler(Widget wid,
1599a3bd7f05Smrg             XtPointer closure _X_UNUSED,
1600a3bd7f05Smrg             XEvent *event,
1601a3bd7f05Smrg             Boolean *continue_to_dispatch _X_UNUSED)
1602a3bd7f05Smrg{
1603a3bd7f05Smrg    register ShellWidget w = (ShellWidget) wid;
1604a3bd7f05Smrg    WMShellWidget wmshell = (WMShellWidget) w;
1605a3bd7f05Smrg    Boolean sizechanged = FALSE;
1606a3bd7f05Smrg
1607a3bd7f05Smrg    if (w->core.window != event->xany.window) {
1608a3bd7f05Smrg        XtAppErrorMsg(XtWidgetToApplicationContext(wid),
1609a3bd7f05Smrg                      "invalidWindow", "eventHandler", XtCXtToolkitError,
1610a3bd7f05Smrg                      "Event with wrong window", NULL, NULL);
1611a3bd7f05Smrg        return;
1612a3bd7f05Smrg    }
1613a3bd7f05Smrg
1614a3bd7f05Smrg    switch (event->type) {
1615a3bd7f05Smrg    case ConfigureNotify:
1616a3bd7f05Smrg        if (w->core.window != event->xconfigure.window)
1617a3bd7f05Smrg            return;             /* in case of SubstructureNotify */
1618a3bd7f05Smrg#define NEQ(x)  ( w->core.x != event->xconfigure.x )
1619a3bd7f05Smrg        if (NEQ(width) || NEQ(height) || NEQ(border_width)) {
1620a3bd7f05Smrg            sizechanged = TRUE;
1621444c061aSmrg#undef NEQ
1622a3bd7f05Smrg            w->core.width = (Dimension) event->xconfigure.width;
1623a3bd7f05Smrg            w->core.height = (Dimension) event->xconfigure.height;
1624a3bd7f05Smrg            w->core.border_width = (Dimension) event->xconfigure.border_width;
1625a3bd7f05Smrg        }
1626a3bd7f05Smrg        if (event->xany.send_event      /* ICCCM compliant synthetic ev */
1627a3bd7f05Smrg            /* || w->shell.override_redirect */
1628a3bd7f05Smrg            || w->shell.client_specified & _XtShellNotReparented) {
1629a3bd7f05Smrg            w->core.x = (Position) event->xconfigure.x;
1630a3bd7f05Smrg            w->core.y = (Position) event->xconfigure.y;
1631a3bd7f05Smrg            w->shell.client_specified |= _XtShellPositionValid;
1632a3bd7f05Smrg        }
1633a3bd7f05Smrg        else
1634a3bd7f05Smrg            w->shell.client_specified &= ~_XtShellPositionValid;
1635a3bd7f05Smrg        if (XtIsWMShell(wid) && !wmshell->wm.wait_for_wm) {
1636a3bd7f05Smrg            /* Consider trusting the wm again */
1637a3bd7f05Smrg            register struct _OldXSizeHints *hintp = &wmshell->wm.size_hints;
1638a3bd7f05Smrg
1639444c061aSmrg#define EQ(x) (hintp->x == w->core.x)
1640a3bd7f05Smrg            if (EQ(x) && EQ(y) && EQ(width) && EQ(height)) {
1641a3bd7f05Smrg                wmshell->wm.wait_for_wm = TRUE;
1642a3bd7f05Smrg            }
1643444c061aSmrg#undef EQ
1644a3bd7f05Smrg        }
1645a3bd7f05Smrg        break;
1646a3bd7f05Smrg
1647a3bd7f05Smrg    case ReparentNotify:
1648a3bd7f05Smrg        if (event->xreparent.window == XtWindow(w)) {
1649a3bd7f05Smrg            if (event->xreparent.parent != RootWindowOfScreen(XtScreen(w)))
1650a3bd7f05Smrg                w->shell.client_specified &=
1651a3bd7f05Smrg                    ~(_XtShellNotReparented | _XtShellPositionValid);
1652a3bd7f05Smrg            else {
1653a3bd7f05Smrg                w->core.x = (Position) event->xreparent.x;
1654a3bd7f05Smrg                w->core.y = (Position) event->xreparent.y;
1655a3bd7f05Smrg                w->shell.client_specified |=
1656a3bd7f05Smrg                    (_XtShellNotReparented | _XtShellPositionValid);
1657a3bd7f05Smrg            }
1658a3bd7f05Smrg        }
1659a3bd7f05Smrg        return;
1660444c061aSmrg
1661a3bd7f05Smrg    case MapNotify:
1662a3bd7f05Smrg        if (XtIsTopLevelShell(wid)) {
1663a3bd7f05Smrg            ((TopLevelShellWidget) wid)->topLevel.iconic = FALSE;
1664a3bd7f05Smrg        }
1665a3bd7f05Smrg        return;
1666444c061aSmrg
1667a3bd7f05Smrg    case UnmapNotify:
1668a3bd7f05Smrg    {
1669a3bd7f05Smrg        XtPerDisplayInput pdi;
1670a3bd7f05Smrg        XtDevice device;
1671a3bd7f05Smrg        Widget p;
1672444c061aSmrg
1673a3bd7f05Smrg        if (XtIsTopLevelShell(wid))
1674a3bd7f05Smrg            ((TopLevelShellWidget) wid)->topLevel.iconic = TRUE;
1675444c061aSmrg
1676a3bd7f05Smrg        pdi = _XtGetPerDisplayInput(event->xunmap.display);
1677444c061aSmrg
1678a3bd7f05Smrg        device = &pdi->pointer;
1679444c061aSmrg
1680a3bd7f05Smrg        if (device->grabType == XtPassiveServerGrab) {
1681a3bd7f05Smrg            p = device->grab.widget;
1682a3bd7f05Smrg            while (p && !(XtIsShell(p)))
1683a3bd7f05Smrg                p = p->core.parent;
1684a3bd7f05Smrg            if (p == wid)
1685a3bd7f05Smrg                device->grabType = XtNoServerGrab;
1686a3bd7f05Smrg        }
1687444c061aSmrg
1688a3bd7f05Smrg        device = &pdi->keyboard;
1689a3bd7f05Smrg        if (IsEitherPassiveGrab(device->grabType)) {
1690a3bd7f05Smrg            p = device->grab.widget;
1691a3bd7f05Smrg            while (p && !(XtIsShell(p)))
1692a3bd7f05Smrg                p = p->core.parent;
1693a3bd7f05Smrg            if (p == wid) {
1694a3bd7f05Smrg                device->grabType = XtNoServerGrab;
1695a3bd7f05Smrg                pdi->activatingKey = 0;
1696a3bd7f05Smrg            }
1697a3bd7f05Smrg        }
1698444c061aSmrg
1699a3bd7f05Smrg        return;
1700a3bd7f05Smrg    }
1701a3bd7f05Smrg    default:
1702a3bd7f05Smrg        return;
1703a3bd7f05Smrg    }
1704a3bd7f05Smrg    {
1705a3bd7f05Smrg        XtWidgetProc resize;
1706a3bd7f05Smrg
1707a3bd7f05Smrg        LOCK_PROCESS;
1708a3bd7f05Smrg        resize = XtClass(wid)->core_class.resize;
1709a3bd7f05Smrg        UNLOCK_PROCESS;
1710a3bd7f05Smrg
1711a3bd7f05Smrg        if (sizechanged && resize) {
1712a3bd7f05Smrg            CALLGEOTAT(_XtGeoTrace((Widget) w,
1713a3bd7f05Smrg                                   "Shell \"%s\" is being resized to %d %d.\n",
1714a3bd7f05Smrg                                   XtName(wid), wid->core.width,
1715a3bd7f05Smrg                                   wid->core.height));
1716a3bd7f05Smrg            (*resize) (wid);
1717a3bd7f05Smrg        }
1718a3bd7f05Smrg    }
1719444c061aSmrg}
1720444c061aSmrg
1721a3bd7f05Smrgstatic void
1722a3bd7f05SmrgDestroy(Widget wid)
1723444c061aSmrg{
1724a3bd7f05Smrg    if (XtIsRealized(wid))
1725a3bd7f05Smrg        XDestroyWindow(XtDisplay(wid), XtWindow(wid));
1726444c061aSmrg}
1727444c061aSmrg
1728a3bd7f05Smrgstatic void
1729a3bd7f05SmrgWMDestroy(Widget wid)
1730444c061aSmrg{
1731a3bd7f05Smrg    WMShellWidget w = (WMShellWidget) wid;
1732444c061aSmrg
1733a3bd7f05Smrg    XtFree((char *) w->wm.title);
1734a3bd7f05Smrg    XtFree((char *) w->wm.window_role);
1735444c061aSmrg}
1736444c061aSmrg
1737a3bd7f05Smrgstatic void
1738a3bd7f05SmrgTopLevelDestroy(Widget wid)
1739444c061aSmrg{
1740a3bd7f05Smrg    TopLevelShellWidget w = (TopLevelShellWidget) wid;
1741444c061aSmrg
1742a3bd7f05Smrg    XtFree((char *) w->topLevel.icon_name);
1743444c061aSmrg}
1744444c061aSmrg
1745a3bd7f05Smrgstatic void
1746a3bd7f05SmrgApplicationDestroy(Widget wid)
1747444c061aSmrg{
1748444c061aSmrg    ApplicationShellWidget w = (ApplicationShellWidget) wid;
1749a3bd7f05Smrg
1750444c061aSmrg    if (w->application.argc > 0)
1751a3bd7f05Smrg        FreeStringArray(w->application.argv);
1752444c061aSmrg}
1753444c061aSmrg
1754a3bd7f05Smrgstatic void
1755a3bd7f05SmrgSessionDestroy(Widget wid)
1756444c061aSmrg{
1757444c061aSmrg#ifndef XT_NO_SM
1758444c061aSmrg    SessionShellWidget w = (SessionShellWidget) wid;
1759444c061aSmrg
1760444c061aSmrg    StopManagingSession(w, w->session.connection);
1761444c061aSmrg    XtFree(w->session.session_id);
1762444c061aSmrg    FreeStringArray(w->session.restart_command);
1763444c061aSmrg    FreeStringArray(w->session.clone_command);
1764444c061aSmrg    FreeStringArray(w->session.discard_command);
1765444c061aSmrg    FreeStringArray(w->session.resign_command);
1766444c061aSmrg    FreeStringArray(w->session.shutdown_command);
1767444c061aSmrg    FreeStringArray(w->session.environment);
1768444c061aSmrg    XtFree(w->session.current_dir);
17690568f49bSmrg    XtFree((_XtString) w->session.program_path);
1770a3bd7f05Smrg#endif                          /* !XT_NO_SM */
1771444c061aSmrg}
1772444c061aSmrg
1773444c061aSmrg/*
1774444c061aSmrg * If the Shell has a width and a height which are zero, and as such
1775444c061aSmrg * suspect, and it has not yet been realized then it will grow to
1776444c061aSmrg * match the child before parsing the geometry resource.
1777444c061aSmrg *
1778444c061aSmrg */
1779a3bd7f05Smrgstatic void
1780a3bd7f05SmrgGetGeometry(Widget W, Widget child)
1781444c061aSmrg{
1782a3bd7f05Smrg    register ShellWidget w = (ShellWidget) W;
1783444c061aSmrg    Boolean is_wmshell = XtIsWMShell(W);
1784444c061aSmrg    int x, y, width, height, win_gravity = -1, flag;
1785444c061aSmrg    XSizeHints hints;
1786444c061aSmrg
1787444c061aSmrg    if (child != NULL) {
1788a3bd7f05Smrg        /* we default to our child's size */
1789a3bd7f05Smrg        if (is_wmshell && (w->core.width == 0 || w->core.height == 0))
1790a3bd7f05Smrg            ((WMShellWidget) W)->wm.size_hints.flags |= PSize;
1791a3bd7f05Smrg        if (w->core.width == 0)
1792a3bd7f05Smrg            w->core.width = child->core.width;
1793a3bd7f05Smrg        if (w->core.height == 0)
1794a3bd7f05Smrg            w->core.height = child->core.height;
1795a3bd7f05Smrg    }
1796a3bd7f05Smrg    if (w->shell.geometry != NULL) {
1797a3bd7f05Smrg        char def_geom[64];
1798a3bd7f05Smrg
1799a3bd7f05Smrg        x = w->core.x;
1800a3bd7f05Smrg        y = w->core.y;
1801a3bd7f05Smrg        width = w->core.width;
1802a3bd7f05Smrg        height = w->core.height;
1803a3bd7f05Smrg        if (is_wmshell) {
1804a3bd7f05Smrg            WMShellPart *wm = &((WMShellWidget) w)->wm;
1805a3bd7f05Smrg
1806a3bd7f05Smrg            EvaluateSizeHints((WMShellWidget) w);
1807fdf6a26fSmrg            (void) memcpy(&hints, &wm->size_hints,
1808fdf6a26fSmrg                          sizeof(struct _OldXSizeHints));
1809a3bd7f05Smrg            hints.win_gravity = wm->win_gravity;
1810a3bd7f05Smrg            if (wm->size_hints.flags & PBaseSize) {
1811a3bd7f05Smrg                width -= wm->base_width;
1812a3bd7f05Smrg                height -= wm->base_height;
1813a3bd7f05Smrg                hints.base_width = wm->base_width;
1814a3bd7f05Smrg                hints.base_height = wm->base_height;
1815a3bd7f05Smrg            }
1816a3bd7f05Smrg            else if (wm->size_hints.flags & PMinSize) {
1817a3bd7f05Smrg                width -= wm->size_hints.min_width;
1818a3bd7f05Smrg                height -= wm->size_hints.min_height;
1819a3bd7f05Smrg            }
1820a3bd7f05Smrg            if (wm->size_hints.flags & PResizeInc) {
1821a3bd7f05Smrg                width /= wm->size_hints.width_inc;
1822a3bd7f05Smrg                height /= wm->size_hints.height_inc;
1823a3bd7f05Smrg            }
1824a3bd7f05Smrg        }
1825a3bd7f05Smrg        else
1826a3bd7f05Smrg            hints.flags = 0;
1827a3bd7f05Smrg
1828a3bd7f05Smrg        snprintf(def_geom, sizeof(def_geom), "%dx%d+%d+%d",
1829a3bd7f05Smrg                 width, height, x, y);
1830a3bd7f05Smrg        flag = XWMGeometry(XtDisplay(W),
1831a3bd7f05Smrg                           XScreenNumberOfScreen(XtScreen(W)),
1832a3bd7f05Smrg                           w->shell.geometry, def_geom,
1833a3bd7f05Smrg                           (unsigned int) w->core.border_width,
1834a3bd7f05Smrg                           &hints, &x, &y, &width, &height, &win_gravity);
1835a3bd7f05Smrg        if (flag) {
1836a3bd7f05Smrg            if (flag & XValue)
1837a3bd7f05Smrg                w->core.x = (Position) x;
1838a3bd7f05Smrg            if (flag & YValue)
1839a3bd7f05Smrg                w->core.y = (Position) y;
1840a3bd7f05Smrg            if (flag & WidthValue)
1841a3bd7f05Smrg                w->core.width = (Dimension) width;
1842a3bd7f05Smrg            if (flag & HeightValue)
1843a3bd7f05Smrg                w->core.height = (Dimension) height;
1844a3bd7f05Smrg        }
1845a3bd7f05Smrg        else {
1846a3bd7f05Smrg            String params[2];
1847a3bd7f05Smrg            Cardinal num_params = 2;
1848a3bd7f05Smrg
1849a3bd7f05Smrg            params[0] = XtName(W);
1850a3bd7f05Smrg            params[1] = w->shell.geometry;
1851a3bd7f05Smrg            XtAppWarningMsg(XtWidgetToApplicationContext(W),
1852a3bd7f05Smrg                            "badGeometry", "shellRealize", XtCXtToolkitError,
1853a3bd7f05Smrg                            "Shell widget \"%s\" has an invalid geometry specification: \"%s\"",
1854a3bd7f05Smrg                            params, &num_params);
1855a3bd7f05Smrg        }
1856444c061aSmrg    }
1857444c061aSmrg    else
1858a3bd7f05Smrg        flag = 0;
1859444c061aSmrg
1860444c061aSmrg    if (is_wmshell) {
1861a3bd7f05Smrg        WMShellWidget wmshell = (WMShellWidget) w;
1862a3bd7f05Smrg
1863a3bd7f05Smrg        if (wmshell->wm.win_gravity == XtUnspecifiedShellInt) {
1864a3bd7f05Smrg            if (win_gravity != -1)
1865a3bd7f05Smrg                wmshell->wm.win_gravity = win_gravity;
1866a3bd7f05Smrg            else
1867a3bd7f05Smrg                wmshell->wm.win_gravity = NorthWestGravity;
1868a3bd7f05Smrg        }
1869a3bd7f05Smrg        wmshell->wm.size_hints.flags |= PWinGravity;
1870a3bd7f05Smrg        if ((flag & (XValue | YValue)) == (XValue | YValue))
1871a3bd7f05Smrg            wmshell->wm.size_hints.flags |= USPosition;
1872a3bd7f05Smrg        if ((flag & (WidthValue | HeightValue)) == (WidthValue | HeightValue))
1873a3bd7f05Smrg            wmshell->wm.size_hints.flags |= USSize;
1874444c061aSmrg    }
1875444c061aSmrg    w->shell.client_specified |= _XtShellGeometryParsed;
1876444c061aSmrg}
1877444c061aSmrg
1878a3bd7f05Smrgstatic void
1879a3bd7f05SmrgChangeManaged(Widget wid)
1880444c061aSmrg{
1881444c061aSmrg    ShellWidget w = (ShellWidget) wid;
1882444c061aSmrg    Widget child = NULL;
1883444c061aSmrg    Cardinal i;
1884444c061aSmrg
1885444c061aSmrg    for (i = 0; i < w->composite.num_children; i++) {
1886a3bd7f05Smrg        if (XtIsManaged(w->composite.children[i])) {
1887a3bd7f05Smrg            child = w->composite.children[i];
1888a3bd7f05Smrg            break;              /* there can only be one of them! */
1889a3bd7f05Smrg        }
1890444c061aSmrg    }
1891444c061aSmrg
1892a3bd7f05Smrg    if (!XtIsRealized(wid))     /* then we're about to be realized... */
1893a3bd7f05Smrg        GetGeometry(wid, child);
1894444c061aSmrg
1895444c061aSmrg    if (child != NULL)
1896a3bd7f05Smrg        XtConfigureWidget(child, (Position) 0, (Position) 0,
1897a3bd7f05Smrg                          w->core.width, w->core.height, (Dimension) 0);
1898444c061aSmrg}
1899444c061aSmrg
1900444c061aSmrg/*
1901444c061aSmrg * This is gross, I can't wait to see if the change happened so I will ask
1902444c061aSmrg * the window manager to change my size and do the appropriate X work.
1903444c061aSmrg * I will then tell the requester that he can.  Care must be taken because
1904444c061aSmrg * it is possible that some time in the future the request will be
1905444c061aSmrg * asynchronusly denied and the window reverted to it's old size/shape.
1906444c061aSmrg */
1907444c061aSmrg
1908a3bd7f05Smrgstatic XtGeometryResult
1909a3bd7f05SmrgGeometryManager(Widget wid,
1910a3bd7f05Smrg                XtWidgetGeometry *request,
1911a3bd7f05Smrg                XtWidgetGeometry *reply _X_UNUSED)
1912a3bd7f05Smrg{
1913a3bd7f05Smrg    ShellWidget shell = (ShellWidget) (wid->core.parent);
1914a3bd7f05Smrg    XtWidgetGeometry my_request;
1915a3bd7f05Smrg
1916a3bd7f05Smrg    if (shell->shell.allow_shell_resize == FALSE && XtIsRealized(wid))
1917a3bd7f05Smrg        return (XtGeometryNo);
1918a3bd7f05Smrg
1919a3bd7f05Smrg    if (request->request_mode & (CWX | CWY))
1920a3bd7f05Smrg        return (XtGeometryNo);
1921a3bd7f05Smrg
1922a3bd7f05Smrg    my_request.request_mode = (request->request_mode & XtCWQueryOnly);
1923a3bd7f05Smrg    if (request->request_mode & CWWidth) {
1924a3bd7f05Smrg        my_request.width = request->width;
1925a3bd7f05Smrg        my_request.request_mode |= CWWidth;
1926a3bd7f05Smrg    }
1927a3bd7f05Smrg    if (request->request_mode & CWHeight) {
1928a3bd7f05Smrg        my_request.height = request->height;
1929a3bd7f05Smrg        my_request.request_mode |= CWHeight;
1930a3bd7f05Smrg    }
1931a3bd7f05Smrg    if (request->request_mode & CWBorderWidth) {
1932a3bd7f05Smrg        my_request.border_width = request->border_width;
1933a3bd7f05Smrg        my_request.request_mode |= CWBorderWidth;
1934a3bd7f05Smrg    }
1935a3bd7f05Smrg    if (XtMakeGeometryRequest((Widget) shell, &my_request, NULL)
1936a3bd7f05Smrg        == XtGeometryYes) {
1937a3bd7f05Smrg        /* assert: if (request->request_mode & CWWidth) then
1938a3bd7f05Smrg         *            shell->core.width == request->width
1939a3bd7f05Smrg         * assert: if (request->request_mode & CWHeight) then
1940a3bd7f05Smrg         *            shell->core.height == request->height
1941a3bd7f05Smrg         *
1942a3bd7f05Smrg         * so, whatever the WM sized us to (if the Shell requested
1943a3bd7f05Smrg         * only one of the two) is now the correct child size
1944a3bd7f05Smrg         */
1945a3bd7f05Smrg
1946a3bd7f05Smrg        if (!(request->request_mode & XtCWQueryOnly)) {
1947a3bd7f05Smrg            wid->core.width = shell->core.width;
1948a3bd7f05Smrg            wid->core.height = shell->core.height;
1949a3bd7f05Smrg            if (request->request_mode & CWBorderWidth) {
1950a3bd7f05Smrg                wid->core.x = wid->core.y = (Position) (-request->border_width);
1951a3bd7f05Smrg            }
1952a3bd7f05Smrg        }
1953a3bd7f05Smrg        return XtGeometryYes;
1954a3bd7f05Smrg    }
1955a3bd7f05Smrg    else
1956a3bd7f05Smrg        return XtGeometryNo;
1957444c061aSmrg}
1958444c061aSmrg
1959444c061aSmrgtypedef struct {
1960a3bd7f05Smrg    Widget w;
1961a3bd7f05Smrg    unsigned long request_num;
1962a3bd7f05Smrg    Boolean done;
1963444c061aSmrg} QueryStruct;
1964444c061aSmrg
1965a3bd7f05Smrgstatic Bool
1966a3bd7f05SmrgisMine(Display *dpy, register XEvent *event, char *arg)
1967a3bd7f05Smrg{
1968a3bd7f05Smrg    QueryStruct *q = (QueryStruct *) arg;
1969a3bd7f05Smrg    register Widget w = q->w;
1970a3bd7f05Smrg
1971a3bd7f05Smrg    if ((dpy != XtDisplay(w)) || (event->xany.window != XtWindow(w))) {
1972a3bd7f05Smrg        return FALSE;
1973a3bd7f05Smrg    }
1974a3bd7f05Smrg    if (event->xany.serial >= q->request_num) {
1975a3bd7f05Smrg        if (event->type == ConfigureNotify) {
1976a3bd7f05Smrg            q->done = TRUE;
1977a3bd7f05Smrg            return TRUE;
1978a3bd7f05Smrg        }
1979a3bd7f05Smrg    }
1980a3bd7f05Smrg    else if (event->type == ConfigureNotify)
1981a3bd7f05Smrg        return TRUE;            /* flush old events */
1982a3bd7f05Smrg    if (event->type == ReparentNotify && event->xreparent.window == XtWindow(w)) {
1983a3bd7f05Smrg        /* we might get ahead of this event, so just in case someone
1984a3bd7f05Smrg         * asks for coordinates before this event is dispatched...
1985a3bd7f05Smrg         */
1986a3bd7f05Smrg        register ShellWidget s = (ShellWidget) w;
1987a3bd7f05Smrg
1988a3bd7f05Smrg        if (event->xreparent.parent != RootWindowOfScreen(XtScreen(w)))
1989a3bd7f05Smrg            s->shell.client_specified &= ~_XtShellNotReparented;
1990a3bd7f05Smrg        else
1991a3bd7f05Smrg            s->shell.client_specified |= _XtShellNotReparented;
1992a3bd7f05Smrg    }
1993a3bd7f05Smrg    return FALSE;
1994a3bd7f05Smrg}
1995a3bd7f05Smrg
1996a3bd7f05Smrgstatic Boolean
1997a3bd7f05Smrg_wait_for_response(ShellWidget w, XEvent *event, unsigned long request_num)
1998a3bd7f05Smrg{
1999a3bd7f05Smrg    XtAppContext app = XtWidgetToApplicationContext((Widget) w);
2000a3bd7f05Smrg    QueryStruct q;
2001a3bd7f05Smrg    unsigned long timeout;
2002a3bd7f05Smrg
2003a3bd7f05Smrg    if (XtIsWMShell((Widget) w))
2004a3bd7f05Smrg        timeout = (unsigned long) ((WMShellWidget) w)->wm.wm_timeout;
2005a3bd7f05Smrg    else
2006a3bd7f05Smrg        timeout = DEFAULT_WM_TIMEOUT;
2007a3bd7f05Smrg
2008a3bd7f05Smrg    XFlush(XtDisplay(w));
2009a3bd7f05Smrg    q.w = (Widget) w;
2010a3bd7f05Smrg    q.request_num = request_num;
2011a3bd7f05Smrg    q.done = FALSE;
2012a3bd7f05Smrg
2013a3bd7f05Smrg    /*
2014a3bd7f05Smrg     * look for match event and discard all prior configures
2015a3bd7f05Smrg     */
2016a3bd7f05Smrg    while (XCheckIfEvent(XtDisplay(w), event, isMine, (char *) &q)) {
2017a3bd7f05Smrg        if (q.done)
2018a3bd7f05Smrg            return TRUE;
2019a3bd7f05Smrg    }
2020a3bd7f05Smrg
2021a3bd7f05Smrg    while (timeout > 0) {
2022a3bd7f05Smrg        if (_XtWaitForSomething(app, FALSE, TRUE, TRUE, TRUE, TRUE,
2023444c061aSmrg#ifdef XTHREADS
2024a3bd7f05Smrg                                FALSE,
2025444c061aSmrg#endif
2026a3bd7f05Smrg                                &timeout) != -1) {
2027a3bd7f05Smrg            while (XCheckIfEvent(XtDisplay(w), event, isMine, (char *) &q)) {
2028a3bd7f05Smrg                if (q.done)
2029a3bd7f05Smrg                    return TRUE;
2030a3bd7f05Smrg            }
2031a3bd7f05Smrg        }
2032a3bd7f05Smrg    }
2033a3bd7f05Smrg    return FALSE;
2034444c061aSmrg}
2035444c061aSmrg
2036a3bd7f05Smrgstatic XtGeometryResult
2037a3bd7f05SmrgRootGeometryManager(Widget gw,
2038a3bd7f05Smrg                    XtWidgetGeometry *request,
2039a3bd7f05Smrg                    XtWidgetGeometry *reply _X_UNUSED)
2040444c061aSmrg{
2041a3bd7f05Smrg    register ShellWidget w = (ShellWidget) gw;
2042444c061aSmrg    XWindowChanges values;
2043444c061aSmrg    unsigned int mask = request->request_mode;
2044444c061aSmrg    XEvent event;
2045444c061aSmrg    Boolean wm;
2046444c061aSmrg    register struct _OldXSizeHints *hintp = NULL;
2047444c061aSmrg    int oldx, oldy, oldwidth, oldheight, oldborder_width;
2048444c061aSmrg    unsigned long request_num;
2049444c061aSmrg
2050444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
2051444c061aSmrg
2052444c061aSmrg    if (XtIsWMShell(gw)) {
2053a3bd7f05Smrg        wm = True;
2054a3bd7f05Smrg        hintp = &((WMShellWidget) w)->wm.size_hints;
2055a3bd7f05Smrg        /* for draft-ICCCM wm's, need to make sure hints reflect
2056a3bd7f05Smrg           (current) reality so client can move and size separately. */
2057a3bd7f05Smrg        hintp->x = w->core.x;
2058a3bd7f05Smrg        hintp->y = w->core.y;
2059a3bd7f05Smrg        hintp->width = w->core.width;
2060a3bd7f05Smrg        hintp->height = w->core.height;
2061a3bd7f05Smrg    }
2062a3bd7f05Smrg    else
2063a3bd7f05Smrg        wm = False;
2064444c061aSmrg
2065444c061aSmrg    oldx = w->core.x;
2066444c061aSmrg    oldy = w->core.y;
2067444c061aSmrg    oldwidth = w->core.width;
2068444c061aSmrg    oldheight = w->core.height;
2069444c061aSmrg    oldborder_width = w->core.border_width;
2070444c061aSmrg
2071444c061aSmrg#define PutBackGeometry() \
2072a3bd7f05Smrg        { w->core.x = (Position) (oldx); \
2073a3bd7f05Smrg          w->core.y = (Position) (oldy); \
2074a3bd7f05Smrg          w->core.width = (Dimension) (oldwidth); \
2075a3bd7f05Smrg          w->core.height = (Dimension) (oldheight); \
2076a3bd7f05Smrg          w->core.border_width = (Dimension) (oldborder_width); }
2077444c061aSmrg
20780568f49bSmrg    memset(&values, 0, sizeof(values));
2079444c061aSmrg    if (mask & CWX) {
2080a3bd7f05Smrg        if (w->core.x == request->x)
2081a3bd7f05Smrg            mask &= (unsigned int) (~CWX);
2082a3bd7f05Smrg        else {
2083a3bd7f05Smrg            w->core.x = (Position) (values.x = request->x);
2084a3bd7f05Smrg            if (wm) {
2085a3bd7f05Smrg                hintp->flags &= ~USPosition;
2086a3bd7f05Smrg                hintp->flags |= PPosition;
2087a3bd7f05Smrg                hintp->x = values.x;
2088a3bd7f05Smrg            }
2089a3bd7f05Smrg        }
2090444c061aSmrg    }
2091444c061aSmrg    if (mask & CWY) {
2092a3bd7f05Smrg        if (w->core.y == request->y)
2093a3bd7f05Smrg            mask &= (unsigned int) (~CWY);
2094a3bd7f05Smrg        else {
2095a3bd7f05Smrg            w->core.y = (Position) (values.y = request->y);
2096a3bd7f05Smrg            if (wm) {
2097a3bd7f05Smrg                hintp->flags &= ~USPosition;
2098a3bd7f05Smrg                hintp->flags |= PPosition;
2099a3bd7f05Smrg                hintp->y = values.y;
2100a3bd7f05Smrg            }
2101a3bd7f05Smrg        }
2102444c061aSmrg    }
2103444c061aSmrg    if (mask & CWBorderWidth) {
2104a3bd7f05Smrg        if (w->core.border_width == request->border_width) {
2105a3bd7f05Smrg            mask &= (unsigned int) (~CWBorderWidth);
2106a3bd7f05Smrg        }
2107a3bd7f05Smrg        else
2108a3bd7f05Smrg            w->core.border_width =
2109a3bd7f05Smrg                (Dimension) (values.border_width = request->border_width);
2110444c061aSmrg    }
2111444c061aSmrg    if (mask & CWWidth) {
2112a3bd7f05Smrg        if (w->core.width == request->width)
2113a3bd7f05Smrg            mask &= (unsigned int) (~CWWidth);
2114a3bd7f05Smrg        else {
2115a3bd7f05Smrg            w->core.width = (Dimension) (values.width = request->width);
2116a3bd7f05Smrg            if (wm) {
2117a3bd7f05Smrg                hintp->flags &= ~USSize;
2118a3bd7f05Smrg                hintp->flags |= PSize;
2119a3bd7f05Smrg                hintp->width = values.width;
2120a3bd7f05Smrg            }
2121a3bd7f05Smrg        }
2122444c061aSmrg    }
2123444c061aSmrg    if (mask & CWHeight) {
2124a3bd7f05Smrg        if (w->core.height == request->height)
2125a3bd7f05Smrg            mask &= (unsigned int) (~CWHeight);
2126a3bd7f05Smrg        else {
2127a3bd7f05Smrg            w->core.height = (Dimension) (values.height = request->height);
2128a3bd7f05Smrg            if (wm) {
2129a3bd7f05Smrg                hintp->flags &= ~USSize;
2130a3bd7f05Smrg                hintp->flags |= PSize;
2131a3bd7f05Smrg                hintp->height = values.height;
2132a3bd7f05Smrg            }
2133a3bd7f05Smrg        }
2134444c061aSmrg    }
2135444c061aSmrg    if (mask & CWStackMode) {
2136a3bd7f05Smrg        values.stack_mode = request->stack_mode;
2137a3bd7f05Smrg        if (mask & CWSibling)
2138a3bd7f05Smrg            values.sibling = XtWindow(request->sibling);
2139444c061aSmrg    }
2140444c061aSmrg
2141a3bd7f05Smrg    if (!XtIsRealized((Widget) w)) {
2142a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w,
2143a3bd7f05Smrg                               "Shell \"%s\" is not realized, return XtGeometryYes.\n",
2144a3bd7f05Smrg                               XtName((Widget) w)));
2145a3bd7f05Smrg        CALLGEOTAT(_XtGeoTab(-1));
2146a3bd7f05Smrg        return XtGeometryYes;
2147444c061aSmrg    }
2148444c061aSmrg
2149444c061aSmrg    request_num = NextRequest(XtDisplay(w));
2150444c061aSmrg
2151a3bd7f05Smrg    CALLGEOTAT(_XtGeoTrace((Widget) w, "XConfiguring the Shell X window :\n"));
2152444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
2153444c061aSmrg#ifdef XT_GEO_TATTLER
2154a3bd7f05Smrg    if (mask & CWX) {
2155a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "x = %d\n", values.x));
2156a3bd7f05Smrg    }
2157a3bd7f05Smrg    if (mask & CWY) {
2158a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "y = %d\n", values.y));
2159a3bd7f05Smrg    }
2160a3bd7f05Smrg    if (mask & CWWidth) {
2161a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "width = %d\n", values.width));
2162a3bd7f05Smrg    }
2163a3bd7f05Smrg    if (mask & CWHeight) {
2164a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "height = %d\n", values.height));
2165a3bd7f05Smrg    }
2166a3bd7f05Smrg    if (mask & CWBorderWidth) {
2167a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w,
2168a3bd7f05Smrg                               "border_width = %d\n", values.border_width));
2169a3bd7f05Smrg    }
2170444c061aSmrg#endif
2171444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
2172444c061aSmrg
2173a3bd7f05Smrg    XConfigureWindow(XtDisplay((Widget) w), XtWindow((Widget) w), mask,
2174a3bd7f05Smrg                     &values);
2175444c061aSmrg
2176444c061aSmrg    if (wm && !w->shell.override_redirect
2177a3bd7f05Smrg        && mask & (CWX | CWY | CWWidth | CWHeight | CWBorderWidth)) {
2178a3bd7f05Smrg        _SetWMSizeHints((WMShellWidget) w);
2179444c061aSmrg    }
2180444c061aSmrg
2181444c061aSmrg    if (w->shell.override_redirect) {
2182a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace
2183a3bd7f05Smrg                   ((Widget) w,
2184a3bd7f05Smrg                    "Shell \"%s\" is override redirect, return XtGeometryYes.\n",
2185a3bd7f05Smrg                    XtName((Widget) w)));
2186a3bd7f05Smrg        CALLGEOTAT(_XtGeoTab(-1));
2187a3bd7f05Smrg        return XtGeometryYes;
2188444c061aSmrg    }
2189444c061aSmrg
2190444c061aSmrg    /* If no non-stacking bits are set, there's no way to tell whether
2191444c061aSmrg       or not this worked, so assume it did */
2192444c061aSmrg
2193a3bd7f05Smrg    if (!(mask & (unsigned) (~(CWStackMode | CWSibling))))
2194a3bd7f05Smrg        return XtGeometryYes;
2195444c061aSmrg
2196a3bd7f05Smrg    if (wm && ((WMShellWidget) w)->wm.wait_for_wm == FALSE) {
2197a3bd7f05Smrg        /* the window manager is sick
2198a3bd7f05Smrg         * so I will do the work and
2199a3bd7f05Smrg         * say no so if a new WM starts up,
2200a3bd7f05Smrg         * or the current one recovers
2201a3bd7f05Smrg         * my size requests will be visible
2202a3bd7f05Smrg         */
2203a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace
2204a3bd7f05Smrg                   ((Widget) w,
2205a3bd7f05Smrg                    "Shell \"%s\" has wait_for_wm == FALSE, return XtGeometryNo.\n",
2206a3bd7f05Smrg                    XtName((Widget) w)));
2207a3bd7f05Smrg        CALLGEOTAT(_XtGeoTab(-1));
2208444c061aSmrg
2209a3bd7f05Smrg        PutBackGeometry();
2210a3bd7f05Smrg        return XtGeometryNo;
2211444c061aSmrg    }
2212444c061aSmrg
2213444c061aSmrg    if (_wait_for_response(w, &event, request_num)) {
2214a3bd7f05Smrg        /* got an event */
2215a3bd7f05Smrg        if (event.type == ConfigureNotify) {
2216444c061aSmrg
2217444c061aSmrg#define NEQ(x, msk) ((mask & msk) && (values.x != event.xconfigure.x))
2218a3bd7f05Smrg            if (NEQ(x, CWX) ||
2219a3bd7f05Smrg                NEQ(y, CWY) ||
2220a3bd7f05Smrg                NEQ(width, CWWidth) ||
2221a3bd7f05Smrg                NEQ(height, CWHeight) || NEQ(border_width, CWBorderWidth)) {
2222444c061aSmrg#ifdef XT_GEO_TATTLER
2223a3bd7f05Smrg                if (NEQ(x, CWX)) {
2224a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2225a3bd7f05Smrg                                           "received Configure X %d\n",
2226a3bd7f05Smrg                                           event.xconfigure.x));
2227a3bd7f05Smrg                }
2228a3bd7f05Smrg                if (NEQ(y, CWY)) {
2229a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2230a3bd7f05Smrg                                           "received Configure Y %d\n",
2231a3bd7f05Smrg                                           event.xconfigure.y));
2232a3bd7f05Smrg                }
2233a3bd7f05Smrg                if (NEQ(width, CWWidth)) {
2234a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2235a3bd7f05Smrg                                           "received Configure Width %d\n",
2236a3bd7f05Smrg                                           event.xconfigure.width));
2237a3bd7f05Smrg                }
2238a3bd7f05Smrg                if (NEQ(height, CWHeight)) {
2239a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2240a3bd7f05Smrg                                           "received Configure Height %d\n",
2241a3bd7f05Smrg                                           event.xconfigure.height));
2242a3bd7f05Smrg                }
2243a3bd7f05Smrg                if (NEQ(border_width, CWBorderWidth)) {
2244a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2245a3bd7f05Smrg                                           "received Configure BorderWidth %d\n",
2246a3bd7f05Smrg                                           event.xconfigure.border_width));
2247a3bd7f05Smrg                }
2248444c061aSmrg#endif
2249444c061aSmrg#undef NEQ
2250a3bd7f05Smrg                XPutBackEvent(XtDisplay(w), &event);
2251a3bd7f05Smrg                PutBackGeometry();
2252a3bd7f05Smrg                /*
2253a3bd7f05Smrg                 * We just potentially re-ordered the event queue
2254a3bd7f05Smrg                 * w.r.t. ConfigureNotifies with some trepidation.
2255a3bd7f05Smrg                 * But this is probably a Good Thing because we
2256a3bd7f05Smrg                 * will know the new true state of the world sooner
2257a3bd7f05Smrg                 * this way.
2258a3bd7f05Smrg                 */
2259a3bd7f05Smrg                CALLGEOTAT(_XtGeoTrace((Widget) w,
2260a3bd7f05Smrg                                       "ConfigureNotify failed, return XtGeometryNo.\n"));
2261a3bd7f05Smrg                CALLGEOTAT(_XtGeoTab(-1));
2262a3bd7f05Smrg
2263a3bd7f05Smrg                return XtGeometryNo;
2264a3bd7f05Smrg            }
2265a3bd7f05Smrg            else {
2266a3bd7f05Smrg                w->core.width = (Dimension) event.xconfigure.width;
2267a3bd7f05Smrg                w->core.height = (Dimension) event.xconfigure.height;
2268a3bd7f05Smrg                w->core.border_width =
2269a3bd7f05Smrg                    (Dimension) event.xconfigure.border_width;
2270a3bd7f05Smrg                if (event.xany.send_event ||    /* ICCCM compliant synth */
2271a3bd7f05Smrg                    w->shell.client_specified & _XtShellNotReparented) {
2272a3bd7f05Smrg
2273a3bd7f05Smrg                    w->core.x = (Position) event.xconfigure.x;
2274a3bd7f05Smrg                    w->core.y = (Position) event.xconfigure.y;
2275a3bd7f05Smrg                    w->shell.client_specified |= _XtShellPositionValid;
2276a3bd7f05Smrg                }
2277a3bd7f05Smrg                else
2278a3bd7f05Smrg                    w->shell.client_specified &= ~_XtShellPositionValid;
2279a3bd7f05Smrg                CALLGEOTAT(_XtGeoTrace((Widget) w,
2280a3bd7f05Smrg                                       "ConfigureNotify succeed, return XtGeometryYes.\n"));
2281a3bd7f05Smrg                CALLGEOTAT(_XtGeoTab(-1));
2282a3bd7f05Smrg                return XtGeometryYes;
2283a3bd7f05Smrg            }
2284a3bd7f05Smrg        }
2285a3bd7f05Smrg        else if (!wm) {
2286a3bd7f05Smrg            PutBackGeometry();
2287a3bd7f05Smrg            CALLGEOTAT(_XtGeoTrace((Widget) w,
2288a3bd7f05Smrg                                   "Not wm, return XtGeometryNo.\n"));
2289a3bd7f05Smrg            CALLGEOTAT(_XtGeoTab(-1));
2290a3bd7f05Smrg            return XtGeometryNo;
2291a3bd7f05Smrg        }
2292a3bd7f05Smrg        else
2293a3bd7f05Smrg            XtAppWarningMsg(XtWidgetToApplicationContext((Widget) w),
2294a3bd7f05Smrg                            "internalError", "shell", XtCXtToolkitError,
2295a3bd7f05Smrg                            "Shell's window manager interaction is broken",
2296a3bd7f05Smrg                            NULL, NULL);
2297a3bd7f05Smrg    }
2298a3bd7f05Smrg    else if (wm) {              /* no event */
2299a3bd7f05Smrg        ((WMShellWidget) w)->wm.wait_for_wm = FALSE;    /* timed out; must be broken */
2300444c061aSmrg    }
2301444c061aSmrg    PutBackGeometry();
2302444c061aSmrg#undef PutBackGeometry
2303a3bd7f05Smrg    CALLGEOTAT(_XtGeoTrace((Widget) w,
2304a3bd7f05Smrg                           "Timeout passed?, return XtGeometryNo.\n"));
2305444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
2306444c061aSmrg    return XtGeometryNo;
2307a3bd7f05Smrg}
2308a3bd7f05Smrg
2309a3bd7f05Smrgstatic Boolean
2310a3bd7f05SmrgSetValues(Widget old,
2311a3bd7f05Smrg          Widget ref _X_UNUSED,
2312a3bd7f05Smrg          Widget new,
2313a3bd7f05Smrg          ArgList args,
2314a3bd7f05Smrg          Cardinal *num_args)
2315a3bd7f05Smrg{
2316a3bd7f05Smrg    ShellWidget nw = (ShellWidget) new;
2317a3bd7f05Smrg    ShellWidget ow = (ShellWidget) old;
2318a3bd7f05Smrg    Mask mask = 0;
2319a3bd7f05Smrg    XSetWindowAttributes attr;
2320a3bd7f05Smrg
2321a3bd7f05Smrg    if (!XtIsRealized(new))
2322a3bd7f05Smrg        return False;
2323a3bd7f05Smrg
2324a3bd7f05Smrg    if (ow->shell.save_under != nw->shell.save_under) {
2325a3bd7f05Smrg        mask = CWSaveUnder;
2326a3bd7f05Smrg        attr.save_under = nw->shell.save_under;
2327a3bd7f05Smrg    }
2328a3bd7f05Smrg
2329a3bd7f05Smrg    if (ow->shell.override_redirect != nw->shell.override_redirect) {
2330a3bd7f05Smrg        mask |= CWOverrideRedirect;
2331a3bd7f05Smrg        attr.override_redirect = nw->shell.override_redirect;
2332a3bd7f05Smrg    }
2333a3bd7f05Smrg
2334a3bd7f05Smrg    if (mask) {
2335a3bd7f05Smrg        XChangeWindowAttributes(XtDisplay(new), XtWindow(new), mask, &attr);
2336a3bd7f05Smrg        if ((mask & CWOverrideRedirect) && !nw->shell.override_redirect)
2337a3bd7f05Smrg            _popup_set_prop(nw);
2338a3bd7f05Smrg    }
2339a3bd7f05Smrg
2340a3bd7f05Smrg    if (!(ow->shell.client_specified & _XtShellPositionValid)) {
2341a3bd7f05Smrg        Cardinal n;
2342a3bd7f05Smrg
2343a3bd7f05Smrg        for (n = *num_args; n; n--, args++) {
2344a3bd7f05Smrg            if (strcmp(XtNx, args->name) == 0) {
2345a3bd7f05Smrg                _XtShellGetCoordinates((Widget) ow, &ow->core.x, &ow->core.y);
2346a3bd7f05Smrg            }
2347a3bd7f05Smrg            else if (strcmp(XtNy, args->name) == 0) {
2348a3bd7f05Smrg                _XtShellGetCoordinates((Widget) ow, &ow->core.x, &ow->core.y);
2349a3bd7f05Smrg            }
2350a3bd7f05Smrg        }
2351a3bd7f05Smrg    }
2352a3bd7f05Smrg    return FALSE;
2353a3bd7f05Smrg}
2354a3bd7f05Smrg
2355a3bd7f05Smrgstatic Boolean
2356a3bd7f05SmrgWMSetValues(Widget old,
2357a3bd7f05Smrg            Widget ref _X_UNUSED,
2358a3bd7f05Smrg            Widget new,
2359a3bd7f05Smrg            ArgList args _X_UNUSED,
2360a3bd7f05Smrg            Cardinal *num_args _X_UNUSED)
2361a3bd7f05Smrg{
2362a3bd7f05Smrg    WMShellWidget nwmshell = (WMShellWidget) new;
2363a3bd7f05Smrg    WMShellWidget owmshell = (WMShellWidget) old;
2364a3bd7f05Smrg    Boolean set_prop = XtIsRealized(new) && !nwmshell->shell.override_redirect;
2365a3bd7f05Smrg    Boolean title_changed;
2366a3bd7f05Smrg
2367a3bd7f05Smrg    EvaluateSizeHints(nwmshell);
2368444c061aSmrg
2369444c061aSmrg#define NEQ(f) (nwmshell->wm.size_hints.f != owmshell->wm.size_hints.f)
2370444c061aSmrg
2371a3bd7f05Smrg    if (set_prop && (NEQ(flags) || NEQ(min_width) || NEQ(min_height)
2372a3bd7f05Smrg                     || NEQ(max_width) || NEQ(max_height)
2373a3bd7f05Smrg                     || NEQ(width_inc) || NEQ(height_inc)
2374a3bd7f05Smrg                     || NEQ(min_aspect.x) || NEQ(min_aspect.y)
2375a3bd7f05Smrg                     || NEQ(max_aspect.x) || NEQ(max_aspect.y)
2376444c061aSmrg#undef NEQ
2377444c061aSmrg#define NEQ(f) (nwmshell->wm.f != owmshell->wm.f)
2378a3bd7f05Smrg                     || NEQ(base_width) || NEQ(base_height) ||
2379a3bd7f05Smrg                     NEQ(win_gravity))) {
2380a3bd7f05Smrg        _SetWMSizeHints(nwmshell);
2381a3bd7f05Smrg    }
2382444c061aSmrg#undef NEQ
2383444c061aSmrg
2384a3bd7f05Smrg    if (nwmshell->wm.title != owmshell->wm.title) {
2385a3bd7f05Smrg        XtFree(owmshell->wm.title);
2386a3bd7f05Smrg        if (!nwmshell->wm.title)
2387a3bd7f05Smrg            nwmshell->wm.title = (_XtString) "";
2388a3bd7f05Smrg        nwmshell->wm.title = XtNewString(nwmshell->wm.title);
2389a3bd7f05Smrg        title_changed = True;
2390a3bd7f05Smrg    }
2391a3bd7f05Smrg    else
2392a3bd7f05Smrg        title_changed = False;
2393a3bd7f05Smrg
2394a3bd7f05Smrg    if (set_prop
2395a3bd7f05Smrg        && (title_changed ||
2396a3bd7f05Smrg            nwmshell->wm.title_encoding != owmshell->wm.title_encoding)) {
2397a3bd7f05Smrg
2398a3bd7f05Smrg        XTextProperty title;
2399a3bd7f05Smrg        Boolean copied = False;
2400a3bd7f05Smrg
2401a3bd7f05Smrg        if (nwmshell->wm.title_encoding == None &&
2402a3bd7f05Smrg            XmbTextListToTextProperty(XtDisplay(new),
2403a3bd7f05Smrg                                      (char **) &nwmshell->wm.title,
2404a3bd7f05Smrg                                      1, XStdICCTextStyle, &title) >= Success) {
2405a3bd7f05Smrg            copied = True;
2406a3bd7f05Smrg        }
2407a3bd7f05Smrg        else {
2408a3bd7f05Smrg            title.value = (unsigned char *) nwmshell->wm.title;
2409a3bd7f05Smrg            title.encoding = nwmshell->wm.title_encoding ?
2410a3bd7f05Smrg                nwmshell->wm.title_encoding : XA_STRING;
2411a3bd7f05Smrg            title.format = 8;
2412a3bd7f05Smrg            title.nitems = strlen(nwmshell->wm.title);
2413a3bd7f05Smrg        }
2414a3bd7f05Smrg        XSetWMName(XtDisplay(new), XtWindow(new), &title);
2415a3bd7f05Smrg        if (copied)
2416a3bd7f05Smrg            XFree((XPointer) title.value);
2417a3bd7f05Smrg    }
2418a3bd7f05Smrg
2419a3bd7f05Smrg    EvaluateWMHints(nwmshell);
2420a3bd7f05Smrg
2421a3bd7f05Smrg#define NEQ(f)  (nwmshell->wm.wm_hints.f != owmshell->wm.wm_hints.f)
2422a3bd7f05Smrg
2423a3bd7f05Smrg    if (set_prop && (NEQ(flags) || NEQ(input) || NEQ(initial_state)
2424a3bd7f05Smrg                     || NEQ(icon_x) || NEQ(icon_y)
2425a3bd7f05Smrg                     || NEQ(icon_pixmap) || NEQ(icon_mask) || NEQ(icon_window)
2426a3bd7f05Smrg                     || NEQ(window_group))) {
2427a3bd7f05Smrg
2428a3bd7f05Smrg        XSetWMHints(XtDisplay(new), XtWindow(new), &nwmshell->wm.wm_hints);
2429a3bd7f05Smrg    }
2430444c061aSmrg#undef NEQ
2431444c061aSmrg
2432a3bd7f05Smrg    if (XtIsRealized(new) && nwmshell->wm.transient != owmshell->wm.transient) {
2433a3bd7f05Smrg        if (nwmshell->wm.transient) {
2434a3bd7f05Smrg            if (!XtIsTransientShell(new) &&
2435a3bd7f05Smrg                !nwmshell->shell.override_redirect &&
2436a3bd7f05Smrg                nwmshell->wm.wm_hints.window_group != XtUnspecifiedWindowGroup)
2437a3bd7f05Smrg                XSetTransientForHint(XtDisplay(new), XtWindow(new),
2438a3bd7f05Smrg                                     nwmshell->wm.wm_hints.window_group);
2439a3bd7f05Smrg        }
2440a3bd7f05Smrg        else
2441a3bd7f05Smrg            XDeleteProperty(XtDisplay(new), XtWindow(new), XA_WM_TRANSIENT_FOR);
2442a3bd7f05Smrg    }
2443a3bd7f05Smrg
2444a3bd7f05Smrg    if (nwmshell->wm.client_leader != owmshell->wm.client_leader
2445a3bd7f05Smrg        && XtWindow(new) && !nwmshell->shell.override_redirect) {
2446a3bd7f05Smrg        Widget leader = GetClientLeader(new);
2447a3bd7f05Smrg
2448a3bd7f05Smrg        if (XtWindow(leader))
2449a3bd7f05Smrg            XChangeProperty(XtDisplay(new), XtWindow(new),
2450a3bd7f05Smrg                            XInternAtom(XtDisplay(new),
2451a3bd7f05Smrg                                        "WM_CLIENT_LEADER", False),
2452a3bd7f05Smrg                            XA_WINDOW, 32, PropModeReplace,
2453a3bd7f05Smrg                            (unsigned char *) &(leader->core.window), 1);
2454a3bd7f05Smrg    }
2455a3bd7f05Smrg
2456a3bd7f05Smrg    if (nwmshell->wm.window_role != owmshell->wm.window_role) {
2457a3bd7f05Smrg        XtFree((_XtString) owmshell->wm.window_role);
2458a3bd7f05Smrg        if (set_prop && nwmshell->wm.window_role) {
2459a3bd7f05Smrg            XChangeProperty(XtDisplay(new), XtWindow(new),
2460a3bd7f05Smrg                            XInternAtom(XtDisplay(new), "WM_WINDOW_ROLE",
2461a3bd7f05Smrg                                        False),
2462a3bd7f05Smrg                            XA_STRING, 8, PropModeReplace,
2463a3bd7f05Smrg                            (unsigned char *) nwmshell->wm.window_role,
2464a3bd7f05Smrg                            (int) strlen(nwmshell->wm.window_role));
2465a3bd7f05Smrg        }
2466a3bd7f05Smrg        else if (XtIsRealized(new) && !nwmshell->wm.window_role) {
2467a3bd7f05Smrg            XDeleteProperty(XtDisplay(new), XtWindow(new),
2468a3bd7f05Smrg                            XInternAtom(XtDisplay(new), "WM_WINDOW_ROLE",
2469a3bd7f05Smrg                                        False));
2470a3bd7f05Smrg        }
2471a3bd7f05Smrg    }
2472a3bd7f05Smrg
2473a3bd7f05Smrg    return FALSE;
2474a3bd7f05Smrg}
2475a3bd7f05Smrg
2476a3bd7f05Smrgstatic Boolean
2477a3bd7f05SmrgTransientSetValues(Widget oldW,
2478a3bd7f05Smrg                   Widget refW _X_UNUSED,
2479a3bd7f05Smrg                   Widget newW,
2480a3bd7f05Smrg                   ArgList args _X_UNUSED,
2481a3bd7f05Smrg                   Cardinal *num_args _X_UNUSED)
2482a3bd7f05Smrg{
2483a3bd7f05Smrg    TransientShellWidget old = (TransientShellWidget) oldW;
2484a3bd7f05Smrg    TransientShellWidget new = (TransientShellWidget) newW;
2485444c061aSmrg
2486444c061aSmrg    if (XtIsRealized(newW)
2487a3bd7f05Smrg        && ((new->wm.transient && !old->wm.transient)
2488a3bd7f05Smrg            || ((new->transient.transient_for != old->transient.transient_for)
2489a3bd7f05Smrg                || (new->transient.transient_for == NULL
2490a3bd7f05Smrg                    && (new->wm.wm_hints.window_group
2491a3bd7f05Smrg                        != old->wm.wm_hints.window_group))))) {
2492444c061aSmrg
2493a3bd7f05Smrg        _SetTransientForHint(new, True);
2494444c061aSmrg    }
2495444c061aSmrg    return False;
2496444c061aSmrg}
2497444c061aSmrg
2498a3bd7f05Smrgstatic Boolean
2499a3bd7f05SmrgTopLevelSetValues(Widget oldW,
2500a3bd7f05Smrg                  Widget refW _X_UNUSED,
2501a3bd7f05Smrg                  Widget newW,
2502a3bd7f05Smrg                  ArgList args _X_UNUSED,
2503a3bd7f05Smrg                  Cardinal *num_args _X_UNUSED)
2504444c061aSmrg{
2505a3bd7f05Smrg    TopLevelShellWidget old = (TopLevelShellWidget) oldW;
2506a3bd7f05Smrg    TopLevelShellWidget new = (TopLevelShellWidget) newW;
2507444c061aSmrg    Boolean name_changed;
2508444c061aSmrg
2509444c061aSmrg    if (old->topLevel.icon_name != new->topLevel.icon_name) {
2510a3bd7f05Smrg        XtFree((XtPointer) old->topLevel.icon_name);
2511a3bd7f05Smrg        if (!new->topLevel.icon_name)
2512a3bd7f05Smrg            new->topLevel.icon_name = (_XtString) "";
2513a3bd7f05Smrg        new->topLevel.icon_name = XtNewString(new->topLevel.icon_name);
2514a3bd7f05Smrg        name_changed = True;
2515a3bd7f05Smrg    }
2516a3bd7f05Smrg    else
2517a3bd7f05Smrg        name_changed = False;
2518444c061aSmrg
2519444c061aSmrg    if (XtIsRealized(newW)) {
2520a3bd7f05Smrg        if (new->topLevel.iconic != old->topLevel.iconic) {
2521a3bd7f05Smrg            if (new->topLevel.iconic)
2522a3bd7f05Smrg                XIconifyWindow(XtDisplay(newW),
2523a3bd7f05Smrg                               XtWindow(newW),
2524a3bd7f05Smrg                               XScreenNumberOfScreen(XtScreen(newW))
2525a3bd7f05Smrg                    );
2526a3bd7f05Smrg            else {
2527a3bd7f05Smrg                Boolean map = new->shell.popped_up;
2528a3bd7f05Smrg
2529a3bd7f05Smrg                XtPopup(newW, XtGrabNone);
2530a3bd7f05Smrg                if (map)
2531a3bd7f05Smrg                    XMapWindow(XtDisplay(newW), XtWindow(newW));
2532a3bd7f05Smrg            }
2533a3bd7f05Smrg        }
2534a3bd7f05Smrg
2535a3bd7f05Smrg        if (!new->shell.override_redirect &&
2536a3bd7f05Smrg            (name_changed ||
2537a3bd7f05Smrg             (old->topLevel.icon_name_encoding
2538a3bd7f05Smrg              != new->topLevel.icon_name_encoding))) {
2539a3bd7f05Smrg
2540a3bd7f05Smrg            XTextProperty icon_name;
2541a3bd7f05Smrg            Boolean copied = False;
2542444c061aSmrg
2543444c061aSmrg            if (new->topLevel.icon_name_encoding == None &&
2544a3bd7f05Smrg                XmbTextListToTextProperty(XtDisplay(newW),
2545a3bd7f05Smrg                                          (char **) &new->topLevel.icon_name,
2546a3bd7f05Smrg                                          1, XStdICCTextStyle,
2547a3bd7f05Smrg                                          &icon_name) >= Success) {
2548a3bd7f05Smrg                copied = True;
2549a3bd7f05Smrg            }
2550a3bd7f05Smrg            else {
2551a3bd7f05Smrg                icon_name.value = (unsigned char *) new->topLevel.icon_name;
2552a3bd7f05Smrg                icon_name.encoding = new->topLevel.icon_name_encoding ?
2553a3bd7f05Smrg                    new->topLevel.icon_name_encoding : XA_STRING;
2554a3bd7f05Smrg                icon_name.format = 8;
2555a3bd7f05Smrg                icon_name.nitems = strlen((char *) icon_name.value);
2556a3bd7f05Smrg            }
2557a3bd7f05Smrg            XSetWMIconName(XtDisplay(newW), XtWindow(newW), &icon_name);
2558a3bd7f05Smrg            if (copied)
2559a3bd7f05Smrg                XFree((XPointer) icon_name.value);
2560a3bd7f05Smrg        }
2561444c061aSmrg    }
2562bdf0f55dSmrg    else if (new->topLevel.iconic != old->topLevel.iconic) {
2563a3bd7f05Smrg        if (new->topLevel.iconic)
2564a3bd7f05Smrg            new->wm.wm_hints.initial_state = IconicState;
2565bdf0f55dSmrg    }
2566444c061aSmrg    return False;
2567444c061aSmrg}
2568444c061aSmrg
2569a3bd7f05Smrg/* do not assume it's terminated by a NULL element */
2570a3bd7f05Smrgstatic _XtString *
2571a3bd7f05SmrgNewArgv(int count, _XtString *str)
2572a3bd7f05Smrg{
2573444c061aSmrg    Cardinal nbytes = 0;
2574444c061aSmrg    Cardinal num = 0;
25750568f49bSmrg    _XtString *newarray;
25760568f49bSmrg    _XtString *new;
25770568f49bSmrg    _XtString *strarray = str;
25780568f49bSmrg    _XtString sptr;
2579444c061aSmrg
2580a3bd7f05Smrg    if (count <= 0 || !str)
2581a3bd7f05Smrg        return NULL;
2582444c061aSmrg
25830568f49bSmrg    for (num = (Cardinal) count; num--; str++) {
2584a3bd7f05Smrg        nbytes = (nbytes + (Cardinal) strlen(*str));
2585a3bd7f05Smrg        nbytes++;
2586444c061aSmrg    }
2587a3bd7f05Smrg    num = (Cardinal) ((size_t) (count + 1) * sizeof(_XtString));
25880568f49bSmrg    new = newarray = (_XtString *) __XtMalloc(num + nbytes);
2589444c061aSmrg    sptr = ((char *) new) + num;
2590444c061aSmrg
2591444c061aSmrg    for (str = strarray; count--; str++) {
2592a3bd7f05Smrg        *new = sptr;
2593a3bd7f05Smrg        strcpy(*new, *str);
2594a3bd7f05Smrg        new++;
2595a3bd7f05Smrg        sptr = strchr(sptr, '\0');
2596a3bd7f05Smrg        sptr++;
2597444c061aSmrg    }
2598444c061aSmrg    *new = NULL;
2599444c061aSmrg    return newarray;
2600444c061aSmrg}
2601444c061aSmrg
2602a3bd7f05Smrgstatic Boolean
2603a3bd7f05SmrgApplicationSetValues(Widget current,
2604a3bd7f05Smrg                     Widget request _X_UNUSED,
2605a3bd7f05Smrg                     Widget new,
2606a3bd7f05Smrg                     ArgList args _X_UNUSED,
2607a3bd7f05Smrg                     Cardinal *num_args _X_UNUSED)
2608444c061aSmrg{
2609444c061aSmrg    ApplicationShellWidget nw = (ApplicationShellWidget) new;
2610444c061aSmrg    ApplicationShellWidget cw = (ApplicationShellWidget) current;
2611444c061aSmrg
2612444c061aSmrg    if (cw->application.argc != nw->application.argc ||
2613a3bd7f05Smrg        cw->application.argv != nw->application.argv) {
2614a3bd7f05Smrg
2615a3bd7f05Smrg        if (nw->application.argc > 0)
2616a3bd7f05Smrg            nw->application.argv = NewArgv(nw->application.argc,
2617a3bd7f05Smrg                                           nw->application.argv);
2618a3bd7f05Smrg        if (cw->application.argc > 0)
2619a3bd7f05Smrg            FreeStringArray(cw->application.argv);
2620a3bd7f05Smrg
2621a3bd7f05Smrg        if (XtIsRealized(new) && !nw->shell.override_redirect) {
2622a3bd7f05Smrg            if (nw->application.argc >= 0 && nw->application.argv)
2623a3bd7f05Smrg                XSetCommand(XtDisplay(new), XtWindow(new),
2624a3bd7f05Smrg                            nw->application.argv, nw->application.argc);
2625a3bd7f05Smrg            else
2626a3bd7f05Smrg                XDeleteProperty(XtDisplay(new), XtWindow(new), XA_WM_COMMAND);
2627a3bd7f05Smrg        }
2628444c061aSmrg    }
2629444c061aSmrg    return False;
2630444c061aSmrg}
2631444c061aSmrg
2632a3bd7f05Smrgstatic Boolean
2633a3bd7f05SmrgSessionSetValues(Widget current,
2634a3bd7f05Smrg                 Widget request _X_UNUSED,
2635a3bd7f05Smrg                 Widget new,
2636a3bd7f05Smrg                 ArgList args _X_UNUSED,
2637a3bd7f05Smrg                 Cardinal *num_args _X_UNUSED)
2638444c061aSmrg{
2639444c061aSmrg#ifndef XT_NO_SM
2640444c061aSmrg    SessionShellWidget nw = (SessionShellWidget) new;
2641444c061aSmrg    SessionShellWidget cw = (SessionShellWidget) current;
2642444c061aSmrg    unsigned long set_mask = 0UL;
2643444c061aSmrg    unsigned long unset_mask = 0UL;
2644444c061aSmrg    Boolean initialize = False;
2645444c061aSmrg
2646444c061aSmrg    if (cw->session.session_id != nw->session.session_id) {
2647a3bd7f05Smrg        nw->session.session_id = XtNewString(nw->session.session_id);
2648a3bd7f05Smrg        XtFree(cw->session.session_id);
2649444c061aSmrg    }
2650444c061aSmrg
2651444c061aSmrg    if (cw->session.clone_command != nw->session.clone_command) {
2652a3bd7f05Smrg        if (nw->session.clone_command) {
2653a3bd7f05Smrg            nw->session.clone_command =
2654a3bd7f05Smrg                NewStringArray(nw->session.clone_command);
2655a3bd7f05Smrg            set_mask |= XtCloneCommandMask;
2656a3bd7f05Smrg        }
2657a3bd7f05Smrg        else
2658a3bd7f05Smrg            unset_mask |= XtCloneCommandMask;
2659a3bd7f05Smrg        FreeStringArray(cw->session.clone_command);
2660444c061aSmrg    }
2661444c061aSmrg
2662444c061aSmrg    if (cw->session.current_dir != nw->session.current_dir) {
2663a3bd7f05Smrg        if (nw->session.current_dir) {
2664a3bd7f05Smrg            nw->session.current_dir = XtNewString(nw->session.current_dir);
2665a3bd7f05Smrg            set_mask |= XtCurrentDirectoryMask;
2666a3bd7f05Smrg        }
2667a3bd7f05Smrg        else
2668a3bd7f05Smrg            unset_mask |= XtCurrentDirectoryMask;
2669a3bd7f05Smrg        XtFree((char *) cw->session.current_dir);
2670444c061aSmrg    }
2671444c061aSmrg
2672444c061aSmrg    if (cw->session.discard_command != nw->session.discard_command) {
2673a3bd7f05Smrg        if (nw->session.discard_command) {
2674a3bd7f05Smrg            nw->session.discard_command =
2675a3bd7f05Smrg                NewStringArray(nw->session.discard_command);
2676a3bd7f05Smrg            set_mask |= XtDiscardCommandMask;
2677a3bd7f05Smrg        }
2678a3bd7f05Smrg        else
2679a3bd7f05Smrg            unset_mask |= XtDiscardCommandMask;
2680a3bd7f05Smrg        FreeStringArray(cw->session.discard_command);
2681444c061aSmrg    }
2682444c061aSmrg
2683444c061aSmrg    if (cw->session.environment != nw->session.environment) {
2684a3bd7f05Smrg        if (nw->session.environment) {
2685a3bd7f05Smrg            nw->session.environment = NewStringArray(nw->session.environment);
2686a3bd7f05Smrg            set_mask |= XtEnvironmentMask;
2687a3bd7f05Smrg        }
2688a3bd7f05Smrg        else
2689a3bd7f05Smrg            unset_mask |= XtEnvironmentMask;
2690a3bd7f05Smrg        FreeStringArray(cw->session.environment);
2691444c061aSmrg    }
2692444c061aSmrg
2693444c061aSmrg    if (cw->session.program_path != nw->session.program_path) {
2694a3bd7f05Smrg        if (nw->session.program_path) {
2695a3bd7f05Smrg            nw->session.program_path = XtNewString(nw->session.program_path);
2696a3bd7f05Smrg            set_mask |= XtProgramMask;
2697a3bd7f05Smrg        }
2698a3bd7f05Smrg        else
2699a3bd7f05Smrg            unset_mask |= XtProgramMask;
2700a3bd7f05Smrg        XtFree((char *) cw->session.program_path);
2701444c061aSmrg    }
2702444c061aSmrg
2703444c061aSmrg    if (cw->session.resign_command != nw->session.resign_command) {
2704a3bd7f05Smrg        if (nw->session.resign_command) {
2705a3bd7f05Smrg            nw->session.resign_command =
2706a3bd7f05Smrg                NewStringArray(nw->session.resign_command);
2707a3bd7f05Smrg            set_mask |= XtResignCommandMask;
2708a3bd7f05Smrg        }
2709a3bd7f05Smrg        else
2710a3bd7f05Smrg            set_mask |= XtResignCommandMask;
2711a3bd7f05Smrg        FreeStringArray(cw->session.resign_command);
2712444c061aSmrg    }
2713444c061aSmrg
2714444c061aSmrg    if (cw->session.restart_command != nw->session.restart_command) {
2715a3bd7f05Smrg        if (nw->session.restart_command) {
2716a3bd7f05Smrg            nw->session.restart_command =
2717a3bd7f05Smrg                NewStringArray(nw->session.restart_command);
2718a3bd7f05Smrg            set_mask |= XtRestartCommandMask;
2719a3bd7f05Smrg        }
2720a3bd7f05Smrg        else
2721a3bd7f05Smrg            unset_mask |= XtRestartCommandMask;
2722a3bd7f05Smrg        FreeStringArray(cw->session.restart_command);
2723444c061aSmrg    }
2724444c061aSmrg
2725444c061aSmrg    if (cw->session.restart_style != nw->session.restart_style)
2726a3bd7f05Smrg        set_mask |= XtRestartStyleHintMask;
2727444c061aSmrg
2728444c061aSmrg    if (cw->session.shutdown_command != nw->session.shutdown_command) {
2729a3bd7f05Smrg        if (nw->session.shutdown_command) {
2730a3bd7f05Smrg            nw->session.shutdown_command =
2731a3bd7f05Smrg                NewStringArray(nw->session.shutdown_command);
2732a3bd7f05Smrg            set_mask |= XtShutdownCommandMask;
2733a3bd7f05Smrg        }
2734a3bd7f05Smrg        else
2735a3bd7f05Smrg            unset_mask |= XtShutdownCommandMask;
2736a3bd7f05Smrg        FreeStringArray(cw->session.shutdown_command);
2737444c061aSmrg    }
2738444c061aSmrg
2739444c061aSmrg    if ((!cw->session.join_session && nw->session.join_session) ||
2740a3bd7f05Smrg        (!cw->session.connection && nw->session.connection)) {
2741a3bd7f05Smrg        JoinSession(nw);
2742a3bd7f05Smrg        initialize = True;
2743444c061aSmrg    }
2744444c061aSmrg
2745444c061aSmrg    if (nw->session.connection && (set_mask || unset_mask || initialize))
2746a3bd7f05Smrg        SetSessionProperties((SessionShellWidget) new, initialize, set_mask,
2747a3bd7f05Smrg                             unset_mask);
2748444c061aSmrg
2749444c061aSmrg    if ((cw->session.join_session && !nw->session.join_session) ||
2750a3bd7f05Smrg        (cw->session.connection && !nw->session.connection))
2751a3bd7f05Smrg        StopManagingSession(nw, nw->session.connection);
2752a3bd7f05Smrg#endif                          /* !XT_NO_SM */
2753444c061aSmrg
2754444c061aSmrg    if (cw->wm.client_leader != nw->wm.client_leader ||
2755a3bd7f05Smrg        cw->session.session_id != nw->session.session_id) {
2756a3bd7f05Smrg        Widget leader;
2757a3bd7f05Smrg
2758a3bd7f05Smrg        if (cw->session.session_id) {
2759a3bd7f05Smrg            leader = GetClientLeader(current);
2760a3bd7f05Smrg            if (XtWindow(leader))
2761a3bd7f05Smrg                XDeleteProperty(XtDisplay(leader), XtWindow(leader),
2762a3bd7f05Smrg                                XInternAtom(XtDisplay(leader), "SM_CLIENT_ID",
2763a3bd7f05Smrg                                            False));
2764a3bd7f05Smrg        }
2765a3bd7f05Smrg        if (nw->session.session_id) {
2766a3bd7f05Smrg            leader = GetClientLeader(new);
2767a3bd7f05Smrg            if (XtWindow(leader))
2768a3bd7f05Smrg                XChangeProperty(XtDisplay(leader), XtWindow(leader),
2769a3bd7f05Smrg                                XInternAtom(XtDisplay(leader), "SM_CLIENT_ID",
2770a3bd7f05Smrg                                            False),
2771a3bd7f05Smrg                                XA_STRING, 8, PropModeReplace,
2772a3bd7f05Smrg                                (unsigned char *) nw->session.session_id,
2773a3bd7f05Smrg                                (int) strlen(nw->session.session_id));
2774a3bd7f05Smrg        }
2775444c061aSmrg    }
2776444c061aSmrg    return False;
2777444c061aSmrg}
2778444c061aSmrg
2779a3bd7f05Smrgvoid
2780a3bd7f05Smrg_XtShellGetCoordinates(Widget widget, Position *x, Position *y)
2781444c061aSmrg{
2782a3bd7f05Smrg    ShellWidget w = (ShellWidget) widget;
2783a3bd7f05Smrg
2784444c061aSmrg    if (XtIsRealized(widget) &&
2785a3bd7f05Smrg        !(w->shell.client_specified & _XtShellPositionValid)) {
2786a3bd7f05Smrg        int tmpx, tmpy;
2787a3bd7f05Smrg        Window tmpchild;
2788a3bd7f05Smrg
2789a3bd7f05Smrg        (void) XTranslateCoordinates(XtDisplay(w), XtWindow(w),
2790a3bd7f05Smrg                                     RootWindowOfScreen(XtScreen(w)),
2791a3bd7f05Smrg                                     (int) -w->core.border_width,
2792a3bd7f05Smrg                                     (int) -w->core.border_width,
2793a3bd7f05Smrg                                     &tmpx, &tmpy, &tmpchild);
2794a3bd7f05Smrg        w->core.x = (Position) tmpx;
2795a3bd7f05Smrg        w->core.y = (Position) tmpy;
2796a3bd7f05Smrg        w->shell.client_specified |= _XtShellPositionValid;
2797444c061aSmrg    }
2798444c061aSmrg    *x = w->core.x;
2799444c061aSmrg    *y = w->core.y;
2800444c061aSmrg}
2801444c061aSmrg
2802a3bd7f05Smrgstatic void
2803a3bd7f05SmrgGetValuesHook(Widget widget, ArgList args, Cardinal *num_args)
2804444c061aSmrg{
2805444c061aSmrg    ShellWidget w = (ShellWidget) widget;
2806444c061aSmrg
2807444c061aSmrg    /* x and y resource values may be invalid after a shell resize */
2808444c061aSmrg    if (XtIsRealized(widget) &&
2809a3bd7f05Smrg        !(w->shell.client_specified & _XtShellPositionValid)) {
2810a3bd7f05Smrg        Cardinal n;
2811a3bd7f05Smrg        Position x, y;
2812a3bd7f05Smrg
2813a3bd7f05Smrg        for (n = *num_args; n; n--, args++) {
2814a3bd7f05Smrg            if (strcmp(XtNx, args->name) == 0) {
2815a3bd7f05Smrg                _XtShellGetCoordinates(widget, &x, &y);
2816a3bd7f05Smrg                _XtCopyToArg((char *) &x, &args->value, sizeof(Position));
2817a3bd7f05Smrg            }
2818a3bd7f05Smrg            else if (strcmp(XtNy, args->name) == 0) {
2819a3bd7f05Smrg                _XtShellGetCoordinates(widget, &x, &y);
2820a3bd7f05Smrg                _XtCopyToArg((char *) &y, &args->value, sizeof(Position));
2821a3bd7f05Smrg            }
2822a3bd7f05Smrg        }
2823444c061aSmrg    }
2824444c061aSmrg}
2825444c061aSmrg
2826a3bd7f05Smrgstatic void
2827a3bd7f05SmrgApplicationShellInsertChild(Widget widget)
2828444c061aSmrg{
2829a3bd7f05Smrg    if (!XtIsWidget(widget) && XtIsRectObj(widget)) {
2830a3bd7f05Smrg        XtAppWarningMsg(XtWidgetToApplicationContext(widget),
2831a3bd7f05Smrg                        "invalidClass", "applicationShellInsertChild",
2832a3bd7f05Smrg                        XtCXtToolkitError,
2833a3bd7f05Smrg                        "ApplicationShell does not accept RectObj children; ignored",
2834a3bd7f05Smrg                        NULL, NULL);
2835444c061aSmrg    }
2836444c061aSmrg    else {
2837a3bd7f05Smrg        XtWidgetProc insert_child;
2838444c061aSmrg
2839a3bd7f05Smrg        LOCK_PROCESS;
2840a3bd7f05Smrg        insert_child =
2841a3bd7f05Smrg            ((CompositeWidgetClass) applicationShellClassRec.core_class.
2842a3bd7f05Smrg             superclass)->composite_class.insert_child;
2843a3bd7f05Smrg        UNLOCK_PROCESS;
2844a3bd7f05Smrg        (*insert_child) (widget);
2845444c061aSmrg    }
2846444c061aSmrg}
2847444c061aSmrg
2848444c061aSmrg/**************************************************************************
2849444c061aSmrg
2850444c061aSmrg  Session Protocol Participation
2851444c061aSmrg
2852444c061aSmrg *************************************************************************/
2853444c061aSmrg
2854a3bd7f05Smrg#define XtSessionCheckpoint     0
2855a3bd7f05Smrg#define XtSessionInteract       1
2856444c061aSmrg
2857a3bd7f05Smrgstatic void CallSaveCallbacks(SessionShellWidget);
28580568f49bSmrgstatic _XtString *EditCommand(_XtString, _XtString *, _XtString *);
2859444c061aSmrgstatic Boolean ExamineToken(XtPointer);
2860444c061aSmrgstatic void GetIceEvent(XtPointer, int *, XtInputId *);
2861444c061aSmrgstatic XtCheckpointToken GetToken(Widget, int);
2862444c061aSmrgstatic void XtCallCancelCallbacks(SmcConn, SmPointer);
2863444c061aSmrgstatic void XtCallDieCallbacks(SmcConn, SmPointer);
2864444c061aSmrgstatic void XtCallSaveCallbacks(SmcConn, SmPointer, int, Bool, int, Bool);
2865444c061aSmrgstatic void XtCallSaveCompleteCallbacks(SmcConn, SmPointer);
2866444c061aSmrg
2867444c061aSmrg#ifndef XT_NO_SM
2868a3bd7f05Smrgstatic void
2869a3bd7f05SmrgStopManagingSession(SessionShellWidget w, SmcConn connection)
2870a3bd7f05Smrg{                               /* connection to close, if any */
2871444c061aSmrg    if (connection)
2872a3bd7f05Smrg        SmcCloseConnection(connection, 0, NULL);
2873444c061aSmrg
2874444c061aSmrg    if (w->session.input_id) {
2875a3bd7f05Smrg        XtRemoveInput(w->session.input_id);
2876a3bd7f05Smrg        w->session.input_id = 0;
2877444c061aSmrg    }
2878444c061aSmrg    w->session.connection = NULL;
2879444c061aSmrg}
2880444c061aSmrg
2881444c061aSmrg#define XT_MSG_LENGTH 256
2882a3bd7f05Smrgstatic void
2883a3bd7f05SmrgJoinSession(SessionShellWidget w)
2884444c061aSmrg{
2885444c061aSmrg    IceConn ice_conn;
2886444c061aSmrg    SmcCallbacks smcb;
2887a3bd7f05Smrg    char *sm_client_id;
2888444c061aSmrg    unsigned long mask;
2889a3bd7f05Smrg    static char context;        /* used to guarantee the connection isn't shared */
2890444c061aSmrg
2891444c061aSmrg    smcb.save_yourself.callback = XtCallSaveCallbacks;
2892444c061aSmrg    smcb.die.callback = XtCallDieCallbacks;
2893444c061aSmrg    smcb.save_complete.callback = XtCallSaveCompleteCallbacks;
2894444c061aSmrg    smcb.shutdown_cancelled.callback = XtCallCancelCallbacks;
2895444c061aSmrg    smcb.save_yourself.client_data = smcb.die.client_data =
2896a3bd7f05Smrg        smcb.save_complete.client_data =
2897a3bd7f05Smrg        smcb.shutdown_cancelled.client_data = (SmPointer) w;
2898444c061aSmrg    mask = SmcSaveYourselfProcMask | SmcDieProcMask |
2899a3bd7f05Smrg        SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask;
2900444c061aSmrg
2901444c061aSmrg    if (w->session.connection) {
2902a3bd7f05Smrg        SmcModifyCallbacks(w->session.connection, mask, &smcb);
2903a3bd7f05Smrg        sm_client_id = SmcClientID(w->session.connection);
2904a3bd7f05Smrg    }
2905a3bd7f05Smrg    else if (getenv("SESSION_MANAGER")) {
2906a3bd7f05Smrg        char error_msg[XT_MSG_LENGTH];
2907a3bd7f05Smrg
2908a3bd7f05Smrg        error_msg[0] = '\0';
2909a3bd7f05Smrg        w->session.connection =
2910a3bd7f05Smrg            SmcOpenConnection(NULL, &context, SmProtoMajor, SmProtoMinor,
2911a3bd7f05Smrg                              mask, &smcb, w->session.session_id,
2912a3bd7f05Smrg                              &sm_client_id, XT_MSG_LENGTH, error_msg);
2913a3bd7f05Smrg        if (error_msg[0]) {
2914a3bd7f05Smrg            String params[1];
2915a3bd7f05Smrg            Cardinal num_params = 1;
2916a3bd7f05Smrg
2917a3bd7f05Smrg            params[0] = error_msg;
2918a3bd7f05Smrg            XtAppWarningMsg(XtWidgetToApplicationContext((Widget) w),
2919a3bd7f05Smrg                            "sessionManagement", "SmcOpenConnection",
2920a3bd7f05Smrg                            XtCXtToolkitError,
2921a3bd7f05Smrg                            "Tried to connect to session manager, %s",
2922a3bd7f05Smrg                            params, &num_params);
2923a3bd7f05Smrg        }
2924444c061aSmrg    }
2925444c061aSmrg
2926444c061aSmrg    if (w->session.connection) {
2927a3bd7f05Smrg        if (w->session.session_id == NULL
2928a3bd7f05Smrg            || (strcmp(w->session.session_id, sm_client_id) != 0)) {
2929a3bd7f05Smrg            XtFree(w->session.session_id);
2930a3bd7f05Smrg            w->session.session_id = XtNewString(sm_client_id);
2931a3bd7f05Smrg        }
2932a3bd7f05Smrg        free(sm_client_id);
2933a3bd7f05Smrg        ice_conn = SmcGetIceConnection(w->session.connection);
2934a3bd7f05Smrg        w->session.input_id =
2935a3bd7f05Smrg            XtAppAddInput(XtWidgetToApplicationContext((Widget) w),
2936a3bd7f05Smrg                          IceConnectionNumber(ice_conn),
2937a3bd7f05Smrg                          (XtPointer) XtInputReadMask,
2938a3bd7f05Smrg                          GetIceEvent, (XtPointer) w);
2939a3bd7f05Smrg
2940a3bd7f05Smrg        w->session.restart_command =
2941a3bd7f05Smrg            EditCommand(w->session.session_id, w->session.restart_command,
2942a3bd7f05Smrg                        w->application.argv);
2943a3bd7f05Smrg
2944a3bd7f05Smrg        if (!w->session.clone_command)
2945a3bd7f05Smrg            w->session.clone_command =
2946a3bd7f05Smrg                EditCommand(NULL, NULL, w->session.restart_command);
2947a3bd7f05Smrg
2948a3bd7f05Smrg        if (!w->session.program_path)
2949a3bd7f05Smrg            w->session.program_path = w->session.restart_command
2950a3bd7f05Smrg                ? XtNewString(w->session.restart_command[0]) : NULL;
2951444c061aSmrg    }
2952444c061aSmrg}
2953a3bd7f05Smrg
2954444c061aSmrg#undef XT_MSG_LENGTH
2955444c061aSmrg
2956a3bd7f05Smrg#endif                          /* !XT_NO_SM */
2957444c061aSmrg
2958a3bd7f05Smrgstatic _XtString *
2959a3bd7f05SmrgNewStringArray(_XtString *str)
2960444c061aSmrg{
2961444c061aSmrg    Cardinal nbytes = 0;
2962444c061aSmrg    Cardinal num = 0;
29630568f49bSmrg    _XtString *newarray;
29640568f49bSmrg    _XtString *new;
29650568f49bSmrg    _XtString *strarray = str;
29660568f49bSmrg    _XtString sptr;
2967444c061aSmrg
2968a3bd7f05Smrg    if (!str)
2969a3bd7f05Smrg        return NULL;
2970444c061aSmrg
2971444c061aSmrg    for (num = 0; *str; num++, str++) {
2972a3bd7f05Smrg        nbytes = nbytes + (Cardinal) strlen(*str);
2973a3bd7f05Smrg        nbytes++;
2974444c061aSmrg    }
2975a3bd7f05Smrg    num = (Cardinal) ((size_t) (num + 1) * sizeof(_XtString));
29760568f49bSmrg    new = newarray = (_XtString *) __XtMalloc(num + nbytes);
2977444c061aSmrg    sptr = ((char *) new) + num;
2978444c061aSmrg
2979444c061aSmrg    for (str = strarray; *str; str++) {
2980a3bd7f05Smrg        *new = sptr;
2981a3bd7f05Smrg        strcpy(*new, *str);
2982a3bd7f05Smrg        new++;
2983a3bd7f05Smrg        sptr = strchr(sptr, '\0');
2984a3bd7f05Smrg        sptr++;
2985444c061aSmrg    }
2986444c061aSmrg    *new = NULL;
2987444c061aSmrg    return newarray;
2988444c061aSmrg}
2989444c061aSmrg
2990a3bd7f05Smrgstatic void
2991a3bd7f05SmrgFreeStringArray(_XtString *str)
2992444c061aSmrg{
2993444c061aSmrg    if (str)
2994a3bd7f05Smrg        XtFree((_XtString) str);
2995444c061aSmrg}
2996444c061aSmrg
2997444c061aSmrg#ifndef XT_NO_SM
2998a3bd7f05Smrgstatic SmProp *
2999a3bd7f05SmrgCardPack(_Xconst _XtString name, XtPointer closure)
3000444c061aSmrg{
3001444c061aSmrg    unsigned char *prop = (unsigned char *) closure;
3002444c061aSmrg    SmProp *p;
3003444c061aSmrg
3004444c061aSmrg    p = (SmProp *) __XtMalloc(sizeof(SmProp) + sizeof(SmPropValue));
3005444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
3006444c061aSmrg    p->num_vals = 1;
3007a3bd7f05Smrg    p->type = (char *) SmCARD8;
3008a3bd7f05Smrg    p->name = (char *) name;
3009444c061aSmrg    p->vals->length = 1;
3010444c061aSmrg    p->vals->value = (SmPointer) prop;
3011444c061aSmrg    return p;
3012444c061aSmrg}
3013444c061aSmrg
3014a3bd7f05Smrgstatic SmProp *
3015a3bd7f05SmrgArrayPack(_Xconst _XtString name, XtPointer closure)
3016444c061aSmrg{
30170568f49bSmrg    _XtString prop = *(_XtString *) closure;
3018444c061aSmrg    SmProp *p;
3019444c061aSmrg
3020444c061aSmrg    p = (SmProp *) __XtMalloc(sizeof(SmProp) + sizeof(SmPropValue));
3021444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
3022444c061aSmrg    p->num_vals = 1;
3023a3bd7f05Smrg    p->type = (char *) SmARRAY8;
30240568f49bSmrg    p->name = (char *) name;
30250568f49bSmrg    p->vals->length = (int) strlen(prop) + 1;
3026444c061aSmrg    p->vals->value = prop;
3027444c061aSmrg    return p;
3028444c061aSmrg}
3029444c061aSmrg
3030a3bd7f05Smrgstatic SmProp *
3031a3bd7f05SmrgListPack(_Xconst _XtString name, XtPointer closure)
3032444c061aSmrg{
30330568f49bSmrg    _XtString *prop = *(_XtString **) closure;
3034444c061aSmrg    SmProp *p;
30350568f49bSmrg    _XtString *ptr;
3036444c061aSmrg    SmPropValue *vals;
3037444c061aSmrg    int n = 0;
3038444c061aSmrg
3039444c061aSmrg    for (ptr = prop; *ptr; ptr++)
3040a3bd7f05Smrg        n++;
3041a3bd7f05Smrg    p = (SmProp *)
3042a3bd7f05Smrg        __XtMalloc((Cardinal)
3043a3bd7f05Smrg                   (sizeof(SmProp) + (size_t) n * sizeof(SmPropValue)));
3044444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
3045444c061aSmrg    p->num_vals = n;
3046a3bd7f05Smrg    p->type = (char *) SmLISTofARRAY8;
3047a3bd7f05Smrg    p->name = (char *) name;
3048444c061aSmrg    for (ptr = prop, vals = p->vals; *ptr; ptr++, vals++) {
3049a3bd7f05Smrg        vals->length = (int) strlen(*ptr) + 1;
3050a3bd7f05Smrg        vals->value = *ptr;
3051444c061aSmrg    }
3052444c061aSmrg    return p;
3053444c061aSmrg}
3054444c061aSmrg
3055a3bd7f05Smrgstatic void
3056a3bd7f05SmrgFreePacks(SmProp ** props, int num_props)
3057444c061aSmrg{
3058444c061aSmrg    while (--num_props >= 0)
3059a3bd7f05Smrg        XtFree((char *) props[num_props]);
3060444c061aSmrg}
3061444c061aSmrg
3062a3bd7f05Smrgtypedef SmProp *(*PackProc) (_Xconst _XtString, XtPointer);
3063444c061aSmrg
3064444c061aSmrgtypedef struct PropertyRec {
3065a3bd7f05Smrg    String name;
3066a3bd7f05Smrg    int offset;
3067a3bd7f05Smrg    PackProc proc;
3068444c061aSmrg} PropertyRec, *PropertyTable;
3069444c061aSmrg
3070444c061aSmrg#define Offset(x) (XtOffsetOf(SessionShellRec, x))
3071a3bd7f05Smrg/* *INDENT-OFF* */
3072444c061aSmrgstatic PropertyRec propertyTable[] = {
3073444c061aSmrg  {SmCloneCommand,     Offset(session.clone_command),    ListPack},
3074444c061aSmrg  {SmCurrentDirectory, Offset(session.current_dir),      ArrayPack},
3075444c061aSmrg  {SmDiscardCommand,   Offset(session.discard_command),  ListPack},
3076444c061aSmrg  {SmEnvironment,      Offset(session.environment),      ListPack},
3077444c061aSmrg  {SmProgram,          Offset(session.program_path),     ArrayPack},
3078444c061aSmrg  {SmResignCommand,    Offset(session.resign_command),   ListPack},
3079444c061aSmrg  {SmRestartCommand,   Offset(session.restart_command),  ListPack},
3080444c061aSmrg  {SmRestartStyleHint, Offset(session.restart_style),    CardPack},
3081444c061aSmrg  {SmShutdownCommand,  Offset(session.shutdown_command), ListPack}
3082444c061aSmrg};
3083a3bd7f05Smrg/* *INDENT-ON* */
3084444c061aSmrg#undef Offset
3085444c061aSmrg
3086444c061aSmrg#define XT_NUM_SM_PROPS 11
3087444c061aSmrg
3088a3bd7f05Smrgstatic void
3089a3bd7f05SmrgSetSessionProperties(SessionShellWidget w,
3090a3bd7f05Smrg                     Boolean initialize,
3091a3bd7f05Smrg                     unsigned long set_mask,
3092a3bd7f05Smrg                     unsigned long unset_mask)
3093444c061aSmrg{
3094444c061aSmrg    PropertyTable p = propertyTable;
3095444c061aSmrg    int n;
3096444c061aSmrg    int num_props = 0;
3097444c061aSmrg    XtPointer *addr;
3098444c061aSmrg    unsigned long mask;
3099444c061aSmrg    SmProp *props[XT_NUM_SM_PROPS];
3100444c061aSmrg
3101444c061aSmrg    if (w->session.connection == NULL)
3102a3bd7f05Smrg        return;
3103444c061aSmrg
3104444c061aSmrg    if (initialize) {
3105a3bd7f05Smrg        char nam_buf[32];
3106a3bd7f05Smrg        char pid[12];
3107a3bd7f05Smrg        String user_name;
3108a3bd7f05Smrg        String pidp = pid;
3109a3bd7f05Smrg
3110a3bd7f05Smrg        /* set all non-NULL session properties, the UserID and the ProcessID */
3111a3bd7f05Smrg        for (n = XtNumber(propertyTable); n; n--, p++) {
3112a3bd7f05Smrg            addr = (XtPointer *) ((char *) w + p->offset);
3113a3bd7f05Smrg            if (p->proc == CardPack) {
3114a3bd7f05Smrg                if (*(unsigned char *) addr)
3115a3bd7f05Smrg                    props[num_props++] =
3116a3bd7f05Smrg                        (*(p->proc)) (p->name, (XtPointer) addr);
3117a3bd7f05Smrg            }
3118a3bd7f05Smrg            else if (*addr)
3119a3bd7f05Smrg                props[num_props++] = (*(p->proc)) (p->name, (XtPointer) addr);
3120a3bd7f05Smrg
3121a3bd7f05Smrg        }
3122a3bd7f05Smrg        user_name = _XtGetUserName(nam_buf, sizeof nam_buf);
3123a3bd7f05Smrg        if (user_name)
3124a3bd7f05Smrg            props[num_props++] = ArrayPack(SmUserID, &user_name);
3125a3bd7f05Smrg        snprintf(pid, sizeof(pid), "%ld", (long) getpid());
3126a3bd7f05Smrg        props[num_props++] = ArrayPack(SmProcessID, &pidp);
3127a3bd7f05Smrg
3128a3bd7f05Smrg        if (num_props) {
3129a3bd7f05Smrg            SmcSetProperties(w->session.connection, num_props, props);
3130a3bd7f05Smrg            FreePacks(props, num_props);
3131a3bd7f05Smrg        }
3132a3bd7f05Smrg        return;
3133444c061aSmrg    }
3134444c061aSmrg
3135444c061aSmrg    if (set_mask) {
3136a3bd7f05Smrg        mask = 1L;
3137a3bd7f05Smrg        for (n = XtNumber(propertyTable); n; n--, p++, mask <<= 1)
3138a3bd7f05Smrg            if (mask & set_mask) {
3139a3bd7f05Smrg                addr = (XtPointer *) ((char *) w + p->offset);
3140a3bd7f05Smrg                props[num_props++] = (*(p->proc)) (p->name, (XtPointer) addr);
3141a3bd7f05Smrg            }
3142a3bd7f05Smrg        SmcSetProperties(w->session.connection, num_props, props);
3143a3bd7f05Smrg        FreePacks(props, num_props);
3144444c061aSmrg    }
3145444c061aSmrg
3146444c061aSmrg    if (unset_mask) {
3147a3bd7f05Smrg        char *pnames[XT_NUM_SM_PROPS];
31480568f49bSmrg
3149a3bd7f05Smrg        mask = 1L;
3150a3bd7f05Smrg        num_props = 0;
3151a3bd7f05Smrg        for (n = XtNumber(propertyTable); n; n--, p++, mask <<= 1)
3152a3bd7f05Smrg            if (mask & unset_mask)
3153a3bd7f05Smrg                pnames[num_props++] = (char *) p->name;
3154a3bd7f05Smrg        SmcDeleteProperties(w->session.connection, num_props, pnames);
3155444c061aSmrg    }
3156444c061aSmrg}
3157444c061aSmrg
3158a3bd7f05Smrgstatic void
3159a3bd7f05SmrgGetIceEvent(XtPointer client_data,
3160a3bd7f05Smrg            int *source _X_UNUSED,
3161a3bd7f05Smrg            XtInputId *id _X_UNUSED)
3162444c061aSmrg{
3163444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3164444c061aSmrg    IceProcessMessagesStatus status;
3165444c061aSmrg
3166444c061aSmrg    status = IceProcessMessages(SmcGetIceConnection(w->session.connection),
3167a3bd7f05Smrg                                NULL, NULL);
3168444c061aSmrg
3169444c061aSmrg    if (status == IceProcessMessagesIOError) {
3170a3bd7f05Smrg        StopManagingSession(w, w->session.connection);
3171a3bd7f05Smrg        XtCallCallbackList((Widget) w, w->session.error_callbacks,
3172a3bd7f05Smrg                           (XtPointer) NULL);
3173444c061aSmrg    }
3174444c061aSmrg}
3175444c061aSmrg
3176a3bd7f05Smrgstatic void
3177a3bd7f05SmrgCleanUpSave(SessionShellWidget w)
3178444c061aSmrg{
3179444c061aSmrg    XtSaveYourself next = w->session.save->next;
3180a3bd7f05Smrg
3181a3bd7f05Smrg    XtFree((char *) w->session.save);
3182444c061aSmrg    w->session.save = next;
3183444c061aSmrg    if (w->session.save)
3184a3bd7f05Smrg        CallSaveCallbacks(w);
3185444c061aSmrg}
3186444c061aSmrg
3187a3bd7f05Smrgstatic void
3188a3bd7f05SmrgCallSaveCallbacks(SessionShellWidget w)
3189444c061aSmrg{
3190444c061aSmrg    if (XtHasCallbacks((Widget) w, XtNsaveCallback) != XtCallbackHasSome) {
3191a3bd7f05Smrg        /* if the application makes no attempt to save state, report failure */
3192a3bd7f05Smrg        SmcSaveYourselfDone(w->session.connection, False);
3193a3bd7f05Smrg        CleanUpSave(w);
3194a3bd7f05Smrg    }
3195a3bd7f05Smrg    else {
3196a3bd7f05Smrg        XtCheckpointToken token;
31970568f49bSmrg
3198a3bd7f05Smrg        w->session.checkpoint_state = XtSaveActive;
3199a3bd7f05Smrg        token = GetToken((Widget) w, XtSessionCheckpoint);
3200a3bd7f05Smrg        _XtCallConditionalCallbackList((Widget) w, w->session.save_callbacks,
3201a3bd7f05Smrg                                       (XtPointer) token, ExamineToken);
3202a3bd7f05Smrg        XtSessionReturnToken(token);
3203444c061aSmrg    }
3204444c061aSmrg}
3205444c061aSmrg
3206a3bd7f05Smrgstatic void
3207a3bd7f05SmrgXtCallSaveCallbacks(SmcConn connection _X_UNUSED,
3208a3bd7f05Smrg                    SmPointer client_data,
3209a3bd7f05Smrg                    int save_type,
3210a3bd7f05Smrg                    Bool shutdown,
3211a3bd7f05Smrg                    int interact,
3212a3bd7f05Smrg                    Bool fast)
3213444c061aSmrg{
3214444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3215444c061aSmrg    XtSaveYourself save;
3216444c061aSmrg    XtSaveYourself prev;
3217444c061aSmrg
3218444c061aSmrg    save = XtNew(XtSaveYourselfRec);
3219444c061aSmrg    save->next = NULL;
3220444c061aSmrg    save->save_type = save_type;
3221444c061aSmrg    save->interact_style = interact;
32220568f49bSmrg    save->shutdown = (Boolean) shutdown;
32230568f49bSmrg    save->fast = (Boolean) fast;
3224444c061aSmrg    save->cancel_shutdown = False;
3225444c061aSmrg    save->phase = 1;
3226444c061aSmrg    save->interact_dialog_type = SmDialogNormal;
3227444c061aSmrg    save->request_cancel = save->request_next_phase = False;
3228444c061aSmrg    save->save_success = True;
3229444c061aSmrg    save->save_tokens = save->interact_tokens = 0;
3230444c061aSmrg
3231444c061aSmrg    prev = (XtSaveYourself) &w->session.save;
3232444c061aSmrg    while (prev->next)
3233a3bd7f05Smrg        prev = prev->next;
3234444c061aSmrg    prev->next = save;
3235444c061aSmrg
3236444c061aSmrg    if (w->session.checkpoint_state == XtSaveInactive)
3237a3bd7f05Smrg        CallSaveCallbacks(w);
3238444c061aSmrg}
3239444c061aSmrg
3240a3bd7f05Smrgstatic void
3241a3bd7f05SmrgXtInteractPermission(SmcConn connection, SmPointer data)
3242444c061aSmrg{
3243444c061aSmrg    Widget w = (Widget) data;
3244444c061aSmrg    SessionShellWidget sw = (SessionShellWidget) data;
3245444c061aSmrg    XtCallbackProc callback;
3246444c061aSmrg    XtPointer client_data;
3247444c061aSmrg
3248a3bd7f05Smrg    _XtPeekCallback(w, sw->session.interact_callbacks, &callback, &client_data);
3249444c061aSmrg    if (callback) {
3250a3bd7f05Smrg        XtCheckpointToken token;
32510568f49bSmrg
3252a3bd7f05Smrg        sw->session.checkpoint_state = XtInteractActive;
3253a3bd7f05Smrg        token = GetToken(w, XtSessionInteract);
3254a3bd7f05Smrg        XtRemoveCallback(w, XtNinteractCallback, callback, client_data);
3255a3bd7f05Smrg        (*callback) (w, client_data, (XtPointer) token);
3256a3bd7f05Smrg    }
3257a3bd7f05Smrg    else if (!sw->session.save->cancel_shutdown) {
3258a3bd7f05Smrg        SmcInteractDone(connection, False);
3259444c061aSmrg    }
3260444c061aSmrg}
3261444c061aSmrg
3262a3bd7f05Smrgstatic void
3263a3bd7f05SmrgXtCallSaveCompleteCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3264444c061aSmrg{
3265a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) client_data;
3266444c061aSmrg
3267a3bd7f05Smrg    XtCallCallbackList((Widget) w, w->session.save_complete_callbacks,
3268a3bd7f05Smrg                       (XtPointer) NULL);
3269444c061aSmrg}
3270444c061aSmrg
3271a3bd7f05Smrgstatic void
3272a3bd7f05SmrgXtCallNextPhaseCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3273444c061aSmrg{
3274a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) client_data;
3275a3bd7f05Smrg
3276444c061aSmrg    w->session.save->phase = 2;
3277444c061aSmrg    CallSaveCallbacks(w);
3278444c061aSmrg}
3279444c061aSmrg
3280a3bd7f05Smrgstatic void
3281a3bd7f05SmrgXtCallDieCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3282444c061aSmrg{
3283a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) client_data;
3284444c061aSmrg
3285444c061aSmrg    StopManagingSession(w, w->session.connection);
3286a3bd7f05Smrg    XtCallCallbackList((Widget) w, w->session.die_callbacks, (XtPointer) NULL);
3287444c061aSmrg}
3288444c061aSmrg
3289a3bd7f05Smrgstatic void
3290a3bd7f05SmrgXtCallCancelCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3291444c061aSmrg{
3292444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3293444c061aSmrg    Boolean call_interacts = False;
3294444c061aSmrg
3295444c061aSmrg    if (w->session.checkpoint_state != XtSaveInactive) {
3296a3bd7f05Smrg        w->session.save->cancel_shutdown = True;
3297a3bd7f05Smrg        call_interacts = (w->session.save->interact_style !=
3298a3bd7f05Smrg                          SmInteractStyleNone);
3299444c061aSmrg    }
3300444c061aSmrg
3301a3bd7f05Smrg    XtCallCallbackList((Widget) w, w->session.cancel_callbacks,
3302a3bd7f05Smrg                       (XtPointer) NULL);
3303444c061aSmrg
3304444c061aSmrg    if (call_interacts) {
3305a3bd7f05Smrg        w->session.save->interact_style = SmInteractStyleNone;
3306a3bd7f05Smrg        XtInteractPermission(w->session.connection, (SmPointer) w);
3307444c061aSmrg    }
3308444c061aSmrg
3309444c061aSmrg    if (w->session.checkpoint_state != XtSaveInactive) {
3310a3bd7f05Smrg        if (w->session.save->save_tokens == 0 &&
3311a3bd7f05Smrg            w->session.checkpoint_state == XtSaveActive) {
3312a3bd7f05Smrg            w->session.checkpoint_state = XtSaveInactive;
3313a3bd7f05Smrg            SmcSaveYourselfDone(w->session.connection,
3314a3bd7f05Smrg                                w->session.save->save_success);
3315a3bd7f05Smrg            CleanUpSave(w);
3316a3bd7f05Smrg        }
3317444c061aSmrg    }
3318444c061aSmrg}
3319444c061aSmrg
3320a3bd7f05Smrgstatic XtCheckpointToken
3321a3bd7f05SmrgGetToken(Widget widget, int type)
3322444c061aSmrg{
3323444c061aSmrg    SessionShellWidget w = (SessionShellWidget) widget;
3324444c061aSmrg    XtCheckpointToken token;
3325444c061aSmrg    XtSaveYourself save = w->session.save;
3326444c061aSmrg
3327444c061aSmrg    if (type == XtSessionCheckpoint)
3328a3bd7f05Smrg        w->session.save->save_tokens++;
3329444c061aSmrg    else if (type == XtSessionInteract)
3330a3bd7f05Smrg        w->session.save->interact_tokens++;
3331444c061aSmrg    else
3332a3bd7f05Smrg        return (XtCheckpointToken) NULL;
3333444c061aSmrg
3334444c061aSmrg    token = (XtCheckpointToken) __XtMalloc(sizeof(XtCheckpointTokenRec));
3335444c061aSmrg    token->save_type = save->save_type;
3336444c061aSmrg    token->interact_style = save->interact_style;
3337444c061aSmrg    token->shutdown = save->shutdown;
3338444c061aSmrg    token->fast = save->fast;
3339444c061aSmrg    token->cancel_shutdown = save->cancel_shutdown;
3340444c061aSmrg    token->phase = save->phase;
3341444c061aSmrg    token->interact_dialog_type = save->interact_dialog_type;
3342444c061aSmrg    token->request_cancel = save->request_cancel;
3343444c061aSmrg    token->request_next_phase = save->request_next_phase;
3344444c061aSmrg    token->save_success = save->save_success;
3345444c061aSmrg    token->type = type;
3346444c061aSmrg    token->widget = widget;
3347444c061aSmrg    return token;
3348444c061aSmrg}
3349444c061aSmrg
3350a3bd7f05SmrgXtCheckpointToken
3351a3bd7f05SmrgXtSessionGetToken(Widget widget)
3352444c061aSmrg{
3353444c061aSmrg    SessionShellWidget w = (SessionShellWidget) widget;
3354444c061aSmrg    XtCheckpointToken token = NULL;
3355a3bd7f05Smrg
3356444c061aSmrg    WIDGET_TO_APPCON(widget);
3357444c061aSmrg
3358444c061aSmrg    LOCK_APP(app);
3359444c061aSmrg    if (w->session.checkpoint_state)
3360a3bd7f05Smrg        token = GetToken(widget, XtSessionCheckpoint);
3361444c061aSmrg
3362444c061aSmrg    UNLOCK_APP(app);
3363444c061aSmrg    return token;
3364444c061aSmrg}
3365444c061aSmrg
3366a3bd7f05Smrgstatic Boolean
3367a3bd7f05SmrgExamineToken(XtPointer call_data)
3368444c061aSmrg{
3369444c061aSmrg    XtCheckpointToken token = (XtCheckpointToken) call_data;
3370444c061aSmrg    SessionShellWidget w = (SessionShellWidget) token->widget;
3371444c061aSmrg
3372444c061aSmrg    if (token->interact_dialog_type == SmDialogError)
3373a3bd7f05Smrg        w->session.save->interact_dialog_type = SmDialogError;
3374444c061aSmrg    if (token->request_next_phase)
3375a3bd7f05Smrg        w->session.save->request_next_phase = True;
3376a3bd7f05Smrg    if (!token->save_success)
3377a3bd7f05Smrg        w->session.save->save_success = False;
3378444c061aSmrg
3379444c061aSmrg    token->interact_dialog_type = w->session.save->interact_dialog_type;
3380444c061aSmrg    token->request_next_phase = w->session.save->request_next_phase;
3381444c061aSmrg    token->save_success = w->session.save->save_success;
3382444c061aSmrg    token->cancel_shutdown = w->session.save->cancel_shutdown;
3383444c061aSmrg
3384444c061aSmrg    return True;
3385444c061aSmrg}
3386444c061aSmrg
3387a3bd7f05Smrgvoid
3388a3bd7f05SmrgXtSessionReturnToken(XtCheckpointToken token)
3389444c061aSmrg{
3390444c061aSmrg    SessionShellWidget w = (SessionShellWidget) token->widget;
3391444c061aSmrg    Boolean has_some;
3392444c061aSmrg    Boolean phase_done;
3393444c061aSmrg    XtCallbackProc callback;
3394444c061aSmrg    XtPointer client_data;
3395a3bd7f05Smrg
3396a3bd7f05Smrg    WIDGET_TO_APPCON((Widget) w);
3397444c061aSmrg
3398444c061aSmrg    LOCK_APP(app);
3399444c061aSmrg
3400444c061aSmrg    has_some = (XtHasCallbacks(token->widget, XtNinteractCallback)
3401a3bd7f05Smrg                == XtCallbackHasSome);
3402444c061aSmrg
3403444c061aSmrg    (void) ExamineToken((XtPointer) token);
3404444c061aSmrg
3405444c061aSmrg    if (token->type == XtSessionCheckpoint) {
3406a3bd7f05Smrg        w->session.save->save_tokens--;
3407a3bd7f05Smrg        if (has_some && w->session.checkpoint_state == XtSaveActive) {
3408a3bd7f05Smrg            w->session.checkpoint_state = XtInteractPending;
3409a3bd7f05Smrg            SmcInteractRequest(w->session.connection,
3410a3bd7f05Smrg                               w->session.save->interact_dialog_type,
3411a3bd7f05Smrg                               XtInteractPermission, (SmPointer) w);
3412a3bd7f05Smrg        }
3413a3bd7f05Smrg        XtFree((char *) token);
3414a3bd7f05Smrg    }
3415a3bd7f05Smrg    else {
3416a3bd7f05Smrg        if (token->request_cancel)
3417a3bd7f05Smrg            w->session.save->request_cancel = True;
3418a3bd7f05Smrg        token->request_cancel = w->session.save->request_cancel;
3419a3bd7f05Smrg        if (has_some) {
3420a3bd7f05Smrg            _XtPeekCallback((Widget) w, w->session.interact_callbacks,
3421a3bd7f05Smrg                            &callback, &client_data);
3422a3bd7f05Smrg            XtRemoveCallback((Widget) w, XtNinteractCallback,
3423a3bd7f05Smrg                             callback, client_data);
3424a3bd7f05Smrg            (*callback) ((Widget) w, client_data, (XtPointer) token);
3425a3bd7f05Smrg        }
3426a3bd7f05Smrg        else {
3427a3bd7f05Smrg            w->session.save->interact_tokens--;
3428a3bd7f05Smrg            if (w->session.save->interact_tokens == 0) {
3429a3bd7f05Smrg                w->session.checkpoint_state = XtSaveActive;
3430a3bd7f05Smrg                if (!w->session.save->cancel_shutdown)
3431a3bd7f05Smrg                    SmcInteractDone(w->session.connection,
3432a3bd7f05Smrg                                    w->session.save->request_cancel);
3433a3bd7f05Smrg            }
3434a3bd7f05Smrg            XtFree((char *) token);
3435a3bd7f05Smrg        }
3436444c061aSmrg    }
3437444c061aSmrg
3438444c061aSmrg    phase_done = (w->session.save->save_tokens == 0 &&
3439a3bd7f05Smrg                  w->session.checkpoint_state == XtSaveActive);
3440444c061aSmrg
3441444c061aSmrg    if (phase_done) {
3442a3bd7f05Smrg        if (w->session.save->request_next_phase && w->session.save->phase == 1) {
3443a3bd7f05Smrg            SmcRequestSaveYourselfPhase2(w->session.connection,
3444a3bd7f05Smrg                                         XtCallNextPhaseCallbacks,
3445a3bd7f05Smrg                                         (SmPointer) w);
3446a3bd7f05Smrg        }
3447a3bd7f05Smrg        else {
3448a3bd7f05Smrg            w->session.checkpoint_state = XtSaveInactive;
3449a3bd7f05Smrg            SmcSaveYourselfDone(w->session.connection,
3450a3bd7f05Smrg                                w->session.save->save_success);
3451a3bd7f05Smrg            CleanUpSave(w);
3452a3bd7f05Smrg        }
3453444c061aSmrg    }
3454444c061aSmrg
3455444c061aSmrg    UNLOCK_APP(app);
3456444c061aSmrg}
3457444c061aSmrg
3458a3bd7f05Smrgstatic Boolean
3459a3bd7f05SmrgIsInArray(String str, _XtString *sarray)
3460444c061aSmrg{
3461444c061aSmrg    if (str == NULL || sarray == NULL)
3462a3bd7f05Smrg        return False;
3463444c061aSmrg    for (; *sarray; sarray++) {
3464a3bd7f05Smrg        if (strcmp(*sarray, str) == 0)
3465a3bd7f05Smrg            return True;
3466444c061aSmrg    }
3467444c061aSmrg    return False;
3468444c061aSmrg}
3469444c061aSmrg
3470a3bd7f05Smrgstatic _XtString *
3471a3bd7f05SmrgEditCommand(_XtString str,      /* if not NULL, the sm_client_id */
3472a3bd7f05Smrg            _XtString *src1,   /* first choice */
3473a3bd7f05Smrg            _XtString *src2)   /* alternate */
3474a3bd7f05Smrg{
3475444c061aSmrg    Boolean have;
3476444c061aSmrg    Boolean want;
3477444c061aSmrg    int count;
34780568f49bSmrg    _XtString *sarray;
34790568f49bSmrg    _XtString *s;
34800568f49bSmrg    _XtString *new;
3481444c061aSmrg
3482444c061aSmrg    want = (str != NULL);
3483444c061aSmrg    sarray = (src1 ? src1 : src2);
3484a3bd7f05Smrg    if (!sarray)
3485a3bd7f05Smrg        return NULL;
3486444c061aSmrg    have = IsInArray("-xtsessionID", sarray);
3487444c061aSmrg    if ((want && have) || (!want && !have)) {
3488a3bd7f05Smrg        if (sarray == src1)
3489a3bd7f05Smrg            return src1;
3490a3bd7f05Smrg        else
3491a3bd7f05Smrg            return NewStringArray(sarray);
3492444c061aSmrg    }
3493444c061aSmrg
3494444c061aSmrg    count = 0;
3495444c061aSmrg    for (s = sarray; *s; s++)
3496a3bd7f05Smrg        count++;
3497444c061aSmrg
3498444c061aSmrg    if (want) {
3499fdf6a26fSmrg        s = new = XtMallocArray((Cardinal) count + 3,
3500fdf6a26fSmrg                                (Cardinal) sizeof(_XtString *));
3501a3bd7f05Smrg        *s = *sarray;
3502a3bd7f05Smrg        s++;
3503a3bd7f05Smrg        sarray++;
3504a3bd7f05Smrg        *s = (_XtString) "-xtsessionID";
3505a3bd7f05Smrg        s++;
3506a3bd7f05Smrg        *s = str;
3507a3bd7f05Smrg        s++;
3508a3bd7f05Smrg        for (; --count > 0; s++, sarray++)
3509a3bd7f05Smrg            *s = *sarray;
3510a3bd7f05Smrg        *s = NULL;
3511a3bd7f05Smrg    }
3512a3bd7f05Smrg    else {
3513a3bd7f05Smrg        if (count < 3)
3514a3bd7f05Smrg            return NewStringArray(sarray);
3515fdf6a26fSmrg        s = new = XtMallocArray((Cardinal) count - 1,
3516fdf6a26fSmrg                                (Cardinal) sizeof(_XtString *));
3517a3bd7f05Smrg        for (; --count >= 0; sarray++) {
3518a3bd7f05Smrg            if (strcmp(*sarray, "-xtsessionID") == 0) {
3519a3bd7f05Smrg                sarray++;
3520a3bd7f05Smrg                count--;
3521a3bd7f05Smrg            }
3522a3bd7f05Smrg            else {
3523a3bd7f05Smrg                *s = *sarray;
3524a3bd7f05Smrg                s++;
3525a3bd7f05Smrg            }
3526a3bd7f05Smrg        }
3527a3bd7f05Smrg        *s = NULL;
3528444c061aSmrg    }
3529444c061aSmrg    s = new;
3530444c061aSmrg    new = NewStringArray(new);
3531a3bd7f05Smrg    XtFree((char *) s);
3532444c061aSmrg    return new;
3533444c061aSmrg}
3534444c061aSmrg
3535a3bd7f05Smrg#endif                          /* !XT_NO_SM */
3536