1 /**
2  *
3  * $Header: /cvsroot/lesstif/lesstif/lib/Xm-2.1/Vendor.c,v 1.5 2005/03/19 15:15:27 dannybackx Exp $
4  *
5  * Copyright (C) 1996 Free Software Foundation, Inc.
6  * Copyright � 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005 LessTif Development Team
7  *
8  * This file is part of the GNU LessTif Library.
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public
21  * License along with this library; if not, write to the Free
22  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  **/
25 
26 static const char rcsid[] = "$Id: Vendor.c,v 1.5 2005/03/19 15:15:27 dannybackx Exp $";
27 
28 #include <LTconfig.h>
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 /* amai, 5/2001: (This is not very nice ...)
35    Later on we use some internal stuff from the Intrinsics which we
36    should _not_ use. In rare conditions we may lack some stuff from the
37    headers if this setting is not done (-> e.g. _XtBoolean).
38    I hope that this does not hurt anywhere. */
39 #ifndef FUNCPROTO
40 #define FUNCPROTO 11
41 #endif
42 
43 #include <X11/IntrinsicP.h>
44 #include <X11/StringDefs.h>
45 #include <X11/Shell.h>
46 #include <X11/ShellP.h>
47 #include <X11/Vendor.h>
48 #include <X11/VendorP.h>
49 
50 #include <XmI/XmI.h>
51 #include <XmI/AtomMgrI.h>
52 
53 #include <Xm/XmP.h>
54 #include <Xm/AtomMgr.h>
55 #include <Xm/BulletinBP.h>
56 #include <Xm/ShellEP.h>
57 #include <Xm/MenuShellP.h>
58 #include <Xm/VendorSEP.h>
59 #include <Xm/VendorSP.h>
60 #include <Xm/DisplayP.h>
61 #include <Xm/ScreenP.h>
62 #include <Xm/BaseClassP.h>
63 #include <Xm/Protocols.h>
64 #include <Xm/ProtocolsP.h>
65 #include <Xm/DialogSEP.h>
66 #include <Xm/ExtObjectP.h>
67 #include <Xm/VendorS.h>
68 
69 #include <Xm/SpecRenderT.h>
70 
71 #include <Xm/TraitP.h>
72 
73 #include <XmI/DebugUtil.h>
74 
75 #if defined(__EMX__) || defined(__CYGWIN__)
76 extern void _LtXmFixupVendorShell(void);
77 #ifdef __EMX__
78 unsigned long _DLL_InitTerm(unsigned long mod_handle, unsigned long flag);
79 #endif
80 #ifdef __CYGWIN__
81 int __stdcall DllMain(unsigned long mod_handle, unsigned long flag, void *routine);
82 #endif
83 #endif
84 
85 /* We use a 'private', i.e. non-declared, but actually exported call
86     from the original Intrinsic sources (lib/Xt/Callback.c) here.
87     Note that we don't give the precise prototype:
88  */
89 extern void
90 _XtRemoveCallback (
91     /* InternalCallbackList   *callbacks, */
92     void               *callbacks,
93     XtCallbackProc	callback,
94     XtPointer		closure);
95 
96 /***************************************************************************
97  *
98  * Vendor shell class record
99  *
100  ***************************************************************************/
101 
102 static void class_initialize(void);
103 static void class_part_initialize(WidgetClass w_class);
104 static void initialize(Widget req, Widget new_w, ArgList args, Cardinal *num_args);
105 static Boolean set_values(Widget old, Widget req, Widget new_w, ArgList args, Cardinal *num_args);
106 static void destroy(Widget w);
107 static void realize(Widget w, XtValueMask *value_mask, XSetWindowAttributes *attributes);
108 static void change_managed(Widget w);
109 static void resize(Widget w);
110 static void get_values_prehook(Widget widget, ArgList args, Cardinal *num_args);
111 static void get_values_posthook(Widget widget, ArgList args, Cardinal *num_args);
112 static void initialize_prehook(Widget req, Widget new_w, ArgList args, Cardinal *num_args);
113 static void initialize_posthook(Widget req, Widget new_w, ArgList args, Cardinal *num_args);
114 static Boolean set_values_prehook(Widget old, Widget req, Widget new_w,
115 				  ArgList args, Cardinal *num_args);
116 static Boolean set_values_posthook(Widget old, Widget req, Widget new_w,
117 				   ArgList args, Cardinal *num_args);
118 static void insert_child(Widget w);
119 static void delete_child(Widget w);
120 static XtGeometryResult geometry_manager(Widget wid,
121 					 XtWidgetGeometry *request,
122 					 XtWidgetGeometry *reply);
123 static Cardinal get_sec_res_data(WidgetClass wc, XmSecondaryResourceData **data);
124 static void secondary_object_create(Widget req, Widget new_w, ArgList args, Cardinal *num_args);
125 static void WmProtocolHandler(Widget w, XtPointer client, XtPointer call);
126 
127 /*
128  * "forwards" needed within the vendor class implementation
129  */
130 static void LTAddGrab(Widget wid, Boolean exclusive, Boolean spring_loaded,
131 		      XmVendorShellExtObject ve,
132 		      XmVendorShellExtObject grabber);
133 static void LTRemoveGrab(Widget wid, XmVendorShellExtObject ve, Boolean remove_grab_physically);
134 static void LTRemoveGrabCallback(Widget wid, XtPointer client_data, XtPointer callback_data);
135 static void LTShellPopupCallback(Widget w, XtPointer ClientData, XtPointer CallbackData);
136 static void LTShellPopdownCallback(Widget w, XtPointer ClientData, XtPointer CallbackData);
137 static void LTGrabRelatives(XmVendorShellExtObject grabber);
138 static void VendorFromHorizontalPixels(Widget w, int offset, XtArgVal *value);
139 static void VendorFromVerticalPixels(Widget w, int offset, XtArgVal *value);
140 static XmImportOperator VendorToHorizontalPixels(Widget w, int offset, XtArgVal *value);
141 static XmImportOperator VendorToVerticalPixels(Widget w, int offset, XtArgVal *value);
142 static Bool ConfigEventForMe(Display *dpy, XEvent *event, char *arg);
143 static XmRenderTable GetRenderTable(Widget w, XtEnum renderTableType);
144 
145 /*
146  * the following is for the extension record for LessTif Vendor Shells
147  * this is needed before the shell record as the shell's base class extension
148  * needs some of the data defined here.
149  */
150 static void _XmVendorExtInitialize(Widget req, Widget new_w,
151 				   ArgList args, Cardinal *num_args);
152 static Boolean _XmVendorExtSetValues(Widget cw, Widget rw, Widget nw,
153 				     ArgList args, Cardinal *nargs);
154 static void _XmVendorExtDestroy(Widget w);
155 
156 #define Offset(field) XtOffsetOf(XmVendorShellExtRec, vendor.field)
157 static XtResource ext_resources[] =
158 {
159     {
160 	XmNextensionType, XmCExtensionType, XmRExtensionType,
161      sizeof(unsigned char), XtOffsetOf(XmVendorShellExtRec, ext.extensionType),
162 	XtRImmediate, (XtPointer)XmSHELL_EXTENSION
163     },
164     {
165 	XmNdefaultFontList, XmCDefaultFontList, XmRFontList,
166 	sizeof(XmFontList), Offset(default_font_list),
167 	XmRImmediate, (XtPointer)NULL
168     },
169     {
170 	XmNbuttonFontList, XmCButtonFontList, XmRFontList,
171 	sizeof(XmFontList), Offset(button_font_list),
172 	XmRImmediate, (XtPointer)NULL
173     },
174     {
175 	XmNlabelFontList, XmCLabelFontList, XmRFontList,
176 	sizeof(XmFontList), Offset(label_font_list),
177 	XmRImmediate, (XtPointer)NULL
178     },
179     {
180 	XmNtextFontList, XmCTextFontList, XmRFontList,
181 	sizeof(XmFontList), Offset(text_font_list),
182 	XmRImmediate, NULL
183     },
184     {
185 	XmNaudibleWarning, XmCAudibleWarning, XmRAudibleWarning,
186 	sizeof(unsigned char), Offset(audible_warning),
187 	XmRImmediate, (XtPointer)XmBELL
188     },
189     {
190 	XmNshellUnitType, XmCShellUnitType, XmRUnitType,
191 	sizeof(unsigned char), Offset(unit_type),
192 	XmRImmediate, (XtPointer)XmPIXELS	/* CHECK THIS */
193     },
194     {
195 	XmNdeleteResponse, XmCDeleteResponse, XmRDeleteResponse,
196 	sizeof(unsigned char), Offset(delete_response),
197 	XmRImmediate, (XtPointer)XmDESTROY
198     },
199     {
200 	XmNkeyboardFocusPolicy, XmCKeyboardFocusPolicy, XmRKeyboardFocusPolicy,
201 	sizeof(unsigned char), Offset(focus_policy),
202 	XmRImmediate, (XtPointer)XmEXPLICIT
203     },
204     {
205 	XmNmwmDecorations, XmCMwmDecorations, XmRInt,
206 	sizeof(int), Offset(mwm_hints.decorations),
207 	XmRImmediate, (XtPointer)-1
208     },
209     {
210 	XmNmwmFunctions, XmCMwmFunctions, XmRInt,
211 	sizeof(int), Offset(mwm_hints.functions),
212 	XmRImmediate, (XtPointer)-1
213     },
214     {
215 	XmNmwmInputMode, XmCMwmInputMode, XmRInt,
216 	sizeof(int), Offset(mwm_hints.input_mode),
217 	XmRImmediate, (XtPointer)-1
218     },
219     {
220 	XmNmwmMenu, XmCMwmMenu, XmRString,
221 	sizeof(String), Offset(mwm_menu),
222 	XmRImmediate, NULL
223     },
224     {
225 	XmNfocusMovedCallback, XmCCallback, XmRCallback,
226 	sizeof(XtCallbackList), Offset(focus_moved_callback),
227 	XmRImmediate, NULL
228     },
229     {
230 	XmNrealizeCallback, XmCCallback, XmRCallback,
231 	sizeof(XtCallbackList), Offset(realize_callback),
232 	XmRImmediate, NULL
233     },
234     {
235 	XmNinputMethod, XmCInputMethod, XmRString,
236 	sizeof(String), Offset(input_method_string),
237 	XtRImmediate, (XtPointer)NULL	/* FIX ME */
238     },
239     {
240 	XmNpreeditType, XmCPreeditType, XmRString,
241 	sizeof(String), Offset(preedit_type_string),
242 	XtRImmediate, (XtPointer)"OffTheSpot,OverTheSpot,Root"
243     },
244     {
245 	XmNlightThreshold, XmCLightThreshold, XmRInt,
246 	sizeof(int), Offset(light_threshold),
247 	XtRImmediate, (XtPointer)0
248     },
249     {
250 	XmNdarkThreshold, XmCDarkThreshold, XmRInt,
251 	sizeof(int), Offset(dark_threshold),
252 	XtRImmediate, (XtPointer)0
253     },
254     {
255 	XmNforegroundThreshold, XmCForegroundThreshold, XmRInt,
256 	sizeof(int), Offset(foreground_threshold),
257 	XtRImmediate, (XtPointer)0
258     },
259     /* FIX ME which version does this originate at ? */
260     {
261 	XmNlayoutDirection, XmCLayoutDirection, XmRDirection,
262 	sizeof(XmDirection), Offset(layout_direction),
263 	XtRImmediate, (XtPointer)XmLEFT_TO_RIGHT
264     },
265     {
266 	XmNinputPolicy, XmCInputPolicy, XmRInputPolicy,
267 	sizeof(XmInputPolicy), Offset(input_policy),
268 	XtRImmediate, (XtPointer)XmPER_SHELL
269     },
270 };
271 
272 
273 static XmSyntheticResource ext_syn_resources[] =
274 {
275     {
276 	XmNx,
277 	sizeof(Position), XtOffsetOf(VendorShellRec, core.x),
278 	VendorFromHorizontalPixels, VendorToHorizontalPixels
279     },
280     {
281 	XmNy,
282 	sizeof(Position), XtOffsetOf(VendorShellRec, core.y),
283 	VendorFromVerticalPixels, VendorToVerticalPixels
284     },
285     {
286 	XmNwidth,
287 	sizeof(Dimension), XtOffsetOf(VendorShellRec, core.width),
288 	VendorFromHorizontalPixels, VendorToHorizontalPixels
289     },
290     {
291 	XmNheight,
292 	sizeof(Dimension), XtOffsetOf(VendorShellRec, core.height),
293 	VendorFromVerticalPixels, VendorToVerticalPixels
294     },
295     {
296 	XmNborderWidth,
297 	sizeof(Dimension), XtOffsetOf(VendorShellRec, core.border_width),
298 	VendorFromHorizontalPixels, VendorToHorizontalPixels
299     },
300     {
301 	XmNminWidth,
302 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.min_width),
303 	VendorFromHorizontalPixels , VendorToHorizontalPixels
304     },
305     {
306 	XmNminHeight,
307 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.min_height),
308 	VendorFromVerticalPixels , VendorToVerticalPixels
309     },
310     {
311 	XmNmaxWidth,
312 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.max_width),
313 	VendorFromHorizontalPixels , VendorToHorizontalPixels
314     },
315     {
316 	XmNmaxHeight,
317 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.max_height),
318 	VendorFromVerticalPixels , VendorToVerticalPixels
319     },
320     {
321 	XmNiconX,
322 	sizeof(Position), XtOffsetOf(VendorShellRec, wm.wm_hints.icon_x),
323 	VendorFromHorizontalPixels , VendorToHorizontalPixels
324     },
325     {
326 	XmNiconY,
327 	sizeof(Position), XtOffsetOf(VendorShellRec, wm.wm_hints.icon_y),
328 	VendorFromVerticalPixels , VendorToVerticalPixels
329     },
330 #if 0
331     {
332 	XmNmwmFunctions,
333 	sizeof(), XtOffsetOf(),
334 	NULL /* FIX ME */ , NULL
335     },
336 #endif
337 };
338 
339 
340 XmVendorShellExtClassRec xmVendorShellExtClassRec = {
341     /* Object Class Part */
342     {
343  	/* superclass         */    (WidgetClass)&xmShellExtClassRec,
344 	/* class_name         */    "VendorShell",
345 	/* size               */    sizeof(XmVendorShellExtRec),
346 	/* class_initialize   */    NULL,
347 	/* class_part_initialize*/  NULL,
348 	/* Class init'ed ?    */    False,
349 	/* initialize         */    NULL,
350 	/* initialize_hook    */    NULL,
351 	/* pad                */    NULL,
352 	/* pad                */    NULL,
353 	/* pad                */    0,
354 	/* resources          */    ext_resources,
355 	/* resource_count     */    XtNumber(ext_resources),
356 	/* xrm_class          */    NULLQUARK,
357 	/* pad                */    False,
358 	/* pad                */    False,
359 	/* pad                */    False,
360 	/* pad                */    False,
361 	/* destroy            */    _XmVendorExtDestroy,
362 	/* pad                */    NULL,
363 	/* pad                */    NULL,
364 	/* set_values         */    NULL,
365 	/* set_values_hook    */    NULL,
366 	/* pad                */    NULL,
367 	/* get_values_hook    */    NULL,
368 	/* pad                */    NULL,
369 	/* version            */    XtVersion,
370 	/* callback_offsets   */    NULL,
371 	/* pad                */    NULL,
372 	/* pad                */    NULL,
373 	/* pad                */    NULL,
374 	/* extension          */    NULL
375     },
376     /* XmExtObject part */
377     {
378         /* syn_resources      */ ext_syn_resources,
379         /* num_syn_resources  */ XtNumber(ext_syn_resources),
380         /* extension          */ NULL
381     },
382     /* Desktop Class part */
383     {
384         /* child_class           */ NULL,
385         /* insert_child          */ XmInheritWidgetProc,
386         /* delete_child          */ XmInheritWidgetProc,
387         /* extension             */ NULL
388     },
389     /* ShellExt Class part */
390     {
391 	/* structure_notify_handler */ XmInheritEventHandler,
392 	/* extension                */ NULL
393     },
394     /* VendorClass Part */
395     {
396 	/* delete_window_handler */ WmProtocolHandler,
397 	/* offset_handler        */ NULL, /* FIX ME */
398 	/* extension             */ NULL
399     }
400 };
401 
402 static XmSpecRenderTraitRec _XmVendorShellTraitRec = {
403 	/* version      */      0,
404 	/* cb           */      GetRenderTable
405 };
406 
407 WidgetClass xmVendorShellExtObjectClass = (WidgetClass) &xmVendorShellExtClassRec;
408 
409 static int default_shell_int = XtUnspecifiedShellInt;
410 
411 static XtResource vendor_resources[] = {
412     {
413 	XmNx, XmCPosition, XmRShellHorizPos,
414 	sizeof(Position), XtOffsetOf(VendorShellRec, core.x),
415 	XmRImmediate, (XtPointer)0
416     },
417     {
418 	XmNy, XmCPosition, XmRShellVertPos,
419 	sizeof(Position), XtOffsetOf(VendorShellRec, core.y),
420 	XmRImmediate, (XtPointer)0
421     },
422     {
423 	XmNwidth, XmCDimension, XmRShellHorizDim,
424 	sizeof(Dimension), XtOffsetOf(VendorShellRec, core.width),
425 	XmRImmediate, (XtPointer)0
426     },
427     {
428 	XmNheight, XmCDimension, XmRShellVertDim,
429 	sizeof(Dimension), XtOffsetOf(VendorShellRec, core.height),
430 	XmRImmediate, (XtPointer)0
431     },
432     {
433 	XmNborderWidth, XmCBorderWidth, XmRShellHorizDim,
434 	sizeof(Dimension), XtOffsetOf(VendorShellRec, core.border_width),
435 	XmRImmediate, (XtPointer)0
436     },
437     {
438 	XmNbaseWidth, XmCBaseWidth, XmRHorizontalInt,
439 	sizeof(int), XtOffsetOf(VendorShellRec, wm.base_width),
440         XmRHorizontalInt, (XtPointer)&default_shell_int
441     },
442     {
443 	XmNbaseHeight, XmCBaseHeight, XmRVerticalInt,
444 	sizeof(int), XtOffsetOf(VendorShellRec, wm.base_height),
445         XmRVerticalInt, (XtPointer)&default_shell_int
446     },
447     {
448 	XmNminWidth, XmCMinWidth, XmRHorizontalInt,
449 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.min_width),
450         XmRHorizontalInt, (XtPointer)&default_shell_int
451     },
452     {
453 	XmNminHeight, XmCMinHeight, XmRVerticalInt,
454 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.min_height),
455         XmRVerticalInt, (XtPointer)&default_shell_int
456     },
457     {
458 	XmNmaxWidth, XmCMaxWidth, XmRHorizontalInt,
459 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.max_width),
460         XmRHorizontalInt, (XtPointer)&default_shell_int
461     },
462     {
463 	XmNmaxHeight, XmCMaxHeight, XmRVerticalInt,
464 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.max_height),
465         XmRVerticalInt, (XtPointer)&default_shell_int
466     },
467     {
468 	XmNwidthInc, XmCWidthInc, XmRHorizontalInt,
469 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.width_inc),
470         XmRHorizontalInt, (XtPointer)&default_shell_int
471     },
472     {
473 	XmNheightInc, XmCHeightInc, XmRVerticalInt,
474 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.height_inc),
475         XmRVerticalInt, (XtPointer)&default_shell_int
476     },
477     {
478 	XmNminAspectX, XmCMinAspectX, XmRHorizontalInt,
479 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.min_aspect.x),
480         XmRHorizontalInt, (XtPointer)&default_shell_int
481     },
482     {
483 	XmNminAspectY, XmCMinAspectY, XmRVerticalInt,
484 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.min_aspect.y),
485         XmRVerticalInt, (XtPointer)&default_shell_int
486     },
487     {
488 	XmNmaxAspectX, XmCMaxAspectX, XmRHorizontalInt,
489 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.max_aspect.x),
490         XmRHorizontalInt, (XtPointer)&default_shell_int
491     },
492     {
493 	XmNmaxAspectY, XmCMaxAspectY, XmRVerticalInt,
494 	sizeof(int), XtOffsetOf(VendorShellRec, wm.size_hints.max_aspect.y),
495         XmRVerticalInt, (XtPointer)&default_shell_int
496     },
497     {
498 	XmNiconPixmap, XmCIconPixmap, XmRPixmap,
499 	sizeof(Pixmap), XtOffsetOf(VendorShellRec, wm.wm_hints.icon_pixmap),
500         XmRPixmap, (XtPointer)NULL
501     },
502     {
503 	XmNiconX, XmCIconX, XmRHorizontalInt,
504 	sizeof(int), XtOffsetOf(VendorShellRec, wm.wm_hints.icon_x),
505         XmRHorizontalInt, (XtPointer)&default_shell_int
506     },
507     {
508 	XmNiconY, XmCIconY, XmRVerticalInt,
509 	sizeof(int), XtOffsetOf(VendorShellRec, wm.wm_hints.icon_y),
510         XmRVerticalInt, (XtPointer)&default_shell_int
511     },
512     {
513 	XtNinput, XtCInput, XmRBool,
514 	sizeof(Bool), XtOffsetOf(WMShellRec, wm.wm_hints.input),
515 	XtRImmediate, (XtPointer)True
516     },
517     {
518 	XmNwindowGroup, XmCWindowGroup, XmRWindow,
519 	sizeof(Window), XtOffsetOf(WMShellRec, wm.wm_hints.window_group),
520 	XmRImmediate, (XtPointer)XtUnspecifiedWindowGroup
521     }
522 };
523 
524 static XmBaseClassExtRec _XmVendorSCoreClassExtRec = {
525     /* next_extension            */ NULL,
526     /* record_type               */ NULLQUARK,
527     /* version                   */ XmBaseClassExtVersion,
528     /* size                      */ sizeof(XmBaseClassExtRec),
529     /* initialize_prehook        */ initialize_prehook,
530     /* set_values_prehook        */ set_values_prehook,
531     /* initialize_posthook       */ initialize_posthook,
532     /* set_values_posthook       */ set_values_posthook,
533     /* secondary_object_class    */ (WidgetClass)&xmVendorShellExtClassRec,
534     /* secondary_object_create   */ secondary_object_create,
535     /* get_secondary_resources   */ get_sec_res_data,
536     /* fast_subclass             */ { 0 },
537     /* get_values_prehook        */ get_values_prehook,
538     /* get_values_posthook       */ get_values_posthook,
539     /* class_part_init_prehook   */ NULL,
540     /* class_part_init_posthook  */ NULL,
541     /* ext_resources             */ NULL,
542     /* compiled_ext_resources    */ NULL,
543     /* num_ext_resources         */ 0,
544     /* use_sub_resources         */ False,
545     /* widget_navigable          */ NULL,
546     /* focus_change              */ NULL,
547     /* wrapper_data              */ NULL
548 };
549 
550 static CompositeClassExtensionRec vendorCompositeExt =
551 {
552     /* next_extension */            NULL,
553     /* record_type    */            NULLQUARK,
554     /* version        */            XtCompositeExtensionVersion,
555     /* record_size    */            sizeof(CompositeClassExtensionRec),
556     /* accepts_objects */           True,
557 #if XtSpecificationRelease >= 6
558     /* allows_change_managed_set */ False
559 #endif
560 };
561 
562 static ShellClassExtensionRec shellClassExtRec = {
563     NULL,
564     NULLQUARK,
565     XtShellExtensionVersion,
566     sizeof(ShellClassExtensionRec),
567     _XmRootGeometryManager
568 };
569 
570 VendorShellClassRec vendorShellClassRec = {
571     /* Core Class Part */
572     {
573 	/* superclass            */ (WidgetClass)&wmShellClassRec,
574 	/* class_name	         */ "VendorShell",
575 	/* size                  */ sizeof(VendorShellRec),
576 	/* class_initialize      */ class_initialize,
577 	/* class_part_initialize */ class_part_initialize,
578 	/* Class init'ed ?       */ False,
579 	/* initialize            */ initialize,
580 	/* initialize_hook       */ NULL,
581 	/* realize               */ realize,
582 	/* actions               */ NULL,
583 	/* num_actions           */ 0,
584 	/* resources             */ vendor_resources,
585 	/* resource_count        */ XtNumber(vendor_resources),
586 	/* xrm_class             */ NULLQUARK,
587 	/* compress_motion       */ False,
588 	/* compress_exposure     */ True,
589 	/* compress_enterleave   */ False,
590 	/* visible_interest      */ False,
591 	/* destroy               */ destroy,
592 	/* resize                */ resize,
593 	/* expose                */ NULL,
594 	/* set_values            */ set_values,
595 	/* set_values_hook       */ NULL,
596 	/* set_values_almost     */ XtInheritSetValuesAlmost,
597 	/* get_values_hook       */ NULL,
598 	/* accept_focus          */ NULL,
599 	/* intrinsics version    */ XtVersion,
600 	/* callback offsets      */ NULL,
601 	/* tm_table              */ NULL,
602 	/* query_geometry        */ NULL,
603 	/* display_accelerator   */ NULL,
604 	/* extension             */ (XtPointer)&_XmVendorSCoreClassExtRec,
605     },
606     /* Composite Class Part */
607     {
608 	/* geometry_manager */ geometry_manager,
609         /* change_managed   */ change_managed,
610         /* insert_child     */ insert_child,
611         /* delete_child     */ delete_child,
612         /* extension        */ (XtPointer) &vendorCompositeExt,
613     },
614     /* Shell Class Part */
615     {
616         /* extension */ (XtPointer)&shellClassExtRec
617     },
618     /* WMShell Class Part */
619     {
620         /* extension */ NULL
621     },
622     /* Vendor Shell Class Part */
623     {
624         /* extension */ NULL
625     }
626 };
627 
628 
629 WidgetClass vendorShellWidgetClass = (WidgetClass)(&vendorShellClassRec);
630 
631 static Display *default_display = NULL;
632 
633 
634 static void
class_initialize(void)635 class_initialize(void)
636 {
637 	int		ncom;
638 	XtResourceList	combined, shells;
639 	Cardinal	nshells;
640 
641 	/* we only do this here so that people can override the default reptypes,
642 	 * based on information from Harald Albrecht */
643 	XmSetColorCalculation(NULL);
644 	_XmRegisterConverters();
645 	_XmRegisterPixmapConverters();
646 
647 	ncom = XtNumber(ext_resources) + xmShellExtClassRec.object_class.num_resources;
648 
649 	_XmTransformSubResources(xmShellExtClassRec.object_class.resources,
650 			xmShellExtClassRec.object_class.num_resources,
651 			&shells, &nshells);
652 
653 	combined = (XtResourceList)XtMalloc(sizeof(XtResource) * ncom);
654 
655 	memcpy(combined, shells, nshells * sizeof(XtResource));
656 	memcpy(&combined[nshells], ext_resources,
657 			XtNumber(ext_resources) * sizeof(XtResource));
658 
659 	xmVendorShellExtClassRec.object_class.resources = combined;
660 	xmVendorShellExtClassRec.object_class.num_resources = ncom;
661 
662 	_XmInitializeExtensions();
663 	_XmVendorSCoreClassExtRec.record_type = XmQmotif;
664 
665 	_XmBuildExtResources((WidgetClass)&xmVendorShellExtClassRec);
666 
667 	if (((XmShellExtObjectClass)&xmVendorShellExtClassRec)->desktop_class.insert_child ==
668 			XtInheritInsertChild) {
669 		((XmShellExtObjectClass)&xmVendorShellExtClassRec)->desktop_class.insert_child =
670 			((XmShellExtObjectClass)xmDesktopClass)->desktop_class.insert_child;
671 	}
672 	if (((XmShellExtObjectClass)&xmVendorShellExtClassRec)->desktop_class.delete_child ==
673 			XtInheritDeleteChild) {
674 		((XmShellExtObjectClass)&xmVendorShellExtClassRec)->desktop_class.delete_child =
675 			((XmShellExtObjectClass)xmDesktopClass)->desktop_class.delete_child;
676 	}
677 
678 	if (((XmShellExtObjectClass)&xmVendorShellExtClassRec)->shell_class.structureNotifyHandler
679 			== XmInheritEventHandler) {
680 		((XmShellExtObjectClass)&xmVendorShellExtClassRec)->
681 			shell_class.structureNotifyHandler =
682 			((XmShellExtObjectClass)xmShellExtClass)->
683 			shell_class.structureNotifyHandler;
684 	}
685 
686 	/* Initialize traits */
687 	_XmInitTraits();
688 
689 	if (! XmeTraitSet((XtPointer)vendorShellWidgetClass, XmQTspecifyRenderTable,
690 				(XtPointer)&_XmVendorShellTraitRec)) {
691 		_XmWarning(NULL, "(Xm)VendorShell ClassInitialize: XmeTraitSet failed\n");
692 	}
693 
694 }
695 
696 static void
VendorFromHorizontalPixels(Widget w,int offset,XtArgVal * value)697 VendorFromHorizontalPixels(Widget w, int offset, XtArgVal *value)
698 {
699     *value = (XtArgVal)(*(short *)((char *)XtParent(w) + offset));
700 
701     _XmFromHorizontalPixels(XtParent(w), offset, value);
702 }
703 
704 
705 static void
VendorFromVerticalPixels(Widget w,int offset,XtArgVal * value)706 VendorFromVerticalPixels(Widget w, int offset, XtArgVal *value)
707 {
708     *value = (XtArgVal)(*(short *)((char *)XtParent(w) + offset));
709 
710     _XmFromVerticalPixels(XtParent(w), offset, value);
711 }
712 
713 
714 static XmImportOperator
VendorToHorizontalPixels(Widget w,int offset,XtArgVal * value)715 VendorToHorizontalPixels(Widget w, int offset, XtArgVal *value)
716 {
717     _XmToHorizontalPixels(XtParent(w), offset, value);
718 
719     return XmSYNTHETIC_NONE;
720 }
721 
722 
723 static XmImportOperator
VendorToVerticalPixels(Widget w,int offset,XtArgVal * value)724 VendorToVerticalPixels(Widget w, int offset, XtArgVal *value)
725 {
726     _XmToVerticalPixels(XtParent(w), offset, value);
727 
728     return XmSYNTHETIC_NONE;
729 }
730 
731 
732 static void
class_part_initialize(WidgetClass widget_class)733 class_part_initialize(WidgetClass widget_class)
734 {
735     CompositeClassExtension ext, *extptr;
736     VendorShellWidgetClass vsclass = (VendorShellWidgetClass)widget_class;
737 
738     DEBUGOUT(_LtDebug(__FILE__, NULL,
739 		      "Vendor Shell's class_part_initialize()\n"));
740 
741     extptr = (CompositeClassExtension *)_XmGetClassExtensionPtr((XmGenericClassExt *)&(vsclass->composite_class.extension),
742 								NULLQUARK);
743 
744     if (extptr == NULL || *extptr == NULL)
745     {
746 	ext = (CompositeClassExtension)XtNew(CompositeClassExtensionRec);
747 	if (ext != NULL)
748 	{
749 	    ext->next_extension = vsclass->composite_class.extension;
750 	    ext->record_type = NULLQUARK;
751 	    ext->version = XtCompositeExtensionVersion;
752 	    ext->record_size = sizeof(CompositeClassExtensionRec);
753 	    ext->accepts_objects = True;
754 #if XtSpecificationRelease >= 6
755 	    ext->allows_change_managed_set = False;
756 #endif
757 	    vsclass->composite_class.extension = (XtPointer)ext;
758 	}
759     }
760 
761     _XmBaseClassPartInitialize(widget_class);
762     _XmFastSubclassInit(widget_class, XmVENDOR_SHELL_BIT);
763 
764     /* compile the resources */
765     if (widget_class == vendorShellWidgetClass)
766     {
767         _XmSortResourceList((XrmResource **)vsclass->core_class.resources,
768                             vsclass->core_class.num_resources);
769     }
770 }
771 
772 
773 /*
774  * Helper function: checks whether a shell is a (real) popup shell or some
775  * other kind of shell. We need this one lateron when we have do deal with
776  * top level shells.
777  * The check is done by searching the list of popups which is maintained by
778  * our parent widget. As the widget we're looking for has probably just been
779  * added a few machine cycles ago, we're browsing the list backwards.
780  */
781 static Boolean
LTIsARealPopupShell(Widget wid)782 LTIsARealPopupShell(Widget wid)
783 {
784     Widget dad = XtParent(wid);
785     WidgetList popups;
786     int i;
787 
788     /* Oops, we might got an application shell with no parent */
789     if (dad)
790     {
791 	popups = dad->core.popup_list;
792 	for (i = dad->core.num_popups; --i >= 0;)
793 	{
794 	    if (popups[i] == wid)
795 	    {
796 		return True;
797 	    }
798 	}
799     }
800 
801     return False;
802 }
803 
804 
805 /*
806  * Helper function: returns the next parental shell for any given shell
807  * widget. If there isn't any parent shell (as we're might already be at the
808  * top of the hill) then the function returns NULL.
809  */
810 static Widget
LTGetParentShell(Widget w)811 LTGetParentShell(Widget w)
812 {
813     while (((w = XtParent(w)) != NULL) && !XtIsVendorShell(w))
814     {
815     }
816 
817     return w;
818 }
819 
820 
821 /*
822  * When given the current shell widget this function returns the desktop
823  * extension object belonging to the parent shell of the shell given.
824  * Well -- if we're already at the top level of the shell hierarchy then
825  * the function returns the widget id of the screen widget.
826  */
827 static Widget
LTGetDesktopLogicalParentForShell(Widget w)828 LTGetDesktopLogicalParentForShell(Widget w)
829 {
830     Widget logParent = NULL;
831     XmWidgetExtData extData;
832 
833     if (!XtIsWMShell(w))
834     {
835 	_XmError(w, "LTGetDesktopLogicalParentForShell: "
836 		 "need a WM shell or a subclass of.");
837     }
838 
839     if (((WMShellRec *)w)->wm.transient)
840     {
841 	if (XtIsTransientShell(w))
842 	{
843 	    /*
844 	     * If the current shell (in "w") is transient and is indeed of
845 	     * the transientShell widget class (some kind of dialog), then
846 	     * we may already may have a shell we're transient for. If we
847 	     * don't have such a shell, we search for our next parental shell
848 	     * and use that as the shell we're transient for.
849 	     */
850 	    logParent = ((TransientShellRec *)w)->transient.transient_for;
851 
852 	    if (logParent == NULL)
853 	    {
854 		logParent = LTGetParentShell(w);
855 		((TransientShellRec *)w)->transient.transient_for = logParent;
856 	    }
857 	}
858 	else
859 	{
860 	    /*
861 	     * We're transient, but we are something other than a real
862 	     * transient shell. So look out for the nearest parental shell
863 	     * and use that.
864 	     */
865 	    logParent = LTGetParentShell(w);
866 	}
867     }
868 
869     /*
870      * Now if we have found a suitable shell then we're returning the
871      * extension object associated with that shell.
872      */
873     if (logParent && XtIsVendorShell(logParent))
874     {
875 	extData = _XmGetWidgetExtData(logParent, XmSHELL_EXTENSION);
876 	if (extData == NULL)
877 	{
878 	    _XmError(logParent, "vendor shell has no shell extension data");
879 	}
880 
881 	return extData->widget;
882     }
883 
884     /*
885      * In case there is no parental shell left -- or -- there is something
886      * wrong with the parental shell (that is it is not a vendor shell or
887      * a subclass of) then we return the screen widget. This way the
888      * vendor extension object is added to the screen's widget child list.
889      */
890     return XmGetXmScreen(XtScreenOfObject(w));
891 
892 }
893 
894 
895 static void
secondary_object_create(Widget req,Widget new_w,ArgList args,Cardinal * num_args)896 secondary_object_create(Widget req, Widget new_w,
897 			ArgList args, Cardinal *num_args)
898 {
899     XmBaseClassExt *bce;
900     Widget desktopParent;
901     XmDisplay d = (XmDisplay)XmGetXmDisplay(XtDisplay(new_w));
902     XmWidgetExtData ed;
903     Cardinal size;
904     XtPointer nsec, rsec;
905     extern void _XtAddCallback(XtCallbackList *, XtCallbackProc, XtPointer);
906 
907     Display_ShellCount(d)++;
908 
909     bce = _XmGetBaseClassExtPtr(XtClass(new_w), XmQmotif);
910 
911     DEBUGOUT(_LtDebug(__FILE__, new_w, "secondary_object_create\n"));
912 
913     /*
914      * The shell extension objects have their XmNdesktopParent set pointing
915      * to the next higher level within the shells' hierarchy. The other
916      * "parent" resource -- XmNlogicalParent -- indicates the widget the
917      * extension object is associated with.
918      * --aldi 97/01/03: someone "optimized" here so that setting the
919      * logicalParent and the extensionType is done after the XtCreateWidget().
920      * But the initialize() method of the Desktop object relies on the
921      * desktopParent resource being set already when it is called.
922      */
923     desktopParent = LTGetDesktopLogicalParentForShell(new_w);
924 
925     size = (*bce)->secondaryObjectClass->core_class.widget_size;
926 
927     nsec = XtCalloc(1, size);
928     rsec = _XmExtObjAlloc(size);
929 
930     ((XmExtRec *)nsec)->object.self = (Widget)nsec;
931     ((XmExtRec *)nsec)->object.widget_class = (*bce)->secondaryObjectClass;
932     ((XmExtRec *)nsec)->object.parent = new_w;
933     ((XmExtRec *)nsec)->object.xrm_name = new_w->core.xrm_name;
934     ((XmExtRec *)nsec)->object.being_destroyed = False;
935     ((XmExtRec *)nsec)->object.destroy_callbacks = NULL;
936     ((XmExtRec *)nsec)->object.constraints = NULL;
937 
938     ExtObj_LogicalParent(nsec) = new_w;
939     ExtObj_ExtensionType(nsec) = XmSHELL_EXTENSION;
940 
941     Desktop_Parent(nsec) = desktopParent;
942 
943     XtGetSubresources(new_w, nsec, NULL, NULL,
944                       (*bce)->secondaryObjectClass->core_class.resources,
945                       (*bce)->secondaryObjectClass->core_class.num_resources,
946                       args, *num_args);
947 
948     ed = (XmWidgetExtData)XtMalloc(sizeof(XmWidgetExtDataRec));
949     ed->widget = (Widget)nsec;
950     ed->reqWidget = (Widget)rsec;
951 
952     memcpy(rsec, nsec, size);
953     ((XmExtRec *)rsec)->object.self = (Widget)rsec;
954 
955     _XmPushWidgetExtData(new_w, ed, XmSHELL_EXTENSION);
956 
957     _XmExtImportArgs((Widget)nsec, args, num_args);
958 
959     _XtAddCallback(&VSEP_RealizeCallback(ed->widget),
960 		   _XmVendorExtRealize, NULL);
961 
962     /*
963      * Now install some callbacks for use with the grab mechanism...
964      */
965     DEBUGOUT(_LtDebug2(__FILE__, new_w, ed->widget, "Install pop up/down callbacks\n"));
966 
967     XtAddCallback(new_w, XmNpopupCallback,
968 		  LTShellPopupCallback, (XtPointer)ed->widget);
969     XtAddCallback(new_w, XmNpopdownCallback,
970 		  LTShellPopdownCallback, (XtPointer)ed->widget);
971 }
972 
973 
974 static void
initialize_prehook(Widget req,Widget new_w,ArgList args,Cardinal * num_args)975 initialize_prehook(Widget req, Widget new_w,
976 		   ArgList args, Cardinal *num_args)
977 {
978     XmBaseClassExt bce;
979 
980     /*
981      * I had to move this here to avoid recursion problems with XmDisplay
982      * 051696 -- seems those problems may have been related to the bugs
983      * in BaseClass.  -- MLM
984      */
985     if (!XmIsDisplay(new_w))
986     {
987 
988 	bce = *(XmBaseClassExt *)_XmGetBaseClassExtPtr(XtClass(new_w),
989 						       XmQmotif);
990 	if (bce && bce->secondaryObjectClass)
991 	{
992 	    if (bce->secondaryObjectCreate)
993 		(bce->secondaryObjectCreate) (req, new_w, args, num_args);
994 	}
995     }
996 }
997 
998 
999 static void
initialize_posthook(Widget req,Widget new_w,ArgList args,Cardinal * num_args)1000 initialize_posthook(Widget req, Widget new_w,
1001 		    ArgList args, Cardinal *num_args)
1002 {
1003     XmWidgetExtData ext;
1004 
1005     if ((ext = _XmGetWidgetExtData(new_w, XmSHELL_EXTENSION)) != NULL)
1006     {
1007 	_XmExtObjFree((XtPointer)ext->reqWidget);
1008         ext->reqWidget = NULL;
1009     }
1010 }
1011 
1012 
1013 #define VSEPC_DeleteWindowHandler(w) \
1014     (((XmVendorShellExtClassRec *)XtClass(w))-> \
1015 					vendor_class.delete_window_handler)
1016 
1017 
1018 static void
initialize(Widget req,Widget new_w,ArgList args,Cardinal * num_args)1019 initialize(Widget req, Widget new_w,
1020 	   ArgList args, Cardinal *num_args)
1021 {
1022     XmWidgetExtData data;
1023     XtEventHandler str_not;
1024     XmShellExtClassRec *shellc;
1025 
1026     DEBUGOUT(_LtDebug(__FILE__, new_w, "####VendorShell initialize\n"));
1027 
1028     ((WMShellWidget)new_w)->wm.wait_for_wm = True;
1029 
1030     data = _XmGetWidgetExtData(new_w, XmSHELL_EXTENSION);
1031     if (data)
1032     {
1033 	_XmVendorExtInitialize(data->reqWidget, data->widget, args, num_args);
1034     }
1035 
1036     if (!default_display)
1037     {
1038 	default_display = XtDisplay(new_w);
1039     }
1040 
1041     if (!XmIsDisplay(new_w))
1042     {
1043 #ifdef LESSTIF_EDITRES
1044 	/* add the handler for editres messages */
1045 	XtAddEventHandler(new_w, (EventMask)0, True,
1046 			  (XtEventHandler)_XmNSEEditResCheckMessages, NULL);
1047 #endif
1048 
1049 	DEBUGOUT(_LtDebug(__FILE__, new_w,
1050 			  "Setting up virtual key bindings\n"));
1051 
1052 	XtSetKeyTranslator(XtDisplay(new_w), (XtKeyProc)XmTranslateKey);
1053 
1054 	if (data)
1055 	{
1056 	    shellc = (XmShellExtClassRec *)XtClass(data->widget);
1057 	    str_not = shellc->shell_class.structureNotifyHandler;
1058 
1059 	    XtAddEventHandler(new_w,
1060 			      (EventMask)FocusChangeMask |
1061 			      EnterWindowMask | LeaveWindowMask,
1062 			      True,
1063 			      (XtEventHandler)_XmTrackShellFocus,
1064 			      (XtPointer)data->widget);
1065 
1066 	    XtAddEventHandler(new_w,
1067 			      (EventMask)StructureNotifyMask,
1068 			      True,
1069 			      (XtEventHandler)str_not,
1070 			      (XtPointer)data->widget);
1071 	}
1072     }
1073 }
1074 
1075 
1076 /*
1077  * Don't forget to clean up: the shell extension data as well as the
1078  * extension object for example...
1079  */
1080 static void
destroy(Widget w)1081 destroy(Widget w)
1082 {
1083     XmWidgetExtData data;
1084 
1085     DEBUGOUT(_LtDebug(__FILE__, w, "VendorShell Destroy()\n"));
1086 /*  DEBUGOUT(_LtDebug("NEDIT", w, "VendorShell Destroy()\n")); */
1087 
1088     _XmPopWidgetExtData(w, &data, XmSHELL_EXTENSION);
1089     if (data != NULL) {
1090 	DEBUGOUT(_LtDebug2(__FILE__, w, data->widget,
1091 		"VendorShell Destroy: destroy child\n"));
1092 
1093 	/* mitch
1094 	XtDestroyWidget(data->widget);
1095 	*/
1096 	_XmVendorExtDestroy(data->widget);
1097 	XtFree((char *)data);
1098     }
1099 }
1100 
1101 
1102 static void
_XmVendorExtDestroy(Widget w)1103 _XmVendorExtDestroy(Widget w)
1104 {
1105 	XmVendorShellExtObject ve = (XmVendorShellExtObject)w;
1106 	Atom wm_delete_window;
1107 	Widget shell = ExtObj_LogicalParent(w);
1108 
1109 	DEBUGOUT(_LtDebug(__FILE__, w, "VendorShellExt Destroy()\n"));
1110 
1111 	if (VSEP_DefaultFontList(ve)) {
1112 		XmFontListFree(VSEP_DefaultFontList(ve));
1113 	}
1114 	if (VSEP_ButtonFontList(ve)) {
1115 		XmFontListFree(VSEP_ButtonFontList(ve));
1116 	}
1117 	if (VSEP_TextFontList(ve)) {
1118 		XmFontListFree(VSEP_TextFontList(ve));
1119 	}
1120 	if (VSEP_LabelFontList(ve)) {
1121 		XmFontListFree(VSEP_LabelFontList(ve));
1122 	}
1123 
1124 	if (VSEP_MwmMenu(ve) != NULL) {
1125 		XtFree((char*)VSEP_MwmMenu(ve));
1126 	}
1127 
1128 	_XmDestroyFocusData(VSEP_FocusData(ve));
1129 
1130 	wm_delete_window = XmInternAtom(XtDisplay(shell), _XA_WM_DELETE_WINDOW, False);
1131 
1132 	/* This removes all protocols and destroys the associated extension object */
1133 	_XmDestroyProtocols(shell);
1134 	_XtRemoveCallback(&VSEP_RealizeCallback(w), _XmVendorExtRealize, NULL);
1135 	XtFree((char *)w);
1136 }
1137 
1138 
1139 static void
realize(Widget w,XtValueMask * value_mask,XSetWindowAttributes * attributes)1140 realize(Widget w, XtValueMask *value_mask, XSetWindowAttributes *attributes)
1141 {
1142     DEBUGOUT(_LtDebug(__FILE__, w, "VendorRealize\n"));
1143 
1144     if (XtWidth(w) == 0)
1145     	XtWidth(w) = 1;
1146     if (XtHeight(w) == 0)
1147     	XtHeight(w) = 1;
1148 #define superclass (&wmShellClassRec)
1149     (*superclass->core_class.realize) (w, value_mask, attributes);
1150 #undef superclass
1151 #if 0
1152     {
1153     int i;
1154 
1155     	printf("%s %s %d %d %s\n",
1156     		XtName(w),
1157     		XtClass(w)->core_class.class_name,
1158     		CoreNumPopups(w),
1159     		MGR_NumChildren(w),
1160     		XtParent(w) ? XtName(XtParent(w)) : "NULL"
1161     		);
1162     	for (i = 0; i < MGR_NumChildren(w); i++)
1163     	{
1164 	    printf("\t%s %s\n",
1165 	    	XtName(MGR_Children(w)[i]),
1166 	    	XtClass(MGR_Children(w)[i])->core_class.class_name
1167 	    	);
1168 	    if (XtIsTransientShell(MGR_Children(w)[i]))
1169 	    {
1170 		XSetTransientForHint(XtDisplay(w),
1171 				     XtWindow(MGR_Children(w)[i]),
1172 				     XtWindow(w));
1173 	    }
1174     	}
1175     }
1176 #endif
1177 }
1178 
1179 
1180 static void
WmProtocolHandler(Widget w,XtPointer client,XtPointer call)1181 WmProtocolHandler(Widget w, XtPointer client, XtPointer call)
1182 {
1183     XmVendorShellExtObject ve = (XmVendorShellExtObject)client;
1184     Cardinal i;
1185 
1186     DEBUGOUT(_LtDebug(__FILE__, w, "WmProtocolHandler\n"));
1187 
1188     switch (VSEP_DeleteResponse(ve))
1189     {
1190     case XmDESTROY:
1191 	XtDestroyWidget(w);
1192 	if (XtIsApplicationShell(w))
1193 	{
1194 	    DEBUGOUT(_LtDebug(__FILE__, w,
1195 			      "WmProtocolHandler(DeleteResponse XmDESTROY) "
1196 			      "- Exiting (WM_DELETE_WINDOW)\n"));
1197 	    XtDestroyApplicationContext(XtWidgetToApplicationContext(w));
1198 	    exit(0);
1199 	}
1200 	DEBUGOUT(_LtDebug(__FILE__, w,
1201 			  "WmProtocolHandler(DeleteResponse XmDESTROY)\n"));
1202 	break;
1203 
1204     case XmUNMAP:
1205 	XtPopdown(w);
1206 	break;
1207 
1208     case XmDO_NOTHING:
1209 	DEBUGOUT(_LtDebug(__FILE__, w,
1210 			  "WmProtocolHandler(DeleteResponse XmNO_NOTHING)\n"));
1211 	return;
1212     }
1213 }
1214 
1215 
1216 static void
resize(Widget w)1217 resize(Widget w)
1218 {
1219     int i;
1220 
1221     /* Chain up for now -- needed due to the resize mechanism */
1222     wmShellClassRec.core_class.resize(w);
1223 
1224     for (i = MGR_NumChildren(w) - 1; i >= 0; i--)
1225     {
1226 
1227 	if (XtIsWidget(MGR_Children(w)[i]) &&
1228 	    XtIsManaged(MGR_Children(w)[i]))
1229 	{
1230 	    XtSetKeyboardFocus(MGR_Children(w)[i], MGR_Children(w)[i]);
1231 	}
1232     }
1233 }
1234 
1235 
1236 /*
1237  * set_values_prehook
1238  */
1239 static Boolean
set_values_prehook(Widget old,Widget req,Widget new_w,ArgList args,Cardinal * num_args)1240 set_values_prehook(Widget old, Widget req, Widget new_w,
1241 		   ArgList args, Cardinal *num_args)
1242 {
1243     XmBaseClassExt *bce;
1244     XmWidgetExtData data;
1245     Cardinal size;
1246     XtPointer nsec, rsec;
1247     Widget ve;
1248 
1249     bce = _XmGetBaseClassExtPtr(XtClass(new_w), XmQmotif);
1250     size = (*bce)->secondaryObjectClass->core_class.widget_size;
1251 
1252     nsec = _XmExtObjAlloc(size);
1253     rsec = _XmExtObjAlloc(size);
1254 
1255     ve = _LtFindVendorExt(new_w);
1256 
1257     data = (XmWidgetExtData)XtMalloc(sizeof(XmWidgetExtDataRec));
1258 
1259     memcpy(rsec, ve, size);
1260     memcpy(nsec, ve, size);
1261 
1262     data->widget = (Widget)ve;
1263     data->oldWidget = (Widget)nsec;
1264     data->reqWidget = (Widget)rsec;
1265 
1266     _XmPushWidgetExtData(new_w, data, XmSHELL_EXTENSION);
1267 
1268     XtSetSubvalues((XtPointer)data->widget,
1269                    (*bce)->secondaryObjectClass->core_class.resources,
1270                    (*bce)->secondaryObjectClass->core_class.num_resources,
1271                    args, *num_args);
1272 
1273     _XmExtImportArgs(data->widget, args, num_args);
1274 
1275     return False;
1276 }
1277 
1278 
1279 static Boolean
set_values_posthook(Widget old,Widget req,Widget new_w,ArgList args,Cardinal * num_args)1280 set_values_posthook(Widget old, Widget req, Widget new_w,
1281 		    ArgList args, Cardinal *num_args)
1282 {
1283     XmWidgetExtData data;
1284 
1285     _XmPopWidgetExtData(new_w, &data, XmSHELL_EXTENSION);
1286 
1287     _XmExtObjFree((XtPointer)data->oldWidget);
1288     _XmExtObjFree((XtPointer)data->reqWidget);
1289 
1290     XtFree((char *)data);
1291 
1292     return False;
1293 }
1294 
1295 static Boolean
set_values(Widget old,Widget req,Widget new_w,ArgList args,Cardinal * num_args)1296 set_values(Widget old, Widget req, Widget new_w, ArgList args, Cardinal *num_args)
1297 {
1298 	XmWidgetExtData		data;
1299 	Boolean			refresh = False;
1300 	XmVendorShellExtObject	ve;
1301 
1302 	DEBUGOUT(_LtDebug(__FILE__, new_w,
1303 		"VendorSetValues: %i args\n"
1304 		"\t    old X %5i Y %5i W %5i H %5i\n"
1305 		"\trequest X %5i Y %5i W %5i H %5i\n"
1306 		"\t  new_w X %5i Y %5i W %5i H %5i\n",
1307 		*num_args,
1308 		XtX(old), XtY(old),
1309 		XtWidth(old), XtHeight(old),
1310 		XtX(req), XtY(req),
1311 		XtWidth(req), XtHeight(req),
1312 		XtX(new_w), XtY(new_w),
1313 		XtWidth(new_w), XtHeight(new_w)));
1314 	DEBUGOUT(_LtDebugPrintArgList(__FILE__, new_w, args, *num_args, False));
1315 
1316 	data = _XmGetWidgetExtData(new_w, XmSHELL_EXTENSION);
1317 	if (data) {
1318 		refresh = _XmVendorExtSetValues(data->oldWidget, data->reqWidget,
1319 					data->widget, args, num_args);
1320 	}
1321 
1322 	return refresh;
1323 }
1324 
1325 static void
get_values_prehook(Widget widget,ArgList args,Cardinal * num_args)1326 get_values_prehook(Widget widget, ArgList args, Cardinal *num_args)
1327 {
1328     XmBaseClassExt *bce;
1329     XmWidgetExtData data;
1330     Cardinal size;
1331     XtPointer nsec;
1332     Widget ve;
1333 
1334     bce = _XmGetBaseClassExtPtr(XtClass(widget), XmQmotif);
1335     size = (*bce)->secondaryObjectClass->core_class.widget_size;
1336 
1337     nsec = _XmExtObjAlloc(size);
1338 
1339     ve = _LtFindVendorExt(widget);
1340 
1341     memcpy(nsec, ve, size);
1342 
1343     data = (XmWidgetExtData)XtMalloc(sizeof(XmWidgetExtDataRec));
1344     data->widget = (Widget)nsec;
1345 
1346     _XmPushWidgetExtData(widget, data, XmSHELL_EXTENSION);
1347 
1348     XtGetSubvalues((XtPointer)data->widget,
1349                    (*bce)->secondaryObjectClass->core_class.resources,
1350                    (*bce)->secondaryObjectClass->core_class.num_resources,
1351 		   args, *num_args);
1352 
1353     _XmExtGetValuesHook(data->widget, args, num_args);
1354 }
1355 
1356 
1357 static void
get_values_posthook(Widget widget,ArgList args,Cardinal * num_args)1358 get_values_posthook(Widget widget, ArgList args, Cardinal *num_args)
1359 {
1360 	XmWidgetExtData ext;
1361 
1362 	_XmPopWidgetExtData(widget, &ext, XmSHELL_EXTENSION);
1363 	_XmExtObjFree((XtPointer)ext->widget);
1364 	XtFree((char *)ext);
1365 }
1366 
1367 static void
change_managed(Widget wid)1368 change_managed(Widget wid)
1369 {
1370     int i;
1371 
1372     DEBUGOUT(_LtDebug(__FILE__, wid, "VendorChangeManaged()\n"));
1373 #define superclass (&wmShellClassRec)
1374     (*superclass->composite_class.change_managed) (wid);
1375 #undef superclass
1376 
1377     for (i = MGR_NumChildren(wid) - 1; i >= 0; i--)
1378     {
1379 	if (XtIsWidget(MGR_Children(wid)[i]) &&
1380 	    XtIsManaged(MGR_Children(wid)[i]))
1381 	{
1382 	    XtSetKeyboardFocus(wid, MGR_Children(wid)[i]);
1383 	}
1384     }
1385 }
1386 
1387 static void
insert_child(Widget w)1388 insert_child(Widget w)
1389 {
1390 	DEBUGOUT(_LtDebug(__FILE__, w, "insert_child()\n"));
1391 	/* Keep those pesky objects OUT of the child list */
1392 	if (!XtIsRectObj(w)) {
1393 		return;
1394 	}
1395 
1396 #define superclass (&wmShellClassRec)
1397 	(*superclass->composite_class.insert_child) (w);
1398 #undef superclass
1399 }
1400 
1401 
1402 static void
delete_child(Widget w)1403 delete_child(Widget w)
1404 {
1405     DEBUGOUT(_LtDebug(__FILE__, w, "delete_child()\n"));
1406     DEBUGOUT(_LtDebug2("RWS", XtParent(w), w,"%s:delete_child(%d)\n",
1407     	__FILE__, __LINE__
1408     	));
1409     /* Keep those pesky objects OUT of the child list */
1410     if (!XtIsRectObj(w))
1411     {
1412 	return;
1413     }
1414 
1415 #define superclass (&wmShellClassRec)
1416     (*superclass->composite_class.delete_child) (w);
1417 #undef superclass
1418 }
1419 
1420 
1421 extern Cardinal
_XmFilterResources(XtResource * resources,Cardinal numResources,WidgetClass filterClass,XtResource ** filteredResourcesRtn)1422 _XmFilterResources(XtResource *resources,
1423 		   Cardinal numResources,
1424 		   WidgetClass filterClass,
1425 		   XtResource **filteredResourcesRtn)
1426 {
1427     *filteredResourcesRtn = NULL;
1428     return 0;
1429 }
1430 
1431 
1432 /*
1433  * This dumps LessTif's idea about Xt's grab list.
1434  * Changed so it gets triggered both by selecting this file and by GRAB,
1435  * but not twice :-)
1436  */
1437 static void
dump_grab_list(Widget w)1438 dump_grab_list(Widget w)
1439 {
1440     Cardinal i;
1441 
1442     if (_LtDebugInDebug(__FILE__, w))
1443     {
1444 	DEBUGOUT(_LtDebug(__FILE__, w, "Current Grab List\n"));
1445 	for (i = 0; i < Display_NumModals(w); i++)
1446 	{
1447 	    DEBUGOUT(_LtDebug0(__FILE__, w, "\tWid: %p (%s) ve: %p grabber: %p exclusive: %d sprung: %d\n",
1448 		   Display_Modals(w)[i].wid,
1449 		   XtName(Display_Modals(w)[i].wid),
1450 		   Display_Modals(w)[i].ve,
1451 		   Display_Modals(w)[i].grabber, Display_Modals(w)[i].exclusive,
1452 		   Display_Modals(w)[i].springLoaded));
1453 	}
1454     } else if (_LtDebugInDebug("GRAB", w)) {
1455 	DEBUGOUT(_LtDebug("GRAB", w, "Current Grab List\n"));
1456 	for (i = 0; i < Display_NumModals(w); i++)
1457 	{
1458 	    DEBUGOUT(_LtDebug0("GRAB", w, "\tWid: %p (%s) ve: %p grabber: %p exclusive: %d sprung: %d\n",
1459 		   Display_Modals(w)[i].wid,
1460 		   XtName(Display_Modals(w)[i].wid),
1461 		   Display_Modals(w)[i].ve,
1462 		   Display_Modals(w)[i].grabber, Display_Modals(w)[i].exclusive,
1463 		   Display_Modals(w)[i].springLoaded));
1464 	}
1465     }
1466 }
1467 
1468 
1469 /*
1470  * Put a widget on LessTif's grab list and issue an Intrinsics' grab.
1471  * The correct use of the function's parameters is a little bit tricky:
1472  *   - In the simplest case, leave "ve" and "grabber" set to NULL and use
1473  *     "wid", "exclusive", and "spring_loaded" exactly the same way as you
1474  *     would using XtAddGrab(). _XmAddGrab() does it just that way.
1475  *   - You can set "wid" to NULL, but then you *must* specify a valid
1476  *     "ve" (= vendor shell extension object). In this case the grab is
1477  *     set to the logical parent to which the "ve" object is bound to.
1478  */
1479 static void
LTAddGrab(Widget wid,Boolean exclusive,Boolean spring_loaded,XmVendorShellExtObject ve,XmVendorShellExtObject grabber)1480 LTAddGrab(Widget wid, Boolean exclusive, Boolean spring_loaded,
1481 	  XmVendorShellExtObject ve, XmVendorShellExtObject grabber)
1482 {
1483 	Widget d;
1484 	XmModalData	modal = NULL, ps;
1485 	int i;
1486 
1487 	/*
1488 	 * If there's no widget wid specified, we'll take the logical parent
1489 	 * of the vendor shell extension object as the grab destination instead.
1490 	 */
1491 	if (wid == NULL) {
1492 		wid = ExtObj_LogicalParent(ve);
1493 		DEBUGOUT(_LtDebug(__FILE__, wid, "LTAddGrab(NULL)\n"));
1494 	} else {
1495 		DEBUGOUT(_LtDebug(__FILE__, wid, "LTAddGrab\n"));
1496 	}
1497 
1498 	d = XmGetXmDisplay(XtDisplayOfObject(wid));
1499 	ps = Display_Modals(d);
1500 
1501 #if 0
1502 	/* Xt doesn't check what's in there already so why should we ? */
1503 	for (i = Display_NumModals(d); i > 0; i--, ps++) {
1504 #if 1
1505 		/*
1506 		 * This possibly fixes the nedit menu problem.
1507 		 * Now we're comparing not only the widget but also its
1508 		 * status. This probably matches Xt's algorithm better.
1509 		 */
1510 		if (ps->wid == wid && ps->exclusive == exclusive) {
1511 			DEBUGOUT(_LtDebug(__FILE__, wid,
1512 				"LTAddGrab(double) [%d %d] old [%d %d]\n",
1513 				ps->exclusive, ps->springLoaded,
1514 				exclusive, spring_loaded));
1515 			modal = ps;
1516 		}
1517 #else
1518 		if (ps->wid == wid) {
1519 			DEBUGOUT(_LtDebug(__FILE__, wid,
1520 				"LTAddGrab(double) [%d %d] old [%d %d]\n",
1521 				ps->exclusive, ps->springLoaded,
1522 				exclusive, spring_loaded));
1523 			/*
1524 			 * FIX ME this tests for a known problem, it may be
1525 			 * necessary to handle more cases.
1526 			 */
1527 			if (exclusive == ps->exclusive)
1528 				return;
1529 			modal = ps;
1530 		}
1531 #endif
1532 	}
1533 #endif
1534 	dump_grab_list(d);
1535 
1536 	if (modal == 0) {
1537 		/* grow the modal list, if necessary */
1538 		if (Display_NumModals(d) >= Display_MaxModals(d)) {
1539 			Display_MaxModals(d) += 8;
1540 			Display_Modals(d) = (XmModalData)XtRealloc(
1541 				(char *)Display_Modals(d),
1542 				sizeof(XmModalDataRec) * Display_MaxModals(d));
1543 		}
1544 		modal = Display_Modals(d) + Display_NumModals(d);
1545 		Display_NumModals(d)++;
1546 	}
1547 
1548 	/*
1549 	 * Now occupy a free entry and pollute it with information about the
1550 	 * grab. Then introduce the grab to the Intrinsics and make sure the
1551 	 * grab gets removed if the grab widget should ever be destroyed
1552 	 * before releasing the grab. This is necessary so LessTif's grab list
1553 	 * stays in sync with the Intrinsics's list.
1554 	 */
1555 	modal->wid = wid;
1556 	modal->ve = ve;
1557 	modal->grabber = grabber;
1558 	modal->exclusive = exclusive;
1559 	modal->springLoaded = spring_loaded;
1560 
1561 	DEBUGOUT(_LtDebug("GRAB", wid, "%s:XtAddGrab(%d) - %s %s\n",
1562 		__FILE__, __LINE__,
1563 		exclusive ? "True" : "False",
1564 		spring_loaded ? "True" : "False"));
1565 	XtAddGrab(wid, exclusive, spring_loaded);
1566 
1567 	/*
1568 	 * Never, NEVER, add this callback before you'd set up the grab. See
1569 	 * below ( RemoveLessTifGrab() ) for some explanation.
1570 	 */
1571 	XtAddCallback(wid, XmNdestroyCallback,
1572 		(XtCallbackProc)LTRemoveGrabCallback,
1573 		(XtPointer)ve);
1574 	DEBUGOUT(_LtDebug(__FILE__, wid, "LTAddGrab - After it is added\n"));
1575 	DEBUGOUT(_LtDebug("GRAB", wid, "LTAddGrab - After it is added\n"));
1576 	dump_grab_list(d);
1577 }
1578 
1579 
1580 /*
1581  * The "public" grab interface. Put a widget on LessTif's grab list. This
1582  * will also set an Intrinsic's grab on that widget. The tricky thing comes
1583  * in whenever you remove the grab from such a widget... but see the comments
1584  * below for more information. Please note that you should always use
1585  * _XmAddGrab() instead of XtAddGrab() within LessTif.
1586  */
1587 extern void
_XmAddGrab(Widget wid,Boolean exclusive,Boolean spring_loaded)1588 _XmAddGrab(Widget wid, Boolean exclusive, Boolean spring_loaded)
1589 {
1590     DEBUGOUT(_LtDebug(__FILE__, wid, "_XmAddGrab()\n"));
1591     LTAddGrab(wid, exclusive, spring_loaded,
1592 	      (XmVendorShellExtObject)NULL, (XmVendorShellExtObject)NULL);
1593 }
1594 
1595 
1596 /*
1597  * The third parameter "remove_grab" is just a small optimization, so we
1598  * don't need to remove callbacks and grabs if the widget to be removed
1599  * from the grab list is already in the phase of being destroyed.
1600  * There's an exception though:
1601  *  It seems that Xt is cleaning up the grabs okay
1602  *  for anything except topLevelShells!
1603  *
1604  * One last reflection about what we're doing here:
1605  *   Especially during destruction of a widget we must restore right at
1606  *   this place all those grabs that have been issued after the grab on
1607  *   that widget in destruction. We therefore reissue the appropriate
1608  *   grabs. We *do rely* on the fact that during destruction of a widget
1609  *   the grab on that widget has *already been removed* by a callback.
1610  *   That grab in turn had been set up by the Intrinsics. So we *rely* on
1611  *   the calling order of callbacks. Sigh. This is the reason why you
1612  *   *must never* do the XtAddCallback() before the XtAddGrab() in
1613  *   LTAddGrab() -- or you're dead: in this case the cascade will break.
1614  *   See: LessTif and it's alter ego M*tif is an excellent example of
1615  *   clean design. Bang, bang, bang!
1616  */
1617 static void
LTRemoveGrab(Widget wid,XmVendorShellExtObject ve,Boolean remove_grab_physically)1618 LTRemoveGrab(Widget wid, XmVendorShellExtObject ve,
1619 	     Boolean remove_grab_physically)
1620 {
1621     Widget d;
1622     XmModalData pd, ps;
1623     int i, skipped;
1624 
1625     if (wid == NULL) {
1626 	wid = ExtObj_LogicalParent(ve);
1627 	DEBUGOUT(_LtDebug2(__FILE__, wid, (Widget)ve, "LTRemoveGrab\n"));
1628 	DEBUGOUT(_LtDebug2("GRAB", wid, (Widget)ve, "LTRemoveGrab\n"));
1629     } else {
1630 	DEBUGOUT(_LtDebug(__FILE__, wid, "LTRemoveGrab\n"));
1631 	DEBUGOUT(_LtDebug("GRAB", wid, "LTRemoveGrab\n"));
1632     }
1633 
1634     /*
1635      * If we got called during the destruction phase of a widget/object, we
1636      * don't mind about removing the callback at all -- the callback will
1637      * blast of into ethernity as soon as the widget fades away.
1638      */
1639     if (remove_grab_physically)
1640     {
1641 	XtRemoveCallback(wid, XmNdestroyCallback,
1642 			 (XtCallbackProc)LTRemoveGrabCallback,
1643 			 (XtPointer)ve);
1644     }
1645 
1646     /*
1647      * Now walk through the grab list and reissue all grabs that have
1648      * been issued after the grab(s) we just about to kill. Due to the
1649      * Intrinsics' cascade concept, we first must remove the grabs and
1650      * only then we can regrab the remaining widgets. Otherwise we can
1651      * put our list out of sync with the grabs set by the Intrinsics'
1652      */
1653     d = XmGetXmDisplay(XtDisplayOfObject(wid));
1654     dump_grab_list(d);
1655     pd = ps = Display_Modals(d);
1656     skipped = 0;
1657 
1658     for (i = Display_NumModals(d); i > 0; i--, ps++)
1659     {
1660 /*	DEBUGOUT(_LtDebug2("GRAB", XtParent(wid), wid, "NEDIT\n")); */
1661 
1662 /* amai: The famous "NEdit freeze" bug (an out of sync problem between
1663          the Xt and LT grab list) was cured by changing
1664            if ((ps->wid == wid) && !CoreBeingDestroyed(wid) && remove_grab_physically)
1665 	to
1666            if ((ps->wid == wid) && remove_grab_physically)
1667 
1668 	This 'fix' in turn triggered XtRemoveGrabs with bogus arguments, leading
1669 	to Xt warning messages. See comments at beginning of LTRemoveGrab()!
1670 */
1671 #if 1
1672 	if ((ps->wid == wid) && remove_grab_physically) {
1673 		DEBUGOUT(_LtDebug("GRAB", wid, "XtRemoveGrab-1\n"));
1674 		XtRemoveGrab(wid);
1675 	} else
1676 #endif
1677 #if 1
1678 	/* 1.83 version */
1679 	if ((XtParent(wid) == NULL) ||
1680 			((ps->wid == wid) && !CoreBeingDestroyed(wid) &&
1681 			!XtIsTopLevelShell(wid) && remove_grab_physically)) {
1682 		DEBUGOUT(_LtDebug("GRAB", wid, "XtRemoveGrab-2\n"));
1683 		XtRemoveGrab(wid);
1684 	}
1685 #endif
1686     }
1687 
1688     DEBUGOUT(_LtDebug("GRAB", wid, "Loop to restore grabs : %d iterations\n",
1689 	Display_NumModals(d)));
1690 
1691     ps = pd;
1692     for (i = Display_NumModals(d); i > 0; i--, ps++, pd++)
1693     {
1694 	do
1695 	{
1696 	    if (ps->wid == wid)
1697 	    {
1698 		DEBUGOUT(_LtDebug0("GRAB", wid, "\t%d : %s (skip, equal)\n",
1699 			i, ps->wid ? XtName(ps->wid) : "(null)"));
1700 		ps++;
1701 		i--;
1702 		skipped++;	/* skip this entry */
1703 	    }
1704 	    else if ((ps->grabber == ve) && ve)
1705 	    {
1706 
1707 		DEBUGOUT(_LtDebug0("GRAB", wid, "\t%d : %s (skip, primary appl modal)\n",
1708 			i, ps->wid ? XtName(ps->wid) : "(null)"));
1709 		/* Get rid off all primary application modal grabs too. */
1710 		ps++;
1711 		i--;
1712 		skipped++;
1713 	    }
1714 	    /* nothing more to skip at the moment */
1715 	    else
1716 	    {
1717 		DEBUGOUT(_LtDebug0("GRAB", wid, "\t%d : %s\n",
1718 			i, ps->wid ? XtName(ps->wid) : "(null)"));
1719 		break;
1720 	    }
1721 
1722 	}
1723 	while (i > 0);
1724 
1725 	/*
1726 	 * See if we've already reached the end of the list and leave
1727 	 * the loop then. Otherwise check if we've skipped one or more
1728 	 * entries. We know then that we must reissue all grabs coming
1729 	 * after the first entry skipped.
1730 	 */
1731 	if (i <= 0)
1732 	{
1733 	    DEBUGOUT(_LtDebug0("GRAB", wid, "\tLeave loop\n"));
1734 	    break;
1735 	}
1736 
1737 	if (pd != ps)
1738 	{
1739 	    *pd = *ps;
1740 	    DEBUGOUT(_LtDebug("GRAB", pd->wid, "%s:XtAddGrab(%d) - %s %s\n",
1741 		__FILE__, __LINE__,
1742 		pd->exclusive ? "True" : "False",
1743 		pd->springLoaded ? "True" : "False"));
1744 	    XtAddGrab(pd->wid, pd->exclusive, pd->springLoaded);
1745 	}
1746     }
1747 
1748     Display_NumModals(d) -= skipped;
1749     DEBUGOUT(_LtDebug("GRAB", wid, "End of loop to restore grabs : %d modals left\n",
1750 	Display_NumModals(d)));
1751 }
1752 
1753 
1754 /*
1755  * This is called whenever a widget issued a grab and is now being
1756  * destroyed. We then must remove the grab from LessTif's grab list
1757  * to this list in sync with the list from the Intrinsics. Note that the
1758  * grab has already been removed when we come to this function as calling
1759  * LTAddGrab() installs another callback located inside the Xt lib and that
1760  * callback removed the grab.
1761  */
1762 static void
LTRemoveGrabCallback(Widget wid,XtPointer client_data,XtPointer callback_data)1763 LTRemoveGrabCallback(Widget wid, XtPointer client_data,
1764 		     XtPointer callback_data)
1765 {
1766     DEBUGOUT(_LtDebug(__FILE__, wid, "LTRemoveGrabCallback()\n"));
1767     DEBUGOUT(_LtDebug("GRAB", wid, "LTRemoveGrabCallback()\n"));
1768 
1769     /* rws 14 Feb 1998
1770        This is the cause of the segfault in ddd when pressing OK from
1771        the edit->preferences dialog.  When the "init_shell" is created,
1772        or popped up, a grab gets added.  This callback is being invoked
1773        because the "init_shell" is being destroyed. For some reason the
1774        "init_shell" is not being considered a subclass of vendor and
1775        the grab was not being removed but the widget was getting destroyed.
1776        This causes problem later when we are playing with the grab list since
1777        this widget no longer exists _but_ is still on the grab list.
1778 
1779        The only way we get to this point is from a callback added in
1780        LTAddGrab.  That being the case it should be safe to remove the
1781        grab!!!
1782      */
1783 #if 0
1784     if (!XtIsSubclass(wid, vendorShellWidgetClass))
1785 #endif
1786     {
1787 #if 1
1788 	/* rws 18 Sep 1999
1789 	   This seems to be the problem of the nedit File->Open problem
1790 	   Also ddd --separate-windows
1791 	 */
1792 	LTRemoveGrab(wid, (XmVendorShellExtObject)client_data, False);
1793 #else
1794 	LTRemoveGrab(wid, (XmVendorShellExtObject)client_data, True);
1795 #endif
1796     }
1797 }
1798 
1799 
1800 /*
1801  * Simply remove a grab from a widget (identified by "wid"). This results
1802  * in: a) removal of the Intrinsics' grab,
1803  *     b) removal of the widget from LessTif's grab list.
1804  * All widgets that did add a grab after our widget wid had added a grab
1805  * will be put back on their grab. So LessTif's grab list isn't a cascade
1806  * like the Intrinsics' grab list but rather a modality list.
1807  */
1808 extern void
_XmRemoveGrab(Widget wid)1809 _XmRemoveGrab(Widget wid)
1810 {
1811     DEBUGOUT(_LtDebug(__FILE__, wid, "_XmRemoveGrab()\n"));
1812     LTRemoveGrab(wid, NULL, True);
1813 }
1814 
1815 
1816 /*
1817  * Whenever a primary application modal dialog shows up we must add grabs
1818  * to all those shells which are not a parental shell of that dialog. This
1819  * function as well as the next one -- LTGrabRelatives() -- are responsible
1820  * for this task. LTGrabRelatives() ascends the shell shadow hierarchy
1821  * starting with the primary application modal dialog and calls LTGrabKids()
1822  * for every side-branch. LTGrabKids() then recursively put all shells
1823  * located within the branch on the grab list again.
1824  */
1825 static void
LTGrabKids(XmVendorShellExtObject ve,XmVendorShellExtObject skip_branch,XmVendorShellExtObject grabber)1826 LTGrabKids(XmVendorShellExtObject ve,
1827 	   XmVendorShellExtObject skip_branch,
1828 	   XmVendorShellExtObject grabber)
1829 {
1830     int num_kids;
1831     WidgetList kids;
1832     Widget logParent;
1833 
1834     DEBUGOUT(_LtDebug(__FILE__, NULL, "LTGrabKids()\n"));
1835     /*
1836      * Depending on the class of object within the shadow shell hierarchy
1837      * we've to choose one out of three different ways to get the object's
1838      * child list.
1839      */
1840     if (XmIsDisplay(ve))
1841     {
1842 	/*
1843 	 * We do use the short path and dive into the next deeper level
1844 	 * of the shadow hierarchy. There we recursively repeat our task.
1845 	 */
1846 	kids = MGR_Children((Widget)ve);
1847 	num_kids = MGR_NumChildren((Widget)ve);
1848 	for (; --num_kids >= 0; kids++)
1849 	{
1850 	    if (((XmVendorShellExtObject)*kids != skip_branch) &&
1851 		XmIsScreen(*kids))
1852 	    {
1853 		LTGrabKids((XmVendorShellExtObject)*kids,
1854 			   skip_branch, grabber);
1855 	    }
1856 	}
1857 
1858 	return;
1859     }
1860     else if (_XmIsFastSubclass(XtClass(ve), XmSCREEN_BIT))
1861     {
1862 	kids = ((XmScreen)ve)->desktop.children;
1863 	num_kids = ((XmScreen)ve)->desktop.num_children;
1864     }
1865     else
1866     {
1867 	kids = Desktop_Children(ve);
1868 	num_kids = Desktop_NumChildren(ve);
1869     }
1870 
1871     /*
1872      * We're either working on the children of a screen widget or a
1873      * vendor shell extension object. So we're sure in every case that
1874      * these kids are vendor shell extension objects.
1875      */
1876     for (; --num_kids >= 0; kids++)
1877     {
1878 	if ((XmVendorShellExtObject)*kids != skip_branch)
1879 	{
1880 	    logParent = ExtObj_LogicalParent(*kids);
1881 	    /*
1882 	     * If the shell (those vendor shell extension object we're just
1883 	     * observing) has been popped up we must set a non-exclusive
1884 	     * grab on it or otherwise it will get no user input events.
1885 	     * In case this shell is not a popup shell but rather a top
1886 	     * level shell and it has been realized then we must add
1887 	     * a non-exclusive grab, too. Otherwise we would cut it off
1888 	     * from user input.
1889 	     */
1890 	    if (Shell_PoppedUp(logParent))
1891 	    {
1892 		LTAddGrab(NULL, False, False,
1893 			  (XmVendorShellExtObject)*kids, grabber);
1894 	    }
1895 	    else if (XtIsRealized(logParent) &&
1896 		     !LTIsARealPopupShell(logParent))
1897 	    {
1898 		LTAddGrab(NULL, False, False,
1899 			  (XmVendorShellExtObject)*kids, grabber);
1900 	    }
1901 	    /*
1902 	     * Dive into next level of the shadow shell hierarchy and
1903 	     * repeat your task there...
1904 	     */
1905 	    LTGrabKids((XmVendorShellExtObject)*kids,
1906 		       skip_branch, grabber);
1907 	}
1908     }
1909 }
1910 
1911 
1912 /*
1913  * Within this function we start at those vendor shell extension object
1914  * which has belongs to the dialog just about to pop up. Then we ascend
1915  * the shadow shell hierarchy, and at each level we descend into those
1916  * branches which we haven't visited so far. This way we only add a grab
1917  * to such dialogs which are not parents of the current pop up dialog.
1918  */
1919 static void
LTGrabRelatives(XmVendorShellExtObject grabber)1920 LTGrabRelatives(XmVendorShellExtObject grabber)
1921 {
1922     XmVendorShellExtObject eo, skip_branch;
1923 
1924     DEBUGOUT(_LtDebug(__FILE__, NULL, "LTGrabRelatives()\n"));
1925     eo = (XmVendorShellExtObject)Desktop_Parent(grabber);
1926     skip_branch = grabber;
1927     for (;;)
1928     {
1929 	/*
1930 	 * Descend into side-branches not visited so far...
1931 	 */
1932 	LTGrabKids(eo, skip_branch, grabber);
1933 	skip_branch = eo;
1934 	if (_XmIsFastSubclass(XtClass(eo), XmDISPLAY_BIT))
1935 	{
1936 	    /*
1937 	     * We've reached the top of the shadow shell hierarchy. So
1938 	     * let us make a break. We've now visited all important
1939 	     * relatives.
1940 	     */
1941 	    break;
1942 	}
1943 	else if (_XmIsFastSubclass(XtClass(eo), XmSCREEN_BIT))
1944 	{
1945 	    eo = (XmVendorShellExtObject)XtParent(eo);
1946 	}
1947 	else
1948 	{
1949 	    eo = (XmVendorShellExtObject)Desktop_Parent(eo);
1950 	}
1951     }
1952 }				/* LTGrabRelatives */
1953 
1954 
1955 /*
1956  * Whenever a shell widget pops up on the display of a surprised user this
1957  * callback handler makes sure the appropiate grabs are installed according
1958  * to the modality mode of the shell. Ouch, what a sentence.
1959  */
1960 static void
LTShellPopupCallback(Widget w,XtPointer ClientData,XtPointer CallbackData)1961 LTShellPopupCallback(Widget w, XtPointer ClientData, XtPointer CallbackData)
1962 {
1963     XmVendorShellExtObject ve = (XmVendorShellExtObject)ClientData;
1964     Widget ws;
1965     XtGrabKind GrabKind = XtGrabNone;
1966     Boolean GrabRelatives = False;
1967 
1968     DEBUGOUT(_LtDebug(__FILE__, w, "LTShellPopupCallback(%s)\n",
1969 	_LtDebugMwmInput2String(VSEP_MwmHints(ve).input_mode)));
1970 
1971     ws = XmGetXmScreen(XtScreenOfObject(w));
1972 
1973     VSEP_XAtMap(ve) = XtX(w);
1974     VSEP_YAtMap(ve) = XtY(w);
1975     if (!XtIsRealized(w) /* == None */ )
1976 	XtRealizeWidget(w);
1977 
1978     /* FIX ME! Is the next one right?? */
1979     VSEP_LastMapRequest(ve) = LastKnownRequestProcessed(XtDisplayOfObject(w));
1980 
1981     switch (VSEP_MwmHints(ve).input_mode)
1982     {
1983     case MWM_INPUT_PRIMARY_APPLICATION_MODAL:
1984 	/*
1985 	 * Input to the ancestors of this window is prohibited. That is, no
1986 	 * parental shell will receive input, whereas our relatives (cousines)
1987 	 * will still receive input as will all dialogs of other top level
1988 	 * shells within our application.
1989 	 */
1990 	GrabKind = XtGrabExclusive;
1991 	if (Screen_MwmPresent(ws))
1992 	{
1993 	    /*
1994 	     * This is at least what M*tif does: if can't find mwm it just
1995 	     * disables ALL other dialogs after popping up a primary
1996 	     * application modal dialog. SOOOORRRRYYY. But I don't know
1997 	     * what support from mwm here would be necessary.
1998 	     */
1999 	    GrabRelatives = True;
2000 	}
2001 	break;
2002 
2003     case MWM_INPUT_SYSTEM_MODAL:
2004 	/*
2005 	 * Input only goes to this window, no other window from any other
2006 	 * application or ourself can receive input. This needs help from
2007 	 * the window manager.
2008 	 *
2009 	 * Fall through.
2010 	 */
2011 
2012     case MWM_INPUT_FULL_APPLICATION_MODAL:
2013 	/*
2014 	 * Input only goes to this window within this application. Other
2015 	 * applications receive input as normal.
2016 	 */
2017 	GrabKind = XtGrabExclusive;	/* Only dispatch all incoming events
2018 					 * to us.
2019 					 */
2020 	break;
2021 
2022     case MWM_INPUT_MODELESS:
2023     default:
2024 	/*
2025 	 * The input goes to any window as usual.
2026 	 */
2027 	GrabKind = XtGrabNonexclusive;
2028 	break;
2029     }
2030 
2031     if (GrabKind != XtGrabNone)
2032     {
2033 	LTAddGrab(NULL,
2034 		  GrabKind == XtGrabExclusive ? True : False, False,
2035 		  ve, ve);
2036     }
2037     VSEP_GrabKind(ve) = GrabKind;
2038     if (GrabRelatives)
2039     {
2040 	LTGrabRelatives(ve);
2041     }
2042 }
2043 
2044 
2045 static void
LTShellPopdownCallback(Widget w,XtPointer ClientData,XtPointer CallbackData)2046 LTShellPopdownCallback(Widget w, XtPointer ClientData, XtPointer CallbackData)
2047 {
2048     XmVendorShellExtObject ve = (XmVendorShellExtObject)ClientData;
2049 
2050     DEBUGOUT(_LtDebug(__FILE__, w, "ShellPopdown callback\n"));
2051 
2052     if (VSEP_GrabKind(ve) != XtGrabNone)
2053     {
2054 	DEBUGOUT(_LtDebug(__FILE__, w, "Remove grab\n"));
2055 
2056 	LTRemoveGrab(NULL, ve, True);
2057     }
2058 }
2059 
2060 #ifndef DEFAULT_WM_TIMEOUT
2061 #define DEFAULT_WM_TIMEOUT 500
2062 #endif
2063 
2064 
2065 static void
ComputeWMSizeHints(WMShellWidget w,XSizeHints * hints)2066 ComputeWMSizeHints(WMShellWidget w, XSizeHints * hints)
2067 {
2068     long flags;
2069 
2070     hints->flags = flags = w->wm.size_hints.flags;
2071 
2072 #define copy(field) hints->field = w->wm.size_hints.field
2073 
2074     if (flags & (USPosition | PPosition))
2075     {
2076 	copy(x);
2077 	copy(y);
2078     }
2079     if (flags & (USSize | PSize))
2080     {
2081 	copy(width);
2082 	copy(height);
2083     }
2084     if (flags & PMinSize)
2085     {
2086 	copy(min_width);
2087 	copy(min_height);
2088     }
2089     if (flags & PMaxSize)
2090     {
2091 	copy(max_width);
2092 	copy(max_height);
2093     }
2094     if (flags & PResizeInc)
2095     {
2096 	copy(width_inc);
2097 	copy(height_inc);
2098     }
2099     if (flags & PAspect)
2100     {
2101 	copy(min_aspect.x);
2102 	copy(min_aspect.y);
2103 	copy(max_aspect.x);
2104 	copy(max_aspect.y);
2105     }
2106 #undef copy
2107 #define copy(field) hints->field = w->wm.field
2108     if (flags & PBaseSize)
2109     {
2110 	copy(base_width);
2111 	copy(base_height);
2112     }
2113     if (flags & PWinGravity)
2114     {
2115 	copy(win_gravity);
2116     }
2117 #undef copy
2118 }
2119 
2120 
2121 static void
SetWMSizeHints(WMShellWidget w)2122 SetWMSizeHints(WMShellWidget w)
2123 {
2124     XSizeHints *size_hints = XAllocSizeHints();
2125 
2126     if (size_hints == NULL)
2127     {
2128 	_XmError((Widget)w, "XAllocSizeHints failed.");
2129     }
2130 
2131     ComputeWMSizeHints(w, size_hints);
2132 
2133     XSetWMNormalHints(XtDisplay((Widget)w), XtWindow((Widget)w), size_hints);
2134 
2135     XFree((char *)size_hints);
2136 }
2137 
2138 #if XtSpecificationRelease < 6
2139 
2140 #define WM_CONFIGURE_DENIED(w) (((WMShellWidget) (w))->wm.wm_configure_denied)
2141 #define WM_MOVED(w) (((WMShellWidget) (w))->wm.wm_moved)
2142 
2143 typedef struct
2144 {
2145     Widget w;
2146     unsigned long request_num;
2147     Boolean done;
2148 }
2149 QueryStruct;
2150 
2151 /* A prototype for a private libXt function ... */
2152 /* rws 17 Dec 2000
2153    The lower case w may look wrong here, BUT IT IS NOT
2154  */
2155 extern int _XtwaitForSomething(_XtBoolean ignoreTimers, _XtBoolean ignoreInputs,
2156 			       _XtBoolean ignoreEvents, _XtBoolean block,
2157 			       unsigned long *howlong, XtAppContext app);
2158 
2159 static Bool
ConfigEventForMe(Display * dpy,XEvent * event,char * arg)2160 ConfigEventForMe(Display *dpy, XEvent *event, char *arg)
2161 {
2162     QueryStruct *q = (QueryStruct *) arg;
2163     Widget w = q->w;
2164 
2165     if ((dpy != XtDisplay(w)) || (event->xany.window != XtWindow(w)))
2166     {
2167 	return FALSE;
2168     }
2169     if (event->xany.serial >= q->request_num)
2170     {
2171 	if (event->type == ConfigureNotify)
2172 	{
2173 	    q->done = TRUE;
2174 
2175 	    return TRUE;
2176 	}
2177 	else
2178 	{
2179 	    /* This is draft-ICCCM stuff; here for compatibility */
2180 	    if (event->type == ClientMessage &&
2181 		(event->xclient.message_type == WM_CONFIGURE_DENIED(w) ||
2182 		 event->xclient.message_type == WM_MOVED(w)))
2183 	    {
2184 		q->done = TRUE;
2185 
2186 		return TRUE;
2187 	    }
2188 	}
2189     }
2190     else if (event->type == ConfigureNotify ||
2191 	     (event->type == ClientMessage &&
2192 	      (event->xclient.message_type == WM_CONFIGURE_DENIED(w) ||
2193 	       event->xclient.message_type == WM_MOVED(w))))
2194     {
2195 	/* flush old events */
2196 	return TRUE;
2197     }
2198 
2199     if (event->type == ReparentNotify &&
2200 	event->xreparent.window == XtWindow(w))
2201     {
2202 	/* we might get ahead of this event, so just in case someone
2203 	 * asks for coordinates before this event is dispatched...
2204 	 */
2205 	ShellWidget s = (ShellWidget)w;
2206 	if (event->xreparent.parent != RootWindowOfScreen(XtScreen(w)))
2207 	{
2208 	    s->shell.client_specified &= ~_XtShellNotReparented;
2209 	}
2210 	else
2211 	{
2212 	    s->shell.client_specified |= _XtShellNotReparented;
2213 	}
2214     }
2215 
2216     return FALSE;
2217 }
2218 
2219 
2220 static int
WaitForWM(ShellWidget w,XEvent * event,unsigned long request_num)2221 WaitForWM(ShellWidget w, XEvent *event, unsigned long request_num)
2222 {
2223     XtAppContext app = XtWidgetToApplicationContext((Widget)w);
2224     QueryStruct q;
2225     unsigned long timeout;
2226 
2227     if (XtIsWMShell((Widget)w))
2228     {
2229 	timeout = ((WMShellWidget)w)->wm.wm_timeout;
2230     }
2231     else
2232     {
2233 	timeout = DEFAULT_WM_TIMEOUT;
2234     }
2235 
2236     XFlush(XtDisplay(w));
2237     q.w = (Widget)w;
2238     q.request_num = request_num;
2239     q.done = FALSE;
2240 
2241     for (;;)
2242     {
2243 	/*
2244 	 * look for match event and discard all prior configures
2245 	 */
2246 	if (XCheckIfEvent(XtDisplay(w), event, ConfigEventForMe, (char *)&q))
2247 	{
2248 	    if (q.done)
2249 	    {
2250 		return TRUE;
2251 	    }
2252 	    else
2253 	    {
2254 		continue;	/* flush old events */
2255 	    }
2256 	}
2257 
2258 /* rws 17 Dec 2000
2259    The lower case w may look wrong here, BUT IT IS NOT
2260  */
2261 	if (_XtwaitForSomething(TRUE, TRUE, FALSE, TRUE, &timeout, app) != -1)
2262 	{
2263 	    continue;
2264 	}
2265 	if (timeout == 0)
2266 	{
2267 	    return FALSE;
2268 	}
2269     }
2270 }
2271 
2272 
2273 extern XtGeometryResult
_XmRootGeometryManager(Widget wid,XtWidgetGeometry * request,XtWidgetGeometry * reply)2274 _XmRootGeometryManager(Widget wid,
2275 		       XtWidgetGeometry *request,
2276 		       XtWidgetGeometry *reply)
2277 {
2278     ShellWidget w = (ShellWidget)wid;
2279     XWindowChanges values;
2280     unsigned int mask = request->request_mode;
2281     XEvent event;
2282     Boolean wm;
2283     struct _OldXSizeHints *hintp = NULL;
2284     int oldx, oldy, oldwidth, oldheight, oldborder_width;
2285     unsigned long request_num;
2286     extern String XtCXtToolkitError;
2287 
2288     if (XtIsWMShell(wid))
2289     {
2290 	wm = True;
2291 	hintp = &((WMShellWidget)w)->wm.size_hints;
2292 	/* for draft-ICCCM wm's, need to make sure hints reflect
2293 	 * (current) reality so client can move and size separately. */
2294 	hintp->x = XtX(w);
2295 	hintp->y = XtY(w);
2296 	hintp->width = XtWidth(w);
2297 	hintp->height = XtHeight(w);
2298     }
2299     else
2300     {
2301 	wm = False;
2302     }
2303 
2304     oldx = XtX(w);
2305     oldy = XtY(w);
2306     oldwidth = XtWidth(w);
2307     oldheight = XtHeight(w);
2308     oldborder_width = XtBorderWidth(w);
2309 
2310 #define PutBackGeometry() \
2311         { XtX(w) = oldx; \
2312           XtY(w) = oldy; \
2313           XtWidth(w) = oldwidth; \
2314           XtHeight(w) = oldheight; \
2315           XtBorderWidth(w) = oldborder_width; }
2316 
2317     if (mask & CWX)
2318     {
2319 	if (XtX(w) == request->x)
2320 	{
2321 	    mask &= ~CWX;
2322 	}
2323 	else
2324 	{
2325 	    XtX(w) = values.x = request->x;
2326 	    if (wm)
2327 	    {
2328 		hintp->flags &= ~USPosition;
2329 		hintp->flags |= PPosition;
2330 		hintp->x = values.x;
2331 	    }
2332 	}
2333     }
2334 
2335     if (mask & CWY)
2336     {
2337 	if (XtY(w) == request->y)
2338 	{
2339 	    mask &= ~CWY;
2340 	}
2341 	else
2342 	{
2343 	    XtY(w) = values.y = request->y;
2344 	    if (wm)
2345 	    {
2346 		hintp->flags &= ~USPosition;
2347 		hintp->flags |= PPosition;
2348 		hintp->y = values.y;
2349 	    }
2350 	}
2351     }
2352 
2353     if (mask & CWBorderWidth)
2354     {
2355 	if (XtBorderWidth(w) == request->border_width)
2356 	{
2357 	    mask &= ~CWBorderWidth;
2358 	}
2359 	else
2360 	{
2361 	    XtBorderWidth(w) = values.border_width = request->border_width;
2362 	}
2363     }
2364 
2365     if (mask & CWWidth)
2366     {
2367 	if (XtWidth(w) == request->width)
2368 	{
2369 	    mask &= ~CWWidth;
2370 	}
2371 	else
2372 	{
2373 	    XtWidth(w) = values.width = request->width;
2374 	    if (wm)
2375 	    {
2376 		hintp->flags &= ~USSize;
2377 		hintp->flags |= PSize;
2378 		hintp->width = values.width;
2379 	    }
2380 	}
2381     }
2382 
2383     if (mask & CWHeight)
2384     {
2385 	if (XtHeight(w) == request->height)
2386 	{
2387 	    mask &= ~CWHeight;
2388 	}
2389 	else
2390 	{
2391 	    XtHeight(w) = values.height = request->height;
2392 	    if (wm)
2393 	    {
2394 		hintp->flags &= ~USSize;
2395 		hintp->flags |= PSize;
2396 		hintp->height = values.height;
2397 	    }
2398 	}
2399     }
2400 
2401     if (mask & CWStackMode)
2402     {
2403 	values.stack_mode = request->stack_mode;
2404 	if (mask & CWSibling)
2405 	{
2406 	    values.sibling = XtWindow(request->sibling);
2407 	}
2408     }
2409 
2410     if (!XtIsRealized((Widget)w))
2411     {
2412 	return XtGeometryYes;
2413     }
2414 
2415     request_num = NextRequest(XtDisplay(w));
2416 
2417     XConfigureWindow(XtDisplay((Widget)w), XtWindow((Widget)w), mask, &values);
2418 
2419     if (wm && !w->shell.override_redirect &&
2420 	mask & (CWX | CWY | CWWidth | CWHeight | CWBorderWidth))
2421     {
2422 	SetWMSizeHints((WMShellWidget)w);
2423     }
2424 
2425     if (w->shell.override_redirect)
2426     {
2427 	return XtGeometryYes;
2428     }
2429 
2430     /* If no non-stacking bits are set, there's no way to tell whether
2431      * or not this worked, so assume it did */
2432     if (!(mask & ~(CWStackMode | CWSibling)))
2433     {
2434 	return XtGeometryYes;
2435     }
2436 
2437     if (wm && ((WMShellWidget)w)->wm.wait_for_wm == FALSE)
2438     {
2439 	/* From Xt:
2440 	 * the window manager is sick so I will do the work and
2441 	 * say no so if a new WM starts up, or the current one recovers
2442 	 * my size requests will be visible
2443 	 *
2444 	 * From MLM:
2445 	 * This is madness, I think.  That means you'll refuse any resize
2446 	 * requests, unless the WM follows the ICCCM, right?
2447 	 */
2448 	return XtGeometryYes;
2449     }
2450 
2451     if (WaitForWM(w, &event, request_num))
2452     {
2453 	/* got an event */
2454 	if (event.type == ConfigureNotify)
2455 	{
2456 
2457 
2458 #define NEQ(x, msk) ((mask & msk) && (values.x != event.xconfigure.x))
2459 	    if (NEQ(x, CWX) ||
2460 		NEQ(y, CWY) ||
2461 		NEQ(width, CWWidth) ||
2462 		NEQ(height, CWHeight) ||
2463 		NEQ(border_width, CWBorderWidth))
2464 	    {
2465 #undef NEQ
2466 		XPutBackEvent(XtDisplay(w), &event);
2467 		PutBackGeometry();
2468 
2469 		/*
2470 		 * We just potentially re-ordered the event queue
2471 		 * w.r.t. ConfigureNotifies with some trepidation.
2472 		 * But this is probably a Good Thing because we
2473 		 * will know the new true state of the world sooner
2474 		 * this way.
2475 		 */
2476 
2477 		DEBUGOUT(_LtDebug(__FILE__, (Widget)w,
2478 				  "Returning XtGeometryNo because config "
2479 				  "differed\n"));
2480 
2481 		return XtGeometryNo;
2482 	    }
2483 	    else
2484 	    {
2485 		XtWidth(w) = event.xconfigure.width;
2486 		XtHeight(w) = event.xconfigure.height;
2487 		XtBorderWidth(w) = event.xconfigure.border_width;
2488 
2489 		if (event.xany.send_event ||	/* ICCCM compliant synth */
2490 		    w->shell.client_specified & _XtShellNotReparented)
2491 		{
2492 
2493 		    XtX(w) = event.xconfigure.x;
2494 		    XtY(w) = event.xconfigure.y;
2495 		    w->shell.client_specified |= _XtShellPositionValid;
2496 		}
2497 		else
2498 		{
2499 		    w->shell.client_specified &= ~_XtShellPositionValid;
2500 		}
2501 
2502 		return XtGeometryYes;
2503 	    }
2504 	}
2505 	else if (!wm ||
2506 		 (event.type == ClientMessage &&
2507 		  event.xclient.message_type == WM_CONFIGURE_DENIED(w)))
2508 	{
2509 	    PutBackGeometry();
2510 
2511 	    DEBUGOUT(_LtDebug(__FILE__, (Widget)w,
2512 			      "Returning XtGeometryNo because config "
2513 			      "denied\n"));
2514 
2515 	    return XtGeometryNo;
2516 	}
2517 	else if (event.type == ClientMessage &&
2518 		 event.xclient.message_type == WM_MOVED(w))
2519 	{
2520 	    XtX(w) = event.xclient.data.s[0];
2521 	    XtY(w) = event.xclient.data.s[1];
2522 	    w->shell.client_specified |= _XtShellPositionValid;
2523 	    return XtGeometryYes;
2524 	}
2525 	else
2526 	{
2527 	    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)w),
2528 			    "internalError", "shell", XtCXtToolkitError,
2529 			    "Shell's window manager interaction is broken",
2530 			    (String *)NULL, (Cardinal *)NULL);
2531 	}
2532     }
2533     else if (wm)
2534     {
2535 	/* no event */
2536 	((WMShellWidget)w)->wm.wait_for_wm = FALSE;
2537 	/* timed out; must be broken */
2538     }
2539 
2540 #undef PutBackGeometry
2541 
2542     return XtGeometryYes;
2543 }
2544 
2545 #else
2546 
2547 /*
2548  * For R6:
2549  */
2550 
2551 typedef struct
2552 {
2553     Widget w;
2554     unsigned long request_num;
2555     Boolean done;
2556 }
2557 QueryStruct;
2558 
2559 /* A prototype for a private libXt function ... */
2560 extern int _XtWaitForSomething(XtAppContext app,
2561 			       _XtBoolean ignoreEvents,
2562 			       _XtBoolean ignoreTimers,
2563 			       _XtBoolean ignoreInputs,
2564 			       _XtBoolean ignoreSignals,
2565 			       _XtBoolean block,
2566 #ifdef XTHREADS
2567 			       _XtBoolean drop_lock,
2568 #endif
2569 			       unsigned long *howlong);
2570 
2571 /* amai: citing the docs, e.g. from
2572  *     ftp://ftp.x.org/pub/R6.6/xc/lib/Xt/NextEvent.c
2573  * for that
2574  * Routine to block in the toolkit.  This should be the only call to select.
2575  *
2576  * This routine returns when there is something to be done.
2577  *
2578  * Before calling this with ignoreInputs==False, app->outstandingQueue should
2579  * be checked; this routine will not verify that an alternate input source
2580  * has not already been enqueued.
2581  *
2582  *
2583  * _XtWaitForSomething( appContext,
2584  *                      ignoreEvent, ignoreTimers, ignoreInputs, ignoreSignals,
2585  *			block, drop_lock, howlong)
2586  * XtAppContext app;	     (Displays to check wait on)
2587  *
2588  * Boolean ignoreEvents;     (Don't return if XEvents are available
2589  *                              Also implies forget XEvents exist)
2590  *
2591  * Boolean ignoreTimers;     (Ditto for timers)
2592  *
2593  * Boolean ignoreInputs;     (Ditto for input callbacks )
2594  *
2595  * Boolean ignoreSignals;    (Ditto for signals)
2596  *
2597  * Boolean block;	     (Okay to block)
2598  *
2599  * Boolean drop_lock         (drop lock before going into select/poll)
2600  *
2601  * TimeVal howlong;	     (howlong to wait for if blocking and not
2602  *				doing Timers... Null means forever.
2603  *				Maybe should mean shortest of both)
2604  * Returns display for which input is available, if any
2605  * and if ignoreEvents==False, else returns -1
2606  *
2607  * if ignoring everything && block=True && howlong=NULL, you'll have
2608  * lots of time for coffee; better not try it!  In fact, it probably
2609  * makes little sense to do this regardless of the value of howlong
2610  * (bottom line is, we don't bother checking here).
2611  *
2612  * If drop_lock is FALSE, the app->lock->mutex is not unlocked before
2613  * entering select/poll. It is illegal for drop_lock to be FALSE if
2614  * ignoreTimers, ignoreInputs, or ignoreSignals is FALSE.
2615  */
2616 
2617 static Bool
ConfigEventForMe(Display * dpy,XEvent * event,char * arg)2618 ConfigEventForMe(Display *dpy, XEvent *event, char *arg)
2619 {
2620     QueryStruct *q = (QueryStruct *) arg;
2621     Widget w = q->w;
2622 
2623     if ((dpy != XtDisplay(w)) || (event->xany.window != XtWindow(w)))
2624     {
2625 	return FALSE;
2626     }
2627     if (event->xany.serial >= q->request_num)
2628     {
2629 	if (event->type == ConfigureNotify)
2630 	{
2631 	    q->done = TRUE;
2632 	    return TRUE;
2633 	}
2634     }
2635     else if (event->type == ConfigureNotify)
2636     {
2637 	/* flush old events */
2638 	return TRUE;
2639     }
2640 
2641     if (event->type == ReparentNotify
2642 	&& event->xreparent.window == XtWindow(w))
2643     {
2644 	/* we might get ahead of this event, so just in case someone
2645 	 * asks for coordinates before this event is dispatched...
2646 	 */
2647 	ShellWidget s = (ShellWidget)w;
2648 	if (event->xreparent.parent != RootWindowOfScreen(XtScreen(w)))
2649 	{
2650 	    s->shell.client_specified &= ~_XtShellNotReparented;
2651 	}
2652 	else
2653 	{
2654 	    s->shell.client_specified |= _XtShellNotReparented;
2655 	}
2656     }
2657 
2658     return FALSE;
2659 }
2660 
2661 
2662 static int
WaitForWM(ShellWidget w,XEvent * event,unsigned long request_num)2663 WaitForWM(ShellWidget w, XEvent *event, unsigned long request_num)
2664 {
2665     XtAppContext app = XtWidgetToApplicationContext((Widget)w);
2666     QueryStruct q;
2667     unsigned long timeout;
2668 
2669     if (XtIsWMShell((Widget)w))
2670     {
2671 	timeout = ((WMShellWidget)w)->wm.wm_timeout;
2672     }
2673     else
2674     {
2675 	timeout = DEFAULT_WM_TIMEOUT;
2676     }
2677 
2678     XFlush(XtDisplay(w));
2679     q.w = (Widget)w;
2680     q.request_num = request_num;
2681     q.done = FALSE;
2682 
2683     /*
2684      * look for match event and discard all prior configures
2685      */
2686     while (XCheckIfEvent(XtDisplay(w), event, ConfigEventForMe, (char *)&q))
2687     {
2688 	if (q.done)
2689 	{
2690 	    return TRUE;
2691 	}
2692     }
2693 
2694 /*
2695   amai: we have to get rid of this _XtWaitForSomething ASAP:
2696     this call changes it's signature based on compile-time options
2697     for the X libraries :-(
2698     So beyond the pure annoying fact of using a non-documented, private call
2699     from libXt we also break cross-compiling.
2700     And no, a run-time if-clause is not a "real" solution IMHO.
2701     A proposal is to install an even handler and a timer
2702        XtAppAddTimeOut()
2703        XtAddEventHandler()
2704     and then do the remaining job in the triggered callbacks.
2705     WaitForWM() is only called once in the code, one has to check
2706     what is done _there_.
2707 */
2708     while (timeout > 0)
2709     {
2710 	if (_XtWaitForSomething(app,
2711 				FALSE,
2712 				TRUE,
2713 				TRUE,
2714 				TRUE,
2715 				TRUE,
2716 #ifdef XTHREADS
2717 				FALSE,
2718 #endif
2719 				&timeout) != -1)
2720 	{
2721 	    while (XCheckIfEvent(XtDisplay(w), event,
2722 				 ConfigEventForMe, (char *)&q))
2723 	    {
2724 		if (q.done)
2725 		{
2726 		    return TRUE;
2727 		}
2728 	    }
2729 	}
2730     }
2731     return FALSE;
2732 }
2733 
2734 
2735 XtGeometryResult
_XmRootGeometryManager(Widget gw,XtWidgetGeometry * request,XtWidgetGeometry * reply)2736 _XmRootGeometryManager(Widget gw,
2737 		       XtWidgetGeometry *request,
2738 		       XtWidgetGeometry *reply)
2739 {
2740     ShellWidget w = (ShellWidget)gw;
2741     XWindowChanges values;
2742     unsigned int mask = request->request_mode;
2743     XEvent event;
2744     Boolean wm;
2745     struct _OldXSizeHints *hintp = NULL;
2746     int oldx, oldy, oldwidth, oldheight, oldborder_width;
2747     unsigned long request_num;
2748     extern String XtCXtToolkitError;
2749 
2750     if (XtIsWMShell(gw))
2751     {
2752 	wm = True;
2753 	hintp = &((WMShellWidget)w)->wm.size_hints;
2754 	/* for draft-ICCCM wm's, need to make sure hints reflect
2755 	   (current) reality so client can move and size separately. */
2756 	hintp->x = XtX(w);
2757 	hintp->y = XtY(w);
2758 	hintp->width = XtWidth(w);
2759 	hintp->height = XtHeight(w);
2760     }
2761     else
2762     {
2763 	wm = False;
2764     }
2765 
2766     oldx = XtX(w);
2767     oldy = XtY(w);
2768     oldwidth = XtWidth(w);
2769     oldheight = XtHeight(w);
2770     oldborder_width = XtBorderWidth(w);
2771 
2772 #define PutBackGeometry() \
2773         { XtX(w) = oldx; \
2774           XtY(w) = oldy; \
2775           XtWidth(w) = oldwidth; \
2776           XtHeight(w) = oldheight; \
2777           XtBorderWidth(w) = oldborder_width; }
2778 
2779     if (mask & CWX)
2780     {
2781 	if (XtX(w) == request->x)
2782 	{
2783 	    mask &= ~CWX;
2784 	}
2785 	else
2786 	{
2787 	    XtX(w) = values.x = request->x;
2788 	    if (wm)
2789 	    {
2790 		hintp->flags &= ~USPosition;
2791 		hintp->flags |= PPosition;
2792 		hintp->x = values.x;
2793 	    }
2794 	}
2795     }
2796     if (mask & CWY)
2797     {
2798 	if (XtY(w) == request->y)
2799 	{
2800 	    mask &= ~CWY;
2801 	}
2802 	else
2803 	{
2804 	    XtY(w) = values.y = request->y;
2805 	    if (wm)
2806 	    {
2807 		hintp->flags &= ~USPosition;
2808 		hintp->flags |= PPosition;
2809 		hintp->y = values.y;
2810 	    }
2811 	}
2812     }
2813     if (mask & CWBorderWidth)
2814     {
2815 	if (XtBorderWidth(w) == request->border_width)
2816 	{
2817 	    mask &= ~CWBorderWidth;
2818 	}
2819 	else
2820 	{
2821 	    XtBorderWidth(w) = values.border_width = request->border_width;
2822 	}
2823     }
2824     if (mask & CWWidth)
2825     {
2826 	if (XtWidth(w) == request->width)
2827 	{
2828 	    mask &= ~CWWidth;
2829 	}
2830 	else
2831 	{
2832 	    XtWidth(w) = values.width = request->width;
2833 	    if (wm)
2834 	    {
2835 		hintp->flags &= ~USSize;
2836 		hintp->flags |= PSize;
2837 		hintp->width = values.width;
2838 	    }
2839 	}
2840     }
2841     if (mask & CWHeight)
2842     {
2843 	if (XtHeight(w) == request->height)
2844 	{
2845 	    mask &= ~CWHeight;
2846 	}
2847 	else
2848 	{
2849 	    XtHeight(w) = values.height = request->height;
2850 	    if (wm)
2851 	    {
2852 		hintp->flags &= ~USSize;
2853 		hintp->flags |= PSize;
2854 		hintp->height = values.height;
2855 	    }
2856 	}
2857     }
2858     if (mask & CWStackMode)
2859     {
2860 	values.stack_mode = request->stack_mode;
2861 	if (mask & CWSibling)
2862 	{
2863 	    values.sibling = XtWindow(request->sibling);
2864 	}
2865     }
2866 
2867     if (!XtIsRealized((Widget)w))
2868     {
2869 	return XtGeometryYes;
2870     }
2871 
2872     request_num = NextRequest(XtDisplay(w));
2873     XConfigureWindow(XtDisplay((Widget)w), XtWindow((Widget)w), mask, &values);
2874 
2875     if (wm && !w->shell.override_redirect
2876 	&& mask & (CWX | CWY | CWWidth | CWHeight | CWBorderWidth))
2877     {
2878 	SetWMSizeHints((WMShellWidget)w);
2879     }
2880 
2881     if (w->shell.override_redirect)
2882     {
2883 	return XtGeometryYes;
2884     }
2885 
2886     /* If no non-stacking bits are set, there's no way to tell whether
2887        or not this worked, so assume it did */
2888 
2889     if (!(mask & ~(CWStackMode | CWSibling)))
2890     {
2891 	return XtGeometryYes;
2892     }
2893 
2894     if (wm && ((WMShellWidget)w)->wm.wait_for_wm == FALSE)
2895     {
2896 	/*
2897 	 * From R6:
2898 	 * the window manager is sick so I will do the work and
2899 	 * say no so if a new WM starts up, or the current one recovers
2900 	 * my size requests will be visible
2901 	 *
2902 	 * From MLM:
2903 	 * This is madness, I think.  That means you'll refuse any
2904 	 * resize requests, unless the WM follows the ICCCM, right?
2905 	 */
2906 	return XtGeometryYes;
2907     }
2908 
2909     if (WaitForWM(w, &event, request_num))
2910     {
2911 	/* got an event */
2912 	if (event.type == ConfigureNotify)
2913 	{
2914 
2915 #define NEQ(x, msk) ((mask & msk) && (values.x != event.xconfigure.x))
2916 	    if (NEQ(x, CWX) ||
2917 		NEQ(y, CWY) ||
2918 		NEQ(width, CWWidth) ||
2919 		NEQ(height, CWHeight) ||
2920 		NEQ(border_width, CWBorderWidth))
2921 	    {
2922 #undef NEQ
2923 		XPutBackEvent(XtDisplay(w), &event);
2924 		PutBackGeometry();
2925 		/*
2926 		 * We just potentially re-ordered the event queue
2927 		 * w.r.t. ConfigureNotifies with some trepidation.
2928 		 * But this is probably a Good Thing because we
2929 		 * will know the new true state of the world sooner
2930 		 * this way.
2931 		 */
2932 
2933 		DEBUGOUT(_LtDebug(__FILE__, (Widget)w,
2934 				  "Returning XtGeometryNo because config "
2935 				  "differed\n"));
2936 
2937 		return XtGeometryNo;
2938 	    }
2939 	    else
2940 	    {
2941 		XtWidth(w) = event.xconfigure.width;
2942 		XtHeight(w) = event.xconfigure.height;
2943 		XtBorderWidth(w) = event.xconfigure.border_width;
2944 		if (event.xany.send_event ||	/* ICCCM compliant synth */
2945 		    w->shell.client_specified & _XtShellNotReparented)
2946 		{
2947 
2948 		    XtX(w) = event.xconfigure.x;
2949 		    XtY(w) = event.xconfigure.y;
2950 		    w->shell.client_specified |= _XtShellPositionValid;
2951 		}
2952 		else
2953 		{
2954 		    w->shell.client_specified &= ~_XtShellPositionValid;
2955 		}
2956 
2957 		return XtGeometryYes;
2958 	    }
2959 	}
2960 	else if (!wm)
2961 	{
2962 	    PutBackGeometry();
2963 
2964 	    DEBUGOUT(_LtDebug(__FILE__, (Widget)w,
2965 			      "Returning XtGeometryNo because not "
2966 			      "WMShell\n"));
2967 
2968 	    return XtGeometryNo;
2969 	}
2970 	else
2971 	{
2972 	    XtAppWarningMsg(XtWidgetToApplicationContext((Widget)w),
2973 			    "internalError", "shell", XtCXtToolkitError,
2974 			    "Shell's window manager interaction is broken",
2975 			    (String *)NULL, (Cardinal *)NULL);
2976 	}
2977     }
2978     else if (wm)
2979     {
2980 	/* no event */
2981 	((WMShellWidget)w)->wm.wait_for_wm = FALSE;
2982 	/* timed out; must be broken */
2983     }
2984 #undef PutBackGeometry
2985 
2986     return XtGeometryYes;
2987 }
2988 
2989 #endif /* XtSpecificationRelease < 6 */
2990 
2991 
2992 /*
2993  * if this doesn't exist, the BaseClass geometry wrapper won't work.
2994  */
2995 static XtGeometryResult
geometry_manager(Widget wid,XtWidgetGeometry * request,XtWidgetGeometry * reply)2996 geometry_manager(Widget wid,
2997 		 XtWidgetGeometry *request,
2998 		 XtWidgetGeometry *reply)
2999 {
3000     ShellWidget shell = (ShellWidget)XtParent(wid);
3001     XtWidgetGeometry req;
3002 
3003     DEBUGOUT(_LtDebug2(__FILE__, XtParent(wid), wid, "%s:geometry_manager(%d) - request (%s)\n",
3004     	__FILE__, __LINE__,
3005     	_LtDebugWidgetGeometry2String(request)));
3006 
3007     if ((request->width == 0 && (request->request_mode & CWWidth)) ||
3008 	(request->height == 0 && (request->request_mode & CWHeight)))
3009     {
3010 	DEBUGOUT(_LtDebug(__FILE__, wid,
3011 		          "Returning XtGeometryNo because asked "
3012 		          "for 0 w/h\n"));
3013 
3014 	return XtGeometryNo;
3015     }
3016 
3017     if (shell->shell.allow_shell_resize == False && XtIsRealized(wid) && (request->request_mode & (CWWidth | CWHeight)))
3018     {
3019 	DEBUGOUT(_LtDebug(__FILE__, wid,
3020 		          "Returning XtGeometryNo because "
3021 		          "no shell resize\n"));
3022 
3023 	return XtGeometryNo;
3024     }
3025 
3026     /* rws 12 Dec 1997
3027        mgs bubble help
3028     if (request->request_mode & (CWX | CWY))
3029     {
3030 	DEBUGOUT(_LtDebug(__FILE__, wid,
3031 		          "Returning XtGeometryNo because "
3032 		          "asked for x/y\n"));
3033 
3034 	return XtGeometryNo;
3035     }
3036     */
3037 
3038     /*
3039      * This is a slight change from the Xt implementation.  For some reason,
3040      * even though we were passing in XtCWQueryOnly in the request call below,
3041      * the shell was still getting resized.  For now, if we pass the above
3042      * tests, and are only querying, return Yes.
3043      */
3044     if (request->request_mode & XtCWQueryOnly)
3045     {
3046 	return XtGeometryYes;
3047     }
3048 
3049     req.request_mode = (request->request_mode & XtCWQueryOnly);
3050     if (request->request_mode & CWWidth)
3051     {
3052 	req.width = request->width;
3053 	req.request_mode |= CWWidth;
3054     }
3055     if (request->request_mode & CWHeight)
3056     {
3057 	req.height = request->height;
3058 	req.request_mode |= CWHeight;
3059     }
3060     if (request->request_mode & CWBorderWidth)
3061     {
3062 	req.border_width = request->border_width;
3063 	req.request_mode |= CWBorderWidth;
3064     }
3065     if ((request->request_mode & CWX) && request->x != 0)
3066     {
3067 	req.x = request->x;
3068 	req.request_mode |= CWX;
3069     }
3070     if ((request->request_mode & CWY) && request->y != 0)
3071     {
3072 	req.y = request->y;
3073 	req.request_mode |= CWY;
3074     }
3075 
3076     if (XtMakeGeometryRequest((Widget)shell, &req, NULL) == XtGeometryYes)
3077     {
3078 	if (!(request->request_mode & XtCWQueryOnly))
3079 	{
3080 	    wid->core.width = /*req.width; */ shell->core.width;
3081 	    wid->core.height = /*req.height; */	shell->core.height;
3082 	    if (request->request_mode & CWBorderWidth)
3083 	    {
3084 		wid->core.x = wid->core.y = -request->border_width;
3085 	    }
3086 	}
3087 
3088 	XSync(XtDisplay(wid), False);
3089 
3090 	return XtGeometryYes;
3091     }
3092 
3093    DEBUGOUT(_LtDebug(__FILE__, wid,
3094 		     "Returning XtGeometryNo because "
3095 		     "XtMakeGeometryRequest failed\n"));
3096 
3097     return XtGeometryNo;
3098 }
3099 
3100 
3101 static void
_XmVendorExtInitialize(Widget req,Widget new_w,ArgList args,Cardinal * num_args)3102 _XmVendorExtInitialize(Widget req,
3103 		       Widget new_w,
3104 		       ArgList args,
3105 		       Cardinal *num_args)
3106 {
3107     XmVendorShellExtObject ve = (XmVendorShellExtObject)new_w;
3108     Atom wm_delete_window;
3109 
3110     DEBUGOUT(_LtDebug(__FILE__, new_w, "VendorShellExtInitialize\n"));
3111 
3112     if (VSEP_DefaultFontList(ve) != NULL)
3113     {
3114 	VSEP_DefaultFontList(ve) = XmFontListCopy(VSEP_DefaultFontList(ve));
3115     }
3116 
3117     /* initialize the button font list */
3118     if (VSEP_ButtonFontList(ve) == NULL)
3119     {
3120 	if (VSEP_DefaultFontList(ve)) {
3121 	    VSEP_ButtonFontList(ve) = XmFontListCopy(VSEP_DefaultFontList(ve));
3122 	} else {
3123 	    VSEP_ButtonFontList(ve) =
3124 		_XmGetDefaultFontList(ExtObj_LogicalParent(new_w), XmBUTTON_FONTLIST);
3125 	}
3126     } else {
3127 	VSEP_ButtonFontList(ve) = XmFontListCopy(VSEP_ButtonFontList(ve));
3128     }
3129 
3130     /* initialize the label font list */
3131     if (VSEP_LabelFontList(ve) == NULL) {
3132 	if (VSEP_DefaultFontList(ve)) {
3133 	    VSEP_LabelFontList(ve) = XmFontListCopy(VSEP_DefaultFontList(ve));
3134 	} else {
3135 	    VSEP_LabelFontList(ve) =
3136 		_XmGetDefaultFontList(ExtObj_LogicalParent(new_w), XmLABEL_FONTLIST);
3137 	}
3138     } else {
3139 	VSEP_LabelFontList(ve) = XmFontListCopy(VSEP_LabelFontList(ve));
3140     }
3141 
3142     /* initialize the text font list */
3143     if (VSEP_TextFontList(ve) == NULL) {
3144 	if (VSEP_DefaultFontList(ve)) {
3145 	    VSEP_TextFontList(ve) = XmFontListCopy(VSEP_DefaultFontList(ve));
3146 	} else {
3147 	    VSEP_TextFontList(ve) =
3148 		_XmGetDefaultFontList(ExtObj_LogicalParent(new_w), XmTEXT_FONTLIST);
3149 	}
3150     } else {
3151 	VSEP_TextFontList(ve) = XmFontListCopy(VSEP_TextFontList(ve));
3152     }
3153 
3154     VSEP_MwmHints(ve).flags = 0;
3155 
3156     if (VSEP_MwmMenu(ve) != NULL)
3157     {
3158 	VSEP_MwmMenu(ve) = XtNewString(VSEP_MwmMenu(ve));
3159     }
3160 
3161     if (VSEP_MwmHints(ve).functions != -1)
3162     {
3163 	VSEP_MwmHints(ve).flags |= MWM_HINTS_FUNCTIONS;
3164     }
3165     if (VSEP_MwmHints(ve).decorations != -1)
3166     {
3167 	VSEP_MwmHints(ve).flags |= MWM_HINTS_DECORATIONS;
3168     }
3169     if (VSEP_MwmHints(ve).input_mode != -1)
3170     {
3171 	VSEP_MwmHints(ve).flags |= MWM_HINTS_INPUT_MODE;
3172     }
3173 
3174     VSEP_ImInfo(ve) = NULL;
3175 
3176     VSEP_FocusData(ve) = _XmCreateFocusData();
3177 
3178     wm_delete_window = XmInternAtom(XtDisplay(ExtObj_LogicalParent(new_w)),
3179 				    _XA_WM_DELETE_WINDOW, False);
3180 
3181     _XmInitProtocols(ExtObj_LogicalParent(new_w));
3182 
3183     XmAddWMProtocols(ExtObj_LogicalParent(new_w), &wm_delete_window, 1);
3184     XmSetWMProtocolHooks(ExtObj_LogicalParent(new_w), wm_delete_window,
3185 			 NULL, NULL,
3186 			 VSEPC_DeleteWindowHandler(new_w), (XtPointer)new_w);
3187 }
3188 
3189 static Boolean
_XmVendorExtSetValues(Widget cw,Widget rw,Widget nw,ArgList args,Cardinal * nargs)3190 _XmVendorExtSetValues(Widget cw, Widget rw, Widget nw, ArgList args, Cardinal *nargs)
3191 {
3192     Atom at;
3193     long prop32[5];
3194     XmVendorShellExtObject o= (XmVendorShellExtObject)nw;
3195 
3196     DEBUGOUT(_LtDebug(__FILE__, nw,
3197 		      "VendorShellExtSetValues, args:%d\n",
3198 		      *nargs));
3199 
3200     if (VSEP_ButtonFontList(nw) != VSEP_ButtonFontList(cw))
3201     {
3202 	XmFontListFree(VSEP_ButtonFontList(cw));
3203 	VSEP_ButtonFontList(nw) = XmFontListCopy(VSEP_ButtonFontList(nw));
3204     }
3205     if (VSEP_LabelFontList(nw) != VSEP_LabelFontList(cw))
3206     {
3207 	XmFontListFree(VSEP_LabelFontList(cw));
3208 	VSEP_LabelFontList(nw) = XmFontListCopy(VSEP_LabelFontList(nw));
3209     }
3210     if (VSEP_TextFontList(nw) != VSEP_TextFontList(cw))
3211     {
3212 	XmFontListFree(VSEP_TextFontList(cw));
3213 	VSEP_TextFontList(nw) = XmFontListCopy(VSEP_TextFontList(nw));
3214     }
3215 
3216     VSEP_MwmHints(nw).flags = 0;
3217 
3218     if (VSEP_MwmHints(nw).functions != -1)
3219     {
3220 	VSEP_MwmHints(nw).flags |= MWM_HINTS_FUNCTIONS;
3221     }
3222     if (VSEP_MwmHints(nw).decorations != -1)
3223     {
3224 	VSEP_MwmHints(nw).flags |= MWM_HINTS_DECORATIONS;
3225     }
3226     if (VSEP_MwmHints(nw).input_mode != -1)
3227     {
3228 	VSEP_MwmHints(nw).flags |= MWM_HINTS_INPUT_MODE;
3229     }
3230 
3231     if (XtIsRealized(ExtObj_LogicalParent(nw)) &&
3232 	memcmp(&VSEP_MwmHints(nw), &VSEP_MwmHints(cw), sizeof(MwmHints)) != 0)
3233     {
3234 	at = XmInternAtom(XtDisplay(nw), _XA_MWM_HINTS, False);
3235 	/* note the 32 format = long on client side */
3236 	prop32[0]=VSEP_MwmHints(nw).flags;
3237 	prop32[1]=VSEP_MwmHints(nw).functions;
3238 	prop32[2]=VSEP_MwmHints(nw).decorations;
3239 	prop32[3]=VSEP_MwmHints(nw).input_mode;
3240 	prop32[4]=VSEP_MwmHints(nw).status;
3241 	XChangeProperty(XtDisplay(nw), XtWindow(nw), at, at, 32,
3242 			PropModeReplace,
3243 			(unsigned char *)prop32,
3244 			PROP_MOTIF_WM_HINTS_ELEMENTS);
3245     }
3246 
3247 /* rws 13 Sep 2000
3248    We have to do this whether we are realized or not.
3249    test/Xm/mwm/test5 -xrm "*autoExit: True" show this.
3250    It does a SetValues on mwmMenu with a static string, if we do not
3251    copy this string we end up segfaulting when things get destroyed!!!
3252  */
3253     if (/*XtIsRealized(ExtObj_LogicalParent(nw)) &&*/
3254 	((!VSEP_MwmMenu(nw) && VSEP_MwmMenu(cw)) ||
3255 	 (VSEP_MwmMenu(nw) && !VSEP_MwmMenu(cw)) ||
3256 	 (VSEP_MwmMenu(nw) && VSEP_MwmMenu(cw) &&
3257 	  strcmp(VSEP_MwmMenu(nw), VSEP_MwmMenu(cw)) != 0)))
3258     {
3259 	if (VSEP_MwmMenu(cw))
3260 	{
3261 	    XtFree(VSEP_MwmMenu(cw));
3262 	}
3263 
3264 	if (VSEP_MwmMenu(nw))
3265 	{
3266 	    VSEP_MwmMenu(nw) = XtNewString(VSEP_MwmMenu(nw));
3267 	}
3268 
3269 	if (XtIsRealized(ExtObj_LogicalParent(nw)) && VSEP_MwmMenu(nw) != NULL)
3270 	{
3271 	    /* Only do this if we have a reason for it.
3272 	     * The Motif 2.1 mwm seems to crash without this. */
3273 	    at = XmInternAtom(XtDisplay(nw), _XA_MWM_MENU, False);
3274 	    /* note the 8 format */
3275 	    XChangeProperty(XtDisplay(nw), XtWindow(nw), at, at, 8,
3276 		PropModeReplace,
3277 		(unsigned char *)VSEP_MwmMenu(nw), strlen(VSEP_MwmMenu(nw)));
3278 	}
3279     }
3280 
3281 	return False;
3282 }
3283 
3284 
3285 extern void
_XmVendorExtRealize(Widget w,XtPointer closure,XtPointer call_data)3286 _XmVendorExtRealize(Widget w, XtPointer closure, XtPointer call_data)
3287 {
3288     Atom at;
3289     Widget par;
3290     Cardinal i;
3291     long prop32[5];
3292 
3293     DEBUGOUT(_LtDebug(__FILE__, w, "XmVendorExtRealize\n"));
3294 
3295 	_XmPickupUnspecifiedPixmaps(XtDisplay(w));
3296 
3297     par = ExtObj_LogicalParent(w);
3298 
3299     if (!XmIsDisplay(par))
3300     {
3301 	_XmInstallProtocols(par);
3302     }
3303 
3304     DEBUGOUT(_LtDebug(__FILE__, w,
3305 		 "_XmVendorExtRealize[flags %d, functions %d, decorations %d, "
3306 		      "input_mode %d, status %d\n",
3307 		      VSEP_MwmHints(w).flags,
3308 		      VSEP_MwmHints(w).functions,
3309 		      VSEP_MwmHints(w).decorations,
3310 		      VSEP_MwmHints(w).input_mode,
3311 		      VSEP_MwmHints(w).status));
3312 
3313     /*
3314      * Note all the fields must be in the right order here !
3315      * flags, functions, decorations, input_mode, status
3316      * The XChangeProperty will set them all in one go.
3317      * note the 32 format for HINTS, the 8 format for MENU
3318      */
3319     /* format 32 = long on client side */
3320     prop32[0]=VSEP_MwmHints(w).flags;
3321     prop32[1]=VSEP_MwmHints(w).functions;
3322     prop32[2]=VSEP_MwmHints(w).decorations;
3323     prop32[3]=VSEP_MwmHints(w).input_mode;
3324     prop32[4]=VSEP_MwmHints(w).status;
3325     at = XmInternAtom(XtDisplay(par), _XA_MWM_HINTS, False);
3326     XChangeProperty(XtDisplay(par), XtWindow(par), at, at, 32,
3327 		    PropModeReplace,
3328 		    (unsigned char *)prop32,
3329 		    PROP_MOTIF_WM_HINTS_ELEMENTS);
3330 
3331     if (VSEP_MwmMenu(w)) {
3332 	/* Only do this if we have a reason for it.
3333 	 * The Motif 2.1 mwm seems to crash without this. */
3334 	at = XmInternAtom(XtDisplay(par), _XA_MWM_MENU, False);
3335 	XChangeProperty(XtDisplay(par), XtWindow(par), at, at, 8,
3336 		    PropModeReplace,
3337 		    (unsigned char *)VSEP_MwmMenu(w), strlen(VSEP_MwmMenu(w)));
3338     }
3339 
3340     for (i = 0; i < par->core.num_popups; i++)
3341     {
3342 	if (XtIsTransientShell(par->core.popup_list[i]))
3343 	{
3344 	    Arg args[2];
3345 	    int argc = 0;
3346 
3347 	    XtSetArg(args[argc], XmNtransientFor, par);
3348 	    argc++;
3349 	    XtSetArg(args[argc], XmNwindowGroup, XtWindow(par));
3350 	    argc++;
3351 	    XtSetValues(par->core.popup_list[i], args, argc);
3352 	    if (XtIsRealized(par->core.popup_list[i]))
3353 	    {
3354 		XSetTransientForHint(XtDisplay(par->core.popup_list[i]),
3355 				     XtWindow(par->core.popup_list[i]),
3356 				     XtWindow(par));
3357 	    }
3358 	}
3359     }
3360 
3361     /*
3362      * In case this is something like a top level shell and not a real
3363      * pop up shell we have to do a explicit grab here or we do lose the
3364      * ability to get user input whenever a non-modal dialog shows up.
3365      */
3366     if (!LTIsARealPopupShell(par))
3367     {
3368 	LTAddGrab(NULL, False, False,
3369 		  (XmVendorShellExtObject)w, (XmVendorShellExtObject)w);
3370     }
3371 }
3372 
3373 
3374 static Cardinal
get_sec_res_data(WidgetClass wc,XmSecondaryResourceData ** data)3375 get_sec_res_data(WidgetClass wc, XmSecondaryResourceData **data)
3376 {
3377     /* FIX ME */
3378 
3379     return _XmSecondaryResourceData(&_XmVendorSCoreClassExtRec,
3380 				    data, NULL, NULL, NULL, NULL);
3381 }
3382 
3383 
3384 extern Display *
_XmGetDefaultDisplay(void)3385 _XmGetDefaultDisplay(void)
3386 {
3387     return default_display;
3388 }
3389 
3390 
3391 extern unsigned char
_XmGetAudibleWarning(Widget w)3392 _XmGetAudibleWarning(Widget w)
3393 {
3394     XmWidgetExtData data;
3395     DEBUGOUT(_LtDebug(__FILE__, w, "_XmGetAudibleWarning\n"));
3396     if ( XmIsVendorShell (w) && ( data = _XmGetWidgetExtData(w, XmSHELL_EXTENSION ) ) )
3397 	{
3398 	XmVendorShellExtObject vSE = (XmVendorShellExtObject)data -> widget ;
3399 	unsigned char audibleWarning = vSE -> vendor.audible_warning ;
3400 	return audibleWarning ;
3401 	}
3402 
3403     _XmWarning(w, "_XmGetAudibleWarning: widget has invalid class");
3404     return False;
3405 }
3406 
3407 
3408 extern char *
_XmGetIconPixmapName(void)3409 _XmGetIconPixmapName(void)
3410 {
3411     return NULL;
3412 }
3413 
3414 
3415 extern void
_XmClearIconPixmapName(void)3416 _XmClearIconPixmapName(void)
3417 {
3418 }
3419 
3420 
3421 /* To be used elsewhere ... */
3422 extern Widget
_LtFindVendorExt(Widget w)3423 _LtFindVendorExt(Widget w)
3424 {
3425     Widget p;
3426     XmWidgetExtData data;
3427 
3428     if (w == (Widget)0)
3429     {
3430 	return NULL;
3431     }
3432 
3433     for (p = w;
3434 	 !XtIsSubclass(p, vendorShellWidgetClass) && XtParent(p);
3435 	 p = XtParent(p))
3436     {
3437     }
3438 
3439     data = _XmGetWidgetExtData(p, XmSHELL_EXTENSION);
3440     if (data)
3441     {
3442 	return data->widget;
3443     }
3444     else
3445     {
3446 	return NULL;
3447     }
3448 }
3449 
3450 
3451 /*
3452   From: Martin Simmons:
3453     Perhaps LessTif can guard against this common linking problem?
3454     E.g. the following function will check the VendorShell for consistency:
3455 
3456      returns     True if successful, i.e. everything's fine
3457      returns     False if no widget was supplied as an argument
3458      _XmError()s if linkage is/was wrong
3459  */
3460 extern Boolean
_LtCheckClassOfVendorShell(Widget w)3461 _LtCheckClassOfVendorShell(Widget w)
3462 {
3463     WidgetClass widget_class;
3464 
3465     if (!w)
3466        return False;
3467     for (widget_class = XtClass(w); widget_class != NULL; widget_class = widget_class->core_class.superclass)
3468     {
3469         if (0 == strcmp(widget_class->core_class.class_name, "VendorShell")) {
3470             if (widget_class->core_class.extension == (XtPointer)&_XmVendorSCoreClassExtRec)
3471                 return True;
3472             else
3473                 _XmError(w, "Application not linked correctly: try putting -lXm before -lXt.");
3474         }
3475     }
3476 
3477     return False;
3478 }
3479 
3480 
3481 /*
3482    This corrects for the (shared) library loading mechanism in OS/2 and Windows
3483    which differs from those on many standard Unix systems.
3484    The routine should be called before any other function,
3485    actually done by the _DLL_InitTerm-function in OS/2 and DllMain in Windows.
3486    On un*x/ELF systems the problem addressed here seems to be avoided
3487    by specifying the libraries in correct, canonical order on the linker
3488    command line.
3489    amai (20010112): I once decided to make it static, but this was an error:
3490    to call it from a static libXm one may need this symbol.
3491  */
3492 #if defined(__EMX__) || defined(__CYGWIN__)
3493 extern void
_LtXmFixupVendorShell(void)3494 _LtXmFixupVendorShell(void)
3495 {
3496 
3497     transientShellWidgetClass->core_class.superclass =
3498        (WidgetClass)&vendorShellClassRec;
3499     topLevelShellWidgetClass->core_class.superclass =
3500        (WidgetClass)&vendorShellClassRec;
3501 }
3502 
3503 
3504 #ifdef __EMX__
3505 unsigned long
_DLL_InitTerm(unsigned long mod_handle,unsigned long flag)3506 _DLL_InitTerm(unsigned long mod_handle, unsigned long flag)
3507 {
3508     if (flag == 0UL)  /* initialize DLL */
3509     {
3510 	    _LtXmFixupVendorShell();
3511 	    return 1; /* success */
3512     }
3513     else     /* terminate DLL */
3514     {
3515         return 1; /* success */
3516     }
3517 }
3518 #endif
3519 
3520 #ifdef __CYGWIN__
3521 int __stdcall
DllMain(unsigned long mod_handle,unsigned long flag,void * routine)3522 DllMain(unsigned long mod_handle, unsigned long flag, void *routine)
3523 {
3524     switch (flag)
3525     {
3526         case 1: /* DLL_PROCESS_ATTACH - process attach */
3527             _LtXmFixupVendorShell();
3528             break;
3529         case 0: /* DLL_PROCESS_DETACH - process detach */
3530             break;
3531     }
3532     return 1;
3533 }
3534 #endif
3535 
3536 #endif /* __EMX__ || __CYGWIN__ */
3537 
GetRenderTable(Widget w,XtEnum renderTableType)3538 static XmRenderTable GetRenderTable(Widget w, XtEnum renderTableType)
3539 {
3540 	XmWidgetExtData data;
3541 
3542 	if (XmIsVendorShell(w) && (data = _XmGetWidgetExtData(w, XmSHELL_EXTENSION))) {
3543 		XmVendorShellExtObject ve = (XmVendorShellExtObject)data->widget ;
3544 
3545 		switch(renderTableType) {
3546 		case XmLABEL_RENDER_TABLE:
3547 			return ve->vendor.label_font_list;
3548 		case XmBUTTON_RENDER_TABLE:
3549 			return ve->vendor.button_font_list;
3550 		case XmTEXT_RENDER_TABLE:
3551 			return ve->vendor.text_font_list;
3552 		}
3553 	}
3554 	return NULL;
3555 }
3556