Shell.c revision 0568f49b
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
123444c061aSmrg#define Offset(x)	(XtOffsetOf(ShellRec, x))
124444c061aSmrgstatic XtResource shellResources[]=
125444c061aSmrg{
126444c061aSmrg	{XtNx, XtCPosition, XtRPosition, sizeof(Position),
127444c061aSmrg	    Offset(core.x), XtRImmediate, (XtPointer)BIGSIZE},
128444c061aSmrg	{XtNy, XtCPosition, XtRPosition, sizeof(Position),
129444c061aSmrg	    Offset(core.y), XtRImmediate, (XtPointer)BIGSIZE},
130444c061aSmrg	{ XtNdepth, XtCDepth, XtRInt, sizeof(int),
131444c061aSmrg	    Offset(core.depth), XtRCallProc, (XtPointer) _XtShellDepth},
132444c061aSmrg	{ XtNcolormap, XtCColormap, XtRColormap, sizeof(Colormap),
133444c061aSmrg	    Offset(core.colormap), XtRCallProc, (XtPointer) _XtShellColormap},
134444c061aSmrg	{ XtNancestorSensitive, XtCSensitive, XtRBoolean, sizeof(Boolean),
135444c061aSmrg	    Offset(core.ancestor_sensitive), XtRCallProc,
136444c061aSmrg	    (XtPointer) _XtShellAncestorSensitive},
137444c061aSmrg	{ XtNallowShellResize, XtCAllowShellResize, XtRBoolean,
138444c061aSmrg	    sizeof(Boolean), Offset(shell.allow_shell_resize),
139444c061aSmrg	    XtRImmediate, (XtPointer)False},
140444c061aSmrg	{ XtNgeometry, XtCGeometry, XtRString, sizeof(String),
141444c061aSmrg	    Offset(shell.geometry), XtRString, (XtPointer)NULL},
142444c061aSmrg	{ XtNcreatePopupChildProc, XtCCreatePopupChildProc, XtRFunction,
143444c061aSmrg	    sizeof(XtCreatePopupChildProc), Offset(shell.create_popup_child_proc),
144444c061aSmrg	    XtRFunction, NULL},
145444c061aSmrg	{ XtNsaveUnder, XtCSaveUnder, XtRBoolean, sizeof(Boolean),
146444c061aSmrg	    Offset(shell.save_under), XtRImmediate, (XtPointer)False},
147444c061aSmrg	{ XtNpopupCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
148444c061aSmrg	    Offset(shell.popup_callback), XtRCallback, (XtPointer) NULL},
149444c061aSmrg	{ XtNpopdownCallback, XtCCallback, XtRCallback, sizeof(XtCallbackList),
150444c061aSmrg	    Offset(shell.popdown_callback), XtRCallback, (XtPointer) NULL},
151444c061aSmrg	{ XtNoverrideRedirect, XtCOverrideRedirect,
152444c061aSmrg	    XtRBoolean, sizeof(Boolean), Offset(shell.override_redirect),
153444c061aSmrg	    XtRImmediate, (XtPointer)False},
154444c061aSmrg	{ XtNvisual, XtCVisual, XtRVisual, sizeof(Visual*),
1552265a131Smrg	    Offset(shell.visual), XtRImmediate, (XtPointer)CopyFromParent}
156444c061aSmrg};
157444c061aSmrg
158444c061aSmrgstatic void ClassPartInitialize(WidgetClass);
159444c061aSmrgstatic void Initialize(Widget, Widget, ArgList, Cardinal *);
160444c061aSmrgstatic void Realize(Widget, Mask *, XSetWindowAttributes *);
161444c061aSmrgstatic void Resize(Widget);
162444c061aSmrgstatic Boolean SetValues(Widget, Widget, Widget, ArgList , Cardinal *);
163444c061aSmrgstatic void GetValuesHook(Widget, ArgList, Cardinal*);
164444c061aSmrgstatic void ChangeManaged(Widget);
165444c061aSmrgstatic XtGeometryResult GeometryManager(Widget, XtWidgetGeometry *, XtWidgetGeometry *);
166444c061aSmrgstatic XtGeometryResult RootGeometryManager(Widget gw, XtWidgetGeometry *request, XtWidgetGeometry *reply);
167444c061aSmrgstatic void Destroy(Widget);
168444c061aSmrg
169444c061aSmrgstatic ShellClassExtensionRec shellClassExtRec = {
170444c061aSmrg    NULL,
171444c061aSmrg    NULLQUARK,
172444c061aSmrg    XtShellExtensionVersion,
173444c061aSmrg    sizeof(ShellClassExtensionRec),
174444c061aSmrg    RootGeometryManager
175444c061aSmrg};
176444c061aSmrg
177444c061aSmrgexternaldef(shellclassrec) ShellClassRec shellClassRec = {
178444c061aSmrg  {   /* Core */
179444c061aSmrg    /* superclass	  */	(WidgetClass) &compositeClassRec,
180444c061aSmrg    /* class_name	  */	"Shell",
181444c061aSmrg    /* size		  */	sizeof(ShellRec),
182444c061aSmrg    /* Class Initializer  */	NULL,
183444c061aSmrg    /* class_part_initialize*/	ClassPartInitialize,
184444c061aSmrg    /* Class init'ed ?	  */	FALSE,
185444c061aSmrg    /* initialize	  */	Initialize,
186444c061aSmrg    /* initialize_notify  */	NULL,
187444c061aSmrg    /* realize		  */	Realize,
188444c061aSmrg    /* actions		  */	NULL,
189444c061aSmrg    /* num_actions	  */	0,
190444c061aSmrg    /* resources	  */	shellResources,
191444c061aSmrg    /* resource_count	  */	XtNumber(shellResources),
192444c061aSmrg    /* xrm_class	  */	NULLQUARK,
193444c061aSmrg    /* compress_motion	  */	FALSE,
194444c061aSmrg    /* compress_exposure  */	TRUE,
195444c061aSmrg    /* compress_enterleave*/	FALSE,
196444c061aSmrg    /* visible_interest	  */	FALSE,
197444c061aSmrg    /* destroy		  */	Destroy,
198444c061aSmrg    /* resize		  */	Resize,
199444c061aSmrg    /* expose		  */	NULL,
200444c061aSmrg    /* set_values	  */	SetValues,
201444c061aSmrg    /* set_values_hook	  */	NULL,
202444c061aSmrg    /* set_values_almost  */	XtInheritSetValuesAlmost,
203444c061aSmrg    /* get_values_hook	  */	GetValuesHook,
204444c061aSmrg    /* accept_focus	  */	NULL,
205444c061aSmrg    /* intrinsics version */	XtVersion,
206444c061aSmrg    /* callback offsets	  */	NULL,
207444c061aSmrg    /* tm_table		  */	NULL,
208444c061aSmrg    /* query_geometry	  */	NULL,
209444c061aSmrg    /* display_accelerator*/	NULL,
210444c061aSmrg    /* extension	  */	NULL
211444c061aSmrg  },{ /* Composite */
212444c061aSmrg    /* geometry_manager	  */	GeometryManager,
213444c061aSmrg    /* change_managed	  */	ChangeManaged,
214444c061aSmrg    /* insert_child	  */	XtInheritInsertChild,
215444c061aSmrg    /* delete_child	  */	XtInheritDeleteChild,
216444c061aSmrg    /* extension	  */	NULL
217444c061aSmrg  },{ /* Shell */
218444c061aSmrg    /* extension	  */	(XtPointer)&shellClassExtRec
219444c061aSmrg  }
220444c061aSmrg};
221444c061aSmrg
222444c061aSmrgexternaldef(shellwidgetclass) WidgetClass shellWidgetClass = (WidgetClass) (&shellClassRec);
223444c061aSmrg
224444c061aSmrg/***************************************************************************
225444c061aSmrg *
226444c061aSmrg * OverrideShell class record
227444c061aSmrg *
228444c061aSmrg ***************************************************************************/
229444c061aSmrg
230444c061aSmrgstatic XtResource overrideResources[]=
231444c061aSmrg{
232444c061aSmrg	{ XtNoverrideRedirect, XtCOverrideRedirect,
233444c061aSmrg	    XtRBoolean, sizeof(Boolean), Offset(shell.override_redirect),
234444c061aSmrg	    XtRImmediate, (XtPointer)True},
235444c061aSmrg	{ XtNsaveUnder, XtCSaveUnder, XtRBoolean, sizeof(Boolean),
236444c061aSmrg	    Offset(shell.save_under), XtRImmediate, (XtPointer)True},
237444c061aSmrg};
238444c061aSmrg
239444c061aSmrgexternaldef(overrideshellclassrec) OverrideShellClassRec overrideShellClassRec = {
240444c061aSmrg  {
241444c061aSmrg    /* superclass         */    (WidgetClass) &shellClassRec,
242444c061aSmrg    /* class_name         */    "OverrideShell",
243444c061aSmrg    /* size               */    sizeof(OverrideShellRec),
244444c061aSmrg    /* Class Initializer  */	NULL,
245444c061aSmrg    /* class_part_initialize*/	NULL,
246444c061aSmrg    /* Class init'ed ?    */	FALSE,
247444c061aSmrg    /* initialize         */    NULL,
248444c061aSmrg    /* initialize_notify    */	NULL,
249444c061aSmrg    /* realize            */    XtInheritRealize,
250444c061aSmrg    /* actions            */    NULL,
251444c061aSmrg    /* num_actions        */    0,
252444c061aSmrg    /* resources          */    overrideResources,
253444c061aSmrg    /* resource_count     */	XtNumber(overrideResources),
254444c061aSmrg    /* xrm_class          */    NULLQUARK,
255444c061aSmrg    /* compress_motion    */    FALSE,
256444c061aSmrg    /* compress_exposure  */    TRUE,
257444c061aSmrg    /* compress_enterleave*/ 	FALSE,
258444c061aSmrg    /* visible_interest   */    FALSE,
259444c061aSmrg    /* destroy            */    NULL,
260444c061aSmrg    /* resize             */    XtInheritResize,
261444c061aSmrg    /* expose             */    NULL,
262444c061aSmrg    /* set_values         */    NULL,
263444c061aSmrg    /* set_values_hook      */	NULL,
264444c061aSmrg    /* set_values_almost    */	XtInheritSetValuesAlmost,
265444c061aSmrg    /* get_values_hook      */	NULL,
266444c061aSmrg    /* accept_focus       */    NULL,
267444c061aSmrg    /* intrinsics version */	XtVersion,
268444c061aSmrg    /* callback offsets   */    NULL,
269444c061aSmrg    /* tm_table		    */  NULL,
270444c061aSmrg    /* query_geometry	    */  NULL,
271444c061aSmrg    /* display_accelerator  */  NULL,
272444c061aSmrg    /* extension	    */  NULL
273444c061aSmrg  },{
274444c061aSmrg    /* geometry_manager   */    XtInheritGeometryManager,
275444c061aSmrg    /* change_managed     */    XtInheritChangeManaged,
276444c061aSmrg    /* insert_child	  */	XtInheritInsertChild,
277444c061aSmrg    /* delete_child	  */	XtInheritDeleteChild,
278444c061aSmrg    /* extension	    */  NULL
279444c061aSmrg  },{
280444c061aSmrg    /* extension	    */  NULL
281444c061aSmrg  },{
282444c061aSmrg    /* extension	    */  NULL
283444c061aSmrg  }
284444c061aSmrg};
285444c061aSmrg
286444c061aSmrgexternaldef(overrideshellwidgetclass) WidgetClass overrideShellWidgetClass =
287444c061aSmrg	(WidgetClass) (&overrideShellClassRec);
288444c061aSmrg
289444c061aSmrg/***************************************************************************
290444c061aSmrg *
291444c061aSmrg * WMShell class record
292444c061aSmrg *
293444c061aSmrg ***************************************************************************/
294444c061aSmrg
295444c061aSmrg#undef Offset
296444c061aSmrg#define Offset(x)	(XtOffsetOf(WMShellRec, x))
297444c061aSmrg
298444c061aSmrgstatic int default_unspecified_shell_int = XtUnspecifiedShellInt;
299444c061aSmrg/*
300444c061aSmrg * Warning, casting XtUnspecifiedShellInt (which is -1) to an (XtPointer)
301444c061aSmrg * can result is loss of bits on some machines (i.e. crays)
302444c061aSmrg */
303444c061aSmrg
304444c061aSmrgstatic XtResource wmResources[]=
305444c061aSmrg{
306444c061aSmrg	{ XtNtitle, XtCTitle, XtRString, sizeof(String),
307444c061aSmrg	    Offset(wm.title), XtRString, NULL},
308444c061aSmrg	{ XtNtitleEncoding, XtCTitleEncoding, XtRAtom, sizeof(Atom),
309444c061aSmrg	    Offset(wm.title_encoding),
310444c061aSmrg	    XtRCallProc, (XtPointer) _XtTitleEncoding},
311444c061aSmrg	{ XtNwmTimeout, XtCWmTimeout, XtRInt, sizeof(int),
312444c061aSmrg	    Offset(wm.wm_timeout), XtRImmediate,(XtPointer)DEFAULT_WM_TIMEOUT},
313444c061aSmrg	{ XtNwaitForWm, XtCWaitForWm, XtRBoolean, sizeof(Boolean),
314444c061aSmrg	    Offset(wm.wait_for_wm), XtRImmediate, (XtPointer)True},
315444c061aSmrg	{ XtNtransient, XtCTransient, XtRBoolean, sizeof(Boolean),
316444c061aSmrg	    Offset(wm.transient), XtRImmediate, (XtPointer)False},
317444c061aSmrg/* size_hints minus things stored in core */
318444c061aSmrg	{ XtNbaseWidth, XtCBaseWidth, XtRInt, sizeof(int),
319444c061aSmrg	    Offset(wm.base_width),
320444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
321444c061aSmrg	{ XtNbaseHeight, XtCBaseHeight, XtRInt, sizeof(int),
322444c061aSmrg	    Offset(wm.base_height),
323444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
324444c061aSmrg	{ XtNwinGravity, XtCWinGravity, XtRGravity, sizeof(int),
325444c061aSmrg	    Offset(wm.win_gravity),
326444c061aSmrg	    XtRGravity, (XtPointer) &default_unspecified_shell_int},
327444c061aSmrg	{ XtNminWidth, XtCMinWidth, XtRInt, sizeof(int),
328444c061aSmrg	    Offset(wm.size_hints.min_width),
329444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
330444c061aSmrg	{ XtNminHeight, XtCMinHeight, XtRInt, sizeof(int),
331444c061aSmrg	    Offset(wm.size_hints.min_height),
332444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
333444c061aSmrg	{ XtNmaxWidth, XtCMaxWidth, XtRInt, sizeof(int),
334444c061aSmrg	    Offset(wm.size_hints.max_width),
335444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
336444c061aSmrg	{ XtNmaxHeight, XtCMaxHeight, XtRInt, sizeof(int),
337444c061aSmrg	    Offset(wm.size_hints.max_height),
338444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
339444c061aSmrg	{ XtNwidthInc, XtCWidthInc, XtRInt, sizeof(int),
340444c061aSmrg	    Offset(wm.size_hints.width_inc),
341444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
342444c061aSmrg	{ XtNheightInc, XtCHeightInc, XtRInt, sizeof(int),
343444c061aSmrg	    Offset(wm.size_hints.height_inc),
344444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
345444c061aSmrg	{ XtNminAspectX, XtCMinAspectX, XtRInt, sizeof(int),
346444c061aSmrg	    Offset(wm.size_hints.min_aspect.x),
347444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
348444c061aSmrg	{ XtNminAspectY, XtCMinAspectY, XtRInt, sizeof(int),
349444c061aSmrg	    Offset(wm.size_hints.min_aspect.y),
350444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
351444c061aSmrg	{ XtNmaxAspectX, XtCMaxAspectX, XtRInt, sizeof(int),
352444c061aSmrg	    Offset(wm.size_hints.max_aspect.x),
353444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
354444c061aSmrg	{ XtNmaxAspectY, XtCMaxAspectY, XtRInt, sizeof(int),
355444c061aSmrg	    Offset(wm.size_hints.max_aspect.y),
356444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
357444c061aSmrg/* wm_hints */
358444c061aSmrg	{ XtNinput, XtCInput, XtRBool, sizeof(Bool),
359444c061aSmrg	    Offset(wm.wm_hints.input), XtRImmediate, (XtPointer)False},
360444c061aSmrg	{ XtNinitialState, XtCInitialState, XtRInitialState, sizeof(int),
361444c061aSmrg	    Offset(wm.wm_hints.initial_state),
362444c061aSmrg	    XtRImmediate, (XtPointer)NormalState},
363444c061aSmrg	{ XtNiconPixmap, XtCIconPixmap, XtRBitmap, sizeof(Pixmap),
364444c061aSmrg	    Offset(wm.wm_hints.icon_pixmap), XtRPixmap, NULL},
365444c061aSmrg	{ XtNiconWindow, XtCIconWindow, XtRWindow, sizeof(Window),
366444c061aSmrg	    Offset(wm.wm_hints.icon_window), XtRWindow,   (XtPointer) NULL},
367444c061aSmrg	{ XtNiconX, XtCIconX, XtRInt, sizeof(int),
368444c061aSmrg	    Offset(wm.wm_hints.icon_x),
369444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
370444c061aSmrg	{ XtNiconY, XtCIconY, XtRInt, sizeof(int),
371444c061aSmrg	    Offset(wm.wm_hints.icon_y),
372444c061aSmrg	    XtRInt, (XtPointer) &default_unspecified_shell_int},
373444c061aSmrg	{ XtNiconMask, XtCIconMask, XtRBitmap, sizeof(Pixmap),
374444c061aSmrg	    Offset(wm.wm_hints.icon_mask), XtRPixmap, NULL},
375444c061aSmrg	{ XtNwindowGroup, XtCWindowGroup, XtRWindow, sizeof(Window),
376444c061aSmrg	    Offset(wm.wm_hints.window_group),
377444c061aSmrg	    XtRImmediate, (XtPointer)XtUnspecifiedWindow},
378444c061aSmrg	{ XtNclientLeader, XtCClientLeader, XtRWidget, sizeof(Widget),
379444c061aSmrg	    Offset(wm.client_leader), XtRWidget, NULL},
380444c061aSmrg	{ XtNwindowRole, XtCWindowRole, XtRString, sizeof(String),
381444c061aSmrg	    Offset(wm.window_role), XtRString, (XtPointer) NULL},
382444c061aSmrg	{ XtNurgency, XtCUrgency, XtRBoolean, sizeof(Boolean),
383444c061aSmrg	    Offset(wm.urgency), XtRImmediate, (XtPointer) False}
384444c061aSmrg};
385444c061aSmrg
386444c061aSmrgstatic void WMInitialize(Widget, Widget, ArgList, Cardinal *);
387444c061aSmrgstatic Boolean WMSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
388444c061aSmrgstatic void WMDestroy(Widget);
389444c061aSmrg
390444c061aSmrgexternaldef(wmshellclassrec) WMShellClassRec wmShellClassRec = {
391444c061aSmrg  {
392444c061aSmrg    /* superclass         */    (WidgetClass) &shellClassRec,
393444c061aSmrg    /* class_name         */    "WMShell",
394444c061aSmrg    /* size               */    sizeof(WMShellRec),
395444c061aSmrg    /* Class Initializer  */	NULL,
396444c061aSmrg    /* class_part_initialize*/	NULL,
397444c061aSmrg    /* Class init'ed ?    */	FALSE,
398444c061aSmrg    /* initialize         */    WMInitialize,
399444c061aSmrg    /* initialize_notify    */	NULL,
400444c061aSmrg    /* realize            */    XtInheritRealize,
401444c061aSmrg    /* actions            */    NULL,
402444c061aSmrg    /* num_actions        */    0,
403444c061aSmrg    /* resources          */    wmResources,
404444c061aSmrg    /* resource_count     */	XtNumber(wmResources),
405444c061aSmrg    /* xrm_class          */    NULLQUARK,
406444c061aSmrg    /* compress_motion    */    FALSE,
407444c061aSmrg    /* compress_exposure  */    TRUE,
408444c061aSmrg    /* compress_enterleave*/	FALSE,
409444c061aSmrg    /* visible_interest   */    FALSE,
410444c061aSmrg    /* destroy            */    WMDestroy,
411444c061aSmrg    /* resize             */    XtInheritResize,
412444c061aSmrg    /* expose             */    NULL,
413444c061aSmrg    /* set_values         */    WMSetValues,
414444c061aSmrg    /* set_values_hook      */	NULL,
415444c061aSmrg    /* set_values_almost    */	XtInheritSetValuesAlmost,
416444c061aSmrg    /* get_values_hook      */	NULL,
417444c061aSmrg    /* accept_focus       */    NULL,
418444c061aSmrg    /* intrinsics version */	XtVersion,
419444c061aSmrg    /* callback offsets   */    NULL,
420444c061aSmrg    /* tm_table		    */  NULL,
421444c061aSmrg    /* query_geometry	    */  NULL,
422444c061aSmrg    /* display_accelerator  */  NULL,
423444c061aSmrg    /* extension	    */  NULL
424444c061aSmrg  },{
425444c061aSmrg    /* geometry_manager   */    XtInheritGeometryManager,
426444c061aSmrg    /* change_managed     */    XtInheritChangeManaged,
427444c061aSmrg    /* insert_child	  */	XtInheritInsertChild,
428444c061aSmrg    /* delete_child	  */	XtInheritDeleteChild,
429444c061aSmrg    /* extension	    */  NULL
430444c061aSmrg  },{
431444c061aSmrg    /* extension	    */  NULL
432444c061aSmrg  },{
433444c061aSmrg    /* extension	    */  NULL
434444c061aSmrg  }
435444c061aSmrg};
436444c061aSmrg
437444c061aSmrgexternaldef(wmshellwidgetclass) WidgetClass wmShellWidgetClass = (WidgetClass) (&wmShellClassRec);
438444c061aSmrg
439444c061aSmrg/***************************************************************************
440444c061aSmrg *
441444c061aSmrg * TransientShell class record
442444c061aSmrg *
443444c061aSmrg ***************************************************************************/
444444c061aSmrg
445444c061aSmrg#undef Offset
446444c061aSmrg#define Offset(x)	(XtOffsetOf(TransientShellRec, x))
447444c061aSmrg
448444c061aSmrgstatic XtResource transientResources[]=
449444c061aSmrg{
450444c061aSmrg	{ XtNtransient, XtCTransient, XtRBoolean, sizeof(Boolean),
451444c061aSmrg	    Offset(wm.transient), XtRImmediate, (XtPointer)True},
452444c061aSmrg	{ XtNtransientFor, XtCTransientFor, XtRWidget, sizeof(Widget),
453444c061aSmrg	    Offset(transient.transient_for), XtRWidget, NULL},
454444c061aSmrg	{ XtNsaveUnder, XtCSaveUnder, XtRBoolean, sizeof(Boolean),
455444c061aSmrg	    Offset(shell.save_under), XtRImmediate, (XtPointer)True},
456444c061aSmrg};
457444c061aSmrg
458444c061aSmrgstatic void TransientRealize(Widget, Mask *, XSetWindowAttributes *);
459444c061aSmrgstatic Boolean TransientSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
460444c061aSmrg
461444c061aSmrgexternaldef(transientshellclassrec) TransientShellClassRec transientShellClassRec = {
462444c061aSmrg  {
463444c061aSmrg    /* superclass	  */	(WidgetClass) &vendorShellClassRec,
464444c061aSmrg    /* class_name	  */	"TransientShell",
465444c061aSmrg    /* size		  */	sizeof(TransientShellRec),
466444c061aSmrg    /* Class Initializer  */	NULL,
467444c061aSmrg    /* class_part_initialize*/	NULL,
468444c061aSmrg    /* Class init'ed ?	  */	FALSE,
469444c061aSmrg    /* initialize	  */	NULL,
470444c061aSmrg    /* initialize_notify  */	NULL,
471444c061aSmrg    /* realize		  */	TransientRealize,
472444c061aSmrg    /* actions		  */	NULL,
473444c061aSmrg    /* num_actions	  */	0,
474444c061aSmrg    /* resources	  */	transientResources,
475444c061aSmrg    /* resource_count	  */	XtNumber(transientResources),
476444c061aSmrg    /* xrm_class	  */	NULLQUARK,
477444c061aSmrg    /* compress_motion	  */	FALSE,
478444c061aSmrg    /* compress_exposure  */	TRUE,
479444c061aSmrg    /* compress_enterleave*/	FALSE,
480444c061aSmrg    /* visible_interest	  */	FALSE,
481444c061aSmrg    /* destroy		  */	NULL,
482444c061aSmrg    /* resize		  */	XtInheritResize,
483444c061aSmrg    /* expose		  */	NULL,
484444c061aSmrg    /* set_values	  */	TransientSetValues,
485444c061aSmrg    /* set_values_hook	  */	NULL,
486444c061aSmrg    /* set_values_almost  */	XtInheritSetValuesAlmost,
487444c061aSmrg    /* get_values_hook	  */	NULL,
488444c061aSmrg    /* accept_focus	  */	NULL,
489444c061aSmrg    /* intrinsics version */	XtVersion,
490444c061aSmrg    /* callback offsets	  */	NULL,
491444c061aSmrg    /* tm_table		  */	XtInheritTranslations,
492444c061aSmrg    /* query_geometry	  */	NULL,
493444c061aSmrg    /* display_accelerator*/	NULL,
494444c061aSmrg    /* extension	  */	NULL
495444c061aSmrg  },{
496444c061aSmrg    /* geometry_manager	  */	XtInheritGeometryManager,
497444c061aSmrg    /* change_managed	  */	XtInheritChangeManaged,
498444c061aSmrg    /* insert_child	  */	XtInheritInsertChild,
499444c061aSmrg    /* delete_child	  */	XtInheritDeleteChild,
500444c061aSmrg    /* extension	  */	NULL
501444c061aSmrg  },{
502444c061aSmrg    /* extension	  */	NULL
503444c061aSmrg  },{
504444c061aSmrg    /* extension	  */	NULL
505444c061aSmrg  },{
506444c061aSmrg    /* extension	  */	NULL
507444c061aSmrg  },{
508444c061aSmrg    /* extension	  */	NULL
509444c061aSmrg  }
510444c061aSmrg};
511444c061aSmrg
512444c061aSmrgexternaldef(transientshellwidgetclass) WidgetClass transientShellWidgetClass =
513444c061aSmrg	(WidgetClass) (&transientShellClassRec);
514444c061aSmrg
515444c061aSmrg/***************************************************************************
516444c061aSmrg *
517444c061aSmrg * TopLevelShell class record
518444c061aSmrg *
519444c061aSmrg ***************************************************************************/
520444c061aSmrg
521444c061aSmrg#undef Offset
522444c061aSmrg#define Offset(x)	(XtOffsetOf(TopLevelShellRec, x))
523444c061aSmrg
524444c061aSmrgstatic XtResource topLevelResources[]=
525444c061aSmrg{
526444c061aSmrg	{ XtNiconName, XtCIconName, XtRString, sizeof(String),
527444c061aSmrg	    Offset(topLevel.icon_name), XtRString, (XtPointer) NULL},
528444c061aSmrg	{ XtNiconNameEncoding, XtCIconNameEncoding, XtRAtom, sizeof(Atom),
529444c061aSmrg	    Offset(topLevel.icon_name_encoding),
530444c061aSmrg	    XtRCallProc, (XtPointer) _XtTitleEncoding},
531444c061aSmrg	{ XtNiconic, XtCIconic, XtRBoolean, sizeof(Boolean),
532444c061aSmrg	    Offset(topLevel.iconic), XtRImmediate, (XtPointer)False}
533444c061aSmrg};
534444c061aSmrg
535444c061aSmrgstatic void TopLevelInitialize(Widget, Widget, ArgList, Cardinal *);
536444c061aSmrgstatic Boolean TopLevelSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
537444c061aSmrgstatic void TopLevelDestroy(Widget);
538444c061aSmrg
539444c061aSmrgexternaldef(toplevelshellclassrec) TopLevelShellClassRec topLevelShellClassRec = {
540444c061aSmrg  {
541444c061aSmrg    /* superclass         */    (WidgetClass) &vendorShellClassRec,
542444c061aSmrg    /* class_name         */    "TopLevelShell",
543444c061aSmrg    /* size               */    sizeof(TopLevelShellRec),
544444c061aSmrg    /* Class Initializer  */	NULL,
545444c061aSmrg    /* class_part_initialize*/	NULL,
546444c061aSmrg    /* Class init'ed ?    */	FALSE,
547444c061aSmrg    /* initialize         */    TopLevelInitialize,
548444c061aSmrg    /* initialize_notify    */	NULL,
549444c061aSmrg    /* realize            */    XtInheritRealize,
550444c061aSmrg    /* actions            */    NULL,
551444c061aSmrg    /* num_actions        */    0,
552444c061aSmrg    /* resources          */    topLevelResources,
553444c061aSmrg    /* resource_count     */	XtNumber(topLevelResources),
554444c061aSmrg    /* xrm_class          */    NULLQUARK,
555444c061aSmrg    /* compress_motion    */    FALSE,
556444c061aSmrg    /* compress_exposure  */    TRUE,
557444c061aSmrg    /* compress_enterleave*/ 	FALSE,
558444c061aSmrg    /* visible_interest   */    FALSE,
559444c061aSmrg    /* destroy            */    TopLevelDestroy,
560444c061aSmrg    /* resize             */    XtInheritResize,
561444c061aSmrg    /* expose             */    NULL,
562444c061aSmrg    /* set_values         */    TopLevelSetValues,
563444c061aSmrg    /* set_values_hook      */	NULL,
564444c061aSmrg    /* set_values_almost    */	XtInheritSetValuesAlmost,
565444c061aSmrg    /* get_values_hook      */	NULL,
566444c061aSmrg    /* accept_focus       */    NULL,
567444c061aSmrg    /* intrinsics version */	XtVersion,
568444c061aSmrg    /* callback offsets   */    NULL,
569444c061aSmrg    /* tm_table		    */  XtInheritTranslations,
570444c061aSmrg    /* query_geometry	    */  NULL,
571444c061aSmrg    /* display_accelerator  */  NULL,
572444c061aSmrg    /* extension	    */  NULL
573444c061aSmrg  },{
574444c061aSmrg    /* geometry_manager   */    XtInheritGeometryManager,
575444c061aSmrg    /* change_managed     */    XtInheritChangeManaged,
576444c061aSmrg    /* insert_child	  */	XtInheritInsertChild,
577444c061aSmrg    /* delete_child	  */	XtInheritDeleteChild,
578444c061aSmrg    /* extension	    */  NULL
579444c061aSmrg  },{
580444c061aSmrg    /* extension	    */  NULL
581444c061aSmrg  },{
582444c061aSmrg    /* extension	    */  NULL
583444c061aSmrg  },{
584444c061aSmrg    /* extension	    */  NULL
585444c061aSmrg  },{
586444c061aSmrg    /* extension	    */  NULL
587444c061aSmrg  }
588444c061aSmrg};
589444c061aSmrg
590444c061aSmrgexternaldef(toplevelshellwidgetclass) WidgetClass topLevelShellWidgetClass =
591444c061aSmrg	(WidgetClass) (&topLevelShellClassRec);
592444c061aSmrg
593444c061aSmrg/***************************************************************************
594444c061aSmrg *
595444c061aSmrg * ApplicationShell class record
596444c061aSmrg *
597444c061aSmrg ***************************************************************************/
598444c061aSmrg
599444c061aSmrg#undef Offset
600444c061aSmrg#define Offset(x)	(XtOffsetOf(ApplicationShellRec, x))
601444c061aSmrg
602444c061aSmrgstatic XtResource applicationResources[]=
603444c061aSmrg{
604444c061aSmrg    {XtNargc, XtCArgc, XtRInt, sizeof(int),
605444c061aSmrg	  Offset(application.argc), XtRImmediate, (XtPointer)0},
606444c061aSmrg    {XtNargv, XtCArgv, XtRStringArray, sizeof(String*),
607444c061aSmrg	  Offset(application.argv), XtRPointer, (XtPointer) NULL}
608444c061aSmrg};
609444c061aSmrg#undef Offset
610444c061aSmrg
611444c061aSmrgstatic void ApplicationInitialize(Widget, Widget, ArgList, Cardinal *);
612444c061aSmrgstatic void ApplicationDestroy(Widget);
613444c061aSmrgstatic Boolean ApplicationSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
614444c061aSmrgstatic void ApplicationShellInsertChild(Widget);
615444c061aSmrg
616444c061aSmrgstatic CompositeClassExtensionRec compositeClassExtension = {
617444c061aSmrg    /* next_extension	*/	NULL,
618444c061aSmrg    /* record_type	*/	NULLQUARK,
619444c061aSmrg    /* version		*/	XtCompositeExtensionVersion,
620444c061aSmrg    /* record_size	*/	sizeof(CompositeClassExtensionRec),
621444c061aSmrg    /* accepts_objects	*/	TRUE,
622444c061aSmrg    /* allows_change_managed_set */ FALSE
623444c061aSmrg};
624444c061aSmrg
625444c061aSmrg
626444c061aSmrgexternaldef(applicationshellclassrec) ApplicationShellClassRec applicationShellClassRec = {
627444c061aSmrg  {
628444c061aSmrg    /* superclass         */    (WidgetClass) &topLevelShellClassRec,
629444c061aSmrg    /* class_name         */    "ApplicationShell",
630444c061aSmrg    /* size               */    sizeof(ApplicationShellRec),
631444c061aSmrg    /* Class Initializer  */	NULL,
632444c061aSmrg    /* class_part_initialize*/	NULL,
633444c061aSmrg    /* Class init'ed ?    */	FALSE,
634444c061aSmrg    /* initialize         */    ApplicationInitialize,
635444c061aSmrg    /* initialize_notify  */	NULL,
636444c061aSmrg    /* realize            */    XtInheritRealize,
637444c061aSmrg    /* actions            */    NULL,
638444c061aSmrg    /* num_actions        */    0,
639444c061aSmrg    /* resources          */    applicationResources,
640444c061aSmrg    /* resource_count     */	XtNumber(applicationResources),
641444c061aSmrg    /* xrm_class          */    NULLQUARK,
642444c061aSmrg    /* compress_motion    */    FALSE,
643444c061aSmrg    /* compress_exposure  */    TRUE,
644444c061aSmrg    /* compress_enterleave*/    FALSE,
645444c061aSmrg    /* visible_interest   */    FALSE,
646444c061aSmrg    /* destroy            */    ApplicationDestroy,
647444c061aSmrg    /* resize             */    XtInheritResize,
648444c061aSmrg    /* expose             */    NULL,
649444c061aSmrg    /* set_values         */    ApplicationSetValues,
650444c061aSmrg    /* set_values_hook    */	NULL,
651444c061aSmrg    /* set_values_almost  */	XtInheritSetValuesAlmost,
652444c061aSmrg    /* get_values_hook    */	NULL,
653444c061aSmrg    /* accept_focus       */    NULL,
654444c061aSmrg    /* intrinsics version */	XtVersion,
655444c061aSmrg    /* callback offsets   */    NULL,
656444c061aSmrg    /* tm_table		  */	XtInheritTranslations,
657444c061aSmrg    /* query_geometry	  */	NULL,
658444c061aSmrg    /* display_accelerator*/	NULL,
659444c061aSmrg    /* extension	  */	NULL
660444c061aSmrg  },{
661444c061aSmrg    /* geometry_manager   */    XtInheritGeometryManager,
662444c061aSmrg    /* change_managed     */    XtInheritChangeManaged,
663444c061aSmrg    /* insert_child	  */	ApplicationShellInsertChild,
664444c061aSmrg    /* delete_child	  */	XtInheritDeleteChild,
665444c061aSmrg    /* extension	  */	(XtPointer)&compositeClassExtension
666444c061aSmrg  },{
667444c061aSmrg    /* extension	  */	NULL
668444c061aSmrg  },{
669444c061aSmrg    /* extension	  */	NULL
670444c061aSmrg  },{
671444c061aSmrg    /* extension	  */	NULL
672444c061aSmrg  },{
673444c061aSmrg    /* extension	  */	NULL
674444c061aSmrg  },{
675444c061aSmrg    /* extension	  */	NULL
676444c061aSmrg  }
677444c061aSmrg};
678444c061aSmrg
679444c061aSmrgexternaldef(applicationshellwidgetclass) WidgetClass applicationShellWidgetClass =
680444c061aSmrg	(WidgetClass) (&applicationShellClassRec);
681444c061aSmrg
682444c061aSmrg/***************************************************************************
683444c061aSmrg *
684444c061aSmrg * SessionShell class record
685444c061aSmrg *
686444c061aSmrg ***************************************************************************/
687444c061aSmrg
688444c061aSmrg#undef Offset
689444c061aSmrg#define Offset(x)	(XtOffsetOf(SessionShellRec, x))
690444c061aSmrg
691444c061aSmrgstatic XtResource sessionResources[]=
692444c061aSmrg{
693444c061aSmrg#ifndef XT_NO_SM
694444c061aSmrg {XtNconnection, XtCConnection, XtRSmcConn, sizeof(SmcConn),
695444c061aSmrg       Offset(session.connection), XtRSmcConn, (XtPointer) NULL},
696444c061aSmrg#endif
697444c061aSmrg {XtNsessionID, XtCSessionID, XtRString, sizeof(String),
698444c061aSmrg       Offset(session.session_id), XtRString, (XtPointer) NULL},
699444c061aSmrg {XtNrestartCommand, XtCRestartCommand, XtRCommandArgArray, sizeof(String*),
700444c061aSmrg       Offset(session.restart_command), XtRPointer, (XtPointer) NULL},
701444c061aSmrg {XtNcloneCommand, XtCCloneCommand, XtRCommandArgArray, sizeof(String*),
702444c061aSmrg       Offset(session.clone_command), XtRPointer, (XtPointer) NULL},
703444c061aSmrg {XtNdiscardCommand, XtCDiscardCommand, XtRCommandArgArray, sizeof(String*),
704444c061aSmrg       Offset(session.discard_command), XtRPointer, (XtPointer) NULL},
705444c061aSmrg {XtNresignCommand, XtCResignCommand, XtRCommandArgArray, sizeof(String*),
706444c061aSmrg       Offset(session.resign_command), XtRPointer, (XtPointer) NULL},
707444c061aSmrg {XtNshutdownCommand, XtCShutdownCommand, XtRCommandArgArray, sizeof(String*),
708444c061aSmrg       Offset(session.shutdown_command), XtRPointer, (XtPointer) NULL},
709444c061aSmrg {XtNenvironment, XtCEnvironment, XtREnvironmentArray, sizeof(String*),
710444c061aSmrg       Offset(session.environment), XtRPointer, (XtPointer) NULL},
711444c061aSmrg {XtNcurrentDirectory, XtCCurrentDirectory, XtRDirectoryString, sizeof(String),
712444c061aSmrg       Offset(session.current_dir), XtRString, (XtPointer) NULL},
713444c061aSmrg {XtNprogramPath, XtCProgramPath, XtRString, sizeof(String),
714444c061aSmrg      Offset(session.program_path), XtRString, (XtPointer) NULL},
715444c061aSmrg {XtNrestartStyle, XtCRestartStyle, XtRRestartStyle, sizeof(unsigned char),
716444c061aSmrg      Offset(session.restart_style), XtRImmediate,
717444c061aSmrg      (XtPointer) SmRestartIfRunning},
718444c061aSmrg {XtNjoinSession, XtCJoinSession, XtRBoolean, sizeof(Boolean),
719444c061aSmrg       Offset(session.join_session), XtRImmediate, (XtPointer) True},
720444c061aSmrg {XtNsaveCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
721444c061aSmrg       Offset(session.save_callbacks), XtRCallback, (XtPointer) NULL},
722444c061aSmrg {XtNinteractCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
723444c061aSmrg       Offset(session.interact_callbacks), XtRCallback, (XtPointer)NULL},
724444c061aSmrg {XtNcancelCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
725444c061aSmrg       Offset(session.cancel_callbacks), XtRCallback, (XtPointer) NULL},
726444c061aSmrg {XtNsaveCompleteCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
727444c061aSmrg       Offset(session.save_complete_callbacks), XtRCallback, (XtPointer) NULL},
728444c061aSmrg {XtNdieCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
729444c061aSmrg       Offset(session.die_callbacks), XtRCallback, (XtPointer) NULL},
730444c061aSmrg {XtNerrorCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
731444c061aSmrg       Offset(session.error_callbacks), XtRCallback, (XtPointer) NULL}
732444c061aSmrg};
733444c061aSmrg#undef Offset
734444c061aSmrg
735444c061aSmrgstatic void SessionInitialize(Widget, Widget, ArgList, Cardinal *);
736444c061aSmrgstatic void SessionDestroy(Widget);
737444c061aSmrgstatic Boolean SessionSetValues(Widget, Widget, Widget, ArgList, Cardinal *);
738444c061aSmrg
739444c061aSmrgstatic CompositeClassExtensionRec sessionCompositeClassExtension = {
740444c061aSmrg    /* next_extension	*/	NULL,
741444c061aSmrg    /* record_type	*/	NULLQUARK,
742444c061aSmrg    /* version		*/	XtCompositeExtensionVersion,
743444c061aSmrg    /* record_size	*/	sizeof(CompositeClassExtensionRec),
744444c061aSmrg    /* accepts_objects	*/	TRUE,
745444c061aSmrg    /* allows_change_managed_set */ FALSE
746444c061aSmrg};
747444c061aSmrg
748444c061aSmrg
749444c061aSmrgexternaldef(sessionshellclassrec) SessionShellClassRec sessionShellClassRec = {
750444c061aSmrg  {
751444c061aSmrg    /* superclass         */    (WidgetClass) &applicationShellClassRec,
752444c061aSmrg    /* class_name         */    "SessionShell",
753444c061aSmrg    /* size               */    sizeof(SessionShellRec),
754444c061aSmrg    /* Class Initializer  */	NULL,
755444c061aSmrg    /* class_part_initialize*/	NULL,
756444c061aSmrg    /* Class init'ed ?    */	FALSE,
757444c061aSmrg    /* initialize         */    SessionInitialize,
758444c061aSmrg    /* initialize_notify  */	NULL,
759444c061aSmrg    /* realize            */    XtInheritRealize,
760444c061aSmrg    /* actions            */    NULL,
761444c061aSmrg    /* num_actions        */    0,
762444c061aSmrg    /* resources          */    sessionResources,
763444c061aSmrg    /* resource_count     */	XtNumber(sessionResources),
764444c061aSmrg    /* xrm_class          */    NULLQUARK,
765444c061aSmrg    /* compress_motion    */    FALSE,
766444c061aSmrg    /* compress_exposure  */    TRUE,
767444c061aSmrg    /* compress_enterleave*/    FALSE,
768444c061aSmrg    /* visible_interest   */    FALSE,
769444c061aSmrg    /* destroy            */    SessionDestroy,
770444c061aSmrg    /* resize             */    XtInheritResize,
771444c061aSmrg    /* expose             */    NULL,
772444c061aSmrg    /* set_values         */    SessionSetValues,
773444c061aSmrg    /* set_values_hook    */	NULL,
774444c061aSmrg    /* set_values_almost  */	XtInheritSetValuesAlmost,
775444c061aSmrg    /* get_values_hook    */	NULL,
776444c061aSmrg    /* accept_focus       */    NULL,
777444c061aSmrg    /* intrinsics version */	XtVersion,
778444c061aSmrg    /* callback offsets   */    NULL,
779444c061aSmrg    /* tm_table		  */	XtInheritTranslations,
780444c061aSmrg    /* query_geometry	  */	NULL,
781444c061aSmrg    /* display_accelerator*/	NULL,
782444c061aSmrg    /* extension	  */	NULL
783444c061aSmrg  },{
784444c061aSmrg    /* geometry_manager   */    XtInheritGeometryManager,
785444c061aSmrg    /* change_managed     */    XtInheritChangeManaged,
786444c061aSmrg    /* insert_child	  */	XtInheritInsertChild,
787444c061aSmrg    /* delete_child	  */	XtInheritDeleteChild,
788444c061aSmrg    /* extension	  */	(XtPointer)&sessionCompositeClassExtension
789444c061aSmrg  },{
790444c061aSmrg    /* extension	  */	NULL
791444c061aSmrg  },{
792444c061aSmrg    /* extension	  */	NULL
793444c061aSmrg  },{
794444c061aSmrg    /* extension	  */	NULL
795444c061aSmrg  },{
796444c061aSmrg    /* extension	  */	NULL
797444c061aSmrg  },{
798444c061aSmrg    /* extension	  */	NULL
799444c061aSmrg  },{
800444c061aSmrg    /* extension          */    NULL
801444c061aSmrg  }
802444c061aSmrg};
803444c061aSmrg
804444c061aSmrgexternaldef(sessionshellwidgetclass) WidgetClass sessionShellWidgetClass =
805444c061aSmrg	(WidgetClass) (&sessionShellClassRec);
806444c061aSmrg
807444c061aSmrg/****************************************************************************
808444c061aSmrg * Whew!
809444c061aSmrg ****************************************************************************/
810444c061aSmrg
811444c061aSmrgstatic void ComputeWMSizeHints(
812444c061aSmrg    WMShellWidget w,
813444c061aSmrg    XSizeHints *hints)
814444c061aSmrg{
815444c061aSmrg    register long flags;
816444c061aSmrg    hints->flags = flags = w->wm.size_hints.flags;
817444c061aSmrg#define copy(field) hints->field = w->wm.size_hints.field
818444c061aSmrg    if (flags & (USPosition | PPosition)) {
819444c061aSmrg	copy(x);
820444c061aSmrg	copy(y);
821444c061aSmrg    }
822444c061aSmrg    if (flags & (USSize | PSize)) {
823444c061aSmrg	copy(width);
824444c061aSmrg	copy(height);
825444c061aSmrg    }
826444c061aSmrg    if (flags & PMinSize) {
827444c061aSmrg	copy(min_width);
828444c061aSmrg	copy(min_height);
829444c061aSmrg    }
830444c061aSmrg    if (flags & PMaxSize) {
831444c061aSmrg	copy(max_width);
832444c061aSmrg	copy(max_height);
833444c061aSmrg    }
834444c061aSmrg    if (flags & PResizeInc) {
835444c061aSmrg	copy(width_inc);
836444c061aSmrg	copy(height_inc);
837444c061aSmrg    }
838444c061aSmrg    if (flags & PAspect) {
839444c061aSmrg	copy(min_aspect.x);
840444c061aSmrg	copy(min_aspect.y);
841444c061aSmrg	copy(max_aspect.x);
842444c061aSmrg	copy(max_aspect.y);
843444c061aSmrg    }
844444c061aSmrg#undef copy
845444c061aSmrg#define copy(field) hints->field = w->wm.field
846444c061aSmrg    if (flags & PBaseSize) {
847444c061aSmrg	copy(base_width);
848444c061aSmrg	copy(base_height);
849444c061aSmrg    }
850444c061aSmrg    if (flags & PWinGravity)
851444c061aSmrg	copy(win_gravity);
852444c061aSmrg#undef copy
853444c061aSmrg}
854444c061aSmrg
855444c061aSmrgstatic void _SetWMSizeHints(
856444c061aSmrg    WMShellWidget w)
857444c061aSmrg{
858444c061aSmrg    XSizeHints *size_hints = XAllocSizeHints();
859444c061aSmrg
860444c061aSmrg    if (size_hints == NULL) _XtAllocError("XAllocSizeHints");
861444c061aSmrg    ComputeWMSizeHints(w, size_hints);
862444c061aSmrg    XSetWMNormalHints(XtDisplay((Widget)w), XtWindow((Widget)w), size_hints);
863444c061aSmrg    XFree((char*)size_hints);
864444c061aSmrg}
865444c061aSmrg
866444c061aSmrgstatic ShellClassExtension _FindClassExtension(
867444c061aSmrg    WidgetClass widget_class)
868444c061aSmrg{
869444c061aSmrg    ShellClassExtension ext;
870444c061aSmrg    for (ext = (ShellClassExtension)((ShellWidgetClass)widget_class)
871444c061aSmrg	       ->shell_class.extension;
872444c061aSmrg	 ext != NULL && ext->record_type != NULLQUARK;
873444c061aSmrg	 ext = (ShellClassExtension)ext->next_extension);
874444c061aSmrg
875444c061aSmrg    if (ext != NULL) {
876444c061aSmrg	if (  ext->version == XtShellExtensionVersion
877444c061aSmrg	      && ext->record_size == sizeof(ShellClassExtensionRec)) {
878444c061aSmrg	    /* continue */
879444c061aSmrg	} else {
880444c061aSmrg	    String params[1];
881444c061aSmrg	    Cardinal num_params = 1;
882444c061aSmrg	    params[0] = widget_class->core_class.class_name;
883444c061aSmrg	    XtErrorMsg( "invalidExtension", "shellClassPartInitialize",
884444c061aSmrg		        XtCXtToolkitError,
885444c061aSmrg		 "widget class %s has invalid ShellClassExtension record",
886444c061aSmrg		 params, &num_params);
887444c061aSmrg	}
888444c061aSmrg    }
889444c061aSmrg    return ext;
890444c061aSmrg}
891444c061aSmrg
892444c061aSmrgstatic void ClassPartInitialize(WidgetClass widget_class)
893444c061aSmrg{
894444c061aSmrg    ShellClassExtension ext = _FindClassExtension(widget_class);
895444c061aSmrg    if (ext != NULL) {
896444c061aSmrg	if (ext->root_geometry_manager == XtInheritRootGeometryManager) {
897444c061aSmrg	    ext->root_geometry_manager =
898444c061aSmrg		_FindClassExtension(widget_class->core_class.superclass)
899444c061aSmrg		    ->root_geometry_manager;
900444c061aSmrg	}
901444c061aSmrg    } else {
902444c061aSmrg	/* if not found, spec requires XtInheritRootGeometryManager */
903444c061aSmrg	XtPointer *extP
904444c061aSmrg	    = &((ShellWidgetClass)widget_class)->shell_class.extension;
905444c061aSmrg	ext = XtNew(ShellClassExtensionRec);
906444c061aSmrg	(void) memmove((char*)ext,
907444c061aSmrg		       (char*)_FindClassExtension(widget_class->core_class.superclass),
908444c061aSmrg		       sizeof(ShellClassExtensionRec));
909444c061aSmrg	ext->next_extension = *extP;
910444c061aSmrg	*extP = (XtPointer)ext;
911444c061aSmrg    }
912444c061aSmrg}
913444c061aSmrg
914444c061aSmrg
915444c061aSmrgstatic void EventHandler(Widget wid, XtPointer closure, XEvent *event, Boolean *continue_to_dispatch);
916444c061aSmrgstatic void _popup_set_prop(ShellWidget);
917444c061aSmrg
918444c061aSmrg
919444c061aSmrg/*ARGSUSED*/
920444c061aSmrgstatic void XtCopyDefaultDepth(
921444c061aSmrg    Widget      widget,
922444c061aSmrg    int		offset,
923444c061aSmrg    XrmValue    *value)
924444c061aSmrg{
925444c061aSmrg    value->addr = (XPointer)(&DefaultDepthOfScreen(XtScreenOfObject(widget)));
926444c061aSmrg}
927444c061aSmrg
928444c061aSmrgstatic
929444c061aSmrgvoid _XtShellDepth(
930444c061aSmrg    Widget widget,
931444c061aSmrg    int closure,
932444c061aSmrg    XrmValue *value)
933444c061aSmrg{
934444c061aSmrg   if (widget->core.parent == NULL) XtCopyDefaultDepth(widget,closure,value);
935444c061aSmrg   else _XtCopyFromParent (widget,closure,value);
936444c061aSmrg}
937444c061aSmrg
938444c061aSmrg/*ARGSUSED*/
939444c061aSmrgstatic void XtCopyDefaultColormap(
940444c061aSmrg    Widget      widget,
941444c061aSmrg    int		offset,
942444c061aSmrg    XrmValue    *value)
943444c061aSmrg{
944444c061aSmrg    value->addr = (XPointer)(&DefaultColormapOfScreen(XtScreenOfObject(widget)));
945444c061aSmrg}
946444c061aSmrg
947444c061aSmrgstatic
948444c061aSmrgvoid _XtShellColormap(
949444c061aSmrg    Widget widget,
950444c061aSmrg    int closure,
951444c061aSmrg    XrmValue *value)
952444c061aSmrg{
953444c061aSmrg   if (widget->core.parent == NULL)
954444c061aSmrg	   XtCopyDefaultColormap(widget,closure,value);
955444c061aSmrg   else _XtCopyFromParent (widget,closure,value);
956444c061aSmrg}
957444c061aSmrg
958444c061aSmrgstatic
959444c061aSmrgvoid _XtShellAncestorSensitive(
960444c061aSmrg    Widget widget,
961444c061aSmrg    int closure,
962444c061aSmrg    XrmValue *value)
963444c061aSmrg{
964444c061aSmrg   static Boolean true = True;
965444c061aSmrg   if (widget->core.parent == NULL) value->addr = (XPointer)(&true);
966444c061aSmrg   else _XtCopyFromParent (widget,closure,value);
967444c061aSmrg}
968444c061aSmrg
969444c061aSmrg/*ARGSUSED*/
970444c061aSmrgstatic
971444c061aSmrgvoid _XtTitleEncoding(
972444c061aSmrg    Widget widget,
973444c061aSmrg    int offset,
974444c061aSmrg    XrmValue *value)
975444c061aSmrg{
976444c061aSmrg    static Atom atom;
977444c061aSmrg    if (XtWidgetToApplicationContext(widget)->langProcRec.proc) atom = None;
978444c061aSmrg    else atom = XA_STRING;
979444c061aSmrg    value->addr = (XPointer) &atom;
980444c061aSmrg}
981444c061aSmrg
982444c061aSmrg
983444c061aSmrg/* ARGSUSED */
984444c061aSmrgstatic void Initialize(
985444c061aSmrg	Widget req,
986444c061aSmrg	Widget new,
987444c061aSmrg	ArgList args,		/* unused */
988444c061aSmrg	Cardinal *num_args)	/* unused */
989444c061aSmrg{
990444c061aSmrg	ShellWidget w = (ShellWidget) new;
991444c061aSmrg
992444c061aSmrg	w->shell.popped_up = FALSE;
993444c061aSmrg	w->shell.client_specified =
994444c061aSmrg	    _XtShellNotReparented | _XtShellPositionValid;
995444c061aSmrg
996444c061aSmrg	if (w->core.x == BIGSIZE) {
997444c061aSmrg	    w->core.x = 0;
998444c061aSmrg	    if (w->core.y == BIGSIZE) w->core.y = 0;
999444c061aSmrg	} else {
1000444c061aSmrg	    if (w->core.y == BIGSIZE) w->core.y = 0;
1001444c061aSmrg	    else w->shell.client_specified |= _XtShellPPositionOK;
1002444c061aSmrg	}
1003444c061aSmrg
1004444c061aSmrg	XtAddEventHandler(new, (EventMask) StructureNotifyMask,
1005444c061aSmrg		TRUE, EventHandler, (XtPointer) NULL);
1006444c061aSmrg
1007444c061aSmrg#ifdef EDITRES
1008444c061aSmrg	XtAddEventHandler(new, (EventMask) 0, TRUE,
1009444c061aSmrg			  _XEditResCheckMessages, NULL);
1010444c061aSmrg#endif
1011444c061aSmrg}
1012444c061aSmrg
1013444c061aSmrg/* ARGSUSED */
1014444c061aSmrgstatic void WMInitialize(
1015444c061aSmrg	Widget req, Widget new,
1016444c061aSmrg	ArgList args,		/* unused */
1017444c061aSmrg	Cardinal *num_args)	/* unused */
1018444c061aSmrg{
1019444c061aSmrg	WMShellWidget w = (WMShellWidget) new;
1020444c061aSmrg	TopLevelShellWidget tls = (TopLevelShellWidget) new;	/* maybe */
1021444c061aSmrg
1022444c061aSmrg	if(w->wm.title == NULL) {
1023444c061aSmrg	    if (XtIsTopLevelShell(new) &&
1024444c061aSmrg		    tls->topLevel.icon_name != NULL &&
1025444c061aSmrg		    strlen(tls->topLevel.icon_name) != 0) {
1026444c061aSmrg		w->wm.title = XtNewString(tls->topLevel.icon_name);
1027444c061aSmrg	    } else {
1028444c061aSmrg		w->wm.title = XtNewString(w->core.name);
1029444c061aSmrg	    }
1030444c061aSmrg	} else {
1031444c061aSmrg	    w->wm.title = XtNewString(w->wm.title);
1032444c061aSmrg	}
1033444c061aSmrg	w->wm.size_hints.flags = 0;
1034444c061aSmrg	w->wm.wm_hints.flags = 0;
1035444c061aSmrg	if (w->wm.window_role)
1036444c061aSmrg	    w->wm.window_role = XtNewString(w->wm.window_role);
1037444c061aSmrg}
1038444c061aSmrg
1039444c061aSmrg
1040444c061aSmrg/* ARGSUSED */
1041444c061aSmrgstatic void TopLevelInitialize(
1042444c061aSmrg	Widget req, Widget new,
1043444c061aSmrg	ArgList args,		/* unused */
1044444c061aSmrg	Cardinal *num_args)	/* unused */
1045444c061aSmrg{
1046444c061aSmrg	TopLevelShellWidget w = (TopLevelShellWidget) new;
1047444c061aSmrg
1048444c061aSmrg	if (w->topLevel.icon_name == NULL) {
1049444c061aSmrg	    w->topLevel.icon_name = XtNewString(w->core.name);
1050444c061aSmrg	} else {
1051444c061aSmrg	    w->topLevel.icon_name = XtNewString(w->topLevel.icon_name);
1052444c061aSmrg	}
1053444c061aSmrg
1054444c061aSmrg	if (w->topLevel.iconic)
1055444c061aSmrg	    w->wm.wm_hints.initial_state = IconicState;
1056444c061aSmrg}
1057444c061aSmrg
10580568f49bSmrgstatic _XtString *NewArgv(int, _XtString *);
10590568f49bSmrgstatic _XtString *NewStringArray(_XtString *);
10600568f49bSmrgstatic void FreeStringArray(_XtString *);
1061444c061aSmrg
1062444c061aSmrg/* ARGSUSED */
1063444c061aSmrgstatic void ApplicationInitialize(
1064444c061aSmrg    Widget req, Widget new,
1065444c061aSmrg    ArgList args,		/* unused */
1066444c061aSmrg    Cardinal *num_args)		/* unused */
1067444c061aSmrg{
1068444c061aSmrg    ApplicationShellWidget w = (ApplicationShellWidget)new;
1069444c061aSmrg
1070444c061aSmrg    if (w->application.argc > 0)
1071444c061aSmrg	w->application.argv = NewArgv(w->application.argc,
1072444c061aSmrg				      w->application.argv);
1073444c061aSmrg}
1074444c061aSmrg
1075444c061aSmrg#define XtSaveInactive 0
1076444c061aSmrg#define XtSaveActive   1
1077444c061aSmrg#define XtInteractPending    2
1078444c061aSmrg#define XtInteractActive     3
1079444c061aSmrg
1080444c061aSmrg#define XtCloneCommandMask	(1L<<0)
1081444c061aSmrg#define XtCurrentDirectoryMask	(1L<<1)
1082444c061aSmrg#define XtDiscardCommandMask	(1L<<2)
1083444c061aSmrg#define XtEnvironmentMask	(1L<<3)
1084444c061aSmrg#define XtProgramMask		(1L<<4)
1085444c061aSmrg#define XtResignCommandMask	(1L<<5)
1086444c061aSmrg#define XtRestartCommandMask	(1L<<6)
1087444c061aSmrg#define XtRestartStyleHintMask	(1L<<7)
1088444c061aSmrg#define XtShutdownCommandMask	(1L<<8)
1089444c061aSmrg
1090444c061aSmrgstatic void JoinSession(SessionShellWidget);
1091444c061aSmrgstatic void SetSessionProperties(SessionShellWidget, Boolean, unsigned long, unsigned long);
1092444c061aSmrgstatic void StopManagingSession(SessionShellWidget, SmcConn);
1093444c061aSmrg
1094444c061aSmrgtypedef struct _XtSaveYourselfRec {
1095444c061aSmrg    XtSaveYourself next;
1096444c061aSmrg    int            save_type;
1097444c061aSmrg    int            interact_style;
1098444c061aSmrg    Boolean        shutdown;
1099444c061aSmrg    Boolean        fast;
1100444c061aSmrg    Boolean        cancel_shutdown;
1101444c061aSmrg    int		   phase;
1102444c061aSmrg    int            interact_dialog_type;
1103444c061aSmrg    Boolean	   request_cancel;
1104444c061aSmrg    Boolean	   request_next_phase;
1105444c061aSmrg    Boolean        save_success;
1106444c061aSmrg    int            save_tokens;
1107444c061aSmrg    int            interact_tokens;
1108444c061aSmrg} XtSaveYourselfRec;
1109444c061aSmrg
1110444c061aSmrg/* ARGSUSED */
1111444c061aSmrgstatic void SessionInitialize(
1112444c061aSmrg    Widget req, Widget new,
1113444c061aSmrg    ArgList args,		/* unused */
1114444c061aSmrg    Cardinal *num_args)		/* unused */
1115444c061aSmrg{
1116444c061aSmrg#ifndef XT_NO_SM
1117444c061aSmrg    SessionShellWidget w = (SessionShellWidget)new;
1118444c061aSmrg
1119444c061aSmrg    if (w->session.session_id) w->session.session_id =
1120444c061aSmrg	XtNewString(w->session.session_id);
1121444c061aSmrg    if (w->session.restart_command) w->session.restart_command =
1122444c061aSmrg	NewStringArray(w->session.restart_command);
1123444c061aSmrg    if (w->session.clone_command) w->session.clone_command =
1124444c061aSmrg	NewStringArray(w->session.clone_command);
1125444c061aSmrg    if (w->session.discard_command) w->session.discard_command =
1126444c061aSmrg	NewStringArray(w->session.discard_command);
1127444c061aSmrg    if (w->session.resign_command) w->session.resign_command =
1128444c061aSmrg	NewStringArray(w->session.resign_command);
1129444c061aSmrg    if (w->session.shutdown_command) w->session.shutdown_command =
1130444c061aSmrg	NewStringArray(w->session.shutdown_command);
1131444c061aSmrg    if (w->session.environment) w->session.environment =
1132444c061aSmrg	NewStringArray(w->session.environment);
1133444c061aSmrg    if (w->session.current_dir) w->session.current_dir =
1134444c061aSmrg	XtNewString(w->session.current_dir);
1135444c061aSmrg    if (w->session.program_path) w->session.program_path =
1136444c061aSmrg	XtNewString(w->session.program_path);
1137444c061aSmrg
1138444c061aSmrg    w->session.checkpoint_state = XtSaveInactive;
1139444c061aSmrg    w->session.input_id = 0;
1140444c061aSmrg    w->session.save = NULL;
1141444c061aSmrg
1142444c061aSmrg    if ((w->session.join_session) &&
1143444c061aSmrg	(w->application.argv || w->session.restart_command))
1144444c061aSmrg	JoinSession(w);
1145444c061aSmrg
1146444c061aSmrg    if (w->session.connection)
1147444c061aSmrg	SetSessionProperties(w, True, 0L, 0L);
1148444c061aSmrg#endif /* !XT_NO_SM */
1149444c061aSmrg}
1150444c061aSmrg
1151444c061aSmrgstatic void Resize(
1152444c061aSmrg    Widget w)
1153444c061aSmrg{
1154444c061aSmrg    register ShellWidget sw = (ShellWidget)w;
1155444c061aSmrg    Widget childwid;
1156444c061aSmrg    Cardinal i;
1157444c061aSmrg    for(i = 0; i < sw->composite.num_children; i++) {
1158444c061aSmrg        if (XtIsManaged(sw->composite.children[i])) {
1159444c061aSmrg             childwid = sw->composite.children[i];
1160444c061aSmrg             XtResizeWidget(childwid, sw->core.width, sw->core.height,
1161444c061aSmrg                           childwid->core.border_width);
1162444c061aSmrg	     break;		/* can only be one managed child */
1163444c061aSmrg        }
1164444c061aSmrg    }
1165444c061aSmrg}
1166444c061aSmrg
1167444c061aSmrgstatic void GetGeometry(Widget, Widget);
1168444c061aSmrg
1169444c061aSmrgstatic void Realize(
1170444c061aSmrg	Widget wid,
1171444c061aSmrg	Mask *vmask,
1172444c061aSmrg	XSetWindowAttributes *attr)
1173444c061aSmrg{
1174444c061aSmrg	ShellWidget w = (ShellWidget) wid;
1175444c061aSmrg        Mask mask = *vmask;
1176444c061aSmrg
1177444c061aSmrg	if (! (w->shell.client_specified & _XtShellGeometryParsed)) {
1178444c061aSmrg	    /* we'll get here only if there was no child the first
1179444c061aSmrg	       time we were realized.  If the shell was Unrealized
1180444c061aSmrg	       and then re-Realized, we probably don't want to
1181444c061aSmrg	       re-evaluate the defaults anyway.
1182444c061aSmrg	     */
1183444c061aSmrg	    GetGeometry(wid, (Widget)NULL);
1184444c061aSmrg	}
1185444c061aSmrg	else if (w->core.background_pixmap == XtUnspecifiedPixmap) {
1186444c061aSmrg	    /* I attempt to inherit my child's background to avoid screen flash
1187444c061aSmrg	     * if there is latency between when I get resized and when my child
1188444c061aSmrg	     * is resized.  Background=None is not satisfactory, as I want the
1189444c061aSmrg	     * user to get immediate feedback on the new dimensions (most
1190444c061aSmrg	     * particularly in the case of a non-reparenting wm).  It is
1191444c061aSmrg	     * especially important to have the server clear any old cruft
1192444c061aSmrg	     * from the display when I am resized larger.
1193444c061aSmrg	     */
1194444c061aSmrg	    register Widget *childP = w->composite.children;
1195444c061aSmrg	    int i;
11960568f49bSmrg	    for (i = (int) w->composite.num_children; i; i--, childP++) {
1197444c061aSmrg		if (XtIsWidget(*childP) && XtIsManaged(*childP)) {
1198444c061aSmrg		    if ((*childP)->core.background_pixmap
1199444c061aSmrg			    != XtUnspecifiedPixmap) {
12000568f49bSmrg			mask &= (unsigned long) (~(CWBackPixel));
1201444c061aSmrg			mask |= CWBackPixmap;
1202444c061aSmrg			attr->background_pixmap =
1203444c061aSmrg			    w->core.background_pixmap =
1204444c061aSmrg				(*childP)->core.background_pixmap;
1205444c061aSmrg		    } else {
1206444c061aSmrg			attr->background_pixel =
1207444c061aSmrg			    w->core.background_pixel =
1208444c061aSmrg				(*childP)->core.background_pixel;
1209444c061aSmrg		    }
1210444c061aSmrg		    break;
1211444c061aSmrg		}
1212444c061aSmrg	    }
1213444c061aSmrg	}
1214444c061aSmrg
1215444c061aSmrg	if(w->shell.save_under) {
1216444c061aSmrg		mask |= CWSaveUnder;
1217444c061aSmrg		attr->save_under = TRUE;
1218444c061aSmrg	}
1219444c061aSmrg	if(w->shell.override_redirect) {
1220444c061aSmrg		mask |= CWOverrideRedirect;
1221444c061aSmrg		attr->override_redirect = TRUE;
1222444c061aSmrg	}
1223444c061aSmrg	if (wid->core.width == 0 || wid->core.height == 0) {
1224444c061aSmrg	    Cardinal count = 1;
1225444c061aSmrg	    XtErrorMsg("invalidDimension", "shellRealize", XtCXtToolkitError,
1226444c061aSmrg		       "Shell widget %s has zero width and/or height",
1227444c061aSmrg		       &wid->core.name, &count);
1228444c061aSmrg	}
1229444c061aSmrg	wid->core.window = XCreateWindow(XtDisplay(wid),
1230444c061aSmrg		wid->core.screen->root, (int)wid->core.x, (int)wid->core.y,
1231444c061aSmrg		(unsigned int)wid->core.width, (unsigned int)wid->core.height,
1232444c061aSmrg		(unsigned int)wid->core.border_width, (int) wid->core.depth,
1233444c061aSmrg		(unsigned int) InputOutput, w->shell.visual,
1234444c061aSmrg		mask, attr);
1235444c061aSmrg
1236444c061aSmrg	_popup_set_prop(w);
1237444c061aSmrg}
1238444c061aSmrg
1239444c061aSmrg
1240444c061aSmrgstatic void _SetTransientForHint(
1241444c061aSmrg     TransientShellWidget w,
1242444c061aSmrg     Boolean delete)
1243444c061aSmrg{
1244444c061aSmrg    Window window_group;
1245444c061aSmrg
1246444c061aSmrg    if (w->wm.transient) {
1247444c061aSmrg	if (w->transient.transient_for != NULL
1248444c061aSmrg	    && XtIsRealized(w->transient.transient_for))
1249444c061aSmrg	    window_group = XtWindow(w->transient.transient_for);
1250444c061aSmrg	else if ((window_group = w->wm.wm_hints.window_group)
1251444c061aSmrg		 == XtUnspecifiedWindowGroup) {
1252444c061aSmrg	    if (delete)
1253444c061aSmrg		XDeleteProperty( XtDisplay((Widget)w),
1254444c061aSmrg				 XtWindow((Widget)w),
1255444c061aSmrg				 XA_WM_TRANSIENT_FOR
1256444c061aSmrg				);
1257444c061aSmrg	    return;
1258444c061aSmrg	}
1259444c061aSmrg
1260444c061aSmrg	XSetTransientForHint( XtDisplay((Widget)w),
1261444c061aSmrg			      XtWindow((Widget)w),
1262444c061aSmrg			      window_group
1263444c061aSmrg			     );
1264444c061aSmrg    }
1265444c061aSmrg}
1266444c061aSmrg
1267444c061aSmrg
1268444c061aSmrgstatic void TransientRealize(
1269444c061aSmrg     Widget w,
1270444c061aSmrg     Mask *vmask,
1271444c061aSmrg     XSetWindowAttributes *attr)
1272444c061aSmrg{
1273444c061aSmrg    XtRealizeProc realize;
1274444c061aSmrg
1275444c061aSmrg    LOCK_PROCESS;
1276444c061aSmrg    realize =
1277444c061aSmrg	transientShellWidgetClass->core_class.superclass->core_class.realize;
1278444c061aSmrg    UNLOCK_PROCESS;
1279444c061aSmrg    (*realize) (w, vmask, attr);
1280444c061aSmrg
1281444c061aSmrg    _SetTransientForHint((TransientShellWidget)w, False);
1282444c061aSmrg}
1283444c061aSmrg
1284444c061aSmrgstatic Widget GetClientLeader(
1285444c061aSmrg    Widget w)
1286444c061aSmrg{
1287444c061aSmrg    while ((! XtIsWMShell(w) || ! ((WMShellWidget)w)->wm.client_leader)
1288444c061aSmrg	   && w->core.parent)
1289444c061aSmrg	w = w->core.parent;
1290444c061aSmrg
1291444c061aSmrg    /* ASSERT: w is a WMshell with client_leader set, or w has no parent */
1292444c061aSmrg
1293444c061aSmrg    if (XtIsWMShell(w) && ((WMShellWidget)w)->wm.client_leader)
1294444c061aSmrg	w = ((WMShellWidget)w)->wm.client_leader;
1295444c061aSmrg    return w;
1296444c061aSmrg}
1297444c061aSmrg
1298444c061aSmrgstatic void EvaluateWMHints(
1299444c061aSmrg    WMShellWidget w)
1300444c061aSmrg{
1301444c061aSmrg	XWMHints *hintp = &w->wm.wm_hints;
1302444c061aSmrg
1303444c061aSmrg	hintp->flags = StateHint | InputHint;
1304444c061aSmrg
1305444c061aSmrg	if (hintp->icon_x == XtUnspecifiedShellInt)
1306444c061aSmrg	    hintp->icon_x = -1;
1307444c061aSmrg	else
1308444c061aSmrg	    hintp->flags |= IconPositionHint;
1309444c061aSmrg
1310444c061aSmrg	if (hintp->icon_y == XtUnspecifiedShellInt)
1311444c061aSmrg	    hintp->icon_y = -1;
1312444c061aSmrg	else
1313444c061aSmrg	    hintp->flags |= IconPositionHint;
1314444c061aSmrg
1315444c061aSmrg	if (hintp->icon_pixmap != None) hintp->flags |= IconPixmapHint;
1316444c061aSmrg	if (hintp->icon_mask != None)   hintp->flags |= IconMaskHint;
1317444c061aSmrg	if (hintp->icon_window != None) hintp->flags |= IconWindowHint;
1318444c061aSmrg
1319444c061aSmrg	if (hintp->window_group == XtUnspecifiedWindow) {
1320444c061aSmrg	    if(w->core.parent) {
1321444c061aSmrg		Widget p;
1322444c061aSmrg		for (p = w->core.parent; p->core.parent; p = p->core.parent);
1323444c061aSmrg		if (XtIsRealized(p)) {
1324444c061aSmrg		    hintp->window_group = XtWindow(p);
1325444c061aSmrg		    hintp->flags |=  WindowGroupHint;
1326444c061aSmrg		}
1327444c061aSmrg	    }
1328444c061aSmrg	} else if (hintp->window_group != XtUnspecifiedWindowGroup)
1329444c061aSmrg	    hintp->flags |=  WindowGroupHint;
1330444c061aSmrg
1331444c061aSmrg	if (w->wm.urgency) hintp->flags |= XUrgencyHint;
1332444c061aSmrg}
1333444c061aSmrg
1334444c061aSmrg
1335444c061aSmrgstatic void EvaluateSizeHints(
1336444c061aSmrg    WMShellWidget w)
1337444c061aSmrg{
1338444c061aSmrg	struct _OldXSizeHints *sizep = &w->wm.size_hints;
1339444c061aSmrg
1340444c061aSmrg	sizep->x = w->core.x;
1341444c061aSmrg	sizep->y = w->core.y;
1342444c061aSmrg	sizep->width = w->core.width;
1343444c061aSmrg	sizep->height = w->core.height;
1344444c061aSmrg
1345444c061aSmrg	if (sizep->flags & USSize) {
1346444c061aSmrg	    if (sizep->flags & PSize) sizep->flags &= ~PSize;
1347444c061aSmrg	} else
1348444c061aSmrg	    sizep->flags |= PSize;
1349444c061aSmrg
1350444c061aSmrg	if (sizep->flags & USPosition) {
1351444c061aSmrg	    if (sizep->flags & PPosition) sizep->flags &= ~PPosition;
1352444c061aSmrg	} else if (w->shell.client_specified & _XtShellPPositionOK)
1353444c061aSmrg	    sizep->flags |= PPosition;
1354444c061aSmrg
1355444c061aSmrg	if (sizep->min_aspect.x != XtUnspecifiedShellInt
1356444c061aSmrg	    || sizep->min_aspect.y != XtUnspecifiedShellInt
1357444c061aSmrg	    || sizep->max_aspect.x != XtUnspecifiedShellInt
1358444c061aSmrg	    || sizep->max_aspect.y != XtUnspecifiedShellInt) {
1359444c061aSmrg	    sizep->flags |= PAspect;
1360444c061aSmrg	}
1361444c061aSmrg	if (sizep->flags & PBaseSize
1362444c061aSmrg	    || w->wm.base_width != XtUnspecifiedShellInt
1363444c061aSmrg	    || w->wm.base_height != XtUnspecifiedShellInt) {
1364444c061aSmrg	    sizep->flags |= PBaseSize;
1365444c061aSmrg	    if (w->wm.base_width == XtUnspecifiedShellInt)
1366444c061aSmrg		w->wm.base_width = 0;
1367444c061aSmrg	    if (w->wm.base_height == XtUnspecifiedShellInt)
1368444c061aSmrg		w->wm.base_height = 0;
1369444c061aSmrg	}
1370444c061aSmrg	if (sizep->flags & PResizeInc
1371444c061aSmrg	    || sizep->width_inc != XtUnspecifiedShellInt
1372444c061aSmrg	    || sizep->height_inc != XtUnspecifiedShellInt) {
1373444c061aSmrg	    if (sizep->width_inc < 1) sizep->width_inc = 1;
1374444c061aSmrg	    if (sizep->height_inc < 1) sizep->height_inc = 1;
1375444c061aSmrg	    sizep->flags |= PResizeInc;
1376444c061aSmrg	}
1377444c061aSmrg	if (sizep->flags & PMaxSize
1378444c061aSmrg	    || sizep->max_width != XtUnspecifiedShellInt
1379444c061aSmrg	    || sizep->max_height != XtUnspecifiedShellInt) {
1380444c061aSmrg	    sizep->flags |= PMaxSize;
1381444c061aSmrg	    if (sizep->max_width == XtUnspecifiedShellInt)
1382444c061aSmrg		sizep->max_width = BIGSIZE;
1383444c061aSmrg	    if (sizep->max_height == XtUnspecifiedShellInt)
1384444c061aSmrg		sizep->max_height = BIGSIZE;
1385444c061aSmrg	}
1386444c061aSmrg	if (sizep->flags & PMinSize
1387444c061aSmrg	    || sizep->min_width != XtUnspecifiedShellInt
1388444c061aSmrg	    || sizep->min_height != XtUnspecifiedShellInt) {
1389444c061aSmrg	    sizep->flags |= PMinSize;
1390444c061aSmrg	    if (sizep->min_width == XtUnspecifiedShellInt)
1391444c061aSmrg		sizep->min_width = 1;
1392444c061aSmrg	    if (sizep->min_height == XtUnspecifiedShellInt)
1393444c061aSmrg		sizep->min_height = 1;
1394444c061aSmrg	}
1395444c061aSmrg}
1396444c061aSmrg
1397444c061aSmrgstatic void _popup_set_prop(
1398444c061aSmrg	ShellWidget w)
1399444c061aSmrg{
1400444c061aSmrg	Widget p;
1401444c061aSmrg	WMShellWidget wmshell = (WMShellWidget) w;
1402444c061aSmrg	TopLevelShellWidget tlshell = (TopLevelShellWidget) w;
1403444c061aSmrg	ApplicationShellWidget appshell = (ApplicationShellWidget) w;
1404444c061aSmrg	XTextProperty icon_name;
1405444c061aSmrg	XTextProperty window_name;
1406444c061aSmrg	char **argv;
1407444c061aSmrg	int argc;
1408444c061aSmrg	XSizeHints *size_hints;
1409444c061aSmrg	Window window_group;
1410444c061aSmrg	XClassHint classhint;
1411444c061aSmrg	Boolean copied_iname, copied_wname;
1412444c061aSmrg
1413444c061aSmrg	if (!XtIsWMShell((Widget)w) || w->shell.override_redirect) return;
1414444c061aSmrg
1415444c061aSmrg	if ((size_hints = XAllocSizeHints()) == NULL)
1416444c061aSmrg	    _XtAllocError("XAllocSizeHints");
1417444c061aSmrg
1418444c061aSmrg	copied_iname = copied_wname = False;
1419444c061aSmrg        if (wmshell->wm.title_encoding == None &&
1420444c061aSmrg	    XmbTextListToTextProperty(XtDisplay((Widget)w),
1421444c061aSmrg				      (char**)&wmshell->wm.title,
1422444c061aSmrg				      1, XStdICCTextStyle,
1423444c061aSmrg				      &window_name) >= Success) {
1424444c061aSmrg	    copied_wname = True;
1425444c061aSmrg	} else {
1426444c061aSmrg	    window_name.value = (unsigned char*)wmshell->wm.title;
1427444c061aSmrg	    window_name.encoding = wmshell->wm.title_encoding ?
1428444c061aSmrg		wmshell->wm.title_encoding : XA_STRING;
1429444c061aSmrg	    window_name.format = 8;
1430444c061aSmrg	    window_name.nitems = strlen((char *)window_name.value);
1431444c061aSmrg	}
1432444c061aSmrg
1433444c061aSmrg	if (XtIsTopLevelShell((Widget)w)) {
1434444c061aSmrg            if (tlshell->topLevel.icon_name_encoding == None &&
1435444c061aSmrg		XmbTextListToTextProperty(XtDisplay((Widget)w),
1436444c061aSmrg					  (char**)&tlshell->topLevel.icon_name,
1437444c061aSmrg					  1, XStdICCTextStyle,
1438444c061aSmrg					  &icon_name) >= Success) {
1439444c061aSmrg		copied_iname = True;
1440444c061aSmrg	    } else {
1441444c061aSmrg		icon_name.value = (unsigned char*)tlshell->topLevel.icon_name;
1442444c061aSmrg		icon_name.encoding = tlshell->topLevel.icon_name_encoding ?
1443444c061aSmrg		    tlshell->topLevel.icon_name_encoding : XA_STRING;
1444444c061aSmrg		icon_name.format = 8;
1445444c061aSmrg		icon_name.nitems = strlen((char *)icon_name.value);
1446444c061aSmrg	    }
1447444c061aSmrg	}
1448444c061aSmrg
1449444c061aSmrg	EvaluateWMHints(wmshell);
1450444c061aSmrg	EvaluateSizeHints(wmshell);
1451444c061aSmrg	ComputeWMSizeHints(wmshell, size_hints);
1452444c061aSmrg
1453444c061aSmrg	if (wmshell->wm.transient
1454444c061aSmrg	    && !XtIsTransientShell((Widget)w)
1455444c061aSmrg	    && (window_group = wmshell->wm.wm_hints.window_group)
1456444c061aSmrg	       != XtUnspecifiedWindowGroup) {
1457444c061aSmrg
1458444c061aSmrg	    XSetTransientForHint(XtDisplay((Widget)w),
1459444c061aSmrg				 XtWindow((Widget)w),
1460444c061aSmrg				 window_group
1461444c061aSmrg				 );
1462444c061aSmrg	}
1463444c061aSmrg
14640568f49bSmrg	classhint.res_name = (_XtString) w->core.name;
1465444c061aSmrg	/* For the class, look up to the top of the tree */
1466444c061aSmrg	for (p = (Widget)w; p->core.parent != NULL; p = p->core.parent);
1467444c061aSmrg	if (XtIsApplicationShell(p)) {
1468444c061aSmrg	    classhint.res_class =
1469444c061aSmrg		((ApplicationShellWidget)p)->application.class;
1470444c061aSmrg	} else {
1471444c061aSmrg	    LOCK_PROCESS;
14720568f49bSmrg	    classhint.res_class = (_XtString) XtClass(p)->core_class.class_name;
1473444c061aSmrg	    UNLOCK_PROCESS;
1474444c061aSmrg	}
1475444c061aSmrg
1476444c061aSmrg	if (XtIsApplicationShell((Widget)w)
1477444c061aSmrg	    && (argc = appshell->application.argc) != -1)
1478444c061aSmrg	    argv = (char**)appshell->application.argv;
1479444c061aSmrg	else {
1480444c061aSmrg	    argv = NULL;
1481444c061aSmrg	    argc = 0;
1482444c061aSmrg	}
1483444c061aSmrg
1484444c061aSmrg	XSetWMProperties(XtDisplay((Widget)w), XtWindow((Widget)w),
1485444c061aSmrg			 &window_name,
1486444c061aSmrg			 (XtIsTopLevelShell((Widget)w)) ? &icon_name : NULL,
1487444c061aSmrg			 argv, argc,
1488444c061aSmrg			 size_hints,
1489444c061aSmrg			 &wmshell->wm.wm_hints,
1490444c061aSmrg			 &classhint);
1491444c061aSmrg	XFree((char*)size_hints);
1492444c061aSmrg	if (copied_wname)
1493444c061aSmrg	    XFree((XPointer)window_name.value);
1494444c061aSmrg	if (copied_iname)
1495444c061aSmrg	    XFree((XPointer)icon_name.value);
1496444c061aSmrg
1497444c061aSmrg	LOCK_PROCESS;
1498444c061aSmrg	if (XtWidgetToApplicationContext((Widget)w)->langProcRec.proc) {
1499444c061aSmrg	    char *locale = setlocale(LC_CTYPE, (char *)NULL);
1500444c061aSmrg	    if (locale)
1501444c061aSmrg		XChangeProperty(XtDisplay((Widget)w), XtWindow((Widget)w),
1502444c061aSmrg				XInternAtom(XtDisplay((Widget)w),
1503444c061aSmrg					    "WM_LOCALE_NAME", False),
1504444c061aSmrg				XA_STRING, 8, PropModeReplace,
15050568f49bSmrg				(unsigned char *)locale, (int) strlen(locale));
1506444c061aSmrg	}
1507444c061aSmrg	UNLOCK_PROCESS;
1508444c061aSmrg
1509444c061aSmrg	p = GetClientLeader((Widget)w);
1510444c061aSmrg	if (XtWindow(p))
1511444c061aSmrg	    XChangeProperty(XtDisplay((Widget)w), XtWindow((Widget)w),
1512444c061aSmrg			    XInternAtom(XtDisplay((Widget)w),
1513444c061aSmrg					"WM_CLIENT_LEADER", False),
1514444c061aSmrg			    XA_WINDOW, 32, PropModeReplace,
1515444c061aSmrg			    (unsigned char *)(&(p->core.window)), 1);
1516444c061aSmrg#ifndef XT_NO_SM
1517444c061aSmrg	if (p == (Widget) w) {
1518444c061aSmrg	    for ( ; p->core.parent != NULL; p = p->core.parent);
1519444c061aSmrg	    if (XtIsSubclass(p, sessionShellWidgetClass)) {
1520444c061aSmrg		String sm_client_id =
1521444c061aSmrg		    ((SessionShellWidget)p)->session.session_id;
1522444c061aSmrg		if (sm_client_id != NULL) {
1523444c061aSmrg		    XChangeProperty(XtDisplay((Widget)w), XtWindow((Widget)w),
1524444c061aSmrg				    XInternAtom(XtDisplay((Widget)w),
1525444c061aSmrg						"SM_CLIENT_ID", False),
1526444c061aSmrg				    XA_STRING, 8, PropModeReplace,
1527444c061aSmrg				    (unsigned char *) sm_client_id,
15280568f49bSmrg				    (int) strlen(sm_client_id));
1529444c061aSmrg		}
1530444c061aSmrg	    }
1531444c061aSmrg	}
1532444c061aSmrg#endif /* !XT_NO_SM */
1533444c061aSmrg
1534444c061aSmrg	if (wmshell->wm.window_role)
1535444c061aSmrg	    XChangeProperty(XtDisplay((Widget)w), XtWindow((Widget)w),
1536444c061aSmrg			    XInternAtom(XtDisplay((Widget)w),
1537444c061aSmrg					"WM_WINDOW_ROLE", False),
1538444c061aSmrg			    XA_STRING, 8, PropModeReplace,
1539444c061aSmrg			    (unsigned char *)wmshell->wm.window_role,
15400568f49bSmrg			    (int) strlen(wmshell->wm.window_role));
1541444c061aSmrg}
1542444c061aSmrg
1543444c061aSmrg/* ARGSUSED */
1544444c061aSmrgstatic void EventHandler(
1545444c061aSmrg	Widget wid,
1546444c061aSmrg	XtPointer closure,	/* unused */
1547444c061aSmrg	XEvent *event,
1548444c061aSmrg        Boolean *continue_to_dispatch) /* unused */
1549444c061aSmrg{
1550444c061aSmrg	register ShellWidget w = (ShellWidget) wid;
1551444c061aSmrg	WMShellWidget wmshell = (WMShellWidget) w;
1552444c061aSmrg	Boolean  sizechanged = FALSE;
1553444c061aSmrg
1554444c061aSmrg	if(w->core.window != event->xany.window) {
1555444c061aSmrg		XtAppErrorMsg(XtWidgetToApplicationContext(wid),
1556444c061aSmrg			"invalidWindow","eventHandler",XtCXtToolkitError,
1557444c061aSmrg                        "Event with wrong window",
15580568f49bSmrg			NULL, NULL);
1559444c061aSmrg		return;
1560444c061aSmrg	}
1561444c061aSmrg
1562444c061aSmrg	switch(event->type) {
1563444c061aSmrg	    case ConfigureNotify:
1564444c061aSmrg	        if (w->core.window != event->xconfigure.window)
1565444c061aSmrg		    return;  /* in case of SubstructureNotify */
1566444c061aSmrg#define NEQ(x)	( w->core.x != event->xconfigure.x )
1567444c061aSmrg		if( NEQ(width) || NEQ(height) || NEQ(border_width) ) {
1568444c061aSmrg			sizechanged = TRUE;
1569444c061aSmrg#undef NEQ
15700568f49bSmrg			w->core.width = (Dimension) event->xconfigure.width;
15710568f49bSmrg			w->core.height = (Dimension) event->xconfigure.height;
15720568f49bSmrg			w->core.border_width = (Dimension) event->xconfigure.border_width;
1573444c061aSmrg		}
1574444c061aSmrg		if (event->xany.send_event /* ICCCM compliant synthetic ev */
1575444c061aSmrg		    /* || w->shell.override_redirect */
1576444c061aSmrg		    || w->shell.client_specified & _XtShellNotReparented)
1577444c061aSmrg	        {
15780568f49bSmrg		    w->core.x = (Position) event->xconfigure.x;
15790568f49bSmrg		    w->core.y = (Position) event->xconfigure.y;
1580444c061aSmrg		    w->shell.client_specified |= _XtShellPositionValid;
1581444c061aSmrg		}
1582444c061aSmrg		else w->shell.client_specified &= ~_XtShellPositionValid;
1583444c061aSmrg		if (XtIsWMShell(wid) && !wmshell->wm.wait_for_wm) {
1584444c061aSmrg		    /* Consider trusting the wm again */
1585444c061aSmrg		    register struct _OldXSizeHints *hintp
1586444c061aSmrg			= &wmshell->wm.size_hints;
1587444c061aSmrg#define EQ(x) (hintp->x == w->core.x)
1588444c061aSmrg		    if (EQ(x) && EQ(y) && EQ(width) && EQ(height)) {
1589444c061aSmrg			wmshell->wm.wait_for_wm = TRUE;
1590444c061aSmrg		    }
1591444c061aSmrg#undef EQ
1592444c061aSmrg		}
1593444c061aSmrg		break;
1594444c061aSmrg
1595444c061aSmrg	      case ReparentNotify:
1596444c061aSmrg		if (event->xreparent.window == XtWindow(w)) {
1597444c061aSmrg		   if (event->xreparent.parent !=
1598444c061aSmrg		       RootWindowOfScreen(XtScreen(w)))
1599444c061aSmrg		       w->shell.client_specified &=
1600444c061aSmrg			   ~(_XtShellNotReparented | _XtShellPositionValid);
1601444c061aSmrg		   else {
16020568f49bSmrg		       w->core.x = (Position) event->xreparent.x;
16030568f49bSmrg		       w->core.y = (Position) event->xreparent.y;
1604444c061aSmrg		       w->shell.client_specified |=
1605444c061aSmrg			   (_XtShellNotReparented | _XtShellPositionValid);
1606444c061aSmrg		   }
1607444c061aSmrg	        }
1608444c061aSmrg		return;
1609444c061aSmrg
1610444c061aSmrg              case MapNotify:
1611444c061aSmrg                if (XtIsTopLevelShell(wid)) {
1612444c061aSmrg                    ((TopLevelShellWidget)wid)->topLevel.iconic = FALSE;
1613444c061aSmrg                }
1614444c061aSmrg                return;
1615444c061aSmrg
1616444c061aSmrg	      case UnmapNotify:
1617444c061aSmrg		{
1618444c061aSmrg		    XtPerDisplayInput	pdi;
1619444c061aSmrg		    XtDevice		device;
1620444c061aSmrg		    Widget		p;
1621444c061aSmrg
1622444c061aSmrg                    if (XtIsTopLevelShell(wid))
1623444c061aSmrg                        ((TopLevelShellWidget)wid)->topLevel.iconic = TRUE;
1624444c061aSmrg
1625444c061aSmrg		    pdi = _XtGetPerDisplayInput(event->xunmap.display);
1626444c061aSmrg
1627444c061aSmrg		    device = &pdi->pointer;
1628444c061aSmrg		    if (device->grabType == XtPassiveServerGrab) {
1629444c061aSmrg			p = device->grab.widget;
1630444c061aSmrg			while (p && !(XtIsShell(p)))
1631444c061aSmrg			    p = p->core.parent;
1632444c061aSmrg			if (p == wid)
1633444c061aSmrg			    device->grabType = XtNoServerGrab;
1634444c061aSmrg		    }
1635444c061aSmrg
1636444c061aSmrg		    device = &pdi->keyboard;
1637444c061aSmrg		    if (IsEitherPassiveGrab(device->grabType)) {
1638444c061aSmrg			p = device->grab.widget;
1639444c061aSmrg			while (p && !(XtIsShell(p)))
1640444c061aSmrg			    p = p->core.parent;
1641444c061aSmrg			if (p == wid) {
1642444c061aSmrg			    device->grabType = XtNoServerGrab;
1643444c061aSmrg			    pdi->activatingKey = 0;
1644444c061aSmrg			}
1645444c061aSmrg		    }
1646444c061aSmrg
1647444c061aSmrg		    return;
1648444c061aSmrg		}
1649444c061aSmrg	      default:
1650444c061aSmrg		 return;
1651444c061aSmrg	}
1652444c061aSmrg	{
1653444c061aSmrg	XtWidgetProc resize;
1654444c061aSmrg
1655444c061aSmrg	LOCK_PROCESS;
1656444c061aSmrg	resize = XtClass(wid)->core_class.resize;
1657444c061aSmrg	UNLOCK_PROCESS;
1658444c061aSmrg
1659444c061aSmrg	if (sizechanged && resize) {
1660444c061aSmrg	    CALLGEOTAT(_XtGeoTrace((Widget)w,
1661444c061aSmrg			   "Shell \"%s\" is being resized to %d %d.\n",
1662444c061aSmrg			   XtName(wid), wid->core.width, wid->core.height ));
1663444c061aSmrg	    (*resize)(wid);
1664444c061aSmrg	 }
1665444c061aSmrg	}
1666444c061aSmrg}
1667444c061aSmrg
1668444c061aSmrgstatic void Destroy(
1669444c061aSmrg	Widget wid)
1670444c061aSmrg{
1671444c061aSmrg	if (XtIsRealized(wid))
1672444c061aSmrg	    XDestroyWindow( XtDisplay(wid), XtWindow(wid) );
1673444c061aSmrg}
1674444c061aSmrg
1675444c061aSmrgstatic void WMDestroy(
1676444c061aSmrg	Widget wid)
1677444c061aSmrg{
1678444c061aSmrg	WMShellWidget w = (WMShellWidget) wid;
1679444c061aSmrg
1680444c061aSmrg	XtFree((char *) w->wm.title);
1681444c061aSmrg	XtFree((char *) w->wm.window_role);
1682444c061aSmrg}
1683444c061aSmrg
1684444c061aSmrgstatic void TopLevelDestroy(
1685444c061aSmrg	Widget wid)
1686444c061aSmrg{
1687444c061aSmrg	TopLevelShellWidget w = (TopLevelShellWidget) wid;
1688444c061aSmrg
1689444c061aSmrg	XtFree((char *) w->topLevel.icon_name);
1690444c061aSmrg}
1691444c061aSmrg
1692444c061aSmrgstatic void ApplicationDestroy(
1693444c061aSmrg    Widget wid)
1694444c061aSmrg{
1695444c061aSmrg    ApplicationShellWidget w = (ApplicationShellWidget) wid;
1696444c061aSmrg    if (w->application.argc > 0)
1697444c061aSmrg	FreeStringArray(w->application.argv);
1698444c061aSmrg}
1699444c061aSmrg
1700444c061aSmrgstatic void SessionDestroy(
1701444c061aSmrg    Widget wid)
1702444c061aSmrg{
1703444c061aSmrg#ifndef XT_NO_SM
1704444c061aSmrg    SessionShellWidget w = (SessionShellWidget) wid;
1705444c061aSmrg
1706444c061aSmrg    StopManagingSession(w, w->session.connection);
1707444c061aSmrg    XtFree(w->session.session_id);
1708444c061aSmrg    FreeStringArray(w->session.restart_command);
1709444c061aSmrg    FreeStringArray(w->session.clone_command);
1710444c061aSmrg    FreeStringArray(w->session.discard_command);
1711444c061aSmrg    FreeStringArray(w->session.resign_command);
1712444c061aSmrg    FreeStringArray(w->session.shutdown_command);
1713444c061aSmrg    FreeStringArray(w->session.environment);
1714444c061aSmrg    XtFree(w->session.current_dir);
17150568f49bSmrg    XtFree((_XtString) w->session.program_path);
1716444c061aSmrg#endif /* !XT_NO_SM */
1717444c061aSmrg}
1718444c061aSmrg
1719444c061aSmrg/*
1720444c061aSmrg * If the Shell has a width and a height which are zero, and as such
1721444c061aSmrg * suspect, and it has not yet been realized then it will grow to
1722444c061aSmrg * match the child before parsing the geometry resource.
1723444c061aSmrg *
1724444c061aSmrg */
1725444c061aSmrgstatic void GetGeometry(
1726444c061aSmrg    Widget W, Widget child)
1727444c061aSmrg{
1728444c061aSmrg    register ShellWidget w = (ShellWidget)W;
1729444c061aSmrg    Boolean is_wmshell = XtIsWMShell(W);
1730444c061aSmrg    int x, y, width, height, win_gravity = -1, flag;
1731444c061aSmrg    XSizeHints hints;
1732444c061aSmrg
1733444c061aSmrg    if (child != NULL) {
1734444c061aSmrg	/* we default to our child's size */
1735444c061aSmrg	if (is_wmshell && (w->core.width == 0 || w->core.height == 0))
1736444c061aSmrg	    ((WMShellWidget)W)->wm.size_hints.flags |= PSize;
1737444c061aSmrg	if (w->core.width == 0)	    w->core.width = child->core.width;
1738444c061aSmrg	if (w->core.height == 0)    w->core.height = child->core.height;
1739444c061aSmrg    }
1740444c061aSmrg    if(w->shell.geometry != NULL) {
1741444c061aSmrg	char def_geom[64];
1742444c061aSmrg	x = w->core.x;
1743444c061aSmrg	y = w->core.y;
1744444c061aSmrg	width = w->core.width;
1745444c061aSmrg	height = w->core.height;
1746444c061aSmrg	if (is_wmshell) {
1747444c061aSmrg	    WMShellPart* wm = &((WMShellWidget)w)->wm;
1748444c061aSmrg	    EvaluateSizeHints((WMShellWidget)w);
1749444c061aSmrg	    (void) memmove((char*)&hints, (char*)&wm->size_hints,
1750444c061aSmrg			   sizeof(struct _OldXSizeHints));
1751444c061aSmrg	    hints.win_gravity = wm->win_gravity;
1752444c061aSmrg	    if (wm->size_hints.flags & PBaseSize) {
1753444c061aSmrg		width -= wm->base_width;
1754444c061aSmrg		height -= wm->base_height;
1755444c061aSmrg		hints.base_width = wm->base_width;
1756444c061aSmrg		hints.base_height = wm->base_height;
1757444c061aSmrg	    }
1758444c061aSmrg	    else if (wm->size_hints.flags & PMinSize) {
1759444c061aSmrg		width -= wm->size_hints.min_width;
1760444c061aSmrg		height -= wm->size_hints.min_height;
1761444c061aSmrg	    }
1762444c061aSmrg	    if (wm->size_hints.flags & PResizeInc) {
1763444c061aSmrg		width /= wm->size_hints.width_inc;
1764444c061aSmrg		height /= wm->size_hints.height_inc;
1765444c061aSmrg	    }
1766444c061aSmrg	}
1767444c061aSmrg	else hints.flags = 0;
1768444c061aSmrg
1769bdf0f55dSmrg	snprintf( def_geom, sizeof(def_geom), "%dx%d+%d+%d",
1770bdf0f55dSmrg		  width, height, x, y );
1771444c061aSmrg	flag = XWMGeometry( XtDisplay(W),
1772444c061aSmrg			    XScreenNumberOfScreen(XtScreen(W)),
1773444c061aSmrg			    w->shell.geometry, def_geom,
1774444c061aSmrg			    (unsigned int)w->core.border_width,
1775444c061aSmrg			    &hints, &x, &y, &width, &height,
1776444c061aSmrg			    &win_gravity
1777444c061aSmrg			   );
1778444c061aSmrg	if (flag) {
1779444c061aSmrg	    if (flag & XValue) w->core.x = (Position)x;
1780444c061aSmrg	    if (flag & YValue) w->core.y = (Position)y;
1781444c061aSmrg	    if (flag & WidthValue) w->core.width = (Dimension)width;
1782444c061aSmrg	    if (flag & HeightValue) w->core.height = (Dimension)height;
1783444c061aSmrg	}
1784444c061aSmrg	else {
1785444c061aSmrg	    String params[2];
1786444c061aSmrg	    Cardinal num_params = 2;
1787444c061aSmrg	    params[0] = XtName(W);
1788444c061aSmrg	    params[1] = w->shell.geometry;
1789444c061aSmrg	    XtAppWarningMsg(XtWidgetToApplicationContext(W),
1790444c061aSmrg       "badGeometry", "shellRealize", XtCXtToolkitError,
1791444c061aSmrg       "Shell widget \"%s\" has an invalid geometry specification: \"%s\"",
1792444c061aSmrg			    params, &num_params);
1793444c061aSmrg	}
1794444c061aSmrg    }
1795444c061aSmrg    else
1796444c061aSmrg	flag = 0;
1797444c061aSmrg
1798444c061aSmrg    if (is_wmshell) {
1799444c061aSmrg	WMShellWidget wmshell = (WMShellWidget) w;
1800444c061aSmrg	if (wmshell->wm.win_gravity == XtUnspecifiedShellInt) {
1801444c061aSmrg	    if (win_gravity != -1)
1802444c061aSmrg		wmshell->wm.win_gravity = win_gravity;
1803444c061aSmrg	    else
1804444c061aSmrg		wmshell->wm.win_gravity = NorthWestGravity;
1805444c061aSmrg	}
1806444c061aSmrg	wmshell->wm.size_hints.flags |= PWinGravity;
1807444c061aSmrg	if ((flag & (XValue|YValue)) == (XValue|YValue))
1808444c061aSmrg	    wmshell->wm.size_hints.flags |= USPosition;
1809444c061aSmrg	if ((flag & (WidthValue|HeightValue)) == (WidthValue|HeightValue))
1810444c061aSmrg	    wmshell->wm.size_hints.flags |= USSize;
1811444c061aSmrg    }
1812444c061aSmrg    w->shell.client_specified |= _XtShellGeometryParsed;
1813444c061aSmrg}
1814444c061aSmrg
1815444c061aSmrg
1816444c061aSmrgstatic void ChangeManaged(Widget wid)
1817444c061aSmrg{
1818444c061aSmrg    ShellWidget w = (ShellWidget) wid;
1819444c061aSmrg    Widget child = NULL;
1820444c061aSmrg    Cardinal i;
1821444c061aSmrg
1822444c061aSmrg    for (i = 0; i < w->composite.num_children; i++) {
1823444c061aSmrg	if (XtIsManaged(w->composite.children[i])) {
1824444c061aSmrg	    child = w->composite.children[i];
1825444c061aSmrg	    break;		/* there can only be one of them! */
1826444c061aSmrg	}
1827444c061aSmrg    }
1828444c061aSmrg
1829444c061aSmrg    if (!XtIsRealized (wid))	/* then we're about to be realized... */
1830444c061aSmrg	GetGeometry(wid, child);
1831444c061aSmrg
1832444c061aSmrg    if (child != NULL)
1833444c061aSmrg	XtConfigureWidget (child, (Position)0, (Position)0,
1834444c061aSmrg			   w->core.width, w->core.height, (Dimension)0 );
1835444c061aSmrg}
1836444c061aSmrg
1837444c061aSmrg/*
1838444c061aSmrg * This is gross, I can't wait to see if the change happened so I will ask
1839444c061aSmrg * the window manager to change my size and do the appropriate X work.
1840444c061aSmrg * I will then tell the requester that he can.  Care must be taken because
1841444c061aSmrg * it is possible that some time in the future the request will be
1842444c061aSmrg * asynchronusly denied and the window reverted to it's old size/shape.
1843444c061aSmrg */
1844444c061aSmrg
1845444c061aSmrg/*ARGSUSED*/
1846444c061aSmrgstatic XtGeometryResult GeometryManager(
1847444c061aSmrg	Widget wid,
1848444c061aSmrg	XtWidgetGeometry *request,
1849444c061aSmrg	XtWidgetGeometry *reply)
1850444c061aSmrg{
1851444c061aSmrg	ShellWidget shell = (ShellWidget)(wid->core.parent);
1852444c061aSmrg	XtWidgetGeometry my_request;
1853444c061aSmrg
1854444c061aSmrg	if(shell->shell.allow_shell_resize == FALSE && XtIsRealized(wid))
1855444c061aSmrg		return(XtGeometryNo);
1856444c061aSmrg
1857444c061aSmrg	if (request->request_mode & (CWX | CWY))
1858444c061aSmrg	    return(XtGeometryNo);
1859444c061aSmrg
1860444c061aSmrg	my_request.request_mode = (request->request_mode & XtCWQueryOnly);
1861444c061aSmrg	if (request->request_mode & CWWidth) {
1862444c061aSmrg	    my_request.width = request->width;
1863444c061aSmrg	    my_request.request_mode |= CWWidth;
1864444c061aSmrg	}
1865444c061aSmrg	if (request->request_mode & CWHeight) {
1866444c061aSmrg	    my_request.height = request->height;
1867444c061aSmrg	    my_request.request_mode |= CWHeight;
1868444c061aSmrg	}
1869444c061aSmrg	if (request->request_mode & CWBorderWidth) {
1870444c061aSmrg	    my_request.border_width = request->border_width;
1871444c061aSmrg	    my_request.request_mode |= CWBorderWidth;
1872444c061aSmrg	}
1873444c061aSmrg	if (XtMakeGeometryRequest((Widget)shell, &my_request, NULL)
1874444c061aSmrg		== XtGeometryYes) {
1875444c061aSmrg	    /* assert: if (request->request_mode & CWWidth) then
1876444c061aSmrg	     * 		  shell->core.width == request->width
1877444c061aSmrg	     * assert: if (request->request_mode & CWHeight) then
1878444c061aSmrg	     * 		  shell->core.height == request->height
1879444c061aSmrg	     *
1880444c061aSmrg	     * so, whatever the WM sized us to (if the Shell requested
1881444c061aSmrg	     * only one of the two) is now the correct child size
1882444c061aSmrg	     */
1883444c061aSmrg
1884444c061aSmrg	    if (!(request->request_mode & XtCWQueryOnly)) {
1885444c061aSmrg		wid->core.width = shell->core.width;
1886444c061aSmrg		wid->core.height = shell->core.height;
1887444c061aSmrg		if (request->request_mode & CWBorderWidth) {
18880568f49bSmrg		    wid->core.x = wid->core.y = (Position) (-request->border_width);
1889444c061aSmrg		}
1890444c061aSmrg	    }
1891444c061aSmrg	    return XtGeometryYes;
1892444c061aSmrg	} else return XtGeometryNo;
1893444c061aSmrg}
1894444c061aSmrg
1895444c061aSmrgtypedef struct {
1896444c061aSmrg	Widget  w;
1897444c061aSmrg	unsigned long request_num;
1898444c061aSmrg	Boolean done;
1899444c061aSmrg} QueryStruct;
1900444c061aSmrg
1901444c061aSmrgstatic Bool isMine(
1902444c061aSmrg	Display *dpy,
1903444c061aSmrg	register XEvent  *event,
1904444c061aSmrg	char *arg)
1905444c061aSmrg{
1906444c061aSmrg	QueryStruct *q = (QueryStruct *) arg;
1907444c061aSmrg	register Widget w = q->w;
1908444c061aSmrg
1909444c061aSmrg	if ( (dpy != XtDisplay(w)) || (event->xany.window != XtWindow(w)) ) {
1910444c061aSmrg	    return FALSE;
1911444c061aSmrg	}
1912444c061aSmrg	if (event->xany.serial >= q->request_num) {
1913444c061aSmrg	    if (event->type == ConfigureNotify) {
1914444c061aSmrg		q->done = TRUE;
1915444c061aSmrg		return TRUE;
1916444c061aSmrg	    }
1917444c061aSmrg	}
1918444c061aSmrg	else if (event->type == ConfigureNotify)
1919444c061aSmrg	    return TRUE;	/* flush old events */
1920444c061aSmrg	if (event->type == ReparentNotify
1921444c061aSmrg		 && event->xreparent.window == XtWindow(w)) {
1922444c061aSmrg	    /* we might get ahead of this event, so just in case someone
1923444c061aSmrg	     * asks for coordinates before this event is dispatched...
1924444c061aSmrg	     */
1925444c061aSmrg	    register ShellWidget s = (ShellWidget)w;
1926444c061aSmrg	    if (event->xreparent.parent != RootWindowOfScreen(XtScreen(w)))
1927444c061aSmrg		s->shell.client_specified &= ~_XtShellNotReparented;
1928444c061aSmrg	    else
1929444c061aSmrg		s->shell.client_specified |= _XtShellNotReparented;
1930444c061aSmrg	}
1931444c061aSmrg	return FALSE;
1932444c061aSmrg}
1933444c061aSmrg
1934444c061aSmrgstatic Boolean _wait_for_response(
1935444c061aSmrg	ShellWidget	w,
1936444c061aSmrg	XEvent		*event,
1937444c061aSmrg        unsigned long	request_num)
1938444c061aSmrg{
1939444c061aSmrg	XtAppContext app = XtWidgetToApplicationContext((Widget) w);
1940444c061aSmrg	QueryStruct q;
1941444c061aSmrg	unsigned long timeout;
1942444c061aSmrg
1943444c061aSmrg	if (XtIsWMShell((Widget)w))
19440568f49bSmrg	    timeout = (unsigned long) ((WMShellWidget)w)->wm.wm_timeout;
1945444c061aSmrg	else
1946444c061aSmrg	    timeout = DEFAULT_WM_TIMEOUT;
1947444c061aSmrg
1948444c061aSmrg	XFlush(XtDisplay(w));
1949444c061aSmrg	q.w = (Widget) w;
1950444c061aSmrg	q.request_num = request_num;
1951444c061aSmrg	q.done = FALSE;
1952444c061aSmrg
1953444c061aSmrg	/*
1954444c061aSmrg	 * look for match event and discard all prior configures
1955444c061aSmrg	 */
1956444c061aSmrg	while (XCheckIfEvent(XtDisplay(w),event,isMine,(char*)&q)) {
1957444c061aSmrg	    if (q.done) return TRUE;
1958444c061aSmrg	}
1959444c061aSmrg
1960444c061aSmrg	while (timeout > 0) {
1961444c061aSmrg	    if (_XtWaitForSomething (app,
1962444c061aSmrg				     FALSE, TRUE, TRUE, TRUE,
1963444c061aSmrg				     TRUE,
1964444c061aSmrg#ifdef XTHREADS
1965444c061aSmrg				     FALSE,
1966444c061aSmrg#endif
1967444c061aSmrg				     &timeout) != -1) {
1968444c061aSmrg		while (XCheckIfEvent(XtDisplay(w),event,isMine,(char*)&q)) {
1969444c061aSmrg		    if (q.done) return TRUE;
1970444c061aSmrg		}
1971444c061aSmrg	    }
1972444c061aSmrg	}
1973444c061aSmrg	return FALSE;
1974444c061aSmrg}
1975444c061aSmrg
1976444c061aSmrg/*ARGSUSED*/
1977444c061aSmrgstatic XtGeometryResult RootGeometryManager(
1978444c061aSmrg    Widget gw,
1979444c061aSmrg    XtWidgetGeometry *request, XtWidgetGeometry *reply)
1980444c061aSmrg{
1981444c061aSmrg    register ShellWidget w = (ShellWidget)gw;
1982444c061aSmrg    XWindowChanges values;
1983444c061aSmrg    unsigned int mask = request->request_mode;
1984444c061aSmrg    XEvent event;
1985444c061aSmrg    Boolean wm;
1986444c061aSmrg    register struct _OldXSizeHints *hintp = NULL;
1987444c061aSmrg    int oldx, oldy, oldwidth, oldheight, oldborder_width;
1988444c061aSmrg    unsigned long request_num;
1989444c061aSmrg
1990444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
1991444c061aSmrg
1992444c061aSmrg    if (XtIsWMShell(gw)) {
1993444c061aSmrg	wm = True;
1994444c061aSmrg	hintp = &((WMShellWidget)w)->wm.size_hints;
1995444c061aSmrg	/* for draft-ICCCM wm's, need to make sure hints reflect
1996444c061aSmrg	   (current) reality so client can move and size separately. */
1997444c061aSmrg  	hintp->x = w->core.x;
1998444c061aSmrg  	hintp->y = w->core.y;
1999444c061aSmrg  	hintp->width = w->core.width;
2000444c061aSmrg   	hintp->height = w->core.height;
2001444c061aSmrg    } else
2002444c061aSmrg	wm = False;
2003444c061aSmrg
2004444c061aSmrg    oldx = w->core.x;
2005444c061aSmrg    oldy = w->core.y;
2006444c061aSmrg    oldwidth = w->core.width;
2007444c061aSmrg    oldheight = w->core.height;
2008444c061aSmrg    oldborder_width = w->core.border_width;
2009444c061aSmrg
2010444c061aSmrg#define PutBackGeometry() \
20110568f49bSmrg	{ w->core.x = (Position) (oldx); \
20120568f49bSmrg	  w->core.y = (Position) (oldy); \
20130568f49bSmrg	  w->core.width = (Dimension) (oldwidth); \
20140568f49bSmrg	  w->core.height = (Dimension) (oldheight); \
20150568f49bSmrg	  w->core.border_width = (Dimension) (oldborder_width); }
2016444c061aSmrg
20170568f49bSmrg    memset(&values, 0, sizeof(values));
2018444c061aSmrg    if (mask & CWX) {
20190568f49bSmrg	    if (w->core.x == request->x) mask &= (unsigned int) (~CWX);
2020444c061aSmrg	    else {
20210568f49bSmrg		w->core.x = (Position) (values.x = request->x);
2022444c061aSmrg		if (wm) {
2023444c061aSmrg		    hintp->flags &= ~USPosition;
2024444c061aSmrg		    hintp->flags |= PPosition;
2025444c061aSmrg		    hintp->x = values.x;
2026444c061aSmrg		}
2027444c061aSmrg	    }
2028444c061aSmrg    }
2029444c061aSmrg    if (mask & CWY) {
20300568f49bSmrg	    if (w->core.y == request->y) mask &= (unsigned int) (~CWY);
2031444c061aSmrg	    else {
20320568f49bSmrg		w->core.y = (Position) (values.y = request->y);
2033444c061aSmrg		if (wm) {
2034444c061aSmrg		    hintp->flags &= ~USPosition;
2035444c061aSmrg		    hintp->flags |= PPosition;
2036444c061aSmrg		    hintp->y = values.y;
2037444c061aSmrg		}
2038444c061aSmrg	    }
2039444c061aSmrg    }
2040444c061aSmrg    if (mask & CWBorderWidth) {
2041444c061aSmrg	    if (w->core.border_width == request->border_width) {
20420568f49bSmrg		    mask &= (unsigned int) (~CWBorderWidth);
2043444c061aSmrg	    } else
2044444c061aSmrg		w->core.border_width =
20450568f49bSmrg		    (Dimension) (values.border_width =
20460568f49bSmrg			request->border_width);
2047444c061aSmrg    }
2048444c061aSmrg    if (mask & CWWidth) {
20490568f49bSmrg	    if (w->core.width == request->width) mask &= (unsigned int) (~CWWidth);
2050444c061aSmrg	    else {
20510568f49bSmrg		w->core.width = (Dimension)(values.width = request->width);
2052444c061aSmrg		if (wm) {
2053444c061aSmrg		    hintp->flags &= ~USSize;
2054444c061aSmrg		    hintp->flags |= PSize;
2055444c061aSmrg		    hintp->width = values.width;
2056444c061aSmrg		}
2057444c061aSmrg	    }
2058444c061aSmrg    }
2059444c061aSmrg    if (mask & CWHeight) {
20600568f49bSmrg	    if (w->core.height == request->height) mask &= (unsigned int) (~CWHeight);
2061444c061aSmrg	    else {
20620568f49bSmrg		w->core.height = (Dimension)(values.height = request->height);
2063444c061aSmrg		if (wm) {
2064444c061aSmrg		    hintp->flags &= ~USSize;
2065444c061aSmrg		    hintp->flags |= PSize;
2066444c061aSmrg		    hintp->height = values.height;
2067444c061aSmrg		}
2068444c061aSmrg	    }
2069444c061aSmrg    }
2070444c061aSmrg    if (mask & CWStackMode) {
2071444c061aSmrg	values.stack_mode = request->stack_mode;
2072444c061aSmrg	if (mask & CWSibling)
2073444c061aSmrg	    values.sibling = XtWindow(request->sibling);
2074444c061aSmrg    }
2075444c061aSmrg
2076444c061aSmrg    if (!XtIsRealized((Widget)w)) {
2077444c061aSmrg	CALLGEOTAT(_XtGeoTrace((Widget)w,
2078444c061aSmrg		      "Shell \"%s\" is not realized, return XtGeometryYes.\n",
2079444c061aSmrg		       XtName((Widget)w)));
2080444c061aSmrg    	CALLGEOTAT(_XtGeoTab(-1));
2081444c061aSmrg	return XtGeometryYes;
2082444c061aSmrg    }
2083444c061aSmrg
2084444c061aSmrg    request_num = NextRequest(XtDisplay(w));
2085444c061aSmrg
2086444c061aSmrg    CALLGEOTAT(_XtGeoTrace((Widget)w,"XConfiguring the Shell X window :\n"));
2087444c061aSmrg    CALLGEOTAT(_XtGeoTab(1));
2088444c061aSmrg#ifdef XT_GEO_TATTLER
2089444c061aSmrg    if (mask & CWX) { CALLGEOTAT(_XtGeoTrace((Widget)w,"x = %d\n",values.x));}
2090444c061aSmrg    if (mask & CWY) { CALLGEOTAT(_XtGeoTrace((Widget)w,"y = %d\n",values.y));}
2091444c061aSmrg    if (mask & CWWidth) { CALLGEOTAT(_XtGeoTrace((Widget)w,
2092444c061aSmrg					       "width = %d\n",values.width));}
2093444c061aSmrg    if (mask & CWHeight) { CALLGEOTAT(_XtGeoTrace((Widget)w,
2094444c061aSmrg					    "height = %d\n",values.height));}
2095444c061aSmrg    if (mask & CWBorderWidth) { CALLGEOTAT(_XtGeoTrace((Widget)w,
2096444c061aSmrg				  "border_width = %d\n",values.border_width));}
2097444c061aSmrg#endif
2098444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
2099444c061aSmrg
2100444c061aSmrg    XConfigureWindow(XtDisplay((Widget)w), XtWindow((Widget)w), mask,&values);
2101444c061aSmrg
2102444c061aSmrg    if (wm && !w->shell.override_redirect
2103444c061aSmrg	&& mask & (CWX | CWY | CWWidth | CWHeight | CWBorderWidth)) {
2104444c061aSmrg	_SetWMSizeHints((WMShellWidget)w);
2105444c061aSmrg    }
2106444c061aSmrg
2107444c061aSmrg    if (w->shell.override_redirect) {
2108444c061aSmrg	CALLGEOTAT(_XtGeoTrace((Widget)w,"Shell \"%s\" is override redirect, return XtGeometryYes.\n", XtName((Widget)w)));
2109444c061aSmrg    	CALLGEOTAT(_XtGeoTab(-1));
2110444c061aSmrg	return XtGeometryYes;
2111444c061aSmrg    }
2112444c061aSmrg
2113444c061aSmrg
2114444c061aSmrg    /* If no non-stacking bits are set, there's no way to tell whether
2115444c061aSmrg       or not this worked, so assume it did */
2116444c061aSmrg
21170568f49bSmrg    if (!(mask & (unsigned)(~(CWStackMode | CWSibling)))) return XtGeometryYes;
2118444c061aSmrg
2119444c061aSmrg    if (wm && ((WMShellWidget)w)->wm.wait_for_wm == FALSE) {
2120444c061aSmrg	    /* the window manager is sick
2121444c061aSmrg	     * so I will do the work and
2122444c061aSmrg	     * say no so if a new WM starts up,
2123444c061aSmrg	     * or the current one recovers
2124444c061aSmrg	     * my size requests will be visible
2125444c061aSmrg	     */
2126444c061aSmrg	CALLGEOTAT(_XtGeoTrace((Widget)w,"Shell \"%s\" has wait_for_wm == FALSE, return XtGeometryNo.\n",
2127444c061aSmrg		       XtName((Widget)w)));
2128444c061aSmrg    	CALLGEOTAT(_XtGeoTab(-1));
2129444c061aSmrg
2130444c061aSmrg	PutBackGeometry();
2131444c061aSmrg	return XtGeometryNo;
2132444c061aSmrg    }
2133444c061aSmrg
2134444c061aSmrg    if (_wait_for_response(w, &event, request_num)) {
2135444c061aSmrg	/* got an event */
2136444c061aSmrg	if (event.type == ConfigureNotify) {
2137444c061aSmrg
2138444c061aSmrg#define NEQ(x, msk) ((mask & msk) && (values.x != event.xconfigure.x))
2139444c061aSmrg	    if (NEQ(x, CWX) ||
2140444c061aSmrg		NEQ(y, CWY) ||
2141444c061aSmrg		NEQ(width, CWWidth) ||
2142444c061aSmrg		NEQ(height, CWHeight) ||
2143444c061aSmrg		NEQ(border_width, CWBorderWidth)) {
2144444c061aSmrg#ifdef XT_GEO_TATTLER
2145444c061aSmrg		if (NEQ(x, CWX)) {
2146444c061aSmrg		    CALLGEOTAT(_XtGeoTrace((Widget)w,
2147444c061aSmrg					   "received Configure X %d\n",
2148444c061aSmrg					   event.xconfigure.x));
2149444c061aSmrg		}
2150444c061aSmrg		if (NEQ(y, CWY)) {
2151444c061aSmrg		    CALLGEOTAT(_XtGeoTrace((Widget)w,
2152444c061aSmrg					   "received Configure Y %d\n",
2153444c061aSmrg					   event.xconfigure.y));
2154444c061aSmrg		}
2155444c061aSmrg		if (NEQ(width, CWWidth)) {
2156444c061aSmrg		    CALLGEOTAT(_XtGeoTrace((Widget)w,
2157444c061aSmrg					   "received Configure Width %d\n",
2158444c061aSmrg					   event.xconfigure.width));
2159444c061aSmrg		}
2160444c061aSmrg		if (NEQ(height, CWHeight)) {
2161444c061aSmrg		    CALLGEOTAT(_XtGeoTrace((Widget)w,
2162444c061aSmrg					   "received Configure Height %d\n",
2163444c061aSmrg					   event.xconfigure.height));
2164444c061aSmrg		}
2165444c061aSmrg		if (NEQ(border_width, CWBorderWidth)) {
2166444c061aSmrg		    CALLGEOTAT(_XtGeoTrace((Widget)w,
2167444c061aSmrg				        "received Configure BorderWidth %d\n",
2168444c061aSmrg					event.xconfigure.border_width));
2169444c061aSmrg		}
2170444c061aSmrg#endif
2171444c061aSmrg#undef NEQ
2172444c061aSmrg		XPutBackEvent(XtDisplay(w), &event);
2173444c061aSmrg		PutBackGeometry();
2174444c061aSmrg		/*
2175444c061aSmrg		 * We just potentially re-ordered the event queue
2176444c061aSmrg		 * w.r.t. ConfigureNotifies with some trepidation.
2177444c061aSmrg		 * But this is probably a Good Thing because we
2178444c061aSmrg		 * will know the new true state of the world sooner
2179444c061aSmrg		 * this way.
2180444c061aSmrg		 */
2181444c061aSmrg		CALLGEOTAT(_XtGeoTrace((Widget)w,
2182444c061aSmrg			   "ConfigureNotify failed, return XtGeometryNo.\n"));
2183444c061aSmrg		CALLGEOTAT(_XtGeoTab(-1));
2184444c061aSmrg
2185444c061aSmrg		return XtGeometryNo;
2186444c061aSmrg	    }
2187444c061aSmrg	    else {
21880568f49bSmrg		w->core.width = (Dimension) event.xconfigure.width;
21890568f49bSmrg		w->core.height = (Dimension) event.xconfigure.height;
21900568f49bSmrg		w->core.border_width = (Dimension) event.xconfigure.border_width;
2191444c061aSmrg		if (event.xany.send_event || /* ICCCM compliant synth */
2192444c061aSmrg		    w->shell.client_specified & _XtShellNotReparented) {
2193444c061aSmrg
21940568f49bSmrg		    w->core.x = (Position) event.xconfigure.x;
21950568f49bSmrg		    w->core.y = (Position) event.xconfigure.y;
2196444c061aSmrg		    w->shell.client_specified |= _XtShellPositionValid;
2197444c061aSmrg		}
2198444c061aSmrg		else w->shell.client_specified &= ~_XtShellPositionValid;
2199444c061aSmrg		CALLGEOTAT(_XtGeoTrace((Widget)w,
2200444c061aSmrg			 "ConfigureNotify succeed, return XtGeometryYes.\n"));
2201444c061aSmrg		CALLGEOTAT(_XtGeoTab(-1));
2202444c061aSmrg		return XtGeometryYes;
2203444c061aSmrg	    }
2204444c061aSmrg	} else if (!wm) {
2205444c061aSmrg	    PutBackGeometry();
2206444c061aSmrg	    CALLGEOTAT(_XtGeoTrace((Widget)w,
2207444c061aSmrg				   "Not wm, return XtGeometryNo.\n"));
2208444c061aSmrg	    CALLGEOTAT(_XtGeoTab(-1));
2209444c061aSmrg	    return XtGeometryNo;
2210444c061aSmrg	} else XtAppWarningMsg(XtWidgetToApplicationContext((Widget)w),
2211444c061aSmrg			       "internalError", "shell", XtCXtToolkitError,
2212444c061aSmrg			       "Shell's window manager interaction is broken",
22130568f49bSmrg			       NULL, NULL);
2214444c061aSmrg    } else if (wm) { /* no event */
2215444c061aSmrg	((WMShellWidget)w)->wm.wait_for_wm = FALSE; /* timed out; must be broken */
2216444c061aSmrg    }
2217444c061aSmrg    PutBackGeometry();
2218444c061aSmrg#undef PutBackGeometry
2219444c061aSmrg    CALLGEOTAT(_XtGeoTrace((Widget)w,
2220444c061aSmrg			   "Timeout passed?, return XtGeometryNo.\n"));
2221444c061aSmrg    CALLGEOTAT(_XtGeoTab(-1));
2222444c061aSmrg    return XtGeometryNo;
2223444c061aSmrg		}
2224444c061aSmrg
2225444c061aSmrg/* ARGSUSED */
2226444c061aSmrgstatic Boolean SetValues(
2227444c061aSmrg	Widget old, Widget ref, Widget new,
2228444c061aSmrg	ArgList args,
2229444c061aSmrg	Cardinal *num_args)
2230444c061aSmrg{
2231444c061aSmrg	ShellWidget nw = (ShellWidget) new;
2232444c061aSmrg	ShellWidget ow = (ShellWidget) old;
2233444c061aSmrg	Mask mask = 0;
2234444c061aSmrg	XSetWindowAttributes attr;
2235444c061aSmrg
2236444c061aSmrg	if (!XtIsRealized(new))
2237444c061aSmrg	    return False;
2238444c061aSmrg
2239444c061aSmrg	if (ow->shell.save_under != nw->shell.save_under) {
2240444c061aSmrg	    mask = CWSaveUnder;
2241444c061aSmrg	    attr.save_under = nw->shell.save_under;
2242444c061aSmrg	}
2243444c061aSmrg
2244444c061aSmrg	if (ow->shell.override_redirect != nw->shell.override_redirect) {
2245444c061aSmrg	    mask |= CWOverrideRedirect;
2246444c061aSmrg	    attr.override_redirect = nw->shell.override_redirect;
2247444c061aSmrg	}
2248444c061aSmrg
2249444c061aSmrg	if (mask) {
2250444c061aSmrg	    XChangeWindowAttributes(XtDisplay(new),XtWindow(new), mask, &attr);
2251444c061aSmrg	    if ((mask & CWOverrideRedirect) && !nw->shell.override_redirect)
2252444c061aSmrg		_popup_set_prop(nw);
2253444c061aSmrg	}
2254444c061aSmrg
2255444c061aSmrg	if (! (ow->shell.client_specified & _XtShellPositionValid)) {
2256444c061aSmrg	    Cardinal n;
2257444c061aSmrg
2258444c061aSmrg	    for (n = *num_args; n; n--, args++) {
2259444c061aSmrg		if (strcmp(XtNx, args->name) == 0) {
2260444c061aSmrg		    _XtShellGetCoordinates((Widget)ow, &ow->core.x,
2261444c061aSmrg							&ow->core.y);
2262444c061aSmrg		} else if (strcmp(XtNy, args->name) == 0) {
2263444c061aSmrg		    _XtShellGetCoordinates((Widget)ow, &ow->core.x,
2264444c061aSmrg							&ow->core.y);
2265444c061aSmrg		}
2266444c061aSmrg	    }
2267444c061aSmrg	}
2268444c061aSmrg	return FALSE;
2269444c061aSmrg}
2270444c061aSmrg
2271444c061aSmrg/* ARGSUSED */
2272444c061aSmrgstatic Boolean WMSetValues(
2273444c061aSmrg	Widget old, Widget ref, Widget new,
2274444c061aSmrg	ArgList args,		/* unused */
2275444c061aSmrg	Cardinal *num_args)	/* unused */
2276444c061aSmrg{
2277444c061aSmrg	WMShellWidget nwmshell = (WMShellWidget) new;
2278444c061aSmrg	WMShellWidget owmshell = (WMShellWidget) old;
2279444c061aSmrg	Boolean set_prop
2280444c061aSmrg	    = XtIsRealized(new) && !nwmshell->shell.override_redirect;
2281444c061aSmrg	Boolean title_changed;
2282444c061aSmrg
2283444c061aSmrg	EvaluateSizeHints(nwmshell);
2284444c061aSmrg
2285444c061aSmrg#define NEQ(f) (nwmshell->wm.size_hints.f != owmshell->wm.size_hints.f)
2286444c061aSmrg
2287444c061aSmrg	if (set_prop
2288444c061aSmrg	    && (NEQ(flags) || NEQ(min_width) || NEQ(min_height)
2289444c061aSmrg		|| NEQ(max_width) || NEQ(max_height)
2290444c061aSmrg		|| NEQ(width_inc) || NEQ(height_inc)
2291444c061aSmrg		|| NEQ(min_aspect.x) || NEQ(min_aspect.y)
2292444c061aSmrg		|| NEQ(max_aspect.x) || NEQ(max_aspect.y)
2293444c061aSmrg#undef NEQ
2294444c061aSmrg#define NEQ(f) (nwmshell->wm.f != owmshell->wm.f)
2295444c061aSmrg
2296444c061aSmrg		|| NEQ(base_width) || NEQ(base_height) || NEQ(win_gravity))) {
2297444c061aSmrg	    _SetWMSizeHints(nwmshell);
2298444c061aSmrg	}
2299444c061aSmrg#undef NEQ
2300444c061aSmrg
2301444c061aSmrg	if (nwmshell->wm.title != owmshell->wm.title) {
2302444c061aSmrg	    XtFree(owmshell->wm.title);
23030568f49bSmrg	    if (! nwmshell->wm.title) nwmshell->wm.title = (_XtString) "";
2304444c061aSmrg	    nwmshell->wm.title = XtNewString(nwmshell->wm.title);
2305444c061aSmrg	    title_changed = True;
2306444c061aSmrg	} else
2307444c061aSmrg	    title_changed = False;
2308444c061aSmrg
2309444c061aSmrg	if (set_prop
2310444c061aSmrg	    && (title_changed ||
2311444c061aSmrg		nwmshell->wm.title_encoding != owmshell->wm.title_encoding)) {
2312444c061aSmrg
2313444c061aSmrg	    XTextProperty title;
2314444c061aSmrg	    Boolean copied = False;
2315444c061aSmrg
2316444c061aSmrg            if (nwmshell->wm.title_encoding == None &&
2317444c061aSmrg		XmbTextListToTextProperty(XtDisplay(new),
2318444c061aSmrg					  (char**)&nwmshell->wm.title,
2319444c061aSmrg					  1, XStdICCTextStyle,
2320444c061aSmrg					  &title) >= Success) {
2321444c061aSmrg		copied = True;
2322444c061aSmrg	    } else {
2323444c061aSmrg		title.value = (unsigned char*)nwmshell->wm.title;
2324444c061aSmrg		title.encoding = nwmshell->wm.title_encoding ?
2325444c061aSmrg		    nwmshell->wm.title_encoding : XA_STRING;
2326444c061aSmrg		title.format = 8;
2327444c061aSmrg		title.nitems = strlen(nwmshell->wm.title);
2328444c061aSmrg	    }
2329444c061aSmrg	    XSetWMName(XtDisplay(new), XtWindow(new), &title);
2330444c061aSmrg	    if (copied)
2331444c061aSmrg		XFree((XPointer)title.value);
2332444c061aSmrg	}
2333444c061aSmrg
2334444c061aSmrg	EvaluateWMHints(nwmshell);
2335444c061aSmrg
2336444c061aSmrg#define NEQ(f)	(nwmshell->wm.wm_hints.f != owmshell->wm.wm_hints.f)
2337444c061aSmrg
2338444c061aSmrg	if (set_prop
2339444c061aSmrg	    && (NEQ(flags) || NEQ(input) || NEQ(initial_state)
2340444c061aSmrg		|| NEQ(icon_x) || NEQ(icon_y)
2341444c061aSmrg		|| NEQ(icon_pixmap) || NEQ(icon_mask) || NEQ(icon_window)
2342444c061aSmrg		|| NEQ(window_group))) {
2343444c061aSmrg
2344444c061aSmrg	    XSetWMHints(XtDisplay(new), XtWindow(new), &nwmshell->wm.wm_hints);
2345444c061aSmrg	}
2346444c061aSmrg#undef NEQ
2347444c061aSmrg
2348444c061aSmrg 	if (XtIsRealized(new) &&
2349444c061aSmrg	    nwmshell->wm.transient != owmshell->wm.transient) {
2350444c061aSmrg 	    if (nwmshell->wm.transient) {
2351444c061aSmrg		if (!XtIsTransientShell(new) &&
2352444c061aSmrg		    !nwmshell->shell.override_redirect &&
2353444c061aSmrg		    nwmshell->wm.wm_hints.window_group !=
2354444c061aSmrg		       XtUnspecifiedWindowGroup)
2355444c061aSmrg		    XSetTransientForHint(XtDisplay(new), XtWindow(new),
2356444c061aSmrg					 nwmshell->wm.wm_hints.window_group);
2357444c061aSmrg	    }
2358444c061aSmrg 	    else XDeleteProperty(XtDisplay(new), XtWindow(new),
2359444c061aSmrg 				 XA_WM_TRANSIENT_FOR);
2360444c061aSmrg 	}
2361444c061aSmrg
2362444c061aSmrg	if (nwmshell->wm.client_leader != owmshell->wm.client_leader
2363444c061aSmrg	    && XtWindow(new) && !nwmshell->shell.override_redirect) {
2364444c061aSmrg	    Widget leader = GetClientLeader(new);
2365444c061aSmrg	    if (XtWindow(leader))
2366444c061aSmrg		XChangeProperty(XtDisplay(new), XtWindow(new),
2367444c061aSmrg				XInternAtom(XtDisplay(new),
2368444c061aSmrg					    "WM_CLIENT_LEADER", False),
2369444c061aSmrg				XA_WINDOW, 32, PropModeReplace,
2370444c061aSmrg				(unsigned char *) &(leader->core.window), 1);
2371444c061aSmrg	}
2372444c061aSmrg
2373444c061aSmrg	if (nwmshell->wm.window_role != owmshell->wm.window_role) {
23740568f49bSmrg	    XtFree((_XtString) owmshell->wm.window_role);
2375444c061aSmrg	    if (set_prop && nwmshell->wm.window_role) {
2376444c061aSmrg		XChangeProperty(XtDisplay(new), XtWindow(new),
2377444c061aSmrg				XInternAtom(XtDisplay(new), "WM_WINDOW_ROLE",
2378444c061aSmrg					    False),
2379444c061aSmrg				XA_STRING, 8, PropModeReplace,
2380444c061aSmrg				(unsigned char *)nwmshell->wm.window_role,
23810568f49bSmrg				(int) strlen(nwmshell->wm.window_role));
2382444c061aSmrg	    } else if (XtIsRealized(new) && ! nwmshell->wm.window_role) {
2383444c061aSmrg		XDeleteProperty(XtDisplay(new), XtWindow(new),
2384444c061aSmrg				XInternAtom(XtDisplay(new), "WM_WINDOW_ROLE",
2385444c061aSmrg					    False));
2386444c061aSmrg	    }
2387444c061aSmrg	}
2388444c061aSmrg
2389444c061aSmrg	return FALSE;
2390444c061aSmrg}
2391444c061aSmrg
2392444c061aSmrg/*ARGSUSED*/
2393444c061aSmrgstatic Boolean TransientSetValues(
2394444c061aSmrg     Widget oldW, Widget refW, Widget newW,
2395444c061aSmrg     ArgList args,		/* unused */
2396444c061aSmrg     Cardinal *num_args)	/* unused */
2397444c061aSmrg{
2398444c061aSmrg    TransientShellWidget old = (TransientShellWidget)oldW;
2399444c061aSmrg    TransientShellWidget new = (TransientShellWidget)newW;
2400444c061aSmrg
2401444c061aSmrg    if (XtIsRealized(newW)
2402444c061aSmrg	&& ((new->wm.transient && !old->wm.transient)
2403444c061aSmrg	    || ((new->transient.transient_for != old->transient.transient_for)
2404444c061aSmrg		|| (new->transient.transient_for == NULL
2405444c061aSmrg		    && (new->wm.wm_hints.window_group
2406444c061aSmrg			!= old->wm.wm_hints.window_group))))) {
2407444c061aSmrg
2408444c061aSmrg	_SetTransientForHint(new, True);
2409444c061aSmrg    }
2410444c061aSmrg    return False;
2411444c061aSmrg}
2412444c061aSmrg
2413444c061aSmrg
2414444c061aSmrg/* ARGSUSED */
2415444c061aSmrgstatic Boolean TopLevelSetValues(
2416444c061aSmrg     Widget oldW, Widget refW, Widget newW,
2417444c061aSmrg     ArgList args,		/* unused */
2418444c061aSmrg     Cardinal *num_args)	/* unused */
2419444c061aSmrg{
2420444c061aSmrg    TopLevelShellWidget old = (TopLevelShellWidget)oldW;
2421444c061aSmrg    TopLevelShellWidget new = (TopLevelShellWidget)newW;
2422444c061aSmrg    Boolean name_changed;
2423444c061aSmrg
2424444c061aSmrg    if (old->topLevel.icon_name != new->topLevel.icon_name) {
2425444c061aSmrg	XtFree((XtPointer)old->topLevel.icon_name);
24260568f49bSmrg	if (! new->topLevel.icon_name) new->topLevel.icon_name = (_XtString) "";
2427444c061aSmrg	new->topLevel.icon_name = XtNewString(new->topLevel.icon_name);
2428444c061aSmrg	name_changed = True;
2429444c061aSmrg    } else
2430444c061aSmrg	name_changed = False;
2431444c061aSmrg
2432444c061aSmrg    if (XtIsRealized(newW)) {
2433444c061aSmrg	if (new->topLevel.iconic != old->topLevel.iconic) {
2434444c061aSmrg	    if (new->topLevel.iconic)
2435444c061aSmrg		XIconifyWindow(XtDisplay(newW),
2436444c061aSmrg			       XtWindow(newW),
2437444c061aSmrg			       XScreenNumberOfScreen(XtScreen(newW))
2438444c061aSmrg			       );
2439444c061aSmrg	    else {
2440444c061aSmrg		Boolean map = new->shell.popped_up;
2441444c061aSmrg		XtPopup(newW, XtGrabNone);
2442444c061aSmrg		if (map) XMapWindow(XtDisplay(newW), XtWindow(newW));
2443444c061aSmrg	    }
2444444c061aSmrg	}
2445444c061aSmrg
2446444c061aSmrg	if (!new->shell.override_redirect &&
2447444c061aSmrg	    (name_changed ||
2448444c061aSmrg	     (old->topLevel.icon_name_encoding
2449444c061aSmrg	      != new->topLevel.icon_name_encoding))) {
2450444c061aSmrg
2451444c061aSmrg	    XTextProperty icon_name;
2452444c061aSmrg	    Boolean copied = False;
2453444c061aSmrg
2454444c061aSmrg            if (new->topLevel.icon_name_encoding == None &&
2455444c061aSmrg		XmbTextListToTextProperty(XtDisplay(newW),
2456444c061aSmrg					  (char**) &new->topLevel.icon_name,
2457444c061aSmrg					  1, XStdICCTextStyle,
2458444c061aSmrg					  &icon_name) >= Success) {
2459444c061aSmrg		copied = True;
2460444c061aSmrg	    } else {
2461444c061aSmrg		icon_name.value = (unsigned char *)new->topLevel.icon_name;
2462444c061aSmrg		icon_name.encoding = new->topLevel.icon_name_encoding ?
2463444c061aSmrg		    new->topLevel.icon_name_encoding : XA_STRING;
2464444c061aSmrg		icon_name.format = 8;
2465444c061aSmrg		icon_name.nitems = strlen((char *)icon_name.value);
2466444c061aSmrg	    }
2467444c061aSmrg	    XSetWMIconName(XtDisplay(newW), XtWindow(newW), &icon_name);
2468444c061aSmrg	    if (copied)
2469444c061aSmrg		XFree((XPointer)icon_name.value);
2470444c061aSmrg	}
2471444c061aSmrg    }
2472bdf0f55dSmrg    else if (new->topLevel.iconic != old->topLevel.iconic) {
2473bdf0f55dSmrg	if (new->topLevel.iconic)
2474bdf0f55dSmrg	    new->wm.wm_hints.initial_state = IconicState;
2475bdf0f55dSmrg    }
2476444c061aSmrg    return False;
2477444c061aSmrg}
2478444c061aSmrg
24790568f49bSmrgstatic _XtString * NewArgv(
2480444c061aSmrg    int count,
24810568f49bSmrg    _XtString *str)  /* do not assume it's terminated by a NULL element */
2482444c061aSmrg{
2483444c061aSmrg    Cardinal nbytes = 0;
2484444c061aSmrg    Cardinal num = 0;
24850568f49bSmrg    _XtString *newarray;
24860568f49bSmrg    _XtString *new;
24870568f49bSmrg    _XtString *strarray = str;
24880568f49bSmrg    _XtString sptr;
2489444c061aSmrg
2490444c061aSmrg    if (count <= 0 || !str) return NULL;
2491444c061aSmrg
24920568f49bSmrg    for (num = (Cardinal) count; num--; str++) {
24930568f49bSmrg	nbytes = (nbytes + (Cardinal) strlen(*str));
2494444c061aSmrg	nbytes++;
2495444c061aSmrg    }
24960568f49bSmrg    num = (Cardinal) ((size_t)(count+1) * sizeof(_XtString));
24970568f49bSmrg    new = newarray = (_XtString *) __XtMalloc(num + nbytes);
2498444c061aSmrg    sptr = ((char *) new) + num;
2499444c061aSmrg
2500444c061aSmrg    for (str = strarray; count--; str++) {
2501444c061aSmrg	*new = sptr;
2502444c061aSmrg	strcpy(*new, *str);
2503444c061aSmrg	new++;
2504444c061aSmrg	sptr = strchr(sptr, '\0');
2505444c061aSmrg	sptr++;
2506444c061aSmrg    }
2507444c061aSmrg    *new = NULL;
2508444c061aSmrg    return newarray;
2509444c061aSmrg}
2510444c061aSmrg
2511444c061aSmrg
2512444c061aSmrg/*ARGSUSED*/
2513444c061aSmrgstatic Boolean ApplicationSetValues(
2514444c061aSmrg    Widget current, Widget request, Widget new,
2515444c061aSmrg    ArgList args,
2516444c061aSmrg    Cardinal *num_args)
2517444c061aSmrg{
2518444c061aSmrg    ApplicationShellWidget nw = (ApplicationShellWidget) new;
2519444c061aSmrg    ApplicationShellWidget cw = (ApplicationShellWidget) current;
2520444c061aSmrg
2521444c061aSmrg    if (cw->application.argc != nw->application.argc ||
2522444c061aSmrg	cw->application.argv != nw->application.argv) {
2523444c061aSmrg
2524444c061aSmrg	if (nw->application.argc > 0)
2525444c061aSmrg	    nw->application.argv = NewArgv(nw->application.argc,
2526444c061aSmrg					   nw->application.argv);
2527444c061aSmrg	if (cw->application.argc > 0)
2528444c061aSmrg	    FreeStringArray(cw->application.argv);
2529444c061aSmrg
2530444c061aSmrg	if (XtIsRealized(new) && !nw->shell.override_redirect) {
2531444c061aSmrg	    if (nw->application.argc >= 0 && nw->application.argv)
2532444c061aSmrg		XSetCommand(XtDisplay(new), XtWindow(new),
2533444c061aSmrg			    nw->application.argv, nw->application.argc);
2534444c061aSmrg	    else
2535444c061aSmrg		XDeleteProperty(XtDisplay(new), XtWindow(new), XA_WM_COMMAND);
2536444c061aSmrg	}
2537444c061aSmrg    }
2538444c061aSmrg    return False;
2539444c061aSmrg}
2540444c061aSmrg
2541444c061aSmrg/*ARGSUSED*/
2542444c061aSmrgstatic Boolean SessionSetValues(
2543444c061aSmrg    Widget current, Widget request, Widget new,
2544444c061aSmrg    ArgList args,
2545444c061aSmrg    Cardinal *num_args)
2546444c061aSmrg{
2547444c061aSmrg#ifndef XT_NO_SM
2548444c061aSmrg    SessionShellWidget nw = (SessionShellWidget) new;
2549444c061aSmrg    SessionShellWidget cw = (SessionShellWidget) current;
2550444c061aSmrg    unsigned long set_mask = 0UL;
2551444c061aSmrg    unsigned long unset_mask = 0UL;
2552444c061aSmrg    Boolean initialize = False;
2553444c061aSmrg
2554444c061aSmrg    if (cw->session.session_id != nw->session.session_id) {
2555444c061aSmrg	nw->session.session_id = XtNewString(nw->session.session_id);
2556444c061aSmrg	XtFree(cw->session.session_id);
2557444c061aSmrg    }
2558444c061aSmrg
2559444c061aSmrg    if (cw->session.clone_command != nw->session.clone_command) {
2560444c061aSmrg	if (nw->session.clone_command) {
2561444c061aSmrg	    nw->session.clone_command =
2562444c061aSmrg		NewStringArray(nw->session.clone_command);
2563444c061aSmrg	    set_mask |= XtCloneCommandMask;
2564444c061aSmrg	} else unset_mask |= XtCloneCommandMask;
2565444c061aSmrg	FreeStringArray(cw->session.clone_command);
2566444c061aSmrg    }
2567444c061aSmrg
2568444c061aSmrg    if (cw->session.current_dir != nw->session.current_dir) {
2569444c061aSmrg	if (nw->session.current_dir) {
2570444c061aSmrg	    nw->session.current_dir =
2571444c061aSmrg		XtNewString(nw->session.current_dir);
2572444c061aSmrg	    set_mask |= XtCurrentDirectoryMask;
2573444c061aSmrg	} else unset_mask |= XtCurrentDirectoryMask;
2574444c061aSmrg	XtFree((char *) cw->session.current_dir);
2575444c061aSmrg    }
2576444c061aSmrg
2577444c061aSmrg    if (cw->session.discard_command != nw->session.discard_command) {
2578444c061aSmrg	if (nw->session.discard_command) {
2579444c061aSmrg	    nw->session.discard_command =
2580444c061aSmrg		NewStringArray(nw->session.discard_command);
2581444c061aSmrg	    set_mask |=  XtDiscardCommandMask;
2582444c061aSmrg	} else unset_mask |= XtDiscardCommandMask;
2583444c061aSmrg	FreeStringArray(cw->session.discard_command);
2584444c061aSmrg    }
2585444c061aSmrg
2586444c061aSmrg    if (cw->session.environment != nw->session.environment) {
2587444c061aSmrg	if (nw->session.environment) {
2588444c061aSmrg	    nw->session.environment =
2589444c061aSmrg		NewStringArray(nw->session.environment);
2590444c061aSmrg	    set_mask |= XtEnvironmentMask;
2591444c061aSmrg	} else unset_mask |= XtEnvironmentMask;
2592444c061aSmrg	FreeStringArray(cw->session.environment);
2593444c061aSmrg    }
2594444c061aSmrg
2595444c061aSmrg    if (cw->session.program_path != nw->session.program_path) {
2596444c061aSmrg	if (nw->session.program_path) {
2597444c061aSmrg	    nw->session.program_path =
2598444c061aSmrg		XtNewString(nw->session.program_path);
2599444c061aSmrg	    set_mask |= XtProgramMask;
2600444c061aSmrg	} else unset_mask |= XtProgramMask;
2601444c061aSmrg	XtFree((char *) cw->session.program_path);
2602444c061aSmrg    }
2603444c061aSmrg
2604444c061aSmrg    if (cw->session.resign_command != nw->session.resign_command) {
2605444c061aSmrg	if (nw->session.resign_command) {
2606444c061aSmrg	    nw->session.resign_command =
2607444c061aSmrg		NewStringArray(nw->session.resign_command);
2608444c061aSmrg	    set_mask |= XtResignCommandMask;
2609444c061aSmrg	} else set_mask |= XtResignCommandMask;
2610444c061aSmrg	FreeStringArray(cw->session.resign_command);
2611444c061aSmrg    }
2612444c061aSmrg
2613444c061aSmrg    if (cw->session.restart_command != nw->session.restart_command) {
2614444c061aSmrg	if (nw->session.restart_command) {
2615444c061aSmrg	    nw->session.restart_command =
2616444c061aSmrg		NewStringArray(nw->session.restart_command);
2617444c061aSmrg	    set_mask |= XtRestartCommandMask;
2618444c061aSmrg	} else unset_mask |= XtRestartCommandMask;
2619444c061aSmrg	FreeStringArray(cw->session.restart_command);
2620444c061aSmrg    }
2621444c061aSmrg
2622444c061aSmrg    if (cw->session.restart_style != nw->session.restart_style)
2623444c061aSmrg	set_mask |= XtRestartStyleHintMask;
2624444c061aSmrg
2625444c061aSmrg    if (cw->session.shutdown_command != nw->session.shutdown_command) {
2626444c061aSmrg	if (nw->session.shutdown_command) {
2627444c061aSmrg	    nw->session.shutdown_command =
2628444c061aSmrg		NewStringArray(nw->session.shutdown_command);
2629444c061aSmrg	    set_mask |= XtShutdownCommandMask;
2630444c061aSmrg	} else unset_mask |= XtShutdownCommandMask;
2631444c061aSmrg	FreeStringArray(cw->session.shutdown_command);
2632444c061aSmrg    }
2633444c061aSmrg
2634444c061aSmrg    if ((!cw->session.join_session && nw->session.join_session) ||
2635444c061aSmrg	(!cw->session.connection && nw->session.connection)) {
2636444c061aSmrg	JoinSession(nw);
2637444c061aSmrg	initialize = True;
2638444c061aSmrg    }
2639444c061aSmrg
2640444c061aSmrg    if (nw->session.connection && (set_mask || unset_mask || initialize))
2641444c061aSmrg	SetSessionProperties((SessionShellWidget) new, initialize, set_mask, unset_mask);
2642444c061aSmrg
2643444c061aSmrg    if ((cw->session.join_session && !nw->session.join_session) ||
2644444c061aSmrg	(cw->session.connection && !nw->session.connection))
2645444c061aSmrg	StopManagingSession(nw, nw->session.connection);
2646444c061aSmrg#endif /* !XT_NO_SM */
2647444c061aSmrg
2648444c061aSmrg    if (cw->wm.client_leader != nw->wm.client_leader ||
2649444c061aSmrg	cw->session.session_id != nw->session.session_id) {
2650444c061aSmrg	Widget leader;
2651444c061aSmrg	if (cw->session.session_id) {
2652444c061aSmrg	    leader = GetClientLeader(current);
2653444c061aSmrg	    if (XtWindow(leader))
2654444c061aSmrg		XDeleteProperty(XtDisplay(leader), XtWindow(leader),
2655444c061aSmrg				XInternAtom(XtDisplay(leader), "SM_CLIENT_ID",
2656444c061aSmrg					    False));
2657444c061aSmrg	}
2658444c061aSmrg	if (nw->session.session_id) {
2659444c061aSmrg	    leader = GetClientLeader(new);
2660444c061aSmrg	    if (XtWindow(leader))
2661444c061aSmrg		XChangeProperty(XtDisplay(leader), XtWindow(leader),
2662444c061aSmrg				XInternAtom(XtDisplay(leader), "SM_CLIENT_ID",
2663444c061aSmrg					    False),
2664444c061aSmrg				XA_STRING, 8, PropModeReplace,
2665444c061aSmrg				(unsigned char *) nw->session.session_id,
26660568f49bSmrg				(int) strlen(nw->session.session_id));
2667444c061aSmrg	}
2668444c061aSmrg    }
2669444c061aSmrg    return False;
2670444c061aSmrg}
2671444c061aSmrg
2672444c061aSmrgvoid _XtShellGetCoordinates(
2673444c061aSmrg    Widget widget,
2674444c061aSmrg    Position* x,
2675444c061aSmrg    Position* y)
2676444c061aSmrg{
2677444c061aSmrg    ShellWidget w = (ShellWidget)widget;
2678444c061aSmrg    if (XtIsRealized(widget) &&
2679444c061aSmrg	!(w->shell.client_specified & _XtShellPositionValid)) {
2680444c061aSmrg	int tmpx, tmpy;
2681444c061aSmrg	Window tmpchild;
2682444c061aSmrg	(void) XTranslateCoordinates(XtDisplay(w), XtWindow(w),
2683444c061aSmrg				     RootWindowOfScreen(XtScreen(w)),
2684444c061aSmrg				     (int) -w->core.border_width,
2685444c061aSmrg				     (int) -w->core.border_width,
2686444c061aSmrg				     &tmpx, &tmpy, &tmpchild);
26870568f49bSmrg	w->core.x = (Position) tmpx;
26880568f49bSmrg	w->core.y = (Position) tmpy;
2689444c061aSmrg	w->shell.client_specified |= _XtShellPositionValid;
2690444c061aSmrg    }
2691444c061aSmrg    *x = w->core.x;
2692444c061aSmrg    *y = w->core.y;
2693444c061aSmrg}
2694444c061aSmrg
2695444c061aSmrgstatic void GetValuesHook(
2696444c061aSmrg    Widget	widget,
2697444c061aSmrg    ArgList	args,
2698444c061aSmrg    Cardinal*	num_args)
2699444c061aSmrg{
2700444c061aSmrg    ShellWidget w = (ShellWidget) widget;
2701444c061aSmrg
2702444c061aSmrg    /* x and y resource values may be invalid after a shell resize */
2703444c061aSmrg    if (XtIsRealized(widget) &&
2704444c061aSmrg	!(w->shell.client_specified & _XtShellPositionValid)) {
2705444c061aSmrg	Cardinal	n;
2706444c061aSmrg	Position	x, y;
2707444c061aSmrg
2708444c061aSmrg	for (n = *num_args; n; n--, args++) {
2709444c061aSmrg	    if (strcmp(XtNx, args->name) == 0) {
2710444c061aSmrg		_XtShellGetCoordinates(widget, &x, &y);
2711444c061aSmrg		_XtCopyToArg((char *) &x, &args->value, sizeof(Position));
2712444c061aSmrg	    } else if (strcmp(XtNy, args->name) == 0) {
2713444c061aSmrg		_XtShellGetCoordinates(widget, &x, &y);
2714444c061aSmrg		_XtCopyToArg((char *) &y, &args->value, sizeof(Position));
2715444c061aSmrg	    }
2716444c061aSmrg	}
2717444c061aSmrg    }
2718444c061aSmrg}
2719444c061aSmrg
2720444c061aSmrgstatic void ApplicationShellInsertChild(
2721444c061aSmrg    Widget widget)
2722444c061aSmrg{
2723444c061aSmrg    if (! XtIsWidget(widget) && XtIsRectObj(widget)) {
2724444c061aSmrg	XtAppWarningMsg(XtWidgetToApplicationContext(widget),
2725444c061aSmrg	       "invalidClass", "applicationShellInsertChild", XtCXtToolkitError,
2726444c061aSmrg	       "ApplicationShell does not accept RectObj children; ignored",
27270568f49bSmrg	       NULL, NULL);
2728444c061aSmrg    }
2729444c061aSmrg    else {
2730444c061aSmrg	XtWidgetProc insert_child;
2731444c061aSmrg
2732444c061aSmrg	LOCK_PROCESS;
2733444c061aSmrg	insert_child =
2734444c061aSmrg	    ((CompositeWidgetClass)applicationShellClassRec.core_class.
2735444c061aSmrg	   superclass)->composite_class.insert_child;
2736444c061aSmrg	UNLOCK_PROCESS;
2737444c061aSmrg	(*insert_child) (widget);
2738444c061aSmrg    }
2739444c061aSmrg}
2740444c061aSmrg
2741444c061aSmrg/**************************************************************************
2742444c061aSmrg
2743444c061aSmrg  Session Protocol Participation
2744444c061aSmrg
2745444c061aSmrg *************************************************************************/
2746444c061aSmrg
2747444c061aSmrg#define XtSessionCheckpoint	0
2748444c061aSmrg#define XtSessionInteract	1
2749444c061aSmrg
2750444c061aSmrgstatic void CallSaveCallbacks(SessionShellWidget );
27510568f49bSmrgstatic _XtString *EditCommand(_XtString, _XtString *, _XtString *);
2752444c061aSmrgstatic Boolean ExamineToken(XtPointer);
2753444c061aSmrgstatic void GetIceEvent(XtPointer, int *, XtInputId *);
2754444c061aSmrgstatic XtCheckpointToken GetToken(Widget, int);
2755444c061aSmrgstatic void XtCallCancelCallbacks(SmcConn, SmPointer);
2756444c061aSmrgstatic void XtCallDieCallbacks(SmcConn, SmPointer);
2757444c061aSmrgstatic void XtCallSaveCallbacks(SmcConn, SmPointer, int, Bool, int, Bool);
2758444c061aSmrgstatic void XtCallSaveCompleteCallbacks(SmcConn, SmPointer);
2759444c061aSmrg
2760444c061aSmrg#ifndef XT_NO_SM
2761444c061aSmrgstatic void StopManagingSession(
2762444c061aSmrg    SessionShellWidget w,
2763444c061aSmrg    SmcConn connection) /* connection to close, if any */
2764444c061aSmrg{
2765444c061aSmrg    if (connection)
2766444c061aSmrg	SmcCloseConnection(connection, 0, NULL);
2767444c061aSmrg
2768444c061aSmrg    if (w->session.input_id) {
2769444c061aSmrg	XtRemoveInput(w->session.input_id);
2770444c061aSmrg	w->session.input_id = 0;
2771444c061aSmrg    }
2772444c061aSmrg    w->session.connection = NULL;
2773444c061aSmrg}
2774444c061aSmrg
2775444c061aSmrg#define XT_MSG_LENGTH 256
2776444c061aSmrgstatic void JoinSession(
2777444c061aSmrg    SessionShellWidget w)
2778444c061aSmrg{
2779444c061aSmrg    IceConn ice_conn;
2780444c061aSmrg    SmcCallbacks smcb;
2781444c061aSmrg    char * sm_client_id;
2782444c061aSmrg    unsigned long mask;
2783444c061aSmrg    static char context;  /* used to guarantee the connection isn't shared */
2784444c061aSmrg
2785444c061aSmrg    smcb.save_yourself.callback = XtCallSaveCallbacks;
2786444c061aSmrg    smcb.die.callback = XtCallDieCallbacks;
2787444c061aSmrg    smcb.save_complete.callback = XtCallSaveCompleteCallbacks;
2788444c061aSmrg    smcb.shutdown_cancelled.callback = XtCallCancelCallbacks;
2789444c061aSmrg    smcb.save_yourself.client_data = smcb.die.client_data =
2790444c061aSmrg	smcb.save_complete.client_data =
2791444c061aSmrg	    smcb.shutdown_cancelled.client_data = (SmPointer) w;
2792444c061aSmrg    mask = SmcSaveYourselfProcMask | SmcDieProcMask |
2793444c061aSmrg	SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask;
2794444c061aSmrg
2795444c061aSmrg    if (w->session.connection) {
2796444c061aSmrg	SmcModifyCallbacks(w->session.connection, mask, &smcb);
2797444c061aSmrg	sm_client_id = SmcClientID(w->session.connection);
2798444c061aSmrg    } else if (getenv("SESSION_MANAGER")) {
2799444c061aSmrg	char error_msg[XT_MSG_LENGTH];
2800444c061aSmrg	error_msg[0] = '\0';
2801444c061aSmrg	w->session.connection =
2802444c061aSmrg	    SmcOpenConnection(NULL, &context, SmProtoMajor, SmProtoMinor,
2803444c061aSmrg			      mask, &smcb, w->session.session_id,
2804444c061aSmrg			      &sm_client_id, XT_MSG_LENGTH, error_msg);
2805444c061aSmrg	if (error_msg[0]) {
2806444c061aSmrg	    String params[1];
2807444c061aSmrg	    Cardinal num_params = 1;
2808444c061aSmrg	    params[0] = error_msg;
2809444c061aSmrg	    XtAppWarningMsg(XtWidgetToApplicationContext((Widget) w),
2810444c061aSmrg			    "sessionManagement", "SmcOpenConnection",
2811444c061aSmrg			    XtCXtToolkitError,
2812444c061aSmrg			    "Tried to connect to session manager, %s",
2813444c061aSmrg			    params, &num_params);
2814444c061aSmrg	}
2815444c061aSmrg    }
2816444c061aSmrg
2817444c061aSmrg    if (w->session.connection) {
2818444c061aSmrg	if (w->session.session_id == NULL
2819444c061aSmrg	    || (strcmp(w->session.session_id, sm_client_id) != 0)) {
2820444c061aSmrg	    XtFree(w->session.session_id);
2821444c061aSmrg	    w->session.session_id = XtNewString(sm_client_id);
2822444c061aSmrg	}
2823444c061aSmrg	free(sm_client_id);
2824444c061aSmrg	ice_conn = SmcGetIceConnection(w->session.connection);
2825444c061aSmrg	w->session.input_id =
2826444c061aSmrg	    XtAppAddInput(XtWidgetToApplicationContext((Widget)w),
2827444c061aSmrg			  IceConnectionNumber(ice_conn),
2828444c061aSmrg			  (XtPointer) XtInputReadMask,
2829444c061aSmrg			  GetIceEvent, (XtPointer) w);
2830444c061aSmrg
2831444c061aSmrg	w->session.restart_command =
2832444c061aSmrg	    EditCommand(w->session.session_id, w->session.restart_command,
2833444c061aSmrg			w->application.argv);
2834444c061aSmrg
2835444c061aSmrg	if (! w->session.clone_command) w->session.clone_command =
2836444c061aSmrg	    EditCommand(NULL, NULL, w->session.restart_command);
2837444c061aSmrg
2838444c061aSmrg	if (! w->session.program_path)
2839444c061aSmrg	    w->session.program_path = w->session.restart_command
2840444c061aSmrg		? XtNewString(w->session.restart_command[0]) : NULL;
2841444c061aSmrg    }
2842444c061aSmrg}
2843444c061aSmrg#undef XT_MSG_LENGTH
2844444c061aSmrg
2845444c061aSmrg#endif /* !XT_NO_SM */
2846444c061aSmrg
28470568f49bSmrgstatic _XtString * NewStringArray(_XtString *str)
2848444c061aSmrg{
2849444c061aSmrg    Cardinal nbytes = 0;
2850444c061aSmrg    Cardinal num = 0;
28510568f49bSmrg    _XtString *newarray;
28520568f49bSmrg    _XtString *new;
28530568f49bSmrg    _XtString *strarray = str;
28540568f49bSmrg    _XtString sptr;
2855444c061aSmrg
2856444c061aSmrg    if (!str) return NULL;
2857444c061aSmrg
2858444c061aSmrg    for (num = 0; *str; num++, str++) {
28590568f49bSmrg	nbytes = nbytes + (Cardinal)strlen(*str);
2860444c061aSmrg	nbytes++;
2861444c061aSmrg    }
28620568f49bSmrg    num = (Cardinal)((size_t)(num + 1) * sizeof(_XtString));
28630568f49bSmrg    new = newarray = (_XtString *) __XtMalloc(num + nbytes);
2864444c061aSmrg    sptr = ((char *) new) + num;
2865444c061aSmrg
2866444c061aSmrg    for (str = strarray; *str; str++) {
2867444c061aSmrg	*new = sptr;
2868444c061aSmrg	strcpy(*new, *str);
2869444c061aSmrg	new++;
2870444c061aSmrg	sptr = strchr(sptr, '\0');
2871444c061aSmrg	sptr++;
2872444c061aSmrg    }
2873444c061aSmrg    *new = NULL;
2874444c061aSmrg    return newarray;
2875444c061aSmrg}
2876444c061aSmrg
28770568f49bSmrgstatic void FreeStringArray(_XtString *str)
2878444c061aSmrg{
2879444c061aSmrg    if (str)
28800568f49bSmrg	XtFree((_XtString) str);
2881444c061aSmrg}
2882444c061aSmrg
2883444c061aSmrg
2884444c061aSmrg#ifndef XT_NO_SM
2885444c061aSmrgstatic SmProp * CardPack(
28860568f49bSmrg    _Xconst _XtString name,
2887444c061aSmrg    XtPointer closure)
2888444c061aSmrg{
2889444c061aSmrg    unsigned char *prop = (unsigned char *) closure;
2890444c061aSmrg    SmProp *p;
2891444c061aSmrg
2892444c061aSmrg    p = (SmProp *) __XtMalloc(sizeof(SmProp) + sizeof(SmPropValue));
2893444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
2894444c061aSmrg    p->num_vals = 1;
28950568f49bSmrg    p->type = (char *)SmCARD8;
28960568f49bSmrg    p->name = (char *)name;
2897444c061aSmrg    p->vals->length = 1;
2898444c061aSmrg    p->vals->value = (SmPointer) prop;
2899444c061aSmrg    return p;
2900444c061aSmrg}
2901444c061aSmrg
29020568f49bSmrgstatic SmProp * ArrayPack(_Xconst _XtString name, XtPointer closure)
2903444c061aSmrg{
29040568f49bSmrg    _XtString prop = *(_XtString *) closure;
2905444c061aSmrg    SmProp *p;
2906444c061aSmrg
2907444c061aSmrg    p = (SmProp *) __XtMalloc(sizeof(SmProp) + sizeof(SmPropValue));
2908444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
2909444c061aSmrg    p->num_vals = 1;
29100568f49bSmrg    p->type = (char *)SmARRAY8;
29110568f49bSmrg    p->name = (char *) name;
29120568f49bSmrg    p->vals->length = (int) strlen(prop) + 1;
2913444c061aSmrg    p->vals->value = prop;
2914444c061aSmrg    return p;
2915444c061aSmrg}
2916444c061aSmrg
2917444c061aSmrgstatic SmProp * ListPack(
29180568f49bSmrg    _Xconst _XtString name,
2919444c061aSmrg    XtPointer closure)
2920444c061aSmrg{
29210568f49bSmrg    _XtString *prop = *(_XtString **) closure;
2922444c061aSmrg    SmProp *p;
29230568f49bSmrg    _XtString *ptr;
2924444c061aSmrg    SmPropValue *vals;
2925444c061aSmrg    int n = 0;
2926444c061aSmrg
2927444c061aSmrg    for (ptr = prop; *ptr; ptr++)
2928444c061aSmrg	n++;
29290568f49bSmrg    p = (SmProp*) __XtMalloc((Cardinal)(sizeof(SmProp) + (size_t)n * sizeof(SmPropValue)));
2930444c061aSmrg    p->vals = (SmPropValue *) (((char *) p) + sizeof(SmProp));
2931444c061aSmrg    p->num_vals = n;
29320568f49bSmrg    p->type = (char *)SmLISTofARRAY8;
29330568f49bSmrg    p->name = (char *)name;
2934444c061aSmrg    for (ptr = prop, vals = p->vals; *ptr; ptr++, vals++) {
29350568f49bSmrg	vals->length = (int) strlen(*ptr) + 1;
2936444c061aSmrg	vals->value = *ptr;
2937444c061aSmrg    }
2938444c061aSmrg    return p;
2939444c061aSmrg}
2940444c061aSmrg
2941444c061aSmrgstatic void FreePacks(
2942444c061aSmrg    SmProp **props,
2943444c061aSmrg    int num_props)
2944444c061aSmrg{
2945444c061aSmrg    while (--num_props >= 0)
2946444c061aSmrg	XtFree((char *) props[num_props]);
2947444c061aSmrg}
2948444c061aSmrg
29490568f49bSmrgtypedef SmProp* (*PackProc)(_Xconst _XtString, XtPointer);
2950444c061aSmrg
2951444c061aSmrgtypedef struct PropertyRec {
29520568f49bSmrg    String	name;
2953444c061aSmrg    int		offset;
2954444c061aSmrg    PackProc	proc;
2955444c061aSmrg} PropertyRec, *PropertyTable;
2956444c061aSmrg
2957444c061aSmrg#define Offset(x) (XtOffsetOf(SessionShellRec, x))
2958444c061aSmrgstatic PropertyRec propertyTable[] = {
2959444c061aSmrg  {SmCloneCommand,     Offset(session.clone_command),    ListPack},
2960444c061aSmrg  {SmCurrentDirectory, Offset(session.current_dir),      ArrayPack},
2961444c061aSmrg  {SmDiscardCommand,   Offset(session.discard_command),  ListPack},
2962444c061aSmrg  {SmEnvironment,      Offset(session.environment),      ListPack},
2963444c061aSmrg  {SmProgram,          Offset(session.program_path),     ArrayPack},
2964444c061aSmrg  {SmResignCommand,    Offset(session.resign_command),   ListPack},
2965444c061aSmrg  {SmRestartCommand,   Offset(session.restart_command),  ListPack},
2966444c061aSmrg  {SmRestartStyleHint, Offset(session.restart_style),    CardPack},
2967444c061aSmrg  {SmShutdownCommand,  Offset(session.shutdown_command), ListPack}
2968444c061aSmrg};
2969444c061aSmrg#undef Offset
2970444c061aSmrg
2971444c061aSmrg#define XT_NUM_SM_PROPS 11
2972444c061aSmrg
2973444c061aSmrgstatic void SetSessionProperties(
2974444c061aSmrg    SessionShellWidget w,
2975444c061aSmrg    Boolean initialize,
2976444c061aSmrg    unsigned long set_mask,
2977444c061aSmrg    unsigned long unset_mask)
2978444c061aSmrg{
2979444c061aSmrg    PropertyTable p = propertyTable;
2980444c061aSmrg    int n;
2981444c061aSmrg    int num_props = 0;
2982444c061aSmrg    XtPointer *addr;
2983444c061aSmrg    unsigned long mask;
2984444c061aSmrg    SmProp *props[XT_NUM_SM_PROPS];
2985444c061aSmrg
2986444c061aSmrg    if (w->session.connection == NULL)
2987444c061aSmrg	return;
2988444c061aSmrg
2989444c061aSmrg    if (initialize) {
2990444c061aSmrg	char nam_buf[32];
2991444c061aSmrg	char pid[12];
2992444c061aSmrg	String user_name;
2993444c061aSmrg	String pidp = pid;
2994444c061aSmrg
2995444c061aSmrg	/* set all non-NULL session properties, the UserID and the ProcessID */
2996444c061aSmrg	for (n = XtNumber(propertyTable); n; n--, p++) {
2997444c061aSmrg	    addr = (XtPointer *) ((char *) w + p->offset);
2998444c061aSmrg	    if (p->proc == CardPack) {
2999444c061aSmrg		if (*(unsigned char *)addr)
3000444c061aSmrg		    props[num_props++] =(*(p->proc))(p->name, (XtPointer)addr);
3001444c061aSmrg	    }
3002444c061aSmrg	    else if (* addr)
3003444c061aSmrg		props[num_props++] = (*(p->proc))(p->name, (XtPointer)addr);
3004444c061aSmrg
3005444c061aSmrg	}
3006444c061aSmrg	user_name = _XtGetUserName(nam_buf, sizeof nam_buf);
3007444c061aSmrg	if (user_name)
3008444c061aSmrg	    props[num_props++] = ArrayPack(SmUserID, &user_name);
3009bdf0f55dSmrg	snprintf(pid, sizeof(pid), "%ld", (long)getpid());
3010444c061aSmrg	props[num_props++] = ArrayPack(SmProcessID, &pidp);
3011444c061aSmrg
3012444c061aSmrg	if (num_props) {
3013444c061aSmrg	    SmcSetProperties(w->session.connection, num_props, props);
3014444c061aSmrg	    FreePacks(props, num_props);
3015444c061aSmrg	}
3016444c061aSmrg	return;
3017444c061aSmrg    }
3018444c061aSmrg
3019444c061aSmrg    if (set_mask) {
3020444c061aSmrg	mask = 1L;
3021444c061aSmrg	for (n = XtNumber(propertyTable); n; n--, p++, mask <<= 1)
3022444c061aSmrg	    if (mask & set_mask) {
3023444c061aSmrg		addr = (XtPointer *) ((char *) w + p->offset);
3024444c061aSmrg		props[num_props++] = (*(p->proc))(p->name, (XtPointer)addr);
3025444c061aSmrg	    }
3026444c061aSmrg	SmcSetProperties(w->session.connection, num_props, props);
3027444c061aSmrg	FreePacks(props, num_props);
3028444c061aSmrg    }
3029444c061aSmrg
3030444c061aSmrg    if (unset_mask) {
30310568f49bSmrg	char *pnames[XT_NUM_SM_PROPS];
30320568f49bSmrg
3033444c061aSmrg	mask = 1L;
3034444c061aSmrg	num_props = 0;
3035444c061aSmrg	for (n = XtNumber(propertyTable); n; n--, p++, mask <<= 1)
3036444c061aSmrg	    if (mask & unset_mask)
30370568f49bSmrg		pnames[num_props++] = (char *)p->name;
3038444c061aSmrg	SmcDeleteProperties(w->session.connection, num_props, pnames);
3039444c061aSmrg    }
3040444c061aSmrg}
3041444c061aSmrg
3042444c061aSmrg/*ARGSUSED*/
3043444c061aSmrgstatic void GetIceEvent(
3044444c061aSmrg    XtPointer	client_data,
3045444c061aSmrg    int *	source,
3046444c061aSmrg    XtInputId *	id)
3047444c061aSmrg{
3048444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3049444c061aSmrg    IceProcessMessagesStatus status;
3050444c061aSmrg
3051444c061aSmrg    status = IceProcessMessages(SmcGetIceConnection(w->session.connection),
3052444c061aSmrg				NULL, NULL);
3053444c061aSmrg
3054444c061aSmrg    if (status == IceProcessMessagesIOError) {
3055444c061aSmrg	StopManagingSession(w, w->session.connection);
3056444c061aSmrg	XtCallCallbackList((Widget)w, w->session.error_callbacks,
3057444c061aSmrg			   (XtPointer) NULL);
3058444c061aSmrg    }
3059444c061aSmrg}
3060444c061aSmrg
3061444c061aSmrgstatic void CleanUpSave(
3062444c061aSmrg    SessionShellWidget w)
3063444c061aSmrg{
3064444c061aSmrg    XtSaveYourself next = w->session.save->next;
3065444c061aSmrg    XtFree((char *)w->session.save);
3066444c061aSmrg    w->session.save = next;
3067444c061aSmrg    if (w->session.save)
3068444c061aSmrg	CallSaveCallbacks(w);
3069444c061aSmrg}
3070444c061aSmrg
3071444c061aSmrgstatic void CallSaveCallbacks(
3072444c061aSmrg    SessionShellWidget w)
3073444c061aSmrg{
3074444c061aSmrg    if (XtHasCallbacks((Widget) w, XtNsaveCallback) != XtCallbackHasSome) {
3075444c061aSmrg	/* if the application makes no attempt to save state, report failure */
3076444c061aSmrg	SmcSaveYourselfDone(w->session.connection, False);
3077444c061aSmrg	CleanUpSave(w);
3078444c061aSmrg    } else {
30790568f49bSmrg	XtCheckpointToken token;
30800568f49bSmrg
3081444c061aSmrg	w->session.checkpoint_state = XtSaveActive;
3082444c061aSmrg	token = GetToken((Widget) w, XtSessionCheckpoint);
3083444c061aSmrg	_XtCallConditionalCallbackList((Widget)w, w->session.save_callbacks,
3084444c061aSmrg				       (XtPointer)token, ExamineToken);
3085444c061aSmrg	XtSessionReturnToken(token);
3086444c061aSmrg    }
3087444c061aSmrg}
3088444c061aSmrg
3089444c061aSmrg/*ARGSUSED*/
3090444c061aSmrgstatic void XtCallSaveCallbacks(
3091444c061aSmrg    SmcConn	connection,	/* unused */
3092444c061aSmrg    SmPointer	client_data,
3093444c061aSmrg    int		save_type,
3094444c061aSmrg    Bool	shutdown,
3095444c061aSmrg    int		interact,
3096444c061aSmrg    Bool	fast)
3097444c061aSmrg{
3098444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3099444c061aSmrg    XtSaveYourself save;
3100444c061aSmrg    XtSaveYourself prev;
3101444c061aSmrg
3102444c061aSmrg    save = XtNew(XtSaveYourselfRec);
3103444c061aSmrg    save->next = NULL;
3104444c061aSmrg    save->save_type = save_type;
3105444c061aSmrg    save->interact_style = interact;
31060568f49bSmrg    save->shutdown = (Boolean) shutdown;
31070568f49bSmrg    save->fast = (Boolean) fast;
3108444c061aSmrg    save->cancel_shutdown = False;
3109444c061aSmrg    save->phase = 1;
3110444c061aSmrg    save->interact_dialog_type = SmDialogNormal;
3111444c061aSmrg    save->request_cancel = save->request_next_phase = False;
3112444c061aSmrg    save->save_success = True;
3113444c061aSmrg    save->save_tokens = save->interact_tokens = 0;
3114444c061aSmrg
3115444c061aSmrg    prev = (XtSaveYourself) &w->session.save;
3116444c061aSmrg    while (prev->next)
3117444c061aSmrg	prev = prev->next;
3118444c061aSmrg    prev->next = save;
3119444c061aSmrg
3120444c061aSmrg    if (w->session.checkpoint_state == XtSaveInactive)
3121444c061aSmrg	CallSaveCallbacks(w);
3122444c061aSmrg}
3123444c061aSmrg
3124444c061aSmrgstatic void XtInteractPermission(
3125444c061aSmrg    SmcConn	connection,
3126444c061aSmrg    SmPointer	data)
3127444c061aSmrg{
3128444c061aSmrg    Widget w = (Widget) data;
3129444c061aSmrg    SessionShellWidget sw = (SessionShellWidget) data;
3130444c061aSmrg    XtCallbackProc callback;
3131444c061aSmrg    XtPointer client_data;
3132444c061aSmrg
3133444c061aSmrg
3134444c061aSmrg    _XtPeekCallback(w, sw->session.interact_callbacks, &callback,
3135444c061aSmrg		    &client_data);
3136444c061aSmrg    if (callback) {
31370568f49bSmrg	XtCheckpointToken token;
31380568f49bSmrg
3139444c061aSmrg	sw->session.checkpoint_state = XtInteractActive;
3140444c061aSmrg	token = GetToken(w, XtSessionInteract);
3141444c061aSmrg    	XtRemoveCallback(w, XtNinteractCallback, callback, client_data);
3142444c061aSmrg	(*callback)(w, client_data, (XtPointer) token);
3143444c061aSmrg    } else if (! sw->session.save->cancel_shutdown) {
3144444c061aSmrg	SmcInteractDone(connection, False);
3145444c061aSmrg    }
3146444c061aSmrg}
3147444c061aSmrg
3148444c061aSmrg/*ARGSUSED*/
3149444c061aSmrgstatic void XtCallSaveCompleteCallbacks(
3150444c061aSmrg    SmcConn	connection,
3151444c061aSmrg    SmPointer	client_data)
3152444c061aSmrg{
3153444c061aSmrg    SessionShellWidget w =  (SessionShellWidget) client_data;
3154444c061aSmrg
3155444c061aSmrg    XtCallCallbackList((Widget)w, w->session.save_complete_callbacks,
3156444c061aSmrg		       (XtPointer) NULL);
3157444c061aSmrg}
3158444c061aSmrg
3159444c061aSmrg/*ARGSUSED*/
3160444c061aSmrgstatic void XtCallNextPhaseCallbacks(
3161444c061aSmrg    SmcConn	connection,	/* unused */
3162444c061aSmrg    SmPointer	client_data)
3163444c061aSmrg{
3164444c061aSmrg    SessionShellWidget w =  (SessionShellWidget) client_data;
3165444c061aSmrg    w->session.save->phase = 2;
3166444c061aSmrg    CallSaveCallbacks(w);
3167444c061aSmrg}
3168444c061aSmrg
3169444c061aSmrg/*ARGSUSED*/
3170444c061aSmrgstatic void XtCallDieCallbacks(
3171444c061aSmrg    SmcConn	connection,	/* unused */
3172444c061aSmrg    SmPointer	client_data)
3173444c061aSmrg{
3174444c061aSmrg    SessionShellWidget w =  (SessionShellWidget) client_data;
3175444c061aSmrg
3176444c061aSmrg    StopManagingSession(w, w->session.connection);
3177444c061aSmrg    XtCallCallbackList((Widget)w, w->session.die_callbacks,
3178444c061aSmrg		       (XtPointer) NULL);
3179444c061aSmrg}
3180444c061aSmrg
3181444c061aSmrg/*ARGSUSED*/
3182444c061aSmrgstatic void XtCallCancelCallbacks(
3183444c061aSmrg    SmcConn	connection,	/* unused */
3184444c061aSmrg    SmPointer	client_data)
3185444c061aSmrg{
3186444c061aSmrg    SessionShellWidget w = (SessionShellWidget) client_data;
3187444c061aSmrg    Boolean call_interacts = False;
3188444c061aSmrg
3189444c061aSmrg    if (w->session.checkpoint_state != XtSaveInactive) {
3190444c061aSmrg	w->session.save->cancel_shutdown = True;
3191444c061aSmrg	call_interacts = (w->session.save->interact_style !=
3192444c061aSmrg			  SmInteractStyleNone);
3193444c061aSmrg    }
3194444c061aSmrg
3195444c061aSmrg    XtCallCallbackList((Widget)w, w->session.cancel_callbacks,
3196444c061aSmrg		       (XtPointer) NULL);
3197444c061aSmrg
3198444c061aSmrg    if (call_interacts) {
3199444c061aSmrg	w->session.save->interact_style = SmInteractStyleNone;
3200444c061aSmrg	XtInteractPermission(w->session.connection, (SmPointer) w);
3201444c061aSmrg    }
3202444c061aSmrg
3203444c061aSmrg    if (w->session.checkpoint_state != XtSaveInactive) {
3204444c061aSmrg	if (w->session.save->save_tokens == 0 &&
3205444c061aSmrg	    w->session.checkpoint_state == XtSaveActive) {
3206444c061aSmrg	    w->session.checkpoint_state = XtSaveInactive;
3207444c061aSmrg	    SmcSaveYourselfDone(w->session.connection,
3208444c061aSmrg				w->session.save->save_success);
3209444c061aSmrg	    CleanUpSave(w);
3210444c061aSmrg	}
3211444c061aSmrg    }
3212444c061aSmrg}
3213444c061aSmrg
3214444c061aSmrgstatic XtCheckpointToken GetToken(
3215444c061aSmrg    Widget	widget,
3216444c061aSmrg    int		type)
3217444c061aSmrg{
3218444c061aSmrg    SessionShellWidget w = (SessionShellWidget) widget;
3219444c061aSmrg    XtCheckpointToken token;
3220444c061aSmrg    XtSaveYourself save = w->session.save;
3221444c061aSmrg
3222444c061aSmrg    if (type == XtSessionCheckpoint)
3223444c061aSmrg	w->session.save->save_tokens++;
3224444c061aSmrg    else if (type == XtSessionInteract)
3225444c061aSmrg	w->session.save->interact_tokens++;
3226444c061aSmrg    else
3227444c061aSmrg	return (XtCheckpointToken) NULL;
3228444c061aSmrg
3229444c061aSmrg    token = (XtCheckpointToken) __XtMalloc(sizeof(XtCheckpointTokenRec));
3230444c061aSmrg    token->save_type = save->save_type;
3231444c061aSmrg    token->interact_style = save->interact_style;
3232444c061aSmrg    token->shutdown = save->shutdown;
3233444c061aSmrg    token->fast = save->fast;
3234444c061aSmrg    token->cancel_shutdown = save->cancel_shutdown;
3235444c061aSmrg    token->phase = save->phase;
3236444c061aSmrg    token->interact_dialog_type = save->interact_dialog_type;
3237444c061aSmrg    token->request_cancel = save->request_cancel;
3238444c061aSmrg    token->request_next_phase = save->request_next_phase;
3239444c061aSmrg    token->save_success = save->save_success;
3240444c061aSmrg    token->type = type;
3241444c061aSmrg    token->widget = widget;
3242444c061aSmrg    return token;
3243444c061aSmrg}
3244444c061aSmrg
3245444c061aSmrgXtCheckpointToken XtSessionGetToken(Widget widget)
3246444c061aSmrg{
3247444c061aSmrg    SessionShellWidget w = (SessionShellWidget) widget;
3248444c061aSmrg    XtCheckpointToken token = NULL;
3249444c061aSmrg    WIDGET_TO_APPCON(widget);
3250444c061aSmrg
3251444c061aSmrg    LOCK_APP(app);
3252444c061aSmrg    if (w->session.checkpoint_state)
3253444c061aSmrg	token = GetToken(widget, XtSessionCheckpoint);
3254444c061aSmrg
3255444c061aSmrg    UNLOCK_APP(app);
3256444c061aSmrg    return token;
3257444c061aSmrg}
3258444c061aSmrg
3259444c061aSmrgstatic Boolean ExamineToken(
3260444c061aSmrg    XtPointer	call_data)
3261444c061aSmrg{
3262444c061aSmrg    XtCheckpointToken token = (XtCheckpointToken) call_data;
3263444c061aSmrg    SessionShellWidget w = (SessionShellWidget) token->widget;
3264444c061aSmrg
3265444c061aSmrg    if (token->interact_dialog_type == SmDialogError)
3266444c061aSmrg	w->session.save->interact_dialog_type = SmDialogError;
3267444c061aSmrg    if (token->request_next_phase)
3268444c061aSmrg	w->session.save->request_next_phase = True;
3269444c061aSmrg    if (! token->save_success)
3270444c061aSmrg	w->session.save->save_success = False;
3271444c061aSmrg
3272444c061aSmrg    token->interact_dialog_type = w->session.save->interact_dialog_type;
3273444c061aSmrg    token->request_next_phase = w->session.save->request_next_phase;
3274444c061aSmrg    token->save_success = w->session.save->save_success;
3275444c061aSmrg    token->cancel_shutdown = w->session.save->cancel_shutdown;
3276444c061aSmrg
3277444c061aSmrg    return True;
3278444c061aSmrg}
3279444c061aSmrg
3280444c061aSmrgvoid XtSessionReturnToken(XtCheckpointToken token)
3281444c061aSmrg{
3282444c061aSmrg    SessionShellWidget w = (SessionShellWidget) token->widget;
3283444c061aSmrg    Boolean has_some;
3284444c061aSmrg    Boolean phase_done;
3285444c061aSmrg    XtCallbackProc callback;
3286444c061aSmrg    XtPointer client_data;
3287444c061aSmrg    WIDGET_TO_APPCON((Widget)w);
3288444c061aSmrg
3289444c061aSmrg    LOCK_APP(app);
3290444c061aSmrg
3291444c061aSmrg    has_some = (XtHasCallbacks(token->widget, XtNinteractCallback)
3292444c061aSmrg		== XtCallbackHasSome);
3293444c061aSmrg
3294444c061aSmrg    (void) ExamineToken((XtPointer) token);
3295444c061aSmrg
3296444c061aSmrg    if (token->type == XtSessionCheckpoint) {
3297444c061aSmrg	w->session.save->save_tokens--;
3298444c061aSmrg	if (has_some && w->session.checkpoint_state == XtSaveActive) {
3299444c061aSmrg	    w->session.checkpoint_state = XtInteractPending;
3300444c061aSmrg	    SmcInteractRequest(w->session.connection,
3301444c061aSmrg			       w->session.save->interact_dialog_type,
3302444c061aSmrg			       XtInteractPermission, (SmPointer) w);
3303444c061aSmrg	}
3304444c061aSmrg	XtFree((char*) token);
3305444c061aSmrg    } else {
3306444c061aSmrg	if (token->request_cancel)
3307444c061aSmrg	    w->session.save->request_cancel = True;
3308444c061aSmrg	token->request_cancel = w->session.save->request_cancel;
3309444c061aSmrg	if (has_some) {
3310444c061aSmrg	    _XtPeekCallback((Widget)w, w->session.interact_callbacks,
3311444c061aSmrg			    &callback, &client_data);
3312444c061aSmrg	    XtRemoveCallback((Widget)w, XtNinteractCallback,
3313444c061aSmrg			     callback, client_data);
3314444c061aSmrg	    (*callback)((Widget)w, client_data, (XtPointer)token);
3315444c061aSmrg	} else {
3316444c061aSmrg	    w->session.save->interact_tokens--;
3317444c061aSmrg	    if (w->session.save->interact_tokens == 0) {
3318444c061aSmrg		w->session.checkpoint_state = XtSaveActive;
3319444c061aSmrg		if (! w->session.save->cancel_shutdown)
3320444c061aSmrg		    SmcInteractDone(w->session.connection,
3321444c061aSmrg				    w->session.save->request_cancel);
3322444c061aSmrg	    }
3323444c061aSmrg	    XtFree((char *) token);
3324444c061aSmrg	}
3325444c061aSmrg    }
3326444c061aSmrg
3327444c061aSmrg    phase_done = (w->session.save->save_tokens == 0 &&
3328444c061aSmrg		  w->session.checkpoint_state == XtSaveActive);
3329444c061aSmrg
3330444c061aSmrg    if (phase_done) {
3331444c061aSmrg	if (w->session.save->request_next_phase &&
3332444c061aSmrg	    w->session.save->phase == 1) {
3333444c061aSmrg	    SmcRequestSaveYourselfPhase2(w->session.connection,
3334444c061aSmrg					 XtCallNextPhaseCallbacks,
3335444c061aSmrg					 (SmPointer)w);
3336444c061aSmrg	} else {
3337444c061aSmrg	    w->session.checkpoint_state = XtSaveInactive;
3338444c061aSmrg	    SmcSaveYourselfDone(w->session.connection,
3339444c061aSmrg				w->session.save->save_success);
3340444c061aSmrg	    CleanUpSave(w);
3341444c061aSmrg	}
3342444c061aSmrg    }
3343444c061aSmrg
3344444c061aSmrg    UNLOCK_APP(app);
3345444c061aSmrg}
3346444c061aSmrg
3347444c061aSmrgstatic Boolean IsInArray(
3348444c061aSmrg    String str,
33490568f49bSmrg    _XtString *sarray)
3350444c061aSmrg{
3351444c061aSmrg    if (str == NULL || sarray == NULL)
3352444c061aSmrg	return False;
3353444c061aSmrg    for (; *sarray; sarray++) {
3354444c061aSmrg	if (strcmp(*sarray, str) == 0)
3355444c061aSmrg	    return True;
3356444c061aSmrg    }
3357444c061aSmrg    return False;
3358444c061aSmrg}
3359444c061aSmrg
33600568f49bSmrgstatic _XtString* EditCommand(
33610568f49bSmrg    _XtString str,		/* if not NULL, the sm_client_id */
33620568f49bSmrg    _XtString *src1,	/* first choice */
33630568f49bSmrg    _XtString *src2)	/* alternate */
3364444c061aSmrg{
3365444c061aSmrg    Boolean have;
3366444c061aSmrg    Boolean want;
3367444c061aSmrg    int count;
33680568f49bSmrg    _XtString *sarray;
33690568f49bSmrg    _XtString *s;
33700568f49bSmrg    _XtString *new;
3371444c061aSmrg
3372444c061aSmrg    want = (str != NULL);
3373444c061aSmrg    sarray = (src1 ? src1 : src2);
3374444c061aSmrg    if (! sarray) return NULL;
3375444c061aSmrg    have = IsInArray("-xtsessionID", sarray);
3376444c061aSmrg    if ((want && have) || (!want && !have)) {
3377444c061aSmrg	if (sarray == src1)
3378444c061aSmrg	    return src1;
3379444c061aSmrg	else
3380444c061aSmrg	    return NewStringArray(sarray);
3381444c061aSmrg    }
3382444c061aSmrg
3383444c061aSmrg    count = 0;
3384444c061aSmrg    for (s = sarray; *s; s++)
3385444c061aSmrg	count++;
3386444c061aSmrg
3387444c061aSmrg    if (want) {
33880568f49bSmrg	s = new = (_XtString *) __XtMalloc((Cardinal)((size_t) (count+3) * sizeof(_XtString*)));
33890568f49bSmrg	*s = *sarray;				s++; sarray++;
33900568f49bSmrg	*s = (_XtString) "-xtsessionID";	s++;
33910568f49bSmrg	*s = str;				s++;
3392444c061aSmrg	for (; --count > 0; s++, sarray++)
3393444c061aSmrg	    *s = *sarray;
33940568f49bSmrg	*s = NULL;
3395444c061aSmrg    } else {
3396444c061aSmrg	if (count < 3)
3397444c061aSmrg	    return NewStringArray(sarray);
33980568f49bSmrg	s = new = (_XtString *) __XtMalloc((Cardinal)((size_t)(count-1) * sizeof(_XtString*)));
3399444c061aSmrg	for (; --count >= 0; sarray++) {
3400444c061aSmrg	    if (strcmp(*sarray, "-xtsessionID") == 0) {
3401444c061aSmrg		sarray++;
3402444c061aSmrg		count--;
3403444c061aSmrg	    } else {
3404444c061aSmrg		*s = *sarray;
3405444c061aSmrg		s++;
3406444c061aSmrg	    }
3407444c061aSmrg	}
34080568f49bSmrg	*s = NULL;
3409444c061aSmrg    }
3410444c061aSmrg    s = new;
3411444c061aSmrg    new = NewStringArray(new);
3412444c061aSmrg    XtFree((char *)s);
3413444c061aSmrg    return new;
3414444c061aSmrg}
3415444c061aSmrg
3416444c061aSmrg#endif /* !XT_NO_SM */
3417