Mercurial > hg > xemacs-beta
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 |