Shell.c revision a3bd7f05
1444c061aSmrg/***********************************************************
2249c3046SmrgCopyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
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);
959a3bd7f05Smrg        (void) memmove((char *) ext,
960a3bd7f05Smrg                       (char *) _FindClassExtension(widget_class->
961a3bd7f05Smrg                                                    core_class.superclass),
962a3bd7f05Smrg                       sizeof(ShellClassExtensionRec));
963a3bd7f05Smrg        ext->next_extension = *extP;
964a3bd7f05Smrg        *extP = (XtPointer) ext;
965a3bd7f05Smrg    }
966a3bd7f05Smrg}
967444c061aSmrg
968a3bd7f05Smrgstatic void EventHandler(Widget wid, XtPointer closure, XEvent *event,
969a3bd7f05Smrg                         Boolean *continue_to_dispatch);
970a3bd7f05Smrgstatic void _popup_set_prop(ShellWidget);
971444c061aSmrg
972a3bd7f05Smrgstatic void
973a3bd7f05SmrgXtCopyDefaultDepth(Widget widget, int offset _X_UNUSED, XrmValue *value)
974444c061aSmrg{
975a3bd7f05Smrg    value->addr = (XPointer) (&DefaultDepthOfScreen(XtScreenOfObject(widget)));
976444c061aSmrg}
977444c061aSmrg
978a3bd7f05Smrgstatic void
979a3bd7f05Smrg_XtShellDepth(Widget widget, int closure, XrmValue *value)
980444c061aSmrg{
981a3bd7f05Smrg    if (widget->core.parent == NULL)
982a3bd7f05Smrg        XtCopyDefaultDepth(widget, closure, value);
983a3bd7f05Smrg    else
984a3bd7f05Smrg        _XtCopyFromParent(widget, closure, value);
985444c061aSmrg}
986444c061aSmrg
987a3bd7f05Smrgstatic void
988a3bd7f05SmrgXtCopyDefaultColormap(Widget widget, int offset _X_UNUSED, XrmValue *value)
989444c061aSmrg{
990a3bd7f05Smrg    value->addr =
991a3bd7f05Smrg        (XPointer) (&DefaultColormapOfScreen(XtScreenOfObject(widget)));
992444c061aSmrg}
993444c061aSmrg
994a3bd7f05Smrgstatic void
995a3bd7f05Smrg_XtShellColormap(Widget widget, int closure, XrmValue *value)
996444c061aSmrg{
997a3bd7f05Smrg    if (widget->core.parent == NULL)
998a3bd7f05Smrg        XtCopyDefaultColormap(widget, closure, value);
999a3bd7f05Smrg    else
1000a3bd7f05Smrg        _XtCopyFromParent(widget, closure, value);
1001444c061aSmrg}
1002444c061aSmrg
1003a3bd7f05Smrgstatic void
1004a3bd7f05Smrg_XtShellAncestorSensitive(Widget widget, int closure, XrmValue *value)
1005444c061aSmrg{
1006a3bd7f05Smrg    static Boolean true = True;
1007a3bd7f05Smrg
1008a3bd7f05Smrg    if (widget->core.parent == NULL)
1009a3bd7f05Smrg        value->addr = (XPointer) (&true);
1010a3bd7f05Smrg    else
1011a3bd7f05Smrg        _XtCopyFromParent(widget, closure, value);
1012444c061aSmrg}
1013444c061aSmrg
1014a3bd7f05Smrgstatic void
1015a3bd7f05Smrg_XtTitleEncoding(Widget widget, int offset _X_UNUSED, XrmValue *value)
1016444c061aSmrg{
1017444c061aSmrg    static Atom atom;
1018a3bd7f05Smrg
1019a3bd7f05Smrg    if (XtWidgetToApplicationContext(widget)->langProcRec.proc)
1020a3bd7f05Smrg        atom = None;
1021a3bd7f05Smrg    else
1022a3bd7f05Smrg        atom = XA_STRING;
1023444c061aSmrg    value->addr = (XPointer) &atom;
1024444c061aSmrg}
1025444c061aSmrg
1026a3bd7f05Smrgstatic void
1027a3bd7f05SmrgInitialize(Widget req _X_UNUSED,
1028a3bd7f05Smrg           Widget new,
1029a3bd7f05Smrg           ArgList args _X_UNUSED,
1030a3bd7f05Smrg           Cardinal *num_args _X_UNUSED)
1031444c061aSmrg{
1032a3bd7f05Smrg    ShellWidget w = (ShellWidget) new;
1033444c061aSmrg
1034a3bd7f05Smrg    w->shell.popped_up = FALSE;
1035a3bd7f05Smrg    w->shell.client_specified = _XtShellNotReparented | _XtShellPositionValid;
1036444c061aSmrg
1037a3bd7f05Smrg    if (w->core.x == BIGSIZE) {
1038a3bd7f05Smrg        w->core.x = 0;
1039a3bd7f05Smrg        if (w->core.y == BIGSIZE)
1040a3bd7f05Smrg            w->core.y = 0;
1041a3bd7f05Smrg    }
1042a3bd7f05Smrg    else {
1043a3bd7f05Smrg        if (w->core.y == BIGSIZE)
1044a3bd7f05Smrg            w->core.y = 0;
1045a3bd7f05Smrg        else
1046a3bd7f05Smrg            w->shell.client_specified |= _XtShellPPositionOK;
1047a3bd7f05Smrg    }
1048444c061aSmrg
1049a3bd7f05Smrg    XtAddEventHandler(new, (EventMask) StructureNotifyMask,
1050a3bd7f05Smrg                      TRUE, EventHandler, (XtPointer) NULL);
1051444c061aSmrg
1052444c061aSmrg#ifdef EDITRES
1053a3bd7f05Smrg    XtAddEventHandler(new, (EventMask) 0, TRUE, _XEditResCheckMessages, NULL);
1054444c061aSmrg#endif
1055444c061aSmrg}
1056444c061aSmrg
1057a3bd7f05Smrgstatic void
1058a3bd7f05SmrgWMInitialize(Widget req _X_UNUSED,
1059a3bd7f05Smrg             Widget new,
1060a3bd7f05Smrg             ArgList args _X_UNUSED,
1061a3bd7f05Smrg             Cardinal *num_args _X_UNUSED)
1062444c061aSmrg{
1063a3bd7f05Smrg    WMShellWidget w = (WMShellWidget) new;
1064a3bd7f05Smrg    TopLevelShellWidget tls = (TopLevelShellWidget) new;        /* maybe */
1065444c061aSmrg
1066a3bd7f05Smrg    if (w->wm.title == NULL) {
1067a3bd7f05Smrg        if (XtIsTopLevelShell(new) &&
1068a3bd7f05Smrg            tls->topLevel.icon_name != NULL &&
1069a3bd7f05Smrg            strlen(tls->topLevel.icon_name) != 0) {
1070a3bd7f05Smrg            w->wm.title = XtNewString(tls->topLevel.icon_name);
1071a3bd7f05Smrg        }
1072a3bd7f05Smrg        else {
1073a3bd7f05Smrg            w->wm.title = XtNewString(w->core.name);
1074a3bd7f05Smrg        }
1075a3bd7f05Smrg    }
1076a3bd7f05Smrg    else {
1077a3bd7f05Smrg        w->wm.title = XtNewString(w->wm.title);
1078a3bd7f05Smrg    }
1079a3bd7f05Smrg    w->wm.size_hints.flags = 0;
1080a3bd7f05Smrg    w->wm.wm_hints.flags = 0;
1081a3bd7f05Smrg    if (w->wm.window_role)
1082a3bd7f05Smrg        w->wm.window_role = XtNewString(w->wm.window_role);
1083444c061aSmrg}
1084444c061aSmrg
1085a3bd7f05Smrgstatic void
1086a3bd7f05SmrgTopLevelInitialize(Widget req _X_UNUSED,
1087a3bd7f05Smrg                   Widget new,
1088a3bd7f05Smrg                   ArgList args _X_UNUSED,
1089a3bd7f05Smrg                   Cardinal *num_args _X_UNUSED)
1090444c061aSmrg{
1091a3bd7f05Smrg    TopLevelShellWidget w = (TopLevelShellWidget) new;
1092444c061aSmrg
1093a3bd7f05Smrg    if (w->topLevel.icon_name == NULL) {
1094a3bd7f05Smrg        w->topLevel.icon_name = XtNewString(w->core.name);
1095a3bd7f05Smrg    }
1096a3bd7f05Smrg    else {
1097a3bd7f05Smrg        w->topLevel.icon_name = XtNewString(w->topLevel.icon_name);
1098a3bd7f05Smrg    }
1099444c061aSmrg
1100a3bd7f05Smrg    if (w->topLevel.iconic)
1101a3bd7f05Smrg        w->wm.wm_hints.initial_state = IconicState;
1102444c061aSmrg}
1103444c061aSmrg
11040568f49bSmrgstatic _XtString *NewArgv(int, _XtString *);
11050568f49bSmrgstatic _XtString *NewStringArray(_XtString *);
11060568f49bSmrgstatic void FreeStringArray(_XtString *);
1107444c061aSmrg
1108a3bd7f05Smrgstatic void
1109a3bd7f05SmrgApplicationInitialize(Widget req _X_UNUSED,
1110a3bd7f05Smrg                      Widget new,
1111a3bd7f05Smrg                      ArgList args _X_UNUSED,
1112a3bd7f05Smrg                      Cardinal *num_args _X_UNUSED)
1113444c061aSmrg{
1114a3bd7f05Smrg    ApplicationShellWidget w = (ApplicationShellWidget) new;
1115444c061aSmrg
1116444c061aSmrg    if (w->application.argc > 0)
1117a3bd7f05Smrg        w->application.argv = NewArgv(w->application.argc, w->application.argv);
1118444c061aSmrg}
1119444c061aSmrg
1120444c061aSmrg#define XtSaveInactive 0
1121444c061aSmrg#define XtSaveActive   1
1122444c061aSmrg#define XtInteractPending    2
1123444c061aSmrg#define XtInteractActive     3
1124444c061aSmrg
1125a3bd7f05Smrg#define XtCloneCommandMask      (1L<<0)
1126a3bd7f05Smrg#define XtCurrentDirectoryMask  (1L<<1)
1127a3bd7f05Smrg#define XtDiscardCommandMask    (1L<<2)
1128a3bd7f05Smrg#define XtEnvironmentMask       (1L<<3)
1129a3bd7f05Smrg#define XtProgramMask           (1L<<4)
1130a3bd7f05Smrg#define XtResignCommandMask     (1L<<5)
1131a3bd7f05Smrg#define XtRestartCommandMask    (1L<<6)
1132a3bd7f05Smrg#define XtRestartStyleHintMask  (1L<<7)
1133a3bd7f05Smrg#define XtShutdownCommandMask   (1L<<8)
1134444c061aSmrg
1135444c061aSmrgstatic void JoinSession(SessionShellWidget);
1136a3bd7f05Smrgstatic void SetSessionProperties(SessionShellWidget, Boolean, unsigned long,
1137a3bd7f05Smrg                                 unsigned long);
1138444c061aSmrgstatic void StopManagingSession(SessionShellWidget, SmcConn);
1139444c061aSmrg
1140444c061aSmrgtypedef struct _XtSaveYourselfRec {
1141444c061aSmrg    XtSaveYourself next;
1142a3bd7f05Smrg    int save_type;
1143a3bd7f05Smrg    int interact_style;
1144a3bd7f05Smrg    Boolean shutdown;
1145a3bd7f05Smrg    Boolean fast;
1146a3bd7f05Smrg    Boolean cancel_shutdown;
1147a3bd7f05Smrg    int phase;
1148a3bd7f05Smrg    int interact_dialog_type;
1149a3bd7f05Smrg    Boolean request_cancel;
1150a3bd7f05Smrg    Boolean request_next_phase;
1151a3bd7f05Smrg    Boolean save_success;
1152a3bd7f05Smrg    int save_tokens;
1153a3bd7f05Smrg    int interact_tokens;
1154444c061aSmrg} XtSaveYourselfRec;
1155444c061aSmrg
1156a3bd7f05Smrgstatic void
1157a3bd7f05SmrgSessionInitialize(Widget req _X_UNUSED,
1158a3bd7f05Smrg                  Widget new,
1159a3bd7f05Smrg                  ArgList args _X_UNUSED,
1160a3bd7f05Smrg                  Cardinal *num_args _X_UNUSED)
1161444c061aSmrg{
1162444c061aSmrg#ifndef XT_NO_SM
1163a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) new;
1164a3bd7f05Smrg
1165a3bd7f05Smrg    if (w->session.session_id)
1166a3bd7f05Smrg        w->session.session_id = XtNewString(w->session.session_id);
1167a3bd7f05Smrg    if (w->session.restart_command)
1168a3bd7f05Smrg        w->session.restart_command = NewStringArray(w->session.restart_command);
1169a3bd7f05Smrg    if (w->session.clone_command)
1170a3bd7f05Smrg        w->session.clone_command = NewStringArray(w->session.clone_command);
1171a3bd7f05Smrg    if (w->session.discard_command)
1172a3bd7f05Smrg        w->session.discard_command = NewStringArray(w->session.discard_command);
1173a3bd7f05Smrg    if (w->session.resign_command)
1174a3bd7f05Smrg        w->session.resign_command = NewStringArray(w->session.resign_command);
1175a3bd7f05Smrg    if (w->session.shutdown_command)
1176a3bd7f05Smrg        w->session.shutdown_command =
1177a3bd7f05Smrg            NewStringArray(w->session.shutdown_command);
1178a3bd7f05Smrg    if (w->session.environment)
1179a3bd7f05Smrg        w->session.environment = NewStringArray(w->session.environment);
1180a3bd7f05Smrg    if (w->session.current_dir)
1181a3bd7f05Smrg        w->session.current_dir = XtNewString(w->session.current_dir);
1182a3bd7f05Smrg    if (w->session.program_path)
1183a3bd7f05Smrg        w->session.program_path = XtNewString(w->session.program_path);
1184444c061aSmrg
1185444c061aSmrg    w->session.checkpoint_state = XtSaveInactive;
1186444c061aSmrg    w->session.input_id = 0;
1187444c061aSmrg    w->session.save = NULL;
1188444c061aSmrg
1189444c061aSmrg    if ((w->session.join_session) &&
1190a3bd7f05Smrg        (w->application.argv || w->session.restart_command))
1191a3bd7f05Smrg        JoinSession(w);
1192444c061aSmrg
1193444c061aSmrg    if (w->session.connection)
1194a3bd7f05Smrg        SetSessionProperties(w, True, 0L, 0L);
1195a3bd7f05Smrg#endif                          /* !XT_NO_SM */
1196444c061aSmrg}
1197444c061aSmrg
1198a3bd7f05Smrgstatic void
1199a3bd7f05SmrgResize(Widget w)
1200444c061aSmrg{
1201a3bd7f05Smrg    register ShellWidget sw = (ShellWidget) w;
1202444c061aSmrg    Widget childwid;
1203444c061aSmrg    Cardinal i;
1204a3bd7f05Smrg
1205a3bd7f05Smrg    for (i = 0; i < sw->composite.num_children; i++) {
1206444c061aSmrg        if (XtIsManaged(sw->composite.children[i])) {
1207a3bd7f05Smrg            childwid = sw->composite.children[i];
1208a3bd7f05Smrg            XtResizeWidget(childwid, sw->core.width, sw->core.height,
1209444c061aSmrg                           childwid->core.border_width);
1210a3bd7f05Smrg            break;              /* can only be one managed child */
1211444c061aSmrg        }
1212444c061aSmrg    }
1213444c061aSmrg}
1214444c061aSmrg
1215444c061aSmrgstatic void GetGeometry(Widget, Widget);
1216444c061aSmrg
1217a3bd7f05Smrgstatic void
1218a3bd7f05SmrgRealize(Widget wid, Mask *vmask, XSetWindowAttributes *attr)
1219a3bd7f05Smrg{
1220a3bd7f05Smrg    ShellWidget w = (ShellWidget) wid;
1221a3bd7f05Smrg    Mask mask = *vmask;
1222a3bd7f05Smrg
1223a3bd7f05Smrg    if (!(w->shell.client_specified & _XtShellGeometryParsed)) {
1224a3bd7f05Smrg        /* we'll get here only if there was no child the first
1225a3bd7f05Smrg           time we were realized.  If the shell was Unrealized
1226a3bd7f05Smrg           and then re-Realized, we probably don't want to
1227a3bd7f05Smrg           re-evaluate the defaults anyway.
1228a3bd7f05Smrg         */
1229a3bd7f05Smrg        GetGeometry(wid, (Widget) NULL);
1230a3bd7f05Smrg    }
1231a3bd7f05Smrg    else if (w->core.background_pixmap == XtUnspecifiedPixmap) {
1232a3bd7f05Smrg        /* I attempt to inherit my child's background to avoid screen flash
1233a3bd7f05Smrg         * if there is latency between when I get resized and when my child
1234a3bd7f05Smrg         * is resized.  Background=None is not satisfactory, as I want the
1235a3bd7f05Smrg         * user to get immediate feedback on the new dimensions (most
1236a3bd7f05Smrg         * particularly in the case of a non-reparenting wm).  It is
1237a3bd7f05Smrg         * especially important to have the server clear any old cruft
1238a3bd7f05Smrg         * from the display when I am resized larger.
1239a3bd7f05Smrg         */
1240a3bd7f05Smrg        register Widget *childP = w->composite.children;
1241a3bd7f05Smrg        int i;
1242a3bd7f05Smrg
1243a3bd7f05Smrg        for (i = (int) w->composite.num_children; i; i--, childP++) {
1244a3bd7f05Smrg            if (XtIsWidget(*childP) && XtIsManaged(*childP)) {
1245a3bd7f05Smrg                if ((*childP)->core.background_pixmap != XtUnspecifiedPixmap) {
1246a3bd7f05Smrg                    mask &= (unsigned long) (~(CWBackPixel));
1247a3bd7f05Smrg                    mask |= CWBackPixmap;
1248a3bd7f05Smrg                    attr->background_pixmap =
1249a3bd7f05Smrg                        w->core.background_pixmap =
1250a3bd7f05Smrg                        (*childP)->core.background_pixmap;
1251a3bd7f05Smrg                }
1252a3bd7f05Smrg                else {
1253a3bd7f05Smrg                    attr->background_pixel =
1254a3bd7f05Smrg                        w->core.background_pixel =
1255a3bd7f05Smrg                        (*childP)->core.background_pixel;
1256a3bd7f05Smrg                }
1257a3bd7f05Smrg                break;
1258a3bd7f05Smrg            }
1259a3bd7f05Smrg        }
1260a3bd7f05Smrg    }
1261a3bd7f05Smrg
1262a3bd7f05Smrg    if (w->shell.save_under) {
1263a3bd7f05Smrg        mask |= CWSaveUnder;
1264a3bd7f05Smrg        attr->save_under = TRUE;
1265a3bd7f05Smrg    }
1266a3bd7f05Smrg    if (w->shell.override_redirect) {
1267a3bd7f05Smrg        mask |= CWOverrideRedirect;
1268a3bd7f05Smrg        attr->override_redirect = TRUE;
1269a3bd7f05Smrg    }
1270a3bd7f05Smrg    if (wid->core.width == 0 || wid->core.height == 0) {
1271a3bd7f05Smrg        Cardinal count = 1;
1272a3bd7f05Smrg
1273a3bd7f05Smrg        XtErrorMsg("invalidDimension", "shellRealize", XtCXtToolkitError,
1274a3bd7f05Smrg                   "Shell widget %s has zero width and/or height",
1275a3bd7f05Smrg                   &wid->core.name, &count);
1276a3bd7f05Smrg    }
1277a3bd7f05Smrg    wid->core.window = XCreateWindow(XtDisplay(wid),
1278a3bd7f05Smrg                                     wid->core.screen->root, (int) wid->core.x,
1279a3bd7f05Smrg                                     (int) wid->core.y,
1280a3bd7f05Smrg                                     (unsigned int) wid->core.width,
1281a3bd7f05Smrg                                     (unsigned int) wid->core.height,
1282a3bd7f05Smrg                                     (unsigned int) wid->core.border_width,
1283a3bd7f05Smrg                                     (int) wid->core.depth,
1284a3bd7f05Smrg                                     (unsigned int) InputOutput,
1285a3bd7f05Smrg                                     w->shell.visual, mask, attr);
1286a3bd7f05Smrg
1287a3bd7f05Smrg    _popup_set_prop(w);
1288a3bd7f05Smrg}
1289a3bd7f05Smrg
1290a3bd7f05Smrgstatic void
1291a3bd7f05Smrg_SetTransientForHint(TransientShellWidget w, Boolean delete)
1292444c061aSmrg{
1293444c061aSmrg    Window window_group;
1294444c061aSmrg
1295444c061aSmrg    if (w->wm.transient) {
1296a3bd7f05Smrg        if (w->transient.transient_for != NULL
1297a3bd7f05Smrg            && XtIsRealized(w->transient.transient_for))
1298a3bd7f05Smrg            window_group = XtWindow(w->transient.transient_for);
1299a3bd7f05Smrg        else if ((window_group = w->wm.wm_hints.window_group)
1300a3bd7f05Smrg                 == XtUnspecifiedWindowGroup) {
1301a3bd7f05Smrg            if (delete)
1302a3bd7f05Smrg                XDeleteProperty(XtDisplay((Widget) w),
1303a3bd7f05Smrg                                XtWindow((Widget) w), XA_WM_TRANSIENT_FOR);
1304a3bd7f05Smrg            return;
1305a3bd7f05Smrg        }
1306444c061aSmrg
1307a3bd7f05Smrg        XSetTransientForHint(XtDisplay((Widget) w),
1308a3bd7f05Smrg                             XtWindow((Widget) w), window_group);
1309444c061aSmrg    }
1310444c061aSmrg}
1311444c061aSmrg
1312a3bd7f05Smrgstatic void
1313a3bd7f05SmrgTransientRealize(Widget w, Mask *vmask, XSetWindowAttributes *attr)
1314444c061aSmrg{
1315444c061aSmrg    XtRealizeProc realize;
1316444c061aSmrg
1317444c061aSmrg    LOCK_PROCESS;
1318444c061aSmrg    realize =
1319a3bd7f05Smrg        transientShellWidgetClass->core_class.superclass->core_class.realize;
1320444c061aSmrg    UNLOCK_PROCESS;
1321444c061aSmrg    (*realize) (w, vmask, attr);
1322444c061aSmrg
1323a3bd7f05Smrg    _SetTransientForHint((TransientShellWidget) w, False);
1324444c061aSmrg}
1325444c061aSmrg
1326a3bd7f05Smrgstatic Widget
1327a3bd7f05SmrgGetClientLeader(Widget w)
1328444c061aSmrg{
1329a3bd7f05Smrg    while ((!XtIsWMShell(w) || !((WMShellWidget) w)->wm.client_leader)
1330a3bd7f05Smrg           && w->core.parent)
1331a3bd7f05Smrg        w = w->core.parent;
1332444c061aSmrg
1333444c061aSmrg    /* ASSERT: w is a WMshell with client_leader set, or w has no parent */
1334444c061aSmrg
1335a3bd7f05Smrg    if (XtIsWMShell(w) && ((WMShellWidget) w)->wm.client_leader)
1336a3bd7f05Smrg        w = ((WMShellWidget) w)->wm.client_leader;
1337444c061aSmrg    return w;
1338444c061aSmrg}
1339444c061aSmrg
1340a3bd7f05Smrgstatic void
1341a3bd7f05SmrgEvaluateWMHints(WMShellWidget w)
1342a3bd7f05Smrg{
1343a3bd7f05Smrg    XWMHints *hintp = &w->wm.wm_hints;
1344a3bd7f05Smrg
1345a3bd7f05Smrg    hintp->flags = StateHint | InputHint;
1346a3bd7f05Smrg
1347a3bd7f05Smrg    if (hintp->icon_x == XtUnspecifiedShellInt)
1348a3bd7f05Smrg        hintp->icon_x = -1;
1349a3bd7f05Smrg    else
1350a3bd7f05Smrg        hintp->flags |= IconPositionHint;
1351a3bd7f05Smrg
1352a3bd7f05Smrg    if (hintp->icon_y == XtUnspecifiedShellInt)
1353a3bd7f05Smrg        hintp->icon_y = -1;
1354a3bd7f05Smrg    else
1355a3bd7f05Smrg        hintp->flags |= IconPositionHint;
1356a3bd7f05Smrg
1357a3bd7f05Smrg    if (hintp->icon_pixmap != None)
1358a3bd7f05Smrg        hintp->flags |= IconPixmapHint;
1359a3bd7f05Smrg    if (hintp->icon_mask != None)
1360a3bd7f05Smrg        hintp->flags |= IconMaskHint;
1361a3bd7f05Smrg    if (hintp->icon_window != None)
1362a3bd7f05Smrg        hintp->flags |= IconWindowHint;
1363a3bd7f05Smrg
1364a3bd7f05Smrg    if (hintp->window_group == XtUnspecifiedWindow) {
1365a3bd7f05Smrg        if (w->core.parent) {
1366a3bd7f05Smrg            Widget p;
1367a3bd7f05Smrg
1368a3bd7f05Smrg            for (p = w->core.parent; p->core.parent; p = p->core.parent);
1369a3bd7f05Smrg            if (XtIsRealized(p)) {
1370a3bd7f05Smrg                hintp->window_group = XtWindow(p);
1371a3bd7f05Smrg                hintp->flags |= WindowGroupHint;
1372a3bd7f05Smrg            }
1373a3bd7f05Smrg        }
1374a3bd7f05Smrg    }
1375a3bd7f05Smrg    else if (hintp->window_group != XtUnspecifiedWindowGroup)
1376a3bd7f05Smrg        hintp->flags |= WindowGroupHint;
1377a3bd7f05Smrg
1378a3bd7f05Smrg    if (w->wm.urgency)
1379a3bd7f05Smrg        hintp->flags |= XUrgencyHint;
1380a3bd7f05Smrg}
1381a3bd7f05Smrg
1382a3bd7f05Smrgstatic void
1383a3bd7f05SmrgEvaluateSizeHints(WMShellWidget w)
1384a3bd7f05Smrg{
1385a3bd7f05Smrg    struct _OldXSizeHints *sizep = &w->wm.size_hints;
1386a3bd7f05Smrg
1387a3bd7f05Smrg    sizep->x = w->core.x;
1388a3bd7f05Smrg    sizep->y = w->core.y;
1389a3bd7f05Smrg    sizep->width = w->core.width;
1390a3bd7f05Smrg    sizep->height = w->core.height;
1391a3bd7f05Smrg
1392a3bd7f05Smrg    if (sizep->flags & USSize) {
1393a3bd7f05Smrg        if (sizep->flags & PSize)
1394a3bd7f05Smrg            sizep->flags &= ~PSize;
1395a3bd7f05Smrg    }
1396a3bd7f05Smrg    else
1397a3bd7f05Smrg        sizep->flags |= PSize;
1398a3bd7f05Smrg
1399a3bd7f05Smrg    if (sizep->flags & USPosition) {
1400a3bd7f05Smrg        if (sizep->flags & PPosition)
1401a3bd7f05Smrg            sizep->flags &= ~PPosition;
1402a3bd7f05Smrg    }
1403a3bd7f05Smrg    else if (w->shell.client_specified & _XtShellPPositionOK)
1404a3bd7f05Smrg        sizep->flags |= PPosition;
1405a3bd7f05Smrg
1406a3bd7f05Smrg    if (sizep->min_aspect.x != XtUnspecifiedShellInt
1407a3bd7f05Smrg        || sizep->min_aspect.y != XtUnspecifiedShellInt
1408a3bd7f05Smrg        || sizep->max_aspect.x != XtUnspecifiedShellInt
1409a3bd7f05Smrg        || sizep->max_aspect.y != XtUnspecifiedShellInt) {
1410a3bd7f05Smrg        sizep->flags |= PAspect;
1411a3bd7f05Smrg    }
1412a3bd7f05Smrg    if (sizep->flags & PBaseSize
1413a3bd7f05Smrg        || w->wm.base_width != XtUnspecifiedShellInt
1414a3bd7f05Smrg        || w->wm.base_height != XtUnspecifiedShellInt) {
1415a3bd7f05Smrg        sizep->flags |= PBaseSize;
1416a3bd7f05Smrg        if (w->wm.base_width == XtUnspecifiedShellInt)
1417a3bd7f05Smrg            w->wm.base_width = 0;
1418a3bd7f05Smrg        if (w->wm.base_height == XtUnspecifiedShellInt)
1419a3bd7f05Smrg            w->wm.base_height = 0;
1420a3bd7f05Smrg    }
1421a3bd7f05Smrg    if (sizep->flags & PResizeInc
1422a3bd7f05Smrg        || sizep->width_inc != XtUnspecifiedShellInt
1423a3bd7f05Smrg        || sizep->height_inc != XtUnspecifiedShellInt) {
1424a3bd7f05Smrg        if (sizep->width_inc < 1)
1425a3bd7f05Smrg            sizep->width_inc = 1;
1426a3bd7f05Smrg        if (sizep->height_inc < 1)
1427a3bd7f05Smrg            sizep->height_inc = 1;
1428a3bd7f05Smrg        sizep->flags |= PResizeInc;
1429a3bd7f05Smrg    }
1430a3bd7f05Smrg    if (sizep->flags & PMaxSize
1431a3bd7f05Smrg        || sizep->max_width != XtUnspecifiedShellInt
1432a3bd7f05Smrg        || sizep->max_height != XtUnspecifiedShellInt) {
1433a3bd7f05Smrg        sizep->flags |= PMaxSize;
1434a3bd7f05Smrg        if (sizep->max_width == XtUnspecifiedShellInt)
1435a3bd7f05Smrg            sizep->max_width = BIGSIZE;
1436a3bd7f05Smrg        if (sizep->max_height == XtUnspecifiedShellInt)
1437a3bd7f05Smrg            sizep->max_height = BIGSIZE;
1438a3bd7f05Smrg    }
1439a3bd7f05Smrg    if (sizep->flags & PMinSize
1440a3bd7f05Smrg        || sizep->min_width != XtUnspecifiedShellInt
1441a3bd7f05Smrg        || sizep->min_height != XtUnspecifiedShellInt) {
1442a3bd7f05Smrg        sizep->flags |= PMinSize;
1443a3bd7f05Smrg        if (sizep->min_width == XtUnspecifiedShellInt)
1444a3bd7f05Smrg            sizep->min_width = 1;
1445a3bd7f05Smrg        if (sizep->min_height == XtUnspecifiedShellInt)
1446a3bd7f05Smrg            sizep->min_height = 1;
1447a3bd7f05Smrg    }
1448a3bd7f05Smrg}
1449a3bd7f05Smrg
1450a3bd7f05Smrgstatic void
1451a3bd7f05Smrg_popup_set_prop(ShellWidget w)
1452a3bd7f05Smrg{
1453a3bd7f05Smrg    Widget p;
1454a3bd7f05Smrg    WMShellWidget wmshell = (WMShellWidget) w;
1455a3bd7f05Smrg    TopLevelShellWidget tlshell = (TopLevelShellWidget) w;
1456a3bd7f05Smrg    ApplicationShellWidget appshell = (ApplicationShellWidget) w;
1457a3bd7f05Smrg    XTextProperty icon_name;
1458a3bd7f05Smrg    XTextProperty window_name;
1459a3bd7f05Smrg    char **argv;
1460a3bd7f05Smrg    int argc;
1461a3bd7f05Smrg    XSizeHints *size_hints;
1462a3bd7f05Smrg    Window window_group;
1463a3bd7f05Smrg    XClassHint classhint;
1464a3bd7f05Smrg    Boolean copied_iname, copied_wname;
1465a3bd7f05Smrg
1466a3bd7f05Smrg    if (!XtIsWMShell((Widget) w) || w->shell.override_redirect)
1467a3bd7f05Smrg        return;
1468a3bd7f05Smrg
1469a3bd7f05Smrg    if ((size_hints = XAllocSizeHints()) == NULL)
1470a3bd7f05Smrg        _XtAllocError("XAllocSizeHints");
1471a3bd7f05Smrg
1472a3bd7f05Smrg    copied_iname = copied_wname = False;
1473a3bd7f05Smrg    if (wmshell->wm.title_encoding == None &&
1474a3bd7f05Smrg        XmbTextListToTextProperty(XtDisplay((Widget) w),
1475a3bd7f05Smrg                                  (char **) &wmshell->wm.title,
1476a3bd7f05Smrg                                  1, XStdICCTextStyle,
1477a3bd7f05Smrg                                  &window_name) >= Success) {
1478a3bd7f05Smrg        copied_wname = True;
1479a3bd7f05Smrg    }
1480a3bd7f05Smrg    else {
1481a3bd7f05Smrg        window_name.value = (unsigned char *) wmshell->wm.title;
1482a3bd7f05Smrg        window_name.encoding = wmshell->wm.title_encoding ?
1483a3bd7f05Smrg            wmshell->wm.title_encoding : XA_STRING;
1484a3bd7f05Smrg        window_name.format = 8;
1485a3bd7f05Smrg        window_name.nitems = strlen((char *) window_name.value);
1486a3bd7f05Smrg    }
1487a3bd7f05Smrg
1488a3bd7f05Smrg    if (XtIsTopLevelShell((Widget) w)) {
1489a3bd7f05Smrg        if (tlshell->topLevel.icon_name_encoding == None &&
1490a3bd7f05Smrg            XmbTextListToTextProperty(XtDisplay((Widget) w),
1491a3bd7f05Smrg                                      (char **) &tlshell->topLevel.icon_name,
1492a3bd7f05Smrg                                      1, XStdICCTextStyle,
1493a3bd7f05Smrg                                      &icon_name) >= Success) {
1494a3bd7f05Smrg            copied_iname = True;
1495a3bd7f05Smrg        }
1496a3bd7f05Smrg        else {
1497a3bd7f05Smrg            icon_name.value = (unsigned char *) tlshell->topLevel.icon_name;
1498a3bd7f05Smrg            icon_name.encoding = tlshell->topLevel.icon_name_encoding ?
1499a3bd7f05Smrg                tlshell->topLevel.icon_name_encoding : XA_STRING;
1500a3bd7f05Smrg            icon_name.format = 8;
1501a3bd7f05Smrg            icon_name.nitems = strlen((char *) icon_name.value);
1502a3bd7f05Smrg        }
1503a3bd7f05Smrg    }
1504a3bd7f05Smrg
1505a3bd7f05Smrg    EvaluateWMHints(wmshell);
1506a3bd7f05Smrg    EvaluateSizeHints(wmshell);
1507a3bd7f05Smrg    ComputeWMSizeHints(wmshell, size_hints);
1508a3bd7f05Smrg
1509a3bd7f05Smrg    if (wmshell->wm.transient && !XtIsTransientShell((Widget) w)
1510a3bd7f05Smrg        && (window_group = wmshell->wm.wm_hints.window_group)
1511a3bd7f05Smrg        != XtUnspecifiedWindowGroup) {
1512a3bd7f05Smrg
1513a3bd7f05Smrg        XSetTransientForHint(XtDisplay((Widget) w),
1514a3bd7f05Smrg                             XtWindow((Widget) w), window_group);
1515a3bd7f05Smrg    }
1516a3bd7f05Smrg
1517a3bd7f05Smrg    classhint.res_name = (_XtString) w->core.name;
1518a3bd7f05Smrg    /* For the class, look up to the top of the tree */
1519a3bd7f05Smrg    for (p = (Widget) w; p->core.parent != NULL; p = p->core.parent);
1520a3bd7f05Smrg    if (XtIsApplicationShell(p)) {
1521a3bd7f05Smrg        classhint.res_class = ((ApplicationShellWidget) p)->application.class;
1522a3bd7f05Smrg    }
1523a3bd7f05Smrg    else {
1524a3bd7f05Smrg        LOCK_PROCESS;
1525a3bd7f05Smrg        classhint.res_class = (_XtString) XtClass(p)->core_class.class_name;
1526a3bd7f05Smrg        UNLOCK_PROCESS;
1527a3bd7f05Smrg    }
1528a3bd7f05Smrg
1529a3bd7f05Smrg    if (XtIsApplicationShell((Widget) w)
1530a3bd7f05Smrg        && (argc = appshell->application.argc) != -1)
1531a3bd7f05Smrg        argv = (char **) appshell->application.argv;
1532a3bd7f05Smrg    else {
1533a3bd7f05Smrg        argv = NULL;
1534a3bd7f05Smrg        argc = 0;
1535a3bd7f05Smrg    }
1536a3bd7f05Smrg
1537a3bd7f05Smrg    XSetWMProperties(XtDisplay((Widget) w), XtWindow((Widget) w),
1538a3bd7f05Smrg                     &window_name,
1539a3bd7f05Smrg                     (XtIsTopLevelShell((Widget) w)) ? &icon_name : NULL,
1540a3bd7f05Smrg                     argv, argc, size_hints, &wmshell->wm.wm_hints, &classhint);
1541a3bd7f05Smrg    XFree((char *) size_hints);
1542a3bd7f05Smrg    if (copied_wname)
1543a3bd7f05Smrg        XFree((XPointer) window_name.value);
1544a3bd7f05Smrg    if (copied_iname)
1545a3bd7f05Smrg        XFree((XPointer) icon_name.value);
1546a3bd7f05Smrg
1547a3bd7f05Smrg    LOCK_PROCESS;
1548a3bd7f05Smrg    if (XtWidgetToApplicationContext((Widget) w)->langProcRec.proc) {
1549a3bd7f05Smrg        char *locale = setlocale(LC_CTYPE, (char *) NULL);
1550a3bd7f05Smrg
1551a3bd7f05Smrg        if (locale)
1552a3bd7f05Smrg            XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1553a3bd7f05Smrg                            XInternAtom(XtDisplay((Widget) w),
1554a3bd7f05Smrg                                        "WM_LOCALE_NAME", False),
1555a3bd7f05Smrg                            XA_STRING, 8, PropModeReplace,
1556a3bd7f05Smrg                            (unsigned char *) locale, (int) strlen(locale));
1557a3bd7f05Smrg    }
1558a3bd7f05Smrg    UNLOCK_PROCESS;
1559a3bd7f05Smrg
1560a3bd7f05Smrg    p = GetClientLeader((Widget) w);
1561a3bd7f05Smrg    if (XtWindow(p))
1562a3bd7f05Smrg        XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1563a3bd7f05Smrg                        XInternAtom(XtDisplay((Widget) w),
1564a3bd7f05Smrg                                    "WM_CLIENT_LEADER", False),
1565a3bd7f05Smrg                        XA_WINDOW, 32, PropModeReplace,
1566a3bd7f05Smrg                        (unsigned char *) (&(p->core.window)), 1);
1567444c061aSmrg#ifndef XT_NO_SM
1568a3bd7f05Smrg    if (p == (Widget) w) {
1569a3bd7f05Smrg        for (; p->core.parent != NULL; p = p->core.parent);
1570a3bd7f05Smrg        if (XtIsSubclass(p, sessionShellWidgetClass)) {
1571a3bd7f05Smrg            String sm_client_id = ((SessionShellWidget) p)->session.session_id;
1572a3bd7f05Smrg
1573a3bd7f05Smrg            if (sm_client_id != NULL) {
1574a3bd7f05Smrg                XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1575a3bd7f05Smrg                                XInternAtom(XtDisplay((Widget) w),
1576a3bd7f05Smrg                                            "SM_CLIENT_ID", False),
1577a3bd7f05Smrg                                XA_STRING, 8, PropModeReplace,
1578a3bd7f05Smrg                                (unsigned char *) sm_client_id,
1579a3bd7f05Smrg                                (int) strlen(sm_client_id));
1580a3bd7f05Smrg            }
1581a3bd7f05Smrg        }
1582a3bd7f05Smrg    }
1583a3bd7f05Smrg#endif                          /* !XT_NO_SM */
1584a3bd7f05Smrg
1585a3bd7f05Smrg    if (wmshell->wm.window_role)
1586a3bd7f05Smrg        XChangeProperty(XtDisplay((Widget) w), XtWindow((Widget) w),
1587a3bd7f05Smrg                        XInternAtom(XtDisplay((Widget) w),
1588a3bd7f05Smrg                                    "WM_WINDOW_ROLE", False),
1589a3bd7f05Smrg                        XA_STRING, 8, PropModeReplace,
1590a3bd7f05Smrg                        (unsigned char *) wmshell->wm.window_role,
1591a3bd7f05Smrg                        (int) strlen(wmshell->wm.window_role));
1592a3bd7f05Smrg}
1593a3bd7f05Smrg
1594a3bd7f05Smrgstatic void
1595a3bd7f05SmrgEventHandler(Widget wid,
1596a3bd7f05Smrg             XtPointer closure _X_UNUSED,
1597a3bd7f05Smrg             XEvent *event,
1598a3bd7f05Smrg             Boolean *continue_to_dispatch _X_UNUSED)
1599a3bd7f05Smrg{
1600a3bd7f05Smrg    register ShellWidget w = (ShellWidget) wid;
1601a3bd7f05Smrg    WMShellWidget wmshell = (WMShellWidget) w;
1602a3bd7f05Smrg    Boolean sizechanged = FALSE;
1603a3bd7f05Smrg
1604a3bd7f05Smrg    if (w->core.window != event->xany.window) {
1605a3bd7f05Smrg        XtAppErrorMsg(XtWidgetToApplicationContext(wid),
1606a3bd7f05Smrg                      "invalidWindow", "eventHandler", XtCXtToolkitError,
1607a3bd7f05Smrg                      "Event with wrong window", NULL, NULL);
1608a3bd7f05Smrg        return;
1609a3bd7f05Smrg    }
1610a3bd7f05Smrg
1611a3bd7f05Smrg    switch (event->type) {
1612a3bd7f05Smrg    case ConfigureNotify:
1613a3bd7f05Smrg        if (w->core.window != event->xconfigure.window)
1614a3bd7f05Smrg            return;             /* in case of SubstructureNotify */
1615a3bd7f05Smrg#define NEQ(x)  ( w->core.x != event->xconfigure.x )
1616a3bd7f05Smrg        if (NEQ(width) || NEQ(height) || NEQ(border_width)) {
1617a3bd7f05Smrg            sizechanged = TRUE;
1618444c061aSmrg#undef NEQ
1619a3bd7f05Smrg            w->core.width = (Dimension) event->xconfigure.width;
1620a3bd7f05Smrg            w->core.height = (Dimension) event->xconfigure.height;
1621a3bd7f05Smrg            w->core.border_width = (Dimension) event->xconfigure.border_width;
1622a3bd7f05Smrg        }
1623a3bd7f05Smrg        if (event->xany.send_event      /* ICCCM compliant synthetic ev */
1624a3bd7f05Smrg            /* || w->shell.override_redirect */
1625a3bd7f05Smrg            || w->shell.client_specified & _XtShellNotReparented) {
1626a3bd7f05Smrg            w->core.x = (Position) event->xconfigure.x;
1627a3bd7f05Smrg            w->core.y = (Position) event->xconfigure.y;
1628a3bd7f05Smrg            w->shell.client_specified |= _XtShellPositionValid;
1629a3bd7f05Smrg        }
1630a3bd7f05Smrg        else
1631a3bd7f05Smrg            w->shell.client_specified &= ~_XtShellPositionValid;
1632a3bd7f05Smrg        if (XtIsWMShell(wid) && !wmshell->wm.wait_for_wm) {
1633a3bd7f05Smrg            /* Consider trusting the wm again */
1634a3bd7f05Smrg            register struct _OldXSizeHints *hintp = &wmshell->wm.size_hints;
1635a3bd7f05Smrg
1636444c061aSmrg#define EQ(x) (hintp->x == w->core.x)
1637a3bd7f05Smrg            if (EQ(x) && EQ(y) && EQ(width) && EQ(height)) {
1638a3bd7f05Smrg                wmshell->wm.wait_for_wm = TRUE;
1639a3bd7f05Smrg            }
1640444c061aSmrg#undef EQ
1641a3bd7f05Smrg        }
1642a3bd7f05Smrg        break;
1643a3bd7f05Smrg
1644a3bd7f05Smrg    case ReparentNotify:
1645a3bd7f05Smrg        if (event->xreparent.window == XtWindow(w)) {
1646a3bd7f05Smrg            if (event->xreparent.parent != RootWindowOfScreen(XtScreen(w)))
1647a3bd7f05Smrg                w->shell.client_specified &=
1648a3bd7f05Smrg                    ~(_XtShellNotReparented | _XtShellPositionValid);
1649a3bd7f05Smrg            else {
1650a3bd7f05Smrg                w->core.x = (Position) event->xreparent.x;
1651a3bd7f05Smrg                w->core.y = (Position) event->xreparent.y;
1652a3bd7f05Smrg                w->shell.client_specified |=
1653a3bd7f05Smrg                    (_XtShellNotReparented | _XtShellPositionValid);
1654a3bd7f05Smrg            }
1655a3bd7f05Smrg        }
1656a3bd7f05Smrg        return;
1657444c061aSmrg
1658a3bd7f05Smrg    case MapNotify:
1659a3bd7f05Smrg        if (XtIsTopLevelShell(wid)) {
1660a3bd7f05Smrg            ((TopLevelShellWidget) wid)->topLevel.iconic = FALSE;
1661a3bd7f05Smrg        }
1662a3bd7f05Smrg        return;
1663444c061aSmrg
1664a3bd7f05Smrg    case UnmapNotify:
1665a3bd7f05Smrg    {
1666a3bd7f05Smrg        XtPerDisplayInput pdi;
1667a3bd7f05Smrg        XtDevice device;
1668a3bd7f05Smrg        Widget p;
1669444c061aSmrg
1670a3bd7f05Smrg        if (XtIsTopLevelShell(wid))
1671a3bd7f05Smrg            ((TopLevelShellWidget) wid)->topLevel.iconic = TRUE;
1672444c061aSmrg
1673a3bd7f05Smrg        pdi = _XtGetPerDisplayInput(event->xunmap.display);
1674444c061aSmrg
1675a3bd7f05Smrg        device = &pdi->pointer;
1676444c061aSmrg
1677a3bd7f05Smrg        if (device->grabType == XtPassiveServerGrab) {
1678a3bd7f05Smrg            p = device->grab.widget;
1679a3bd7f05Smrg            while (p && !(XtIsShell(p)))
1680a3bd7f05Smrg                p = p->core.parent;
1681a3bd7f05Smrg            if (p == wid)
1682a3bd7f05Smrg                device->grabType = XtNoServerGrab;
1683a3bd7f05Smrg        }
1684444c061aSmrg
1685a3bd7f05Smrg        device = &pdi->keyboard;
1686a3bd7f05Smrg        if (IsEitherPassiveGrab(device->grabType)) {
1687a3bd7f05Smrg            p = device->grab.widget;
1688a3bd7f05Smrg            while (p && !(XtIsShell(p)))
1689a3bd7f05Smrg                p = p->core.parent;
1690a3bd7f05Smrg            if (p == wid) {
1691a3bd7f05Smrg                device->grabType = XtNoServerGrab;
1692a3bd7f05Smrg                pdi->activatingKey = 0;
1693a3bd7f05Smrg            }
1694a3bd7f05Smrg        }
1695444c061aSmrg
1696a3bd7f05Smrg        return;
1697a3bd7f05Smrg    }
1698a3bd7f05Smrg    default:
1699a3bd7f05Smrg        return;
1700a3bd7f05Smrg    }
1701a3bd7f05Smrg    {
1702a3bd7f05Smrg        XtWidgetProc resize;
1703a3bd7f05Smrg
1704a3bd7f05Smrg        LOCK_PROCESS;
1705a3bd7f05Smrg        resize = XtClass(wid)->core_class.resize;
1706a3bd7f05Smrg        UNLOCK_PROCESS;
1707a3bd7f05Smrg
1708a3bd7f05Smrg        if (sizechanged && resize) {
1709a3bd7f05Smrg            CALLGEOTAT(_XtGeoTrace((Widget) w,
1710a3bd7f05Smrg                                   "Shell \"%s\" is being resized to %d %d.\n",
1711a3bd7f05Smrg                                   XtName(wid), wid->core.width,
1712a3bd7f05Smrg                                   wid->core.height));
1713a3bd7f05Smrg            (*resize) (wid);
1714a3bd7f05Smrg        }
1715a3bd7f05Smrg    }
1716444c061aSmrg}
1717444c061aSmrg
1718a3bd7f05Smrgstatic void
1719a3bd7f05SmrgDestroy(Widget wid)
1720444c061aSmrg{
1721a3bd7f05Smrg    if (XtIsRealized(wid))
1722a3bd7f05Smrg        XDestroyWindow(XtDisplay(wid), XtWindow(wid));
1723444c061aSmrg}
1724444c061aSmrg
1725a3bd7f05Smrgstatic void
1726a3bd7f05SmrgWMDestroy(Widget wid)
1727444c061aSmrg{
1728a3bd7f05Smrg    WMShellWidget w = (WMShellWidget) wid;
1729444c061aSmrg
1730a3bd7f05Smrg    XtFree((char *) w->wm.title);
1731a3bd7f05Smrg    XtFree((char *) w->wm.window_role);
1732444c061aSmrg}
1733444c061aSmrg
1734a3bd7f05Smrgstatic void
1735a3bd7f05SmrgTopLevelDestroy(Widget wid)
1736444c061aSmrg{
1737a3bd7f05Smrg    TopLevelShellWidget w = (TopLevelShellWidget) wid;
1738444c061aSmrg
1739a3bd7f05Smrg    XtFree((char *) w->topLevel.icon_name);
1740444c061aSmrg}
1741444c061aSmrg
1742a3bd7f05Smrgstatic void
1743a3bd7f05SmrgApplicationDestroy(Widget wid)
1744444c061aSmrg{
1745444c061aSmrg    ApplicationShellWidget w = (ApplicationShellWidget) wid;
1746a3bd7f05Smrg
1747444c061aSmrg    if (w->application.argc > 0)
1748a3bd7f05Smrg        FreeStringArray(w->application.argv);
1749444c061aSmrg}
1750444c061aSmrg
1751a3bd7f05Smrgstatic void
1752a3bd7f05SmrgSessionDestroy(Widget wid)
1753444c061aSmrg{
1754444c061aSmrg#ifndef XT_NO_SM
1755444c061aSmrg    SessionShellWidget w = (SessionShellWidget) wid;
1756444c061aSmrg
1757444c061aSmrg    StopManagingSession(w, w->session.connection);
1758444c061aSmrg    XtFree(w->session.session_id);
1759444c061aSmrg    FreeStringArray(w->session.restart_command);
1760444c061aSmrg    FreeStringArray(w->session.clone_command);
1761444c061aSmrg    FreeStringArray(w->session.discard_command);
1762444c061aSmrg    FreeStringArray(w->session.resign_command);
1763444c061aSmrg    FreeStringArray(w->session.shutdown_command);
1764444c061aSmrg    FreeStringArray(w->session.environment);
1765444c061aSmrg    XtFree(w->session.current_dir);
17660568f49bSmrg    XtFree((_XtString) w->session.program_path);
1767a3bd7f05Smrg#endif                          /* !XT_NO_SM */
1768444c061aSmrg}
1769444c061aSmrg
1770444c061aSmrg/*
1771444c061aSmrg * If the Shell has a width and a height which are zero, and as such
1772444c061aSmrg * suspect, and it has not yet been realized then it will grow to
1773444c061aSmrg * match the child before parsing the geometry resource.
1774444c061aSmrg *
1775444c061aSmrg */
1776a3bd7f05Smrgstatic void
1777a3bd7f05SmrgGetGeometry(Widget W, Widget child)
1778444c061aSmrg{
1779a3bd7f05Smrg    register ShellWidget w = (ShellWidget) W;
1780444c061aSmrg    Boolean is_wmshell = XtIsWMShell(W);
1781444c061aSmrg    int x, y, width, height, win_gravity = -1, flag;
1782444c061aSmrg    XSizeHints hints;
1783444c061aSmrg
1784444c061aSmrg    if (child != NULL) {
1785a3bd7f05Smrg        /* we default to our child's size */
1786a3bd7f05Smrg        if (is_wmshell && (w->core.width == 0 || w->core.height == 0))
1787a3bd7f05Smrg            ((WMShellWidget) W)->wm.size_hints.flags |= PSize;
1788a3bd7f05Smrg        if (w->core.width == 0)
1789a3bd7f05Smrg            w->core.width = child->core.width;
1790a3bd7f05Smrg        if (w->core.height == 0)
1791a3bd7f05Smrg            w->core.height = child->core.height;
1792a3bd7f05Smrg    }
1793a3bd7f05Smrg    if (w->shell.geometry != NULL) {
1794a3bd7f05Smrg        char def_geom[64];
1795a3bd7f05Smrg
1796a3bd7f05Smrg        x = w->core.x;
1797a3bd7f05Smrg        y = w->core.y;
1798a3bd7f05Smrg        width = w->core.width;
1799a3bd7f05Smrg        height = w->core.height;
1800a3bd7f05Smrg        if (is_wmshell) {
1801a3bd7f05Smrg            WMShellPart *wm = &((WMShellWidget) w)->wm;
1802a3bd7f05Smrg
1803a3bd7f05Smrg            EvaluateSizeHints((WMShellWidget) w);
1804a3bd7f05Smrg            (void) memmove((char *) &hints, (char *) &wm->size_hints,
1805a3bd7f05Smrg                           sizeof(struct _OldXSizeHints));
1806a3bd7f05Smrg            hints.win_gravity = wm->win_gravity;
1807a3bd7f05Smrg            if (wm->size_hints.flags & PBaseSize) {
1808a3bd7f05Smrg                width -= wm->base_width;
1809a3bd7f05Smrg                height -= wm->base_height;
1810a3bd7f05Smrg                hints.base_width = wm->base_width;
1811a3bd7f05Smrg                hints.base_height = wm->base_height;
1812a3bd7f05Smrg            }
1813a3bd7f05Smrg            else if (wm->size_hints.flags & PMinSize) {
1814a3bd7f05Smrg                width -= wm->size_hints.min_width;
1815a3bd7f05Smrg                height -= wm->size_hints.min_height;
1816a3bd7f05Smrg            }
1817a3bd7f05Smrg            if (wm->size_hints.flags & PResizeInc) {
1818a3bd7f05Smrg                width /= wm->size_hints.width_inc;
1819a3bd7f05Smrg                height /= wm->size_hints.height_inc;
1820a3bd7f05Smrg            }
1821a3bd7f05Smrg        }
1822a3bd7f05Smrg        else
1823a3bd7f05Smrg            hints.flags = 0;
1824a3bd7f05Smrg
1825a3bd7f05Smrg        snprintf(def_geom, sizeof(def_geom), "%dx%d+%d+%d",
1826a3bd7f05Smrg                 width, height, x, y);
1827a3bd7f05Smrg        flag = XWMGeometry(XtDisplay(W),
1828a3bd7f05Smrg                           XScreenNumberOfScreen(XtScreen(W)),
1829a3bd7f05Smrg                           w->shell.geometry, def_geom,
1830a3bd7f05Smrg                           (unsigned int) w->core.border_width,
1831a3bd7f05Smrg                           &hints, &x, &y, &width, &height, &win_gravity);
1832a3bd7f05Smrg        if (flag) {
1833a3bd7f05Smrg            if (flag & XValue)
1834a3bd7f05Smrg                w->core.x = (Position) x;
1835a3bd7f05Smrg            if (flag & YValue)
1836a3bd7f05Smrg                w->core.y = (Position) y;
1837a3bd7f05Smrg            if (flag & WidthValue)
1838a3bd7f05Smrg                w->core.width = (Dimension) width;
1839a3bd7f05Smrg            if (flag & HeightValue)
1840a3bd7f05Smrg                w->core.height = (Dimension) height;
1841a3bd7f05Smrg        }
1842a3bd7f05Smrg        else {
1843a3bd7f05Smrg            String params[2];
1844a3bd7f05Smrg            Cardinal num_params = 2;
1845a3bd7f05Smrg
1846a3bd7f05Smrg            params[0] = XtName(W);
1847a3bd7f05Smrg            params[1] = w->shell.geometry;
1848a3bd7f05Smrg            XtAppWarningMsg(XtWidgetToApplicationContext(W),
1849a3bd7f05Smrg                            "badGeometry", "shellRealize", XtCXtToolkitError,
1850a3bd7f05Smrg                            "Shell widget \"%s\" has an invalid geometry specification: \"%s\"",
1851a3bd7f05Smrg                            params, &num_params);
1852a3bd7f05Smrg        }
1853444c061aSmrg    }
1854444c061aSmrg    else
1855a3bd7f05Smrg        flag = 0;
1856444c061aSmrg
1857444c061aSmrg    if (is_wmshell) {
1858a3bd7f05Smrg        WMShellWidget wmshell = (WMShellWidget) w;
1859a3bd7f05Smrg
1860a3bd7f05Smrg        if (wmshell->wm.win_gravity == XtUnspecifiedShellInt) {
1861a3bd7f05Smrg            if (win_gravity != -1)
1862a3bd7f05Smrg                wmshell->wm.win_gravity = win_gravity;
1863a3bd7f05Smrg            else
1864a3bd7f05Smrg                wmshell->wm.win_gravity = NorthWestGravity;
1865a3bd7f05Smrg        }
1866a3bd7f05Smrg        wmshell->wm.size_hints.flags |= PWinGravity;
1867a3bd7f05Smrg        if ((flag & (XValue | YValue)) == (XValue | YValue))
1868a3bd7f05Smrg            wmshell->wm.size_hints.flags |= USPosition;
1869a3bd7f05Smrg        if ((flag & (WidthValue | HeightValue)) == (WidthValue | HeightValue))
1870a3bd7f05Smrg            wmshell->wm.size_hints.flags |= USSize;
1871444c061aSmrg    }
1872444c061aSmrg    w->shell.client_specified |= _XtShellGeometryParsed;
1873444c061aSmrg}
1874444c061aSmrg
1875a3bd7f05Smrgstatic void
1876a3bd7f05SmrgChangeManaged(Widget wid)
1877444c061aSmrg{
1878444c061aSmrg    ShellWidget w = (ShellWidget) wid;
1879444c061aSmrg    Widget child = NULL;
1880444c061aSmrg    Cardinal i;
1881444c061aSmrg
1882444c061aSmrg    for (i = 0; i < w->composite.num_children; i++) {
1883a3bd7f05Smrg        if (XtIsManaged(w->composite.children[i])) {
1884a3bd7f05Smrg            child = w->composite.children[i];
1885a3bd7f05Smrg            break;              /* there can only be one of them! */
1886a3bd7f05Smrg        }
1887444c061aSmrg    }
1888444c061aSmrg
1889a3bd7f05Smrg    if (!XtIsRealized(wid))     /* then we're about to be realized... */
1890a3bd7f05Smrg        GetGeometry(wid, child);
1891444c061aSmrg
1892444c061aSmrg    if (child != NULL)
1893a3bd7f05Smrg        XtConfigureWidget(child, (Position) 0, (Position) 0,
1894a3bd7f05Smrg                          w->core.width, w->core.height, (Dimension) 0);
1895444c061aSmrg}
1896444c061aSmrg
1897444c061aSmrg/*
1898444c061aSmrg * This is gross, I can't wait to see if the change happened so I will ask
1899444c061aSmrg * the window manager to change my size and do the appropriate X work.
1900444c061aSmrg * I will then tell the requester that he can.  Care must be taken because
1901444c061aSmrg * it is possible that some time in the future the request will be
1902444c061aSmrg * asynchronusly denied and the window reverted to it's old size/shape.
1903444c061aSmrg */
1904444c061aSmrg
1905a3bd7f05Smrgstatic XtGeometryResult
1906a3bd7f05SmrgGeometryManager(Widget wid,
1907a3bd7f05Smrg                XtWidgetGeometry *request,
1908a3bd7f05Smrg                XtWidgetGeometry *reply _X_UNUSED)
1909a3bd7f05Smrg{
1910a3bd7f05Smrg    ShellWidget shell = (ShellWidget) (wid->core.parent);
1911a3bd7f05Smrg    XtWidgetGeometry my_request;
1912a3bd7f05Smrg
1913a3bd7f05Smrg    if (shell->shell.allow_shell_resize == FALSE && XtIsRealized(wid))
1914a3bd7f05Smrg        return (XtGeometryNo);
1915a3bd7f05Smrg
1916a3bd7f05Smrg    if (request->request_mode & (CWX | CWY))
1917a3bd7f05Smrg        return (XtGeometryNo);
1918a3bd7f05Smrg
1919a3bd7f05Smrg    my_request.request_mode = (request->request_mode & XtCWQueryOnly);
1920a3bd7f05Smrg    if (request->request_mode & CWWidth) {
1921a3bd7f05Smrg        my_request.width = request->width;
1922a3bd7f05Smrg        my_request.request_mode |= CWWidth;
1923a3bd7f05Smrg    }
1924a3bd7f05Smrg    if (request->request_mode & CWHeight) {
1925a3bd7f05Smrg        my_request.height = request->height;
1926a3bd7f05Smrg        my_request.request_mode |= CWHeight;
1927a3bd7f05Smrg    }
1928a3bd7f05Smrg    if (request->request_mode & CWBorderWidth) {
1929a3bd7f05Smrg        my_request.border_width = request->border_width;
1930a3bd7f05Smrg        my_request.request_mode |= CWBorderWidth;
1931a3bd7f05Smrg    }
1932a3bd7f05Smrg    if (XtMakeGeometryRequest((Widget) shell, &my_request, NULL)
1933a3bd7f05Smrg        == XtGeometryYes) {
1934a3bd7f05Smrg        /* assert: if (request->request_mode & CWWidth) then
1935a3bd7f05Smrg         *            shell->core.width == request->width
1936a3bd7f05Smrg         * assert: if (request->request_mode & CWHeight) then
1937a3bd7f05Smrg         *            shell->core.height == request->height
1938a3bd7f05Smrg         *
1939a3bd7f05Smrg         * so, whatever the WM sized us to (if the Shell requested
1940a3bd7f05Smrg         * only one of the two) is now the correct child size
1941a3bd7f05Smrg         */
1942a3bd7f05Smrg
1943a3bd7f05Smrg        if (!(request->request_mode & XtCWQueryOnly)) {
1944a3bd7f05Smrg            wid->core.width = shell->core.width;
1945a3bd7f05Smrg            wid->core.height = shell->core.height;
1946a3bd7f05Smrg            if (request->request_mode & CWBorderWidth) {
1947a3bd7f05Smrg                wid->core.x = wid->core.y = (Position) (-request->border_width);
1948a3bd7f05Smrg            }
1949a3bd7f05Smrg        }
1950a3bd7f05Smrg        return XtGeometryYes;
1951a3bd7f05Smrg    }
1952a3bd7f05Smrg    else
1953a3bd7f05Smrg        return XtGeometryNo;
1954444c061aSmrg}
1955444c061aSmrg
1956444c061aSmrgtypedef struct {
1957a3bd7f05Smrg    Widget w;
1958a3bd7f05Smrg    unsigned long request_num;
1959a3bd7f05Smrg    Boolean done;
1960444c061aSmrg} QueryStruct;
1961444c061aSmrg
1962a3bd7f05Smrgstatic Bool
1963a3bd7f05SmrgisMine(Display *dpy, register XEvent *event, char *arg)
1964a3bd7f05Smrg{
1965a3bd7f05Smrg    QueryStruct *q = (QueryStruct *) arg;
1966a3bd7f05Smrg    register Widget w = q->w;
1967a3bd7f05Smrg
1968a3bd7f05Smrg    if ((dpy != XtDisplay(w)) || (event->xany.window != XtWindow(w))) {
1969a3bd7f05Smrg        return FALSE;
1970a3bd7f05Smrg    }
1971a3bd7f05Smrg    if (event->xany.serial >= q->request_num) {
1972a3bd7f05Smrg        if (event->type == ConfigureNotify) {
1973a3bd7f05Smrg            q->done = TRUE;
1974a3bd7f05Smrg            return TRUE;
1975a3bd7f05Smrg        }
1976a3bd7f05Smrg    }
1977a3bd7f05Smrg    else if (event->type == ConfigureNotify)
1978a3bd7f05Smrg        return TRUE;            /* flush old events */
1979a3bd7f05Smrg    if (event->type == ReparentNotify && event->xreparent.window == XtWindow(w)) {
1980a3bd7f05Smrg        /* we might get ahead of this event, so just in case someone
1981a3bd7f05Smrg         * asks for coordinates before this event is dispatched...
1982a3bd7f05Smrg         */
1983a3bd7f05Smrg        register ShellWidget s = (ShellWidget) w;
1984a3bd7f05Smrg
1985a3bd7f05Smrg        if (event->xreparent.parent != RootWindowOfScreen(XtScreen(w)))
1986a3bd7f05Smrg            s->shell.client_specified &= ~_XtShellNotReparented;
1987a3bd7f05Smrg        else
1988a3bd7f05Smrg            s->shell.client_specified |= _XtShellNotReparented;
1989a3bd7f05Smrg    }
1990a3bd7f05Smrg    return FALSE;
1991a3bd7f05Smrg}
1992a3bd7f05Smrg
1993a3bd7f05Smrgstatic Boolean
1994a3bd7f05Smrg_wait_for_response(ShellWidget w, XEvent *event, unsigned long request_num)
1995a3bd7f05Smrg{
1996a3bd7f05Smrg    XtAppContext app = XtWidgetToApplicationContext((Widget) w);
1997a3bd7f05Smrg    QueryStruct q;
1998a3bd7f05Smrg    unsigned long timeout;
1999a3bd7f05Smrg
2000a3bd7f05Smrg    if (XtIsWMShell((Widget) w))
2001a3bd7f05Smrg        timeout = (unsigned long) ((WMShellWidget) w)->wm.wm_timeout;
2002a3bd7f05Smrg    else
2003a3bd7f05Smrg        timeout = DEFAULT_WM_TIMEOUT;
2004a3bd7f05Smrg
2005a3bd7f05Smrg    XFlush(XtDisplay(w));
2006a3bd7f05Smrg    q.w = (Widget) w;
2007a3bd7f05Smrg    q.request_num = request_num;
2008a3bd7f05Smrg    q.done = FALSE;
2009a3bd7f05Smrg
2010a3bd7f05Smrg    /*
2011a3bd7f05Smrg     * look for match event and discard all prior configures
2012a3bd7f05Smrg     */
2013a3bd7f05Smrg    while (XCheckIfEvent(XtDisplay(w), event, isMine, (char *) &q)) {
2014a3bd7f05Smrg        if (q.done)
2015a3bd7f05Smrg            return TRUE;
2016a3bd7f05Smrg    }
2017a3bd7f05Smrg
2018a3bd7f05Smrg    while (timeout > 0) {
2019a3bd7f05Smrg        if (_XtWaitForSomething(app, FALSE, TRUE, TRUE, TRUE, TRUE,
2020444c061aSmrg#ifdef XTHREADS
2021a3bd7f05Smrg                                FALSE,
2022444c061aSmrg#endif
2023a3bd7f05Smrg                                &timeout) != -1) {
2024a3bd7f05Smrg            while (XCheckIfEvent(XtDisplay(w), event, isMine, (char *) &q)) {
2025a3bd7f05Smrg                if (q.done)
2026a3bd7f05Smrg                    return TRUE;
2027a3bd7f05Smrg            }
2028a3bd7f05Smrg        }
2029a3bd7f05Smrg    }
2030a3bd7f05Smrg    return FALSE;
2031444c061aSmrg}
2032444c061aSmrg
2033a3bd7f05Smrgstatic XtGeometryResult
2034a3bd7f05SmrgRootGeometryManager(Widget gw,
2035a3bd7f05Smrg                    XtWidgetGeometry *request,
2036a3bd7f05Smrg                    XtWidgetGeometry *reply _X_UNUSED)
2037444c061aSmrg{
2038a3bd7f05Smrg    register ShellWidget w = (ShellWidget) gw;
2039444c061aSmrg    XWindowChanges values;
2040444c061aSmrg    unsigned int mask = request->request_mode;
2041444c061aSmrg    XEvent event;
2042444c061aSmrg    Boolean wm;
2043444c061aSmrg    register struct _OldXSizeHints *hintp = NULL;
2044444c061aSmrg    int oldx, oldy, oldwidth, oldheight, oldborder_width;
2045444c061aSmrg    unsigned long request_num;
2046444c061aSmrg
2047444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
2048444c061aSmrg
2049444c061aSmrg    if (XtIsWMShell(gw)) {
2050a3bd7f05Smrg        wm = True;
2051a3bd7f05Smrg        hintp = &((WMShellWidget) w)->wm.size_hints;
2052a3bd7f05Smrg        /* for draft-ICCCM wm's, need to make sure hints reflect
2053a3bd7f05Smrg           (current) reality so client can move and size separately. */
2054a3bd7f05Smrg        hintp->x = w->core.x;
2055a3bd7f05Smrg        hintp->y = w->core.y;
2056a3bd7f05Smrg        hintp->width = w->core.width;
2057a3bd7f05Smrg        hintp->height = w->core.height;
2058a3bd7f05Smrg    }
2059a3bd7f05Smrg    else
2060a3bd7f05Smrg        wm = False;
2061444c061aSmrg
2062444c061aSmrg    oldx = w->core.x;
2063444c061aSmrg    oldy = w->core.y;
2064444c061aSmrg    oldwidth = w->core.width;
2065444c061aSmrg    oldheight = w->core.height;
2066444c061aSmrg    oldborder_width = w->core.border_width;
2067444c061aSmrg
2068444c061aSmrg#define PutBackGeometry() \
2069a3bd7f05Smrg        { w->core.x = (Position) (oldx); \
2070a3bd7f05Smrg          w->core.y = (Position) (oldy); \
2071a3bd7f05Smrg          w->core.width = (Dimension) (oldwidth); \
2072a3bd7f05Smrg          w->core.height = (Dimension) (oldheight); \
2073a3bd7f05Smrg          w->core.border_width = (Dimension) (oldborder_width); }
2074444c061aSmrg
20750568f49bSmrg    memset(&values, 0, sizeof(values));
2076444c061aSmrg    if (mask & CWX) {
2077a3bd7f05Smrg        if (w->core.x == request->x)
2078a3bd7f05Smrg            mask &= (unsigned int) (~CWX);
2079a3bd7f05Smrg        else {
2080a3bd7f05Smrg            w->core.x = (Position) (values.x = request->x);
2081a3bd7f05Smrg            if (wm) {
2082a3bd7f05Smrg                hintp->flags &= ~USPosition;
2083a3bd7f05Smrg                hintp->flags |= PPosition;
2084a3bd7f05Smrg                hintp->x = values.x;
2085a3bd7f05Smrg            }
2086a3bd7f05Smrg        }
2087444c061aSmrg    }
2088444c061aSmrg    if (mask & CWY) {
2089a3bd7f05Smrg        if (w->core.y == request->y)
2090a3bd7f05Smrg            mask &= (unsigned int) (~CWY);
2091a3bd7f05Smrg        else {
2092a3bd7f05Smrg            w->core.y = (Position) (values.y = request->y);
2093a3bd7f05Smrg            if (wm) {
2094a3bd7f05Smrg                hintp->flags &= ~USPosition;
2095a3bd7f05Smrg                hintp->flags |= PPosition;
2096a3bd7f05Smrg                hintp->y = values.y;
2097a3bd7f05Smrg            }
2098a3bd7f05Smrg        }
2099444c061aSmrg    }
2100444c061aSmrg    if (mask & CWBorderWidth) {
2101a3bd7f05Smrg        if (w->core.border_width == request->border_width) {
2102a3bd7f05Smrg            mask &= (unsigned int) (~CWBorderWidth);
2103a3bd7f05Smrg        }
2104a3bd7f05Smrg        else
2105a3bd7f05Smrg            w->core.border_width =
2106a3bd7f05Smrg                (Dimension) (values.border_width = request->border_width);
2107444c061aSmrg    }
2108444c061aSmrg    if (mask & CWWidth) {
2109a3bd7f05Smrg        if (w->core.width == request->width)
2110a3bd7f05Smrg            mask &= (unsigned int) (~CWWidth);
2111a3bd7f05Smrg        else {
2112a3bd7f05Smrg            w->core.width = (Dimension) (values.width = request->width);
2113a3bd7f05Smrg            if (wm) {
2114a3bd7f05Smrg                hintp->flags &= ~USSize;
2115a3bd7f05Smrg                hintp->flags |= PSize;
2116a3bd7f05Smrg                hintp->width = values.width;
2117a3bd7f05Smrg            }
2118a3bd7f05Smrg        }
2119444c061aSmrg    }
2120444c061aSmrg    if (mask & CWHeight) {
2121a3bd7f05Smrg        if (w->core.height == request->height)
2122a3bd7f05Smrg            mask &= (unsigned int) (~CWHeight);
2123a3bd7f05Smrg        else {
2124a3bd7f05Smrg            w->core.height = (Dimension) (values.height = request->height);
2125a3bd7f05Smrg            if (wm) {
2126a3bd7f05Smrg                hintp->flags &= ~USSize;
2127a3bd7f05Smrg                hintp->flags |= PSize;
2128a3bd7f05Smrg                hintp->height = values.height;
2129a3bd7f05Smrg            }
2130a3bd7f05Smrg        }
2131444c061aSmrg    }
2132444c061aSmrg    if (mask & CWStackMode) {
2133a3bd7f05Smrg        values.stack_mode = request->stack_mode;
2134a3bd7f05Smrg        if (mask & CWSibling)
2135a3bd7f05Smrg            values.sibling = XtWindow(request->sibling);
2136444c061aSmrg    }
2137444c061aSmrg
2138a3bd7f05Smrg    if (!XtIsRealized((Widget) w)) {
2139a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w,
2140a3bd7f05Smrg                               "Shell \"%s\" is not realized, return XtGeometryYes.\n",
2141a3bd7f05Smrg                               XtName((Widget) w)));
2142a3bd7f05Smrg        CALLGEOTAT(_XtGeoTab(-1));
2143a3bd7f05Smrg        return XtGeometryYes;
2144444c061aSmrg    }
2145444c061aSmrg
2146444c061aSmrg    request_num = NextRequest(XtDisplay(w));
2147444c061aSmrg
2148a3bd7f05Smrg    CALLGEOTAT(_XtGeoTrace((Widget) w, "XConfiguring the Shell X window :\n"));
2149444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
2150444c061aSmrg#ifdef XT_GEO_TATTLER
2151a3bd7f05Smrg    if (mask & CWX) {
2152a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "x = %d\n", values.x));
2153a3bd7f05Smrg    }
2154a3bd7f05Smrg    if (mask & CWY) {
2155a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "y = %d\n", values.y));
2156a3bd7f05Smrg    }
2157a3bd7f05Smrg    if (mask & CWWidth) {
2158a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "width = %d\n", values.width));
2159a3bd7f05Smrg    }
2160a3bd7f05Smrg    if (mask & CWHeight) {
2161a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w, "height = %d\n", values.height));
2162a3bd7f05Smrg    }
2163a3bd7f05Smrg    if (mask & CWBorderWidth) {
2164a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace((Widget) w,
2165a3bd7f05Smrg                               "border_width = %d\n", values.border_width));
2166a3bd7f05Smrg    }
2167444c061aSmrg#endif
2168444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
2169444c061aSmrg
2170a3bd7f05Smrg    XConfigureWindow(XtDisplay((Widget) w), XtWindow((Widget) w), mask,
2171a3bd7f05Smrg                     &values);
2172444c061aSmrg
2173444c061aSmrg    if (wm && !w->shell.override_redirect
2174a3bd7f05Smrg        && mask & (CWX | CWY | CWWidth | CWHeight | CWBorderWidth)) {
2175a3bd7f05Smrg        _SetWMSizeHints((WMShellWidget) w);
2176444c061aSmrg    }
2177444c061aSmrg
2178444c061aSmrg    if (w->shell.override_redirect) {
2179a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace
2180a3bd7f05Smrg                   ((Widget) w,
2181a3bd7f05Smrg                    "Shell \"%s\" is override redirect, return XtGeometryYes.\n",
2182a3bd7f05Smrg                    XtName((Widget) w)));
2183a3bd7f05Smrg        CALLGEOTAT(_XtGeoTab(-1));
2184a3bd7f05Smrg        return XtGeometryYes;
2185444c061aSmrg    }
2186444c061aSmrg
2187444c061aSmrg    /* If no non-stacking bits are set, there's no way to tell whether
2188444c061aSmrg       or not this worked, so assume it did */
2189444c061aSmrg
2190a3bd7f05Smrg    if (!(mask & (unsigned) (~(CWStackMode | CWSibling))))
2191a3bd7f05Smrg        return XtGeometryYes;
2192444c061aSmrg
2193a3bd7f05Smrg    if (wm && ((WMShellWidget) w)->wm.wait_for_wm == FALSE) {
2194a3bd7f05Smrg        /* the window manager is sick
2195a3bd7f05Smrg         * so I will do the work and
2196a3bd7f05Smrg         * say no so if a new WM starts up,
2197a3bd7f05Smrg         * or the current one recovers
2198a3bd7f05Smrg         * my size requests will be visible
2199a3bd7f05Smrg         */
2200a3bd7f05Smrg        CALLGEOTAT(_XtGeoTrace
2201a3bd7f05Smrg                   ((Widget) w,
2202a3bd7f05Smrg                    "Shell \"%s\" has wait_for_wm == FALSE, return XtGeometryNo.\n",
2203a3bd7f05Smrg                    XtName((Widget) w)));
2204a3bd7f05Smrg        CALLGEOTAT(_XtGeoTab(-1));
2205444c061aSmrg
2206a3bd7f05Smrg        PutBackGeometry();
2207a3bd7f05Smrg        return XtGeometryNo;
2208444c061aSmrg    }
2209444c061aSmrg
2210444c061aSmrg    if (_wait_for_response(w, &event, request_num)) {
2211a3bd7f05Smrg        /* got an event */
2212a3bd7f05Smrg        if (event.type == ConfigureNotify) {
2213444c061aSmrg
2214444c061aSmrg#define NEQ(x, msk) ((mask & msk) && (values.x != event.xconfigure.x))
2215a3bd7f05Smrg            if (NEQ(x, CWX) ||
2216a3bd7f05Smrg                NEQ(y, CWY) ||
2217a3bd7f05Smrg                NEQ(width, CWWidth) ||
2218a3bd7f05Smrg                NEQ(height, CWHeight) || NEQ(border_width, CWBorderWidth)) {
2219444c061aSmrg#ifdef XT_GEO_TATTLER
2220a3bd7f05Smrg                if (NEQ(x, CWX)) {
2221a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2222a3bd7f05Smrg                                           "received Configure X %d\n",
2223a3bd7f05Smrg                                           event.xconfigure.x));
2224a3bd7f05Smrg                }
2225a3bd7f05Smrg                if (NEQ(y, CWY)) {
2226a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2227a3bd7f05Smrg                                           "received Configure Y %d\n",
2228a3bd7f05Smrg                                           event.xconfigure.y));
2229a3bd7f05Smrg                }
2230a3bd7f05Smrg                if (NEQ(width, CWWidth)) {
2231a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2232a3bd7f05Smrg                                           "received Configure Width %d\n",
2233a3bd7f05Smrg                                           event.xconfigure.width));
2234a3bd7f05Smrg                }
2235a3bd7f05Smrg                if (NEQ(height, CWHeight)) {
2236a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2237a3bd7f05Smrg                                           "received Configure Height %d\n",
2238a3bd7f05Smrg                                           event.xconfigure.height));
2239a3bd7f05Smrg                }
2240a3bd7f05Smrg                if (NEQ(border_width, CWBorderWidth)) {
2241a3bd7f05Smrg                    CALLGEOTAT(_XtGeoTrace((Widget) w,
2242a3bd7f05Smrg                                           "received Configure BorderWidth %d\n",
2243a3bd7f05Smrg                                           event.xconfigure.border_width));
2244a3bd7f05Smrg                }
2245444c061aSmrg#endif
2246444c061aSmrg#undef NEQ
2247a3bd7f05Smrg                XPutBackEvent(XtDisplay(w), &event);
2248a3bd7f05Smrg                PutBackGeometry();
2249a3bd7f05Smrg                /*
2250a3bd7f05Smrg                 * We just potentially re-ordered the event queue
2251a3bd7f05Smrg                 * w.r.t. ConfigureNotifies with some trepidation.
2252a3bd7f05Smrg                 * But this is probably a Good Thing because we
2253a3bd7f05Smrg                 * will know the new true state of the world sooner
2254a3bd7f05Smrg                 * this way.
2255a3bd7f05Smrg                 */
2256a3bd7f05Smrg                CALLGEOTAT(_XtGeoTrace((Widget) w,
2257a3bd7f05Smrg                                       "ConfigureNotify failed, return XtGeometryNo.\n"));
2258a3bd7f05Smrg                CALLGEOTAT(_XtGeoTab(-1));
2259a3bd7f05Smrg
2260a3bd7f05Smrg                return XtGeometryNo;
2261a3bd7f05Smrg            }
2262a3bd7f05Smrg            else {
2263a3bd7f05Smrg                w->core.width = (Dimension) event.xconfigure.width;
2264a3bd7f05Smrg                w->core.height = (Dimension) event.xconfigure.height;
2265a3bd7f05Smrg                w->core.border_width =
2266a3bd7f05Smrg                    (Dimension) event.xconfigure.border_width;
2267a3bd7f05Smrg                if (event.xany.send_event ||    /* ICCCM compliant synth */
2268a3bd7f05Smrg                    w->shell.client_specified & _XtShellNotReparented) {
2269a3bd7f05Smrg
2270a3bd7f05Smrg                    w->core.x = (Position) event.xconfigure.x;
2271a3bd7f05Smrg                    w->core.y = (Position) event.xconfigure.y;
2272a3bd7f05Smrg                    w->shell.client_specified |= _XtShellPositionValid;
2273a3bd7f05Smrg                }
2274a3bd7f05Smrg                else
2275a3bd7f05Smrg                    w->shell.client_specified &= ~_XtShellPositionValid;
2276a3bd7f05Smrg                CALLGEOTAT(_XtGeoTrace((Widget) w,
2277a3bd7f05Smrg                                       "ConfigureNotify succeed, return XtGeometryYes.\n"));
2278a3bd7f05Smrg                CALLGEOTAT(_XtGeoTab(-1));
2279a3bd7f05Smrg                return XtGeometryYes;
2280a3bd7f05Smrg            }
2281a3bd7f05Smrg        }
2282a3bd7f05Smrg        else if (!wm) {
2283a3bd7f05Smrg            PutBackGeometry();
2284a3bd7f05Smrg            CALLGEOTAT(_XtGeoTrace((Widget) w,
2285a3bd7f05Smrg                                   "Not wm, return XtGeometryNo.\n"));
2286a3bd7f05Smrg            CALLGEOTAT(_XtGeoTab(-1));
2287a3bd7f05Smrg            return XtGeometryNo;
2288a3bd7f05Smrg        }
2289a3bd7f05Smrg        else
2290a3bd7f05Smrg            XtAppWarningMsg(XtWidgetToApplicationContext((Widget) w),
2291a3bd7f05Smrg                            "internalError", "shell", XtCXtToolkitError,
2292a3bd7f05Smrg                            "Shell's window manager interaction is broken",
2293a3bd7f05Smrg                            NULL, NULL);
2294a3bd7f05Smrg    }
2295a3bd7f05Smrg    else if (wm) {              /* no event */
2296a3bd7f05Smrg        ((WMShellWidget) w)->wm.wait_for_wm = FALSE;    /* timed out; must be broken */
2297444c061aSmrg    }
2298444c061aSmrg    PutBackGeometry();
2299444c061aSmrg#undef PutBackGeometry
2300a3bd7f05Smrg    CALLGEOTAT(_XtGeoTrace((Widget) w,
2301a3bd7f05Smrg                           "Timeout passed?, return XtGeometryNo.\n"));
2302444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
2303444c061aSmrg    return XtGeometryNo;
2304a3bd7f05Smrg}
2305a3bd7f05Smrg
2306a3bd7f05Smrgstatic Boolean
2307a3bd7f05SmrgSetValues(Widget old,
2308a3bd7f05Smrg          Widget ref _X_UNUSED,
2309a3bd7f05Smrg          Widget new,
2310a3bd7f05Smrg          ArgList args,
2311a3bd7f05Smrg          Cardinal *num_args)
2312a3bd7f05Smrg{
2313a3bd7f05Smrg    ShellWidget nw = (ShellWidget) new;
2314a3bd7f05Smrg    ShellWidget ow = (ShellWidget) old;
2315a3bd7f05Smrg    Mask mask = 0;
2316a3bd7f05Smrg    XSetWindowAttributes attr;
2317a3bd7f05Smrg
2318a3bd7f05Smrg    if (!XtIsRealized(new))
2319a3bd7f05Smrg        return False;
2320a3bd7f05Smrg
2321a3bd7f05Smrg    if (ow->shell.save_under != nw->shell.save_under) {
2322a3bd7f05Smrg        mask = CWSaveUnder;
2323a3bd7f05Smrg        attr.save_under = nw->shell.save_under;
2324a3bd7f05Smrg    }
2325a3bd7f05Smrg
2326a3bd7f05Smrg    if (ow->shell.override_redirect != nw->shell.override_redirect) {
2327a3bd7f05Smrg        mask |= CWOverrideRedirect;
2328a3bd7f05Smrg        attr.override_redirect = nw->shell.override_redirect;
2329a3bd7f05Smrg    }
2330a3bd7f05Smrg
2331a3bd7f05Smrg    if (mask) {
2332a3bd7f05Smrg        XChangeWindowAttributes(XtDisplay(new), XtWindow(new), mask, &attr);
2333a3bd7f05Smrg        if ((mask & CWOverrideRedirect) && !nw->shell.override_redirect)
2334a3bd7f05Smrg            _popup_set_prop(nw);
2335a3bd7f05Smrg    }
2336a3bd7f05Smrg
2337a3bd7f05Smrg    if (!(ow->shell.client_specified & _XtShellPositionValid)) {
2338a3bd7f05Smrg        Cardinal n;
2339a3bd7f05Smrg
2340a3bd7f05Smrg        for (n = *num_args; n; n--, args++) {
2341a3bd7f05Smrg            if (strcmp(XtNx, args->name) == 0) {
2342a3bd7f05Smrg                _XtShellGetCoordinates((Widget) ow, &ow->core.x, &ow->core.y);
2343a3bd7f05Smrg            }
2344a3bd7f05Smrg            else if (strcmp(XtNy, args->name) == 0) {
2345a3bd7f05Smrg                _XtShellGetCoordinates((Widget) ow, &ow->core.x, &ow->core.y);
2346a3bd7f05Smrg            }
2347a3bd7f05Smrg        }
2348a3bd7f05Smrg    }
2349a3bd7f05Smrg    return FALSE;
2350a3bd7f05Smrg}
2351a3bd7f05Smrg
2352a3bd7f05Smrgstatic Boolean
2353a3bd7f05SmrgWMSetValues(Widget old,
2354a3bd7f05Smrg            Widget ref _X_UNUSED,
2355a3bd7f05Smrg            Widget new,
2356a3bd7f05Smrg            ArgList args _X_UNUSED,
2357a3bd7f05Smrg            Cardinal *num_args _X_UNUSED)
2358a3bd7f05Smrg{
2359a3bd7f05Smrg    WMShellWidget nwmshell = (WMShellWidget) new;
2360a3bd7f05Smrg    WMShellWidget owmshell = (WMShellWidget) old;
2361a3bd7f05Smrg    Boolean set_prop = XtIsRealized(new) && !nwmshell->shell.override_redirect;
2362a3bd7f05Smrg    Boolean title_changed;
2363a3bd7f05Smrg
2364a3bd7f05Smrg    EvaluateSizeHints(nwmshell);
2365444c061aSmrg
2366444c061aSmrg#define NEQ(f) (nwmshell->wm.size_hints.f != owmshell->wm.size_hints.f)
2367444c061aSmrg
2368a3bd7f05Smrg    if (set_prop && (NEQ(flags) || NEQ(min_width) || NEQ(min_height)
2369a3bd7f05Smrg                     || NEQ(max_width) || NEQ(max_height)
2370a3bd7f05Smrg                     || NEQ(width_inc) || NEQ(height_inc)
2371a3bd7f05Smrg                     || NEQ(min_aspect.x) || NEQ(min_aspect.y)
2372a3bd7f05Smrg                     || NEQ(max_aspect.x) || NEQ(max_aspect.y)
2373444c061aSmrg#undef NEQ
2374444c061aSmrg#define NEQ(f) (nwmshell->wm.f != owmshell->wm.f)
2375a3bd7f05Smrg                     || NEQ(base_width) || NEQ(base_height) ||
2376a3bd7f05Smrg                     NEQ(win_gravity))) {
2377a3bd7f05Smrg        _SetWMSizeHints(nwmshell);
2378a3bd7f05Smrg    }
2379444c061aSmrg#undef NEQ
2380444c061aSmrg
2381a3bd7f05Smrg    if (nwmshell->wm.title != owmshell->wm.title) {
2382a3bd7f05Smrg        XtFree(owmshell->wm.title);
2383a3bd7f05Smrg        if (!nwmshell->wm.title)
2384a3bd7f05Smrg            nwmshell->wm.title = (_XtString) "";
2385a3bd7f05Smrg        nwmshell->wm.title = XtNewString(nwmshell->wm.title);
2386a3bd7f05Smrg        title_changed = True;
2387a3bd7f05Smrg    }
2388a3bd7f05Smrg    else
2389a3bd7f05Smrg        title_changed = False;
2390a3bd7f05Smrg
2391a3bd7f05Smrg    if (set_prop
2392a3bd7f05Smrg        && (title_changed ||
2393a3bd7f05Smrg            nwmshell->wm.title_encoding != owmshell->wm.title_encoding)) {
2394a3bd7f05Smrg
2395a3bd7f05Smrg        XTextProperty title;
2396a3bd7f05Smrg        Boolean copied = False;
2397a3bd7f05Smrg
2398a3bd7f05Smrg        if (nwmshell->wm.title_encoding == None &&
2399a3bd7f05Smrg            XmbTextListToTextProperty(XtDisplay(new),
2400a3bd7f05Smrg                                      (char **) &nwmshell->wm.title,
2401a3bd7f05Smrg                                      1, XStdICCTextStyle, &title) >= Success) {
2402a3bd7f05Smrg            copied = True;
2403a3bd7f05Smrg        }
2404a3bd7f05Smrg        else {
2405a3bd7f05Smrg            title.value = (unsigned char *) nwmshell->wm.title;
2406a3bd7f05Smrg            title.encoding = nwmshell->wm.title_encoding ?
2407a3bd7f05Smrg                nwmshell->wm.title_encoding : XA_STRING;
2408a3bd7f05Smrg            title.format = 8;
2409a3bd7f05Smrg            title.nitems = strlen(nwmshell->wm.title);
2410a3bd7f05Smrg        }
2411a3bd7f05Smrg        XSetWMName(XtDisplay(new), XtWindow(new), &title);
2412a3bd7f05Smrg        if (copied)
2413a3bd7f05Smrg            XFree((XPointer) title.value);
2414a3bd7f05Smrg    }
2415a3bd7f05Smrg
2416a3bd7f05Smrg    EvaluateWMHints(nwmshell);
2417a3bd7f05Smrg
2418a3bd7f05Smrg#define NEQ(f)  (nwmshell->wm.wm_hints.f != owmshell->wm.wm_hints.f)
2419a3bd7f05Smrg
2420a3bd7f05Smrg    if (set_prop && (NEQ(flags) || NEQ(input) || NEQ(initial_state)
2421a3bd7f05Smrg                     || NEQ(icon_x) || NEQ(icon_y)
2422a3bd7f05Smrg                     || NEQ(icon_pixmap) || NEQ(icon_mask) || NEQ(icon_window)
2423a3bd7f05Smrg                     || NEQ(window_group))) {
2424a3bd7f05Smrg
2425a3bd7f05Smrg        XSetWMHints(XtDisplay(new), XtWindow(new), &nwmshell->wm.wm_hints);
2426a3bd7f05Smrg    }
2427444c061aSmrg#undef NEQ
2428444c061aSmrg
2429a3bd7f05Smrg    if (XtIsRealized(new) && nwmshell->wm.transient != owmshell->wm.transient) {
2430a3bd7f05Smrg        if (nwmshell->wm.transient) {
2431a3bd7f05Smrg            if (!XtIsTransientShell(new) &&
2432a3bd7f05Smrg                !nwmshell->shell.override_redirect &&
2433a3bd7f05Smrg                nwmshell->wm.wm_hints.window_group != XtUnspecifiedWindowGroup)
2434a3bd7f05Smrg                XSetTransientForHint(XtDisplay(new), XtWindow(new),
2435a3bd7f05Smrg                                     nwmshell->wm.wm_hints.window_group);
2436a3bd7f05Smrg        }
2437a3bd7f05Smrg        else
2438a3bd7f05Smrg            XDeleteProperty(XtDisplay(new), XtWindow(new), XA_WM_TRANSIENT_FOR);
2439a3bd7f05Smrg    }
2440a3bd7f05Smrg
2441a3bd7f05Smrg    if (nwmshell->wm.client_leader != owmshell->wm.client_leader
2442a3bd7f05Smrg        && XtWindow(new) && !nwmshell->shell.override_redirect) {
2443a3bd7f05Smrg        Widget leader = GetClientLeader(new);
2444a3bd7f05Smrg
2445a3bd7f05Smrg        if (XtWindow(leader))
2446a3bd7f05Smrg            XChangeProperty(XtDisplay(new), XtWindow(new),
2447a3bd7f05Smrg                            XInternAtom(XtDisplay(new),
2448a3bd7f05Smrg                                        "WM_CLIENT_LEADER", False),
2449a3bd7f05Smrg                            XA_WINDOW, 32, PropModeReplace,
2450a3bd7f05Smrg                            (unsigned char *) &(leader->core.window), 1);
2451a3bd7f05Smrg    }
2452a3bd7f05Smrg
2453a3bd7f05Smrg    if (nwmshell->wm.window_role != owmshell->wm.window_role) {
2454a3bd7f05Smrg        XtFree((_XtString) owmshell->wm.window_role);
2455a3bd7f05Smrg        if (set_prop && nwmshell->wm.window_role) {
2456a3bd7f05Smrg            XChangeProperty(XtDisplay(new), XtWindow(new),
2457a3bd7f05Smrg                            XInternAtom(XtDisplay(new), "WM_WINDOW_ROLE",
2458a3bd7f05Smrg                                        False),
2459a3bd7f05Smrg                            XA_STRING, 8, PropModeReplace,
2460a3bd7f05Smrg                            (unsigned char *) nwmshell->wm.window_role,
2461a3bd7f05Smrg                            (int) strlen(nwmshell->wm.window_role));
2462a3bd7f05Smrg        }
2463a3bd7f05Smrg        else if (XtIsRealized(new) && !nwmshell->wm.window_role) {
2464a3bd7f05Smrg            XDeleteProperty(XtDisplay(new), XtWindow(new),
2465a3bd7f05Smrg                            XInternAtom(XtDisplay(new), "WM_WINDOW_ROLE",
2466a3bd7f05Smrg                                        False));
2467a3bd7f05Smrg        }
2468a3bd7f05Smrg    }
2469a3bd7f05Smrg
2470a3bd7f05Smrg    return FALSE;
2471a3bd7f05Smrg}
2472a3bd7f05Smrg
2473a3bd7f05Smrgstatic Boolean
2474a3bd7f05SmrgTransientSetValues(Widget oldW,
2475a3bd7f05Smrg                   Widget refW _X_UNUSED,
2476a3bd7f05Smrg                   Widget newW,
2477a3bd7f05Smrg                   ArgList args _X_UNUSED,
2478a3bd7f05Smrg                   Cardinal *num_args _X_UNUSED)
2479a3bd7f05Smrg{
2480a3bd7f05Smrg    TransientShellWidget old = (TransientShellWidget) oldW;
2481a3bd7f05Smrg    TransientShellWidget new = (TransientShellWidget) newW;
2482444c061aSmrg
2483444c061aSmrg    if (XtIsRealized(newW)
2484a3bd7f05Smrg        && ((new->wm.transient && !old->wm.transient)
2485a3bd7f05Smrg            || ((new->transient.transient_for != old->transient.transient_for)
2486a3bd7f05Smrg                || (new->transient.transient_for == NULL
2487a3bd7f05Smrg                    && (new->wm.wm_hints.window_group
2488a3bd7f05Smrg                        != old->wm.wm_hints.window_group))))) {
2489444c061aSmrg
2490a3bd7f05Smrg        _SetTransientForHint(new, True);
2491444c061aSmrg    }
2492444c061aSmrg    return False;
2493444c061aSmrg}
2494444c061aSmrg
2495a3bd7f05Smrgstatic Boolean
2496a3bd7f05SmrgTopLevelSetValues(Widget oldW,
2497a3bd7f05Smrg                  Widget refW _X_UNUSED,
2498a3bd7f05Smrg                  Widget newW,
2499a3bd7f05Smrg                  ArgList args _X_UNUSED,
2500a3bd7f05Smrg                  Cardinal *num_args _X_UNUSED)
2501444c061aSmrg{
2502a3bd7f05Smrg    TopLevelShellWidget old = (TopLevelShellWidget) oldW;
2503a3bd7f05Smrg    TopLevelShellWidget new = (TopLevelShellWidget) newW;
2504444c061aSmrg    Boolean name_changed;
2505444c061aSmrg
2506444c061aSmrg    if (old->topLevel.icon_name != new->topLevel.icon_name) {
2507a3bd7f05Smrg        XtFree((XtPointer) old->topLevel.icon_name);
2508a3bd7f05Smrg        if (!new->topLevel.icon_name)
2509a3bd7f05Smrg            new->topLevel.icon_name = (_XtString) "";
2510a3bd7f05Smrg        new->topLevel.icon_name = XtNewString(new->topLevel.icon_name);
2511a3bd7f05Smrg        name_changed = True;
2512a3bd7f05Smrg    }
2513a3bd7f05Smrg    else
2514a3bd7f05Smrg        name_changed = False;
2515444c061aSmrg
2516444c061aSmrg    if (XtIsRealized(newW)) {
2517a3bd7f05Smrg        if (new->topLevel.iconic != old->topLevel.iconic) {
2518a3bd7f05Smrg            if (new->topLevel.iconic)
2519a3bd7f05Smrg                XIconifyWindow(XtDisplay(newW),
2520a3bd7f05Smrg                               XtWindow(newW),
2521a3bd7f05Smrg                               XScreenNumberOfScreen(XtScreen(newW))
2522a3bd7f05Smrg                    );
2523a3bd7f05Smrg            else {
2524a3bd7f05Smrg                Boolean map = new->shell.popped_up;
2525a3bd7f05Smrg
2526a3bd7f05Smrg                XtPopup(newW, XtGrabNone);
2527a3bd7f05Smrg                if (map)
2528a3bd7f05Smrg                    XMapWindow(XtDisplay(newW), XtWindow(newW));
2529a3bd7f05Smrg            }
2530a3bd7f05Smrg        }
2531a3bd7f05Smrg
2532a3bd7f05Smrg        if (!new->shell.override_redirect &&
2533a3bd7f05Smrg            (name_changed ||
2534a3bd7f05Smrg             (old->topLevel.icon_name_encoding
2535a3bd7f05Smrg              != new->topLevel.icon_name_encoding))) {
2536a3bd7f05Smrg
2537a3bd7f05Smrg            XTextProperty icon_name;
2538a3bd7f05Smrg            Boolean copied = False;
2539444c061aSmrg
2540444c061aSmrg            if (new->topLevel.icon_name_encoding == None &&
2541a3bd7f05Smrg                XmbTextListToTextProperty(XtDisplay(newW),
2542a3bd7f05Smrg                                          (char **) &new->topLevel.icon_name,
2543a3bd7f05Smrg                                          1, XStdICCTextStyle,
2544a3bd7f05Smrg                                          &icon_name) >= Success) {
2545a3bd7f05Smrg                copied = True;
2546a3bd7f05Smrg            }
2547a3bd7f05Smrg            else {
2548a3bd7f05Smrg                icon_name.value = (unsigned char *) new->topLevel.icon_name;
2549a3bd7f05Smrg                icon_name.encoding = new->topLevel.icon_name_encoding ?
2550a3bd7f05Smrg                    new->topLevel.icon_name_encoding : XA_STRING;
2551a3bd7f05Smrg                icon_name.format = 8;
2552a3bd7f05Smrg                icon_name.nitems = strlen((char *) icon_name.value);
2553a3bd7f05Smrg            }
2554a3bd7f05Smrg            XSetWMIconName(XtDisplay(newW), XtWindow(newW), &icon_name);
2555a3bd7f05Smrg            if (copied)
2556a3bd7f05Smrg                XFree((XPointer) icon_name.value);
2557a3bd7f05Smrg        }
2558444c061aSmrg    }
2559bdf0f55dSmrg    else if (new->topLevel.iconic != old->topLevel.iconic) {
2560a3bd7f05Smrg        if (new->topLevel.iconic)
2561a3bd7f05Smrg            new->wm.wm_hints.initial_state = IconicState;
2562bdf0f55dSmrg    }
2563444c061aSmrg    return False;
2564444c061aSmrg}
2565444c061aSmrg
2566a3bd7f05Smrg/* do not assume it's terminated by a NULL element */
2567a3bd7f05Smrgstatic _XtString *
2568a3bd7f05SmrgNewArgv(int count, _XtString *str)
2569a3bd7f05Smrg{
2570444c061aSmrg    Cardinal nbytes = 0;
2571444c061aSmrg    Cardinal num = 0;
25720568f49bSmrg    _XtString *newarray;
25730568f49bSmrg    _XtString *new;
25740568f49bSmrg    _XtString *strarray = str;
25750568f49bSmrg    _XtString sptr;
2576444c061aSmrg
2577a3bd7f05Smrg    if (count <= 0 || !str)
2578a3bd7f05Smrg        return NULL;
2579444c061aSmrg
25800568f49bSmrg    for (num = (Cardinal) count; num--; str++) {
2581a3bd7f05Smrg        nbytes = (nbytes + (Cardinal) strlen(*str));
2582a3bd7f05Smrg        nbytes++;
2583444c061aSmrg    }
2584a3bd7f05Smrg    num = (Cardinal) ((size_t) (count + 1) * sizeof(_XtString));
25850568f49bSmrg    new = newarray = (_XtString *) __XtMalloc(num + nbytes);
2586444c061aSmrg    sptr = ((char *) new) + num;
2587444c061aSmrg
2588444c061aSmrg    for (str = strarray; count--; str++) {
2589a3bd7f05Smrg        *new = sptr;
2590a3bd7f05Smrg        strcpy(*new, *str);
2591a3bd7f05Smrg        new++;
2592a3bd7f05Smrg        sptr = strchr(sptr, '\0');
2593a3bd7f05Smrg        sptr++;
2594444c061aSmrg    }
2595444c061aSmrg    *new = NULL;
2596444c061aSmrg    return newarray;
2597444c061aSmrg}
2598444c061aSmrg
2599a3bd7f05Smrgstatic Boolean
2600a3bd7f05SmrgApplicationSetValues(Widget current,
2601a3bd7f05Smrg                     Widget request _X_UNUSED,
2602a3bd7f05Smrg                     Widget new,
2603a3bd7f05Smrg                     ArgList args _X_UNUSED,
2604a3bd7f05Smrg                     Cardinal *num_args _X_UNUSED)
2605444c061aSmrg{
2606444c061aSmrg    ApplicationShellWidget nw = (ApplicationShellWidget) new;
2607444c061aSmrg    ApplicationShellWidget cw = (ApplicationShellWidget) current;
2608444c061aSmrg
2609444c061aSmrg    if (cw->application.argc != nw->application.argc ||
2610a3bd7f05Smrg        cw->application.argv != nw->application.argv) {
2611a3bd7f05Smrg
2612a3bd7f05Smrg        if (nw->application.argc > 0)
2613a3bd7f05Smrg            nw->application.argv = NewArgv(nw->application.argc,
2614a3bd7f05Smrg                                           nw->application.argv);
2615a3bd7f05Smrg        if (cw->application.argc > 0)
2616a3bd7f05Smrg            FreeStringArray(cw->application.argv);
2617a3bd7f05Smrg
2618a3bd7f05Smrg        if (XtIsRealized(new) && !nw->shell.override_redirect) {
2619a3bd7f05Smrg            if (nw->application.argc >= 0 && nw->application.argv)
2620a3bd7f05Smrg                XSetCommand(XtDisplay(new), XtWindow(new),
2621a3bd7f05Smrg                            nw->application.argv, nw->application.argc);
2622a3bd7f05Smrg            else
2623a3bd7f05Smrg                XDeleteProperty(XtDisplay(new), XtWindow(new), XA_WM_COMMAND);
2624a3bd7f05Smrg        }
2625444c061aSmrg    }
2626444c061aSmrg    return False;
2627444c061aSmrg}
2628444c061aSmrg
2629a3bd7f05Smrgstatic Boolean
2630a3bd7f05SmrgSessionSetValues(Widget current,
2631a3bd7f05Smrg                 Widget request _X_UNUSED,
2632a3bd7f05Smrg                 Widget new,
2633a3bd7f05Smrg                 ArgList args _X_UNUSED,
2634a3bd7f05Smrg                 Cardinal *num_args _X_UNUSED)
2635444c061aSmrg{
2636444c061aSmrg#ifndef XT_NO_SM
2637444c061aSmrg    SessionShellWidget nw = (SessionShellWidget) new;
2638444c061aSmrg    SessionShellWidget cw = (SessionShellWidget) current;
2639444c061aSmrg    unsigned long set_mask = 0UL;
2640444c061aSmrg    unsigned long unset_mask = 0UL;
2641444c061aSmrg    Boolean initialize = False;
2642444c061aSmrg
2643444c061aSmrg    if (cw->session.session_id != nw->session.session_id) {
2644a3bd7f05Smrg        nw->session.session_id = XtNewString(nw->session.session_id);
2645a3bd7f05Smrg        XtFree(cw->session.session_id);
2646444c061aSmrg    }
2647444c061aSmrg
2648444c061aSmrg    if (cw->session.clone_command != nw->session.clone_command) {
2649a3bd7f05Smrg        if (nw->session.clone_command) {
2650a3bd7f05Smrg            nw->session.clone_command =
2651a3bd7f05Smrg                NewStringArray(nw->session.clone_command);
2652a3bd7f05Smrg            set_mask |= XtCloneCommandMask;
2653a3bd7f05Smrg        }
2654a3bd7f05Smrg        else
2655a3bd7f05Smrg            unset_mask |= XtCloneCommandMask;
2656a3bd7f05Smrg        FreeStringArray(cw->session.clone_command);
2657444c061aSmrg    }
2658444c061aSmrg
2659444c061aSmrg    if (cw->session.current_dir != nw->session.current_dir) {
2660a3bd7f05Smrg        if (nw->session.current_dir) {
2661a3bd7f05Smrg            nw->session.current_dir = XtNewString(nw->session.current_dir);
2662a3bd7f05Smrg            set_mask |= XtCurrentDirectoryMask;
2663a3bd7f05Smrg        }
2664a3bd7f05Smrg        else
2665a3bd7f05Smrg            unset_mask |= XtCurrentDirectoryMask;
2666a3bd7f05Smrg        XtFree((char *) cw->session.current_dir);
2667444c061aSmrg    }
2668444c061aSmrg
2669444c061aSmrg    if (cw->session.discard_command != nw->session.discard_command) {
2670a3bd7f05Smrg        if (nw->session.discard_command) {
2671a3bd7f05Smrg            nw->session.discard_command =
2672a3bd7f05Smrg                NewStringArray(nw->session.discard_command);
2673a3bd7f05Smrg            set_mask |= XtDiscardCommandMask;
2674a3bd7f05Smrg        }
2675a3bd7f05Smrg        else
2676a3bd7f05Smrg            unset_mask |= XtDiscardCommandMask;
2677a3bd7f05Smrg        FreeStringArray(cw->session.discard_command);
2678444c061aSmrg    }
2679444c061aSmrg
2680444c061aSmrg    if (cw->session.environment != nw->session.environment) {
2681a3bd7f05Smrg        if (nw->session.environment) {
2682a3bd7f05Smrg            nw->session.environment = NewStringArray(nw->session.environment);
2683a3bd7f05Smrg            set_mask |= XtEnvironmentMask;
2684a3bd7f05Smrg        }
2685a3bd7f05Smrg        else
2686a3bd7f05Smrg            unset_mask |= XtEnvironmentMask;
2687a3bd7f05Smrg        FreeStringArray(cw->session.environment);
2688444c061aSmrg    }
2689444c061aSmrg
2690444c061aSmrg    if (cw->session.program_path != nw->session.program_path) {
2691a3bd7f05Smrg        if (nw->session.program_path) {
2692a3bd7f05Smrg            nw->session.program_path = XtNewString(nw->session.program_path);
2693a3bd7f05Smrg            set_mask |= XtProgramMask;
2694a3bd7f05Smrg        }
2695a3bd7f05Smrg        else
2696a3bd7f05Smrg            unset_mask |= XtProgramMask;
2697a3bd7f05Smrg        XtFree((char *) cw->session.program_path);
2698444c061aSmrg    }
2699444c061aSmrg
2700444c061aSmrg    if (cw->session.resign_command != nw->session.resign_command) {
2701a3bd7f05Smrg        if (nw->session.resign_command) {
2702a3bd7f05Smrg            nw->session.resign_command =
2703a3bd7f05Smrg                NewStringArray(nw->session.resign_command);
2704a3bd7f05Smrg            set_mask |= XtResignCommandMask;
2705a3bd7f05Smrg        }
2706a3bd7f05Smrg        else
2707a3bd7f05Smrg            set_mask |= XtResignCommandMask;
2708a3bd7f05Smrg        FreeStringArray(cw->session.resign_command);
2709444c061aSmrg    }
2710444c061aSmrg
2711444c061aSmrg    if (cw->session.restart_command != nw->session.restart_command) {
2712a3bd7f05Smrg        if (nw->session.restart_command) {
2713a3bd7f05Smrg            nw->session.restart_command =
2714a3bd7f05Smrg                NewStringArray(nw->session.restart_command);
2715a3bd7f05Smrg            set_mask |= XtRestartCommandMask;
2716a3bd7f05Smrg        }
2717a3bd7f05Smrg        else
2718a3bd7f05Smrg            unset_mask |= XtRestartCommandMask;
2719a3bd7f05Smrg        FreeStringArray(cw->session.restart_command);
2720444c061aSmrg    }
2721444c061aSmrg
2722444c061aSmrg    if (cw->session.restart_style != nw->session.restart_style)
2723a3bd7f05Smrg        set_mask |= XtRestartStyleHintMask;
2724444c061aSmrg
2725444c061aSmrg    if (cw->session.shutdown_command != nw->session.shutdown_command) {
2726a3bd7f05Smrg        if (nw->session.shutdown_command) {
2727a3bd7f05Smrg            nw->session.shutdown_command =
2728a3bd7f05Smrg                NewStringArray(nw->session.shutdown_command);
2729a3bd7f05Smrg            set_mask |= XtShutdownCommandMask;
2730a3bd7f05Smrg        }
2731a3bd7f05Smrg        else
2732a3bd7f05Smrg            unset_mask |= XtShutdownCommandMask;
2733a3bd7f05Smrg        FreeStringArray(cw->session.shutdown_command);
2734444c061aSmrg    }
2735444c061aSmrg
2736444c061aSmrg    if ((!cw->session.join_session && nw->session.join_session) ||
2737a3bd7f05Smrg        (!cw->session.connection && nw->session.connection)) {
2738a3bd7f05Smrg        JoinSession(nw);
2739a3bd7f05Smrg        initialize = True;
2740444c061aSmrg    }
2741444c061aSmrg
2742444c061aSmrg    if (nw->session.connection && (set_mask || unset_mask || initialize))
2743a3bd7f05Smrg        SetSessionProperties((SessionShellWidget) new, initialize, set_mask,
2744a3bd7f05Smrg                             unset_mask);
2745444c061aSmrg
2746444c061aSmrg    if ((cw->session.join_session && !nw->session.join_session) ||
2747a3bd7f05Smrg        (cw->session.connection && !nw->session.connection))
2748a3bd7f05Smrg        StopManagingSession(nw, nw->session.connection);
2749a3bd7f05Smrg#endif                          /* !XT_NO_SM */
2750444c061aSmrg
2751444c061aSmrg    if (cw->wm.client_leader != nw->wm.client_leader ||
2752a3bd7f05Smrg        cw->session.session_id != nw->session.session_id) {
2753a3bd7f05Smrg        Widget leader;
2754a3bd7f05Smrg
2755a3bd7f05Smrg        if (cw->session.session_id) {
2756a3bd7f05Smrg            leader = GetClientLeader(current);
2757a3bd7f05Smrg            if (XtWindow(leader))
2758a3bd7f05Smrg                XDeleteProperty(XtDisplay(leader), XtWindow(leader),
2759a3bd7f05Smrg                                XInternAtom(XtDisplay(leader), "SM_CLIENT_ID",
2760a3bd7f05Smrg                                            False));
2761a3bd7f05Smrg        }
2762a3bd7f05Smrg        if (nw->session.session_id) {
2763a3bd7f05Smrg            leader = GetClientLeader(new);
2764a3bd7f05Smrg            if (XtWindow(leader))
2765a3bd7f05Smrg                XChangeProperty(XtDisplay(leader), XtWindow(leader),
2766a3bd7f05Smrg                                XInternAtom(XtDisplay(leader), "SM_CLIENT_ID",
2767a3bd7f05Smrg                                            False),
2768a3bd7f05Smrg                                XA_STRING, 8, PropModeReplace,
2769a3bd7f05Smrg                                (unsigned char *) nw->session.session_id,
2770a3bd7f05Smrg                                (int) strlen(nw->session.session_id));
2771a3bd7f05Smrg        }
2772444c061aSmrg    }
2773444c061aSmrg    return False;
2774444c061aSmrg}
2775444c061aSmrg
2776a3bd7f05Smrgvoid
2777a3bd7f05Smrg_XtShellGetCoordinates(Widget widget, Position *x, Position *y)
2778444c061aSmrg{
2779a3bd7f05Smrg    ShellWidget w = (ShellWidget) widget;
2780a3bd7f05Smrg
2781444c061aSmrg    if (XtIsRealized(widget) &&
2782a3bd7f05Smrg        !(w->shell.client_specified & _XtShellPositionValid)) {
2783a3bd7f05Smrg        int tmpx, tmpy;
2784a3bd7f05Smrg        Window tmpchild;
2785a3bd7f05Smrg
2786a3bd7f05Smrg        (void) XTranslateCoordinates(XtDisplay(w), XtWindow(w),
2787a3bd7f05Smrg                                     RootWindowOfScreen(XtScreen(w)),
2788a3bd7f05Smrg                                     (int) -w->core.border_width,
2789a3bd7f05Smrg                                     (int) -w->core.border_width,
2790a3bd7f05Smrg                                     &tmpx, &tmpy, &tmpchild);
2791a3bd7f05Smrg        w->core.x = (Position) tmpx;
2792a3bd7f05Smrg        w->core.y = (Position) tmpy;
2793a3bd7f05Smrg        w->shell.client_specified |= _XtShellPositionValid;
2794444c061aSmrg    }
2795444c061aSmrg    *x = w->core.x;
2796444c061aSmrg    *y = w->core.y;
2797444c061aSmrg}
2798444c061aSmrg
2799a3bd7f05Smrgstatic void
2800a3bd7f05SmrgGetValuesHook(Widget widget, ArgList args, Cardinal *num_args)
2801444c061aSmrg{
2802444c061aSmrg    ShellWidget w = (ShellWidget) widget;
2803444c061aSmrg
2804444c061aSmrg    /* x and y resource values may be invalid after a shell resize */
2805444c061aSmrg    if (XtIsRealized(widget) &&
2806a3bd7f05Smrg        !(w->shell.client_specified & _XtShellPositionValid)) {
2807a3bd7f05Smrg        Cardinal n;
2808a3bd7f05Smrg        Position x, y;
2809a3bd7f05Smrg
2810a3bd7f05Smrg        for (n = *num_args; n; n--, args++) {
2811a3bd7f05Smrg            if (strcmp(XtNx, args->name) == 0) {
2812a3bd7f05Smrg                _XtShellGetCoordinates(widget, &x, &y);
2813a3bd7f05Smrg                _XtCopyToArg((char *) &x, &args->value, sizeof(Position));
2814a3bd7f05Smrg            }
2815a3bd7f05Smrg            else if (strcmp(XtNy, args->name) == 0) {
2816a3bd7f05Smrg                _XtShellGetCoordinates(widget, &x, &y);
2817a3bd7f05Smrg                _XtCopyToArg((char *) &y, &args->value, sizeof(Position));
2818a3bd7f05Smrg            }
2819a3bd7f05Smrg        }
2820444c061aSmrg    }
2821444c061aSmrg}
2822444c061aSmrg
2823a3bd7f05Smrgstatic void
2824a3bd7f05SmrgApplicationShellInsertChild(Widget widget)
2825444c061aSmrg{
2826a3bd7f05Smrg    if (!XtIsWidget(widget) && XtIsRectObj(widget)) {
2827a3bd7f05Smrg        XtAppWarningMsg(XtWidgetToApplicationContext(widget),
2828a3bd7f05Smrg                        "invalidClass", "applicationShellInsertChild",
2829a3bd7f05Smrg                        XtCXtToolkitError,
2830a3bd7f05Smrg                        "ApplicationShell does not accept RectObj children; ignored",
2831a3bd7f05Smrg                        NULL, NULL);
2832444c061aSmrg    }
2833444c061aSmrg    else {
2834a3bd7f05Smrg        XtWidgetProc insert_child;
2835444c061aSmrg
2836a3bd7f05Smrg        LOCK_PROCESS;
2837a3bd7f05Smrg        insert_child =
2838a3bd7f05Smrg            ((CompositeWidgetClass) applicationShellClassRec.core_class.
2839a3bd7f05Smrg             superclass)->composite_class.insert_child;
2840a3bd7f05Smrg        UNLOCK_PROCESS;
2841a3bd7f05Smrg        (*insert_child) (widget);
2842444c061aSmrg    }
2843444c061aSmrg}
2844444c061aSmrg
2845444c061aSmrg/**************************************************************************
2846444c061aSmrg
2847444c061aSmrg  Session Protocol Participation
2848444c061aSmrg
2849444c061aSmrg *************************************************************************/
2850444c061aSmrg
2851a3bd7f05Smrg#define XtSessionCheckpoint     0
2852a3bd7f05Smrg#define XtSessionInteract       1
2853444c061aSmrg
2854a3bd7f05Smrgstatic void CallSaveCallbacks(SessionShellWidget);
28550568f49bSmrgstatic _XtString *EditCommand(_XtString, _XtString *, _XtString *);
2856444c061aSmrgstatic Boolean ExamineToken(XtPointer);
2857444c061aSmrgstatic void GetIceEvent(XtPointer, int *, XtInputId *);
2858444c061aSmrgstatic XtCheckpointToken GetToken(Widget, int);
2859444c061aSmrgstatic void XtCallCancelCallbacks(SmcConn, SmPointer);
2860444c061aSmrgstatic void XtCallDieCallbacks(SmcConn, SmPointer);
2861444c061aSmrgstatic void XtCallSaveCallbacks(SmcConn, SmPointer, int, Bool, int, Bool);
2862444c061aSmrgstatic void XtCallSaveCompleteCallbacks(SmcConn, SmPointer);
2863444c061aSmrg
2864444c061aSmrg#ifndef XT_NO_SM
2865a3bd7f05Smrgstatic void
2866a3bd7f05SmrgStopManagingSession(SessionShellWidget w, SmcConn connection)
2867a3bd7f05Smrg{                               /* connection to close, if any */
2868444c061aSmrg    if (connection)
2869a3bd7f05Smrg        SmcCloseConnection(connection, 0, NULL);
2870444c061aSmrg
2871444c061aSmrg    if (w->session.input_id) {
2872a3bd7f05Smrg        XtRemoveInput(w->session.input_id);
2873a3bd7f05Smrg        w->session.input_id = 0;
2874444c061aSmrg    }
2875444c061aSmrg    w->session.connection = NULL;
2876444c061aSmrg}
2877444c061aSmrg
2878444c061aSmrg#define XT_MSG_LENGTH 256
2879a3bd7f05Smrgstatic void
2880a3bd7f05SmrgJoinSession(SessionShellWidget w)
2881444c061aSmrg{
2882444c061aSmrg    IceConn ice_conn;
2883444c061aSmrg    SmcCallbacks smcb;
2884a3bd7f05Smrg    char *sm_client_id;
2885444c061aSmrg    unsigned long mask;
2886a3bd7f05Smrg    static char context;        /* used to guarantee the connection isn't shared */
2887444c061aSmrg
2888444c061aSmrg    smcb.save_yourself.callback = XtCallSaveCallbacks;
2889444c061aSmrg    smcb.die.callback = XtCallDieCallbacks;
2890444c061aSmrg    smcb.save_complete.callback = XtCallSaveCompleteCallbacks;
2891444c061aSmrg    smcb.shutdown_cancelled.callback = XtCallCancelCallbacks;
2892444c061aSmrg    smcb.save_yourself.client_data = smcb.die.client_data =
2893a3bd7f05Smrg        smcb.save_complete.client_data =
2894a3bd7f05Smrg        smcb.shutdown_cancelled.client_data = (SmPointer) w;
2895444c061aSmrg    mask = SmcSaveYourselfProcMask | SmcDieProcMask |
2896a3bd7f05Smrg        SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask;
2897444c061aSmrg
2898444c061aSmrg    if (w->session.connection) {
2899a3bd7f05Smrg        SmcModifyCallbacks(w->session.connection, mask, &smcb);
2900a3bd7f05Smrg        sm_client_id = SmcClientID(w->session.connection);
2901a3bd7f05Smrg    }
2902a3bd7f05Smrg    else if (getenv("SESSION_MANAGER")) {
2903a3bd7f05Smrg        char error_msg[XT_MSG_LENGTH];
2904a3bd7f05Smrg
2905a3bd7f05Smrg        error_msg[0] = '\0';
2906a3bd7f05Smrg        w->session.connection =
2907a3bd7f05Smrg            SmcOpenConnection(NULL, &context, SmProtoMajor, SmProtoMinor,
2908a3bd7f05Smrg                              mask, &smcb, w->session.session_id,
2909a3bd7f05Smrg                              &sm_client_id, XT_MSG_LENGTH, error_msg);
2910a3bd7f05Smrg        if (error_msg[0]) {
2911a3bd7f05Smrg            String params[1];
2912a3bd7f05Smrg            Cardinal num_params = 1;
2913a3bd7f05Smrg
2914a3bd7f05Smrg            params[0] = error_msg;
2915a3bd7f05Smrg            XtAppWarningMsg(XtWidgetToApplicationContext((Widget) w),
2916a3bd7f05Smrg                            "sessionManagement", "SmcOpenConnection",
2917a3bd7f05Smrg                            XtCXtToolkitError,
2918a3bd7f05Smrg                            "Tried to connect to session manager, %s",
2919a3bd7f05Smrg                            params, &num_params);
2920a3bd7f05Smrg        }
2921444c061aSmrg    }
2922444c061aSmrg
2923444c061aSmrg    if (w->session.connection) {
2924a3bd7f05Smrg        if (w->session.session_id == NULL
2925a3bd7f05Smrg            || (strcmp(w->session.session_id, sm_client_id) != 0)) {
2926a3bd7f05Smrg            XtFree(w->session.session_id);
2927a3bd7f05Smrg            w->session.session_id = XtNewString(sm_client_id);
2928a3bd7f05Smrg        }
2929a3bd7f05Smrg        free(sm_client_id);
2930a3bd7f05Smrg        ice_conn = SmcGetIceConnection(w->session.connection);
2931a3bd7f05Smrg        w->session.input_id =
2932a3bd7f05Smrg            XtAppAddInput(XtWidgetToApplicationContext((Widget) w),
2933a3bd7f05Smrg                          IceConnectionNumber(ice_conn),
2934a3bd7f05Smrg                          (XtPointer) XtInputReadMask,
2935a3bd7f05Smrg                          GetIceEvent, (XtPointer) w);
2936a3bd7f05Smrg
2937a3bd7f05Smrg        w->session.restart_command =
2938a3bd7f05Smrg            EditCommand(w->session.session_id, w->session.restart_command,
2939a3bd7f05Smrg                        w->application.argv);
2940a3bd7f05Smrg
2941a3bd7f05Smrg        if (!w->session.clone_command)
2942a3bd7f05Smrg            w->session.clone_command =
2943a3bd7f05Smrg                EditCommand(NULL, NULL, w->session.restart_command);
2944a3bd7f05Smrg
2945a3bd7f05Smrg        if (!w->session.program_path)
2946a3bd7f05Smrg            w->session.program_path = w->session.restart_command
2947a3bd7f05Smrg                ? XtNewString(w->session.restart_command[0]) : NULL;
2948444c061aSmrg    }
2949444c061aSmrg}
2950a3bd7f05Smrg
2951444c061aSmrg#undef XT_MSG_LENGTH
2952444c061aSmrg
2953a3bd7f05Smrg#endif                          /* !XT_NO_SM */
2954444c061aSmrg
2955a3bd7f05Smrgstatic _XtString *
2956a3bd7f05SmrgNewStringArray(_XtString *str)
2957444c061aSmrg{
2958444c061aSmrg    Cardinal nbytes = 0;
2959444c061aSmrg    Cardinal num = 0;
29600568f49bSmrg    _XtString *newarray;
29610568f49bSmrg    _XtString *new;
29620568f49bSmrg    _XtString *strarray = str;
29630568f49bSmrg    _XtString sptr;
2964444c061aSmrg
2965a3bd7f05Smrg    if (!str)
2966a3bd7f05Smrg        return NULL;
2967444c061aSmrg
2968444c061aSmrg    for (num = 0; *str; num++, str++) {
2969a3bd7f05Smrg        nbytes = nbytes + (Cardinal) strlen(*str);
2970a3bd7f05Smrg        nbytes++;
2971444c061aSmrg    }
2972a3bd7f05Smrg    num = (Cardinal) ((size_t) (num + 1) * sizeof(_XtString));
29730568f49bSmrg    new = newarray = (_XtString *) __XtMalloc(num + nbytes);
2974444c061aSmrg    sptr = ((char *) new) + num;
2975444c061aSmrg
2976444c061aSmrg    for (str = strarray; *str; str++) {
2977a3bd7f05Smrg        *new = sptr;
2978a3bd7f05Smrg        strcpy(*new, *str);
2979a3bd7f05Smrg        new++;
2980a3bd7f05Smrg        sptr = strchr(sptr, '\0');
2981a3bd7f05Smrg        sptr++;
2982444c061aSmrg    }
2983444c061aSmrg    *new = NULL;
2984444c061aSmrg    return newarray;
2985444c061aSmrg}
2986444c061aSmrg
2987a3bd7f05Smrgstatic void
2988a3bd7f05SmrgFreeStringArray(_XtString *str)
2989444c061aSmrg{
2990444c061aSmrg    if (str)
2991a3bd7f05Smrg        XtFree((_XtString) str);
2992444c061aSmrg}
2993444c061aSmrg
2994444c061aSmrg#ifndef XT_NO_SM
2995a3bd7f05Smrgstatic SmProp *
2996a3bd7f05SmrgCardPack(_Xconst _XtString name, XtPointer closure)
2997444c061aSmrg{
2998444c061aSmrg    unsigned char *prop = (unsigned char *) closure;
2999444c061aSmrg    SmProp *p;
3000444c061aSmrg
3001444c061aSmrg    p = (SmProp *) __XtMalloc(sizeof(SmProp) + sizeof(SmPropValue));
3002444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
3003444c061aSmrg    p->num_vals = 1;
3004a3bd7f05Smrg    p->type = (char *) SmCARD8;
3005a3bd7f05Smrg    p->name = (char *) name;
3006444c061aSmrg    p->vals->length = 1;
3007444c061aSmrg    p->vals->value = (SmPointer) prop;
3008444c061aSmrg    return p;
3009444c061aSmrg}
3010444c061aSmrg
3011a3bd7f05Smrgstatic SmProp *
3012a3bd7f05SmrgArrayPack(_Xconst _XtString name, XtPointer closure)
3013444c061aSmrg{
30140568f49bSmrg    _XtString prop = *(_XtString *) closure;
3015444c061aSmrg    SmProp *p;
3016444c061aSmrg
3017444c061aSmrg    p = (SmProp *) __XtMalloc(sizeof(SmProp) + sizeof(SmPropValue));
3018444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
3019444c061aSmrg    p->num_vals = 1;
3020a3bd7f05Smrg    p->type = (char *) SmARRAY8;
30210568f49bSmrg    p->name = (char *) name;
30220568f49bSmrg    p->vals->length = (int) strlen(prop) + 1;
3023444c061aSmrg    p->vals->value = prop;
3024444c061aSmrg    return p;
3025444c061aSmrg}
3026444c061aSmrg
3027a3bd7f05Smrgstatic SmProp *
3028a3bd7f05SmrgListPack(_Xconst _XtString name, XtPointer closure)
3029444c061aSmrg{
30300568f49bSmrg    _XtString *prop = *(_XtString **) closure;
3031444c061aSmrg    SmProp *p;
30320568f49bSmrg    _XtString *ptr;
3033444c061aSmrg    SmPropValue *vals;
3034444c061aSmrg    int n = 0;
3035444c061aSmrg
3036444c061aSmrg    for (ptr = prop; *ptr; ptr++)
3037a3bd7f05Smrg        n++;
3038a3bd7f05Smrg    p = (SmProp *)
3039a3bd7f05Smrg        __XtMalloc((Cardinal)
3040a3bd7f05Smrg                   (sizeof(SmProp) + (size_t) n * sizeof(SmPropValue)));
3041444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
3042444c061aSmrg    p->num_vals = n;
3043a3bd7f05Smrg    p->type = (char *) SmLISTofARRAY8;
3044a3bd7f05Smrg    p->name = (char *) name;
3045444c061aSmrg    for (ptr = prop, vals = p->vals; *ptr; ptr++, vals++) {
3046a3bd7f05Smrg        vals->length = (int) strlen(*ptr) + 1;
3047a3bd7f05Smrg        vals->value = *ptr;
3048444c061aSmrg    }
3049444c061aSmrg    return p;
3050444c061aSmrg}
3051444c061aSmrg
3052a3bd7f05Smrgstatic void
3053a3bd7f05SmrgFreePacks(SmProp ** props, int num_props)
3054444c061aSmrg{
3055444c061aSmrg    while (--num_props >= 0)
3056a3bd7f05Smrg        XtFree((char *) props[num_props]);
3057444c061aSmrg}
3058444c061aSmrg
3059a3bd7f05Smrgtypedef SmProp *(*PackProc) (_Xconst _XtString, XtPointer);
3060444c061aSmrg
3061444c061aSmrgtypedef struct PropertyRec {
3062a3bd7f05Smrg    String name;
3063a3bd7f05Smrg    int offset;
3064a3bd7f05Smrg    PackProc proc;
3065444c061aSmrg} PropertyRec, *PropertyTable;
3066444c061aSmrg
3067444c061aSmrg#define Offset(x) (XtOffsetOf(SessionShellRec, x))
3068a3bd7f05Smrg/* *INDENT-OFF* */
3069444c061aSmrgstatic PropertyRec propertyTable[] = {
3070444c061aSmrg  {SmCloneCommand,     Offset(session.clone_command),    ListPack},
3071444c061aSmrg  {SmCurrentDirectory, Offset(session.current_dir),      ArrayPack},
3072444c061aSmrg  {SmDiscardCommand,   Offset(session.discard_command),  ListPack},
3073444c061aSmrg  {SmEnvironment,      Offset(session.environment),      ListPack},
3074444c061aSmrg  {SmProgram,          Offset(session.program_path),     ArrayPack},
3075444c061aSmrg  {SmResignCommand,    Offset(session.resign_command),   ListPack},
3076444c061aSmrg  {SmRestartCommand,   Offset(session.restart_command),  ListPack},
3077444c061aSmrg  {SmRestartStyleHint, Offset(session.restart_style),    CardPack},
3078444c061aSmrg  {SmShutdownCommand,  Offset(session.shutdown_command), ListPack}
3079444c061aSmrg};
3080a3bd7f05Smrg/* *INDENT-ON* */
3081444c061aSmrg#undef Offset
3082444c061aSmrg
3083444c061aSmrg#define XT_NUM_SM_PROPS 11
3084444c061aSmrg
3085a3bd7f05Smrgstatic void
3086a3bd7f05SmrgSetSessionProperties(SessionShellWidget w,
3087a3bd7f05Smrg                     Boolean initialize,
3088a3bd7f05Smrg                     unsigned long set_mask,
3089a3bd7f05Smrg                     unsigned long unset_mask)
3090444c061aSmrg{
3091444c061aSmrg    PropertyTable p = propertyTable;
3092444c061aSmrg    int n;
3093444c061aSmrg    int num_props = 0;
3094444c061aSmrg    XtPointer *addr;
3095444c061aSmrg    unsigned long mask;
3096444c061aSmrg    SmProp *props[XT_NUM_SM_PROPS];
3097444c061aSmrg
3098444c061aSmrg    if (w->session.connection == NULL)
3099a3bd7f05Smrg        return;
3100444c061aSmrg
3101444c061aSmrg    if (initialize) {
3102a3bd7f05Smrg        char nam_buf[32];
3103a3bd7f05Smrg        char pid[12];
3104a3bd7f05Smrg        String user_name;
3105a3bd7f05Smrg        String pidp = pid;
3106a3bd7f05Smrg
3107a3bd7f05Smrg        /* set all non-NULL session properties, the UserID and the ProcessID */
3108a3bd7f05Smrg        for (n = XtNumber(propertyTable); n; n--, p++) {
3109a3bd7f05Smrg            addr = (XtPointer *) ((char *) w + p->offset);
3110a3bd7f05Smrg            if (p->proc == CardPack) {
3111a3bd7f05Smrg                if (*(unsigned char *) addr)
3112a3bd7f05Smrg                    props[num_props++] =
3113a3bd7f05Smrg                        (*(p->proc)) (p->name, (XtPointer) addr);
3114a3bd7f05Smrg            }
3115a3bd7f05Smrg            else if (*addr)
3116a3bd7f05Smrg                props[num_props++] = (*(p->proc)) (p->name, (XtPointer) addr);
3117a3bd7f05Smrg
3118a3bd7f05Smrg        }
3119a3bd7f05Smrg        user_name = _XtGetUserName(nam_buf, sizeof nam_buf);
3120a3bd7f05Smrg        if (user_name)
3121a3bd7f05Smrg            props[num_props++] = ArrayPack(SmUserID, &user_name);
3122a3bd7f05Smrg        snprintf(pid, sizeof(pid), "%ld", (long) getpid());
3123a3bd7f05Smrg        props[num_props++] = ArrayPack(SmProcessID, &pidp);
3124a3bd7f05Smrg
3125a3bd7f05Smrg        if (num_props) {
3126a3bd7f05Smrg            SmcSetProperties(w->session.connection, num_props, props);
3127a3bd7f05Smrg            FreePacks(props, num_props);
3128a3bd7f05Smrg        }
3129a3bd7f05Smrg        return;
3130444c061aSmrg    }
3131444c061aSmrg
3132444c061aSmrg    if (set_mask) {
3133a3bd7f05Smrg        mask = 1L;
3134a3bd7f05Smrg        for (n = XtNumber(propertyTable); n; n--, p++, mask <<= 1)
3135a3bd7f05Smrg            if (mask & set_mask) {
3136a3bd7f05Smrg                addr = (XtPointer *) ((char *) w + p->offset);
3137a3bd7f05Smrg                props[num_props++] = (*(p->proc)) (p->name, (XtPointer) addr);
3138a3bd7f05Smrg            }
3139a3bd7f05Smrg        SmcSetProperties(w->session.connection, num_props, props);
3140a3bd7f05Smrg        FreePacks(props, num_props);
3141444c061aSmrg    }
3142444c061aSmrg
3143444c061aSmrg    if (unset_mask) {
3144a3bd7f05Smrg        char *pnames[XT_NUM_SM_PROPS];
31450568f49bSmrg
3146a3bd7f05Smrg        mask = 1L;
3147a3bd7f05Smrg        num_props = 0;
3148a3bd7f05Smrg        for (n = XtNumber(propertyTable); n; n--, p++, mask <<= 1)
3149a3bd7f05Smrg            if (mask & unset_mask)
3150a3bd7f05Smrg                pnames[num_props++] = (char *) p->name;
3151a3bd7f05Smrg        SmcDeleteProperties(w->session.connection, num_props, pnames);
3152444c061aSmrg    }
3153444c061aSmrg}
3154444c061aSmrg
3155a3bd7f05Smrgstatic void
3156a3bd7f05SmrgGetIceEvent(XtPointer client_data,
3157a3bd7f05Smrg            int *source _X_UNUSED,
3158a3bd7f05Smrg            XtInputId *id _X_UNUSED)
3159444c061aSmrg{
3160444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3161444c061aSmrg    IceProcessMessagesStatus status;
3162444c061aSmrg
3163444c061aSmrg    status = IceProcessMessages(SmcGetIceConnection(w->session.connection),
3164a3bd7f05Smrg                                NULL, NULL);
3165444c061aSmrg
3166444c061aSmrg    if (status == IceProcessMessagesIOError) {
3167a3bd7f05Smrg        StopManagingSession(w, w->session.connection);
3168a3bd7f05Smrg        XtCallCallbackList((Widget) w, w->session.error_callbacks,
3169a3bd7f05Smrg                           (XtPointer) NULL);
3170444c061aSmrg    }
3171444c061aSmrg}
3172444c061aSmrg
3173a3bd7f05Smrgstatic void
3174a3bd7f05SmrgCleanUpSave(SessionShellWidget w)
3175444c061aSmrg{
3176444c061aSmrg    XtSaveYourself next = w->session.save->next;
3177a3bd7f05Smrg
3178a3bd7f05Smrg    XtFree((char *) w->session.save);
3179444c061aSmrg    w->session.save = next;
3180444c061aSmrg    if (w->session.save)
3181a3bd7f05Smrg        CallSaveCallbacks(w);
3182444c061aSmrg}
3183444c061aSmrg
3184a3bd7f05Smrgstatic void
3185a3bd7f05SmrgCallSaveCallbacks(SessionShellWidget w)
3186444c061aSmrg{
3187444c061aSmrg    if (XtHasCallbacks((Widget) w, XtNsaveCallback) != XtCallbackHasSome) {
3188a3bd7f05Smrg        /* if the application makes no attempt to save state, report failure */
3189a3bd7f05Smrg        SmcSaveYourselfDone(w->session.connection, False);
3190a3bd7f05Smrg        CleanUpSave(w);
3191a3bd7f05Smrg    }
3192a3bd7f05Smrg    else {
3193a3bd7f05Smrg        XtCheckpointToken token;
31940568f49bSmrg
3195a3bd7f05Smrg        w->session.checkpoint_state = XtSaveActive;
3196a3bd7f05Smrg        token = GetToken((Widget) w, XtSessionCheckpoint);
3197a3bd7f05Smrg        _XtCallConditionalCallbackList((Widget) w, w->session.save_callbacks,
3198a3bd7f05Smrg                                       (XtPointer) token, ExamineToken);
3199a3bd7f05Smrg        XtSessionReturnToken(token);
3200444c061aSmrg    }
3201444c061aSmrg}
3202444c061aSmrg
3203a3bd7f05Smrgstatic void
3204a3bd7f05SmrgXtCallSaveCallbacks(SmcConn connection _X_UNUSED,
3205a3bd7f05Smrg                    SmPointer client_data,
3206a3bd7f05Smrg                    int save_type,
3207a3bd7f05Smrg                    Bool shutdown,
3208a3bd7f05Smrg                    int interact,
3209a3bd7f05Smrg                    Bool fast)
3210444c061aSmrg{
3211444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3212444c061aSmrg    XtSaveYourself save;
3213444c061aSmrg    XtSaveYourself prev;
3214444c061aSmrg
3215444c061aSmrg    save = XtNew(XtSaveYourselfRec);
3216444c061aSmrg    save->next = NULL;
3217444c061aSmrg    save->save_type = save_type;
3218444c061aSmrg    save->interact_style = interact;
32190568f49bSmrg    save->shutdown = (Boolean) shutdown;
32200568f49bSmrg    save->fast = (Boolean) fast;
3221444c061aSmrg    save->cancel_shutdown = False;
3222444c061aSmrg    save->phase = 1;
3223444c061aSmrg    save->interact_dialog_type = SmDialogNormal;
3224444c061aSmrg    save->request_cancel = save->request_next_phase = False;
3225444c061aSmrg    save->save_success = True;
3226444c061aSmrg    save->save_tokens = save->interact_tokens = 0;
3227444c061aSmrg
3228444c061aSmrg    prev = (XtSaveYourself) &w->session.save;
3229444c061aSmrg    while (prev->next)
3230a3bd7f05Smrg        prev = prev->next;
3231444c061aSmrg    prev->next = save;
3232444c061aSmrg
3233444c061aSmrg    if (w->session.checkpoint_state == XtSaveInactive)
3234a3bd7f05Smrg        CallSaveCallbacks(w);
3235444c061aSmrg}
3236444c061aSmrg
3237a3bd7f05Smrgstatic void
3238a3bd7f05SmrgXtInteractPermission(SmcConn connection, SmPointer data)
3239444c061aSmrg{
3240444c061aSmrg    Widget w = (Widget) data;
3241444c061aSmrg    SessionShellWidget sw = (SessionShellWidget) data;
3242444c061aSmrg    XtCallbackProc callback;
3243444c061aSmrg    XtPointer client_data;
3244444c061aSmrg
3245a3bd7f05Smrg    _XtPeekCallback(w, sw->session.interact_callbacks, &callback, &client_data);
3246444c061aSmrg    if (callback) {
3247a3bd7f05Smrg        XtCheckpointToken token;
32480568f49bSmrg
3249a3bd7f05Smrg        sw->session.checkpoint_state = XtInteractActive;
3250a3bd7f05Smrg        token = GetToken(w, XtSessionInteract);
3251a3bd7f05Smrg        XtRemoveCallback(w, XtNinteractCallback, callback, client_data);
3252a3bd7f05Smrg        (*callback) (w, client_data, (XtPointer) token);
3253a3bd7f05Smrg    }
3254a3bd7f05Smrg    else if (!sw->session.save->cancel_shutdown) {
3255a3bd7f05Smrg        SmcInteractDone(connection, False);
3256444c061aSmrg    }
3257444c061aSmrg}
3258444c061aSmrg
3259a3bd7f05Smrgstatic void
3260a3bd7f05SmrgXtCallSaveCompleteCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3261444c061aSmrg{
3262a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) client_data;
3263444c061aSmrg
3264a3bd7f05Smrg    XtCallCallbackList((Widget) w, w->session.save_complete_callbacks,
3265a3bd7f05Smrg                       (XtPointer) NULL);
3266444c061aSmrg}
3267444c061aSmrg
3268a3bd7f05Smrgstatic void
3269a3bd7f05SmrgXtCallNextPhaseCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3270444c061aSmrg{
3271a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) client_data;
3272a3bd7f05Smrg
3273444c061aSmrg    w->session.save->phase = 2;
3274444c061aSmrg    CallSaveCallbacks(w);
3275444c061aSmrg}
3276444c061aSmrg
3277a3bd7f05Smrgstatic void
3278a3bd7f05SmrgXtCallDieCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3279444c061aSmrg{
3280a3bd7f05Smrg    SessionShellWidget w = (SessionShellWidget) client_data;
3281444c061aSmrg
3282444c061aSmrg    StopManagingSession(w, w->session.connection);
3283a3bd7f05Smrg    XtCallCallbackList((Widget) w, w->session.die_callbacks, (XtPointer) NULL);
3284444c061aSmrg}
3285444c061aSmrg
3286a3bd7f05Smrgstatic void
3287a3bd7f05SmrgXtCallCancelCallbacks(SmcConn connection _X_UNUSED, SmPointer client_data)
3288444c061aSmrg{
3289444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3290444c061aSmrg    Boolean call_interacts = False;
3291444c061aSmrg
3292444c061aSmrg    if (w->session.checkpoint_state != XtSaveInactive) {
3293a3bd7f05Smrg        w->session.save->cancel_shutdown = True;
3294a3bd7f05Smrg        call_interacts = (w->session.save->interact_style !=
3295a3bd7f05Smrg                          SmInteractStyleNone);
3296444c061aSmrg    }
3297444c061aSmrg
3298a3bd7f05Smrg    XtCallCallbackList((Widget) w, w->session.cancel_callbacks,
3299a3bd7f05Smrg                       (XtPointer) NULL);
3300444c061aSmrg
3301444c061aSmrg    if (call_interacts) {
3302a3bd7f05Smrg        w->session.save->interact_style = SmInteractStyleNone;
3303a3bd7f05Smrg        XtInteractPermission(w->session.connection, (SmPointer) w);
3304444c061aSmrg    }
3305444c061aSmrg
3306444c061aSmrg    if (w->session.checkpoint_state != XtSaveInactive) {
3307a3bd7f05Smrg        if (w->session.save->save_tokens == 0 &&
3308a3bd7f05Smrg            w->session.checkpoint_state == XtSaveActive) {
3309a3bd7f05Smrg            w->session.checkpoint_state = XtSaveInactive;
3310a3bd7f05Smrg            SmcSaveYourselfDone(w->session.connection,
3311a3bd7f05Smrg                                w->session.save->save_success);
3312a3bd7f05Smrg            CleanUpSave(w);
3313a3bd7f05Smrg        }
3314444c061aSmrg    }
3315444c061aSmrg}
3316444c061aSmrg
3317a3bd7f05Smrgstatic XtCheckpointToken
3318a3bd7f05SmrgGetToken(Widget widget, int type)
3319444c061aSmrg{
3320444c061aSmrg    SessionShellWidget w = (SessionShellWidget) widget;
3321444c061aSmrg    XtCheckpointToken token;
3322444c061aSmrg    XtSaveYourself save = w->session.save;
3323444c061aSmrg
3324444c061aSmrg    if (type == XtSessionCheckpoint)
3325a3bd7f05Smrg        w->session.save->save_tokens++;
3326444c061aSmrg    else if (type == XtSessionInteract)
3327a3bd7f05Smrg        w->session.save->interact_tokens++;
3328444c061aSmrg    else
3329a3bd7f05Smrg        return (XtCheckpointToken) NULL;
3330444c061aSmrg
3331444c061aSmrg    token = (XtCheckpointToken) __XtMalloc(sizeof(XtCheckpointTokenRec));
3332444c061aSmrg    token->save_type = save->save_type;
3333444c061aSmrg    token->interact_style = save->interact_style;
3334444c061aSmrg    token->shutdown = save->shutdown;
3335444c061aSmrg    token->fast = save->fast;
3336444c061aSmrg    token->cancel_shutdown = save->cancel_shutdown;
3337444c061aSmrg    token->phase = save->phase;
3338444c061aSmrg    token->interact_dialog_type = save->interact_dialog_type;
3339444c061aSmrg    token->request_cancel = save->request_cancel;
3340444c061aSmrg    token->request_next_phase = save->request_next_phase;
3341444c061aSmrg    token->save_success = save->save_success;
3342444c061aSmrg    token->type = type;
3343444c061aSmrg    token->widget = widget;
3344444c061aSmrg    return token;
3345444c061aSmrg}
3346444c061aSmrg
3347a3bd7f05SmrgXtCheckpointToken
3348a3bd7f05SmrgXtSessionGetToken(Widget widget)
3349444c061aSmrg{
3350444c061aSmrg    SessionShellWidget w = (SessionShellWidget) widget;
3351444c061aSmrg    XtCheckpointToken token = NULL;
3352a3bd7f05Smrg
3353444c061aSmrg    WIDGET_TO_APPCON(widget);
3354444c061aSmrg
3355444c061aSmrg    LOCK_APP(app);
3356444c061aSmrg    if (w->session.checkpoint_state)
3357a3bd7f05Smrg        token = GetToken(widget, XtSessionCheckpoint);
3358444c061aSmrg
3359444c061aSmrg    UNLOCK_APP(app);
3360444c061aSmrg    return token;
3361444c061aSmrg}
3362444c061aSmrg
3363a3bd7f05Smrgstatic Boolean
3364a3bd7f05SmrgExamineToken(XtPointer call_data)
3365444c061aSmrg{
3366444c061aSmrg    XtCheckpointToken token = (XtCheckpointToken) call_data;
3367444c061aSmrg    SessionShellWidget w = (SessionShellWidget) token->widget;
3368444c061aSmrg
3369444c061aSmrg    if (token->interact_dialog_type == SmDialogError)
3370a3bd7f05Smrg        w->session.save->interact_dialog_type = SmDialogError;
3371444c061aSmrg    if (token->request_next_phase)
3372a3bd7f05Smrg        w->session.save->request_next_phase = True;
3373a3bd7f05Smrg    if (!token->save_success)
3374a3bd7f05Smrg        w->session.save->save_success = False;
3375444c061aSmrg
3376444c061aSmrg    token->interact_dialog_type = w->session.save->interact_dialog_type;
3377444c061aSmrg    token->request_next_phase = w->session.save->request_next_phase;
3378444c061aSmrg    token->save_success = w->session.save->save_success;
3379444c061aSmrg    token->cancel_shutdown = w->session.save->cancel_shutdown;
3380444c061aSmrg
3381444c061aSmrg    return True;
3382444c061aSmrg}
3383444c061aSmrg
3384a3bd7f05Smrgvoid
3385a3bd7f05SmrgXtSessionReturnToken(XtCheckpointToken token)
3386444c061aSmrg{
3387444c061aSmrg    SessionShellWidget w = (SessionShellWidget) token->widget;
3388444c061aSmrg    Boolean has_some;
3389444c061aSmrg    Boolean phase_done;
3390444c061aSmrg    XtCallbackProc callback;
3391444c061aSmrg    XtPointer client_data;
3392a3bd7f05Smrg
3393a3bd7f05Smrg    WIDGET_TO_APPCON((Widget) w);
3394444c061aSmrg
3395444c061aSmrg    LOCK_APP(app);
3396444c061aSmrg
3397444c061aSmrg    has_some = (XtHasCallbacks(token->widget, XtNinteractCallback)
3398a3bd7f05Smrg                == XtCallbackHasSome);
3399444c061aSmrg
3400444c061aSmrg    (void) ExamineToken((XtPointer) token);
3401444c061aSmrg
3402444c061aSmrg    if (token->type == XtSessionCheckpoint) {
3403a3bd7f05Smrg        w->session.save->save_tokens--;
3404a3bd7f05Smrg        if (has_some && w->session.checkpoint_state == XtSaveActive) {
3405a3bd7f05Smrg            w->session.checkpoint_state = XtInteractPending;
3406a3bd7f05Smrg            SmcInteractRequest(w->session.connection,
3407a3bd7f05Smrg                               w->session.save->interact_dialog_type,
3408a3bd7f05Smrg                               XtInteractPermission, (SmPointer) w);
3409a3bd7f05Smrg        }
3410a3bd7f05Smrg        XtFree((char *) token);
3411a3bd7f05Smrg    }
3412a3bd7f05Smrg    else {
3413a3bd7f05Smrg        if (token->request_cancel)
3414a3bd7f05Smrg            w->session.save->request_cancel = True;
3415a3bd7f05Smrg        token->request_cancel = w->session.save->request_cancel;
3416a3bd7f05Smrg        if (has_some) {
3417a3bd7f05Smrg            _XtPeekCallback((Widget) w, w->session.interact_callbacks,
3418a3bd7f05Smrg                            &callback, &client_data);
3419a3bd7f05Smrg            XtRemoveCallback((Widget) w, XtNinteractCallback,
3420a3bd7f05Smrg                             callback, client_data);
3421a3bd7f05Smrg            (*callback) ((Widget) w, client_data, (XtPointer) token);
3422a3bd7f05Smrg        }
3423a3bd7f05Smrg        else {
3424a3bd7f05Smrg            w->session.save->interact_tokens--;
3425a3bd7f05Smrg            if (w->session.save->interact_tokens == 0) {
3426a3bd7f05Smrg                w->session.checkpoint_state = XtSaveActive;
3427a3bd7f05Smrg                if (!w->session.save->cancel_shutdown)
3428a3bd7f05Smrg                    SmcInteractDone(w->session.connection,
3429a3bd7f05Smrg                                    w->session.save->request_cancel);
3430a3bd7f05Smrg            }
3431a3bd7f05Smrg            XtFree((char *) token);
3432a3bd7f05Smrg        }
3433444c061aSmrg    }
3434444c061aSmrg
3435444c061aSmrg    phase_done = (w->session.save->save_tokens == 0 &&
3436a3bd7f05Smrg                  w->session.checkpoint_state == XtSaveActive);
3437444c061aSmrg
3438444c061aSmrg    if (phase_done) {
3439a3bd7f05Smrg        if (w->session.save->request_next_phase && w->session.save->phase == 1) {
3440a3bd7f05Smrg            SmcRequestSaveYourselfPhase2(w->session.connection,
3441a3bd7f05Smrg                                         XtCallNextPhaseCallbacks,
3442a3bd7f05Smrg                                         (SmPointer) w);
3443a3bd7f05Smrg        }
3444a3bd7f05Smrg        else {
3445a3bd7f05Smrg            w->session.checkpoint_state = XtSaveInactive;
3446a3bd7f05Smrg            SmcSaveYourselfDone(w->session.connection,
3447a3bd7f05Smrg                                w->session.save->save_success);
3448a3bd7f05Smrg            CleanUpSave(w);
3449a3bd7f05Smrg        }
3450444c061aSmrg    }
3451444c061aSmrg
3452444c061aSmrg    UNLOCK_APP(app);
3453444c061aSmrg}
3454444c061aSmrg
3455a3bd7f05Smrgstatic Boolean
3456a3bd7f05SmrgIsInArray(String str, _XtString *sarray)
3457444c061aSmrg{
3458444c061aSmrg    if (str == NULL || sarray == NULL)
3459a3bd7f05Smrg        return False;
3460444c061aSmrg    for (; *sarray; sarray++) {
3461a3bd7f05Smrg        if (strcmp(*sarray, str) == 0)
3462a3bd7f05Smrg            return True;
3463444c061aSmrg    }
3464444c061aSmrg    return False;
3465444c061aSmrg}
3466444c061aSmrg
3467a3bd7f05Smrgstatic _XtString *
3468a3bd7f05SmrgEditCommand(_XtString str,      /* if not NULL, the sm_client_id */
3469a3bd7f05Smrg            _XtString *src1,   /* first choice */
3470a3bd7f05Smrg            _XtString *src2)   /* alternate */
3471a3bd7f05Smrg{
3472444c061aSmrg    Boolean have;
3473444c061aSmrg    Boolean want;
3474444c061aSmrg    int count;
34750568f49bSmrg    _XtString *sarray;
34760568f49bSmrg    _XtString *s;
34770568f49bSmrg    _XtString *new;
3478444c061aSmrg
3479444c061aSmrg    want = (str != NULL);
3480444c061aSmrg    sarray = (src1 ? src1 : src2);
3481a3bd7f05Smrg    if (!sarray)
3482a3bd7f05Smrg        return NULL;
3483444c061aSmrg    have = IsInArray("-xtsessionID", sarray);
3484444c061aSmrg    if ((want && have) || (!want && !have)) {
3485a3bd7f05Smrg        if (sarray == src1)
3486a3bd7f05Smrg            return src1;
3487a3bd7f05Smrg        else
3488a3bd7f05Smrg            return NewStringArray(sarray);
3489444c061aSmrg    }
3490444c061aSmrg
3491444c061aSmrg    count = 0;
3492444c061aSmrg    for (s = sarray; *s; s++)
3493a3bd7f05Smrg        count++;
3494444c061aSmrg
3495444c061aSmrg    if (want) {
3496a3bd7f05Smrg        s = new = (_XtString *)
3497a3bd7f05Smrg            __XtMalloc((Cardinal) ((size_t) (count + 3) * sizeof(_XtString *)));
3498a3bd7f05Smrg        *s = *sarray;
3499a3bd7f05Smrg        s++;
3500a3bd7f05Smrg        sarray++;
3501a3bd7f05Smrg        *s = (_XtString) "-xtsessionID";
3502a3bd7f05Smrg        s++;
3503a3bd7f05Smrg        *s = str;
3504a3bd7f05Smrg        s++;
3505a3bd7f05Smrg        for (; --count > 0; s++, sarray++)
3506a3bd7f05Smrg            *s = *sarray;
3507a3bd7f05Smrg        *s = NULL;
3508a3bd7f05Smrg    }
3509a3bd7f05Smrg    else {
3510a3bd7f05Smrg        if (count < 3)
3511a3bd7f05Smrg            return NewStringArray(sarray);
3512a3bd7f05Smrg        s = new = (_XtString *)
3513a3bd7f05Smrg            __XtMalloc((Cardinal) ((size_t) (count - 1) * sizeof(_XtString *)));
3514a3bd7f05Smrg        for (; --count >= 0; sarray++) {
3515a3bd7f05Smrg            if (strcmp(*sarray, "-xtsessionID") == 0) {
3516a3bd7f05Smrg                sarray++;
3517a3bd7f05Smrg                count--;
3518a3bd7f05Smrg            }
3519a3bd7f05Smrg            else {
3520a3bd7f05Smrg                *s = *sarray;
3521a3bd7f05Smrg                s++;
3522a3bd7f05Smrg            }
3523a3bd7f05Smrg        }
3524a3bd7f05Smrg        *s = NULL;
3525444c061aSmrg    }
3526444c061aSmrg    s = new;
3527444c061aSmrg    new = NewStringArray(new);
3528a3bd7f05Smrg    XtFree((char *) s);
3529444c061aSmrg    return new;
3530444c061aSmrg}
3531444c061aSmrg
3532a3bd7f05Smrg#endif                          /* !XT_NO_SM */
3533