Shell.c revision fdf6a26f
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
96444c061aSmrg/***************************************************************************
97444c061aSmrg *
98444c061aSmrg * Note: per the Xt spec, the Shell geometry management assumes in
99444c061aSmrg * several places that there is only one managed child.  This is
100444c061aSmrg * *not* a bug.  Any subclass that assumes otherwise is broken.
101444c061aSmrg *
102444c061aSmrg ***************************************************************************/
103444c061aSmrg
104444c061aSmrg#define BIGSIZE ((Dimension)32767)
105444c061aSmrg
106444c061aSmrg/***************************************************************************
107444c061aSmrg *
108444c061aSmrg * Default values for resource lists
109444c061aSmrg *
110444c061aSmrg ***************************************************************************/
111444c061aSmrg
112444c061aSmrgstatic void _XtShellDepth(Widget, int, XrmValue *);
113444c061aSmrgstatic void _XtShellColormap(Widget, int, XrmValue *);
114444c061aSmrgstatic void _XtShellAncestorSensitive(Widget, int, XrmValue *);
115444c061aSmrgstatic void _XtTitleEncoding(Widget, int, XrmValue *);
116444c061aSmrg
117444c061aSmrg/***************************************************************************
118444c061aSmrg *
119444c061aSmrg * Shell class record
120444c061aSmrg *
121444c061aSmrg ***************************************************************************/
122444c061aSmrg
123a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(ShellRec, x))
124a3bd7f05Smrg/* *INDENT-OFF* */
125444c061aSmrgstatic XtResource shellResources[]=
126444c061aSmrg{
127a3bd7f05Smrg    {XtNx, XtCPosition, XtRPosition, sizeof(Position),
128a3bd7f05Smrg        Offset(core.x), XtRImmediate, (XtPointer)BIGSIZE},
129a3bd7f05Smrg    {XtNy, XtCPosition, XtRPosition, sizeof(Position),
130a3bd7f05Smrg        Offset(core.y), XtRImmediate, (XtPointer)BIGSIZE},
131a3bd7f05Smrg    { XtNdepth, XtCDepth, XtRInt, sizeof(int),
132a3bd7f05Smrg        Offset(core.depth), XtRCallProc, (XtPointer) _XtShellDepth},
133a3bd7f05Smrg    { XtNcolormap, XtCColormap, XtRColormap, sizeof(Colormap),
134a3bd7f05Smrg        Offset(core.colormap), XtRCallProc, (XtPointer) _XtShellColormap},
135a3bd7f05Smrg    { XtNancestorSensitive, XtCSensitive, XtRBoolean, sizeof(Boolean),
136a3bd7f05Smrg        Offset(core.ancestor_sensitive), XtRCallProc,
137a3bd7f05Smrg        (XtPointer) _XtShellAncestorSensitive},
138a3bd7f05Smrg    { XtNallowShellResize, XtCAllowShellResize, XtRBoolean,
139a3bd7f05Smrg        sizeof(Boolean), Offset(shell.allow_shell_resize),
140a3bd7f05Smrg        XtRImmediate, (XtPointer)False},
141a3bd7f05Smrg    { XtNgeometry, XtCGeometry, XtRString, sizeof(String),
142a3bd7f05Smrg        Offset(shell.geometry), XtRString, (XtPointer)NULL},
143a3bd7f05Smrg    { XtNcreatePopupChildProc, XtCCreatePopupChildProc, XtRFunction,
144a3bd7f05Smrg        sizeof(XtCreatePopupChildProc), Offset(shell.create_popup_child_proc),
145a3bd7f05Smrg        XtRFunction, NULL},
146a3bd7f05Smrg    { XtNsaveUnder, XtCSaveUnder, XtRBoolean, sizeof(Boolean),
147a3bd7f05Smrg        Offset(shell.save_under), XtRImmediate, (XtPointer)False},
148a3bd7f05Smrg    { XtNpopupCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
149a3bd7f05Smrg        Offset(shell.popup_callback), XtRCallback, (XtPointer) NULL},
150a3bd7f05Smrg    { XtNpopdownCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
151a3bd7f05Smrg        Offset(shell.popdown_callback), XtRCallback, (XtPointer) NULL},
152a3bd7f05Smrg    { XtNoverrideRedirect, XtCOverrideRedirect,
153a3bd7f05Smrg        XtRBoolean, sizeof(Boolean), Offset(shell.override_redirect),
154a3bd7f05Smrg        XtRImmediate, (XtPointer)False},
155a3bd7f05Smrg    { XtNvisual, XtCVisual, XtRVisual, sizeof(Visual*),
156a3bd7f05Smrg        Offset(shell.visual), XtRImmediate, (XtPointer)CopyFromParent}
157444c061aSmrg};
158a3bd7f05Smrg/* *INDENT-ON* */
159444c061aSmrg
160444c061aSmrgstatic void ClassPartInitialize(WidgetClass);
161444c061aSmrgstatic void Initialize(Widget, Widget, ArgList, Cardinal *);
162444c061aSmrgstatic void Realize(Widget, Mask *, XSetWindowAttributes *);
163444c061aSmrgstatic void Resize(Widget);
164a3bd7f05Smrgstatic Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
165a3bd7f05Smrgstatic void GetValuesHook(Widget, ArgList, Cardinal *);
166444c061aSmrgstatic void ChangeManaged(Widget);
167a3bd7f05Smrgstatic XtGeometryResult GeometryManager(Widget, XtWidgetGeometry *,
168a3bd7f05Smrg                                        XtWidgetGeometry *);
169a3bd7f05Smrgstatic XtGeometryResult RootGeometryManager(Widget gw,
170a3bd7f05Smrg                                            XtWidgetGeometry *request,
171a3bd7f05Smrg                                            XtWidgetGeometry *reply);
172444c061aSmrgstatic void Destroy(Widget);
173444c061aSmrg
174a3bd7f05Smrg/* *INDENT-OFF* */
175444c061aSmrgstatic ShellClassExtensionRec shellClassExtRec = {
176444c061aSmrg    NULL,
177444c061aSmrg    NULLQUARK,
178444c061aSmrg    XtShellExtensionVersion,
179444c061aSmrg    sizeof(ShellClassExtensionRec),
180444c061aSmrg    RootGeometryManager
181444c061aSmrg};
182444c061aSmrg
183444c061aSmrgexternaldef(shellclassrec) ShellClassRec shellClassRec = {
184444c061aSmrg  {   /* Core */
185a3bd7f05Smrg    /* superclass            */ (WidgetClass) &compositeClassRec,
186a3bd7f05Smrg    /* class_name            */ "Shell",
187a3bd7f05Smrg    /* size                  */ sizeof(ShellRec),
188a3bd7f05Smrg    /* Class Initializer     */ NULL,
189a3bd7f05Smrg    /* class_part_initialize */ ClassPartInitialize,
190a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
191a3bd7f05Smrg    /* initialize            */ Initialize,
192a3bd7f05Smrg    /* initialize_notify     */ NULL,
193a3bd7f05Smrg    /* realize               */ Realize,
194a3bd7f05Smrg    /* actions               */ NULL,
195a3bd7f05Smrg    /* num_actions           */ 0,
196a3bd7f05Smrg    /* resources             */ shellResources,
197a3bd7f05Smrg    /* resource_count        */ XtNumber(shellResources),
198a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
199a3bd7f05Smrg    /* compress_motion       */ FALSE,
200a3bd7f05Smrg    /* compress_exposure     */ TRUE,
201a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
202a3bd7f05Smrg    /* visible_interest      */ FALSE,
203a3bd7f05Smrg    /* destroy               */ Destroy,
204a3bd7f05Smrg    /* resize                */ Resize,
205a3bd7f05Smrg    /* expose                */ NULL,
206a3bd7f05Smrg    /* set_values            */ SetValues,
207a3bd7f05Smrg    /* set_values_hook       */ NULL,
208a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
209a3bd7f05Smrg    /* get_values_hook       */ GetValuesHook,
210a3bd7f05Smrg    /* accept_focus          */ NULL,
211a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
212a3bd7f05Smrg    /* callback offsets      */ NULL,
213a3bd7f05Smrg    /* tm_table              */ NULL,
214a3bd7f05Smrg    /* query_geometry        */ NULL,
215a3bd7f05Smrg    /* display_accelerator   */ NULL,
216a3bd7f05Smrg    /* extension             */ NULL
217444c061aSmrg  },{ /* Composite */
218a3bd7f05Smrg    /* geometry_manager      */ GeometryManager,
219a3bd7f05Smrg    /* change_managed        */ ChangeManaged,
220a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
221a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
222a3bd7f05Smrg    /* extension             */ NULL
223444c061aSmrg  },{ /* Shell */
224a3bd7f05Smrg    /* extension             */ (XtPointer)&shellClassExtRec
225444c061aSmrg  }
226444c061aSmrg};
227a3bd7f05Smrg/* *INDENT-ON* */
228444c061aSmrg
229a3bd7f05Smrgexternaldef(shellwidgetclass)
230a3bd7f05SmrgWidgetClass shellWidgetClass = (WidgetClass) (&shellClassRec);
231444c061aSmrg
232444c061aSmrg/***************************************************************************
233444c061aSmrg *
234444c061aSmrg * OverrideShell class record
235444c061aSmrg *
236444c061aSmrg ***************************************************************************/
237444c061aSmrg
238a3bd7f05Smrg/* *INDENT-OFF* */
239a3bd7f05Smrgstatic XtResource overrideResources[] =
240444c061aSmrg{
241a3bd7f05Smrg    { XtNoverrideRedirect, XtCOverrideRedirect,
242a3bd7f05Smrg        XtRBoolean, sizeof(Boolean), Offset(shell.override_redirect),
243a3bd7f05Smrg        XtRImmediate, (XtPointer)True},
244a3bd7f05Smrg    { XtNsaveUnder, XtCSaveUnder, XtRBoolean, sizeof(Boolean),
245a3bd7f05Smrg        Offset(shell.save_under), XtRImmediate, (XtPointer)True},
246444c061aSmrg};
247444c061aSmrg
248444c061aSmrgexternaldef(overrideshellclassrec) OverrideShellClassRec overrideShellClassRec = {
249444c061aSmrg  {
250a3bd7f05Smrg    /* superclass            */ (WidgetClass) &shellClassRec,
251a3bd7f05Smrg    /* class_name            */ "OverrideShell",
252a3bd7f05Smrg    /* size                  */ sizeof(OverrideShellRec),
253a3bd7f05Smrg    /* Class Initializer     */ NULL,
254a3bd7f05Smrg    /* class_part_initialize */ NULL,
255a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
256a3bd7f05Smrg    /* initialize            */ NULL,
257a3bd7f05Smrg    /* initialize_notify     */ NULL,
258a3bd7f05Smrg    /* realize               */ XtInheritRealize,
259a3bd7f05Smrg    /* actions               */ NULL,
260a3bd7f05Smrg    /* num_actions           */ 0,
261a3bd7f05Smrg    /* resources             */ overrideResources,
262a3bd7f05Smrg    /* resource_count        */ XtNumber(overrideResources),
263a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
264a3bd7f05Smrg    /* compress_motion       */ FALSE,
265a3bd7f05Smrg    /* compress_exposure     */ TRUE,
266a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
267a3bd7f05Smrg    /* visible_interest      */ FALSE,
268a3bd7f05Smrg    /* destroy               */ NULL,
269a3bd7f05Smrg    /* resize                */ XtInheritResize,
270a3bd7f05Smrg    /* expose                */ NULL,
271a3bd7f05Smrg    /* set_values            */ NULL,
272a3bd7f05Smrg    /* set_values_hook       */ NULL,
273a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
274a3bd7f05Smrg    /* get_values_hook       */ NULL,
275a3bd7f05Smrg    /* accept_focus          */ NULL,
276a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
277a3bd7f05Smrg    /* callback offsets      */ NULL,
278a3bd7f05Smrg    /* tm_table              */ NULL,
279a3bd7f05Smrg    /* query_geometry        */ NULL,
280a3bd7f05Smrg    /* display_accelerator   */ NULL,
281a3bd7f05Smrg    /* extension             */ NULL
282444c061aSmrg  },{
283a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
284a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
285a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
286a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
287a3bd7f05Smrg    /* extension             */ NULL
288444c061aSmrg  },{
289a3bd7f05Smrg    /* extension             */ NULL
290444c061aSmrg  },{
291a3bd7f05Smrg    /* extension             */ NULL
292444c061aSmrg  }
293444c061aSmrg};
294a3bd7f05Smrg/* *INDENT-ON* */
295444c061aSmrg
296a3bd7f05Smrgexternaldef(overrideshellwidgetclass)
297a3bd7f05SmrgWidgetClass overrideShellWidgetClass = (WidgetClass) (&overrideShellClassRec);
298444c061aSmrg
299444c061aSmrg/***************************************************************************
300444c061aSmrg *
301444c061aSmrg * WMShell class record
302444c061aSmrg *
303444c061aSmrg ***************************************************************************/
304444c061aSmrg
305444c061aSmrg#undef Offset
306a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(WMShellRec, x))
307444c061aSmrg
308444c061aSmrgstatic int default_unspecified_shell_int = XtUnspecifiedShellInt;
309a3bd7f05Smrg
310444c061aSmrg/*
311444c061aSmrg * Warning, casting XtUnspecifiedShellInt (which is -1) to an (XtPointer)
312444c061aSmrg * can result is loss of bits on some machines (i.e. crays)
313444c061aSmrg */
314444c061aSmrg
315a3bd7f05Smrg/* *INDENT-OFF* */
316a3bd7f05Smrgstatic XtResource wmResources[] =
317a3bd7f05Smrg{
318a3bd7f05Smrg    { XtNtitle, XtCTitle, XtRString, sizeof(String),
319a3bd7f05Smrg        Offset(wm.title), XtRString, NULL},
320a3bd7f05Smrg    { XtNtitleEncoding, XtCTitleEncoding, XtRAtom, sizeof(Atom),
321a3bd7f05Smrg        Offset(wm.title_encoding),
322a3bd7f05Smrg        XtRCallProc, (XtPointer) _XtTitleEncoding},
323a3bd7f05Smrg    { XtNwmTimeout, XtCWmTimeout, XtRInt, sizeof(int),
324a3bd7f05Smrg        Offset(wm.wm_timeout), XtRImmediate,(XtPointer)DEFAULT_WM_TIMEOUT},
325a3bd7f05Smrg    { XtNwaitForWm, XtCWaitForWm, XtRBoolean, sizeof(Boolean),
326a3bd7f05Smrg        Offset(wm.wait_for_wm), XtRImmediate, (XtPointer)True},
327a3bd7f05Smrg    { XtNtransient, XtCTransient, XtRBoolean, sizeof(Boolean),
328a3bd7f05Smrg        Offset(wm.transient), XtRImmediate, (XtPointer)False},
329444c061aSmrg/* size_hints minus things stored in core */
330a3bd7f05Smrg    { XtNbaseWidth, XtCBaseWidth, XtRInt, sizeof(int),
331a3bd7f05Smrg        Offset(wm.base_width),
332a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
333a3bd7f05Smrg    { XtNbaseHeight, XtCBaseHeight, XtRInt, sizeof(int),
334a3bd7f05Smrg        Offset(wm.base_height),
335a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
336a3bd7f05Smrg    { XtNwinGravity, XtCWinGravity, XtRGravity, sizeof(int),
337a3bd7f05Smrg        Offset(wm.win_gravity),
338a3bd7f05Smrg        XtRGravity, (XtPointer) &default_unspecified_shell_int},
339a3bd7f05Smrg    { XtNminWidth, XtCMinWidth, XtRInt, sizeof(int),
340a3bd7f05Smrg        Offset(wm.size_hints.min_width),
341a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
342a3bd7f05Smrg    { XtNminHeight, XtCMinHeight, XtRInt, sizeof(int),
343a3bd7f05Smrg        Offset(wm.size_hints.min_height),
344a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
345a3bd7f05Smrg    { XtNmaxWidth, XtCMaxWidth, XtRInt, sizeof(int),
346a3bd7f05Smrg        Offset(wm.size_hints.max_width),
347a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
348a3bd7f05Smrg    { XtNmaxHeight, XtCMaxHeight, XtRInt, sizeof(int),
349a3bd7f05Smrg        Offset(wm.size_hints.max_height),
350a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
351a3bd7f05Smrg    { XtNwidthInc, XtCWidthInc, XtRInt, sizeof(int),
352a3bd7f05Smrg        Offset(wm.size_hints.width_inc),
353a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
354a3bd7f05Smrg    { XtNheightInc, XtCHeightInc, XtRInt, sizeof(int),
355a3bd7f05Smrg        Offset(wm.size_hints.height_inc),
356a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
357a3bd7f05Smrg    { XtNminAspectX, XtCMinAspectX, XtRInt, sizeof(int),
358a3bd7f05Smrg        Offset(wm.size_hints.min_aspect.x),
359a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
360a3bd7f05Smrg    { XtNminAspectY, XtCMinAspectY, XtRInt, sizeof(int),
361a3bd7f05Smrg        Offset(wm.size_hints.min_aspect.y),
362a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
363a3bd7f05Smrg    { XtNmaxAspectX, XtCMaxAspectX, XtRInt, sizeof(int),
364a3bd7f05Smrg        Offset(wm.size_hints.max_aspect.x),
365a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
366a3bd7f05Smrg    { XtNmaxAspectY, XtCMaxAspectY, XtRInt, sizeof(int),
367a3bd7f05Smrg        Offset(wm.size_hints.max_aspect.y),
368a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
369444c061aSmrg/* wm_hints */
370a3bd7f05Smrg    { XtNinput, XtCInput, XtRBool, sizeof(Bool),
371a3bd7f05Smrg        Offset(wm.wm_hints.input), XtRImmediate, (XtPointer)False},
372a3bd7f05Smrg    { XtNinitialState, XtCInitialState, XtRInitialState, sizeof(int),
373a3bd7f05Smrg        Offset(wm.wm_hints.initial_state),
374a3bd7f05Smrg        XtRImmediate, (XtPointer)NormalState},
375a3bd7f05Smrg    { XtNiconPixmap, XtCIconPixmap, XtRBitmap, sizeof(Pixmap),
376a3bd7f05Smrg        Offset(wm.wm_hints.icon_pixmap), XtRPixmap, NULL},
377a3bd7f05Smrg    { XtNiconWindow, XtCIconWindow, XtRWindow, sizeof(Window),
378a3bd7f05Smrg        Offset(wm.wm_hints.icon_window), XtRWindow,   (XtPointer) NULL},
379a3bd7f05Smrg    { XtNiconX, XtCIconX, XtRInt, sizeof(int),
380a3bd7f05Smrg        Offset(wm.wm_hints.icon_x),
381a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
382a3bd7f05Smrg    { XtNiconY, XtCIconY, XtRInt, sizeof(int),
383a3bd7f05Smrg        Offset(wm.wm_hints.icon_y),
384a3bd7f05Smrg        XtRInt, (XtPointer) &default_unspecified_shell_int},
385a3bd7f05Smrg    { XtNiconMask, XtCIconMask, XtRBitmap, sizeof(Pixmap),
386a3bd7f05Smrg        Offset(wm.wm_hints.icon_mask), XtRPixmap, NULL},
387a3bd7f05Smrg    { XtNwindowGroup, XtCWindowGroup, XtRWindow, sizeof(Window),
388a3bd7f05Smrg        Offset(wm.wm_hints.window_group),
389a3bd7f05Smrg        XtRImmediate, (XtPointer)XtUnspecifiedWindow},
390a3bd7f05Smrg    { XtNclientLeader, XtCClientLeader, XtRWidget, sizeof(Widget),
391a3bd7f05Smrg        Offset(wm.client_leader), XtRWidget, NULL},
392a3bd7f05Smrg    { XtNwindowRole, XtCWindowRole, XtRString, sizeof(String),
393a3bd7f05Smrg        Offset(wm.window_role), XtRString, (XtPointer) NULL},
394a3bd7f05Smrg    { XtNurgency, XtCUrgency, XtRBoolean, sizeof(Boolean),
395a3bd7f05Smrg        Offset(wm.urgency), XtRImmediate, (XtPointer) False}
396444c061aSmrg};
397a3bd7f05Smrg/* *INDENT-ON* */
398444c061aSmrg
399a3bd7f05Smrgstatic void
400a3bd7f05SmrgWMInitialize(Widget, Widget, ArgList, Cardinal *);
401a3bd7f05Smrgstatic Boolean
402a3bd7f05SmrgWMSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
403a3bd7f05Smrgstatic void
404a3bd7f05SmrgWMDestroy(Widget);
405444c061aSmrg
406a3bd7f05Smrg/* *INDENT-OFF* */
407444c061aSmrgexternaldef(wmshellclassrec) WMShellClassRec wmShellClassRec = {
408444c061aSmrg  {
409a3bd7f05Smrg    /* superclass            */ (WidgetClass) &shellClassRec,
410a3bd7f05Smrg    /* class_name            */ "WMShell",
411a3bd7f05Smrg    /* size                  */ sizeof(WMShellRec),
412a3bd7f05Smrg    /* Class Initializer     */ NULL,
413a3bd7f05Smrg    /* class_part_initialize */ NULL,
414a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
415a3bd7f05Smrg    /* initialize            */ WMInitialize,
416a3bd7f05Smrg    /* initialize_notify     */ NULL,
417a3bd7f05Smrg    /* realize               */ XtInheritRealize,
418a3bd7f05Smrg    /* actions               */ NULL,
419a3bd7f05Smrg    /* num_actions           */ 0,
420a3bd7f05Smrg    /* resources             */ wmResources,
421a3bd7f05Smrg    /* resource_count        */ XtNumber(wmResources),
422a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
423a3bd7f05Smrg    /* compress_motion       */ FALSE,
424a3bd7f05Smrg    /* compress_exposure     */ TRUE,
425a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
426a3bd7f05Smrg    /* visible_interest      */ FALSE,
427a3bd7f05Smrg    /* destroy               */ WMDestroy,
428a3bd7f05Smrg    /* resize                */ XtInheritResize,
429a3bd7f05Smrg    /* expose                */ NULL,
430a3bd7f05Smrg    /* set_values            */ WMSetValues,
431a3bd7f05Smrg    /* set_values_hook       */ NULL,
432a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
433a3bd7f05Smrg    /* get_values_hook       */ NULL,
434a3bd7f05Smrg    /* accept_focus          */ NULL,
435a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
436a3bd7f05Smrg    /* callback offsets      */ NULL,
437a3bd7f05Smrg    /* tm_table              */ NULL,
438a3bd7f05Smrg    /* query_geometry        */ NULL,
439a3bd7f05Smrg    /* display_accelerator   */ NULL,
440a3bd7f05Smrg    /* extension             */ NULL
441444c061aSmrg  },{
442a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
443a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
444a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
445a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
446a3bd7f05Smrg    /* extension             */ NULL
447444c061aSmrg  },{
448a3bd7f05Smrg    /* extension             */ NULL
449444c061aSmrg  },{
450a3bd7f05Smrg    /* extension             */ NULL
451444c061aSmrg  }
452444c061aSmrg};
453a3bd7f05Smrg/* *INDENT-ON* */
454444c061aSmrg
455a3bd7f05Smrgexternaldef(wmshellwidgetclass)
456a3bd7f05SmrgWidgetClass wmShellWidgetClass = (WidgetClass) (&wmShellClassRec);
457444c061aSmrg
458444c061aSmrg/***************************************************************************
459444c061aSmrg *
460444c061aSmrg * TransientShell class record
461444c061aSmrg *
462444c061aSmrg ***************************************************************************/
463444c061aSmrg
464444c061aSmrg#undef Offset
465a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(TransientShellRec, x))
466444c061aSmrg
467a3bd7f05Smrg/* *INDENT-OFF* */
468444c061aSmrgstatic XtResource transientResources[]=
469444c061aSmrg{
470a3bd7f05Smrg    { XtNtransient, XtCTransient, XtRBoolean, sizeof(Boolean),
471a3bd7f05Smrg        Offset(wm.transient), XtRImmediate, (XtPointer)True},
472a3bd7f05Smrg    { XtNtransientFor, XtCTransientFor, XtRWidget, sizeof(Widget),
473a3bd7f05Smrg        Offset(transient.transient_for), XtRWidget, NULL},
474a3bd7f05Smrg    { XtNsaveUnder, XtCSaveUnder, XtRBoolean, sizeof(Boolean),
475a3bd7f05Smrg        Offset(shell.save_under), XtRImmediate, (XtPointer)True},
476444c061aSmrg};
477a3bd7f05Smrg/* *INDENT-ON* */
478444c061aSmrg
479a3bd7f05Smrgstatic void
480a3bd7f05SmrgTransientRealize(Widget, Mask *, XSetWindowAttributes *);
481a3bd7f05Smrgstatic Boolean
482a3bd7f05SmrgTransientSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
483444c061aSmrg
484a3bd7f05Smrg/* *INDENT-OFF* */
485444c061aSmrgexternaldef(transientshellclassrec) TransientShellClassRec transientShellClassRec = {
486444c061aSmrg  {
487a3bd7f05Smrg    /* superclass            */ (WidgetClass) &vendorShellClassRec,
488a3bd7f05Smrg    /* class_name            */ "TransientShell",
489a3bd7f05Smrg    /* size                  */ sizeof(TransientShellRec),
490a3bd7f05Smrg    /* Class Initializer     */ NULL,
491a3bd7f05Smrg    /* class_part_initialize */ NULL,
492a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
493a3bd7f05Smrg    /* initialize            */ NULL,
494a3bd7f05Smrg    /* initialize_notify     */ NULL,
495a3bd7f05Smrg    /* realize               */ TransientRealize,
496a3bd7f05Smrg    /* actions               */ NULL,
497a3bd7f05Smrg    /* num_actions           */ 0,
498a3bd7f05Smrg    /* resources             */ transientResources,
499a3bd7f05Smrg    /* resource_count        */ XtNumber(transientResources),
500a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
501a3bd7f05Smrg    /* compress_motion       */ FALSE,
502a3bd7f05Smrg    /* compress_exposure     */ TRUE,
503a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
504a3bd7f05Smrg    /* visible_interest      */ FALSE,
505a3bd7f05Smrg    /* destroy               */ NULL,
506a3bd7f05Smrg    /* resize                */ XtInheritResize,
507a3bd7f05Smrg    /* expose                */ NULL,
508a3bd7f05Smrg    /* set_values            */ TransientSetValues,
509a3bd7f05Smrg    /* set_values_hook       */ NULL,
510a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
511a3bd7f05Smrg    /* get_values_hook       */ NULL,
512a3bd7f05Smrg    /* accept_focus          */ NULL,
513a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
514a3bd7f05Smrg    /* callback offsets      */ NULL,
515a3bd7f05Smrg    /* tm_table              */ XtInheritTranslations,
516a3bd7f05Smrg    /* query_geometry        */ NULL,
517a3bd7f05Smrg    /* display_accelerator   */ NULL,
518a3bd7f05Smrg    /* extension             */ NULL
519444c061aSmrg  },{
520a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
521a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
522a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
523a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
524a3bd7f05Smrg    /* extension             */ NULL
525444c061aSmrg  },{
526a3bd7f05Smrg    /* extension             */ NULL
527444c061aSmrg  },{
528a3bd7f05Smrg    /* extension             */ NULL
529444c061aSmrg  },{
530a3bd7f05Smrg    /* extension             */ NULL
531444c061aSmrg  },{
532a3bd7f05Smrg    /* extension             */ NULL
533444c061aSmrg  }
534444c061aSmrg};
535a3bd7f05Smrg/* *INDENT-ON* */
536444c061aSmrg
537a3bd7f05Smrgexternaldef(transientshellwidgetclass)
538a3bd7f05SmrgWidgetClass transientShellWidgetClass = (WidgetClass) (&transientShellClassRec);
539444c061aSmrg
540444c061aSmrg/***************************************************************************
541444c061aSmrg *
542444c061aSmrg * TopLevelShell class record
543444c061aSmrg *
544444c061aSmrg ***************************************************************************/
545444c061aSmrg
546444c061aSmrg#undef Offset
547a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(TopLevelShellRec, x))
548444c061aSmrg
549a3bd7f05Smrg/* *INDENT-OFF* */
550444c061aSmrgstatic XtResource topLevelResources[]=
551444c061aSmrg{
552a3bd7f05Smrg    { XtNiconName, XtCIconName, XtRString, sizeof(String),
553a3bd7f05Smrg        Offset(topLevel.icon_name), XtRString, (XtPointer) NULL},
554a3bd7f05Smrg    { XtNiconNameEncoding, XtCIconNameEncoding, XtRAtom, sizeof(Atom),
555a3bd7f05Smrg        Offset(topLevel.icon_name_encoding),
556a3bd7f05Smrg        XtRCallProc, (XtPointer) _XtTitleEncoding},
557a3bd7f05Smrg    { XtNiconic, XtCIconic, XtRBoolean, sizeof(Boolean),
558a3bd7f05Smrg        Offset(topLevel.iconic), XtRImmediate, (XtPointer)False}
559444c061aSmrg};
560a3bd7f05Smrg/* *INDENT-ON* */
561444c061aSmrg
562a3bd7f05Smrgstatic void
563a3bd7f05SmrgTopLevelInitialize(Widget, Widget, ArgList, Cardinal *);
564a3bd7f05Smrgstatic Boolean
565a3bd7f05SmrgTopLevelSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
566a3bd7f05Smrgstatic void
567a3bd7f05SmrgTopLevelDestroy(Widget);
568444c061aSmrg
569a3bd7f05Smrg/* *INDENT-OFF* */
570444c061aSmrgexternaldef(toplevelshellclassrec) TopLevelShellClassRec topLevelShellClassRec = {
571444c061aSmrg  {
572a3bd7f05Smrg    /* superclass            */ (WidgetClass) &vendorShellClassRec,
573a3bd7f05Smrg    /* class_name            */ "TopLevelShell",
574a3bd7f05Smrg    /* size                  */ sizeof(TopLevelShellRec),
575a3bd7f05Smrg    /* Class Initializer     */ NULL,
576a3bd7f05Smrg    /* class_part_initialize */ NULL,
577a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
578a3bd7f05Smrg    /* initialize            */ TopLevelInitialize,
579a3bd7f05Smrg    /* initialize_notify     */ NULL,
580a3bd7f05Smrg    /* realize               */ XtInheritRealize,
581a3bd7f05Smrg    /* actions               */ NULL,
582a3bd7f05Smrg    /* num_actions           */ 0,
583a3bd7f05Smrg    /* resources             */ topLevelResources,
584a3bd7f05Smrg    /* resource_count        */ XtNumber(topLevelResources),
585a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
586a3bd7f05Smrg    /* compress_motion       */ FALSE,
587a3bd7f05Smrg    /* compress_exposure     */ TRUE,
588a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
589a3bd7f05Smrg    /* visible_interest      */ FALSE,
590a3bd7f05Smrg    /* destroy               */ TopLevelDestroy,
591a3bd7f05Smrg    /* resize                */ XtInheritResize,
592a3bd7f05Smrg    /* expose                */ NULL,
593a3bd7f05Smrg    /* set_values            */ TopLevelSetValues,
594a3bd7f05Smrg    /* set_values_hook       */ NULL,
595a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
596a3bd7f05Smrg    /* get_values_hook       */ NULL,
597a3bd7f05Smrg    /* accept_focus          */ NULL,
598a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
599a3bd7f05Smrg    /* callback offsets      */ NULL,
600a3bd7f05Smrg    /* tm_table              */ XtInheritTranslations,
601a3bd7f05Smrg    /* query_geometry        */ NULL,
602a3bd7f05Smrg    /* display_accelerator   */ NULL,
603a3bd7f05Smrg    /* extension             */ NULL
604444c061aSmrg  },{
605a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
606a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
607a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
608a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
609a3bd7f05Smrg    /* extension             */ NULL
610444c061aSmrg  },{
611a3bd7f05Smrg    /* extension             */ NULL
612444c061aSmrg  },{
613a3bd7f05Smrg    /* extension             */ NULL
614444c061aSmrg  },{
615a3bd7f05Smrg    /* extension             */ NULL
616444c061aSmrg  },{
617a3bd7f05Smrg    /* extension             */ NULL
618444c061aSmrg  }
619444c061aSmrg};
620a3bd7f05Smrg/* *INDENT-ON* */
621444c061aSmrg
622a3bd7f05Smrgexternaldef(toplevelshellwidgetclass)
623a3bd7f05SmrgWidgetClass topLevelShellWidgetClass = (WidgetClass) (&topLevelShellClassRec);
624444c061aSmrg
625444c061aSmrg/***************************************************************************
626444c061aSmrg *
627444c061aSmrg * ApplicationShell class record
628444c061aSmrg *
629444c061aSmrg ***************************************************************************/
630444c061aSmrg
631444c061aSmrg#undef Offset
632a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(ApplicationShellRec, x))
633444c061aSmrg
634a3bd7f05Smrg/* *INDENT-OFF* */
635444c061aSmrgstatic XtResource applicationResources[]=
636444c061aSmrg{
637444c061aSmrg    {XtNargc, XtCArgc, XtRInt, sizeof(int),
638a3bd7f05Smrg          Offset(application.argc), XtRImmediate, (XtPointer)0},
639444c061aSmrg    {XtNargv, XtCArgv, XtRStringArray, sizeof(String*),
640a3bd7f05Smrg          Offset(application.argv), XtRPointer, (XtPointer) NULL}
641444c061aSmrg};
642a3bd7f05Smrg/* *INDENT-ON* */
643444c061aSmrg#undef Offset
644444c061aSmrg
645a3bd7f05Smrgstatic void
646a3bd7f05SmrgApplicationInitialize(Widget, Widget, ArgList, Cardinal *);
647a3bd7f05Smrgstatic void
648a3bd7f05SmrgApplicationDestroy(Widget);
649a3bd7f05Smrgstatic Boolean
650a3bd7f05SmrgApplicationSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
651a3bd7f05Smrgstatic void
652a3bd7f05SmrgApplicationShellInsertChild(Widget);
653444c061aSmrg
654a3bd7f05Smrg/* *INDENT-OFF* */
655444c061aSmrgstatic CompositeClassExtensionRec compositeClassExtension = {
656a3bd7f05Smrg    /* next_extension        */ NULL,
657a3bd7f05Smrg    /* record_type           */ NULLQUARK,
658a3bd7f05Smrg    /* version               */ XtCompositeExtensionVersion,
659a3bd7f05Smrg    /* record_size           */ sizeof(CompositeClassExtensionRec),
660a3bd7f05Smrg    /* accepts_objects       */ TRUE,
661444c061aSmrg    /* allows_change_managed_set */ FALSE
662444c061aSmrg};
663444c061aSmrg
664444c061aSmrgexternaldef(applicationshellclassrec) ApplicationShellClassRec applicationShellClassRec = {
665444c061aSmrg  {
666a3bd7f05Smrg    /* superclass            */ (WidgetClass) &topLevelShellClassRec,
667a3bd7f05Smrg    /* class_name            */ "ApplicationShell",
668a3bd7f05Smrg    /* size                  */ sizeof(ApplicationShellRec),
669a3bd7f05Smrg    /* Class Initializer     */ NULL,
670a3bd7f05Smrg    /* class_part_initialize*/  NULL,
671a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
672a3bd7f05Smrg    /* initialize            */ ApplicationInitialize,
673a3bd7f05Smrg    /* initialize_notify     */ NULL,
674a3bd7f05Smrg    /* realize               */ XtInheritRealize,
675a3bd7f05Smrg    /* actions               */ NULL,
676a3bd7f05Smrg    /* num_actions           */ 0,
677a3bd7f05Smrg    /* resources             */ applicationResources,
678a3bd7f05Smrg    /* resource_count        */ XtNumber(applicationResources),
679a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
680a3bd7f05Smrg    /* compress_motion       */ FALSE,
681a3bd7f05Smrg    /* compress_exposure     */ TRUE,
682a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
683a3bd7f05Smrg    /* visible_interest      */ FALSE,
684a3bd7f05Smrg    /* destroy               */ ApplicationDestroy,
685a3bd7f05Smrg    /* resize                */ XtInheritResize,
686a3bd7f05Smrg    /* expose                */ NULL,
687a3bd7f05Smrg    /* set_values            */ ApplicationSetValues,
688a3bd7f05Smrg    /* set_values_hook       */ NULL,
689a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
690a3bd7f05Smrg    /* get_values_hook       */ NULL,
691a3bd7f05Smrg    /* accept_focus          */ NULL,
692a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
693a3bd7f05Smrg    /* callback offsets      */ NULL,
694a3bd7f05Smrg    /* tm_table              */ XtInheritTranslations,
695a3bd7f05Smrg    /* query_geometry        */ NULL,
696a3bd7f05Smrg    /* display_accelerator   */ NULL,
697a3bd7f05Smrg    /* extension             */ NULL
698444c061aSmrg  },{
699a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
700a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
701a3bd7f05Smrg    /* insert_child          */ ApplicationShellInsertChild,
702a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
703a3bd7f05Smrg    /* extension             */ (XtPointer)&compositeClassExtension
704444c061aSmrg  },{
705a3bd7f05Smrg    /* extension             */ NULL
706444c061aSmrg  },{
707a3bd7f05Smrg    /* extension             */ NULL
708444c061aSmrg  },{
709a3bd7f05Smrg    /* extension             */ NULL
710444c061aSmrg  },{
711a3bd7f05Smrg    /* extension             */ NULL
712444c061aSmrg  },{
713a3bd7f05Smrg    /* extension             */ NULL
714444c061aSmrg  }
715444c061aSmrg};
716a3bd7f05Smrg/* *INDENT-ON* */
717444c061aSmrg
718a3bd7f05Smrgexternaldef(applicationshellwidgetclass)
719a3bd7f05SmrgWidgetClass applicationShellWidgetClass =
720a3bd7f05Smrg    (WidgetClass) (&applicationShellClassRec);
721444c061aSmrg
722444c061aSmrg/***************************************************************************
723444c061aSmrg *
724444c061aSmrg * SessionShell class record
725444c061aSmrg *
726444c061aSmrg ***************************************************************************/
727444c061aSmrg
728444c061aSmrg#undef Offset
729a3bd7f05Smrg#define Offset(x)       (XtOffsetOf(SessionShellRec, x))
730444c061aSmrg
731a3bd7f05Smrg/* *INDENT-OFF* */
732444c061aSmrgstatic XtResource sessionResources[]=
733444c061aSmrg{
734444c061aSmrg#ifndef XT_NO_SM
735444c061aSmrg {XtNconnection, XtCConnection, XtRSmcConn, sizeof(SmcConn),
736444c061aSmrg       Offset(session.connection), XtRSmcConn, (XtPointer) NULL},
737444c061aSmrg#endif
738444c061aSmrg {XtNsessionID, XtCSessionID, XtRString, sizeof(String),
739444c061aSmrg       Offset(session.session_id), XtRString, (XtPointer) NULL},
740444c061aSmrg {XtNrestartCommand, XtCRestartCommand, XtRCommandArgArray, sizeof(String*),
741444c061aSmrg       Offset(session.restart_command), XtRPointer, (XtPointer) NULL},
742444c061aSmrg {XtNcloneCommand, XtCCloneCommand, XtRCommandArgArray, sizeof(String*),
743444c061aSmrg       Offset(session.clone_command), XtRPointer, (XtPointer) NULL},
744444c061aSmrg {XtNdiscardCommand, XtCDiscardCommand, XtRCommandArgArray, sizeof(String*),
745444c061aSmrg       Offset(session.discard_command), XtRPointer, (XtPointer) NULL},
746444c061aSmrg {XtNresignCommand, XtCResignCommand, XtRCommandArgArray, sizeof(String*),
747444c061aSmrg       Offset(session.resign_command), XtRPointer, (XtPointer) NULL},
748444c061aSmrg {XtNshutdownCommand, XtCShutdownCommand, XtRCommandArgArray, sizeof(String*),
749444c061aSmrg       Offset(session.shutdown_command), XtRPointer, (XtPointer) NULL},
750444c061aSmrg {XtNenvironment, XtCEnvironment, XtREnvironmentArray, sizeof(String*),
751444c061aSmrg       Offset(session.environment), XtRPointer, (XtPointer) NULL},
752444c061aSmrg {XtNcurrentDirectory, XtCCurrentDirectory, XtRDirectoryString, sizeof(String),
753444c061aSmrg       Offset(session.current_dir), XtRString, (XtPointer) NULL},
754444c061aSmrg {XtNprogramPath, XtCProgramPath, XtRString, sizeof(String),
755444c061aSmrg      Offset(session.program_path), XtRString, (XtPointer) NULL},
756444c061aSmrg {XtNrestartStyle, XtCRestartStyle, XtRRestartStyle, sizeof(unsigned char),
757444c061aSmrg      Offset(session.restart_style), XtRImmediate,
758444c061aSmrg      (XtPointer) SmRestartIfRunning},
759444c061aSmrg {XtNjoinSession, XtCJoinSession, XtRBoolean, sizeof(Boolean),
760444c061aSmrg       Offset(session.join_session), XtRImmediate, (XtPointer) True},
761444c061aSmrg {XtNsaveCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
762444c061aSmrg       Offset(session.save_callbacks), XtRCallback, (XtPointer) NULL},
763444c061aSmrg {XtNinteractCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
764444c061aSmrg       Offset(session.interact_callbacks), XtRCallback, (XtPointer)NULL},
765444c061aSmrg {XtNcancelCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
766444c061aSmrg       Offset(session.cancel_callbacks), XtRCallback, (XtPointer) NULL},
767444c061aSmrg {XtNsaveCompleteCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
768444c061aSmrg       Offset(session.save_complete_callbacks), XtRCallback, (XtPointer) NULL},
769444c061aSmrg {XtNdieCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
770444c061aSmrg       Offset(session.die_callbacks), XtRCallback, (XtPointer) NULL},
771444c061aSmrg {XtNerrorCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
772444c061aSmrg       Offset(session.error_callbacks), XtRCallback, (XtPointer) NULL}
773444c061aSmrg};
774a3bd7f05Smrg/* *INDENT-ON* */
775444c061aSmrg#undef Offset
776444c061aSmrg
777a3bd7f05Smrgstatic void
778a3bd7f05SmrgSessionInitialize(Widget, Widget, ArgList, Cardinal *);
779a3bd7f05Smrgstatic void
780a3bd7f05SmrgSessionDestroy(Widget);
781a3bd7f05Smrgstatic Boolean
782a3bd7f05SmrgSessionSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
783444c061aSmrg
784a3bd7f05Smrg/* *INDENT-OFF* */
785444c061aSmrgstatic CompositeClassExtensionRec sessionCompositeClassExtension = {
786a3bd7f05Smrg    /* next_extension        */ NULL,
787a3bd7f05Smrg    /* record_type           */ NULLQUARK,
788a3bd7f05Smrg    /* version               */ XtCompositeExtensionVersion,
789a3bd7f05Smrg    /* record_size           */ sizeof(CompositeClassExtensionRec),
790a3bd7f05Smrg    /* accepts_objects       */ TRUE,
791444c061aSmrg    /* allows_change_managed_set */ FALSE
792444c061aSmrg};
793444c061aSmrg
794444c061aSmrgexternaldef(sessionshellclassrec) SessionShellClassRec sessionShellClassRec = {
795444c061aSmrg  {
796a3bd7f05Smrg    /* superclass            */ (WidgetClass) &applicationShellClassRec,
797a3bd7f05Smrg    /* class_name            */ "SessionShell",
798a3bd7f05Smrg    /* size                  */ sizeof(SessionShellRec),
799a3bd7f05Smrg    /* Class Initializer     */ NULL,
800a3bd7f05Smrg    /* class_part_initialize */ NULL,
801a3bd7f05Smrg    /* Class init'ed ?       */ FALSE,
802a3bd7f05Smrg    /* initialize            */ SessionInitialize,
803a3bd7f05Smrg    /* initialize_notify     */ NULL,
804a3bd7f05Smrg    /* realize               */ XtInheritRealize,
805a3bd7f05Smrg    /* actions               */ NULL,
806a3bd7f05Smrg    /* num_actions           */ 0,
807a3bd7f05Smrg    /* resources             */ sessionResources,
808a3bd7f05Smrg    /* resource_count        */ XtNumber(sessionResources),
809a3bd7f05Smrg    /* xrm_class             */ NULLQUARK,
810a3bd7f05Smrg    /* compress_motion       */ FALSE,
811a3bd7f05Smrg    /* compress_exposure     */ TRUE,
812a3bd7f05Smrg    /* compress_enterleave   */ FALSE,
813a3bd7f05Smrg    /* visible_interest      */ FALSE,
814a3bd7f05Smrg    /* destroy               */ SessionDestroy,
815a3bd7f05Smrg    /* resize                */ XtInheritResize,
816a3bd7f05Smrg    /* expose                */ NULL,
817a3bd7f05Smrg    /* set_values            */ SessionSetValues,
818a3bd7f05Smrg    /* set_values_hook       */ NULL,
819a3bd7f05Smrg    /* set_values_almost     */ XtInheritSetValuesAlmost,
820a3bd7f05Smrg    /* get_values_hook       */ NULL,
821a3bd7f05Smrg    /* accept_focus          */ NULL,
822a3bd7f05Smrg    /* intrinsics version    */ XtVersion,
823a3bd7f05Smrg    /* callback offsets      */ NULL,
824a3bd7f05Smrg    /* tm_table              */ XtInheritTranslations,
825a3bd7f05Smrg    /* query_geometry        */ NULL,
826a3bd7f05Smrg    /* display_accelerator   */ NULL,
827a3bd7f05Smrg    /* extension             */ NULL
828444c061aSmrg  },{
829a3bd7f05Smrg    /* geometry_manager      */ XtInheritGeometryManager,
830a3bd7f05Smrg    /* change_managed        */ XtInheritChangeManaged,
831a3bd7f05Smrg    /* insert_child          */ XtInheritInsertChild,
832a3bd7f05Smrg    /* delete_child          */ XtInheritDeleteChild,
833a3bd7f05Smrg    /* extension             */ (XtPointer)&sessionCompositeClassExtension
834444c061aSmrg  },{
835a3bd7f05Smrg    /* extension             */ NULL
836444c061aSmrg  },{
837a3bd7f05Smrg    /* extension             */ NULL
838444c061aSmrg  },{
839a3bd7f05Smrg    /* extension             */ NULL
840444c061aSmrg  },{
841a3bd7f05Smrg    /* extension             */ NULL
842444c061aSmrg  },{
843a3bd7f05Smrg    /* extension             */ NULL
844444c061aSmrg  },{
845a3bd7f05Smrg    /* extension             */ NULL
846444c061aSmrg  }
847444c061aSmrg};
848a3bd7f05Smrg/* *INDENT-ON* */
849444c061aSmrg
850a3bd7f05Smrgexternaldef(sessionshellwidgetclass)
851a3bd7f05SmrgWidgetClass sessionShellWidgetClass = (WidgetClass) (&sessionShellClassRec);
852444c061aSmrg
853444c061aSmrg/****************************************************************************
854444c061aSmrg * Whew!
855444c061aSmrg ****************************************************************************/
856444c061aSmrg
857a3bd7f05Smrgstatic void
858a3bd7f05SmrgComputeWMSizeHints(WMShellWidget w, XSizeHints *hints)
859444c061aSmrg{
860444c061aSmrg    register long flags;
861a3bd7f05Smrg
862444c061aSmrg    hints->flags = flags = w->wm.size_hints.flags;
863444c061aSmrg#define copy(field) hints->field = w->wm.size_hints.field
864444c061aSmrg    if (flags & (USPosition | PPosition)) {
865a3bd7f05Smrg        copy(x);
866a3bd7f05Smrg        copy(y);
867444c061aSmrg    }
868444c061aSmrg    if (flags & (USSize | PSize)) {
869a3bd7f05Smrg        copy(width);
870a3bd7f05Smrg        copy(height);
871444c061aSmrg    }
872444c061aSmrg    if (flags & PMinSize) {
873a3bd7f05Smrg        copy(min_width);
874a3bd7f05Smrg        copy(min_height);
875444c061aSmrg    }
876444c061aSmrg    if (flags & PMaxSize) {
877a3bd7f05Smrg        copy(max_width);
878a3bd7f05Smrg        copy(max_height);
879444c061aSmrg    }
880444c061aSmrg    if (flags & PResizeInc) {
881a3bd7f05Smrg        copy(width_inc);
882a3bd7f05Smrg        copy(height_inc);
883444c061aSmrg    }
884444c061aSmrg    if (flags & PAspect) {
885a3bd7f05Smrg        copy(min_aspect.x);
886a3bd7f05Smrg        copy(min_aspect.y);
887a3bd7f05Smrg        copy(max_aspect.x);
888a3bd7f05Smrg        copy(max_aspect.y);
889444c061aSmrg    }
890444c061aSmrg#undef copy
891444c061aSmrg#define copy(field) hints->field = w->wm.field
892444c061aSmrg    if (flags & PBaseSize) {
893a3bd7f05Smrg        copy(base_width);
894a3bd7f05Smrg        copy(base_height);
895444c061aSmrg    }
896444c061aSmrg    if (flags & PWinGravity)
897a3bd7f05Smrg        copy(win_gravity);
898444c061aSmrg#undef copy
899444c061aSmrg}
900444c061aSmrg
901a3bd7f05Smrgstatic void
902a3bd7f05Smrg_SetWMSizeHints(WMShellWidget w)
903444c061aSmrg{
904444c061aSmrg    XSizeHints *size_hints = XAllocSizeHints();
905444c061aSmrg
906a3bd7f05Smrg    if (size_hints == NULL)
907a3bd7f05Smrg        _XtAllocError("XAllocSizeHints");
908444c061aSmrg    ComputeWMSizeHints(w, size_hints);
909a3bd7f05Smrg    XSetWMNormalHints(XtDisplay((Widget) w), XtWindow((Widget) w), size_hints);
910a3bd7f05Smrg    XFree((char *) size_hints);
911444c061aSmrg}
912444c061aSmrg
913a3bd7f05Smrgstatic ShellClassExtension
914a3bd7f05Smrg_FindClassExtension(WidgetClass widget_class)
915444c061aSmrg{
916444c061aSmrg    ShellClassExtension ext;
917a3bd7f05Smrg
918a3bd7f05Smrg    for (ext = (ShellClassExtension) ((ShellWidgetClass) widget_class)
919a3bd7f05Smrg         ->shell_class.extension;
920a3bd7f05Smrg         ext != NULL && ext->record_type != NULLQUARK;
921a3bd7f05Smrg         ext = (ShellClassExtension) ext->next_extension);
922444c061aSmrg
923444c061aSmrg    if (ext != NULL) {
924a3bd7f05Smrg        if (ext->version == XtShellExtensionVersion
925a3bd7f05Smrg            && ext->record_size == sizeof(ShellClassExtensionRec)) {
926a3bd7f05Smrg            /* continue */
927a3bd7f05Smrg        }
928a3bd7f05Smrg        else {
929a3bd7f05Smrg            String params[1];
930a3bd7f05Smrg            Cardinal num_params = 1;
931a3bd7f05Smrg
932a3bd7f05Smrg            params[0] = widget_class->core_class.class_name;
933a3bd7f05Smrg            XtErrorMsg("invalidExtension", "shellClassPartInitialize",
934a3bd7f05Smrg                       XtCXtToolkitError,
935a3bd7f05Smrg                       "widget class %s has invalid ShellClassExtension record",
936a3bd7f05Smrg                       params, &num_params);
937a3bd7f05Smrg        }
938444c061aSmrg    }
939444c061aSmrg    return ext;
940444c061aSmrg}
941444c061aSmrg
942a3bd7f05Smrgstatic void
943a3bd7f05SmrgClassPartInitialize(WidgetClass widget_class)
944444c061aSmrg{
945444c061aSmrg    ShellClassExtension ext = _FindClassExtension(widget_class);
946a3bd7f05Smrg
947444c061aSmrg    if (ext != NULL) {
948a3bd7f05Smrg        if (ext->root_geometry_manager == XtInheritRootGeometryManager) {
949a3bd7f05Smrg            ext->root_geometry_manager =
950a3bd7f05Smrg                _FindClassExtension(widget_class->core_class.superclass)
951a3bd7f05Smrg                ->root_geometry_manager;
952a3bd7f05Smrg        }
953a3bd7f05Smrg    }
954a3bd7f05Smrg    else {
955a3bd7f05Smrg        /* if not found, spec requires XtInheritRootGeometryManager */
956a3bd7f05Smrg        XtPointer *extP
957a3bd7f05Smrg            = &((ShellWidgetClass) widget_class)->shell_class.extension;
958a3bd7f05Smrg        ext = XtNew(ShellClassExtensionRec);
959fdf6a26fSmrg        (void) memcpy(ext,
960fdf6a26fSmrg                      _FindClassExtension(widget_class->core_class.superclass),
961fdf6a26fSmrg                      sizeof(ShellClassExtensionRec));
962a3bd7f05Smrg        ext->next_extension = *extP;
963a3bd7f05Smrg        *extP = (XtPointer) ext;
964a3bd7f05Smrg    }
965a3bd7f05Smrg}
966444c061aSmrg
967a3bd7f05Smrgstatic void EventHandler(Widget wid, XtPointer closure, XEvent *event,
968a3bd7f05Smrg                         Boolean *continue_to_dispatch);
969a3bd7f05Smrgstatic void _popup_set_prop(ShellWidget);
970444c061aSmrg
971a3bd7f05Smrgstatic void
972a3bd7f05SmrgXtCopyDefaultDepth(Widget widget, int offset _X_UNUSED, XrmValue *value)
973444c061aSmrg{
974a3bd7f05Smrg    value->addr = (XPointer) (&DefaultDepthOfScreen(XtScreenOfObject(widget)));
975444c061aSmrg}
976444c061aSmrg
977a3bd7f05Smrgstatic void
978a3bd7f05Smrg_XtShellDepth(Widget widget, int closure, XrmValue *value)
979444c061aSmrg{
980a3bd7f05Smrg    if (widget->core.parent == NULL)
981a3bd7f05Smrg        XtCopyDefaultDepth(widget, closure, value);
982a3bd7f05Smrg    else
983a3bd7f05Smrg        _XtCopyFromParent(widget, closure, value);
984444c061aSmrg}
985444c061aSmrg
986a3bd7f05Smrgstatic void
987a3bd7f05SmrgXtCopyDefaultColormap(Widget widget, int offset _X_UNUSED, XrmValue *value)
988444c061aSmrg{
989a3bd7f05Smrg    value->addr =
990a3bd7f05Smrg        (XPointer) (&DefaultColormapOfScreen(XtScreenOfObject(widget)));
991444c061aSmrg}
992444c061aSmrg
993a3bd7f05Smrgstatic void
994a3bd7f05Smrg_XtShellColormap(Widget widget, int closure, XrmValue *value)
995444c061aSmrg{
996a3bd7f05Smrg    if (widget->core.parent == NULL)
997a3bd7f05Smrg        XtCopyDefaultColormap(widget, closure, value);
998a3bd7f05Smrg    else
999a3bd7f05Smrg        _XtCopyFromParent(widget, closure, value);
1000444c061aSmrg}
1001444c061aSmrg
1002a3bd7f05Smrgstatic void
1003a3bd7f05Smrg_XtShellAncestorSensitive(Widget widget, int closure, XrmValue *value)
1004444c061aSmrg{
1005a3bd7f05Smrg    static Boolean true = True;
1006a3bd7f05Smrg
1007a3bd7f05Smrg    if (widget->core.parent == NULL)
1008a3bd7f05Smrg        value->addr = (XPointer) (&true);
1009a3bd7f05Smrg    else
1010a3bd7f05Smrg        _XtCopyFromParent(widget, closure, value);
1011444c061aSmrg}
1012444c061aSmrg
1013a3bd7f05Smrgstatic void
1014a3bd7f05Smrg_XtTitleEncoding(Widget widget, int offset _X_UNUSED, XrmValue *value)
1015444c061aSmrg{
1016444c061aSmrg    static Atom atom;
1017a3bd7f05Smrg
1018a3bd7f05Smrg    if (XtWidgetToApplicationContext(widget)->langProcRec.proc)
1019a3bd7f05Smrg        atom = None;
1020a3bd7f05Smrg    else
1021a3bd7f05Smrg        atom = XA_STRING;
1022444c061aSmrg    value->addr = (XPointer) &atom;
1023444c061aSmrg}
1024444c061aSmrg
1025a3bd7f05Smrgstatic void
1026a3bd7f05SmrgInitialize(Widget req _X_UNUSED,
1027a3bd7f05Smrg           Widget new,
1028a3bd7f05Smrg           ArgList args _X_UNUSED,
1029a3bd7f05Smrg           Cardinal *num_args _X_UNUSED)
1030444c061aSmrg{
1031a3bd7f05Smrg    ShellWidget w = (ShellWidget) new;
1032444c061aSmrg
1033a3bd7f05Smrg    w->shell.popped_up = FALSE;
1034a3bd7f05Smrg    w->shell.client_specified = _XtShellNotReparented | _XtShellPositionValid;
1035444c061aSmrg
1036a3bd7f05Smrg    if (w->core.x == BIGSIZE) {
1037a3bd7f05Smrg        w->core.x = 0;
1038a3bd7f05Smrg        if (w->core.y == BIGSIZE)
1039a3bd7f05Smrg            w->core.y = 0;
1040a3bd7f05Smrg    }
1041a3bd7f05Smrg    else {
1042a3bd7f05Smrg        if (w->core.y == BIGSIZE)
1043a3bd7f05Smrg            w->core.y = 0;
1044a3bd7f05Smrg        else
1045a3bd7f05Smrg            w->shell.client_specified |= _XtShellPPositionOK;
1046a3bd7f05Smrg    }
1047444c061aSmrg
1048a3bd7f05Smrg    XtAddEventHandler(new, (EventMask) StructureNotifyMask,
1049a3bd7f05Smrg                      TRUE, EventHandler, (XtPointer) NULL);
1050444c061aSmrg
1051444c061aSmrg#ifdef EDITRES
1052a3bd7f05Smrg    XtAddEventHandler(new, (EventMask) 0, TRUE, _XEditResCheckMessages, NULL);
1053444c061aSmrg#endif
1054444c061aSmrg}
1055444c061aSmrg
1056a3bd7f05Smrgstatic void
1057a3bd7f05SmrgWMInitialize(Widget req _X_UNUSED,
1058a3bd7f05Smrg             Widget new,
1059a3bd7f05Smrg             ArgList args _X_UNUSED,
1060a3bd7f05Smrg             Cardinal *num_args _X_UNUSED)
1061444c061aSmrg{
1062a3bd7f05Smrg    WMShellWidget w = (WMShellWidget) new;
1063a3bd7f05Smrg    TopLevelShellWidget tls = (TopLevelShellWidget) new;        /* maybe */
1064444c061aSmrg
1065a3bd7f05Smrg    if (w->wm.title == NULL) {
1066a3bd7f05Smrg        if (XtIsTopLevelShell(new) &&
1067a3bd7f05Smrg            tls->topLevel.icon_name != NULL &&
1068a3bd7f05Smrg            strlen(tls->topLevel.icon_name) != 0) {
1069a3bd7f05Smrg            w->wm.title = XtNewString(tls->topLevel.icon_name);
1070a3bd7f05Smrg        }
1071a3bd7f05Smrg        else {
1072a3bd7f05Smrg            w->wm.title = XtNewString(w->core.name);
1073a3bd7f05Smrg        }
1074a3bd7f05Smrg    }
1075a3bd7f05Smrg    else {
1076a3bd7f05Smrg        w->wm.title = XtNewString(w->wm.title);
1077a3bd7f05Smrg    }
1078a3bd7f05Smrg    w->wm.size_hints.flags = 0;
1079a3bd7f05Smrg    w->wm.wm_hints.flags = 0;
1080a3bd7f05Smrg    if (w->wm.window_role)
1081a3bd7f05Smrg        w->wm.window_role = XtNewString(w->wm.window_role);
1082444c061aSmrg}
1083444c061aSmrg
1084a3bd7f05Smrgstatic void
1085a3bd7f05SmrgTopLevelInitialize(Widget req _X_UNUSED,
1086a3bd7f05Smrg                   Widget new,
1087a3bd7f05Smrg                   ArgList args _X_UNUSED,
1088a3bd7f05Smrg                   Cardinal *num_args _X_UNUSED)
1089444c061aSmrg{
1090a3bd7f05Smrg    TopLevelShellWidget w = (TopLevelShellWidget) new;
1091444c061aSmrg
1092a3bd7f05Smrg    if (w->topLevel.icon_name == NULL) {
1093a3bd7f05Smrg        w->topLevel.icon_name = XtNewString(w->core.name);
1094a3bd7f05Smrg    }
1095a3bd7f05Smrg    else {
1096a3bd7f05Smrg        w->topLevel.icon_name = XtNewString(w->topLevel.icon_name);
1097a3bd7f05Smrg    }
1098444c061aSmrg
1099a3bd7f05Smrg    if (w->topLevel.iconic)
1100a3bd7f05Smrg        w->wm.wm_hints.initial_state = IconicState;
1101444c061aSmrg}
1102444c061aSmrg
11030568f49bSmrgstatic _XtString *NewArgv(int, _XtString *);
11040568f49bSmrgstatic _XtString *NewStringArray(_XtString *);
11050568f49bSmrgstatic void FreeStringArray(_XtString *);
1106444c061aSmrg
1107a3bd7f05Smrgstatic void
1108a3bd7f05SmrgApplicationInitialize(Widget req _X_UNUSED,
1109a3bd7f05Smrg                      Widget new,
1110a3bd7f05Smrg                      ArgList args _X_UNUSED,
1111a3bd7f05Smrg                      Cardinal *num_args _X_UNUSED)
1112444c061aSmrg{
1113a3bd7f05Smrg    ApplicationShellWidget w = (ApplicationShellWidget) new;
1114444c061aSmrg
1115444c061aSmrg    if (w->application.argc > 0)
1116a3bd7f05Smrg        w->application.argv = NewArgv(w->application.argc, w->application.argv);
1117444c061aSmrg}
1118444c061aSmrg
1119444c061aSmrg#define XtSaveInactive 0
1120444c061aSmrg#define XtSaveActive   1
1121444c061aSmrg#define XtInteractPending    2
1122444c061aSmrg#define XtInteractActive     3
1123444c061aSmrg
1124a3bd7f05Smrg#define XtCloneCommandMask      (1L<<0)
1125a3bd7f05Smrg#define XtCurrentDirectoryMask  (1L<<1)
1126a3bd7f05Smrg#define XtDiscardCommandMask    (1L<<2)
1127a3bd7f05Smrg#define XtEnvironmentMask       (1L<<3)
1128a3bd7f05Smrg#define XtProgramMask           (1L<<4)
1129a3bd7f05Smrg#define XtResignCommandMask     (1L<<5)
1130a3bd7f05Smrg#define XtRestartCommandMask    (1L<<6)
1131a3bd7f05Smrg#define XtRestartStyleHintMask  (1L<<7)
1132a3bd7f05Smrg#define XtShutdownCommandMask   (1L<<8)
1133444c061aSmrg
1134444c061aSmrgstatic void JoinSession(SessionShellWidget);
1135a3bd7f05Smrgstatic void SetSessionProperties(SessionShellWidget, Boolean, unsigned long,
1136a3bd7f05Smrg                                 unsigned long);
1137444c061aSmrgstatic void StopManagingSession(SessionShellWidget, SmcConn);
1138444c061aSmrg
1139444c061aSmrgtypedef struct _XtSaveYourselfRec {
1140444c061aSmrg    XtSaveYourself next;
1141a3bd7f05Smrg    int save_type;
1142a3bd7f05Smrg    int interact_style;
1143a3bd7f05Smrg    Boolean shutdown;
1144a3bd7f05Smrg    Boolean fast;
1145a3bd7f05Smrg    Boolean cancel_shutdown;
1146a3bd7f05Smrg    int phase;
1147a3bd7f05Smrg    int interact_dialog_type;
1148a3bd7f05Smrg    Boolean request_cancel;
1149a3bd7f05Smrg    Boolean request_next_phase;
1150a3bd7f05Smrg    Boolean save_success;
1151a3bd7f05Smrg    int save_tokens;
1152a3bd7f05Smrg    int interact_tokens;
1153444c061aSmrg} XtSaveYourselfRec;
1154444c061aSmrg
1155a3bd7f05Smrgstatic void
1156a3bd7f05SmrgSessionInitialize(Widget req _X_UNUSED,
1157a3bd7f05Smrg                  Widget new,
1158a3bd7f05Smrg                  ArgList args _X_UNUSED,
1159a3bd7f05Smrg                  Cardinal *num_args _X_UNUSED)
1160444c061aSmrg{
1161444c061aSmrg#ifndef XT_NO_SM
1162a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) new;
1163a3bd7f05Smrg
1164a3bd7f05Smrg    if (w->session.session_id)
1165a3bd7f05Smrg        w->session.session_id = XtNewString(w->session.session_id);
1166a3bd7f05Smrg    if (w->session.restart_command)
1167a3bd7f05Smrg        w->session.restart_command = NewStringArray(w->session.restart_command);
1168a3bd7f05Smrg    if (w->session.clone_command)
1169a3bd7f05Smrg        w->session.clone_command = NewStringArray(w->session.clone_command);
1170a3bd7f05Smrg    if (w->session.discard_command)
1171a3bd7f05Smrg        w->session.discard_command = NewStringArray(w->session.discard_command);
1172a3bd7f05Smrg    if (w->session.resign_command)
1173a3bd7f05Smrg        w->session.resign_command = NewStringArray(w->session.resign_command);
1174a3bd7f05Smrg    if (w->session.shutdown_command)
1175a3bd7f05Smrg        w->session.shutdown_command =
1176a3bd7f05Smrg            NewStringArray(w->session.shutdown_command);
1177a3bd7f05Smrg    if (w->session.environment)
1178a3bd7f05Smrg        w->session.environment = NewStringArray(w->session.environment);
1179a3bd7f05Smrg    if (w->session.current_dir)
1180a3bd7f05Smrg        w->session.current_dir = XtNewString(w->session.current_dir);
1181a3bd7f05Smrg    if (w->session.program_path)
1182a3bd7f05Smrg        w->session.program_path = XtNewString(w->session.program_path);
1183444c061aSmrg
1184444c061aSmrg    w->session.checkpoint_state = XtSaveInactive;
1185444c061aSmrg    w->session.input_id = 0;
1186444c061aSmrg    w->session.save = NULL;
1187444c061aSmrg
1188444c061aSmrg    if ((w->session.join_session) &&
1189a3bd7f05Smrg        (w->application.argv || w->session.restart_command))
1190a3bd7f05Smrg        JoinSession(w);
1191444c061aSmrg
1192444c061aSmrg    if (w->session.connection)
1193a3bd7f05Smrg        SetSessionProperties(w, True, 0L, 0L);
1194a3bd7f05Smrg#endif                          /* !XT_NO_SM */
1195444c061aSmrg}
1196444c061aSmrg
1197a3bd7f05Smrgstatic void
1198a3bd7f05SmrgResize(Widget w)
1199444c061aSmrg{
1200a3bd7f05Smrg    register ShellWidget sw = (ShellWidget) w;
1201444c061aSmrg    Widget childwid;
1202444c061aSmrg    Cardinal i;
1203a3bd7f05Smrg
1204a3bd7f05Smrg    for (i = 0; i < sw->composite.num_children; i++) {
1205444c061aSmrg        if (XtIsManaged(sw->composite.children[i])) {
1206a3bd7f05Smrg            childwid = sw->composite.children[i];
1207a3bd7f05Smrg            XtResizeWidget(childwid, sw->core.width, sw->core.height,
1208444c061aSmrg                           childwid->core.border_width);
1209a3bd7f05Smrg            break;              /* can only be one managed child */
1210444c061aSmrg        }
1211444c061aSmrg    }
1212444c061aSmrg}
1213444c061aSmrg
1214444c061aSmrgstatic void GetGeometry(Widget, Widget);
1215444c061aSmrg
1216a3bd7f05Smrgstatic void
1217a3bd7f05SmrgRealize(Widget wid, Mask *vmask, XSetWindowAttributes *attr)
1218a3bd7f05Smrg{
1219a3bd7f05Smrg    ShellWidget w = (ShellWidget) wid;
1220a3bd7f05Smrg    Mask mask = *vmask;
1221a3bd7f05Smrg
1222a3bd7f05Smrg    if (!(w->shell.client_specified & _XtShellGeometryParsed)) {
1223a3bd7f05Smrg        /* we'll get here only if there was no child the first
1224a3bd7f05Smrg           time we were realized.  If the shell was Unrealized
1225a3bd7f05Smrg           and then re-Realized, we probably don't want to
1226a3bd7f05Smrg           re-evaluate the defaults anyway.
1227a3bd7f05Smrg         */
1228a3bd7f05Smrg        GetGeometry(wid, (Widget) NULL);
1229a3bd7f05Smrg    }
1230a3bd7f05Smrg    else if (w->core.background_pixmap == XtUnspecifiedPixmap) {
1231a3bd7f05Smrg        /* I attempt to inherit my child's background to avoid screen flash
1232a3bd7f05Smrg         * if there is latency between when I get resized and when my child
1233a3bd7f05Smrg         * is resized.  Background=None is not satisfactory, as I want the
1234a3bd7f05Smrg         * user to get immediate feedback on the new dimensions (most
1235a3bd7f05Smrg         * particularly in the case of a non-reparenting wm).  It is
1236a3bd7f05Smrg         * especially important to have the server clear any old cruft
1237a3bd7f05Smrg         * from the display when I am resized larger.
1238a3bd7f05Smrg         */
1239a3bd7f05Smrg        register Widget *childP = w->composite.children;
1240a3bd7f05Smrg        int i;
1241a3bd7f05Smrg
1242a3bd7f05Smrg        for (i = (int) w->composite.num_children; i; i--, childP++) {
1243a3bd7f05Smrg            if (XtIsWidget(*childP) && XtIsManaged(*childP)) {
1244a3bd7f05Smrg                if ((*childP)->core.background_pixmap != XtUnspecifiedPixmap) {
1245a3bd7f05Smrg                    mask &= (unsigned long) (~(CWBackPixel));
1246a3bd7f05Smrg                    mask |= CWBackPixmap;
1247a3bd7f05Smrg                    attr->background_pixmap =
1248a3bd7f05Smrg                        w->core.background_pixmap =
1249a3bd7f05Smrg                        (*childP)->core.background_pixmap;
1250a3bd7f05Smrg                }
1251a3bd7f05Smrg                else {
1252a3bd7f05Smrg                    attr->background_pixel =
1253a3bd7f05Smrg                        w->core.background_pixel =
1254a3bd7f05Smrg                        (*childP)->core.background_pixel;
1255a3bd7f05Smrg                }
1256a3bd7f05Smrg                break;
1257a3bd7f05Smrg            }
1258a3bd7f05Smrg        }
1259a3bd7f05Smrg    }
1260a3bd7f05Smrg
1261a3bd7f05Smrg    if (w->shell.save_under) {
1262a3bd7f05Smrg        mask |= CWSaveUnder;
1263a3bd7f05Smrg        attr->save_under = TRUE;
1264a3bd7f05Smrg    }
1265a3bd7f05Smrg    if (w->shell.override_redirect) {
1266a3bd7f05Smrg        mask |= CWOverrideRedirect;
1267a3bd7f05Smrg        attr->override_redirect = TRUE;
1268a3bd7f05Smrg    }
1269a3bd7f05Smrg    if (wid->core.width == 0 || wid->core.height == 0) {
1270a3bd7f05Smrg        Cardinal count = 1;
1271a3bd7f05Smrg
1272a3bd7f05Smrg        XtErrorMsg("invalidDimension", "shellRealize", XtCXtToolkitError,
1273a3bd7f05Smrg                   "Shell widget %s has zero width and/or height",
1274a3bd7f05Smrg                   &wid->core.name, &count);
1275a3bd7f05Smrg    }
1276a3bd7f05Smrg    wid->core.window = XCreateWindow(XtDisplay(wid),
1277a3bd7f05Smrg                                     wid->core.screen->root, (int) wid->core.x,
1278a3bd7f05Smrg                                     (int) wid->core.y,
1279a3bd7f05Smrg                                     (unsigned int) wid->core.width,
1280a3bd7f05Smrg                                     (unsigned int) wid->core.height,
1281a3bd7f05Smrg                                     (unsigned int) wid->core.border_width,
1282a3bd7f05Smrg                                     (int) wid->core.depth,
1283a3bd7f05Smrg                                     (unsigned int) InputOutput,
1284a3bd7f05Smrg                                     w->shell.visual, mask, attr);
1285a3bd7f05Smrg
1286a3bd7f05Smrg    _popup_set_prop(w);
1287a3bd7f05Smrg}
1288a3bd7f05Smrg
1289a3bd7f05Smrgstatic void
1290a3bd7f05Smrg_SetTransientForHint(TransientShellWidget w, Boolean delete)
1291444c061aSmrg{
1292444c061aSmrg    Window window_group;
1293444c061aSmrg
1294444c061aSmrg    if (w->wm.transient) {
1295a3bd7f05Smrg        if (w->transient.transient_for != NULL
1296a3bd7f05Smrg            && XtIsRealized(w->transient.transient_for))
1297a3bd7f05Smrg            window_group = XtWindow(w->transient.transient_for);
1298a3bd7f05Smrg        else if ((window_group = w->wm.wm_hints.window_group)
1299a3bd7f05Smrg                 == XtUnspecifiedWindowGroup) {
1300a3bd7f05Smrg            if (delete)
1301a3bd7f05Smrg                XDeleteProperty(XtDisplay((Widget) w),
1302a3bd7f05Smrg                                XtWindow((Widget) w), XA_WM_TRANSIENT_FOR);
1303a3bd7f05Smrg            return;
1304a3bd7f05Smrg        }
1305444c061aSmrg
1306a3bd7f05Smrg        XSetTransientForHint(XtDisplay((Widget) w),
1307a3bd7f05Smrg                             XtWindow((Widget) w), window_group);
1308444c061aSmrg    }
1309444c061aSmrg}
1310444c061aSmrg
1311a3bd7f05Smrgstatic void
1312a3bd7f05SmrgTransientRealize(Widget w, Mask *vmask, XSetWindowAttributes *attr)
1313444c061aSmrg{
1314444c061aSmrg    XtRealizeProc realize;
1315444c061aSmrg
1316444c061aSmrg    LOCK_PROCESS;
1317444c061aSmrg    realize =
1318a3bd7f05Smrg        transientShellWidgetClass->core_class.superclass->core_class.realize;
1319444c061aSmrg    UNLOCK_PROCESS;
1320444c061aSmrg    (*realize) (w, vmask, attr);
1321444c061aSmrg
1322a3bd7f05Smrg    _SetTransientForHint((TransientShellWidget) w, False);
1323444c061aSmrg}
1324444c061aSmrg
1325a3bd7f05Smrgstatic Widget
1326a3bd7f05SmrgGetClientLeader(Widget w)
1327444c061aSmrg{
1328a3bd7f05Smrg    while ((!XtIsWMShell(w) || !((WMShellWidget) w)->wm.client_leader)
1329a3bd7f05Smrg           && w->core.parent)
1330a3bd7f05Smrg        w = w->core.parent;
1331444c061aSmrg
1332444c061aSmrg    /* ASSERT: w is a WMshell with client_leader set, or w has no parent */
1333444c061aSmrg
1334a3bd7f05Smrg    if (XtIsWMShell(w) && ((WMShellWidget) w)->wm.client_leader)
1335a3bd7f05Smrg        w = ((WMShellWidget) w)->wm.client_leader;
1336444c061aSmrg    return w;
1337444c061aSmrg}
1338444c061aSmrg
1339a3bd7f05Smrgstatic void
1340a3bd7f05SmrgEvaluateWMHints(WMShellWidget w)
1341a3bd7f05Smrg{
1342a3bd7f05Smrg    XWMHints *hintp = &w->wm.wm_hints;
1343a3bd7f05Smrg
1344a3bd7f05Smrg    hintp->flags = StateHint | InputHint;
1345a3bd7f05Smrg
1346a3bd7f05Smrg    if (hintp->icon_x == XtUnspecifiedShellInt)
1347a3bd7f05Smrg        hintp->icon_x = -1;
1348a3bd7f05Smrg    else
1349a3bd7f05Smrg        hintp->flags |= IconPositionHint;
1350a3bd7f05Smrg
1351a3bd7f05Smrg    if (hintp->icon_y == XtUnspecifiedShellInt)
1352a3bd7f05Smrg        hintp->icon_y = -1;
1353a3bd7f05Smrg    else
1354a3bd7f05Smrg        hintp->flags |= IconPositionHint;
1355a3bd7f05Smrg
1356a3bd7f05Smrg    if (hintp->icon_pixmap != None)
1357a3bd7f05Smrg        hintp->flags |= IconPixmapHint;
1358a3bd7f05Smrg    if (hintp->icon_mask != None)
1359a3bd7f05Smrg        hintp->flags |= IconMaskHint;
1360a3bd7f05Smrg    if (hintp->icon_window != None)
1361a3bd7f05Smrg        hintp->flags |= IconWindowHint;
1362a3bd7f05Smrg
1363a3bd7f05Smrg    if (hintp->window_group == XtUnspecifiedWindow) {
1364a3bd7f05Smrg        if (w->core.parent) {
1365a3bd7f05Smrg            Widget p;
1366a3bd7f05Smrg
1367a3bd7f05Smrg            for (p = w->core.parent; p->core.parent; p = p->core.parent);
1368a3bd7f05Smrg            if (XtIsRealized(p)) {
1369a3bd7f05Smrg                hintp->window_group = XtWindow(p);
1370a3bd7f05Smrg                hintp->flags |= WindowGroupHint;
1371a3bd7f05Smrg            }
1372a3bd7f05Smrg        }
1373a3bd7f05Smrg    }
1374a3bd7f05Smrg    else if (hintp->window_group != XtUnspecifiedWindowGroup)
1375a3bd7f05Smrg        hintp->flags |= WindowGroupHint;
1376a3bd7f05Smrg
1377a3bd7f05Smrg    if (w->wm.urgency)
1378a3bd7f05Smrg        hintp->flags |= XUrgencyHint;
1379a3bd7f05Smrg}
1380a3bd7f05Smrg
1381a3bd7f05Smrgstatic void
1382a3bd7f05SmrgEvaluateSizeHints(WMShellWidget w)
1383a3bd7f05Smrg{
1384a3bd7f05Smrg    struct _OldXSizeHints *sizep = &w->wm.size_hints;
1385a3bd7f05Smrg
1386a3bd7f05Smrg    sizep->x = w->core.x;
1387a3bd7f05Smrg    sizep->y = w->core.y;
1388a3bd7f05Smrg    sizep->width = w->core.width;
1389a3bd7f05Smrg    sizep->height = w->core.height;
1390a3bd7f05Smrg
1391a3bd7f05Smrg    if (sizep->flags & USSize) {
1392a3bd7f05Smrg        if (sizep->flags & PSize)
1393a3bd7f05Smrg            sizep->flags &= ~PSize;
1394a3bd7f05Smrg    }
1395a3bd7f05Smrg    else
1396a3bd7f05Smrg        sizep->flags |= PSize;
1397a3bd7f05Smrg
1398a3bd7f05Smrg    if (sizep->flags & USPosition) {
1399a3bd7f05Smrg        if (sizep->flags & PPosition)
1400a3bd7f05Smrg            sizep->flags &= ~PPosition;
1401a3bd7f05Smrg    }
1402a3bd7f05Smrg    else if (w->shell.client_specified & _XtShellPPositionOK)
1403a3bd7f05Smrg        sizep->flags |= PPosition;
1404a3bd7f05Smrg
1405a3bd7f05Smrg    if (sizep->min_aspect.x != XtUnspecifiedShellInt
1406a3bd7f05Smrg        || sizep->min_aspect.y != XtUnspecifiedShellInt
1407a3bd7f05Smrg        || sizep->max_aspect.x != XtUnspecifiedShellInt
1408a3bd7f05Smrg        || sizep->max_aspect.y != XtUnspecifiedShellInt) {
1409a3bd7f05Smrg        sizep->flags |= PAspect;
1410a3bd7f05Smrg    }
1411a3bd7f05Smrg    if (sizep->flags & PBaseSize
1412a3bd7f05Smrg        || w->wm.base_width != XtUnspecifiedShellInt
1413a3bd7f05Smrg        || w->wm.base_height != XtUnspecifiedShellInt) {
1414a3bd7f05Smrg        sizep->flags |= PBaseSize;
1415a3bd7f05Smrg        if (w->wm.base_width == XtUnspecifiedShellInt)
1416a3bd7f05Smrg            w->wm.base_width = 0;
1417a3bd7f05Smrg        if (w->wm.base_height == XtUnspecifiedShellInt)
1418a3bd7f05Smrg            w->wm.base_height = 0;
1419a3bd7f05Smrg    }
1420a3bd7f05Smrg    if (sizep->flags & PResizeInc
1421a3bd7f05Smrg        || sizep->width_inc != XtUnspecifiedShellInt
1422a3bd7f05Smrg        || sizep->height_inc != XtUnspecifiedShellInt) {
1423a3bd7f05Smrg        if (sizep->width_inc < 1)
1424a3bd7f05Smrg            sizep->width_inc = 1;
1425a3bd7f05Smrg        if (sizep->height_inc < 1)
1426a3bd7f05Smrg            sizep->height_inc = 1;
1427a3bd7f05Smrg        sizep->flags |= PResizeInc;
1428a3bd7f05Smrg    }
1429a3bd7f05Smrg    if (sizep->flags & PMaxSize
1430a3bd7f05Smrg        || sizep->max_width != XtUnspecifiedShellInt
1431a3bd7f05Smrg        || sizep->max_height != XtUnspecifiedShellInt) {
1432a3bd7f05Smrg        sizep->flags |= PMaxSize;
1433a3bd7f05Smrg        if (sizep->max_width == XtUnspecifiedShellInt)
1434a3bd7f05Smrg            sizep->max_width = BIGSIZE;
1435a3bd7f05Smrg        if (sizep->max_height == XtUnspecifiedShellInt)
1436a3bd7f05Smrg            sizep->max_height = BIGSIZE;
1437a3bd7f05Smrg    }
1438a3bd7f05Smrg    if (sizep->flags & PMinSize
1439a3bd7f05Smrg        || sizep->min_width != XtUnspecifiedShellInt
1440a3bd7f05Smrg        || sizep->min_height != XtUnspecifiedShellInt) {
1441a3bd7f05Smrg        sizep->flags |= PMinSize;
1442a3bd7f05Smrg        if (sizep->min_width == XtUnspecifiedShellInt)
1443a3bd7f05Smrg            sizep->min_width = 1;
1444a3bd7f05Smrg        if (sizep->min_height == XtUnspecifiedShellInt)
1445a3bd7f05Smrg            sizep->min_height = 1;
1446a3bd7f05Smrg    }
1447a3bd7f05Smrg}
1448a3bd7f05Smrg
1449a3bd7f05Smrgstatic void
1450a3bd7f05Smrg_popup_set_prop(ShellWidget w)
1451a3bd7f05Smrg{
1452a3bd7f05Smrg    Widget p;
1453a3bd7f05Smrg    WMShellWidget wmshell = (WMShellWidget) w;
1454a3bd7f05Smrg    TopLevelShellWidget tlshell = (TopLevelShellWidget) w;
1455a3bd7f05Smrg    ApplicationShellWidget appshell = (ApplicationShellWidget) w;
1456a3bd7f05Smrg    XTextProperty icon_name;
1457a3bd7f05Smrg    XTextProperty window_name;
1458a3bd7f05Smrg    char **argv;
1459a3bd7f05Smrg    int argc;
1460a3bd7f05Smrg    XSizeHints *size_hints;
1461a3bd7f05Smrg    Window window_group;
1462a3bd7f05Smrg    XClassHint classhint;
1463a3bd7f05Smrg    Boolean copied_iname, copied_wname;
1464a3bd7f05Smrg
1465a3bd7f05Smrg    if (!XtIsWMShell((Widget) w) || w->shell.override_redirect)
1466a3bd7f05Smrg        return;
1467a3bd7f05Smrg
1468a3bd7f05Smrg    if ((size_hints = XAllocSizeHints()) == NULL)
1469a3bd7f05Smrg        _XtAllocError("XAllocSizeHints");
1470a3bd7f05Smrg
1471a3bd7f05Smrg    copied_iname = copied_wname = False;
1472a3bd7f05Smrg    if (wmshell->wm.title_encoding == None &&
1473a3bd7f05Smrg        XmbTextListToTextProperty(XtDisplay((Widget) w),
1474a3bd7f05Smrg                                  (char **) &wmshell->wm.title,
1475a3bd7f05Smrg                                  1, XStdICCTextStyle,
1476a3bd7f05Smrg                                  &window_name) >= Success) {
1477a3bd7f05Smrg        copied_wname = True;
1478a3bd7f05Smrg    }
1479a3bd7f05Smrg    else {
1480a3bd7f05Smrg        window_name.value = (unsigned char *) wmshell->wm.title;
1481a3bd7f05Smrg        window_name.encoding = wmshell->wm.title_encoding ?
1482a3bd7f05Smrg            wmshell->wm.title_encoding : XA_STRING;
1483a3bd7f05Smrg        window_name.format = 8;
1484a3bd7f05Smrg        window_name.nitems = strlen((char *) window_name.value);
1485a3bd7f05Smrg    }
1486a3bd7f05Smrg
1487a3bd7f05Smrg    if (XtIsTopLevelShell((Widget) w)) {
1488a3bd7f05Smrg        if (tlshell->topLevel.icon_name_encoding == None &&
1489a3bd7f05Smrg            XmbTextListToTextProperty(XtDisplay((Widget) w),
1490a3bd7f05Smrg                                      (char **) &tlshell->topLevel.icon_name,
1491a3bd7f05Smrg                                      1, XStdICCTextStyle,
1492a3bd7f05Smrg                                      &icon_name) >= Success) {
1493a3bd7f05Smrg            copied_iname = True;
1494a3bd7f05Smrg        }
1495a3bd7f05Smrg        else {
1496a3bd7f05Smrg            icon_name.value = (unsigned char *) tlshell->topLevel.icon_name;
1497a3bd7f05Smrg            icon_name.encoding = tlshell->topLevel.icon_name_encoding ?
1498a3bd7f05Smrg                tlshell->topLevel.icon_name_encoding : XA_STRING;
1499a3bd7f05Smrg            icon_name.format = 8;
1500a3bd7f05Smrg            icon_name.nitems = strlen((char *) icon_name.value);
1501a3bd7f05Smrg        }
1502a3bd7f05Smrg    }
1503a3bd7f05Smrg
1504a3bd7f05Smrg    EvaluateWMHints(wmshell);
1505a3bd7f05Smrg    EvaluateSizeHints(wmshell);
1506a3bd7f05Smrg    ComputeWMSizeHints(wmshell, size_hints);
1507a3bd7f05Smrg
1508a3bd7f05Smrg    if (wmshell->wm.transient && !XtIsTransientShell((Widget) w)
1509a3bd7f05Smrg        && (window_group = wmshell->wm.wm_hints.window_group)
1510a3bd7f05Smrg        != XtUnspecifiedWindowGroup) {
1511a3bd7f05Smrg
1512a3bd7f05Smrg        XSetTransientForHint(XtDisplay((Widget) w),
1513a3bd7f05Smrg                             XtWindow((Widget) w), window_group);
1514a3bd7f05Smrg    }
1515a3bd7f05Smrg
1516a3bd7f05Smrg    classhint.res_name = (_XtString) w->core.name;
1517a3bd7f05Smrg    /* For the class, look up to the top of the tree */
1518a3bd7f05Smrg    for (p = (Widget) w; p->core.parent != NULL; p = p->core.parent);
1519a3bd7f05Smrg    if (XtIsApplicationShell(p)) {
1520a3bd7f05Smrg        classhint.res_class = ((ApplicationShellWidget) p)->application.class;
1521a3bd7f05Smrg    }
1522a3bd7f05Smrg    else {
1523a3bd7f05Smrg        LOCK_PROCESS;
1524a3bd7f05Smrg        classhint.res_class = (_XtString) XtClass(p)->core_class.class_name;
1525a3bd7f05Smrg        UNLOCK_PROCESS;
1526a3bd7f05Smrg    }
1527a3bd7f05Smrg
1528a3bd7f05Smrg    if (XtIsApplicationShell((Widget) w)
1529a3bd7f05Smrg        && (argc = appshell->application.argc) != -1)
1530a3bd7f05Smrg        argv = (char **) appshell->application.argv;
1531a3bd7f05Smrg    else {
1532a3bd7f05Smrg        argv = NULL;
1533a3bd7f05Smrg        argc = 0;
1534a3bd7f05Smrg    }
1535a3bd7f05Smrg
1536a3bd7f05Smrg    XSetWMProperties(XtDisplay((Widget) w), XtWindow((Widget) w),
1537a3bd7f05Smrg                     &window_name,
1538a3bd7f05Smrg                     (XtIsTopLevelShell((Widget) w)) ? &icon_name : NULL,
1539a3bd7f05Smrg                     argv, argc, size_hints, &wmshell->wm.wm_hints, &classhint);
1540a3bd7f05Smrg    XFree((char *) size_hints);
1541a3bd7f05Smrg    if (copied_wname)
1542a3bd7f05Smrg        XFree((XPointer) window_name.value);
1543a3bd7f05Smrg    if (copied_iname)
1544a3bd7f05Smrg        XFree((XPointer) icon_name.value);
1545a3bd7f05Smrg
1546a3bd7f05Smrg    LOCK_PROCESS;
1547a3bd7f05Smrg    if (XtWidgetToApplicationContext((Widget) w)->langProcRec.proc) {
1548a3bd7f05Smrg        char *locale = setlocale(LC_CTYPE, (char *) NULL);
1549a3bd7f05Smrg
1550a3bd7f05Smrg        if (locale)
1551a3bd7f05Smrg            XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1552a3bd7f05Smrg                            XInternAtom(XtDisplay((Widget) w),
1553a3bd7f05Smrg                                        "WM_LOCALE_NAME", False),
1554a3bd7f05Smrg                            XA_STRING, 8, PropModeReplace,
1555a3bd7f05Smrg                            (unsigned char *) locale, (int) strlen(locale));
1556a3bd7f05Smrg    }
1557a3bd7f05Smrg    UNLOCK_PROCESS;
1558a3bd7f05Smrg
1559a3bd7f05Smrg    p = GetClientLeader((Widget) w);
1560a3bd7f05Smrg    if (XtWindow(p))
1561a3bd7f05Smrg        XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1562a3bd7f05Smrg                        XInternAtom(XtDisplay((Widget) w),
1563a3bd7f05Smrg                                    "WM_CLIENT_LEADER", False),
1564a3bd7f05Smrg                        XA_WINDOW, 32, PropModeReplace,
1565a3bd7f05Smrg                        (unsigned char *) (&(p->core.window)), 1);
1566444c061aSmrg#ifndef XT_NO_SM
1567a3bd7f05Smrg    if (p == (Widget) w) {
1568a3bd7f05Smrg        for (; p->core.parent != NULL; p = p->core.parent);
1569a3bd7f05Smrg        if (XtIsSubclass(p, sessionShellWidgetClass)) {
1570a3bd7f05Smrg            String sm_client_id = ((SessionShellWidget) p)->session.session_id;
1571a3bd7f05Smrg
1572a3bd7f05Smrg            if (sm_client_id != NULL) {
1573a3bd7f05Smrg                XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1574a3bd7f05Smrg                                XInternAtom(XtDisplay((Widget) w),
1575a3bd7f05Smrg                                            "SM_CLIENT_ID", False),
1576a3bd7f05Smrg                                XA_STRING, 8, PropModeReplace,
1577a3bd7f05Smrg                                (unsigned char *) sm_client_id,
1578a3bd7f05Smrg                                (int) strlen(sm_client_id));
1579a3bd7f05Smrg            }
1580a3bd7f05Smrg        }
1581a3bd7f05Smrg    }
1582a3bd7f05Smrg#endif                          /* !XT_NO_SM */
1583a3bd7f05Smrg
1584a3bd7f05Smrg    if (wmshell->wm.window_role)
1585a3bd7f05Smrg        XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1586a3bd7f05Smrg                        XInternAtom(XtDisplay((Widget) w),
1587a3bd7f05Smrg                                    "WM_WINDOW_ROLE", False),
1588a3bd7f05Smrg                        XA_STRING, 8, PropModeReplace,
1589a3bd7f05Smrg                        (unsigned char *) wmshell->wm.window_role,
1590a3bd7f05Smrg                        (int) strlen(wmshell->wm.window_role));
1591a3bd7f05Smrg}
1592a3bd7f05Smrg
1593a3bd7f05Smrgstatic void
1594a3bd7f05SmrgEventHandler(Widget wid,
1595a3bd7f05Smrg             XtPointer closure _X_UNUSED,
1596a3bd7f05Smrg             XEvent *event,
1597a3bd7f05Smrg             Boolean *continue_to_dispatch _X_UNUSED)
1598a3bd7f05Smrg{
1599a3bd7f05Smrg    register ShellWidget w = (ShellWidget) wid;
1600a3bd7f05Smrg    WMShellWidget wmshell = (WMShellWidget) w;
1601a3bd7f05Smrg    Boolean sizechanged = FALSE;
1602a3bd7f05Smrg
1603a3bd7f05Smrg    if (w->core.window != event->xany.window) {
1604a3bd7f05Smrg        XtAppErrorMsg(XtWidgetToApplicationContext(wid),
1605a3bd7f05Smrg                      "invalidWindow", "eventHandler", XtCXtToolkitError,
1606a3bd7f05Smrg                      "Event with wrong window", NULL, NULL);
1607a3bd7f05Smrg        return;
1608a3bd7f05Smrg    }
1609a3bd7f05Smrg
1610a3bd7f05Smrg    switch (event->type) {
1611a3bd7f05Smrg    case ConfigureNotify:
1612a3bd7f05Smrg        if (w->core.window != event->xconfigure.window)
1613a3bd7f05Smrg            return;             /* in case of SubstructureNotify */
1614a3bd7f05Smrg#define NEQ(x)  ( w->core.x != event->xconfigure.x )
1615a3bd7f05Smrg        if (NEQ(width) || NEQ(height) || NEQ(border_width)) {
1616a3bd7f05Smrg            sizechanged = TRUE;
1617444c061aSmrg#undef NEQ
1618a3bd7f05Smrg            w->core.width = (Dimension) event->xconfigure.width;
1619a3bd7f05Smrg            w->core.height = (Dimension) event->xconfigure.height;
1620a3bd7f05Smrg            w->core.border_width = (Dimension) event->xconfigure.border_width;
1621a3bd7f05Smrg        }
1622a3bd7f05Smrg        if (event->xany.send_event      /* ICCCM compliant synthetic ev */
1623a3bd7f05Smrg            /* || w->shell.override_redirect */
1624a3bd7f05Smrg            || w->shell.client_specified & _XtShellNotReparented) {
1625a3bd7f05Smrg            w->core.x = (Position) event->xconfigure.x;
1626a3bd7f05Smrg            w->core.y = (Position) event->xconfigure.y;
1627a3bd7f05Smrg            w->shell.client_specified |= _XtShellPositionValid;
1628a3bd7f05Smrg        }
1629a3bd7f05Smrg        else
1630a3bd7f05Smrg            w->shell.client_specified &= ~_XtShellPositionValid;
1631a3bd7f05Smrg        if (XtIsWMShell(wid) && !wmshell->wm.wait_for_wm) {
1632a3bd7f05Smrg            /* Consider trusting the wm again */
1633a3bd7f05Smrg            register struct _OldXSizeHints *hintp = &wmshell->wm.size_hints;
1634a3bd7f05Smrg
1635444c061aSmrg#define EQ(x) (hintp->x == w->core.x)
1636a3bd7f05Smrg            if (EQ(x) && EQ(y) && EQ(width) && EQ(height)) {
1637a3bd7f05Smrg                wmshell->wm.wait_for_wm = TRUE;
1638a3bd7f05Smrg            }
1639444c061aSmrg#undef EQ
1640a3bd7f05Smrg        }
1641a3bd7f05Smrg        break;
1642a3bd7f05Smrg
1643a3bd7f05Smrg    case ReparentNotify:
1644a3bd7f05Smrg        if (event->xreparent.window == XtWindow(w)) {
1645a3bd7f05Smrg            if (event->xreparent.parent != RootWindowOfScreen(XtScreen(w)))
1646a3bd7f05Smrg                w->shell.client_specified &=
1647a3bd7f05Smrg                    ~(_XtShellNotReparented | _XtShellPositionValid);
1648a3bd7f05Smrg            else {
1649a3bd7f05Smrg                w->core.x = (Position) event->xreparent.x;
1650a3bd7f05Smrg                w->core.y = (Position) event->xreparent.y;
1651a3bd7f05Smrg                w->shell.client_specified |=
1652a3bd7f05Smrg                    (_XtShellNotReparented | _XtShellPositionValid);
1653a3bd7f05Smrg            }
1654a3bd7f05Smrg        }
1655a3bd7f05Smrg        return;
1656444c061aSmrg
1657a3bd7f05Smrg    case MapNotify:
1658a3bd7f05Smrg        if (XtIsTopLevelShell(wid)) {
1659a3bd7f05Smrg            ((TopLevelShellWidget) wid)->topLevel.iconic = FALSE;
1660a3bd7f05Smrg        }
1661a3bd7f05Smrg        return;
1662444c061aSmrg
1663a3bd7f05Smrg    case UnmapNotify:
1664a3bd7f05Smrg    {
1665a3bd7f05Smrg        XtPerDisplayInput pdi;
1666a3bd7f05Smrg        XtDevice device;
1667a3bd7f05Smrg        Widget p;
1668444c061aSmrg
1669a3bd7f05Smrg        if (XtIsTopLevelShell(wid))
1670a3bd7f05Smrg            ((TopLevelShellWidget) wid)->topLevel.iconic = TRUE;
1671444c061aSmrg
1672a3bd7f05Smrg        pdi = _XtGetPerDisplayInput(event->xunmap.display);
1673444c061aSmrg
1674a3bd7f05Smrg        device = &pdi->pointer;
1675444c061aSmrg
1676a3bd7f05Smrg        if (device->grabType == XtPassiveServerGrab) {
1677a3bd7f05Smrg            p = device->grab.widget;
1678a3bd7f05Smrg            while (p && !(XtIsShell(p)))
1679a3bd7f05Smrg                p = p->core.parent;
1680a3bd7f05Smrg            if (p == wid)
1681a3bd7f05Smrg                device->grabType = XtNoServerGrab;
1682a3bd7f05Smrg        }
1683444c061aSmrg
1684a3bd7f05Smrg        device = &pdi->keyboard;
1685a3bd7f05Smrg        if (IsEitherPassiveGrab(device->grabType)) {
1686a3bd7f05Smrg            p = device->grab.widget;
1687a3bd7f05Smrg            while (p && !(XtIsShell(p)))
1688a3bd7f05Smrg                p = p->core.parent;
1689a3bd7f05Smrg            if (p == wid) {
1690a3bd7f05Smrg                device->grabType = XtNoServerGrab;
1691a3bd7f05Smrg                pdi->activatingKey = 0;
1692a3bd7f05Smrg            }
1693a3bd7f05Smrg        }
1694444c061aSmrg
1695a3bd7f05Smrg        return;
1696a3bd7f05Smrg    }
1697a3bd7f05Smrg    default:
1698a3bd7f05Smrg        return;
1699a3bd7f05Smrg    }
1700a3bd7f05Smrg    {
1701a3bd7f05Smrg        XtWidgetProc resize;
1702a3bd7f05Smrg
1703a3bd7f05Smrg        LOCK_PROCESS;
1704a3bd7f05Smrg        resize = XtClass(wid)->core_class.resize;
1705a3bd7f05Smrg        UNLOCK_PROCESS;
1706a3bd7f05Smrg
1707a3bd7f05Smrg        if (sizechanged && resize) {
1708a3bd7f05Smrg            CALLGEOTAT(_XtGeoTrace((Widget) w,
1709a3bd7f05Smrg                                   "Shell \"%s\" is being resized to %d %d.\n",
1710a3bd7f05Smrg                                   XtName(wid), wid->core.width,
1711a3bd7f05Smrg                                   wid->core.height));
1712a3bd7f05Smrg            (*resize) (wid);
1713a3bd7f05Smrg        }
1714a3bd7f05Smrg    }
1715444c061aSmrg}
1716444c061aSmrg
1717a3bd7f05Smrgstatic void
1718a3bd7f05SmrgDestroy(Widget wid)
1719444c061aSmrg{
1720a3bd7f05Smrg    if (XtIsRealized(wid))
1721a3bd7f05Smrg        XDestroyWindow(XtDisplay(wid), XtWindow(wid));
1722444c061aSmrg}
1723444c061aSmrg
1724a3bd7f05Smrgstatic void
1725a3bd7f05SmrgWMDestroy(Widget wid)
1726444c061aSmrg{
1727a3bd7f05Smrg    WMShellWidget w = (WMShellWidget) wid;
1728444c061aSmrg
1729a3bd7f05Smrg    XtFree((char *) w->wm.title);
1730a3bd7f05Smrg    XtFree((char *) w->wm.window_role);
1731444c061aSmrg}
1732444c061aSmrg
1733a3bd7f05Smrgstatic void
1734a3bd7f05SmrgTopLevelDestroy(Widget wid)
1735444c061aSmrg{
1736a3bd7f05Smrg    TopLevelShellWidget w = (TopLevelShellWidget) wid;
1737444c061aSmrg
1738a3bd7f05Smrg    XtFree((char *) w->topLevel.icon_name);
1739444c061aSmrg}
1740444c061aSmrg
1741a3bd7f05Smrgstatic void
1742a3bd7f05SmrgApplicationDestroy(Widget wid)
1743444c061aSmrg{
1744444c061aSmrg    ApplicationShellWidget w = (ApplicationShellWidget) wid;
1745a3bd7f05Smrg
1746444c061aSmrg    if (w->application.argc > 0)
1747a3bd7f05Smrg        FreeStringArray(w->application.argv);
1748444c061aSmrg}
1749444c061aSmrg
1750a3bd7f05Smrgstatic void
1751a3bd7f05SmrgSessionDestroy(Widget wid)
1752444c061aSmrg{
1753444c061aSmrg#ifndef XT_NO_SM
1754444c061aSmrg    SessionShellWidget w = (SessionShellWidget) wid;
1755444c061aSmrg
1756444c061aSmrg    StopManagingSession(w, w->session.connection);
1757444c061aSmrg    XtFree(w->session.session_id);
1758444c061aSmrg    FreeStringArray(w->session.restart_command);
1759444c061aSmrg    FreeStringArray(w->session.clone_command);
1760444c061aSmrg    FreeStringArray(w->session.discard_command);
1761444c061aSmrg    FreeStringArray(w->session.resign_command);
1762444c061aSmrg    FreeStringArray(w->session.shutdown_command);
1763444c061aSmrg    FreeStringArray(w->session.environment);
1764444c061aSmrg    XtFree(w->session.current_dir);
17650568f49bSmrg    XtFree((_XtString) w->session.program_path);
1766a3bd7f05Smrg#endif                          /* !XT_NO_SM */
1767444c061aSmrg}
1768444c061aSmrg
1769444c061aSmrg/*
1770444c061aSmrg * If the Shell has a width and a height which are zero, and as such
1771444c061aSmrg * suspect, and it has not yet been realized then it will grow to
1772444c061aSmrg * match the child before parsing the geometry resource.
1773444c061aSmrg *
1774444c061aSmrg */
1775a3bd7f05Smrgstatic void
1776a3bd7f05SmrgGetGeometry(Widget W, Widget child)
1777444c061aSmrg{
1778a3bd7f05Smrg    register ShellWidget w = (ShellWidget) W;
1779444c061aSmrg    Boolean is_wmshell = XtIsWMShell(W);
1780444c061aSmrg    int x, y, width, height, win_gravity = -1, flag;
1781444c061aSmrg    XSizeHints hints;
1782444c061aSmrg
1783444c061aSmrg    if (child != NULL) {
1784a3bd7f05Smrg        /* we default to our child's size */
1785a3bd7f05Smrg        if (is_wmshell && (w->core.width == 0 || w->core.height == 0))
1786a3bd7f05Smrg            ((WMShellWidget) W)->wm.size_hints.flags |= PSize;
1787a3bd7f05Smrg        if (w->core.width == 0)
1788a3bd7f05Smrg            w->core.width = child->core.width;
1789a3bd7f05Smrg        if (w->core.height == 0)
1790a3bd7f05Smrg            w->core.height = child->core.height;
1791a3bd7f05Smrg    }
1792a3bd7f05Smrg    if (w->shell.geometry != NULL) {
1793a3bd7f05Smrg        char def_geom[64];
1794a3bd7f05Smrg
1795a3bd7f05Smrg        x = w->core.x;
1796a3bd7f05Smrg        y = w->core.y;
1797a3bd7f05Smrg        width = w->core.width;
1798a3bd7f05Smrg        height = w->core.height;
1799a3bd7f05Smrg        if (is_wmshell) {
1800a3bd7f05Smrg            WMShellPart *wm = &((WMShellWidget) w)->wm;
1801a3bd7f05Smrg
1802a3bd7f05Smrg            EvaluateSizeHints((WMShellWidget) w);
1803fdf6a26fSmrg            (void) memcpy(&hints, &wm->size_hints,
1804fdf6a26fSmrg                          sizeof(struct _OldXSizeHints));
1805a3bd7f05Smrg            hints.win_gravity = wm->win_gravity;
1806a3bd7f05Smrg            if (wm->size_hints.flags & PBaseSize) {
1807a3bd7f05Smrg                width -= wm->base_width;
1808a3bd7f05Smrg                height -= wm->base_height;
1809a3bd7f05Smrg                hints.base_width = wm->base_width;
1810a3bd7f05Smrg                hints.base_height = wm->base_height;
1811a3bd7f05Smrg            }
1812a3bd7f05Smrg            else if (wm->size_hints.flags & PMinSize) {
1813a3bd7f05Smrg                width -= wm->size_hints.min_width;
1814a3bd7f05Smrg                height -= wm->size_hints.min_height;
1815a3bd7f05Smrg            }
1816a3bd7f05Smrg            if (wm->size_hints.flags & PResizeInc) {
1817a3bd7f05Smrg                width /= wm->size_hints.width_inc;
1818a3bd7f05Smrg                height /= wm->size_hints.height_inc;
1819a3bd7f05Smrg            }
1820a3bd7f05Smrg        }
1821a3bd7f05Smrg        else
1822a3bd7f05Smrg            hints.flags = 0;
1823a3bd7f05Smrg
1824a3bd7f05Smrg        snprintf(def_geom, sizeof(def_geom), "%dx%d+%d+%d",
1825a3bd7f05Smrg                 width, height, x, y);
1826a3bd7f05Smrg        flag = XWMGeometry(XtDisplay(W),
1827a3bd7f05Smrg                           XScreenNumberOfScreen(XtScreen(W)),
1828a3bd7f05Smrg                           w->shell.geometry, def_geom,
1829a3bd7f05Smrg                           (unsigned int) w->core.border_width,
1830a3bd7f05Smrg                           &hints, &x, &y, &width, &height, &win_gravity);
1831a3bd7f05Smrg        if (flag) {
1832a3bd7f05Smrg            if (flag & XValue)
1833a3bd7f05Smrg                w->core.x = (Position) x;
1834a3bd7f05Smrg            if (flag & YValue)
1835a3bd7f05Smrg                w->core.y = (Position) y;
1836a3bd7f05Smrg            if (flag & WidthValue)
1837a3bd7f05Smrg                w->core.width = (Dimension) width;
1838a3bd7f05Smrg            if (flag & HeightValue)
1839a3bd7f05Smrg                w->core.height = (Dimension) height;
1840a3bd7f05Smrg        }
1841a3bd7f05Smrg        else {
1842a3bd7f05Smrg            String params[2];
1843a3bd7f05Smrg            Cardinal num_params = 2;
1844a3bd7f05Smrg
1845a3bd7f05Smrg            params[0] = XtName(W);
1846a3bd7f05Smrg            params[1] = w->shell.geometry;
1847a3bd7f05Smrg            XtAppWarningMsg(XtWidgetToApplicationContext(W),
1848a3bd7f05Smrg                            "badGeometry", "shellRealize", XtCXtToolkitError,
1849a3bd7f05Smrg                            "Shell widget \"%s\" has an invalid geometry specification: \"%s\"",
1850a3bd7f05Smrg                            params, &num_params);
1851a3bd7f05Smrg        }
1852444c061aSmrg    }
1853444c061aSmrg    else
1854a3bd7f05Smrg        flag = 0;
1855444c061aSmrg
1856444c061aSmrg    if (is_wmshell) {
1857a3bd7f05Smrg        WMShellWidget wmshell = (WMShellWidget) w;
1858a3bd7f05Smrg
1859a3bd7f05Smrg        if (wmshell->wm.win_gravity == XtUnspecifiedShellInt) {
1860a3bd7f05Smrg            if (win_gravity != -1)
1861a3bd7f05Smrg                wmshell->wm.win_gravity = win_gravity;
1862a3bd7f05Smrg            else
1863a3bd7f05Smrg                wmshell->wm.win_gravity = NorthWestGravity;
1864a3bd7f05Smrg        }
1865a3bd7f05Smrg        wmshell->wm.size_hints.flags |= PWinGravity;
1866a3bd7f05Smrg        if ((flag & (XValue | YValue)) == (XValue | YValue))
1867a3bd7f05Smrg            wmshell->wm.size_hints.flags |= USPosition;
1868a3bd7f05Smrg        if ((flag & (WidthValue | HeightValue)) == (WidthValue | HeightValue))
1869a3bd7f05Smrg            wmshell->wm.size_hints.flags |= USSize;
1870444c061aSmrg    }
1871444c061aSmrg    w->shell.client_specified |= _XtShellGeometryParsed;
1872444c061aSmrg}
1873444c061aSmrg
1874a3bd7f05Smrgstatic void
1875a3bd7f05SmrgChangeManaged(Widget wid)
1876444c061aSmrg{
1877444c061aSmrg    ShellWidget w = (ShellWidget) wid;
1878444c061aSmrg    Widget child = NULL;
1879444c061aSmrg    Cardinal i;
1880444c061aSmrg
1881444c061aSmrg    for (i = 0; i < w->composite.num_children; i++) {
1882a3bd7f05Smrg        if (XtIsManaged(w->composite.children[i])) {
1883a3bd7f05Smrg            child = w->composite.children[i];
1884a3bd7f05Smrg            break;              /* there can only be one of them! */
1885a3bd7f05Smrg        }
1886444c061aSmrg    }
1887444c061aSmrg
1888a3bd7f05Smrg    if (!XtIsRealized(wid))     /* then we're about to be realized... */
1889a3bd7f05Smrg        GetGeometry(wid, child);
1890444c061aSmrg
1891444c061aSmrg    if (child != NULL)
1892a3bd7f05Smrg        XtConfigureWidget(child, (Position) 0, (Position) 0,
1893a3bd7f05Smrg                          w->core.width, w->core.height, (Dimension) 0);
1894444c061aSmrg}
1895444c061aSmrg
1896444c061aSmrg/*
1897444c061aSmrg * This is gross, I can't wait to see if the change happened so I will ask
1898444c061aSmrg * the window manager to change my size and do the appropriate X work.
1899444c061aSmrg * I will then tell the requester that he can.  Care must be taken because
1900444c061aSmrg * it is possible that some time in the future the request will be
1901444c061aSmrg * asynchronusly denied and the window reverted to it's old size/shape.
1902444c061aSmrg */
1903444c061aSmrg
1904a3bd7f05Smrgstatic XtGeometryResult
1905a3bd7f05SmrgGeometryManager(Widget wid,
1906a3bd7f05Smrg                XtWidgetGeometry *request,
1907a3bd7f05Smrg                XtWidgetGeometry *reply _X_UNUSED)
1908a3bd7f05Smrg{
1909a3bd7f05Smrg    ShellWidget shell = (ShellWidget) (wid->core.parent);
1910a3bd7f05Smrg    XtWidgetGeometry my_request;
1911a3bd7f05Smrg
1912a3bd7f05Smrg    if (shell->shell.allow_shell_resize == FALSE && XtIsRealized(wid))
1913a3bd7f05Smrg        return (XtGeometryNo);
1914a3bd7f05Smrg
1915a3bd7f05Smrg    if (request->request_mode & (CWX | CWY))
1916a3bd7f05Smrg        return (XtGeometryNo);
1917a3bd7f05Smrg
1918a3bd7f05Smrg    my_request.request_mode = (request->request_mode & XtCWQueryOnly);
1919a3bd7f05Smrg    if (request->request_mode & CWWidth) {
1920a3bd7f05Smrg        my_request.width = request->width;
1921a3bd7f05Smrg        my_request.request_mode |= CWWidth;
1922a3bd7f05Smrg    }
1923a3bd7f05Smrg    if (request->request_mode & CWHeight) {
1924a3bd7f05Smrg        my_request.height = request->height;
1925a3bd7f05Smrg        my_request.request_mode |= CWHeight;
1926a3bd7f05Smrg    }
1927a3bd7f05Smrg    if (request->request_mode & CWBorderWidth) {
1928a3bd7f05Smrg        my_request.border_width = request->border_width;
1929a3bd7f05Smrg        my_request.request_mode |= CWBorderWidth;
1930a3bd7f05Smrg    }
1931a3bd7f05Smrg    if (XtMakeGeometryRequest((Widget) shell, &my_request, NULL)
1932a3bd7f05Smrg        == XtGeometryYes) {
1933a3bd7f05Smrg        /* assert: if (request->request_mode & CWWidth) then
1934a3bd7f05Smrg         *            shell->core.width == request->width
1935a3bd7f05Smrg         * assert: if (request->request_mode & CWHeight) then
1936a3bd7f05Smrg         *            shell->core.height == request->height
1937a3bd7f05Smrg         *
1938a3bd7f05Smrg         * so, whatever the WM sized us to (if the Shell requested
1939a3bd7f05Smrg         * only one of the two) is now the correct child size
1940a3bd7f05Smrg         */
1941a3bd7f05Smrg
1942a3bd7f05Smrg        if (!(request->request_mode & XtCWQueryOnly)) {
1943a3bd7f05Smrg            wid->core.width = shell->core.width;
1944a3bd7f05Smrg            wid->core.height = shell->core.height;
1945a3bd7f05Smrg            if (request->request_mode & CWBorderWidth) {
1946a3bd7f05Smrg                wid->core.x = wid->core.y = (Position) (-request->border_width);
1947a3bd7f05Smrg            }
1948a3bd7f05Smrg        }
1949a3bd7f05Smrg        return XtGeometryYes;
1950a3bd7f05Smrg    }
1951a3bd7f05Smrg    else
1952a3bd7f05Smrg        return XtGeometryNo;
1953444c061aSmrg}
1954444c061aSmrg
1955444c061aSmrgtypedef struct {
1956a3bd7f05Smrg    Widget w;
1957a3bd7f05Smrg    unsigned long request_num;
1958a3bd7f05Smrg    Boolean done;
1959444c061aSmrg} QueryStruct;
1960444c061aSmrg
1961a3bd7f05Smrgstatic Bool
1962a3bd7f05SmrgisMine(Display *dpy, register XEvent *event, char *arg)
1963a3bd7f05Smrg{
1964a3bd7f05Smrg    QueryStruct *q = (QueryStruct *) arg;
1965a3bd7f05Smrg    register Widget w = q->w;
1966a3bd7f05Smrg
1967a3bd7f05Smrg    if ((dpy != XtDisplay(w)) || (event->xany.window != XtWindow(w))) {
1968a3bd7f05Smrg        return FALSE;
1969a3bd7f05Smrg    }
1970a3bd7f05Smrg    if (event->xany.serial >= q->request_num) {
1971a3bd7f05Smrg        if (event->type == ConfigureNotify) {
1972a3bd7f05Smrg            q->done = TRUE;
1973a3bd7f05Smrg            return TRUE;
1974a3bd7f05Smrg        }
1975a3bd7f05Smrg    }
1976a3bd7f05Smrg    else if (event->type == ConfigureNotify)
1977a3bd7f05Smrg        return TRUE;            /* flush old events */
1978a3bd7f05Smrg    if (event->type == ReparentNotify && event->xreparent.window == XtWindow(w)) {
1979a3bd7f05Smrg        /* we might get ahead of this event, so just in case someone
1980a3bd7f05Smrg         * asks for coordinates before this event is dispatched...
1981a3bd7f05Smrg         */
1982a3bd7f05Smrg        register ShellWidget s = (ShellWidget) w;
1983a3bd7f05Smrg
1984a3bd7f05Smrg        if (event->xreparent.parent != RootWindowOfScreen(XtScreen(w)))
1985a3bd7f05Smrg            s->shell.client_specified &= ~_XtShellNotReparented;
1986a3bd7f05Smrg        else
1987a3bd7f05Smrg            s->shell.client_specified |= _XtShellNotReparented;
1988a3bd7f05Smrg    }
1989a3bd7f05Smrg    return FALSE;
1990a3bd7f05Smrg}
1991a3bd7f05Smrg
1992a3bd7f05Smrgstatic Boolean
1993a3bd7f05Smrg_wait_for_response(ShellWidget w, XEvent *event, unsigned long request_num)
1994a3bd7f05Smrg{
1995a3bd7f05Smrg    XtAppContext app = XtWidgetToApplicationContext((Widget) w);
1996a3bd7f05Smrg    QueryStruct q;
1997a3bd7f05Smrg    unsigned long timeout;
1998a3bd7f05Smrg
1999a3bd7f05Smrg    if (XtIsWMShell((Widget) w))
2000a3bd7f05Smrg        timeout = (unsigned long) ((WMShellWidget) w)->wm.wm_timeout;
2001a3bd7f05Smrg    else
2002a3bd7f05Smrg        timeout = DEFAULT_WM_TIMEOUT;
2003a3bd7f05Smrg
2004a3bd7f05Smrg    XFlush(XtDisplay(w));
2005a3bd7f05Smrg    q.w = (Widget) w;
2006a3bd7f05Smrg    q.request_num = request_num;
2007a3bd7f05Smrg    q.done = FALSE;
2008a3bd7f05Smrg
2009a3bd7f05Smrg    /*
2010a3bd7f05Smrg     * look for match event and discard all prior configures
2011a3bd7f05Smrg     */
2012a3bd7f05Smrg    while (XCheckIfEvent(XtDisplay(w), event, isMine, (char *) &q)) {
2013a3bd7f05Smrg        if (q.done)
2014a3bd7f05Smrg            return TRUE;
2015a3bd7f05Smrg    }
2016a3bd7f05Smrg
2017a3bd7f05Smrg    while (timeout > 0) {
2018a3bd7f05Smrg        if (_XtWaitForSomething(app, FALSE, TRUE, TRUE, TRUE, TRUE,
2019444c061aSmrg#ifdef XTHREADS
2020a3bd7f05Smrg                                FALSE,
2021444c061aSmrg#endif
2022a3bd7f05Smrg                                &timeout) != -1) {
2023a3bd7f05Smrg            while (XCheckIfEvent(XtDisplay(w), event, isMine, (char *) &q)) {
2024a3bd7f05Smrg                if (q.done)
2025a3bd7f05Smrg                    return TRUE;
2026a3bd7f05Smrg            }
2027a3bd7f05Smrg        }
2028a3bd7f05Smrg    }
2029a3bd7f05Smrg    return FALSE;
2030444c061aSmrg}
2031444c061aSmrg
2032a3bd7f05Smrgstatic XtGeometryResult
2033a3bd7f05SmrgRootGeometryManager(Widget gw,
2034a3bd7f05Smrg                    XtWidgetGeometry *request,
2035a3bd7f05Smrg                    XtWidgetGeometry *reply _X_UNUSED)
2036444c061aSmrg{
2037a3bd7f05Smrg    register ShellWidget w = (ShellWidget) gw;
2038444c061aSmrg    XWindowChanges values;
2039444c061aSmrg    unsigned int mask = request->request_mode;
2040444c061aSmrg    XEvent event;
2041444c061aSmrg    Boolean wm;
2042444c061aSmrg    register struct _OldXSizeHints *hintp = NULL;
2043444c061aSmrg    int oldx, oldy, oldwidth, oldheight, oldborder_width;
2044444c061aSmrg    unsigned long request_num;
2045444c061aSmrg
2046444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
2047444c061aSmrg
2048444c061aSmrg    if (XtIsWMShell(gw)) {
2049a3bd7f05Smrg        wm = True;
2050a3bd7f05Smrg        hintp = &((WMShellWidget) w)->wm.size_hints;
2051a3bd7f05Smrg        /* for draft-ICCCM wm's, need to make sure hints reflect
2052a3bd7f05Smrg           (current) reality so client can move and size separately. */
2053a3bd7f05Smrg        hintp->x = w->core.x;
2054a3bd7f05Smrg        hintp->y = w->core.y;
2055a3bd7f05Smrg        hintp->width = w->core.width;
2056a3bd7f05Smrg        hintp->height = w->core.height;
2057a3bd7f05Smrg    }
2058a3bd7f05Smrg    else
2059a3bd7f05Smrg        wm = False;
2060444c061aSmrg
2061444c061aSmrg    oldx = w->core.x;
2062444c061aSmrg    oldy = w->core.y;
2063444c061aSmrg    oldwidth = w->core.width;
2064444c061aSmrg    oldheight = w->core.height;
2065444c061aSmrg    oldborder_width = w->core.border_width;
2066444c061aSmrg
2067444c061aSmrg#define PutBackGeometry() \
2068a3bd7f05Smrg        { w->core.x = (Position) (oldx); \
2069a3bd7f05Smrg          w->core.y = (Position) (oldy); \
2070a3bd7f05Smrg          w->core.width = (Dimension) (oldwidth); \
2071a3bd7f05Smrg          w->core.height = (Dimension) (oldheight); \
2072a3bd7f05Smrg          w->core.border_width = (Dimension) (oldborder_width); }
2073444c061aSmrg
20740568f49bSmrg    memset(&values, 0, sizeof(values));
2075444c061aSmrg    if (mask & CWX) {
2076a3bd7f05Smrg        if (w->core.x == request->x)
2077a3bd7f05Smrg            mask &= (unsigned int) (~CWX);
2078a3bd7f05Smrg        else {
2079a3bd7f05Smrg            w->core.x = (Position) (values.x = request->x);
2080a3bd7f05Smrg            if (wm) {
2081a3bd7f05Smrg                hintp->flags &= ~USPosition;
2082a3bd7f05Smrg                hintp->flags |= PPosition;
2083a3bd7f05Smrg                hintp->x = values.x;
2084a3bd7f05Smrg            }
2085a3bd7f05Smrg        }
2086444c061aSmrg    }
2087444c061aSmrg    if (mask & CWY) {
2088a3bd7f05Smrg        if (w->core.y == request->y)
2089a3bd7f05Smrg            mask &= (unsigned int) (~CWY);
2090a3bd7f05Smrg        else {
2091a3bd7f05Smrg            w->core.y = (Position) (values.y = request->y);
2092a3bd7f05Smrg            if (wm) {
2093a3bd7f05Smrg                hintp->flags &= ~USPosition;
2094a3bd7f05Smrg                hintp->flags |= PPosition;
2095a3bd7f05Smrg                hintp->y = values.y;
2096a3bd7f05Smrg            }
2097a3bd7f05Smrg        }
2098444c061aSmrg    }
2099444c061aSmrg    if (mask & CWBorderWidth) {
2100a3bd7f05Smrg        if (w->core.border_width == request->border_width) {
2101a3bd7f05Smrg            mask &= (unsigned int) (~CWBorderWidth);
2102a3bd7f05Smrg        }
2103a3bd7f05Smrg        else
2104a3bd7f05Smrg            w->core.border_width =
2105a3bd7f05Smrg                (Dimension) (values.border_width = request->border_width);
2106444c061aSmrg    }
2107444c061aSmrg    if (mask & CWWidth) {
2108a3bd7f05Smrg        if (w->core.width == request->width)
2109a3bd7f05Smrg            mask &= (unsigned int) (~CWWidth);
2110a3bd7f05Smrg        else {
2111a3bd7f05Smrg            w->core.width = (Dimension) (values.width = request->width);
2112a3bd7f05Smrg            if (wm) {
2113a3bd7f05Smrg                hintp->flags &= ~USSize;
2114a3bd7f05Smrg                hintp->flags |= PSize;
2115a3bd7f05Smrg                hintp->width = values.width;
2116a3bd7f05Smrg            }
2117a3bd7f05Smrg        }
2118444c061aSmrg    }
2119444c061aSmrg    if (mask & CWHeight) {
2120a3bd7f05Smrg        if (w->core.height == request->height)
2121a3bd7f05Smrg            mask &= (unsigned int) (~CWHeight);
2122a3bd7f05Smrg        else {
2123a3bd7f05Smrg            w->core.height = (Dimension) (values.height = request->height);
2124a3bd7f05Smrg            if (wm) {
2125a3bd7f05Smrg                hintp->flags &= ~USSize;
2126a3bd7f05Smrg                hintp->flags |= PSize;
2127a3bd7f05Smrg                hintp->height = values.height;
2128a3bd7f05Smrg            }
2129a3bd7f05Smrg        }
2130444c061aSmrg    }
2131444c061aSmrg    if (mask & CWStackMode) {
2132a3bd7f05Smrg        values.stack_mode = request->stack_mode;
2133a3bd7f05Smrg        if (mask & CWSibling)
2134a3bd7f05Smrg            values.sibling = XtWindow(request->sibling);
2135444c061aSmrg    }
2136444c061aSmrg
2137a3bd7f05Smrg    if (!XtIsRealized((Widget) w)) {
2138a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w,
2139a3bd7f05Smrg                               "Shell \"%s\" is not realized, return XtGeometryYes.\n",
2140a3bd7f05Smrg                               XtName((Widget) w)));
2141a3bd7f05Smrg        CALLGEOTAT(_XtGeoTab(-1));
2142a3bd7f05Smrg        return XtGeometryYes;
2143444c061aSmrg    }
2144444c061aSmrg
2145444c061aSmrg    request_num = NextRequest(XtDisplay(w));
2146444c061aSmrg
2147a3bd7f05Smrg    CALLGEOTAT(_XtGeoTrace((Widget) w, "XConfiguring the Shell X window :\n"));
2148444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
2149444c061aSmrg#ifdef XT_GEO_TATTLER
2150a3bd7f05Smrg    if (mask & CWX) {
2151a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "x = %d\n", values.x));
2152a3bd7f05Smrg    }
2153a3bd7f05Smrg    if (mask & CWY) {
2154a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "y = %d\n", values.y));
2155a3bd7f05Smrg    }
2156a3bd7f05Smrg    if (mask & CWWidth) {
2157a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "width = %d\n", values.width));
2158a3bd7f05Smrg    }
2159a3bd7f05Smrg    if (mask & CWHeight) {
2160a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "height = %d\n", values.height));
2161a3bd7f05Smrg    }
2162a3bd7f05Smrg    if (mask & CWBorderWidth) {
2163a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w,
2164a3bd7f05Smrg                               "border_width = %d\n", values.border_width));
2165a3bd7f05Smrg    }
2166444c061aSmrg#endif
2167444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
2168444c061aSmrg
2169a3bd7f05Smrg    XConfigureWindow(XtDisplay((Widget) w), XtWindow((Widget) w), mask,
2170a3bd7f05Smrg                     &values);
2171444c061aSmrg
2172444c061aSmrg    if (wm && !w->shell.override_redirect
2173a3bd7f05Smrg        && mask & (CWX | CWY | CWWidth | CWHeight | CWBorderWidth)) {
2174a3bd7f05Smrg        _SetWMSizeHints((WMShellWidget) w);
2175444c061aSmrg    }
2176444c061aSmrg
2177444c061aSmrg    if (w->shell.override_redirect) {
2178a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace
2179a3bd7f05Smrg                   ((Widget) w,
2180a3bd7f05Smrg                    "Shell \"%s\" is override redirect, return XtGeometryYes.\n",
2181a3bd7f05Smrg                    XtName((Widget) w)));
2182a3bd7f05Smrg        CALLGEOTAT(_XtGeoTab(-1));
2183a3bd7f05Smrg        return XtGeometryYes;
2184444c061aSmrg    }
2185444c061aSmrg
2186444c061aSmrg    /* If no non-stacking bits are set, there's no way to tell whether
2187444c061aSmrg       or not this worked, so assume it did */
2188444c061aSmrg
2189a3bd7f05Smrg    if (!(mask & (unsigned) (~(CWStackMode | CWSibling))))
2190a3bd7f05Smrg        return XtGeometryYes;
2191444c061aSmrg
2192a3bd7f05Smrg    if (wm && ((WMShellWidget) w)->wm.wait_for_wm == FALSE) {
2193a3bd7f05Smrg        /* the window manager is sick
2194a3bd7f05Smrg         * so I will do the work and
2195a3bd7f05Smrg         * say no so if a new WM starts up,
2196a3bd7f05Smrg         * or the current one recovers
2197a3bd7f05Smrg         * my size requests will be visible
2198a3bd7f05Smrg         */
2199a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace
2200a3bd7f05Smrg                   ((Widget) w,
2201a3bd7f05Smrg                    "Shell \"%s\" has wait_for_wm == FALSE, return XtGeometryNo.\n",
2202a3bd7f05Smrg                    XtName((Widget) w)));
2203a3bd7f05Smrg        CALLGEOTAT(_XtGeoTab(-1));
2204444c061aSmrg
2205a3bd7f05Smrg        PutBackGeometry();
2206a3bd7f05Smrg        return XtGeometryNo;
2207444c061aSmrg    }
2208444c061aSmrg
2209444c061aSmrg    if (_wait_for_response(w, &event, request_num)) {
2210a3bd7f05Smrg        /* got an event */
2211a3bd7f05Smrg        if (event.type == ConfigureNotify) {
2212444c061aSmrg
2213444c061aSmrg#define NEQ(x, msk) ((mask & msk) && (values.x != event.xconfigure.x))
2214a3bd7f05Smrg            if (NEQ(x, CWX) ||
2215a3bd7f05Smrg                NEQ(y, CWY) ||
2216a3bd7f05Smrg                NEQ(width, CWWidth) ||
2217a3bd7f05Smrg                NEQ(height, CWHeight) || NEQ(border_width, CWBorderWidth)) {
2218444c061aSmrg#ifdef XT_GEO_TATTLER
2219a3bd7f05Smrg                if (NEQ(x, CWX)) {
2220a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2221a3bd7f05Smrg                                           "received Configure X %d\n",
2222a3bd7f05Smrg                                           event.xconfigure.x));
2223a3bd7f05Smrg                }
2224a3bd7f05Smrg                if (NEQ(y, CWY)) {
2225a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2226a3bd7f05Smrg                                           "received Configure Y %d\n",
2227a3bd7f05Smrg                                           event.xconfigure.y));
2228a3bd7f05Smrg                }
2229a3bd7f05Smrg                if (NEQ(width, CWWidth)) {
2230a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2231a3bd7f05Smrg                                           "received Configure Width %d\n",
2232a3bd7f05Smrg                                           event.xconfigure.width));
2233a3bd7f05Smrg                }
2234a3bd7f05Smrg                if (NEQ(height, CWHeight)) {
2235a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2236a3bd7f05Smrg                                           "received Configure Height %d\n",
2237a3bd7f05Smrg                                           event.xconfigure.height));
2238a3bd7f05Smrg                }
2239a3bd7f05Smrg                if (NEQ(border_width, CWBorderWidth)) {
2240a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2241a3bd7f05Smrg                                           "received Configure BorderWidth %d\n",
2242a3bd7f05Smrg                                           event.xconfigure.border_width));
2243a3bd7f05Smrg                }
2244444c061aSmrg#endif
2245444c061aSmrg#undef NEQ
2246a3bd7f05Smrg                XPutBackEvent(XtDisplay(w), &event);
2247a3bd7f05Smrg                PutBackGeometry();
2248a3bd7f05Smrg                /*
2249a3bd7f05Smrg                 * We just potentially re-ordered the event queue
2250a3bd7f05Smrg                 * w.r.t. ConfigureNotifies with some trepidation.
2251a3bd7f05Smrg                 * But this is probably a Good Thing because we
2252a3bd7f05Smrg                 * will know the new true state of the world sooner
2253a3bd7f05Smrg                 * this way.
2254a3bd7f05Smrg                 */
2255a3bd7f05Smrg                CALLGEOTAT(_XtGeoTrace((Widget) w,
2256a3bd7f05Smrg                                       "ConfigureNotify failed, return XtGeometryNo.\n"));
2257a3bd7f05Smrg                CALLGEOTAT(_XtGeoTab(-1));
2258a3bd7f05Smrg
2259a3bd7f05Smrg                return XtGeometryNo;
2260a3bd7f05Smrg            }
2261a3bd7f05Smrg            else {
2262a3bd7f05Smrg                w->core.width = (Dimension) event.xconfigure.width;
2263a3bd7f05Smrg                w->core.height = (Dimension) event.xconfigure.height;
2264a3bd7f05Smrg                w->core.border_width =
2265a3bd7f05Smrg                    (Dimension) event.xconfigure.border_width;
2266a3bd7f05Smrg                if (event.xany.send_event ||    /* ICCCM compliant synth */
2267a3bd7f05Smrg                    w->shell.client_specified & _XtShellNotReparented) {
2268a3bd7f05Smrg
2269a3bd7f05Smrg                    w->core.x = (Position) event.xconfigure.x;
2270a3bd7f05Smrg                    w->core.y = (Position) event.xconfigure.y;
2271a3bd7f05Smrg                    w->shell.client_specified |= _XtShellPositionValid;
2272a3bd7f05Smrg                }
2273a3bd7f05Smrg                else
2274a3bd7f05Smrg                    w->shell.client_specified &= ~_XtShellPositionValid;
2275a3bd7f05Smrg                CALLGEOTAT(_XtGeoTrace((Widget) w,
2276a3bd7f05Smrg                                       "ConfigureNotify succeed, return XtGeometryYes.\n"));
2277a3bd7f05Smrg                CALLGEOTAT(_XtGeoTab(-1));
2278a3bd7f05Smrg                return XtGeometryYes;
2279a3bd7f05Smrg            }
2280a3bd7f05Smrg        }
2281a3bd7f05Smrg        else if (!wm) {
2282a3bd7f05Smrg            PutBackGeometry();
2283a3bd7f05Smrg            CALLGEOTAT(_XtGeoTrace((Widget) w,
2284a3bd7f05Smrg                                   "Not wm, return XtGeometryNo.\n"));
2285a3bd7f05Smrg            CALLGEOTAT(_XtGeoTab(-1));
2286a3bd7f05Smrg            return XtGeometryNo;
2287a3bd7f05Smrg        }
2288a3bd7f05Smrg        else
2289a3bd7f05Smrg            XtAppWarningMsg(XtWidgetToApplicationContext((Widget) w),
2290a3bd7f05Smrg                            "internalError", "shell", XtCXtToolkitError,
2291a3bd7f05Smrg                            "Shell's window manager interaction is broken",
2292a3bd7f05Smrg                            NULL, NULL);
2293a3bd7f05Smrg    }
2294a3bd7f05Smrg    else if (wm) {              /* no event */
2295a3bd7f05Smrg        ((WMShellWidget) w)->wm.wait_for_wm = FALSE;    /* timed out; must be broken */
2296444c061aSmrg    }
2297444c061aSmrg    PutBackGeometry();
2298444c061aSmrg#undef PutBackGeometry
2299a3bd7f05Smrg    CALLGEOTAT(_XtGeoTrace((Widget) w,
2300a3bd7f05Smrg                           "Timeout passed?, return XtGeometryNo.\n"));
2301444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
2302444c061aSmrg    return XtGeometryNo;
2303a3bd7f05Smrg}
2304a3bd7f05Smrg
2305a3bd7f05Smrgstatic Boolean
2306a3bd7f05SmrgSetValues(Widget old,
2307a3bd7f05Smrg          Widget ref _X_UNUSED,
2308a3bd7f05Smrg          Widget new,
2309a3bd7f05Smrg          ArgList args,
2310a3bd7f05Smrg          Cardinal *num_args)
2311a3bd7f05Smrg{
2312a3bd7f05Smrg    ShellWidget nw = (ShellWidget) new;
2313a3bd7f05Smrg    ShellWidget ow = (ShellWidget) old;
2314a3bd7f05Smrg    Mask mask = 0;
2315a3bd7f05Smrg    XSetWindowAttributes attr;
2316a3bd7f05Smrg
2317a3bd7f05Smrg    if (!XtIsRealized(new))
2318a3bd7f05Smrg        return False;
2319a3bd7f05Smrg
2320a3bd7f05Smrg    if (ow->shell.save_under != nw->shell.save_under) {
2321a3bd7f05Smrg        mask = CWSaveUnder;
2322a3bd7f05Smrg        attr.save_under = nw->shell.save_under;
2323a3bd7f05Smrg    }
2324a3bd7f05Smrg
2325a3bd7f05Smrg    if (ow->shell.override_redirect != nw->shell.override_redirect) {
2326a3bd7f05Smrg        mask |= CWOverrideRedirect;
2327a3bd7f05Smrg        attr.override_redirect = nw->shell.override_redirect;
2328a3bd7f05Smrg    }
2329a3bd7f05Smrg
2330a3bd7f05Smrg    if (mask) {
2331a3bd7f05Smrg        XChangeWindowAttributes(XtDisplay(new), XtWindow(new), mask, &attr);
2332a3bd7f05Smrg        if ((mask & CWOverrideRedirect) && !nw->shell.override_redirect)
2333a3bd7f05Smrg            _popup_set_prop(nw);
2334a3bd7f05Smrg    }
2335a3bd7f05Smrg
2336a3bd7f05Smrg    if (!(ow->shell.client_specified & _XtShellPositionValid)) {
2337a3bd7f05Smrg        Cardinal n;
2338a3bd7f05Smrg
2339a3bd7f05Smrg        for (n = *num_args; n; n--, args++) {
2340a3bd7f05Smrg            if (strcmp(XtNx, args->name) == 0) {
2341a3bd7f05Smrg                _XtShellGetCoordinates((Widget) ow, &ow->core.x, &ow->core.y);
2342a3bd7f05Smrg            }
2343a3bd7f05Smrg            else if (strcmp(XtNy, args->name) == 0) {
2344a3bd7f05Smrg                _XtShellGetCoordinates((Widget) ow, &ow->core.x, &ow->core.y);
2345a3bd7f05Smrg            }
2346a3bd7f05Smrg        }
2347a3bd7f05Smrg    }
2348a3bd7f05Smrg    return FALSE;
2349a3bd7f05Smrg}
2350a3bd7f05Smrg
2351a3bd7f05Smrgstatic Boolean
2352a3bd7f05SmrgWMSetValues(Widget old,
2353a3bd7f05Smrg            Widget ref _X_UNUSED,
2354a3bd7f05Smrg            Widget new,
2355a3bd7f05Smrg            ArgList args _X_UNUSED,
2356a3bd7f05Smrg            Cardinal *num_args _X_UNUSED)
2357a3bd7f05Smrg{
2358a3bd7f05Smrg    WMShellWidget nwmshell = (WMShellWidget) new;
2359a3bd7f05Smrg    WMShellWidget owmshell = (WMShellWidget) old;
2360a3bd7f05Smrg    Boolean set_prop = XtIsRealized(new) && !nwmshell->shell.override_redirect;
2361a3bd7f05Smrg    Boolean title_changed;
2362a3bd7f05Smrg
2363a3bd7f05Smrg    EvaluateSizeHints(nwmshell);
2364444c061aSmrg
2365444c061aSmrg#define NEQ(f) (nwmshell->wm.size_hints.f != owmshell->wm.size_hints.f)
2366444c061aSmrg
2367a3bd7f05Smrg    if (set_prop && (NEQ(flags) || NEQ(min_width) || NEQ(min_height)
2368a3bd7f05Smrg                     || NEQ(max_width) || NEQ(max_height)
2369a3bd7f05Smrg                     || NEQ(width_inc) || NEQ(height_inc)
2370a3bd7f05Smrg                     || NEQ(min_aspect.x) || NEQ(min_aspect.y)
2371a3bd7f05Smrg                     || NEQ(max_aspect.x) || NEQ(max_aspect.y)
2372444c061aSmrg#undef NEQ
2373444c061aSmrg#define NEQ(f) (nwmshell->wm.f != owmshell->wm.f)
2374a3bd7f05Smrg                     || NEQ(base_width) || NEQ(base_height) ||
2375a3bd7f05Smrg                     NEQ(win_gravity))) {
2376a3bd7f05Smrg        _SetWMSizeHints(nwmshell);
2377a3bd7f05Smrg    }
2378444c061aSmrg#undef NEQ
2379444c061aSmrg
2380a3bd7f05Smrg    if (nwmshell->wm.title != owmshell->wm.title) {
2381a3bd7f05Smrg        XtFree(owmshell->wm.title);
2382a3bd7f05Smrg        if (!nwmshell->wm.title)
2383a3bd7f05Smrg            nwmshell->wm.title = (_XtString) "";
2384a3bd7f05Smrg        nwmshell->wm.title = XtNewString(nwmshell->wm.title);
2385a3bd7f05Smrg        title_changed = True;
2386a3bd7f05Smrg    }
2387a3bd7f05Smrg    else
2388a3bd7f05Smrg        title_changed = False;
2389a3bd7f05Smrg
2390a3bd7f05Smrg    if (set_prop
2391a3bd7f05Smrg        && (title_changed ||
2392a3bd7f05Smrg            nwmshell->wm.title_encoding != owmshell->wm.title_encoding)) {
2393a3bd7f05Smrg
2394a3bd7f05Smrg        XTextProperty title;
2395a3bd7f05Smrg        Boolean copied = False;
2396a3bd7f05Smrg
2397a3bd7f05Smrg        if (nwmshell->wm.title_encoding == None &&
2398a3bd7f05Smrg            XmbTextListToTextProperty(XtDisplay(new),
2399a3bd7f05Smrg                                      (char **) &nwmshell->wm.title,
2400a3bd7f05Smrg                                      1, XStdICCTextStyle, &title) >= Success) {
2401a3bd7f05Smrg            copied = True;
2402a3bd7f05Smrg        }
2403a3bd7f05Smrg        else {
2404a3bd7f05Smrg            title.value = (unsigned char *) nwmshell->wm.title;
2405a3bd7f05Smrg            title.encoding = nwmshell->wm.title_encoding ?
2406a3bd7f05Smrg                nwmshell->wm.title_encoding : XA_STRING;
2407a3bd7f05Smrg            title.format = 8;
2408a3bd7f05Smrg            title.nitems = strlen(nwmshell->wm.title);
2409a3bd7f05Smrg        }
2410a3bd7f05Smrg        XSetWMName(XtDisplay(new), XtWindow(new), &title);
2411a3bd7f05Smrg        if (copied)
2412a3bd7f05Smrg            XFree((XPointer) title.value);
2413a3bd7f05Smrg    }
2414a3bd7f05Smrg
2415a3bd7f05Smrg    EvaluateWMHints(nwmshell);
2416a3bd7f05Smrg
2417a3bd7f05Smrg#define NEQ(f)  (nwmshell->wm.wm_hints.f != owmshell->wm.wm_hints.f)
2418a3bd7f05Smrg
2419a3bd7f05Smrg    if (set_prop && (NEQ(flags) || NEQ(input) || NEQ(initial_state)
2420a3bd7f05Smrg                     || NEQ(icon_x) || NEQ(icon_y)
2421a3bd7f05Smrg                     || NEQ(icon_pixmap) || NEQ(icon_mask) || NEQ(icon_window)
2422a3bd7f05Smrg                     || NEQ(window_group))) {
2423a3bd7f05Smrg
2424a3bd7f05Smrg        XSetWMHints(XtDisplay(new), XtWindow(new), &nwmshell->wm.wm_hints);
2425a3bd7f05Smrg    }
2426444c061aSmrg#undef NEQ
2427444c061aSmrg
2428a3bd7f05Smrg    if (XtIsRealized(new) && nwmshell->wm.transient != owmshell->wm.transient) {
2429a3bd7f05Smrg        if (nwmshell->wm.transient) {
2430a3bd7f05Smrg            if (!XtIsTransientShell(new) &&
2431a3bd7f05Smrg                !nwmshell->shell.override_redirect &&
2432a3bd7f05Smrg                nwmshell->wm.wm_hints.window_group != XtUnspecifiedWindowGroup)
2433a3bd7f05Smrg                XSetTransientForHint(XtDisplay(new), XtWindow(new),
2434a3bd7f05Smrg                                     nwmshell->wm.wm_hints.window_group);
2435a3bd7f05Smrg        }
2436a3bd7f05Smrg        else
2437a3bd7f05Smrg            XDeleteProperty(XtDisplay(new), XtWindow(new), XA_WM_TRANSIENT_FOR);
2438a3bd7f05Smrg    }
2439a3bd7f05Smrg
2440a3bd7f05Smrg    if (nwmshell->wm.client_leader != owmshell->wm.client_leader
2441a3bd7f05Smrg        && XtWindow(new) && !nwmshell->shell.override_redirect) {
2442a3bd7f05Smrg        Widget leader = GetClientLeader(new);
2443a3bd7f05Smrg
2444a3bd7f05Smrg        if (XtWindow(leader))
2445a3bd7f05Smrg            XChangeProperty(XtDisplay(new), XtWindow(new),
2446a3bd7f05Smrg                            XInternAtom(XtDisplay(new),
2447a3bd7f05Smrg                                        "WM_CLIENT_LEADER", False),
2448a3bd7f05Smrg                            XA_WINDOW, 32, PropModeReplace,
2449a3bd7f05Smrg                            (unsigned char *) &(leader->core.window), 1);
2450a3bd7f05Smrg    }
2451a3bd7f05Smrg
2452a3bd7f05Smrg    if (nwmshell->wm.window_role != owmshell->wm.window_role) {
2453a3bd7f05Smrg        XtFree((_XtString) owmshell->wm.window_role);
2454a3bd7f05Smrg        if (set_prop && nwmshell->wm.window_role) {
2455a3bd7f05Smrg            XChangeProperty(XtDisplay(new), XtWindow(new),
2456a3bd7f05Smrg                            XInternAtom(XtDisplay(new), "WM_WINDOW_ROLE",
2457a3bd7f05Smrg                                        False),
2458a3bd7f05Smrg                            XA_STRING, 8, PropModeReplace,
2459a3bd7f05Smrg                            (unsigned char *) nwmshell->wm.window_role,
2460a3bd7f05Smrg                            (int) strlen(nwmshell->wm.window_role));
2461a3bd7f05Smrg        }
2462a3bd7f05Smrg        else if (XtIsRealized(new) && !nwmshell->wm.window_role) {
2463a3bd7f05Smrg            XDeleteProperty(XtDisplay(new), XtWindow(new),
2464a3bd7f05Smrg                            XInternAtom(XtDisplay(new), "WM_WINDOW_ROLE",
2465a3bd7f05Smrg                                        False));
2466a3bd7f05Smrg        }
2467a3bd7f05Smrg    }
2468a3bd7f05Smrg
2469a3bd7f05Smrg    return FALSE;
2470a3bd7f05Smrg}
2471a3bd7f05Smrg
2472a3bd7f05Smrgstatic Boolean
2473a3bd7f05SmrgTransientSetValues(Widget oldW,
2474a3bd7f05Smrg                   Widget refW _X_UNUSED,
2475a3bd7f05Smrg                   Widget newW,
2476a3bd7f05Smrg                   ArgList args _X_UNUSED,
2477a3bd7f05Smrg                   Cardinal *num_args _X_UNUSED)
2478a3bd7f05Smrg{
2479a3bd7f05Smrg    TransientShellWidget old = (TransientShellWidget) oldW;
2480a3bd7f05Smrg    TransientShellWidget new = (TransientShellWidget) newW;
2481444c061aSmrg
2482444c061aSmrg    if (XtIsRealized(newW)
2483a3bd7f05Smrg        && ((new->wm.transient && !old->wm.transient)
2484a3bd7f05Smrg            || ((new->transient.transient_for != old->transient.transient_for)
2485a3bd7f05Smrg                || (new->transient.transient_for == NULL
2486a3bd7f05Smrg                    && (new->wm.wm_hints.window_group
2487a3bd7f05Smrg                        != old->wm.wm_hints.window_group))))) {
2488444c061aSmrg
2489a3bd7f05Smrg        _SetTransientForHint(new, True);
2490444c061aSmrg    }
2491444c061aSmrg    return False;
2492444c061aSmrg}
2493444c061aSmrg
2494a3bd7f05Smrgstatic Boolean
2495a3bd7f05SmrgTopLevelSetValues(Widget oldW,
2496a3bd7f05Smrg                  Widget refW _X_UNUSED,
2497a3bd7f05Smrg                  Widget newW,
2498a3bd7f05Smrg                  ArgList args _X_UNUSED,
2499a3bd7f05Smrg                  Cardinal *num_args _X_UNUSED)
2500444c061aSmrg{
2501a3bd7f05Smrg    TopLevelShellWidget old = (TopLevelShellWidget) oldW;
2502a3bd7f05Smrg    TopLevelShellWidget new = (TopLevelShellWidget) newW;
2503444c061aSmrg    Boolean name_changed;
2504444c061aSmrg
2505444c061aSmrg    if (old->topLevel.icon_name != new->topLevel.icon_name) {
2506a3bd7f05Smrg        XtFree((XtPointer) old->topLevel.icon_name);
2507a3bd7f05Smrg        if (!new->topLevel.icon_name)
2508a3bd7f05Smrg            new->topLevel.icon_name = (_XtString) "";
2509a3bd7f05Smrg        new->topLevel.icon_name = XtNewString(new->topLevel.icon_name);
2510a3bd7f05Smrg        name_changed = True;
2511a3bd7f05Smrg    }
2512a3bd7f05Smrg    else
2513a3bd7f05Smrg        name_changed = False;
2514444c061aSmrg
2515444c061aSmrg    if (XtIsRealized(newW)) {
2516a3bd7f05Smrg        if (new->topLevel.iconic != old->topLevel.iconic) {
2517a3bd7f05Smrg            if (new->topLevel.iconic)
2518a3bd7f05Smrg                XIconifyWindow(XtDisplay(newW),
2519a3bd7f05Smrg                               XtWindow(newW),
2520a3bd7f05Smrg                               XScreenNumberOfScreen(XtScreen(newW))
2521a3bd7f05Smrg                    );
2522a3bd7f05Smrg            else {
2523a3bd7f05Smrg                Boolean map = new->shell.popped_up;
2524a3bd7f05Smrg
2525a3bd7f05Smrg                XtPopup(newW, XtGrabNone);
2526a3bd7f05Smrg                if (map)
2527a3bd7f05Smrg                    XMapWindow(XtDisplay(newW), XtWindow(newW));
2528a3bd7f05Smrg            }
2529a3bd7f05Smrg        }
2530a3bd7f05Smrg
2531a3bd7f05Smrg        if (!new->shell.override_redirect &&
2532a3bd7f05Smrg            (name_changed ||
2533a3bd7f05Smrg             (old->topLevel.icon_name_encoding
2534a3bd7f05Smrg              != new->topLevel.icon_name_encoding))) {
2535a3bd7f05Smrg
2536a3bd7f05Smrg            XTextProperty icon_name;
2537a3bd7f05Smrg            Boolean copied = False;
2538444c061aSmrg
2539444c061aSmrg            if (new->topLevel.icon_name_encoding == None &&
2540a3bd7f05Smrg                XmbTextListToTextProperty(XtDisplay(newW),
2541a3bd7f05Smrg                                          (char **) &new->topLevel.icon_name,
2542a3bd7f05Smrg                                          1, XStdICCTextStyle,
2543a3bd7f05Smrg                                          &icon_name) >= Success) {
2544a3bd7f05Smrg                copied = True;
2545a3bd7f05Smrg            }
2546a3bd7f05Smrg            else {
2547a3bd7f05Smrg                icon_name.value = (unsigned char *) new->topLevel.icon_name;
2548a3bd7f05Smrg                icon_name.encoding = new->topLevel.icon_name_encoding ?
2549a3bd7f05Smrg                    new->topLevel.icon_name_encoding : XA_STRING;
2550a3bd7f05Smrg                icon_name.format = 8;
2551a3bd7f05Smrg                icon_name.nitems = strlen((char *) icon_name.value);
2552a3bd7f05Smrg            }
2553a3bd7f05Smrg            XSetWMIconName(XtDisplay(newW), XtWindow(newW), &icon_name);
2554a3bd7f05Smrg            if (copied)
2555a3bd7f05Smrg                XFree((XPointer) icon_name.value);
2556a3bd7f05Smrg        }
2557444c061aSmrg    }
2558bdf0f55dSmrg    else if (new->topLevel.iconic != old->topLevel.iconic) {
2559a3bd7f05Smrg        if (new->topLevel.iconic)
2560a3bd7f05Smrg            new->wm.wm_hints.initial_state = IconicState;
2561bdf0f55dSmrg    }
2562444c061aSmrg    return False;
2563444c061aSmrg}
2564444c061aSmrg
2565a3bd7f05Smrg/* do not assume it's terminated by a NULL element */
2566a3bd7f05Smrgstatic _XtString *
2567a3bd7f05SmrgNewArgv(int count, _XtString *str)
2568a3bd7f05Smrg{
2569444c061aSmrg    Cardinal nbytes = 0;
2570444c061aSmrg    Cardinal num = 0;
25710568f49bSmrg    _XtString *newarray;
25720568f49bSmrg    _XtString *new;
25730568f49bSmrg    _XtString *strarray = str;
25740568f49bSmrg    _XtString sptr;
2575444c061aSmrg
2576a3bd7f05Smrg    if (count <= 0 || !str)
2577a3bd7f05Smrg        return NULL;
2578444c061aSmrg
25790568f49bSmrg    for (num = (Cardinal) count; num--; str++) {
2580a3bd7f05Smrg        nbytes = (nbytes + (Cardinal) strlen(*str));
2581a3bd7f05Smrg        nbytes++;
2582444c061aSmrg    }
2583a3bd7f05Smrg    num = (Cardinal) ((size_t) (count + 1) * sizeof(_XtString));
25840568f49bSmrg    new = newarray = (_XtString *) __XtMalloc(num + nbytes);
2585444c061aSmrg    sptr = ((char *) new) + num;
2586444c061aSmrg
2587444c061aSmrg    for (str = strarray; count--; str++) {
2588a3bd7f05Smrg        *new = sptr;
2589a3bd7f05Smrg        strcpy(*new, *str);
2590a3bd7f05Smrg        new++;
2591a3bd7f05Smrg        sptr = strchr(sptr, '\0');
2592a3bd7f05Smrg        sptr++;
2593444c061aSmrg    }
2594444c061aSmrg    *new = NULL;
2595444c061aSmrg    return newarray;
2596444c061aSmrg}
2597444c061aSmrg
2598a3bd7f05Smrgstatic Boolean
2599a3bd7f05SmrgApplicationSetValues(Widget current,
2600a3bd7f05Smrg                     Widget request _X_UNUSED,
2601a3bd7f05Smrg                     Widget new,
2602a3bd7f05Smrg                     ArgList args _X_UNUSED,
2603a3bd7f05Smrg                     Cardinal *num_args _X_UNUSED)
2604444c061aSmrg{
2605444c061aSmrg    ApplicationShellWidget nw = (ApplicationShellWidget) new;
2606444c061aSmrg    ApplicationShellWidget cw = (ApplicationShellWidget) current;
2607444c061aSmrg
2608444c061aSmrg    if (cw->application.argc != nw->application.argc ||
2609a3bd7f05Smrg        cw->application.argv != nw->application.argv) {
2610a3bd7f05Smrg
2611a3bd7f05Smrg        if (nw->application.argc > 0)
2612a3bd7f05Smrg            nw->application.argv = NewArgv(nw->application.argc,
2613a3bd7f05Smrg                                           nw->application.argv);
2614a3bd7f05Smrg        if (cw->application.argc > 0)
2615a3bd7f05Smrg            FreeStringArray(cw->application.argv);
2616a3bd7f05Smrg
2617a3bd7f05Smrg        if (XtIsRealized(new) && !nw->shell.override_redirect) {
2618a3bd7f05Smrg            if (nw->application.argc >= 0 && nw->application.argv)
2619a3bd7f05Smrg                XSetCommand(XtDisplay(new), XtWindow(new),
2620a3bd7f05Smrg                            nw->application.argv, nw->application.argc);
2621a3bd7f05Smrg            else
2622a3bd7f05Smrg                XDeleteProperty(XtDisplay(new), XtWindow(new), XA_WM_COMMAND);
2623a3bd7f05Smrg        }
2624444c061aSmrg    }
2625444c061aSmrg    return False;
2626444c061aSmrg}
2627444c061aSmrg
2628a3bd7f05Smrgstatic Boolean
2629a3bd7f05SmrgSessionSetValues(Widget current,
2630a3bd7f05Smrg                 Widget request _X_UNUSED,
2631a3bd7f05Smrg                 Widget new,
2632a3bd7f05Smrg                 ArgList args _X_UNUSED,
2633a3bd7f05Smrg                 Cardinal *num_args _X_UNUSED)
2634444c061aSmrg{
2635444c061aSmrg#ifndef XT_NO_SM
2636444c061aSmrg    SessionShellWidget nw = (SessionShellWidget) new;
2637444c061aSmrg    SessionShellWidget cw = (SessionShellWidget) current;
2638444c061aSmrg    unsigned long set_mask = 0UL;
2639444c061aSmrg    unsigned long unset_mask = 0UL;
2640444c061aSmrg    Boolean initialize = False;
2641444c061aSmrg
2642444c061aSmrg    if (cw->session.session_id != nw->session.session_id) {
2643a3bd7f05Smrg        nw->session.session_id = XtNewString(nw->session.session_id);
2644a3bd7f05Smrg        XtFree(cw->session.session_id);
2645444c061aSmrg    }
2646444c061aSmrg
2647444c061aSmrg    if (cw->session.clone_command != nw->session.clone_command) {
2648a3bd7f05Smrg        if (nw->session.clone_command) {
2649a3bd7f05Smrg            nw->session.clone_command =
2650a3bd7f05Smrg                NewStringArray(nw->session.clone_command);
2651a3bd7f05Smrg            set_mask |= XtCloneCommandMask;
2652a3bd7f05Smrg        }
2653a3bd7f05Smrg        else
2654a3bd7f05Smrg            unset_mask |= XtCloneCommandMask;
2655a3bd7f05Smrg        FreeStringArray(cw->session.clone_command);
2656444c061aSmrg    }
2657444c061aSmrg
2658444c061aSmrg    if (cw->session.current_dir != nw->session.current_dir) {
2659a3bd7f05Smrg        if (nw->session.current_dir) {
2660a3bd7f05Smrg            nw->session.current_dir = XtNewString(nw->session.current_dir);
2661a3bd7f05Smrg            set_mask |= XtCurrentDirectoryMask;
2662a3bd7f05Smrg        }
2663a3bd7f05Smrg        else
2664a3bd7f05Smrg            unset_mask |= XtCurrentDirectoryMask;
2665a3bd7f05Smrg        XtFree((char *) cw->session.current_dir);
2666444c061aSmrg    }
2667444c061aSmrg
2668444c061aSmrg    if (cw->session.discard_command != nw->session.discard_command) {
2669a3bd7f05Smrg        if (nw->session.discard_command) {
2670a3bd7f05Smrg            nw->session.discard_command =
2671a3bd7f05Smrg                NewStringArray(nw->session.discard_command);
2672a3bd7f05Smrg            set_mask |= XtDiscardCommandMask;
2673a3bd7f05Smrg        }
2674a3bd7f05Smrg        else
2675a3bd7f05Smrg            unset_mask |= XtDiscardCommandMask;
2676a3bd7f05Smrg        FreeStringArray(cw->session.discard_command);
2677444c061aSmrg    }
2678444c061aSmrg
2679444c061aSmrg    if (cw->session.environment != nw->session.environment) {
2680a3bd7f05Smrg        if (nw->session.environment) {
2681a3bd7f05Smrg            nw->session.environment = NewStringArray(nw->session.environment);
2682a3bd7f05Smrg            set_mask |= XtEnvironmentMask;
2683a3bd7f05Smrg        }
2684a3bd7f05Smrg        else
2685a3bd7f05Smrg            unset_mask |= XtEnvironmentMask;
2686a3bd7f05Smrg        FreeStringArray(cw->session.environment);
2687444c061aSmrg    }
2688444c061aSmrg
2689444c061aSmrg    if (cw->session.program_path != nw->session.program_path) {
2690a3bd7f05Smrg        if (nw->session.program_path) {
2691a3bd7f05Smrg            nw->session.program_path = XtNewString(nw->session.program_path);
2692a3bd7f05Smrg            set_mask |= XtProgramMask;
2693a3bd7f05Smrg        }
2694a3bd7f05Smrg        else
2695a3bd7f05Smrg            unset_mask |= XtProgramMask;
2696a3bd7f05Smrg        XtFree((char *) cw->session.program_path);
2697444c061aSmrg    }
2698444c061aSmrg
2699444c061aSmrg    if (cw->session.resign_command != nw->session.resign_command) {
2700a3bd7f05Smrg        if (nw->session.resign_command) {
2701a3bd7f05Smrg            nw->session.resign_command =
2702a3bd7f05Smrg                NewStringArray(nw->session.resign_command);
2703a3bd7f05Smrg            set_mask |= XtResignCommandMask;
2704a3bd7f05Smrg        }
2705a3bd7f05Smrg        else
2706a3bd7f05Smrg            set_mask |= XtResignCommandMask;
2707a3bd7f05Smrg        FreeStringArray(cw->session.resign_command);
2708444c061aSmrg    }
2709444c061aSmrg
2710444c061aSmrg    if (cw->session.restart_command != nw->session.restart_command) {
2711a3bd7f05Smrg        if (nw->session.restart_command) {
2712a3bd7f05Smrg            nw->session.restart_command =
2713a3bd7f05Smrg                NewStringArray(nw->session.restart_command);
2714a3bd7f05Smrg            set_mask |= XtRestartCommandMask;
2715a3bd7f05Smrg        }
2716a3bd7f05Smrg        else
2717a3bd7f05Smrg            unset_mask |= XtRestartCommandMask;
2718a3bd7f05Smrg        FreeStringArray(cw->session.restart_command);
2719444c061aSmrg    }
2720444c061aSmrg
2721444c061aSmrg    if (cw->session.restart_style != nw->session.restart_style)
2722a3bd7f05Smrg        set_mask |= XtRestartStyleHintMask;
2723444c061aSmrg
2724444c061aSmrg    if (cw->session.shutdown_command != nw->session.shutdown_command) {
2725a3bd7f05Smrg        if (nw->session.shutdown_command) {
2726a3bd7f05Smrg            nw->session.shutdown_command =
2727a3bd7f05Smrg                NewStringArray(nw->session.shutdown_command);
2728a3bd7f05Smrg            set_mask |= XtShutdownCommandMask;
2729a3bd7f05Smrg        }
2730a3bd7f05Smrg        else
2731a3bd7f05Smrg            unset_mask |= XtShutdownCommandMask;
2732a3bd7f05Smrg        FreeStringArray(cw->session.shutdown_command);
2733444c061aSmrg    }
2734444c061aSmrg
2735444c061aSmrg    if ((!cw->session.join_session && nw->session.join_session) ||
2736a3bd7f05Smrg        (!cw->session.connection && nw->session.connection)) {
2737a3bd7f05Smrg        JoinSession(nw);
2738a3bd7f05Smrg        initialize = True;
2739444c061aSmrg    }
2740444c061aSmrg
2741444c061aSmrg    if (nw->session.connection && (set_mask || unset_mask || initialize))
2742a3bd7f05Smrg        SetSessionProperties((SessionShellWidget) new, initialize, set_mask,
2743a3bd7f05Smrg                             unset_mask);
2744444c061aSmrg
2745444c061aSmrg    if ((cw->session.join_session && !nw->session.join_session) ||
2746a3bd7f05Smrg        (cw->session.connection && !nw->session.connection))
2747a3bd7f05Smrg        StopManagingSession(nw, nw->session.connection);
2748a3bd7f05Smrg#endif                          /* !XT_NO_SM */
2749444c061aSmrg
2750444c061aSmrg    if (cw->wm.client_leader != nw->wm.client_leader ||
2751a3bd7f05Smrg        cw->session.session_id != nw->session.session_id) {
2752a3bd7f05Smrg        Widget leader;
2753a3bd7f05Smrg
2754a3bd7f05Smrg        if (cw->session.session_id) {
2755a3bd7f05Smrg            leader = GetClientLeader(current);
2756a3bd7f05Smrg            if (XtWindow(leader))
2757a3bd7f05Smrg                XDeleteProperty(XtDisplay(leader), XtWindow(leader),
2758a3bd7f05Smrg                                XInternAtom(XtDisplay(leader), "SM_CLIENT_ID",
2759a3bd7f05Smrg                                            False));
2760a3bd7f05Smrg        }
2761a3bd7f05Smrg        if (nw->session.session_id) {
2762a3bd7f05Smrg            leader = GetClientLeader(new);
2763a3bd7f05Smrg            if (XtWindow(leader))
2764a3bd7f05Smrg                XChangeProperty(XtDisplay(leader), XtWindow(leader),
2765a3bd7f05Smrg                                XInternAtom(XtDisplay(leader), "SM_CLIENT_ID",
2766a3bd7f05Smrg                                            False),
2767a3bd7f05Smrg                                XA_STRING, 8, PropModeReplace,
2768a3bd7f05Smrg                                (unsigned char *) nw->session.session_id,
2769a3bd7f05Smrg                                (int) strlen(nw->session.session_id));
2770a3bd7f05Smrg        }
2771444c061aSmrg    }
2772444c061aSmrg    return False;
2773444c061aSmrg}
2774444c061aSmrg
2775a3bd7f05Smrgvoid
2776a3bd7f05Smrg_XtShellGetCoordinates(Widget widget, Position *x, Position *y)
2777444c061aSmrg{
2778a3bd7f05Smrg    ShellWidget w = (ShellWidget) widget;
2779a3bd7f05Smrg
2780444c061aSmrg    if (XtIsRealized(widget) &&
2781a3bd7f05Smrg        !(w->shell.client_specified & _XtShellPositionValid)) {
2782a3bd7f05Smrg        int tmpx, tmpy;
2783a3bd7f05Smrg        Window tmpchild;
2784a3bd7f05Smrg
2785a3bd7f05Smrg        (void) XTranslateCoordinates(XtDisplay(w), XtWindow(w),
2786a3bd7f05Smrg                                     RootWindowOfScreen(XtScreen(w)),
2787a3bd7f05Smrg                                     (int) -w->core.border_width,
2788a3bd7f05Smrg                                     (int) -w->core.border_width,
2789a3bd7f05Smrg                                     &tmpx, &tmpy, &tmpchild);
2790a3bd7f05Smrg        w->core.x = (Position) tmpx;
2791a3bd7f05Smrg        w->core.y = (Position) tmpy;
2792a3bd7f05Smrg        w->shell.client_specified |= _XtShellPositionValid;
2793444c061aSmrg    }
2794444c061aSmrg    *x = w->core.x;
2795444c061aSmrg    *y = w->core.y;
2796444c061aSmrg}
2797444c061aSmrg
2798a3bd7f05Smrgstatic void
2799a3bd7f05SmrgGetValuesHook(Widget widget, ArgList args, Cardinal *num_args)
2800444c061aSmrg{
2801444c061aSmrg    ShellWidget w = (ShellWidget) widget;
2802444c061aSmrg
2803444c061aSmrg    /* x and y resource values may be invalid after a shell resize */
2804444c061aSmrg    if (XtIsRealized(widget) &&
2805a3bd7f05Smrg        !(w->shell.client_specified & _XtShellPositionValid)) {
2806a3bd7f05Smrg        Cardinal n;
2807a3bd7f05Smrg        Position x, y;
2808a3bd7f05Smrg
2809a3bd7f05Smrg        for (n = *num_args; n; n--, args++) {
2810a3bd7f05Smrg            if (strcmp(XtNx, args->name) == 0) {
2811a3bd7f05Smrg                _XtShellGetCoordinates(widget, &x, &y);
2812a3bd7f05Smrg                _XtCopyToArg((char *) &x, &args->value, sizeof(Position));
2813a3bd7f05Smrg            }
2814a3bd7f05Smrg            else if (strcmp(XtNy, args->name) == 0) {
2815a3bd7f05Smrg                _XtShellGetCoordinates(widget, &x, &y);
2816a3bd7f05Smrg                _XtCopyToArg((char *) &y, &args->value, sizeof(Position));
2817a3bd7f05Smrg            }
2818a3bd7f05Smrg        }
2819444c061aSmrg    }
2820444c061aSmrg}
2821444c061aSmrg
2822a3bd7f05Smrgstatic void
2823a3bd7f05SmrgApplicationShellInsertChild(Widget widget)
2824444c061aSmrg{
2825a3bd7f05Smrg    if (!XtIsWidget(widget) && XtIsRectObj(widget)) {
2826a3bd7f05Smrg        XtAppWarningMsg(XtWidgetToApplicationContext(widget),
2827a3bd7f05Smrg                        "invalidClass", "applicationShellInsertChild",
2828a3bd7f05Smrg                        XtCXtToolkitError,
2829a3bd7f05Smrg                        "ApplicationShell does not accept RectObj children; ignored",
2830a3bd7f05Smrg                        NULL, NULL);
2831444c061aSmrg    }
2832444c061aSmrg    else {
2833a3bd7f05Smrg        XtWidgetProc insert_child;
2834444c061aSmrg
2835a3bd7f05Smrg        LOCK_PROCESS;
2836a3bd7f05Smrg        insert_child =
2837a3bd7f05Smrg            ((CompositeWidgetClass) applicationShellClassRec.core_class.
2838a3bd7f05Smrg             superclass)->composite_class.insert_child;
2839a3bd7f05Smrg        UNLOCK_PROCESS;
2840a3bd7f05Smrg        (*insert_child) (widget);
2841444c061aSmrg    }
2842444c061aSmrg}
2843444c061aSmrg
2844444c061aSmrg/**************************************************************************
2845444c061aSmrg
2846444c061aSmrg  Session Protocol Participation
2847444c061aSmrg
2848444c061aSmrg *************************************************************************/
2849444c061aSmrg
2850a3bd7f05Smrg#define XtSessionCheckpoint     0
2851a3bd7f05Smrg#define XtSessionInteract       1
2852444c061aSmrg
2853a3bd7f05Smrgstatic void CallSaveCallbacks(SessionShellWidget);
28540568f49bSmrgstatic _XtString *EditCommand(_XtString, _XtString *, _XtString *);
2855444c061aSmrgstatic Boolean ExamineToken(XtPointer);
2856444c061aSmrgstatic void GetIceEvent(XtPointer, int *, XtInputId *);
2857444c061aSmrgstatic XtCheckpointToken GetToken(Widget, int);
2858444c061aSmrgstatic void XtCallCancelCallbacks(SmcConn, SmPointer);
2859444c061aSmrgstatic void XtCallDieCallbacks(SmcConn, SmPointer);
2860444c061aSmrgstatic void XtCallSaveCallbacks(SmcConn, SmPointer, int, Bool, int, Bool);
2861444c061aSmrgstatic void XtCallSaveCompleteCallbacks(SmcConn, SmPointer);
2862444c061aSmrg
2863444c061aSmrg#ifndef XT_NO_SM
2864a3bd7f05Smrgstatic void
2865a3bd7f05SmrgStopManagingSession(SessionShellWidget w, SmcConn connection)
2866a3bd7f05Smrg{                               /* connection to close, if any */
2867444c061aSmrg    if (connection)
2868a3bd7f05Smrg        SmcCloseConnection(connection, 0, NULL);
2869444c061aSmrg
2870444c061aSmrg    if (w->session.input_id) {
2871a3bd7f05Smrg        XtRemoveInput(w->session.input_id);
2872a3bd7f05Smrg        w->session.input_id = 0;
2873444c061aSmrg    }
2874444c061aSmrg    w->session.connection = NULL;
2875444c061aSmrg}
2876444c061aSmrg
2877444c061aSmrg#define XT_MSG_LENGTH 256
2878a3bd7f05Smrgstatic void
2879a3bd7f05SmrgJoinSession(SessionShellWidget w)
2880444c061aSmrg{
2881444c061aSmrg    IceConn ice_conn;
2882444c061aSmrg    SmcCallbacks smcb;
2883a3bd7f05Smrg    char *sm_client_id;
2884444c061aSmrg    unsigned long mask;
2885a3bd7f05Smrg    static char context;        /* used to guarantee the connection isn't shared */
2886444c061aSmrg
2887444c061aSmrg    smcb.save_yourself.callback = XtCallSaveCallbacks;
2888444c061aSmrg    smcb.die.callback = XtCallDieCallbacks;
2889444c061aSmrg    smcb.save_complete.callback = XtCallSaveCompleteCallbacks;
2890444c061aSmrg    smcb.shutdown_cancelled.callback = XtCallCancelCallbacks;
2891444c061aSmrg    smcb.save_yourself.client_data = smcb.die.client_data =
2892a3bd7f05Smrg        smcb.save_complete.client_data =
2893a3bd7f05Smrg        smcb.shutdown_cancelled.client_data = (SmPointer) w;
2894444c061aSmrg    mask = SmcSaveYourselfProcMask | SmcDieProcMask |
2895a3bd7f05Smrg        SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask;
2896444c061aSmrg
2897444c061aSmrg    if (w->session.connection) {
2898a3bd7f05Smrg        SmcModifyCallbacks(w->session.connection, mask, &smcb);
2899a3bd7f05Smrg        sm_client_id = SmcClientID(w->session.connection);
2900a3bd7f05Smrg    }
2901a3bd7f05Smrg    else if (getenv("SESSION_MANAGER")) {
2902a3bd7f05Smrg        char error_msg[XT_MSG_LENGTH];
2903a3bd7f05Smrg
2904a3bd7f05Smrg        error_msg[0] = '\0';
2905a3bd7f05Smrg        w->session.connection =
2906a3bd7f05Smrg            SmcOpenConnection(NULL, &context, SmProtoMajor, SmProtoMinor,
2907a3bd7f05Smrg                              mask, &smcb, w->session.session_id,
2908a3bd7f05Smrg                              &sm_client_id, XT_MSG_LENGTH, error_msg);
2909a3bd7f05Smrg        if (error_msg[0]) {
2910a3bd7f05Smrg            String params[1];
2911a3bd7f05Smrg            Cardinal num_params = 1;
2912a3bd7f05Smrg
2913a3bd7f05Smrg            params[0] = error_msg;
2914a3bd7f05Smrg            XtAppWarningMsg(XtWidgetToApplicationContext((Widget) w),
2915a3bd7f05Smrg                            "sessionManagement", "SmcOpenConnection",
2916a3bd7f05Smrg                            XtCXtToolkitError,
2917a3bd7f05Smrg                            "Tried to connect to session manager, %s",
2918a3bd7f05Smrg                            params, &num_params);
2919a3bd7f05Smrg        }
2920444c061aSmrg    }
2921444c061aSmrg
2922444c061aSmrg    if (w->session.connection) {
2923a3bd7f05Smrg        if (w->session.session_id == NULL
2924a3bd7f05Smrg            || (strcmp(w->session.session_id, sm_client_id) != 0)) {
2925a3bd7f05Smrg            XtFree(w->session.session_id);
2926a3bd7f05Smrg            w->session.session_id = XtNewString(sm_client_id);
2927a3bd7f05Smrg        }
2928a3bd7f05Smrg        free(sm_client_id);
2929a3bd7f05Smrg        ice_conn = SmcGetIceConnection(w->session.connection);
2930a3bd7f05Smrg        w->session.input_id =
2931a3bd7f05Smrg            XtAppAddInput(XtWidgetToApplicationContext((Widget) w),
2932a3bd7f05Smrg                          IceConnectionNumber(ice_conn),
2933a3bd7f05Smrg                          (XtPointer) XtInputReadMask,
2934a3bd7f05Smrg                          GetIceEvent, (XtPointer) w);
2935a3bd7f05Smrg
2936a3bd7f05Smrg        w->session.restart_command =
2937a3bd7f05Smrg            EditCommand(w->session.session_id, w->session.restart_command,
2938a3bd7f05Smrg                        w->application.argv);
2939a3bd7f05Smrg
2940a3bd7f05Smrg        if (!w->session.clone_command)
2941a3bd7f05Smrg            w->session.clone_command =
2942a3bd7f05Smrg                EditCommand(NULL, NULL, w->session.restart_command);
2943a3bd7f05Smrg
2944a3bd7f05Smrg        if (!w->session.program_path)
2945a3bd7f05Smrg            w->session.program_path = w->session.restart_command
2946a3bd7f05Smrg                ? XtNewString(w->session.restart_command[0]) : NULL;
2947444c061aSmrg    }
2948444c061aSmrg}
2949a3bd7f05Smrg
2950444c061aSmrg#undef XT_MSG_LENGTH
2951444c061aSmrg
2952a3bd7f05Smrg#endif                          /* !XT_NO_SM */
2953444c061aSmrg
2954a3bd7f05Smrgstatic _XtString *
2955a3bd7f05SmrgNewStringArray(_XtString *str)
2956444c061aSmrg{
2957444c061aSmrg    Cardinal nbytes = 0;
2958444c061aSmrg    Cardinal num = 0;
29590568f49bSmrg    _XtString *newarray;
29600568f49bSmrg    _XtString *new;
29610568f49bSmrg    _XtString *strarray = str;
29620568f49bSmrg    _XtString sptr;
2963444c061aSmrg
2964a3bd7f05Smrg    if (!str)
2965a3bd7f05Smrg        return NULL;
2966444c061aSmrg
2967444c061aSmrg    for (num = 0; *str; num++, str++) {
2968a3bd7f05Smrg        nbytes = nbytes + (Cardinal) strlen(*str);
2969a3bd7f05Smrg        nbytes++;
2970444c061aSmrg    }
2971a3bd7f05Smrg    num = (Cardinal) ((size_t) (num + 1) * sizeof(_XtString));
29720568f49bSmrg    new = newarray = (_XtString *) __XtMalloc(num + nbytes);
2973444c061aSmrg    sptr = ((char *) new) + num;
2974444c061aSmrg
2975444c061aSmrg    for (str = strarray; *str; str++) {
2976a3bd7f05Smrg        *new = sptr;
2977a3bd7f05Smrg        strcpy(*new, *str);
2978a3bd7f05Smrg        new++;
2979a3bd7f05Smrg        sptr = strchr(sptr, '\0');
2980a3bd7f05Smrg        sptr++;
2981444c061aSmrg    }
2982444c061aSmrg    *new = NULL;
2983444c061aSmrg    return newarray;
2984444c061aSmrg}
2985444c061aSmrg
2986a3bd7f05Smrgstatic void
2987a3bd7f05SmrgFreeStringArray(_XtString *str)
2988444c061aSmrg{
2989444c061aSmrg    if (str)
2990a3bd7f05Smrg        XtFree((_XtString) str);
2991444c061aSmrg}
2992444c061aSmrg
2993444c061aSmrg#ifndef XT_NO_SM
2994a3bd7f05Smrgstatic SmProp *
2995a3bd7f05SmrgCardPack(_Xconst _XtString name, XtPointer closure)
2996444c061aSmrg{
2997444c061aSmrg    unsigned char *prop = (unsigned char *) closure;
2998444c061aSmrg    SmProp *p;
2999444c061aSmrg
3000444c061aSmrg    p = (SmProp *) __XtMalloc(sizeof(SmProp) + sizeof(SmPropValue));
3001444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
3002444c061aSmrg    p->num_vals = 1;
3003a3bd7f05Smrg    p->type = (char *) SmCARD8;
3004a3bd7f05Smrg    p->name = (char *) name;
3005444c061aSmrg    p->vals->length = 1;
3006444c061aSmrg    p->vals->value = (SmPointer) prop;
3007444c061aSmrg    return p;
3008444c061aSmrg}
3009444c061aSmrg
3010a3bd7f05Smrgstatic SmProp *
3011a3bd7f05SmrgArrayPack(_Xconst _XtString name, XtPointer closure)
3012444c061aSmrg{
30130568f49bSmrg    _XtString prop = *(_XtString *) closure;
3014444c061aSmrg    SmProp *p;
3015444c061aSmrg
3016444c061aSmrg    p = (SmProp *) __XtMalloc(sizeof(SmProp) + sizeof(SmPropValue));
3017444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
3018444c061aSmrg    p->num_vals = 1;
3019a3bd7f05Smrg    p->type = (char *) SmARRAY8;
30200568f49bSmrg    p->name = (char *) name;
30210568f49bSmrg    p->vals->length = (int) strlen(prop) + 1;
3022444c061aSmrg    p->vals->value = prop;
3023444c061aSmrg    return p;
3024444c061aSmrg}
3025444c061aSmrg
3026a3bd7f05Smrgstatic SmProp *
3027a3bd7f05SmrgListPack(_Xconst _XtString name, XtPointer closure)
3028444c061aSmrg{
30290568f49bSmrg    _XtString *prop = *(_XtString **) closure;
3030444c061aSmrg    SmProp *p;
30310568f49bSmrg    _XtString *ptr;
3032444c061aSmrg    SmPropValue *vals;
3033444c061aSmrg    int n = 0;
3034444c061aSmrg
3035444c061aSmrg    for (ptr = prop; *ptr; ptr++)
3036a3bd7f05Smrg        n++;
3037a3bd7f05Smrg    p = (SmProp *)
3038a3bd7f05Smrg        __XtMalloc((Cardinal)
3039a3bd7f05Smrg                   (sizeof(SmProp) + (size_t) n * sizeof(SmPropValue)));
3040444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
3041444c061aSmrg    p->num_vals = n;
3042a3bd7f05Smrg    p->type = (char *) SmLISTofARRAY8;
3043a3bd7f05Smrg    p->name = (char *) name;
3044444c061aSmrg    for (ptr = prop, vals = p->vals; *ptr; ptr++, vals++) {
3045a3bd7f05Smrg        vals->length = (int) strlen(*ptr) + 1;
3046a3bd7f05Smrg        vals->value = *ptr;
3047444c061aSmrg    }
3048444c061aSmrg    return p;
3049444c061aSmrg}
3050444c061aSmrg
3051a3bd7f05Smrgstatic void
3052a3bd7f05SmrgFreePacks(SmProp ** props, int num_props)
3053444c061aSmrg{
3054444c061aSmrg    while (--num_props >= 0)
3055a3bd7f05Smrg        XtFree((char *) props[num_props]);
3056444c061aSmrg}
3057444c061aSmrg
3058a3bd7f05Smrgtypedef SmProp *(*PackProc) (_Xconst _XtString, XtPointer);
3059444c061aSmrg
3060444c061aSmrgtypedef struct PropertyRec {
3061a3bd7f05Smrg    String name;
3062a3bd7f05Smrg    int offset;
3063a3bd7f05Smrg    PackProc proc;
3064444c061aSmrg} PropertyRec, *PropertyTable;
3065444c061aSmrg
3066444c061aSmrg#define Offset(x) (XtOffsetOf(SessionShellRec, x))
3067a3bd7f05Smrg/* *INDENT-OFF* */
3068444c061aSmrgstatic PropertyRec propertyTable[] = {
3069444c061aSmrg  {SmCloneCommand,     Offset(session.clone_command),    ListPack},
3070444c061aSmrg  {SmCurrentDirectory, Offset(session.current_dir),      ArrayPack},
3071444c061aSmrg  {SmDiscardCommand,   Offset(session.discard_command),  ListPack},
3072444c061aSmrg  {SmEnvironment,      Offset(session.environment),      ListPack},
3073444c061aSmrg  {SmProgram,          Offset(session.program_path),     ArrayPack},
3074444c061aSmrg  {SmResignCommand,    Offset(session.resign_command),   ListPack},
3075444c061aSmrg  {SmRestartCommand,   Offset(session.restart_command),  ListPack},
3076444c061aSmrg  {SmRestartStyleHint, Offset(session.restart_style),    CardPack},
3077444c061aSmrg  {SmShutdownCommand,  Offset(session.shutdown_command), ListPack}
3078444c061aSmrg};
3079a3bd7f05Smrg/* *INDENT-ON* */
3080444c061aSmrg#undef Offset
3081444c061aSmrg
3082444c061aSmrg#define XT_NUM_SM_PROPS 11
3083444c061aSmrg
3084a3bd7f05Smrgstatic void
3085a3bd7f05SmrgSetSessionProperties(SessionShellWidget w,
3086a3bd7f05Smrg                     Boolean initialize,
3087a3bd7f05Smrg                     unsigned long set_mask,
3088a3bd7f05Smrg                     unsigned long unset_mask)
3089444c061aSmrg{
3090444c061aSmrg    PropertyTable p = propertyTable;
3091444c061aSmrg    int n;
3092444c061aSmrg    int num_props = 0;
3093444c061aSmrg    XtPointer *addr;
3094444c061aSmrg    unsigned long mask;
3095444c061aSmrg    SmProp *props[XT_NUM_SM_PROPS];
3096444c061aSmrg
3097444c061aSmrg    if (w->session.connection == NULL)
3098a3bd7f05Smrg        return;
3099444c061aSmrg
3100444c061aSmrg    if (initialize) {
3101a3bd7f05Smrg        char nam_buf[32];
3102a3bd7f05Smrg        char pid[12];
3103a3bd7f05Smrg        String user_name;
3104a3bd7f05Smrg        String pidp = pid;
3105a3bd7f05Smrg
3106a3bd7f05Smrg        /* set all non-NULL session properties, the UserID and the ProcessID */
3107a3bd7f05Smrg        for (n = XtNumber(propertyTable); n; n--, p++) {
3108a3bd7f05Smrg            addr = (XtPointer *) ((char *) w + p->offset);
3109a3bd7f05Smrg            if (p->proc == CardPack) {
3110a3bd7f05Smrg                if (*(unsigned char *) addr)
3111a3bd7f05Smrg                    props[num_props++] =
3112a3bd7f05Smrg                        (*(p->proc)) (p->name, (XtPointer) addr);
3113a3bd7f05Smrg            }
3114a3bd7f05Smrg            else if (*addr)
3115a3bd7f05Smrg                props[num_props++] = (*(p->proc)) (p->name, (XtPointer) addr);
3116a3bd7f05Smrg
3117a3bd7f05Smrg        }
3118a3bd7f05Smrg        user_name = _XtGetUserName(nam_buf, sizeof nam_buf);
3119a3bd7f05Smrg        if (user_name)
3120a3bd7f05Smrg            props[num_props++] = ArrayPack(SmUserID, &user_name);
3121a3bd7f05Smrg        snprintf(pid, sizeof(pid), "%ld", (long) getpid());
3122a3bd7f05Smrg        props[num_props++] = ArrayPack(SmProcessID, &pidp);
3123a3bd7f05Smrg
3124a3bd7f05Smrg        if (num_props) {
3125a3bd7f05Smrg            SmcSetProperties(w->session.connection, num_props, props);
3126a3bd7f05Smrg            FreePacks(props, num_props);
3127a3bd7f05Smrg        }
3128a3bd7f05Smrg        return;
3129444c061aSmrg    }
3130444c061aSmrg
3131444c061aSmrg    if (set_mask) {
3132a3bd7f05Smrg        mask = 1L;
3133a3bd7f05Smrg        for (n = XtNumber(propertyTable); n; n--, p++, mask <<= 1)
3134a3bd7f05Smrg            if (mask & set_mask) {
3135a3bd7f05Smrg                addr = (XtPointer *) ((char *) w + p->offset);
3136a3bd7f05Smrg                props[num_props++] = (*(p->proc)) (p->name, (XtPointer) addr);
3137a3bd7f05Smrg            }
3138a3bd7f05Smrg        SmcSetProperties(w->session.connection, num_props, props);
3139a3bd7f05Smrg        FreePacks(props, num_props);
3140444c061aSmrg    }
3141444c061aSmrg
3142444c061aSmrg    if (unset_mask) {
3143a3bd7f05Smrg        char *pnames[XT_NUM_SM_PROPS];
31440568f49bSmrg
3145a3bd7f05Smrg        mask = 1L;
3146a3bd7f05Smrg        num_props = 0;
3147a3bd7f05Smrg        for (n = XtNumber(propertyTable); n; n--, p++, mask <<= 1)
3148a3bd7f05Smrg            if (mask & unset_mask)
3149a3bd7f05Smrg                pnames[num_props++] = (char *) p->name;
3150a3bd7f05Smrg        SmcDeleteProperties(w->session.connection, num_props, pnames);
3151444c061aSmrg    }
3152444c061aSmrg}
3153444c061aSmrg
3154a3bd7f05Smrgstatic void
3155a3bd7f05SmrgGetIceEvent(XtPointer client_data,
3156a3bd7f05Smrg            int *source _X_UNUSED,
3157a3bd7f05Smrg            XtInputId *id _X_UNUSED)
3158444c061aSmrg{
3159444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3160444c061aSmrg    IceProcessMessagesStatus status;
3161444c061aSmrg
3162444c061aSmrg    status = IceProcessMessages(SmcGetIceConnection(w->session.connection),
3163a3bd7f05Smrg                                NULL, NULL);
3164444c061aSmrg
3165444c061aSmrg    if (status == IceProcessMessagesIOError) {
3166a3bd7f05Smrg        StopManagingSession(w, w->session.connection);
3167a3bd7f05Smrg        XtCallCallbackList((Widget) w, w->session.error_callbacks,
3168a3bd7f05Smrg                           (XtPointer) NULL);
3169444c061aSmrg    }
3170444c061aSmrg}
3171444c061aSmrg
3172a3bd7f05Smrgstatic void
3173a3bd7f05SmrgCleanUpSave(SessionShellWidget w)
3174444c061aSmrg{
3175444c061aSmrg    XtSaveYourself next = w->session.save->next;
3176a3bd7f05Smrg
3177a3bd7f05Smrg    XtFree((char *) w->session.save);
3178444c061aSmrg    w->session.save = next;
3179444c061aSmrg    if (w->session.save)
3180a3bd7f05Smrg        CallSaveCallbacks(w);
3181444c061aSmrg}
3182444c061aSmrg
3183a3bd7f05Smrgstatic void
3184a3bd7f05SmrgCallSaveCallbacks(SessionShellWidget w)
3185444c061aSmrg{
3186444c061aSmrg    if (XtHasCallbacks((Widget) w, XtNsaveCallback) != XtCallbackHasSome) {
3187a3bd7f05Smrg        /* if the application makes no attempt to save state, report failure */
3188a3bd7f05Smrg        SmcSaveYourselfDone(w->session.connection, False);
3189a3bd7f05Smrg        CleanUpSave(w);
3190a3bd7f05Smrg    }
3191a3bd7f05Smrg    else {
3192a3bd7f05Smrg        XtCheckpointToken token;
31930568f49bSmrg
3194a3bd7f05Smrg        w->session.checkpoint_state = XtSaveActive;
3195a3bd7f05Smrg        token = GetToken((Widget) w, XtSessionCheckpoint);
3196a3bd7f05Smrg        _XtCallConditionalCallbackList((Widget) w, w->session.save_callbacks,
3197a3bd7f05Smrg                                       (XtPointer) token, ExamineToken);
3198a3bd7f05Smrg        XtSessionReturnToken(token);
3199444c061aSmrg    }
3200444c061aSmrg}
3201444c061aSmrg
3202a3bd7f05Smrgstatic void
3203a3bd7f05SmrgXtCallSaveCallbacks(SmcConn connection _X_UNUSED,
3204a3bd7f05Smrg                    SmPointer client_data,
3205a3bd7f05Smrg                    int save_type,
3206a3bd7f05Smrg                    Bool shutdown,
3207a3bd7f05Smrg                    int interact,
3208a3bd7f05Smrg                    Bool fast)
3209444c061aSmrg{
3210444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3211444c061aSmrg    XtSaveYourself save;
3212444c061aSmrg    XtSaveYourself prev;
3213444c061aSmrg
3214444c061aSmrg    save = XtNew(XtSaveYourselfRec);
3215444c061aSmrg    save->next = NULL;
3216444c061aSmrg    save->save_type = save_type;
3217444c061aSmrg    save->interact_style = interact;
32180568f49bSmrg    save->shutdown = (Boolean) shutdown;
32190568f49bSmrg    save->fast = (Boolean) fast;
3220444c061aSmrg    save->cancel_shutdown = False;
3221444c061aSmrg    save->phase = 1;
3222444c061aSmrg    save->interact_dialog_type = SmDialogNormal;
3223444c061aSmrg    save->request_cancel = save->request_next_phase = False;
3224444c061aSmrg    save->save_success = True;
3225444c061aSmrg    save->save_tokens = save->interact_tokens = 0;
3226444c061aSmrg
3227444c061aSmrg    prev = (XtSaveYourself) &w->session.save;
3228444c061aSmrg    while (prev->next)
3229a3bd7f05Smrg        prev = prev->next;
3230444c061aSmrg    prev->next = save;
3231444c061aSmrg
3232444c061aSmrg    if (w->session.checkpoint_state == XtSaveInactive)
3233a3bd7f05Smrg        CallSaveCallbacks(w);
3234444c061aSmrg}
3235444c061aSmrg
3236a3bd7f05Smrgstatic void
3237a3bd7f05SmrgXtInteractPermission(SmcConn connection, SmPointer data)
3238444c061aSmrg{
3239444c061aSmrg    Widget w = (Widget) data;
3240444c061aSmrg    SessionShellWidget sw = (SessionShellWidget) data;
3241444c061aSmrg    XtCallbackProc callback;
3242444c061aSmrg    XtPointer client_data;
3243444c061aSmrg
3244a3bd7f05Smrg    _XtPeekCallback(w, sw->session.interact_callbacks, &callback, &client_data);
3245444c061aSmrg    if (callback) {
3246a3bd7f05Smrg        XtCheckpointToken token;
32470568f49bSmrg
3248a3bd7f05Smrg        sw->session.checkpoint_state = XtInteractActive;
3249a3bd7f05Smrg        token = GetToken(w, XtSessionInteract);
3250a3bd7f05Smrg        XtRemoveCallback(w, XtNinteractCallback, callback, client_data);
3251a3bd7f05Smrg        (*callback) (w, client_data, (XtPointer) token);
3252a3bd7f05Smrg    }
3253a3bd7f05Smrg    else if (!sw->session.save->cancel_shutdown) {
3254a3bd7f05Smrg        SmcInteractDone(connection, False);
3255444c061aSmrg    }
3256444c061aSmrg}
3257444c061aSmrg
3258a3bd7f05Smrgstatic void
3259a3bd7f05SmrgXtCallSaveCompleteCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3260444c061aSmrg{
3261a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) client_data;
3262444c061aSmrg
3263a3bd7f05Smrg    XtCallCallbackList((Widget) w, w->session.save_complete_callbacks,
3264a3bd7f05Smrg                       (XtPointer) NULL);
3265444c061aSmrg}
3266444c061aSmrg
3267a3bd7f05Smrgstatic void
3268a3bd7f05SmrgXtCallNextPhaseCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3269444c061aSmrg{
3270a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) client_data;
3271a3bd7f05Smrg
3272444c061aSmrg    w->session.save->phase = 2;
3273444c061aSmrg    CallSaveCallbacks(w);
3274444c061aSmrg}
3275444c061aSmrg
3276a3bd7f05Smrgstatic void
3277a3bd7f05SmrgXtCallDieCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3278444c061aSmrg{
3279a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) client_data;
3280444c061aSmrg
3281444c061aSmrg    StopManagingSession(w, w->session.connection);
3282a3bd7f05Smrg    XtCallCallbackList((Widget) w, w->session.die_callbacks, (XtPointer) NULL);
3283444c061aSmrg}
3284444c061aSmrg
3285a3bd7f05Smrgstatic void
3286a3bd7f05SmrgXtCallCancelCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3287444c061aSmrg{
3288444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3289444c061aSmrg    Boolean call_interacts = False;
3290444c061aSmrg
3291444c061aSmrg    if (w->session.checkpoint_state != XtSaveInactive) {
3292a3bd7f05Smrg        w->session.save->cancel_shutdown = True;
3293a3bd7f05Smrg        call_interacts = (w->session.save->interact_style !=
3294a3bd7f05Smrg                          SmInteractStyleNone);
3295444c061aSmrg    }
3296444c061aSmrg
3297a3bd7f05Smrg    XtCallCallbackList((Widget) w, w->session.cancel_callbacks,
3298a3bd7f05Smrg                       (XtPointer) NULL);
3299444c061aSmrg
3300444c061aSmrg    if (call_interacts) {
3301a3bd7f05Smrg        w->session.save->interact_style = SmInteractStyleNone;
3302a3bd7f05Smrg        XtInteractPermission(w->session.connection, (SmPointer) w);
3303444c061aSmrg    }
3304444c061aSmrg
3305444c061aSmrg    if (w->session.checkpoint_state != XtSaveInactive) {
3306a3bd7f05Smrg        if (w->session.save->save_tokens == 0 &&
3307a3bd7f05Smrg            w->session.checkpoint_state == XtSaveActive) {
3308a3bd7f05Smrg            w->session.checkpoint_state = XtSaveInactive;
3309a3bd7f05Smrg            SmcSaveYourselfDone(w->session.connection,
3310a3bd7f05Smrg                                w->session.save->save_success);
3311a3bd7f05Smrg            CleanUpSave(w);
3312a3bd7f05Smrg        }
3313444c061aSmrg    }
3314444c061aSmrg}
3315444c061aSmrg
3316a3bd7f05Smrgstatic XtCheckpointToken
3317a3bd7f05SmrgGetToken(Widget widget, int type)
3318444c061aSmrg{
3319444c061aSmrg    SessionShellWidget w = (SessionShellWidget) widget;
3320444c061aSmrg    XtCheckpointToken token;
3321444c061aSmrg    XtSaveYourself save = w->session.save;
3322444c061aSmrg
3323444c061aSmrg    if (type == XtSessionCheckpoint)
3324a3bd7f05Smrg        w->session.save->save_tokens++;
3325444c061aSmrg    else if (type == XtSessionInteract)
3326a3bd7f05Smrg        w->session.save->interact_tokens++;
3327444c061aSmrg    else
3328a3bd7f05Smrg        return (XtCheckpointToken) NULL;
3329444c061aSmrg
3330444c061aSmrg    token = (XtCheckpointToken) __XtMalloc(sizeof(XtCheckpointTokenRec));
3331444c061aSmrg    token->save_type = save->save_type;
3332444c061aSmrg    token->interact_style = save->interact_style;
3333444c061aSmrg    token->shutdown = save->shutdown;
3334444c061aSmrg    token->fast = save->fast;
3335444c061aSmrg    token->cancel_shutdown = save->cancel_shutdown;
3336444c061aSmrg    token->phase = save->phase;
3337444c061aSmrg    token->interact_dialog_type = save->interact_dialog_type;
3338444c061aSmrg    token->request_cancel = save->request_cancel;
3339444c061aSmrg    token->request_next_phase = save->request_next_phase;
3340444c061aSmrg    token->save_success = save->save_success;
3341444c061aSmrg    token->type = type;
3342444c061aSmrg    token->widget = widget;
3343444c061aSmrg    return token;
3344444c061aSmrg}
3345444c061aSmrg
3346a3bd7f05SmrgXtCheckpointToken
3347a3bd7f05SmrgXtSessionGetToken(Widget widget)
3348444c061aSmrg{
3349444c061aSmrg    SessionShellWidget w = (SessionShellWidget) widget;
3350444c061aSmrg    XtCheckpointToken token = NULL;
3351a3bd7f05Smrg
3352444c061aSmrg    WIDGET_TO_APPCON(widget);
3353444c061aSmrg
3354444c061aSmrg    LOCK_APP(app);
3355444c061aSmrg    if (w->session.checkpoint_state)
3356a3bd7f05Smrg        token = GetToken(widget, XtSessionCheckpoint);
3357444c061aSmrg
3358444c061aSmrg    UNLOCK_APP(app);
3359444c061aSmrg    return token;
3360444c061aSmrg}
3361444c061aSmrg
3362a3bd7f05Smrgstatic Boolean
3363a3bd7f05SmrgExamineToken(XtPointer call_data)
3364444c061aSmrg{
3365444c061aSmrg    XtCheckpointToken token = (XtCheckpointToken) call_data;
3366444c061aSmrg    SessionShellWidget w = (SessionShellWidget) token->widget;
3367444c061aSmrg
3368444c061aSmrg    if (token->interact_dialog_type == SmDialogError)
3369a3bd7f05Smrg        w->session.save->interact_dialog_type = SmDialogError;
3370444c061aSmrg    if (token->request_next_phase)
3371a3bd7f05Smrg        w->session.save->request_next_phase = True;
3372a3bd7f05Smrg    if (!token->save_success)
3373a3bd7f05Smrg        w->session.save->save_success = False;
3374444c061aSmrg
3375444c061aSmrg    token->interact_dialog_type = w->session.save->interact_dialog_type;
3376444c061aSmrg    token->request_next_phase = w->session.save->request_next_phase;
3377444c061aSmrg    token->save_success = w->session.save->save_success;
3378444c061aSmrg    token->cancel_shutdown = w->session.save->cancel_shutdown;
3379444c061aSmrg
3380444c061aSmrg    return True;
3381444c061aSmrg}
3382444c061aSmrg
3383a3bd7f05Smrgvoid
3384a3bd7f05SmrgXtSessionReturnToken(XtCheckpointToken token)
3385444c061aSmrg{
3386444c061aSmrg    SessionShellWidget w = (SessionShellWidget) token->widget;
3387444c061aSmrg    Boolean has_some;
3388444c061aSmrg    Boolean phase_done;
3389444c061aSmrg    XtCallbackProc callback;
3390444c061aSmrg    XtPointer client_data;
3391a3bd7f05Smrg
3392a3bd7f05Smrg    WIDGET_TO_APPCON((Widget) w);
3393444c061aSmrg
3394444c061aSmrg    LOCK_APP(app);
3395444c061aSmrg
3396444c061aSmrg    has_some = (XtHasCallbacks(token->widget, XtNinteractCallback)
3397a3bd7f05Smrg                == XtCallbackHasSome);
3398444c061aSmrg
3399444c061aSmrg    (void) ExamineToken((XtPointer) token);
3400444c061aSmrg
3401444c061aSmrg    if (token->type == XtSessionCheckpoint) {
3402a3bd7f05Smrg        w->session.save->save_tokens--;
3403a3bd7f05Smrg        if (has_some && w->session.checkpoint_state == XtSaveActive) {
3404a3bd7f05Smrg            w->session.checkpoint_state = XtInteractPending;
3405a3bd7f05Smrg            SmcInteractRequest(w->session.connection,
3406a3bd7f05Smrg                               w->session.save->interact_dialog_type,
3407a3bd7f05Smrg                               XtInteractPermission, (SmPointer) w);
3408a3bd7f05Smrg        }
3409a3bd7f05Smrg        XtFree((char *) token);
3410a3bd7f05Smrg    }
3411a3bd7f05Smrg    else {
3412a3bd7f05Smrg        if (token->request_cancel)
3413a3bd7f05Smrg            w->session.save->request_cancel = True;
3414a3bd7f05Smrg        token->request_cancel = w->session.save->request_cancel;
3415a3bd7f05Smrg        if (has_some) {
3416a3bd7f05Smrg            _XtPeekCallback((Widget) w, w->session.interact_callbacks,
3417a3bd7f05Smrg                            &callback, &client_data);
3418a3bd7f05Smrg            XtRemoveCallback((Widget) w, XtNinteractCallback,
3419a3bd7f05Smrg                             callback, client_data);
3420a3bd7f05Smrg            (*callback) ((Widget) w, client_data, (XtPointer) token);
3421a3bd7f05Smrg        }
3422a3bd7f05Smrg        else {
3423a3bd7f05Smrg            w->session.save->interact_tokens--;
3424a3bd7f05Smrg            if (w->session.save->interact_tokens == 0) {
3425a3bd7f05Smrg                w->session.checkpoint_state = XtSaveActive;
3426a3bd7f05Smrg                if (!w->session.save->cancel_shutdown)
3427a3bd7f05Smrg                    SmcInteractDone(w->session.connection,
3428a3bd7f05Smrg                                    w->session.save->request_cancel);
3429a3bd7f05Smrg            }
3430a3bd7f05Smrg            XtFree((char *) token);
3431a3bd7f05Smrg        }
3432444c061aSmrg    }
3433444c061aSmrg
3434444c061aSmrg    phase_done = (w->session.save->save_tokens == 0 &&
3435a3bd7f05Smrg                  w->session.checkpoint_state == XtSaveActive);
3436444c061aSmrg
3437444c061aSmrg    if (phase_done) {
3438a3bd7f05Smrg        if (w->session.save->request_next_phase && w->session.save->phase == 1) {
3439a3bd7f05Smrg            SmcRequestSaveYourselfPhase2(w->session.connection,
3440a3bd7f05Smrg                                         XtCallNextPhaseCallbacks,
3441a3bd7f05Smrg                                         (SmPointer) w);
3442a3bd7f05Smrg        }
3443a3bd7f05Smrg        else {
3444a3bd7f05Smrg            w->session.checkpoint_state = XtSaveInactive;
3445a3bd7f05Smrg            SmcSaveYourselfDone(w->session.connection,
3446a3bd7f05Smrg                                w->session.save->save_success);
3447a3bd7f05Smrg            CleanUpSave(w);
3448a3bd7f05Smrg        }
3449444c061aSmrg    }
3450444c061aSmrg
3451444c061aSmrg    UNLOCK_APP(app);
3452444c061aSmrg}
3453444c061aSmrg
3454a3bd7f05Smrgstatic Boolean
3455a3bd7f05SmrgIsInArray(String str, _XtString *sarray)
3456444c061aSmrg{
3457444c061aSmrg    if (str == NULL || sarray == NULL)
3458a3bd7f05Smrg        return False;
3459444c061aSmrg    for (; *sarray; sarray++) {
3460a3bd7f05Smrg        if (strcmp(*sarray, str) == 0)
3461a3bd7f05Smrg            return True;
3462444c061aSmrg    }
3463444c061aSmrg    return False;
3464444c061aSmrg}
3465444c061aSmrg
3466a3bd7f05Smrgstatic _XtString *
3467a3bd7f05SmrgEditCommand(_XtString str,      /* if not NULL, the sm_client_id */
3468a3bd7f05Smrg            _XtString *src1,   /* first choice */
3469a3bd7f05Smrg            _XtString *src2)   /* alternate */
3470a3bd7f05Smrg{
3471444c061aSmrg    Boolean have;
3472444c061aSmrg    Boolean want;
3473444c061aSmrg    int count;
34740568f49bSmrg    _XtString *sarray;
34750568f49bSmrg    _XtString *s;
34760568f49bSmrg    _XtString *new;
3477444c061aSmrg
3478444c061aSmrg    want = (str != NULL);
3479444c061aSmrg    sarray = (src1 ? src1 : src2);
3480a3bd7f05Smrg    if (!sarray)
3481a3bd7f05Smrg        return NULL;
3482444c061aSmrg    have = IsInArray("-xtsessionID", sarray);
3483444c061aSmrg    if ((want && have) || (!want && !have)) {
3484a3bd7f05Smrg        if (sarray == src1)
3485a3bd7f05Smrg            return src1;
3486a3bd7f05Smrg        else
3487a3bd7f05Smrg            return NewStringArray(sarray);
3488444c061aSmrg    }
3489444c061aSmrg
3490444c061aSmrg    count = 0;
3491444c061aSmrg    for (s = sarray; *s; s++)
3492a3bd7f05Smrg        count++;
3493444c061aSmrg
3494444c061aSmrg    if (want) {
3495fdf6a26fSmrg        s = new = XtMallocArray((Cardinal) count + 3,
3496fdf6a26fSmrg                                (Cardinal) sizeof(_XtString *));
3497a3bd7f05Smrg        *s = *sarray;
3498a3bd7f05Smrg        s++;
3499a3bd7f05Smrg        sarray++;
3500a3bd7f05Smrg        *s = (_XtString) "-xtsessionID";
3501a3bd7f05Smrg        s++;
3502a3bd7f05Smrg        *s = str;
3503a3bd7f05Smrg        s++;
3504a3bd7f05Smrg        for (; --count > 0; s++, sarray++)
3505a3bd7f05Smrg            *s = *sarray;
3506a3bd7f05Smrg        *s = NULL;
3507a3bd7f05Smrg    }
3508a3bd7f05Smrg    else {
3509a3bd7f05Smrg        if (count < 3)
3510a3bd7f05Smrg            return NewStringArray(sarray);
3511fdf6a26fSmrg        s = new = XtMallocArray((Cardinal) count - 1,
3512fdf6a26fSmrg                                (Cardinal) sizeof(_XtString *));
3513a3bd7f05Smrg        for (; --count >= 0; sarray++) {
3514a3bd7f05Smrg            if (strcmp(*sarray, "-xtsessionID") == 0) {
3515a3bd7f05Smrg                sarray++;
3516a3bd7f05Smrg                count--;
3517a3bd7f05Smrg            }
3518a3bd7f05Smrg            else {
3519a3bd7f05Smrg                *s = *sarray;
3520a3bd7f05Smrg                s++;
3521a3bd7f05Smrg            }
3522a3bd7f05Smrg        }
3523a3bd7f05Smrg        *s = NULL;
3524444c061aSmrg    }
3525444c061aSmrg    s = new;
3526444c061aSmrg    new = NewStringArray(new);
3527a3bd7f05Smrg    XtFree((char *) s);
3528444c061aSmrg    return new;
3529444c061aSmrg}
3530444c061aSmrg
3531a3bd7f05Smrg#endif                          /* !XT_NO_SM */
3532