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