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