Bug Summary

File:SimpleMenu.c
Location:line 1556, column 2
Description:Value stored to 'warp' is never read

Annotated Source Code

1/*
2Copyright 1989, 1994, 1998 The Open Group
3
4Permission to use, copy, modify, distribute, and sell this software and its
5documentation for any purpose is hereby granted without fee, provided that
6the above copyright notice appear in all copies and that both that
7copyright notice and this permission notice appear in supporting
8documentation.
9
10The above copyright notice and this permission notice shall be included in
11all copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
17AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20Except as contained in this notice, the name of The Open Group shall not be
21used in advertising or otherwise to promote the sale, use or other dealings
22in this Software without prior written authorization from The Open Group.
23 */
24
25/*
26 * SimpleMenu.c - Source code file for SimpleMenu widget.
27 *
28 * Date: April 3, 1989
29 *
30 * By: Chris D. Peterson
31 * MIT X Consortium
32 * kit@expo.lcs.mit.edu
33 */
34
35#ifdef HAVE_CONFIG_H1
36#include <config.h>
37#endif
38#include <stdio.h>
39#include <X11/IntrinsicP.h>
40#include <X11/StringDefs.h>
41#include <X11/Xmu/Initer.h>
42#include <X11/Xaw/Cardinals.h>
43#include <X11/Xaw/SimpleMenP.h>
44#include <X11/Xaw/SmeBSBP.h>
45#include <X11/Xaw/XawInit.h>
46#include "Private.h"
47
48#define streq(a, b)(strcmp((a), (b)) == 0) (strcmp((a), (b)) == 0)
49
50#define ForAllChildren(smw, childP)for ((childP) = (SmeObject *)(smw)->composite.children; (childP
) < (SmeObject *)((smw)->composite.children + (smw)->
composite.num_children); (childP)++)
\
51for ((childP) = (SmeObject *)(smw)->composite.children; \
52 (childP) < (SmeObject *)((smw)->composite.children \
53 + (smw)->composite.num_children); \
54 (childP)++)
55
56#ifndef OLDXAW1
57#define SMW_UNMAPPING 0x01
58#define SMW_POPLEFT 0x02
59#endif
60
61/*
62 * Class Methods
63 */
64static void XawSimpleMenuChangeManaged(Widget);
65static void XawSimpleMenuClassInitialize(void);
66static void XawSimpleMenuClassPartInitialize(WidgetClass);
67static XtGeometryResult XawSimpleMenuGeometryManager(Widget, XtWidgetGeometry*,
68 XtWidgetGeometry*);
69static void XawSimpleMenuInitialize(Widget, Widget, ArgList, Cardinal*);
70static void XawSimpleMenuRealize(Widget, XtValueMask*, XSetWindowAttributes*);
71static void XawSimpleMenuRedisplay(Widget, XEvent*, Region);
72static void XawSimpleMenuResize(Widget);
73static Boolean XawSimpleMenuSetValues(Widget, Widget, Widget,
74 ArgList, Cardinal*);
75static Boolean XawSimpleMenuSetValuesHook(Widget, ArgList, Cardinal*);
76#ifndef OLDXAW1
77static void PopupSubMenu(SimpleMenuWidget);
78static void PopdownSubMenu(SimpleMenuWidget);
79static void PopupCB(Widget, XtPointer, XtPointer);
80#endif
81
82/*
83 * Prototypes
84 */
85static void AddPositionAction(XtAppContext, XPointer);
86static void CalculateNewSize(Widget, Dimension*, Dimension*);
87static void ChangeCursorOnGrab(Widget, XtPointer, XtPointer);
88static void CreateLabel(Widget);
89static SmeObject DoGetEventEntry(Widget, int, int);
90static Widget FindMenu(Widget, String);
91static SmeObject GetEventEntry(Widget, XEvent*);
92static void Layout(Widget, Dimension*, Dimension*);
93static void MakeResizeRequest(Widget);
94static void MakeSetValuesRequest(Widget, unsigned int, unsigned int);
95static void MoveMenu(Widget, int, int);
96static void PositionMenu(Widget, XPoint*);
97
98/*
99 * Actions
100 */
101static void Highlight(Widget, XEvent*, String*, Cardinal*);
102static void Notify(Widget, XEvent*, String*, Cardinal*);
103#ifndef OLDXAW1
104static void Popdown(Widget, XEvent*, String*, Cardinal*);
105#endif
106static void PositionMenuAction(Widget, XEvent*, String*, Cardinal*);
107static void Unhighlight(Widget, XEvent*, String*, Cardinal*);
108
109/*
110 * Initialization
111 */
112#define offset(field) XtOffsetOf(SimpleMenuRec, simple_menu.field)__builtin_offsetof(SimpleMenuRec, simple_menu.field)
113
114static XtResource resources[] = {
115 /* label */
116 {
117 XtNlabel((char*)&XtStrings[429]),
118 XtCLabel((char*)&XtStrings[1151]),
119 XtRString((char*)&XtStrings[1797]),
120 sizeof(String),
121 offset(label_string),
122 XtRString((char*)&XtStrings[1797]),
123 NULL((void*)0)
124 },
125 {
126 XtNlabelClass"labelClass",
127 XtCLabelClass"LabelClass",
128 XtRPointer((char*)&XtStrings[1767]),
129 sizeof(WidgetClass),
130 offset(label_class),
131 XtRImmediate((char*)&XtStrings[1695]),
132 NULL((void*)0)
133 },
134
135 /* layout */
136 {
137 XtNrowHeight"rowHeight",
138 XtCRowHeight"RowHeight",
139 XtRDimension((char*)&XtStrings[1618]),
140 sizeof(Dimension),
141 offset(row_height),
142 XtRImmediate((char*)&XtStrings[1695]),
143 (XtPointer)0
144 },
145 {
146 XtNtopMargin"topMargin",
147 XtCVerticalMargins"VerticalMargins",
148 XtRDimension((char*)&XtStrings[1618]),
149 sizeof(Dimension),
150 offset(top_margin),
151 XtRImmediate((char*)&XtStrings[1695]),
152 (XtPointer)0
153 },
154 {
155 XtNbottomMargin"bottomMargin",
156 XtCVerticalMargins"VerticalMargins",
157 XtRDimension((char*)&XtStrings[1618]),
158 sizeof(Dimension),
159 offset(bottom_margin),
160 XtRImmediate((char*)&XtStrings[1695]),
161 (XtPointer)0
162 },
163#ifndef OLDXAW1
164 {
165 XtNleftMargin"leftMargin",
166 XtCHorizontalMargins"HorizontalMargins",
167 XtRDimension((char*)&XtStrings[1618]),
168 sizeof(Dimension),
169 offset(left_margin),
170 XtRImmediate((char*)&XtStrings[1695]),
171 (XtPointer)0
172 },
173 {
174 XtNrightMargin"rightMargin",
175 XtCHorizontalMargins"HorizontalMargins",
176 XtRDimension((char*)&XtStrings[1618]),
177 sizeof(Dimension),
178 offset(right_margin),
179 XtRImmediate((char*)&XtStrings[1695]),
180 (XtPointer)0
181 },
182#endif
183
184 /* misc */
185 {
186 XtNallowShellResize((char*)&XtShellStrings[280]),
187 XtCAllowShellResize((char*)&XtShellStrings[297]),
188 XtRBoolean((char*)&XtStrings[1561]),
189 sizeof(Boolean),
190 XtOffsetOf(SimpleMenuRec, shell.allow_shell_resize)__builtin_offsetof(SimpleMenuRec, shell.allow_shell_resize),
191 XtRImmediate((char*)&XtStrings[1695]),
192 (XtPointer)True1
193 },
194 {
195 XtNcursor"cursor",
196 XtCCursor((char*)&XtStrings[976]),
197 XtRCursor((char*)&XtStrings[1611]),
198 sizeof(Cursor),
199 offset(cursor),
200 XtRImmediate((char*)&XtStrings[1695]),
201 (XtPointer)None0L
202 },
203 {
204 XtNmenuOnScreen"menuOnScreen",
205 XtCMenuOnScreen"MenuOnScreen",
206 XtRBoolean((char*)&XtStrings[1561]),
207 sizeof(Boolean),
208 offset(menu_on_screen),
209 XtRImmediate((char*)&XtStrings[1695]),
210 (XtPointer)True1
211 },
212 {
213 XtNpopupOnEntry"popupOnEntry",
214 XtCPopupOnEntry"PopupOnEntry",
215 XtRWidget((char*)&XtStrings[1865]),
216 sizeof(Widget),
217 offset(popup_entry),
218 XtRWidget((char*)&XtStrings[1865]),
219 NULL((void*)0)
220 },
221 {
222 XtNbackingStore"backingStore",
223 XtCBackingStore"BackingStore",
224 XtRBackingStore"BackingStore",
225 sizeof(int),
226 offset(backing_store),
227 XtRImmediate((char*)&XtStrings[1695]),
228 (XtPointer)(Always2 + WhenMapped1 + NotUseful0)
229 },
230#ifndef OLDXAW1
231 {
232 XawNdisplayList,
233 XawCDisplayList,
234 XawRDisplayList,
235 sizeof(XawDisplayList*),
236 offset(display_list),
237 XtRImmediate((char*)&XtStrings[1695]),
238 NULL((void*)0)
239 },
240#endif
241};
242#undef offset
243
244static char defaultTranslations[] =
245"<Enter>:" "highlight()\n"
246"<Leave>:" "unhighlight()\n"
247"<BtnMotion>:" "highlight()\n"
248#ifndef OLDXAW1
249"<BtnUp>:" "popdown() notify() unhighlight()\n"
250#else
251"<BtnUp>:" "MenuPopdown() notify() unhighlight()\n"
252#endif
253;
254
255static XtActionsRec actionsList[] =
256{
257 {"notify", Notify},
258 {"highlight", Highlight},
259 {"unhighlight", Unhighlight},
260#ifndef OLDXAW1
261 {"popdown", Popdown},
262 {"set-values", XawSetValuesAction},
263 {"get-values", XawGetValuesAction},
264 {"declare", XawDeclareAction},
265 {"call-proc", XawCallProcAction},
266#endif
267};
268
269static CompositeClassExtensionRec extension_rec = {
270 NULL((void*)0), /* next_extension */
271 NULLQUARK((XrmQuark) 0), /* record_type */
272 XtCompositeExtensionVersion2L, /* version */
273 sizeof(CompositeClassExtensionRec), /* record_size */
274 True1, /* accepts_objects */
275};
276
277#define Superclass(&overrideShellClassRec) (&overrideShellClassRec)
278SimpleMenuClassRec simpleMenuClassRec = {
279 /* core */
280 {
281 (WidgetClass)Superclass(&overrideShellClassRec), /* superclass */
282 "SimpleMenu", /* class_name */
283 sizeof(SimpleMenuRec), /* size */
284 XawSimpleMenuClassInitialize, /* class_initialize */
285 XawSimpleMenuClassPartInitialize, /* class_part_initialize */
286 False0, /* class_inited */
287 XawSimpleMenuInitialize, /* initialize */
288 NULL((void*)0), /* initialize_hook */
289 XawSimpleMenuRealize, /* realize */
290 actionsList, /* actions */
291 XtNumber(actionsList)((Cardinal) (sizeof(actionsList) / sizeof(actionsList[0]))), /* num_actions */
292 resources, /* resources */
293 XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))), /* num_resources */
294 NULLQUARK((XrmQuark) 0), /* xrm_class */
295 True1, /* compress_motion */
296 True1, /* compress_exposure */
297 True1, /* compress_enterleave */
298 False0, /* visible_interest */
299 NULL((void*)0), /* destroy */
300 XawSimpleMenuResize, /* resize */
301 XawSimpleMenuRedisplay, /* expose */
302 XawSimpleMenuSetValues, /* set_values */
303 XawSimpleMenuSetValuesHook, /* set_values_hook */
304 XtInheritSetValuesAlmost((XtAlmostProc) _XtInherit), /* set_values_almost */
305 NULL((void*)0), /* get_values_hook */
306 NULL((void*)0), /* accept_focus */
307 XtVersion(11 * 1000 + 6), /* intrinsics version */
308 NULL((void*)0), /* callback offsets */
309 defaultTranslations, /* tm_table */
310 NULL((void*)0), /* query_geometry */
311 NULL((void*)0), /* display_accelerator */
312 NULL((void*)0), /* extension */
313 },
314 /* composite */
315 {
316 XawSimpleMenuGeometryManager, /* geometry_manager */
317 XawSimpleMenuChangeManaged, /* change_managed */
318 XtInheritInsertChild((XtWidgetProc) _XtInherit), /* insert_child */
319 XtInheritDeleteChild((XtWidgetProc) _XtInherit), /* delete_child */
320 NULL((void*)0), /* extension */
321 },
322 /* shell */
323 {
324 NULL((void*)0), /* extension */
325 },
326 /* override */
327 {
328 NULL((void*)0), /* extension */
329 },
330 /* simple_menu */
331 {
332 NULL((void*)0), /* extension */
333 },
334};
335
336WidgetClass simpleMenuWidgetClass = (WidgetClass)&simpleMenuClassRec;
337
338/*
339 * Implementation
340 */
341/*
342 * Function:
343 * XawSimpleMenuClassInitialize
344 *
345 * Description:
346 * Class Initialize routine, called only once.
347 */
348static void
349XawSimpleMenuClassInitialize(void)
350{
351 XawInitializeWidgetSet();
352 XtAddConverter(XtRString((char*)&XtStrings[1797]), XtRBackingStore"BackingStore", XmuCvtStringToBackingStore,
353 NULL((void*)0), 0);
354 XtSetTypeConverter(XtRBackingStore"BackingStore", XtRString((char*)&XtStrings[1797]), XmuCvtBackingStoreToString,
355 NULL((void*)0), 0, XtCacheNone0x001, NULL((void*)0));
356 XmuAddInitializer(AddPositionAction, NULL((void*)0));
357}
358
359/*
360 * Function:
361 * XawSimpleMenuClassPartInitialize
362 * Arguments: wc - the widget class of the subclass.
363 *
364 * Description:
365 * Class Part Initialize routine, called for every subclass. Makes
366 * sure that the subclasses pick up the extension record.
367 */
368static void
369XawSimpleMenuClassPartInitialize(WidgetClass wc)
370{
371 SimpleMenuWidgetClass smwc = (SimpleMenuWidgetClass)wc;
372
373 /*
374 * Make sure that our subclass gets the extension rec too
375 */
376 extension_rec.next_extension = smwc->composite_class.extension;
377 smwc->composite_class.extension = (XtPointer) &extension_rec;
378}
379
380/*
381 * Function:
382 * XawSimpleMenuInitialize
383 *
384 * Parameters:
385 * request - widget requested by the argument list
386 * cnew - new widget with both resource and non resource values
387 *
388 * Description:
389 * Initializes the simple menu widget.
390 */
391/*ARGSUSED*/
392static void
393XawSimpleMenuInitialize(Widget request, Widget cnew,
394 ArgList args, Cardinal *num_args)
395{
396 SimpleMenuWidget smw = (SimpleMenuWidget)cnew;
397 Dimension width, height;
398
399 XmuCallInitializers(XtWidgetToApplicationContext(cnew));
400
401 if (smw->simple_menu.label_class == NULL((void*)0))
402 smw->simple_menu.label_class = smeBSBObjectClass;
403
404 smw->simple_menu.label = NULL((void*)0);
405 smw->simple_menu.entry_set = NULL((void*)0);
406 smw->simple_menu.recursive_set_values = False0;
407#ifndef OLDXAW1
408 smw->simple_menu.sub_menu = NULL((void*)0);
409 smw->simple_menu.state = 0;
410
411 XtAddCallback(cnew, XtNpopupCallback((char*)&XtStrings[534]), PopupCB, NULL((void*)0));
412#endif
413
414 if (smw->simple_menu.label_string != NULL((void*)0))
415 CreateLabel(cnew);
416
417 width = height = 0;
418 CalculateNewSize(cnew, &width, &height);
419
420 smw->simple_menu.menu_width = True1;
421
422 if (XtWidth(smw)(((RectObj)smw)->rectangle.width) == 0) {
423 smw->simple_menu.menu_width = False0;
424 XtWidth(smw)(((RectObj)smw)->rectangle.width) = width;
425 }
426
427 smw->simple_menu.menu_height = True1;
428
429 if (XtHeight(smw)(((RectObj)smw)->rectangle.height) == 0) {
430 smw->simple_menu.menu_height = False0;
431 XtHeight(smw)(((RectObj)smw)->rectangle.height) = height;
432 }
433
434 /*
435 * Add a popup_callback routine for changing the cursor
436 */
437 XtAddCallback(cnew, XtNpopupCallback((char*)&XtStrings[534]), ChangeCursorOnGrab, NULL((void*)0));
438}
439
440/*
441 * Function:
442 * XawSimpleMenuRedisplay
443 *
444 * Parameters:
445 * w - simple menu widget
446 * event - X event that caused this redisplay
447 * region - region the needs to be repainted
448 *
449 * Description:
450 * Redisplays the contents of the widget.
451 */
452/*ARGSUSED*/
453static void
454XawSimpleMenuRedisplay(Widget w, XEvent *event, Region region)
455{
456 SimpleMenuWidget smw = (SimpleMenuWidget)w;
457 SmeObject *entry;
458 SmeObjectClass cclass;
459
460 if (region == NULL((void*)0))
461 XClearWindow(XtDisplay(w)(((w)->core.screen)->display), XtWindow(w)((w)->core.window));
462
463#ifndef OLDXAW1
464 if (smw->simple_menu.display_list)
465 XawRunDisplayList(w, smw->simple_menu.display_list, event, region);
466#endif
467
468 /*
469 * Check and Paint each of the entries - including the label
470 */
471 ForAllChildren(smw, entry)for ((entry) = (SmeObject *)(smw)->composite.children; (entry
) < (SmeObject *)((smw)->composite.children + (smw)->
composite.num_children); (entry)++)
{
472 if (!XtIsManaged((Widget)*entry))
473 continue;
474
475 if (region != NULL((void*)0))
476 switch(XRectInRegion(region, XtX(*entry)(((RectObj)*entry)->rectangle.x),XtY(*entry)(((RectObj)*entry)->rectangle.y),
477 XtWidth(*entry)(((RectObj)*entry)->rectangle.width), XtHeight(*entry)(((RectObj)*entry)->rectangle.height))) {
478 case RectangleIn1:
479 case RectanglePart2:
480 break;
481 default:
482 continue;
483 }
484
485 cclass = (SmeObjectClass)(*entry)->object.widget_class;
486
487 if (cclass->rect_class.expose != NULL((void*)0))
488 (cclass->rect_class.expose)((Widget)*entry, NULL((void*)0), NULL((void*)0));
489 }
490}
491
492/*
493 * Function:
494 * XawSimpleMenuRealize
495 *
496 * Parameters:
497 * w - simple menu widget
498 * mask - value mask for the window to create
499 * attrs - attributes for the window to create
500 *
501 * Description:
502 * Realizes the widget.
503 */
504static void
505XawSimpleMenuRealize(Widget w, XtValueMask *mask, XSetWindowAttributes *attrs)
506{
507 SimpleMenuWidget smw = (SimpleMenuWidget)w;
508#ifndef OLDXAW1
509 XawPixmap *pixmap;
510#endif
511
512 attrs->cursor = smw->simple_menu.cursor;
513 *mask |= CWCursor(1L<<14);
514 if (smw->simple_menu.backing_store == Always2 ||
515 smw->simple_menu.backing_store == NotUseful0 ||
516 smw->simple_menu.backing_store == WhenMapped1) {
517 *mask |= CWBackingStore(1L<<6);
518 attrs->backing_store = smw->simple_menu.backing_store;
519 }
520 else
521 *mask &= ~CWBackingStore(1L<<6);
522
523 (*Superclass(&overrideShellClassRec)->core_class.realize)(w, mask, attrs);
524
525#ifndef OLDXAW1
526 if (w->core.background_pixmap > XtUnspecifiedPixmap((Pixmap)2)) {
527 pixmap = XawPixmapFromXPixmap(w->core.background_pixmap, XtScreen(w)((w)->core.screen),
528 w->core.colormap, w->core.depth);
529 if (pixmap && pixmap->mask)
530 XawReshapeWidget(w, pixmap);
531 }
532#endif
533}
534
535/*
536 * Function:
537 * XawSimpleMenuResize
538 *
539 * Parameters:
540 * w - simple menu widget
541 *
542 * Description:
543 * Handle the menu being resized.
544 */
545static void
546XawSimpleMenuResize(Widget w)
547{
548 if (!XtIsRealized(w)(XtWindowOfObject(w) != 0L))
549 return;
550
551 Layout(w, NULL((void*)0), NULL((void*)0));
552
553 XawSimpleMenuRedisplay(w, NULL((void*)0), NULL((void*)0));
554}
555
556/*
557 * Function:
558 * XawSimpleMenuSetValues
559 *
560 * Parameters:
561 * current - current state of the widget
562 * request - what was requested
563 * cnew - what the widget will become
564 *
565 * Description:
566 * Relayout the menu when one of the resources is changed.
567 */
568/*ARGSUSED*/
569static Boolean
570XawSimpleMenuSetValues(Widget current, Widget request, Widget cnew,
571 ArgList args, Cardinal *num_args)
572{
573 SimpleMenuWidget smw_old = (SimpleMenuWidget)current;
574 SimpleMenuWidget smw_new = (SimpleMenuWidget)cnew;
575 Boolean ret_val = False0, layout = False0;
576
577 if (!XtIsRealized(current)(XtWindowOfObject(current) != 0L))
578 return (False0);
579
580 if (!smw_new->simple_menu.recursive_set_values) {
581 if (XtWidth(smw_new)(((RectObj)smw_new)->rectangle.width) != XtWidth(smw_old)(((RectObj)smw_old)->rectangle.width)) {
582 smw_new->simple_menu.menu_width = XtWidth(smw_new)(((RectObj)smw_new)->rectangle.width) != 0;
583 layout = True1;
584 }
585 if (XtHeight(smw_new)(((RectObj)smw_new)->rectangle.height) != XtHeight(smw_old)(((RectObj)smw_old)->rectangle.height)) {
586 smw_new->simple_menu.menu_height = XtHeight(smw_new)(((RectObj)smw_new)->rectangle.height) != 0;
587 layout = True1;
588 }
589 }
590
591 if (smw_old->simple_menu.cursor != smw_new->simple_menu.cursor)
592 XDefineCursor(XtDisplay(cnew)(((cnew)->core.screen)->display), XtWindow(cnew)((cnew)->core.window),
593 smw_new->simple_menu.cursor);
594
595 if (smw_old->simple_menu.label_string !=smw_new->simple_menu.label_string) {
596 if (smw_new->simple_menu.label_string == NULL((void*)0)) /* Destroy */
597 XtDestroyWidget((Widget)smw_old->simple_menu.label);
598 else if (smw_old->simple_menu.label_string == NULL((void*)0)) /* Create */
599 CreateLabel(cnew);
600 else { /* Change */
601 Arg arglist[1];
602
603 XtSetArg(arglist[0], XtNlabel, smw_new->simple_menu.label_string)((void)( (arglist[0]).name = (((char*)&XtStrings[429])), (
arglist[0]).value = (XtArgVal)(smw_new->simple_menu.label_string
) ))
;
604 XtSetValues((Widget)smw_new->simple_menu.label, arglist, ONE((Cardinal)1));
605 }
606 }
607
608 if (smw_old->simple_menu.label_class != smw_new->simple_menu.label_class)
609 XtAppWarning(XtWidgetToApplicationContext(cnew),
610 "No Dynamic class change of the SimpleMenu Label.");
611
612 if (smw_old->simple_menu.top_margin != smw_new->simple_menu.top_margin
613 || smw_old->simple_menu.bottom_margin
614 != smw_new->simple_menu.bottom_margin) {
615 layout = True1;
616 ret_val = True1;
617 }
618
619#ifndef OLDXAW1
620 if (smw_old->core.background_pixmap != smw_new->core.background_pixmap) {
621 XawPixmap *opix, *npix;
622
623 opix = XawPixmapFromXPixmap(smw_old->core.background_pixmap,
624 XtScreen(smw_old)((smw_old)->core.screen), smw_old->core.colormap,
625 smw_old->core.depth);
626 npix = XawPixmapFromXPixmap(smw_new->core.background_pixmap,
627 XtScreen(smw_new)((smw_new)->core.screen), smw_new->core.colormap,
628 smw_new->core.depth);
629 if ((npix && npix->mask) || (opix && opix->mask))
630 XawReshapeWidget(cnew, npix);
631 }
632#endif
633
634 if (layout)
635 Layout(cnew, NULL((void*)0), NULL((void*)0));
636
637 return (ret_val);
638}
639
640/*
641 * Function:
642 * XawSimpleMenuSetValuesHook
643 *
644 * Parameters:
645 * w - menu widget
646 * arglist - argument list passed to XtSetValues
647 * num_args - number of args
648 *
649 * Description:
650 * To handle a special case, this is passed the actual arguments.
651 */
652static Boolean
653XawSimpleMenuSetValuesHook(Widget w, ArgList arglist, Cardinal *num_args)
654{
655 Cardinal i;
656 Dimension width, height;
657
658 width = XtWidth(w)(((RectObj)w)->rectangle.width);
659 height = XtHeight(w)(((RectObj)w)->rectangle.height);
660
661 for (i = 0 ; i < *num_args ; i++) {
662 if (streq(arglist[i].name, XtNwidth)(strcmp((arglist[i].name), (((char*)&XtStrings[872]))) ==
0)
)
663 width = (Dimension)arglist[i].value;
664 if (streq(arglist[i].name, XtNheight)(strcmp((arglist[i].name), (((char*)&XtStrings[234]))) ==
0)
)
665 height = (Dimension) arglist[i].value;
666 }
667
668 if (width != XtWidth(w)(((RectObj)w)->rectangle.width) || height != XtHeight(w)(((RectObj)w)->rectangle.height))
669 MakeSetValuesRequest(w, width, height);
670
671 return (False0);
672}
673
674/*
675 * Geometry Management routines
676 */
677/*
678 * Function:
679 * XawSimpleMenuGeometryManager
680 *
681 * Parameters:
682 * w - Menu Entry making the request
683 * request - requested new geometry
684 * reply - the allowed geometry.
685 *
686 * Description:
687 * This is the SimpleMenu Widget's Geometry Manager.
688 *
689 * Returns:
690 * XtGeometry{Yes, No, Almost}
691 */
692static XtGeometryResult
693XawSimpleMenuGeometryManager(Widget w, XtWidgetGeometry *request,
694 XtWidgetGeometry *reply)
695{
696 SimpleMenuWidget smw = (SimpleMenuWidget)XtParent(w)((w)->core.parent);
697 SmeObject entry = (SmeObject)w;
698 XtGeometryMask mode = request->request_mode;
699 XtGeometryResult answer;
700 Dimension old_height, old_width;
701
702 if (!(mode & CWWidth(1<<2)) && !(mode & CWHeight(1<<3)))
703 return (XtGeometryNo);
704
705 reply->width = request->width;
706 reply->height = request->height;
707
708 old_width = XtWidth(entry)(((RectObj)entry)->rectangle.width);
709 old_height = XtHeight(entry)(((RectObj)entry)->rectangle.height);
710
711 Layout(w, &reply->width, &reply->height);
712
713 /*
714 * Since we are an override shell and have no parent there is no one to
715 * ask to see if this geom change is okay, so I am just going to assume
716 * we can do whatever we want. If you subclass be very careful with this
717 * assumption, it could bite you.
718 *
719 * Chris D. Peterson - Sept. 1989.
720 */
721 if ((!(mode & CWWidth(1<<2)) || reply->width == request->width)
722 && (!(mode & CWHeight(1<<3)) || reply->height == request->height)) {
723 if (mode & XtCWQueryOnly(1 << 7)) { /* Actually perform the layout */
724 XtWidth(entry)(((RectObj)entry)->rectangle.width) = old_width;
725 XtHeight(entry)(((RectObj)entry)->rectangle.height) = old_height;
726 }
727 else
728 Layout((Widget)smw, NULL((void*)0), NULL((void*)0));
729 answer = XtGeometryDone;
730 }
731 else {
732 XtWidth(entry)(((RectObj)entry)->rectangle.width) = old_width;
733 XtHeight(entry)(((RectObj)entry)->rectangle.height) = old_height;
734
735 if ((reply->width == request->width && !(mode & CWHeight(1<<3)))
736 || (reply->height == request->height && !(mode & CWWidth(1<<2)))
737 || (reply->width == request->width
738 && reply->height == request->height))
739 answer = XtGeometryNo;
740 else {
741 answer = XtGeometryAlmost;
742 reply->request_mode = 0;
743 if (reply->width != request->width)
744 reply->request_mode |= CWWidth(1<<2);
745 if (reply->height != request->height)
746 reply->request_mode |= CWHeight(1<<3);
747 }
748 }
749
750 return (answer);
751}
752
753/*
754 * Function:
755 * XawSimpleMenuChangeManaged
756 *
757 * Parameters:
758 * w - simple menu widget
759 *
760 * Description:
761 * Called whenever a new child is managed.
762 */
763static void
764XawSimpleMenuChangeManaged(Widget w)
765{
766 Layout(w, NULL((void*)0), NULL((void*)0));
767}
768
769/*
770 * Global Action Routines
771 *
772 * These actions routines will be added to the application's
773 * global action list
774 */
775/*
776 * Function:
777 * PositionMenuAction
778 *
779 * Parameters:
780 * w - a widget (no the simple menu widget)
781 * event - the event that caused this action
782 * params - parameters passed to the routine.
783 * we expect the name of the menu here.
784 * num_params - ""
785 *
786 * Description:
787 * Positions the simple menu widget.
788 */
789/*ARGSUSED*/
790static void
791PositionMenuAction(Widget w, XEvent *event,
792 String *params, Cardinal *num_params)
793{
794 Widget menu;
795 XPoint loc;
796
797 if (*num_params != 1) {
798 XtAppWarning(XtWidgetToApplicationContext(w),
799 "SimpleMenuWidget: position menu action expects "
800 "only one parameter which is the name of the menu.");
801 return;
802 }
803
804 if ((menu = FindMenu(w, params[0])) == NULL((void*)0)) {
805 char error_buf[BUFSIZ8192];
806
807 snprintf(error_buf, sizeof(error_buf),
808 "SimpleMenuWidget: could not find menu named %s.",
809 params[0]);
810 XtAppWarning(XtWidgetToApplicationContext(w), error_buf);
811 return;
812 }
813
814 switch (event->type) {
815 case ButtonPress4:
816 case ButtonRelease5:
817 loc.x = event->xbutton.x_root;
818 loc.y = event->xbutton.y_root;
819 PositionMenu(menu, &loc);
820 break;
821 case EnterNotify7:
822 case LeaveNotify8:
823 loc.x = event->xcrossing.x_root;
824 loc.y = event->xcrossing.y_root;
825 PositionMenu(menu, &loc);
826 break;
827 case MotionNotify6:
828 loc.x = event->xmotion.x_root;
829 loc.y = event->xmotion.y_root;
830 PositionMenu(menu, &loc);
831 break;
832 default:
833 PositionMenu(menu, NULL((void*)0));
834 break;
835 }
836}
837
838/*
839 * Widget Action Routines
840 */
841/*
842 * Function:
843 * Unhighlight
844 *
845 * Parameters:
846 * w - simple menu widget
847 * event - event that caused this action
848 * params - not used
849 * num_params - ""
850 *
851 * Description:
852 * Unhighlights current entry.
853 */
854/*ARGSUSED*/
855static void
856Unhighlight(Widget w, XEvent *event, String *params, Cardinal *num_params)
857{
858 SimpleMenuWidget smw = (SimpleMenuWidget)w;
859 SmeObject entry = smw->simple_menu.entry_set;
860
861 if (entry == NULL((void*)0))
862 return;
863
864#ifndef OLDXAW1
865 if (!smw->simple_menu.sub_menu)
866#endif
867 {
868 SmeObjectClass cclass;
869
870 smw->simple_menu.entry_set = NULL((void*)0);
871 cclass = (SmeObjectClass)entry->object.widget_class;
872 (cclass->sme_class.unhighlight)((Widget)entry);
873 }
874}
875
876/*
877 * Function:
878 * Highlight
879 *
880 * Parameters:
881 * w - simple menu widget
882 * event - event that caused this action
883 * params - not used
884 * num_params - ""
885 *
886 * Description:
887 * Highlights current entry.
888 */
889/*ARGSUSED*/
890static void
891Highlight(Widget w, XEvent *event, String *params, Cardinal *num_params)
892{
893 SimpleMenuWidget smw = (SimpleMenuWidget)w;
894 SmeObject entry;
895
896 if (!XtIsSensitive(w))
897 return;
898
899 entry = GetEventEntry(w, event);
900
901 if (entry == smw->simple_menu.entry_set)
902 return;
903
904#ifndef OLDXAW1
905 if (!smw->simple_menu.sub_menu)
906#endif
907 Unhighlight(w, event, params, num_params);
908
909 if (entry == NULL((void*)0))
910 return;
911
912 if (!XtIsSensitive((Widget)entry))
913 return;
914
915#ifndef OLDXAW1
916 if (smw->simple_menu.sub_menu)
917 PopdownSubMenu(smw);
918#endif
919
920 Unhighlight(w, event, params, num_params);
921
922#ifndef OLDXAW1
923 if (!(smw->simple_menu.state & SMW_UNMAPPING))
924#endif
925 {
926 SmeObjectClass cclass;
927
928 smw->simple_menu.entry_set = entry;
929 cclass = (SmeObjectClass)entry->object.widget_class;
930
931 (cclass->sme_class.highlight)((Widget)entry);
932
933#ifndef OLDXAW1
934 if (XtIsSubclass((Widget)entry, smeBSBObjectClass))
935 PopupSubMenu(smw);
936#endif
937 }
938}
939
940/*
941 * Function:
942 * Notify
943 *
944 * Parameters:
945 * w - simple menu widget
946 * event - event that caused this action
947 * params - not used
948 * num_params - ""
949 *
950 * Description:
951 * Notify user of current entry.
952 */
953/*ARGSUSED*/
954static void
955Notify(Widget w, XEvent *event, String *params, Cardinal *num_params)
956{
957 SmeObject entry;
958 SmeObjectClass cclass;
959
960 /* may be a propagated event from a sub menu, need to check it */
961 if (XtWindow(w)((w)->core.window) != event->xany.window)
962 return;
963 entry = GetEventEntry(w, event);
964 if (entry == NULL((void*)0) || !XtIsSensitive((Widget)entry))
965 return;
966
967 cclass = (SmeObjectClass) entry->object.widget_class;
968 (cclass->sme_class.notify)((Widget)entry);
969}
970
971/*
972 * Public Functions
973 */
974/*
975 * Function:
976 * XawSimpleMenuAddGlobalActions
977 *
978 * Arguments:
979 * app_con - appcontext
980 *
981 * Description:
982 * Adds the global actions to the simple menu widget.
983 */
984void
985XawSimpleMenuAddGlobalActions(XtAppContext app_con)
986{
987 XtInitializeWidgetClass(simpleMenuWidgetClass);
988 XmuCallInitializers(app_con);
989}
990
991/*
992 * Function:
993 * XawSimpleMenuGetActiveEntry
994 *
995 * Parameters:
996 * w - smw widget
997 *
998 * Description:
999 * Gets the currently active (set) entry.
1000 *
1001 * Returns:
1002 * The currently set entry or NULL if none is set
1003 */
1004Widget
1005XawSimpleMenuGetActiveEntry(Widget w)
1006{
1007 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1008
1009 return ((Widget)smw->simple_menu.entry_set);
1010}
1011
1012/*
1013 * Function:
1014 * XawSimpleMenuClearActiveEntry
1015 *
1016 * Parameters:
1017 * w - smw widget
1018 *
1019 * Description:
1020 * Unsets the currently active (set) entry.
1021 */
1022void
1023XawSimpleMenuClearActiveEntry(Widget w)
1024{
1025 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1026
1027 smw->simple_menu.entry_set = NULL((void*)0);
1028}
1029
1030/*
1031 * Private Functions
1032 */
1033/*
1034 * Function:
1035 * CreateLabel
1036 *
1037 * Parameters:
1038 * w - smw widget
1039 *
1040 * Description:
1041 * Creates the label object and makes sure it is the first child in
1042 * in the list.
1043 */
1044static void
1045CreateLabel(Widget w)
1046{
1047 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1048 Widget *child, *next_child;
1049 int i;
1050 Arg args[2];
1051
1052 if (smw->simple_menu.label_string == NULL((void*)0) ||
1053 smw->simple_menu.label != NULL((void*)0)) {
1054 XtAppWarning(XtWidgetToApplicationContext(w),
1055 "Xaw Simple Menu Widget: label string is NULL or "
1056 "label already exists, no label is being created.");
1057 return;
1058 }
1059
1060 XtSetArg(args[0], XtNlabel, smw->simple_menu.label_string)((void)( (args[0]).name = (((char*)&XtStrings[429])), (args
[0]).value = (XtArgVal)(smw->simple_menu.label_string) ))
;
1061 XtSetArg(args[1], XtNjustify, XtJustifyCenter)((void)( (args[1]).name = (((char*)&XtStrings[379])), (args
[1]).value = (XtArgVal)(XtJustifyCenter) ))
;
1062 smw->simple_menu.label = (SmeObject)
1063 XtCreateManagedWidget("menuLabel",
1064 smw->simple_menu.label_class, w, args, TWO((Cardinal)2));
1065
1066 next_child = NULL((void*)0);
1067 for (child = smw->composite.children + smw->composite.num_children,
1068 i = smw->composite.num_children; i > 0; i--, child--) {
1069 if (next_child != NULL((void*)0))
1070 *next_child = *child;
1071 next_child = child;
1072 }
1073 *child = (Widget)smw->simple_menu.label;
1074}
1075
1076/*
1077 * Function:
1078 * Layout
1079 *
1080 * Arguments:
1081 * w - See below
1082 * width_ret - returned width
1083 * height_ret - returned height
1084 *
1085 * Note:
1086 * if width == NULL || height == NULL then it assumes the you do not care
1087 * about the return values, and just want a relayout.
1088 *
1089 * if this is not the case then it will set width_ret and height_ret
1090 * to be width and height that the child would get if it were layed out
1091 * at this time.
1092 *
1093 * "w" can be the simple menu widget or any of its object children.
1094 */
1095static void
1096Layout(Widget w, Dimension *width_ret, Dimension *height_ret)
1097{
1098 SmeObject current_entry;
1099 SimpleMenuWidget smw;
1100 Dimension width, height;
1101 Boolean allow_change_size;
1102 Widget kid;
1103 Cardinal i, count, n;
1104 int width_kid, height_kid, tmp_w, tmp_h;
1105 short vadd, hadd, x_ins, y_ins;
1106 Dimension *widths;
1107
1108 height = 0;
1109
1110 if (XtIsSubclass(w, simpleMenuWidgetClass)) {
1111 smw = (SimpleMenuWidget)w;
1112 current_entry = NULL((void*)0);
1113 }
1114 else {
1115 smw = (SimpleMenuWidget)XtParent(w)((w)->core.parent);
1116 current_entry = (SmeObject)w;
1117 }
1118
1119 allow_change_size = (!XtIsRealized((Widget)smw)(XtWindowOfObject((Widget)smw) != 0L)
1120 || smw->shell.allow_shell_resize);
1121
1122 for (i = smw->simple_menu.label ? 1 : 0;
1123 i < smw->composite.num_children;
1124 i++) {
1125 XtWidgetGeometry preferred;
1126
1127 kid = smw->composite.children[i];
1128 if (!XtIsManaged(kid))
1129 continue;
1130 if (smw->simple_menu.row_height != 0)
1131 XtHeight(kid)(((RectObj)kid)->rectangle.height) = smw->simple_menu.row_height;
1132 XtQueryGeometry(kid, NULL((void*)0), &preferred);
1133 if (preferred.request_mode & CWWidth(1<<2))
1134 XtWidth(kid)(((RectObj)kid)->rectangle.width) = preferred.width;
1135 }
1136
1137 if (smw->simple_menu.label
1138 && XtIsManaged((Widget)smw->simple_menu.label)) {
1139 XtWidgetGeometry preferred;
1140
1141 kid = (Widget)smw->simple_menu.label;
1142 XtQueryGeometry(kid, NULL((void*)0), &preferred);
1143 if (preferred.request_mode & CWWidth(1<<2))
1144 XtWidth(kid)(((RectObj)kid)->rectangle.width) = preferred.width;
1145 if (preferred.request_mode & CWHeight(1<<3))
1146 XtHeight(kid)(((RectObj)kid)->rectangle.height) = preferred.height;
1147 }
1148
1149 /* reset */
1150 if (!smw->simple_menu.menu_width)
1151 XtWidth(smw)(((RectObj)smw)->rectangle.width) = 0;
1152 if (!smw->simple_menu.menu_height)
1153 XtHeight(smw)(((RectObj)smw)->rectangle.height) = 0;
1154 if (!XtWidth(smw)(((RectObj)smw)->rectangle.width) || !XtHeight(smw)(((RectObj)smw)->rectangle.height))
1155 MakeResizeRequest((Widget)smw);
1156
1157 widths = (Dimension *)XtMalloc(sizeof(Dimension));
1158#ifndef OLDXAW1
1159 hadd = smw->simple_menu.left_margin;
1160#else
1161 hadd = 0;
1162#endif
1163 vadd = smw->simple_menu.top_margin;
1164 if (smw->simple_menu.label)
1165 vadd += XtHeight(smw->simple_menu.label)(((RectObj)smw->simple_menu.label)->rectangle.height);
1166
1167 count = 1;
1168 width = tmp_w = tmp_h = n = 0;
1169 height = vadd;
1170
1171 for (i = smw->simple_menu.label ? 1 : 0;
1172 i < smw->composite.num_children;
1173 i++) {
1174 kid = smw->composite.children[i];
1175 if (!XtIsManaged(kid))
1176 continue;
1177 width_kid = XtWidth(kid)(((RectObj)kid)->rectangle.width);
1178 height_kid = XtHeight(kid)(((RectObj)kid)->rectangle.height);
1179
1180 if (n && (height + height_kid + smw->simple_menu.bottom_margin
1181 > XtHeight(smw)(((RectObj)smw)->rectangle.height))) {
1182 ++count;
1183 widths = (Dimension *)XtRealloc((char *)widths,
1184 sizeof(Dimension) * count);
1185 widths[count - 1] = width_kid;
1186 width += tmp_w;
1187 tmp_w = width_kid;
1188 height = height_kid + vadd;
1189 }
1190 else
1191 height += height_kid;
1192 if (height > tmp_h)
1193 tmp_h = height;
1194 if (width_kid > tmp_w)
1195 widths[count - 1] = tmp_w = width_kid;
1196 ++n;
1197 }
1198
1199 height = tmp_h + smw->simple_menu.bottom_margin;
1200 width += tmp_w;
1201
1202 if (smw->simple_menu.label && width < XtWidth(smw->simple_menu.label)(((RectObj)smw->simple_menu.label)->rectangle.width)) {
1203 float inc;
1204
1205 inc = (XtWidth(smw->simple_menu.label)(((RectObj)smw->simple_menu.label)->rectangle.width) - width) / (float)count;
1206 width = XtWidth(smw->simple_menu.label)(((RectObj)smw->simple_menu.label)->rectangle.width);
1207 for (n = 0; n < count; n++)
1208 widths[n] += inc;
1209 }
1210
1211#ifndef OLDXAW1
1212 width += hadd + smw->simple_menu.right_margin;
1213#endif
1214
1215 x_ins = n = count = 0;
1216 tmp_w = widths[0];
1217 tmp_h = vadd;
1218
1219 for (i = smw->simple_menu.label ? 1 : 0;
1220 i < smw->composite.num_children;
1221 i++) {
1222 kid = smw->composite.children[i];
1223 if (!XtIsManaged(kid))
1224 continue;
1225
1226 height_kid = XtHeight(kid)(((RectObj)kid)->rectangle.height);
1227
1228 if (n && (tmp_h + height_kid + smw->simple_menu.bottom_margin
1229 > XtHeight(smw)(((RectObj)smw)->rectangle.height))) {
1230 x_ins = tmp_w;
1231 y_ins = vadd;
1232 ++count;
1233 tmp_w += widths[count];
1234 tmp_h = height_kid + vadd;
1235 }
1236 else {
1237 y_ins = tmp_h;
1238 tmp_h += height_kid;
1239 }
1240 ++n;
1241
1242 XtX(kid)(((RectObj)kid)->rectangle.x) = x_ins + hadd;
1243 XtY(kid)(((RectObj)kid)->rectangle.y) = y_ins;
1244 XtWidth(kid)(((RectObj)kid)->rectangle.width) = widths[count];
1245 }
1246
1247 XtFree((char *)widths);
1248
1249 if (allow_change_size)
1250 MakeSetValuesRequest((Widget) smw, width, height);
1251
1252 if (smw->simple_menu.label) {
1253 XtX(smw->simple_menu.label)(((RectObj)smw->simple_menu.label)->rectangle.x) = 0;
1254 XtY(smw->simple_menu.label)(((RectObj)smw->simple_menu.label)->rectangle.y) = smw->simple_menu.top_margin;
1255 XtWidth(smw->simple_menu.label)(((RectObj)smw->simple_menu.label)->rectangle.width) = XtWidth(smw)(((RectObj)smw)->rectangle.width)
1256#ifndef OLDXAW1
1257 - (smw->simple_menu.left_margin + smw->simple_menu.right_margin)
1258#endif
1259 ;
1260 }
1261 if (current_entry) {
1262 if (width_ret)
1263 *width_ret = XtWidth(current_entry)(((RectObj)current_entry)->rectangle.width);
1264 if (height_ret)
1265 *height_ret = XtHeight(current_entry)(((RectObj)current_entry)->rectangle.height);
1266 }
1267}
1268
1269/*
1270 * Function:
1271 * AddPositionAction
1272 *
1273 * Parameters:
1274 * app_con - application context
1275 * data - (not used)
1276 *
1277 * Description:
1278 * Adds the XawPositionSimpleMenu action to the global
1279 * action list for this appcon.
1280 */
1281/*ARGSUSED*/
1282static void
1283AddPositionAction(XtAppContext app_con, XPointer data)
1284{
1285 static XtActionsRec pos_action[] = {
1286 {"XawPositionSimpleMenu", PositionMenuAction},
1287 };
1288
1289 XtAppAddActions(app_con, pos_action, XtNumber(pos_action)((Cardinal) (sizeof(pos_action) / sizeof(pos_action[0]))));
1290}
1291
1292/*
1293 * Function:
1294 * FindMenu
1295 *
1296 * Parameters:
1297 * widget - reference widget
1298 * name - menu widget's name
1299 *
1300 * Description:
1301 * Find the menu give a name and reference widget
1302 *
1303 * Returns:
1304 * The menu widget or NULL.
1305 */
1306static Widget
1307FindMenu(Widget widget, String name)
1308{
1309 Widget w, menu;
1310
1311 for (w = widget; w != NULL((void*)0); w = XtParent(w)((w)->core.parent))
1312 if ((menu = XtNameToWidget(w, name)) != NULL((void*)0))
1313 return (menu);
1314
1315 return (NULL((void*)0));
1316}
1317
1318/*
1319 * Function:
1320 * PositionMenu
1321 *
1322 * Parameters:
1323 * w - simple menu widget
1324 * location - pointer the the position or NULL
1325 *
1326 * Description:
1327 * Places the menu
1328 */
1329static void
1330PositionMenu(Widget w, XPoint *location)
1331{
1332 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1333 SmeObject entry;
1334 XPoint t_point;
1335
1336 if (location == NULL((void*)0)) {
1337 Window temp1, temp2;
1338 int root_x, root_y, tempX, tempY;
1339 unsigned int tempM;
1340
1341 location = &t_point;
1342 if (XQueryPointer(XtDisplay(w)(((w)->core.screen)->display), XtWindow(w)((w)->core.window), &temp1, &temp2,
1343 &root_x, &root_y, &tempX, &tempY, &tempM) == False0) {
1344 XtAppWarning(XtWidgetToApplicationContext(w),
1345 "Xaw Simple Menu Widget: "
1346 "Could not find location of mouse pointer");
1347 return;
1348 }
1349 location->x = (short) root_x;
1350 location->y = (short) root_y;
1351 }
1352
1353 /*
1354 * The width will not be correct unless it is realized
1355 */
1356 XtRealizeWidget(w);
1357
1358 location->x -= XtWidth(w)(((RectObj)w)->rectangle.width) >> 1;
1359
1360 if (smw->simple_menu.popup_entry == NULL((void*)0))
1361 entry = smw->simple_menu.label;
1362 else
1363 entry = smw->simple_menu.popup_entry;
1364
1365 if (entry != NULL((void*)0))
1366 location->y -= XtY(entry)(((RectObj)entry)->rectangle.y) + (XtHeight(entry)(((RectObj)entry)->rectangle.height) >> 1);
1367
1368 MoveMenu(w, location->x, location->y);
1369}
1370
1371/*
1372 * Function:
1373 * MoveMenu
1374 *
1375 * Parameters:
1376 * w - simple menu widget
1377 * x - current location of the widget
1378 * y - ""
1379 *
1380 * Description:
1381 * Actually moves the menu, may force it to
1382 * to be fully visable if menu_on_screen is True.
1383 */
1384static void
1385MoveMenu(Widget w, int x, int y)
1386{
1387 Arg arglist[2];
1388 Cardinal num_args = 0;
1389 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1390
1391 if (smw->simple_menu.menu_on_screen) {
1392 int width = XtWidth(w)(((RectObj)w)->rectangle.width) + (XtBorderWidth(w)(((RectObj)w)->rectangle.border_width) << 1);
1393 int height = XtHeight(w)(((RectObj)w)->rectangle.height) + (XtBorderWidth(w)(((RectObj)w)->rectangle.border_width) << 1);
1394
1395 if (x >= 0) {
1396 int scr_width = WidthOfScreen(XtScreen(w))((((w)->core.screen))->width);
1397
1398 if (x + width > scr_width)
1399 x = scr_width - width;
1400 }
1401 if (x < 0)
1402 x = 0;
1403
1404 if (y >= 0) {
1405 int scr_height = HeightOfScreen(XtScreen(w))((((w)->core.screen))->height);
1406
1407 if (y + height > scr_height)
1408 y = scr_height - height;
1409 }
1410 if (y < 0)
1411 y = 0;
1412 }
1413
1414 XtSetArg(arglist[num_args], XtNx, x)((void)( (arglist[num_args]).name = (((char*)&XtStrings[885
])), (arglist[num_args]).value = (XtArgVal)(x) ))
; num_args++;
1415 XtSetArg(arglist[num_args], XtNy, y)((void)( (arglist[num_args]).name = (((char*)&XtStrings[887
])), (arglist[num_args]).value = (XtArgVal)(y) ))
; num_args++;
1416 XtSetValues(w, arglist, num_args);
1417}
1418
1419/*
1420 * Function:
1421 * ChangeCursorOnGrab
1422 *
1423 * Parameters:
1424 * w - menu widget
1425 * temp1 - not used
1426 * temp2 - ""
1427 *
1428 * Description:
1429 * Changes the cursor on the active grab to the one
1430 * specified in out resource list.
1431 */
1432/*ARGSUSED*/
1433static void
1434ChangeCursorOnGrab(Widget w, XtPointer temp1, XtPointer temp2)
1435{
1436 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1437
1438 /*
1439 * The event mask here is what is currently in the MIT implementation.
1440 * There really needs to be a way to get the value of the mask out
1441 * of the toolkit (CDP 5/26/89).
1442 */
1443 XChangeActivePointerGrab(XtDisplay(w)(((w)->core.screen)->display), ButtonPressMask(1L<<2) | ButtonReleaseMask(1L<<3),
1444 smw->simple_menu.cursor,
1445 XtLastTimestampProcessed(XtDisplay(w)(((w)->core.screen)->display)));
1446}
1447
1448/*
1449 * Function:
1450 * MakeSetValuesRequest
1451 *
1452 * Parameters:
1453 * w - simple menu widget
1454 * width - size requested
1455 * height - ""
1456 */
1457static void
1458MakeSetValuesRequest(Widget w, unsigned int width, unsigned int height)
1459{
1460 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1461 Arg arglist[2];
1462 Cardinal num_args = 0;
1463
1464 if (!smw->simple_menu.recursive_set_values) {
1465 if (XtWidth(smw)(((RectObj)smw)->rectangle.width) != width || XtHeight(smw)(((RectObj)smw)->rectangle.height) != height) {
1466 smw->simple_menu.recursive_set_values = True1;
1467 XtSetArg(arglist[num_args], XtNwidth, width)((void)( (arglist[num_args]).name = (((char*)&XtStrings[872
])), (arglist[num_args]).value = (XtArgVal)(width) ))
; num_args++;
1468 XtSetArg(arglist[num_args], XtNheight, height)((void)( (arglist[num_args]).name = (((char*)&XtStrings[234
])), (arglist[num_args]).value = (XtArgVal)(height) ))
; num_args++;
1469 XtSetValues(w, arglist, num_args);
1470 }
1471 else if (XtIsRealized((Widget)smw)(XtWindowOfObject((Widget)smw) != 0L))
1472 XawSimpleMenuRedisplay((Widget)smw, NULL((void*)0), NULL((void*)0));
1473 }
1474 smw->simple_menu.recursive_set_values = False0;
1475}
1476
1477static SmeObject
1478DoGetEventEntry(Widget w, int x_loc, int y_loc)
1479{
1480 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1481 SmeObject *entry;
1482
1483 ForAllChildren(smw, entry)for ((entry) = (SmeObject *)(smw)->composite.children; (entry
) < (SmeObject *)((smw)->composite.children + (smw)->
composite.num_children); (entry)++)
{
1484 if (!XtIsManaged((Widget)*entry))
1485 continue;
1486
1487 if (x_loc > XtX(*entry)(((RectObj)*entry)->rectangle.x)
1488 && x_loc <= XtX(*entry)(((RectObj)*entry)->rectangle.x) + XtWidth(*entry)(((RectObj)*entry)->rectangle.width)
1489 && y_loc > XtY(*entry)(((RectObj)*entry)->rectangle.y)
1490 && y_loc <= XtY(*entry)(((RectObj)*entry)->rectangle.y) + XtHeight(*entry)(((RectObj)*entry)->rectangle.height)) {
1491 if (*entry == smw->simple_menu.label)
1492 return (NULL((void*)0)); /* cannot select the label */
1493 else
1494 return (*entry);
1495 }
1496 }
1497
1498 return (NULL((void*)0));
1499}
1500
1501/*
1502 * Function:
1503 * GetEventEntry
1504 *
1505 * Parameters:
1506 * w - simple menu widget
1507 * event - X event
1508 *
1509 * Description:
1510 * Gets an entry given an event that has X and Y coords.
1511 *
1512 * Returns:
1513 * The entry that this point is in
1514 */
1515static SmeObject
1516GetEventEntry(Widget w, XEvent *event)
1517{
1518 int x_loc, y_loc, x_root;
1519 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1520 SmeObject entry;
1521 int warp, move;
1522
1523 switch (event->type) {
1524 case MotionNotify6:
1525 x_loc = event->xmotion.x;
1526 y_loc = event->xmotion.y;
1527 x_root = event->xmotion.x_root;
1528 break;
1529 case EnterNotify7:
1530 case LeaveNotify8:
1531 x_loc = event->xcrossing.x;
1532 y_loc = event->xcrossing.y;
1533 x_root = event->xcrossing.x_root;
1534 break;
1535 case ButtonPress4:
1536 case ButtonRelease5:
1537 x_loc = event->xbutton.x;
1538 y_loc = event->xbutton.y;
1539 x_root = event->xbutton.x_root;
1540 break;
1541 default:
1542 XtAppError(XtWidgetToApplicationContext(w),
1543 "Unknown event type in GetEventEntry().");
1544 return (NULL((void*)0));
1545 }
1546
1547 if (x_loc < 0 || x_loc >= XtWidth(smw)(((RectObj)smw)->rectangle.width) ||
1548 y_loc < 0 || y_loc >= XtHeight(smw)(((RectObj)smw)->rectangle.height))
1549 return (NULL((void*)0));
1550
1551 /* Move the menu if it's outside the screen, does not check
1552 * smw->simple_menu.menu_on_screen because menus is bigger than screen
1553 */
1554 if (x_root == WidthOfScreen(XtScreen(w))((((w)->core.screen))->width) - 1 &&
1555 XtX(w)(((RectObj)w)->rectangle.x) + XtWidth(w)(((RectObj)w)->rectangle.width) + (XtBorderWidth(w)(((RectObj)w)->rectangle.border_width)) > x_root) {
1556 warp = -8;
Value stored to 'warp' is never read
1557 if (smw->simple_menu.entry_set) {
1558 entry = DoGetEventEntry(w,
1559 XtX(smw->simple_menu.entry_set)(((RectObj)smw->simple_menu.entry_set)->rectangle.x)
1560 + XtWidth(smw->simple_menu.entry_set)(((RectObj)smw->simple_menu.entry_set)->rectangle.width
)
+ 1,
1561 y_loc);
1562 Unhighlight(w, event, NULL((void*)0), NULL((void*)0));
1563 if (entry) {
1564 warp = -(int)XtWidth(entry)(((RectObj)entry)->rectangle.width) >> 1;
1565 move = x_loc - XtWidth(entry)(((RectObj)entry)->rectangle.width) - XtX(entry)(((RectObj)entry)->rectangle.x) + XtBorderWidth(w)(((RectObj)w)->rectangle.border_width);
1566 }
1567 else {
1568 warp = 0;
1569 move = WidthOfScreen(XtScreen(w))((((w)->core.screen))->width) -
1570 (XtX(w)(((RectObj)w)->rectangle.x) + XtWidth(w)(((RectObj)w)->rectangle.width) + (XtBorderWidth(w)(((RectObj)w)->rectangle.border_width) << 1));
1571 }
1572 }
1573 else {
1574 warp = 0;
1575 move = WidthOfScreen(XtScreen(w))((((w)->core.screen))->width) -
1576 (XtX(w)(((RectObj)w)->rectangle.x) + XtWidth(w)(((RectObj)w)->rectangle.width) + (XtBorderWidth(w)(((RectObj)w)->rectangle.border_width) << 1));
1577 }
1578 }
1579 else if (x_root == 0 && XtX(w)(((RectObj)w)->rectangle.x) < 0) {
1580 warp = 8;
1581 if (smw->simple_menu.entry_set) {
1582 entry = DoGetEventEntry(w, XtX(smw->simple_menu.entry_set)(((RectObj)smw->simple_menu.entry_set)->rectangle.x) - 1,
1583 y_loc);
1584 Unhighlight(w, event, NULL((void*)0), NULL((void*)0));
1585 if (entry) {
1586 warp = XtWidth(entry)(((RectObj)entry)->rectangle.width) >> 1;
1587 move = x_loc - XtX(entry)(((RectObj)entry)->rectangle.x);
1588 }
1589 else
1590 move = x_loc + XtBorderWidth(w)(((RectObj)w)->rectangle.border_width);
1591 }
1592 else
1593 move = x_loc + XtBorderWidth(w)(((RectObj)w)->rectangle.border_width);
1594 }
1595 else
1596 move = warp = 0;
1597
1598 if (move)
1599 XtMoveWidget(w, XtX(w)(((RectObj)w)->rectangle.x) + move, XtY(w)(((RectObj)w)->rectangle.y));
1600 if (warp)
1601 XWarpPointer(XtDisplay(w)(((w)->core.screen)->display), None0L, None0L, 0, 0, 0, 0, warp, 0);
1602
1603 return (DoGetEventEntry(w, x_loc, y_loc));
1604}
1605
1606static void
1607CalculateNewSize(Widget w, Dimension *width_return, Dimension *height_return)
1608{
1609 SimpleMenuWidget xaw = (SimpleMenuWidget)w;
1610 Widget kid;
1611 Cardinal i;
1612 int width_kid, height_kid;
1613 int width, height, tmp_w, tmp_h, max_dim;
1614 short vadd, hadd;
1615 int n, columns, test_h, num_children = 0;
1616 Boolean try_layout = False0;
1617
1618#ifndef OLDXAW1
1619 hadd = xaw->simple_menu.left_margin + xaw->simple_menu.right_margin;
1620#else
1621 hadd = 0;
1622#endif
1623 vadd = xaw->simple_menu.top_margin + xaw->simple_menu.bottom_margin;
1624 if (xaw->simple_menu.label)
1625 vadd += XtHeight(xaw->simple_menu.label)(((RectObj)xaw->simple_menu.label)->rectangle.height);
1626
1627 if (*height_return)
1628 max_dim = *height_return;
1629 else if (!XtHeight(w)(((RectObj)w)->rectangle.height)) {
1630 max_dim = HeightOfScreen(XtScreen(w))((((w)->core.screen))->height);
1631 try_layout = True1;
1632 }
1633 else
1634 max_dim = XtHeight(w)(((RectObj)w)->rectangle.height);
1635 max_dim -= vadd;
1636
1637 width = height = tmp_w = tmp_h = n = test_h = 0;
1638 columns = 1;
1639 for (i = xaw->simple_menu.label ? 1 : 0;
1640 i < xaw->composite.num_children;
1641 i++) {
1642 kid = xaw->composite.children[i];
1643 if (!XtIsManaged(kid))
1644 continue;
1645 ++num_children;
1646 width_kid = XtWidth(kid)(((RectObj)kid)->rectangle.width);
1647 height_kid = XtHeight(kid)(((RectObj)kid)->rectangle.height);
1648
1649 if (try_layout) {
1650 if (!test_h)
1651 test_h = height_kid;
1652 else if (test_h != height_kid)
1653 try_layout = False0;
1654 }
1655
1656 if (n && (height + height_kid > max_dim)) {
1657 ++columns;
1658 width += tmp_w;
1659 tmp_w = width_kid;
1660 height = height_kid;
1661 }
1662 else
1663 height += height_kid;
1664 if (height > tmp_h)
1665 tmp_h = height;
1666 if (width_kid > tmp_w)
1667 tmp_w = width_kid;
1668 ++n;
1669 }
1670
1671 height = tmp_h + vadd;
1672 width += tmp_w + hadd;
1673
1674 if (xaw->simple_menu.label)
1675 width = XawMax(width, XtWidth(xaw->simple_menu.label) + hadd)((width) > ((((RectObj)xaw->simple_menu.label)->rectangle
.width) + hadd) ? (width) : ((((RectObj)xaw->simple_menu.label
)->rectangle.width) + hadd))
;
1676
1677 *width_return = width;
1678 *height_return = height;
1679
1680 if (try_layout && columns > 1 && num_children > 2) {
1681 int space;
1682
1683 height = test_h * (xaw->simple_menu.label ?
1684 num_children - 1 :
1685 num_children);
1686
1687 max_dim -= max_dim % test_h;
1688 space = max_dim - (height % max_dim);
1689 if (space >= test_h * columns) {
1690 height = max_dim - space / columns;
1691 if (height % test_h)
1692 height += test_h - (height % test_h);
1693 *height_return = height + vadd;
1694 CalculateNewSize(w, width_return, height_return);
1695 }
1696 }
1697}
1698
1699static void
1700MakeResizeRequest(Widget w)
1701{
1702 int tries;
1703 Dimension width, height;
1704
1705 width = XtWidth(w)(((RectObj)w)->rectangle.width);
1706 height = XtHeight(w)(((RectObj)w)->rectangle.height);
1707
1708 for (tries = 0; tries < 100; tries++) {
1709 CalculateNewSize(w, &width, &height);
1710 if (width == XtWidth(w)(((RectObj)w)->rectangle.width) && height == XtHeight(w)(((RectObj)w)->rectangle.height))
1711 break;
1712 if (XtMakeResizeRequest(w, width, height, &width, &height) ==
1713 XtGeometryNo)
1714 break;
1715 }
1716}
1717
1718#ifndef OLDXAW1
1719static void
1720Popdown(Widget w, XEvent *event, String *params, Cardinal *num_params)
1721{
1722 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1723
1724 while (XtParent(w)((w)->core.parent) &&
1725 XtIsSubclass(XtParent(w)((w)->core.parent), simpleMenuWidgetClass)) {
1726 if (((SimpleMenuWidget)XtParent(w)((w)->core.parent))->simple_menu.sub_menu == (Widget)w) {
1727 w = XtParent(w)((w)->core.parent);
1728 smw = (SimpleMenuWidget)w;
1729 smw->simple_menu.entry_set = NULL((void*)0);
1730 }
1731 else
1732 break;
1733 }
1734
1735 smw->simple_menu.state |= SMW_UNMAPPING;
1736 if (smw->simple_menu.sub_menu)
1737 PopdownSubMenu(smw);
1738 XtCallActionProc(w, "XtMenuPopdown", event, params, *num_params);
1739}
1740
1741static void
1742PopupSubMenu(SimpleMenuWidget smw)
1743{
1744 Arg args[2];
1745 Cardinal num_args;
1746 Widget menu;
1747 SmeBSBObject entry = (SmeBSBObject)smw->simple_menu.entry_set;
1748 Position menu_x, menu_y;
1749 Boolint popleft;
1750
1751 if (entry->sme_bsb.menu_name == NULL((void*)0))
1752 return;
1753
1754 if ((menu = FindMenu((Widget)smw, entry->sme_bsb.menu_name)) == NULL((void*)0))
1755 return;
1756
1757 smw->simple_menu.sub_menu = menu;
1758
1759 if (!XtIsRealized(menu)(XtWindowOfObject(menu) != 0L))
1760 XtRealizeWidget(menu);
1761
1762 popleft = (smw->simple_menu.state & SMW_POPLEFT) != 0;
1763
1764 if (popleft)
1765 XtTranslateCoords((Widget)smw, -(int)XtWidth(menu)(((RectObj)menu)->rectangle.width),
1766 XtY(entry)(((RectObj)entry)->rectangle.y) - XtBorderWidth(menu)(((RectObj)menu)->rectangle.border_width), &menu_x, &menu_y);
1767 else
1768 XtTranslateCoords((Widget)smw, XtWidth(smw)(((RectObj)smw)->rectangle.width), XtY(entry)(((RectObj)entry)->rectangle.y)
1769 - XtBorderWidth(menu)(((RectObj)menu)->rectangle.border_width), &menu_x, &menu_y);
1770
1771 if (!popleft && menu_x >= 0) {
1772 int scr_width = WidthOfScreen(XtScreen(menu))((((menu)->core.screen))->width);
1773
1774 if (menu_x + XtWidth(menu)(((RectObj)menu)->rectangle.width) > scr_width) {
1775 menu_x -= XtWidth(menu)(((RectObj)menu)->rectangle.width) + XtWidth(smw)(((RectObj)smw)->rectangle.width);
1776 popleft = True1;
1777 }
1778 }
1779 else if (popleft && menu_x < 0) {
1780 menu_x = 0;
1781 popleft = False0;
1782 }
1783 if (menu_y >= 0) {
1784 int scr_height = HeightOfScreen(XtScreen(menu))((((menu)->core.screen))->height);
1785
1786 if (menu_y + XtHeight(menu)(((RectObj)menu)->rectangle.height) > scr_height)
1787 menu_y = scr_height - XtHeight(menu)(((RectObj)menu)->rectangle.height) - XtBorderWidth(menu)(((RectObj)menu)->rectangle.border_width);
1788 }
1789 if (menu_y < 0)
1790 menu_y = 0;
1791
1792 num_args = 0;
1793 XtSetArg(args[num_args], XtNx, menu_x)((void)( (args[num_args]).name = (((char*)&XtStrings[885]
)), (args[num_args]).value = (XtArgVal)(menu_x) ))
; num_args++;
1794 XtSetArg(args[num_args], XtNy, menu_y)((void)( (args[num_args]).name = (((char*)&XtStrings[887]
)), (args[num_args]).value = (XtArgVal)(menu_y) ))
; num_args++;
1795 XtSetValues(menu, args, num_args);
1796
1797 if (popleft)
1798 ((SimpleMenuWidget)menu)->simple_menu.state |= SMW_POPLEFT;
1799 else
1800 ((SimpleMenuWidget)menu)->simple_menu.state &= ~SMW_POPLEFT;
1801
1802 XtPopup(menu, XtGrabNone);
1803}
1804
1805static void
1806PopdownSubMenu(SimpleMenuWidget smw)
1807{
1808 SimpleMenuWidget menu = (SimpleMenuWidget)smw->simple_menu.sub_menu;
1809
1810 if (!menu)
1811 return;
1812
1813 menu->simple_menu.state |= SMW_UNMAPPING;
1814 PopdownSubMenu(menu);
1815
1816 XtPopdown((Widget)menu);
1817
1818 smw->simple_menu.sub_menu = NULL((void*)0);
1819}
1820
1821/*ARGSUSED*/
1822static void
1823PopupCB(Widget w, XtPointer client_data, XtPointer call_data)
1824{
1825 SimpleMenuWidget smw = (SimpleMenuWidget)w;
1826
1827 smw->simple_menu.state &= ~(SMW_UNMAPPING | SMW_POPLEFT);
1828}
1829#endif /* OLDXAW */