comparison lwlib/xlwmenu.c @ 175:2d532a89d707 r20-3b14

Import from CVS: tag r20-3b14
author cvs
date Mon, 13 Aug 2007 09:50:14 +0200
parents 0132846995bd
children 6075d714658b
comparison
equal deleted inserted replaced
174:bb3568571b84 175:2d532a89d707
45 #ifdef NEED_MOTIF 45 #ifdef NEED_MOTIF
46 #include <Xm/Xm.h> 46 #include <Xm/Xm.h>
47 #endif 47 #endif
48 #include "xlwmenuP.h" 48 #include "xlwmenuP.h"
49 49
50 /* simple, naieve integer maximum */
51 #ifndef max
52 #define max(a,b) ((a)>(b)?(a):(b))
53 #endif
54
50 static char 55 static char
51 xlwMenuTranslations [] = 56 xlwMenuTranslations [] =
52 "<BtnDown>: start()\n\ 57 "<BtnDown>: start()\n\
53 <BtnMotion>: drag()\n\ 58 <BtnMotion>: drag()\n\
54 <BtnUp>: select()\n\ 59 <BtnUp>: select()\n\
55 "; 60 ";
61
62 extern Widget lw_menubar_widget;
56 63
57 #define offset(field) XtOffset(XlwMenuWidget, field) 64 #define offset(field) XtOffset(XlwMenuWidget, field)
58 static XtResource 65 static XtResource
59 xlwMenuResources[] = 66 xlwMenuResources[] =
60 { 67 {
197 }, 204 },
198 }; 205 };
199 206
200 WidgetClass xlwMenuWidgetClass = (WidgetClass) &xlwMenuClassRec; 207 WidgetClass xlwMenuWidgetClass = (WidgetClass) &xlwMenuClassRec;
201 208
209 extern int lw_menu_accelerate;
210
202 /* Utilities */ 211 /* Utilities */
203 #if 0 /* Apparently not used anywhere */ 212 #if 0 /* Apparently not used anywhere */
204 213
205 static char * 214 static char *
206 safe_strdup (char *s) 215 safe_strdup (char *s)
299 static void 308 static void
300 make_old_stack_space (XlwMenuWidget mw, int n) 309 make_old_stack_space (XlwMenuWidget mw, int n)
301 { 310 {
302 if (!mw->menu.old_stack) 311 if (!mw->menu.old_stack)
303 { 312 {
304 mw->menu.old_stack_length = 10; 313 mw->menu.old_stack_length = max (10, n);
305 mw->menu.old_stack = 314 mw->menu.old_stack =
306 (widget_value**)XtCalloc (mw->menu.old_stack_length, 315 (widget_value**)XtCalloc (mw->menu.old_stack_length,
307 sizeof (widget_value*)); 316 sizeof (widget_value*));
308 } 317 }
309 else if (mw->menu.old_stack_length < n) 318 else if (mw->menu.old_stack_length < n)
310 { 319 {
320 while (mw->menu.old_stack_length < n)
311 mw->menu.old_stack_length *= 2; 321 mw->menu.old_stack_length *= 2;
322
312 mw->menu.old_stack = 323 mw->menu.old_stack =
313 (widget_value**)XtRealloc ((char *)mw->menu.old_stack, 324 (widget_value**)XtRealloc ((char *)mw->menu.old_stack,
314 mw->menu.old_stack_length * 325 mw->menu.old_stack_length *
315 sizeof (widget_value*)); 326 sizeof (widget_value*));
316 } 327 }
368 massaged_resource_char[j] = (char) j; 379 massaged_resource_char[j] = (char) j;
369 } 380 }
370 massaged_resource_char ['_'] = '_'; 381 massaged_resource_char ['_'] = '_';
371 massaged_resource_char ['+'] = 'P'; /* Convert C++ to cPP */ 382 massaged_resource_char ['+'] = 'P'; /* Convert C++ to cPP */
372 massaged_resource_char ['.'] = '_'; /* Convert Buffers... to buffers___ */ 383 massaged_resource_char ['.'] = '_'; /* Convert Buffers... to buffers___ */
384 }
385
386 static int
387 string_width_u (XlwMenuWidget mw,
388 #ifdef NEED_MOTIF
389 XmString s
390 #else
391 char *string
392 #endif
393 )
394 {
395 #ifdef NEED_MOTIF
396 Dimension width, height;
397 XmStringExtent (mw->menu.font_list, s, &width, &height);
398 return width;
399 #else
400 XCharStruct xcs;
401 int i,s=0,w=0;
402 int drop;
403 for (i=0;string[i];++i) {
404 if (string[i]=='%'&&string[i+1]=='_') {
405 XTextExtents (mw->menu.font, &string[s], i-s, &drop, &drop, &drop, &xcs);
406 w += xcs.width;
407 s = i + 2;
408 ++i;
409 }
410 }
411 if (string[s]) {
412 XTextExtents (mw->menu.font, &string[s], i-s, &drop, &drop, &drop, &xcs);
413 w += xcs.width;
414 }
415 return w;
416 #endif
373 } 417 }
374 418
375 static void 419 static void
376 massage_resource_name (CONST char *in, char *out) 420 massage_resource_name (CONST char *in, char *out)
377 { 421 {
710 XDrawString (XtDisplay (mw), window, gc, 754 XDrawString (XtDisplay (mw), window, gc,
711 x, y + mw->menu.font_ascent, string, strlen (string)); 755 x, y + mw->menu.font_ascent, string, strlen (string));
712 # endif /* USE_XFONTSET */ 756 # endif /* USE_XFONTSET */
713 757
714 #endif 758 #endif
759 }
760
761 static void
762 string_draw_u (XlwMenuWidget mw,
763 Window window,
764 int x, int y,
765 GC gc,
766 #ifdef NEED_MOTIF
767 XmString string
768 #else
769 char *string
770 #endif
771 )
772 {
773 #ifdef NEED_MOTIF
774 XmStringDraw (XtDisplay (mw), window,
775 mw->menu.font_list,
776 string, gc,
777 x, y,
778 1000, /* ???? width */
779 XmALIGNMENT_BEGINNING,
780 0, /* ???? layout_direction */
781 0);
782 #else
783 int i,s=0;
784 for (i=0;string[i];++i) {
785 if (string[i]=='%'&&string[i+1]=='_') {
786 XCharStruct xcs;
787 int drop;
788 /* underline next character */
789 if (i>s)
790 # ifdef USE_XFONTSET
791 XmbDrawString (XtDisplay (mw), window, mw->menu.font_set, gc,
792 x, y + mw->menu.font_ascent, &string[s], i-s);
793 # else
794 XDrawString (XtDisplay (mw), window, gc,
795 x, y + mw->menu.font_ascent, &string[s], i-s);
796 # endif /* USE_XFONTSET */
797
798 XTextExtents (mw->menu.font, &string[s], i-s, &drop, &drop, &drop,
799 &xcs);
800 x += xcs.width;
801
802 s=i+3;
803 i+=2;
804
805 # ifdef USE_XFONTSET
806 XmbDrawString (XtDisplay (mw), window, mw->menu.font_set, gc,
807 x, y + mw->menu.font_ascent, &string[i], 1);
808 # else
809 XDrawString (XtDisplay (mw), window, gc,
810 x, y + mw->menu.font_ascent, &string[i], 1);
811 # endif /* USE_XFONTSET */
812
813 XTextExtents (mw->menu.font, &string[i], 1, &drop, &drop, &drop,
814 &xcs);
815
816 XDrawLine (XtDisplay (mw), window, gc, x - 1,
817 y + mw->menu.font_ascent + 1,
818 x + xcs.width - 1, y + mw->menu.font_ascent + 1 );
819
820 x += xcs.width;
821 }
822 }
823 if (string[s])
824 # ifdef USE_XFONTSET
825 XmbDrawString (XtDisplay (mw), window, mw->menu.font_set, gc,
826 x, y + mw->menu.font_ascent, &string[s],
827 strlen (&string[s]));
828 # else
829 XDrawString (XtDisplay (mw), window, gc,
830 x, y + mw->menu.font_ascent, &string[s],
831 strlen (&string[s]));
832 # endif /* USE_XFONTSET */
833 #endif /* NEED_MOTIF */
715 } 834 }
716 835
717 static void 836 static void
718 binding_draw (XlwMenuWidget mw, Window w, int x, int y, GC gc, char *value) 837 binding_draw (XlwMenuWidget mw, Window w, int x, int y, GC gc, char *value)
719 { 838 {
1352 2 * mw->menu.vertical_margin + 1471 2 * mw->menu.vertical_margin +
1353 2 * mw->menu.shadow_thickness); 1472 2 * mw->menu.shadow_thickness);
1354 /* no left column decoration */ 1473 /* no left column decoration */
1355 *toggle_width = mw->menu.horizontal_margin + mw->menu.shadow_thickness;; 1474 *toggle_width = mw->menu.horizontal_margin + mw->menu.shadow_thickness;;
1356 1475
1357 *label_width = string_width (mw, resource_widget_value (mw, val)); 1476 *label_width = string_width_u (mw, resource_widget_value (mw, val));
1358 *bindings_width = mw->menu.horizontal_margin + mw->menu.shadow_thickness; 1477 *bindings_width = mw->menu.horizontal_margin + mw->menu.shadow_thickness;
1359 } 1478 }
1360 1479
1361 static void 1480 static void
1362 label_button_draw (XlwMenuWidget mw, 1481 label_button_draw (XlwMenuWidget mw,
1376 label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin; 1495 label_offset = mw->menu.shadow_thickness + mw->menu.horizontal_margin;
1377 1496
1378 /* 1497 /*
1379 * Draw the label string. 1498 * Draw the label string.
1380 */ 1499 */
1381 string_draw (mw, 1500 string_draw_u (mw,
1382 window, 1501 window,
1383 x + label_offset, y + y_offset, 1502 x + label_offset, y + y_offset,
1384 mw->menu.foreground_gc, 1503 mw->menu.foreground_gc,
1385 resource_widget_value (mw, val)); 1504 resource_widget_value (mw, val));
1386 } 1505 }
1450 gc = mw->menu.foreground_gc; 1569 gc = mw->menu.foreground_gc;
1451 else 1570 else
1452 gc = mw->menu.inactive_gc; 1571 gc = mw->menu.inactive_gc;
1453 } 1572 }
1454 1573
1455 string_draw (mw, 1574 string_draw_u (mw,
1456 window, 1575 window,
1457 x + label_offset, y + y_offset, 1576 x + label_offset, y + y_offset,
1458 gc, 1577 gc,
1459 resource_widget_value(mw, val)); 1578 resource_widget_value(mw, val));
1460 1579
2023 abort (); 2142 abort ();
2024 2143
2025 if (level < mw->menu.old_depth - 1) 2144 if (level < mw->menu.old_depth - 1)
2026 following_item = mw->menu.old_stack [level + 1]; 2145 following_item = mw->menu.old_stack [level + 1];
2027 else 2146 else
2028 following_item = NULL; 2147 {
2148 if (lw_menu_accelerate
2149 && level == mw->menu.old_depth - 1
2150 && mw->menu.old_stack [level]->type == CASCADE_TYPE)
2151 just_compute_p = True;
2152 following_item = NULL;
2153 }
2029 2154
2030 #if SLOPPY_TYPES == 1 2155 #if SLOPPY_TYPES == 1
2031 puts("==================================================================="); 2156 puts("===================================================================");
2032 print_widget_value (following_item, 1, 0); 2157 print_widget_value (following_item, 1, 0);
2033 #endif 2158 #endif
2283 for (i = 1; i < old_depth && i < new_depth; i++) 2408 for (i = 1; i < old_depth && i < new_depth; i++)
2284 if (old_stack [i] != new_stack [i]) 2409 if (old_stack [i] != new_stack [i])
2285 break; 2410 break;
2286 last_same = i - 1; 2411 last_same = i - 1;
2287 2412
2413 if (lw_menu_accelerate
2414 && last_same
2415 && last_same == old_depth - 1
2416 && old_stack [last_same]->contents)
2417 last_same--;
2418
2288 /* Memorize the previously selected item to be able to refresh it */ 2419 /* Memorize the previously selected item to be able to refresh it */
2289 old_selection = last_same + 1 < old_depth ? old_stack [last_same + 1] : NULL; 2420 old_selection = last_same + 1 < old_depth ? old_stack [last_same + 1] : NULL;
2290 if (old_selection && !old_selection->enabled) 2421 if (old_selection && !old_selection->enabled)
2291 old_selection = NULL; 2422 old_selection = NULL;
2292 new_selection = last_same + 1 < new_depth ? new_stack [last_same + 1] : NULL; 2423 new_selection = last_same + 1 < new_depth ? new_stack [last_same + 1] : NULL;
2295 2426
2296 /* updates old_state from new_state. It has to be done now because 2427 /* updates old_state from new_state. It has to be done now because
2297 display_menu (called below) uses the old_stack to know what to display. */ 2428 display_menu (called below) uses the old_stack to know what to display. */
2298 for (i = last_same + 1; i < new_depth; i++) 2429 for (i = last_same + 1; i < new_depth; i++)
2299 old_stack [i] = new_stack [i]; 2430 old_stack [i] = new_stack [i];
2431
2300 mw->menu.old_depth = new_depth; 2432 mw->menu.old_depth = new_depth;
2301 2433
2302 /* refresh the last seletion */ 2434 /* refresh the last seletion */
2303 selection_position.x = 0; 2435 selection_position.x = 0;
2304 selection_position.y = 0; 2436 selection_position.y = 0;
2309 for (i = last_same + 1; i < new_depth && new_stack [i]->contents; i++) 2441 for (i = last_same + 1; i < new_depth && new_stack [i]->contents; i++)
2310 { 2442 {
2311 window_state *previous_ws = &windows [i - 1]; 2443 window_state *previous_ws = &windows [i - 1];
2312 window_state *ws = &windows [i]; 2444 window_state *ws = &windows [i];
2313 2445
2446 if (lw_menu_accelerate && i == new_depth - 1)
2447 break;
2448
2314 ws->x = previous_ws->x + selection_position.x; 2449 ws->x = previous_ws->x + selection_position.x;
2315 ws->y = previous_ws->y + selection_position.y; 2450 ws->y = previous_ws->y + selection_position.y;
2316 2451
2317 /* take into account the slab around the new menu */ 2452 /* take into account the slab around the new menu */
2318 ws->y -= mw->menu.shadow_thickness; 2453 ws->y -= mw->menu.shadow_thickness;
2327 XMapRaised (XtDisplay (mw), ws->window); 2462 XMapRaised (XtDisplay (mw), ws->window);
2328 display_menu (mw, i, False, &selection_position, NULL, NULL, NULL, NULL); 2463 display_menu (mw, i, False, &selection_position, NULL, NULL, NULL, NULL);
2329 } 2464 }
2330 2465
2331 /* unmap the menus that popped down */ 2466 /* unmap the menus that popped down */
2332 for (i = new_depth - 1; i < old_depth; i++) 2467
2333 if (i >= new_depth || !new_stack [i]->contents) 2468 last_same = new_depth;
2469 if (lw_menu_accelerate
2470 && last_same > 1
2471 && new_stack [last_same - 1]->contents)
2472 last_same--;
2473
2474 for (i = last_same - 1; i < old_depth; i++)
2475 if (i >= last_same || !new_stack [i]->contents)
2334 XUnmapWindow (XtDisplay (mw), windows [i].window); 2476 XUnmapWindow (XtDisplay (mw), windows [i].window);
2335 } 2477 }
2336 2478
2337 static Boolean 2479 static Boolean
2338 motion_event_is_in_menu (XlwMenuWidget mw, XMotionEvent *ev, int level, 2480 motion_event_is_in_menu (XlwMenuWidget mw, XMotionEvent *ev, int level,
3063 /* don't handle the event twice or that breaks bounce_down. --Stig */ 3205 /* don't handle the event twice or that breaks bounce_down. --Stig */
3064 dummy.type = ev->type; 3206 dummy.type = ev->type;
3065 event = &dummy; 3207 event = &dummy;
3066 } 3208 }
3067 3209
3210 lw_menu_accelerate = False;
3068 handle_single_motion_event (mw, event, select_p); 3211 handle_single_motion_event (mw, event, select_p);
3069 } 3212 }
3213
3214 Time x_focus_timestamp_really_sucks_fix_me_better;
3070 3215
3071 static void 3216 static void
3072 Start (Widget w, XEvent *ev, String *params, Cardinal *num_params) 3217 Start (Widget w, XEvent *ev, String *params, Cardinal *num_params)
3073 { 3218 {
3074 XlwMenuWidget mw = (XlwMenuWidget)w; 3219 XlwMenuWidget mw = (XlwMenuWidget)w;
3075 3220
3221 lw_menubar_widget = w;
3222
3223 lw_menu_active = True;
3224
3076 if (!mw->menu.pointer_grabbed) 3225 if (!mw->menu.pointer_grabbed)
3077 { 3226 {
3078 mw->menu.menu_post_time = ev->xbutton.time; 3227 mw->menu.menu_post_time = ev->xbutton.time;
3079 mw->menu.menu_bounce_time = 0; 3228 mw->menu.menu_bounce_time = 0;
3080 mw->menu.next_release_must_exit = True; 3229 mw->menu.next_release_must_exit = True;
3081 mw->menu.last_selected_val = NULL; 3230 mw->menu.last_selected_val = NULL;
3082 3231 x_focus_timestamp_really_sucks_fix_me_better =
3232 ((XButtonPressedEvent*)ev)->time;
3083 XtCallCallbackList ((Widget)mw, mw->menu.open, NULL); 3233 XtCallCallbackList ((Widget)mw, mw->menu.open, NULL);
3084 3234
3085 /* notes the absolute position of the menubar window */ 3235 /* notes the absolute position of the menubar window */
3086 mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x; 3236 mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x;
3087 mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y; 3237 mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y;
3109 Select (Widget w, XEvent *ev, String *params, Cardinal *num_params) 3259 Select (Widget w, XEvent *ev, String *params, Cardinal *num_params)
3110 { 3260 {
3111 XlwMenuWidget mw = (XlwMenuWidget)w; 3261 XlwMenuWidget mw = (XlwMenuWidget)w;
3112 widget_value *selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; 3262 widget_value *selected_item = mw->menu.old_stack [mw->menu.old_depth - 1];
3113 3263
3264 lw_menu_accelerate = False;
3265
3114 /* If user releases the button quickly, without selecting anything, 3266 /* If user releases the button quickly, without selecting anything,
3115 after the initial down-click that brought the menu up, 3267 after the initial down-click that brought the menu up,
3116 do nothing. */ 3268 do nothing. */
3117 if ((selected_item == 0 || selected_item->call_data == 0) 3269 if ((selected_item == 0 || selected_item->call_data == 0)
3118 && (!mw->menu.next_release_must_exit 3270 && (!mw->menu.next_release_must_exit
3138 { 3290 {
3139 mw->menu.popped_up = False; 3291 mw->menu.popped_up = False;
3140 XtPopdown (XtParent (mw)); 3292 XtPopdown (XtParent (mw));
3141 } 3293 }
3142 3294
3295 lw_menu_active = False;
3296
3297 x_focus_timestamp_really_sucks_fix_me_better =
3298 ((XButtonPressedEvent*)ev)->time;
3299
3143 /* callback */ 3300 /* callback */
3144 XtCallCallbackList ((Widget) mw, mw->menu.select, (XtPointer) selected_item); 3301 XtCallCallbackList ((Widget) mw, mw->menu.select, (XtPointer) selected_item);
3302 }
3303
3304 /* Action procedures for keyboard accelerators */
3305
3306 /* set the menu */
3307 void
3308 xlw_set_menu (Widget w, widget_value *val)
3309 {
3310 lw_menubar_widget = w;
3311 set_new_state ((XlwMenuWidget)w, val, 1);
3312 }
3313
3314 /* prepare the menu structure via the call-backs */
3315 void
3316 xlw_map_menu (Time t)
3317 {
3318 XlwMenuWidget mw = (XlwMenuWidget)lw_menubar_widget;
3319
3320 lw_menu_accelerate = True;
3321
3322 if (!mw->menu.pointer_grabbed)
3323 {
3324 XWindowAttributes ret;
3325 Window parent,root;
3326 Window *waste;
3327 unsigned int num_waste;
3328
3329 lw_menu_active = True;
3330
3331 mw->menu.menu_post_time = t;
3332 mw->menu.menu_bounce_time = 0;
3333
3334 mw->menu.next_release_must_exit = True;
3335 mw->menu.last_selected_val = NULL;
3336
3337 XtCallCallbackList ((Widget)mw, mw->menu.open, NULL);
3338
3339 /* do this for keyboards too! */
3340 /* notes the absolute position of the menubar window */
3341 /*
3342 mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x;
3343 mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y;
3344 */
3345
3346 /* get the geometry of the menubar */
3347
3348 /* there has to be a better way than this. */
3349
3350 mw->menu.windows [0].x = 0;
3351 mw->menu.windows [0].y = 0;
3352
3353 parent = XtWindow (lw_menubar_widget);
3354 do
3355 {
3356 XGetWindowAttributes (XtDisplay (lw_menubar_widget), parent, &ret);
3357 mw->menu.windows [0].x += ret.x;
3358 mw->menu.windows [0].y += ret.y;
3359
3360 if (parent)
3361 XQueryTree (XtDisplay (lw_menubar_widget), parent, &root, &parent, &waste,
3362 &num_waste);
3363 if (waste)
3364 {
3365 XFree (waste);
3366 }
3367 }
3368 while (parent != root);
3369
3370 XtGrabPointer ((Widget)mw, False,
3371 (ButtonMotionMask | ButtonReleaseMask | ButtonPressMask),
3372 GrabModeAsync, GrabModeAsync,
3373 None, mw->menu.cursor_shape, t);
3374 mw->menu.pointer_grabbed = True;
3375 }
3376 }
3377
3378 /* display the stupid menu already */
3379 void
3380 xlw_display_menu (Time t)
3381 {
3382 XlwMenuWidget mw = (XlwMenuWidget)lw_menubar_widget;
3383
3384 lw_menu_accelerate = True;
3385
3386 remap_menubar (mw);
3387
3388 /* Sync with the display. Makes it feel better on X terms. */
3389 XFlush (XtDisplay (mw));
3390 }
3391
3392 /* push a sub menu */
3393 void
3394 xlw_push_menu (widget_value *val)
3395 {
3396 push_new_stack ((XlwMenuWidget)lw_menubar_widget, val);
3397 }
3398
3399 /* pop a sub menu */
3400 int
3401 xlw_pop_menu (void)
3402 {
3403 if (((XlwMenuWidget)lw_menubar_widget)->menu.new_depth > 0)
3404 ((XlwMenuWidget)lw_menubar_widget)->menu.new_depth --;
3405 else
3406 return 0;
3407 return 1;
3408 }
3409
3410 void
3411 xlw_kill_menus (widget_value *val)
3412 {
3413 XlwMenuWidget mw = (XlwMenuWidget)lw_menubar_widget;
3414
3415 lw_menu_accelerate = False;
3416
3417 mw->menu.new_depth = 1;
3418 remap_menubar (mw);
3419
3420 if (mw->menu.pointer_grabbed)
3421 {
3422 XtUngrabPointer (lw_menubar_widget, CurrentTime);
3423 mw->menu.pointer_grabbed = False;
3424 }
3425
3426 lw_menu_active = False;
3427 XtCallCallbackList (lw_menubar_widget, mw->menu.select, (XtPointer)val);
3428 }
3429
3430 /* set the menu item */
3431 void
3432 xlw_set_item (widget_value *val)
3433 {
3434 if (((XlwMenuWidget)lw_menubar_widget)->menu.new_depth > 0)
3435 ((XlwMenuWidget) lw_menubar_widget)->menu.new_depth --;
3436 push_new_stack ((XlwMenuWidget) lw_menubar_widget, val);
3437 }
3438
3439 /* get either the current entry or a list of all entries in the current submenu */
3440 widget_value *
3441 xlw_get_entries (int allp)
3442 {
3443 XlwMenuWidget mw = (XlwMenuWidget)lw_menubar_widget;
3444 if (allp)
3445 {
3446 if (mw->menu.new_depth >= 2)
3447 return mw->menu.new_stack [mw->menu.new_depth - 2]->contents;
3448 else
3449 return mw->menu.new_stack[0];
3450 }
3451 else
3452 if (mw->menu.new_depth >= 1)
3453 return mw->menu.new_stack [mw->menu.new_depth - 1];
3454
3455 return NULL;
3456 }
3457
3458 int
3459 xlw_menu_level (void)
3460 {
3461 return ((XlwMenuWidget)lw_menubar_widget)->menu.new_depth;
3145 } 3462 }
3146 3463
3147 3464
3148 /* Special code to pop-up a menu */ 3465 /* Special code to pop-up a menu */
3149 void 3466 void