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