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