288 |
|
|
289 |
static Lisp_Object |
static Lisp_Object |
290 |
unuse_menu_items (dummy) |
unuse_menu_items (dummy) |
291 |
int dummy; |
Lisp_Object dummy; |
292 |
{ |
{ |
293 |
return menu_items_inuse = Qnil; |
return menu_items_inuse = Qnil; |
294 |
} |
} |
1173 |
|
|
1174 |
#ifdef USE_X_TOOLKIT |
#ifdef USE_X_TOOLKIT |
1175 |
|
|
|
static Lisp_Object |
|
|
pop_down_menu (dummy) |
|
|
int dummy; |
|
|
{ |
|
|
popup_activated_flag = 0; |
|
|
return Qnil; |
|
|
} |
|
|
|
|
1176 |
/* Loop in Xt until the menu pulldown or dialog popup has been |
/* Loop in Xt until the menu pulldown or dialog popup has been |
1177 |
popped down (deactivated). This is used for x-popup-menu |
popped down (deactivated). This is used for x-popup-menu |
1178 |
and x-popup-dialog; it is not used for the menu bar. |
and x-popup-dialog; it is not used for the menu bar. |
1192 |
{ |
{ |
1193 |
XEvent event; |
XEvent event; |
1194 |
|
|
|
int specpdl_count = SPECPDL_INDEX (); |
|
|
record_unwind_protect (pop_down_menu, Qnil); |
|
|
|
|
1195 |
while (popup_activated_flag) |
while (popup_activated_flag) |
1196 |
{ |
{ |
1197 |
if (initial_event) |
if (initial_event) |
1241 |
|
|
1242 |
x_dispatch_event (&event, event.xany.display); |
x_dispatch_event (&event, event.xany.display); |
1243 |
} |
} |
|
|
|
|
unbind_to (specpdl_count, Qnil); |
|
1244 |
} |
} |
1245 |
|
|
1246 |
#endif /* USE_X_TOOLKIT */ |
#endif /* USE_X_TOOLKIT */ |
1248 |
#ifdef USE_GTK |
#ifdef USE_GTK |
1249 |
/* Loop util popup_activated_flag is set to zero in a callback. |
/* Loop util popup_activated_flag is set to zero in a callback. |
1250 |
Used for popup menus and dialogs. */ |
Used for popup menus and dialogs. */ |
|
static GtkWidget *current_menu; |
|
|
|
|
|
static Lisp_Object |
|
|
pop_down_menu (dummy) |
|
|
int dummy; |
|
|
{ |
|
|
if (current_menu) |
|
|
{ |
|
|
gtk_widget_unmap (current_menu); |
|
|
current_menu = 0; |
|
|
popup_activated_flag = 0; |
|
|
} |
|
|
return Qnil; |
|
|
} |
|
1251 |
|
|
1252 |
static void |
static void |
1253 |
popup_widget_loop (do_timers, widget) |
popup_widget_loop (do_timers, widget) |
1254 |
int do_timers; |
int do_timers; |
1255 |
GtkWidget *widget; |
GtkWidget *widget; |
1256 |
{ |
{ |
|
int specpdl_count = SPECPDL_INDEX (); |
|
|
current_menu = widget; |
|
|
record_unwind_protect (pop_down_menu, Qnil); |
|
|
|
|
1257 |
++popup_activated_flag; |
++popup_activated_flag; |
1258 |
|
|
1259 |
/* Process events in the Gtk event loop until done. */ |
/* Process events in the Gtk event loop until done. */ |
1262 |
if (do_timers) x_menu_wait_for_event (0); |
if (do_timers) x_menu_wait_for_event (0); |
1263 |
gtk_main_iteration (); |
gtk_main_iteration (); |
1264 |
} |
} |
|
|
|
|
unbind_to (specpdl_count, Qnil); |
|
1265 |
} |
} |
1266 |
#endif |
#endif |
1267 |
|
|
2410 |
if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data; |
if (cb_data) menu_item_selection = (Lisp_Object *) cb_data->call_data; |
2411 |
} |
} |
2412 |
|
|
2413 |
|
static GtkWidget *current_menu; |
2414 |
|
|
2415 |
|
static Lisp_Object |
2416 |
|
pop_down_menu (dummy) |
2417 |
|
Lisp_Object dummy; |
2418 |
|
{ |
2419 |
|
popup_activated_flag = 0; |
2420 |
|
if (current_menu) |
2421 |
|
{ |
2422 |
|
BLOCK_INPUT; |
2423 |
|
gtk_widget_destroy (current_menu); |
2424 |
|
UNBLOCK_INPUT; |
2425 |
|
current_menu = 0; |
2426 |
|
} |
2427 |
|
return Qnil; |
2428 |
|
} |
2429 |
|
|
2430 |
/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the |
/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the |
2431 |
menu pops down. |
menu pops down. |
2432 |
menu_item_selection will be set to the selection. */ |
menu_item_selection will be set to the selection. */ |
2442 |
GtkWidget *menu; |
GtkWidget *menu; |
2443 |
GtkMenuPositionFunc pos_func = 0; /* Pop up at pointer. */ |
GtkMenuPositionFunc pos_func = 0; /* Pop up at pointer. */ |
2444 |
struct next_popup_x_y popup_x_y; |
struct next_popup_x_y popup_x_y; |
2445 |
|
int specpdl_count = SPECPDL_INDEX (); |
2446 |
|
|
2447 |
xg_crazy_callback_abort = 1; |
xg_crazy_callback_abort = 1; |
2448 |
menu = xg_create_widget ("popup", first_wv->name, f, first_wv, |
menu = xg_create_widget ("popup", first_wv->name, f, first_wv, |
2473 |
gtk_widget_show_all (menu); |
gtk_widget_show_all (menu); |
2474 |
gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0); |
gtk_menu_popup (GTK_MENU (menu), 0, 0, pos_func, &popup_x_y, i, 0); |
2475 |
|
|
2476 |
|
current_menu = menu; |
2477 |
|
record_unwind_protect (pop_down_menu, Qnil); |
2478 |
|
|
2479 |
/* Set this to one. popup_widget_loop increases it by one, so it becomes |
/* Set this to one. popup_widget_loop increases it by one, so it becomes |
2480 |
two. show_help_echo uses this to detect popup menus. */ |
two. show_help_echo uses this to detect popup menus. */ |
2481 |
popup_activated_flag = 1; |
popup_activated_flag = 1; |
2482 |
/* Process events that apply to the menu. */ |
/* Process events that apply to the menu. */ |
2483 |
popup_widget_loop (1, 0); |
popup_widget_loop (1, menu); |
2484 |
|
|
2485 |
gtk_widget_destroy (menu); |
unbind_to (specpdl_count, Qnil); |
2486 |
|
|
2487 |
/* Must reset this manually because the button release event is not passed |
/* Must reset this manually because the button release event is not passed |
2488 |
to Emacs event loop. */ |
to Emacs event loop. */ |
2510 |
menu_item_selection = (Lisp_Object *) client_data; |
menu_item_selection = (Lisp_Object *) client_data; |
2511 |
} |
} |
2512 |
|
|
2513 |
|
/* ARG is the LWLIB ID of the dialog box, represented |
2514 |
|
as a Lisp object as (HIGHPART . LOWPART). */ |
2515 |
|
|
2516 |
|
static Lisp_Object |
2517 |
|
pop_down_menu (arg) |
2518 |
|
Lisp_Object arg; |
2519 |
|
{ |
2520 |
|
LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID) |
2521 |
|
| XINT (XCDR (arg))); |
2522 |
|
|
2523 |
|
BLOCK_INPUT; |
2524 |
|
lw_destroy_all_widgets (id); |
2525 |
|
UNBLOCK_INPUT; |
2526 |
|
popup_activated_flag = 0; |
2527 |
|
|
2528 |
|
return Qnil; |
2529 |
|
} |
2530 |
|
|
2531 |
/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the |
/* Pop up the menu for frame F defined by FIRST_WV at X/Y and loop until the |
2532 |
menu pops down. |
menu pops down. |
2533 |
menu_item_selection will be set to the selection. */ |
menu_item_selection will be set to the selection. */ |
2584 |
/* Display the menu. */ |
/* Display the menu. */ |
2585 |
lw_popup_menu (menu, (XEvent *) &dummy); |
lw_popup_menu (menu, (XEvent *) &dummy); |
2586 |
popup_activated_flag = 1; |
popup_activated_flag = 1; |
2587 |
|
|
2588 |
|
{ |
2589 |
|
int fact = 4 * sizeof (LWLIB_ID); |
2590 |
|
int specpdl_count = SPECPDL_INDEX (); |
2591 |
|
record_unwind_protect (pop_down_menu, |
2592 |
|
Fcons (make_number (menu_id >> (fact)), |
2593 |
|
make_number (menu_id & ~(-1 << (fact))))); |
2594 |
|
|
2595 |
/* Process events that apply to the menu. */ |
/* Process events that apply to the menu. */ |
2596 |
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1, 0); |
popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f), menu_id, 1, 0); |
2597 |
|
|
2598 |
/* fp turned off the following statement and wrote a comment |
unbind_to (specpdl_count, Qnil); |
2599 |
that it is unnecessary--that the menu has already disappeared. |
} |
|
Nowadays the menu disappears ok, all right, but |
|
|
we need to delete the widgets or multiple ones will pile up. */ |
|
|
lw_destroy_all_widgets (menu_id); |
|
2600 |
} |
} |
2601 |
|
|
2602 |
#endif /* not USE_GTK */ |
#endif /* not USE_GTK */ |
2907 |
|
|
2908 |
if (menu) |
if (menu) |
2909 |
{ |
{ |
2910 |
|
int specpdl_count = SPECPDL_INDEX (); |
2911 |
|
current_menu = menu; |
2912 |
|
record_unwind_protect (pop_down_menu, Qnil); |
2913 |
|
|
2914 |
/* Display the menu. */ |
/* Display the menu. */ |
2915 |
gtk_widget_show_all (menu); |
gtk_widget_show_all (menu); |
2916 |
|
|
2917 |
/* Process events that apply to the menu. */ |
/* Process events that apply to the menu. */ |
2918 |
popup_widget_loop (1, menu); |
popup_widget_loop (1, menu); |
2919 |
|
|
2920 |
gtk_widget_destroy (menu); |
unbind_to (specpdl_count, Qnil); |
2921 |
} |
} |
2922 |
} |
} |
2923 |
|
|
2940 |
} |
} |
2941 |
|
|
2942 |
|
|
|
/* ARG is the LWLIB ID of the dialog box, represented |
|
|
as a Lisp object as (HIGHPART . LOWPART). */ |
|
|
|
|
|
Lisp_Object |
|
|
xdialog_show_unwind (arg) |
|
|
Lisp_Object arg; |
|
|
{ |
|
|
LWLIB_ID id = (XINT (XCAR (arg)) << 4 * sizeof (LWLIB_ID) |
|
|
| XINT (XCDR (arg))); |
|
|
BLOCK_INPUT; |
|
|
lw_destroy_all_widgets (id); |
|
|
UNBLOCK_INPUT; |
|
|
popup_activated_flag = 0; |
|
|
return Qnil; |
|
|
} |
|
|
|
|
|
|
|
2943 |
/* Pop up the dialog for frame F defined by FIRST_WV and loop until the |
/* Pop up the dialog for frame F defined by FIRST_WV and loop until the |
2944 |
dialog pops down. |
dialog pops down. |
2945 |
menu_item_selection will be set to the selection. */ |
menu_item_selection will be set to the selection. */ |
2967 |
int fact = 4 * sizeof (LWLIB_ID); |
int fact = 4 * sizeof (LWLIB_ID); |
2968 |
|
|
2969 |
/* xdialog_show_unwind is responsible for popping the dialog box down. */ |
/* xdialog_show_unwind is responsible for popping the dialog box down. */ |
2970 |
record_unwind_protect (xdialog_show_unwind, |
record_unwind_protect (pop_down_menu, |
2971 |
Fcons (make_number (dialog_id >> (fact)), |
Fcons (make_number (dialog_id >> (fact)), |
2972 |
make_number (dialog_id & ~(-1 << (fact))))); |
make_number (dialog_id & ~(-1 << (fact))))); |
2973 |
|
|
3200 |
Qnil, menu_object, make_number (item), 1); |
Qnil, menu_object, make_number (item), 1); |
3201 |
} |
} |
3202 |
|
|
3203 |
|
static XMenu *current_menu; |
3204 |
|
|
3205 |
|
static Lisp_Object |
3206 |
|
pop_down_menu (frame) |
3207 |
|
Lisp_Object frame; |
3208 |
|
{ |
3209 |
|
struct frame *f = XFRAME (frame); |
3210 |
|
|
3211 |
|
BLOCK_INPUT; |
3212 |
|
if (current_menu) |
3213 |
|
{ |
3214 |
|
#ifndef MSDOS |
3215 |
|
XUngrabPointer (FRAME_X_DISPLAY (f), CurrentTime); |
3216 |
|
XUngrabKeyboard (FRAME_X_DISPLAY (f), CurrentTime); |
3217 |
|
#endif |
3218 |
|
XMenuDestroy (FRAME_X_DISPLAY (f), current_menu); |
3219 |
|
current_menu = 0; |
3220 |
|
} |
3221 |
|
|
3222 |
|
#ifdef HAVE_X_WINDOWS |
3223 |
|
/* Assume the mouse has moved out of the X window. |
3224 |
|
If it has actually moved in, we will get an EnterNotify. */ |
3225 |
|
x_mouse_leave (FRAME_X_DISPLAY_INFO (f)); |
3226 |
|
|
3227 |
|
/* State that no mouse buttons are now held. |
3228 |
|
(The oldXMenu code doesn't track this info for us.) |
3229 |
|
That is not necessarily true, but the fiction leads to reasonable |
3230 |
|
results, and it is a pain to ask which are actually held now. */ |
3231 |
|
FRAME_X_DISPLAY_INFO (f)->grabbed = 0; |
3232 |
|
|
3233 |
|
#endif /* HAVE_X_WINDOWS */ |
3234 |
|
|
3235 |
|
UNBLOCK_INPUT; |
3236 |
|
|
3237 |
|
return Qnil; |
3238 |
|
} |
3239 |
|
|
3240 |
|
|
3241 |
static Lisp_Object |
static Lisp_Object |
3242 |
xmenu_show (f, x, y, for_click, keymaps, title, error) |
xmenu_show (f, x, y, for_click, keymaps, title, error) |
3250 |
Window root; |
Window root; |
3251 |
XMenu *menu; |
XMenu *menu; |
3252 |
int pane, selidx, lpane, status; |
int pane, selidx, lpane, status; |
3253 |
Lisp_Object entry, pane_prefix; |
Lisp_Object entry, pane_prefix, frame; |
3254 |
char *datap; |
char *datap; |
3255 |
int ulx, uly, width, height; |
int ulx, uly, width, height; |
3256 |
int dispwidth, dispheight; |
int dispwidth, dispheight; |
3258 |
int maxwidth; |
int maxwidth; |
3259 |
int dummy_int; |
int dummy_int; |
3260 |
unsigned int dummy_uint; |
unsigned int dummy_uint; |
3261 |
|
int specpdl_count = SPECPDL_INDEX (); |
3262 |
|
|
3263 |
*error = 0; |
*error = 0; |
3264 |
if (menu_items_n_panes == 0) |
if (menu_items_n_panes == 0) |
3451 |
#ifndef MSDOS |
#ifndef MSDOS |
3452 |
XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f)); |
XMenuActivateSetWaitFunction (x_menu_wait_for_event, FRAME_X_DISPLAY (f)); |
3453 |
#endif |
#endif |
3454 |
|
|
3455 |
|
XSETFRAME (frame, f); |
3456 |
|
record_unwind_protect (pop_down_menu, frame); |
3457 |
|
|
3458 |
/* Help display under X won't work because XMenuActivate contains |
/* Help display under X won't work because XMenuActivate contains |
3459 |
a loop that doesn't give Emacs a chance to process it. */ |
a loop that doesn't give Emacs a chance to process it. */ |
3460 |
menu_help_frame = f; |
menu_help_frame = f; |
3461 |
|
current_menu = menu; |
3462 |
status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx, |
status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx, |
3463 |
x, y, ButtonReleaseMask, &datap, |
x, y, ButtonReleaseMask, &datap, |
3464 |
menu_help_callback); |
menu_help_callback); |
|
|
|
|
|
|
|
#ifdef HAVE_X_WINDOWS |
|
|
/* Assume the mouse has moved out of the X window. |
|
|
If it has actually moved in, we will get an EnterNotify. */ |
|
|
x_mouse_leave (FRAME_X_DISPLAY_INFO (f)); |
|
|
#endif |
|
3465 |
|
|
3466 |
switch (status) |
switch (status) |
3467 |
{ |
{ |
3512 |
entry = Qnil; |
entry = Qnil; |
3513 |
break; |
break; |
3514 |
} |
} |
|
XMenuDestroy (FRAME_X_DISPLAY (f), menu); |
|
3515 |
|
|
3516 |
#ifdef HAVE_X_WINDOWS |
unbind_to (specpdl_count, Qnil); |
|
/* State that no mouse buttons are now held. |
|
|
(The oldXMenu code doesn't track this info for us.) |
|
|
That is not necessarily true, but the fiction leads to reasonable |
|
|
results, and it is a pain to ask which are actually held now. */ |
|
|
FRAME_X_DISPLAY_INFO (f)->grabbed = 0; |
|
|
#endif |
|
3517 |
|
|
3518 |
return entry; |
return entry; |
3519 |
} |
} |