Bug Summary

File:SimpleMenu.c
Location:line 1455, column 12
Description:The left operand of '>=' is a garbage value

Annotated Source Code

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