comparison src/event-stream.c @ 175:2d532a89d707 r20-3b14

Import from CVS: tag r20-3b14
author cvs
date Mon, 13 Aug 2007 09:50:14 +0200
parents 8eaf7971accc
children 6075d714658b
comparison
equal deleted inserted replaced
174:bb3568571b84 175:2d532a89d707
35 * 35 *
36 */ 36 */
37 37
38 #include <config.h> 38 #include <config.h>
39 #include "lisp.h" 39 #include "lisp.h"
40
41 #ifdef HAVE_X_WINDOWS
42 #include "console-x.h" /* for menu accelerators ... */
43 #include "gui-x.h"
44 #include "../lwlib/lwlib.h"
45 #else
46 #define lw_menu_active 0
47 #endif
40 48
41 #include "buffer.h" 49 #include "buffer.h"
42 #include "commands.h" 50 #include "commands.h"
43 #include "device.h" 51 #include "device.h"
44 #include "elhash.h" 52 #include "elhash.h"
190 198
191 /* Recent keys ring location; a vector of events or nil-s */ 199 /* Recent keys ring location; a vector of events or nil-s */
192 Lisp_Object Vrecent_keys_ring; 200 Lisp_Object Vrecent_keys_ring;
193 int recent_keys_ring_size; 201 int recent_keys_ring_size;
194 int recent_keys_ring_index; 202 int recent_keys_ring_index;
203
204 /* prefix key(s) that must match in order to activate menu.
205 This is ugly. fix me.
206 */
207 Lisp_Object Vmenu_accelerator_prefix;
208
209 /* list of modifier keys to match accelerator for top level menus */
210 Lisp_Object Vmenu_accelerator_modifiers;
211
212 /* whether menu accelerators are enabled */
213 Lisp_Object Vmenu_accelerator_enabled;
214
215 /* keymap for auxillary menu accelerator functions */
216 Lisp_Object Vmenu_accelerator_map;
217
218 Lisp_Object Qmenu_force;
219 Lisp_Object Qmenu_fallback;
220 Lisp_Object Qmenu_quit;
221 Lisp_Object Qmenu_up;
222 Lisp_Object Qmenu_down;
223 Lisp_Object Qmenu_left;
224 Lisp_Object Qmenu_right;
225 Lisp_Object Qmenu_select;
226 Lisp_Object Qmenu_escape;
227
228 /* this is in keymap.c */
229 extern Lisp_Object Fmake_keymap (Lisp_Object name);
195 230
196 #ifdef DEBUG_XEMACS 231 #ifdef DEBUG_XEMACS
197 int debug_emacs_events; 232 int debug_emacs_events;
198 #endif 233 #endif
199 234
650 /* Message turns off echoing unless more keystrokes turn it on again. */ 685 /* Message turns off echoing unless more keystrokes turn it on again. */
651 if (echo_area_active (f) && !EQ (Qcommand, echo_area_status (f))) 686 if (echo_area_active (f) && !EQ (Qcommand, echo_area_status (f)))
652 return; 687 return;
653 688
654 if (minibuf_level == 0 689 if (minibuf_level == 0
655 && echo_keystrokes > 0) 690 && echo_keystrokes > 0
691 && !lw_menu_active)
656 { 692 {
657 if (!no_snooze) 693 if (!no_snooze)
658 { 694 {
659 /* #### C-g here will cause QUIT. Setting dont_check_for_quit 695 /* #### C-g here will cause QUIT. Setting dont_check_for_quit
660 doesn't work. See check_quit. */ 696 doesn't work. See check_quit. */
2161 { 2197 {
2162 default: 2198 default:
2163 goto RETURN; 2199 goto RETURN;
2164 case button_release_event: 2200 case button_release_event:
2165 case misc_user_event: 2201 case misc_user_event:
2202 /* don't echo menu accelerator keys */
2203 reset_key_echo (command_builder, 1);
2166 goto EXECUTE_KEY; 2204 goto EXECUTE_KEY;
2167 case button_press_event: /* key or mouse input can trigger prompting */ 2205 case button_press_event: /* key or mouse input can trigger prompting */
2168 goto STORE_AND_EXECUTE_KEY; 2206 goto STORE_AND_EXECUTE_KEY;
2169 case key_press_event: /* any key input can trigger autosave */ 2207 case key_press_event: /* any key input can trigger autosave */
2170 break; 2208 break;
2531 /* We execute the event even if it's ours, and notice that it's 2569 /* We execute the event even if it's ours, and notice that it's
2532 happened above. */ 2570 happened above. */
2533 case pointer_motion_event: 2571 case pointer_motion_event:
2534 case magic_event: 2572 case magic_event:
2535 { 2573 {
2536 EXECUTE_INTERNAL:
2537 execute_internal_event (event); 2574 execute_internal_event (event);
2538 break; 2575 break;
2539 } 2576 }
2540 default: 2577 default:
2541 { 2578 {
2601 happened above. */ 2638 happened above. */
2602 case process_event: 2639 case process_event:
2603 case pointer_motion_event: 2640 case pointer_motion_event:
2604 case magic_event: 2641 case magic_event:
2605 { 2642 {
2606 EXECUTE_INTERNAL:
2607 execute_internal_event (event); 2643 execute_internal_event (event);
2608 break; 2644 break;
2609 } 2645 }
2610 default: 2646 default:
2611 { 2647 {
2743 case timeout_event: 2779 case timeout_event:
2744 /* We execute the event even if it's ours, and notice that it's 2780 /* We execute the event even if it's ours, and notice that it's
2745 happened above. */ 2781 happened above. */
2746 default: 2782 default:
2747 { 2783 {
2748 EXECUTE_INTERNAL:
2749 execute_internal_event (event); 2784 execute_internal_event (event);
2750 break; 2785 break;
2751 } 2786 }
2752 } 2787 }
2753 } 2788 }
2984 return Qnil; 3019 return Qnil;
2985 3020
2986 return event_binding (event0, 1); 3021 return event_binding (event0, 1);
2987 } 3022 }
2988 3023
3024 #ifdef HAVE_X_WINDOWS
3025 static void
3026 menu_move_up (void)
3027 {
3028 widget_value *current, *prev;
3029 widget_value *entries;
3030
3031 current = lw_get_entries (False);
3032 entries = lw_get_entries (True);
3033 prev = NULL;
3034 if (current != entries)
3035 {
3036 while (entries != current)
3037 {
3038 if (entries->name /*&& entries->enabled*/) prev = entries;
3039 entries = entries->next;
3040 assert (entries);
3041 }
3042 }
3043
3044 if (!prev)
3045 /* move to last item */
3046 {
3047 while (entries->next)
3048 {
3049 if (entries->name /*&& entries->enabled*/) prev = entries;
3050 entries = entries->next;
3051 }
3052 if (prev)
3053 {
3054 if (entries->name /*&& entries->enabled*/)
3055 prev = entries;
3056 }
3057 else
3058 {
3059 /* no selectable items in this menu, pop up to previous level */
3060 lw_pop_menu ();
3061 return;
3062 }
3063 }
3064 lw_set_item (prev);
3065 }
3066
3067 static void
3068 menu_move_down (void)
3069 {
3070 widget_value *current;
3071 widget_value *new;
3072
3073 current = lw_get_entries (False);
3074 new = current;
3075
3076 while (new->next)
3077 {
3078 new = new->next;
3079 if (new->name /*&& new->enabled*/) break;
3080 }
3081
3082 if (new==current||!(new->name/*||new->enabled*/))
3083 {
3084 new = lw_get_entries (True);
3085 while (new!=current)
3086 {
3087 if (new->name /*&& new->enabled*/) break;
3088 new = new->next;
3089 }
3090 if (new==current&&!(new->name /*|| new->enabled*/))
3091 {
3092 lw_pop_menu ();
3093 return;
3094 }
3095 }
3096
3097 lw_set_item (new);
3098 }
3099
3100 static void
3101 menu_move_left (void)
3102 {
3103 int level = lw_menu_level ();
3104 int l = level;
3105 widget_value *current;
3106
3107 while (level >= 3)
3108 {
3109 --level;
3110 lw_pop_menu ();
3111 }
3112 menu_move_up ();
3113 current = lw_get_entries (False);
3114 if (l > 2 && current->contents)
3115 lw_push_menu (current->contents);
3116 }
3117
3118 static void
3119 menu_move_right (void)
3120 {
3121 int level = lw_menu_level ();
3122 int l = level;
3123 widget_value *current;
3124
3125 while (level >= 3)
3126 {
3127 --level;
3128 lw_pop_menu ();
3129 }
3130 menu_move_down ();
3131 current = lw_get_entries (False);
3132 if (l > 2 && current->contents)
3133 lw_push_menu (current->contents);
3134 }
3135
3136 static void
3137 menu_select_item (widget_value *val)
3138 {
3139 if (val == NULL)
3140 val = lw_get_entries (False);
3141
3142 /* is match a submenu? */
3143
3144 if (val->contents)
3145 {
3146 /* enter the submenu */
3147
3148 lw_set_item (val);
3149 lw_push_menu (val->contents);
3150 }
3151 else
3152 {
3153 /* Execute the menu entry by calling the menu's `select'
3154 callback function
3155 */
3156 lw_kill_menus (val);
3157 }
3158 }
3159
3160 static Lisp_Object
3161 command_builder_operate_menu_accelerator (struct command_builder *builder)
3162 {
3163 /* this function can GC */
3164
3165 struct console *con = XCONSOLE (Vselected_console);
3166 Lisp_Object evee = builder->most_current_event;
3167 Lisp_Object binding;
3168 widget_value *entries;
3169
3170 extern int lw_menu_accelerate; /* lwlib.c */
3171
3172 #if 0
3173 {
3174 int i;
3175 Lisp_Object t;
3176 char buf[50];
3177
3178 t = builder->current_events;
3179 i = 0;
3180 while (!NILP (t))
3181 {
3182 i++;
3183 sprintf(buf,"OPERATE (%d): ",i);
3184 write_c_string (buf,Qexternal_debugging_output);
3185 print_internal (t, Qexternal_debugging_output, 1);
3186 write_c_string ("\n", Qexternal_debugging_output);
3187 t = XEVENT_NEXT (t);
3188 }
3189 }
3190 #endif
3191
3192 /* menu accelerator keys don't go into keyboard macros */
3193 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro))
3194 con->kbd_macro_ptr = con->kbd_macro_end;
3195
3196 /* don't echo menu accelerator keys */
3197 /*reset_key_echo (builder, 1);*/
3198
3199 if (!lw_menu_accelerate)
3200 {
3201 /* `convert' mouse display to keyboard display
3202 by entering the open submenu
3203 */
3204 entries = lw_get_entries (False);
3205 if (entries->contents)
3206 {
3207 lw_push_menu (entries->contents);
3208 lw_display_menu (CurrentTime);
3209 }
3210 }
3211
3212 /* compare event to the current menu accelerators */
3213
3214 entries=lw_get_entries (True);
3215
3216 while (entries)
3217 {
3218 Lisp_Object accel;
3219 VOID_TO_LISP (accel, entries->accel);
3220 if (entries->name && !NILP (accel))
3221 {
3222 if (event_matches_key_specifier_p (XEVENT (evee), accel))
3223 {
3224 /* a match! */
3225
3226 menu_select_item (entries);
3227
3228 if (lw_menu_active) lw_display_menu (CurrentTime);
3229
3230 reset_this_command_keys (Vselected_console, 1);
3231 /*reset_command_builder_event_chain (builder);*/
3232 return Vmenu_accelerator_map;
3233 }
3234 }
3235 entries = entries->next;
3236 }
3237
3238 /* try to look up event in menu-accelerator-map */
3239
3240 binding = event_binding_in (evee, Vmenu_accelerator_map, 1);
3241
3242 if (NILP (binding))
3243 {
3244 /* beep at user for undefined key */
3245 return Qnil;
3246 }
3247 else
3248 {
3249 if (EQ (binding, Qmenu_quit))
3250 {
3251 /* turn off menus and set quit flag */
3252 lw_kill_menus (NULL);
3253 Vquit_flag = Qt;
3254 }
3255 else if (EQ (binding, Qmenu_up))
3256 {
3257 int level = lw_menu_level ();
3258 if (level > 2)
3259 menu_move_up ();
3260 }
3261 else if (EQ (binding, Qmenu_down))
3262 {
3263 int level = lw_menu_level ();
3264 if (level > 2)
3265 menu_move_down ();
3266 else
3267 menu_select_item (NULL);
3268 }
3269 else if (EQ (binding, Qmenu_left))
3270 {
3271 int level = lw_menu_level ();
3272 if (level > 3)
3273 {
3274 lw_pop_menu ();
3275 lw_display_menu (CurrentTime);
3276 }
3277 else
3278 menu_move_left ();
3279 }
3280 else if (EQ (binding, Qmenu_right))
3281 {
3282 int level = lw_menu_level ();
3283 if (level > 2 &&
3284 lw_get_entries (False)->contents)
3285 {
3286 widget_value *current = lw_get_entries (False);
3287 if (current->contents)
3288 menu_select_item (NULL);
3289 }
3290 else
3291 menu_move_right ();
3292 }
3293 else if (EQ (binding, Qmenu_select))
3294 menu_select_item (NULL);
3295 else if (EQ (binding, Qmenu_escape))
3296 {
3297 int level = lw_menu_level ();
3298
3299 if (level > 2)
3300 {
3301 lw_pop_menu ();
3302 lw_display_menu (CurrentTime);
3303 }
3304 else
3305 {
3306 /* turn off menus quietly */
3307 lw_kill_menus (NULL);
3308 }
3309 }
3310 else if (KEYMAPP (binding))
3311 {
3312 /* prefix key */
3313 reset_this_command_keys (Vselected_console, 1);
3314 /*reset_command_builder_event_chain (builder);*/
3315 return binding;
3316 }
3317 else
3318 {
3319 /* turn off menus and execute binding */
3320 lw_kill_menus (NULL);
3321 reset_this_command_keys (Vselected_console, 1);
3322 /*reset_command_builder_event_chain (builder);*/
3323 return binding;
3324 }
3325 }
3326
3327 if (lw_menu_active) lw_display_menu (CurrentTime);
3328
3329 reset_this_command_keys (Vselected_console, 1);
3330 /*reset_command_builder_event_chain (builder);*/
3331
3332 return Vmenu_accelerator_map;
3333 }
3334
3335 static Lisp_Object
3336 menu_accelerator_junk_on_error (Lisp_Object errordata, Lisp_Object ignored)
3337 {
3338 Vmenu_accelerator_prefix = Qnil;
3339 Vmenu_accelerator_modifiers = Qnil;
3340 Vmenu_accelerator_enabled = Qnil;
3341 if (!NILP (errordata))
3342 {
3343 Lisp_Object args[2];
3344
3345 args[0] = build_string ("Error in menu accelerators (setting to nil)");
3346 /* #### This should call
3347 (with-output-to-string (display-error errordata))
3348 but that stuff is all in Lisp currently. */
3349 args[1] = errordata;
3350 warn_when_safe_lispobj
3351 (Qerror, Qwarning,
3352 emacs_doprnt_string_lisp ((CONST Bufbyte *) "%s: %s",
3353 Qnil, -1, 2, args));
3354 }
3355
3356 return Qnil;
3357 }
3358
3359 static Lisp_Object
3360 menu_accelerator_safe_compare (Lisp_Object event0)
3361 {
3362 if (CONSP (Vmenu_accelerator_prefix))
3363 {
3364 Lisp_Object t;
3365 t=Vmenu_accelerator_prefix;
3366 while (!NILP (t)
3367 && !NILP (event0)
3368 && event_matches_key_specifier_p (XEVENT (event0), Fcar (t)))
3369 {
3370 t = Fcdr (t);
3371 event0 = XEVENT_NEXT (event0);
3372 }
3373 if (!NILP (t))
3374 return Qnil;
3375 }
3376 else if (NILP (event0))
3377 return Qnil;
3378 else if (event_matches_key_specifier_p (XEVENT (event0), Vmenu_accelerator_prefix))
3379 event0 = XEVENT_NEXT (event0);
3380 else
3381 return Qnil;
3382 return event0;
3383 }
3384
3385 static Lisp_Object
3386 menu_accelerator_safe_mod_compare (Lisp_Object cons)
3387 {
3388 return (event_matches_key_specifier_p (XEVENT (XCAR (cons)), XCDR (cons))
3389 ? Qt
3390 : Qnil);
3391 }
3392
3393 static Lisp_Object
3394 command_builder_find_menu_accelerator (struct command_builder *builder)
3395 {
3396 /* this function can GC */
3397 Lisp_Object event0 = builder->current_events;
3398 struct console *con = XCONSOLE (Vselected_console);
3399 struct frame *f = XFRAME (CONSOLE_SELECTED_FRAME (con));
3400 Widget menubar_widget;
3401
3402 /* compare entries in event0 against the menu prefix */
3403
3404 if ((!CONSOLE_X_P (XCONSOLE (builder->console))) || NILP (event0) ||
3405 XEVENT (event0)->event_type != key_press_event)
3406 return Qnil;
3407
3408 if (!NILP (Vmenu_accelerator_prefix))
3409 {
3410 event0 = condition_case_1 (Qerror,
3411 menu_accelerator_safe_compare,
3412 event0,
3413 menu_accelerator_junk_on_error,
3414 Qnil);
3415 }
3416
3417 if (NILP (event0))
3418 return Qnil;
3419
3420 menubar_widget = FRAME_X_MENUBAR_WIDGET (f);
3421 if (menubar_widget
3422 && CONSP (Vmenu_accelerator_modifiers))
3423 {
3424 Lisp_Object fake;
3425 Lisp_Object last;
3426 struct gcpro gcpro1;
3427 Lisp_Object matchp;
3428
3429 widget_value *val;
3430 LWLIB_ID id = XPOPUP_DATA (f->menubar_data)->id;
3431
3432 val = lw_get_all_values (id);
3433 if (val)
3434 {
3435 val = val->contents;
3436
3437 fake = Fcopy_sequence (Vmenu_accelerator_modifiers);
3438 last = fake;
3439
3440 while (!NILP (Fcdr (last)))
3441 last = Fcdr (last);
3442
3443 Fsetcdr (last, Fcons (Qnil, Qnil));
3444 last = Fcdr (last);
3445 }
3446
3447 fake = Fcons (Qnil, fake);
3448
3449 GCPRO1 (fake);
3450
3451 while (val)
3452 {
3453 Lisp_Object accel;
3454 VOID_TO_LISP (accel, val->accel);
3455 if (val->name && !NILP (accel))
3456 {
3457 Fsetcar (last, accel);
3458 Fsetcar (fake, event0);
3459 matchp = condition_case_1 (Qerror,
3460 menu_accelerator_safe_mod_compare,
3461 fake,
3462 menu_accelerator_junk_on_error,
3463 Qnil);
3464 if (!NILP (matchp))
3465 {
3466 /* we found one! */
3467
3468 lw_set_menu (menubar_widget, val);
3469 /* yah - yet another hack.
3470 pretend emacs timestamp is the same as an X timestamp,
3471 which for the moment it is. (read events.h)
3472 */
3473 lw_map_menu (XEVENT (event0)->timestamp);
3474
3475 if (val->contents)
3476 lw_push_menu (val->contents);
3477
3478 lw_display_menu (CurrentTime);
3479
3480 /* menu accelerator keys don't go into keyboard macros */
3481 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro))
3482 con->kbd_macro_ptr = con->kbd_macro_end;
3483
3484 /* don't echo menu accelerator keys */
3485 /*reset_key_echo (builder, 1);*/
3486 reset_this_command_keys (Vselected_console, 1);
3487 UNGCPRO;
3488
3489 return Vmenu_accelerator_map;
3490 }
3491 }
3492
3493 val = val->next;
3494 }
3495
3496 UNGCPRO;
3497 }
3498 return Qnil;
3499 }
3500
3501 void
3502 event_menu_accelerate ()
3503 {
3504 struct console *con = XCONSOLE (Vselected_console);
3505 struct frame *f = XFRAME (CONSOLE_SELECTED_FRAME (con));
3506 LWLIB_ID id = XPOPUP_DATA (f->menubar_data)->id;
3507 widget_value *val = lw_get_all_values (id);
3508
3509 val = val->contents;
3510 lw_set_menu (FRAME_X_MENUBAR_WIDGET (f), val);
3511 lw_map_menu (CurrentTime);
3512
3513 lw_display_menu (CurrentTime);
3514
3515 /* menu accelerator keys don't go into keyboard macros */
3516 if (!NILP (con->defining_kbd_macro) && NILP (Vexecuting_macro))
3517 con->kbd_macro_ptr = con->kbd_macro_end;
3518 }
3519 #endif /* HAVE_X_WINDOWS */
3520
2989 /* See if we can do function-key-map or key-translation-map translation 3521 /* See if we can do function-key-map or key-translation-map translation
2990 on the current events in the command builder. If so, do this, and 3522 on the current events in the command builder. If so, do this, and
2991 return the resulting binding, if any. */ 3523 return the resulting binding, if any. */
2992 3524
2993 static Lisp_Object 3525 static Lisp_Object
3107 Lisp_Object fn = XEVENT (evee)->event.eval.function; 3639 Lisp_Object fn = XEVENT (evee)->event.eval.function;
3108 Lisp_Object arg = XEVENT (evee)->event.eval.object; 3640 Lisp_Object arg = XEVENT (evee)->event.eval.object;
3109 return list2 (fn, arg); 3641 return list2 (fn, arg);
3110 } 3642 }
3111 3643
3112 else if (XEVENT_TYPE (evee) == misc_user_event) 3644
3645 if (XEVENT_TYPE (evee) == misc_user_event)
3113 return Qnil; 3646 return Qnil;
3114 3647
3115 result = command_builder_find_leaf_1 (builder); 3648 /* if we're currently in a menu accelerator, check there for further events */
3649 #ifdef HAVE_X_WINDOWS
3650 if (lw_menu_active)
3651 {
3652 result = command_builder_operate_menu_accelerator (builder);
3653 return result;
3654 }
3655 else
3656 {
3657 result=Qnil;
3658 if (EQ (Vmenu_accelerator_enabled, Qmenu_force))
3659 result = command_builder_find_menu_accelerator (builder);
3660 if (NILP (result))
3661 #endif
3662 result = command_builder_find_leaf_1 (builder);
3663 #ifdef HAVE_X_WINDOWS
3664 if (NILP (result)
3665 && EQ (Vmenu_accelerator_enabled, Qmenu_fallback))
3666 result = command_builder_find_menu_accelerator (builder);
3667 }
3668 #endif
3116 3669
3117 /* Check to see if we have a potential function-key-map match. */ 3670 /* Check to see if we have a potential function-key-map match. */
3118 if (NILP (result)) 3671 if (NILP (result))
3119 { 3672 {
3120 result = munge_keymap_translate (builder, MUNGE_ME_FUNCTION_KEY, 0); 3673 result = munge_keymap_translate (builder, MUNGE_ME_FUNCTION_KEY, 0);
3586 struct gcpro gcpro1; 4139 struct gcpro gcpro1;
3587 GCPRO1 (leaf); 4140 GCPRO1 (leaf);
3588 4141
3589 if (KEYMAPP (leaf)) 4142 if (KEYMAPP (leaf))
3590 { 4143 {
3591 Lisp_Object prompt = Fkeymap_prompt (leaf, Qt); 4144 if (!lw_menu_active)
3592 if (STRINGP (prompt))
3593 { 4145 {
3594 /* Append keymap prompt to key echo buffer */ 4146 Lisp_Object prompt = Fkeymap_prompt (leaf, Qt);
3595 int buf_index = command_builder->echo_buf_index; 4147 if (STRINGP (prompt))
3596 Bytecount len = XSTRING_LENGTH (prompt);
3597
3598 if (len + buf_index + 1 <= command_builder->echo_buf_length)
3599 { 4148 {
3600 Bufbyte *echo = command_builder->echo_buf + buf_index; 4149 /* Append keymap prompt to key echo buffer */
3601 memcpy (echo, XSTRING_DATA (prompt), len); 4150 int buf_index = command_builder->echo_buf_index;
3602 echo[len] = 0; 4151 Bytecount len = XSTRING_LENGTH (prompt);
4152
4153 if (len + buf_index + 1 <= command_builder->echo_buf_length)
4154 {
4155 Bufbyte *echo = command_builder->echo_buf + buf_index;
4156 memcpy (echo, XSTRING_DATA (prompt), len);
4157 echo[len] = 0;
4158 }
4159 maybe_echo_keys (command_builder, 1);
3603 } 4160 }
3604 maybe_echo_keys (command_builder, 1); 4161 else
4162 maybe_echo_keys (command_builder, 0);
3605 } 4163 }
3606 else 4164 else if (!NILP (Vquit_flag)) {
3607 maybe_echo_keys (command_builder, 0); 4165 Lisp_Object event = Fmake_event();
4166 struct Lisp_Event *e = XEVENT (event);
4167 struct console *con;
4168 int ch;
4169
4170 /* if quit happened during menu acceleration, pretend we read it */
4171 con = XCONSOLE (Fselected_console ());
4172
4173 ch = CONSOLE_QUIT_CHAR (con);
4174
4175 character_to_event (ch, e, con, 1);
4176 e->channel = make_console (con);
4177
4178 enqueue_command_event (event);
4179 Vquit_flag = Qnil;
4180 }
3608 } 4181 }
3609 else if (!NILP (leaf)) 4182 else if (!NILP (leaf))
3610 { 4183 {
3611 if (EQ (Qcommand, echo_area_status (f)) 4184 if (EQ (Qcommand, echo_area_status (f))
3612 && command_builder->echo_buf_index > 0) 4185 && command_builder->echo_buf_index > 0)
4027 Vthis_command = XEVENT (event)->event.eval.function; 4600 Vthis_command = XEVENT (event)->event.eval.function;
4028 else 4601 else
4029 /* Huh? */ 4602 /* Huh? */
4030 Vthis_command = Qnil; 4603 Vthis_command = Qnil;
4031 4604
4605 /* clear the echo area */
4606 reset_key_echo (command_builder, 1);
4607
4032 command_builder->self_insert_countdown = 0; 4608 command_builder->self_insert_countdown = 0;
4033 if (NILP (XCONSOLE (console)->prefix_arg) 4609 if (NILP (XCONSOLE (console)->prefix_arg)
4034 && NILP (Vexecuting_macro) 4610 && NILP (Vexecuting_macro)
4035 && !EQ (minibuf_window, Fselected_window (Qnil))) 4611 && !EQ (minibuf_window, Fselected_window (Qnil)))
4036 Fundo_boundary (); 4612 Fundo_boundary ();
4296 #endif 4872 #endif
4297 defsymbol (&Qretry_undefined_key_binding_unshifted, 4873 defsymbol (&Qretry_undefined_key_binding_unshifted,
4298 "retry-undefined-key-binding-unshifted"); 4874 "retry-undefined-key-binding-unshifted");
4299 defsymbol (&Qauto_show_make_point_visible, 4875 defsymbol (&Qauto_show_make_point_visible,
4300 "auto-show-make-point-visible"); 4876 "auto-show-make-point-visible");
4877
4878 defsymbol (&Qmenu_force, "menu-force");
4879 defsymbol (&Qmenu_fallback, "menu-fallback");
4880
4881 defsymbol (&Qmenu_quit, "menu-quit");
4882 defsymbol (&Qmenu_up, "menu-up");
4883 defsymbol (&Qmenu_down, "menu-down");
4884 defsymbol (&Qmenu_left, "menu-left");
4885 defsymbol (&Qmenu_right, "menu-right");
4886 defsymbol (&Qmenu_select, "menu-select");
4887 defsymbol (&Qmenu_escape, "menu-escape");
4301 } 4888 }
4302 4889
4303 void 4890 void
4304 vars_of_event_stream (void) 4891 vars_of_event_stream (void)
4305 { 4892 {
4614 controlling terminal or the signal was 5201 controlling terminal or the signal was
4615 explicitly sent to the XEmacs process). 5202 explicitly sent to the XEmacs process).
4616 */ ); 5203 */ );
4617 debug_emacs_events = 0; 5204 debug_emacs_events = 0;
4618 #endif 5205 #endif
5206
5207 DEFVAR_LISP("menu-accelerator-prefix", &Vmenu_accelerator_prefix /*
5208 Prefix key(s) that must be typed before menu accelerators will be activated.
5209 Set this to a value acceptable by define-key.
5210 */ );
5211 Vmenu_accelerator_prefix = Qnil;
5212
5213 DEFVAR_LISP ("menu-accelerator-modifiers", &Vmenu_accelerator_modifiers /*
5214 Modifier keys which must be pressed to get to the top level menu accelerators.
5215 This is a list of modifier key symbols. All modifier keys must be held down
5216 while a valid menu accelerator key is pressed in order for the top level
5217 menu to become active.
5218
5219 See also menu-accelerator-enabled and menu-accelerator-prefix.
5220 */ );
5221 Vmenu_accelerator_modifiers = list1 (Qmeta);
5222
5223 DEFVAR_LISP ("menu-accelerator-enabled", &Vmenu_accelerator_enabled /*
5224 Whether menu accelerator keys can cause the menubar to become active.
5225 If 'menu-force or 'menu-fallback, then menu accelerator keys can
5226 be used to activate the top level menu. Once the menubar becomes active, the
5227 accelerator keys can be used regardless of the value of this variable.
5228
5229 menu-force is used to indicate that the menu accelerator key takes
5230 precedence over bindings in the current keymap(s). menu-fallback means
5231 that bindings in the current keymap take precedence over menu accelerator keys.
5232 Thus a top level menu with an accelerator of \"T\" would be activated on a
5233 keypress of Meta-t if menu-accelerator-enabled is menu-force.
5234 However, if menu-accelerator-enabled is menu-fallback, then
5235 Meta-t will not activate the menubar and will instead run the function
5236 transpose-words, to which it is normally bound.
5237
5238 See also menu-accelerator-modifiers and menu-accelerator-prefix.
5239 */ );
5240 Vmenu_accelerator_enabled = Qnil;
4619 } 5241 }
4620 5242
4621 void 5243 void
4622 complex_vars_of_event_stream (void) 5244 complex_vars_of_event_stream (void)
4623 { 5245 {
4624 Vkeyboard_translate_table = Fmake_hashtable (make_int (100), Qnil); 5246 Vkeyboard_translate_table = Fmake_hashtable (make_int (100), Qnil);
5247
5248 DEFVAR_LISP ("menu-accelerator-map", &Vmenu_accelerator_map /*
5249 Keymap for use when the menubar is active.
5250 The actions menu-quit, menu-up, menu-down, menu-left, menu-right,
5251 menu-select and menu-escape can be mapped to keys in this map.
5252
5253 menu-quit Immediately deactivate the menubar and any open submenus without
5254 selecting an item.
5255 menu-up Move the menu cursor up one row in the current menu. If the
5256 move extends past the top of the menu, wrap around to the bottom.
5257 menu-down Move the menu cursor down one row in the current menu. If the
5258 move extends past the bottom of the menu, wrap around to the top.
5259 If executed while the cursor is in the top level menu, move down
5260 into the selected menu.
5261 menu-left Move the cursor from a submenu into the parent menu. If executed
5262 while the cursor is in the top level menu, move the cursor to the
5263 left. If the move extends past the left edge of the menu, wrap
5264 around to the right edge.
5265 menu-right Move the cursor into a submenu. If the cursor is located in the
5266 top level menu or is not currently on a submenu heading, then move
5267 the cursor to the next top level menu entry. If the move extends
5268 past the right edge of the menu, wrap around to the left edge.
5269 menu-select Activate the item under the cursor. If the cursor is located on
5270 a submenu heading, then move the cursor into the submenu.
5271 menu-escape Pop up to the next level of menus. Moves from a submenu into its
5272 parent menu. From the top level menu, this deactivates the
5273 menubar.
5274
5275 This keymap can also contain normal key-command bindings, in which case the
5276 menubar is deactivated and the corresponding command is executed.
5277
5278 The action bindings used by the menu accelerator code are designed to mimic
5279 the actions of menu traversal keys in a commonly used PC operating system.
5280 */ );
5281 Vmenu_accelerator_map = Fmake_keymap(Qnil);
4625 } 5282 }
4626 5283
4627 void 5284 void
4628 init_event_stream (void) 5285 init_event_stream (void)
4629 { 5286 {