diff options
| author | Gerd Moellmann | 2000-07-13 14:07:45 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 2000-07-13 14:07:45 +0000 |
| commit | da8f73681d7947d4f100a69adefaa18a8c032f22 (patch) | |
| tree | 7c0f817b9d993993e377fde88d0ee97378196c0d | |
| parent | 5b50dae19cacd5b39e5f08a1381e6d527ebc688c (diff) | |
| download | emacs-da8f73681d7947d4f100a69adefaa18a8c032f22.tar.gz emacs-da8f73681d7947d4f100a69adefaa18a8c032f22.zip | |
(kbd_buffer_gcpro): Renamed from
kbd_buffer_frame_or_window. Now used for all Lisp objects
referenced from the input queue.
(kbd_buffer_store_event): Always use structure assignment for
copying input events. Record all Lisp objects referenced from
events in kbd_buffer_gcpro.
(kbd_buffer_get_event): Construct Lisp `help-echo' events
differently from input events. Test for prefix menu_bar_events
and TOOL_BAR_EVENTs differently. Reset all slots used by an input
event in kbd_buffer_gcpro to nil.
(make_lispy_event) <TOOL_BAR_EVENT>: Treat an input event whose
frame_or_window is equal to its arg member as prefix events.
(stuff_buffered_input): Reset all slots in kbd_buffer_gcpro
used by an input event to nil.
(init_keyboard): Use two times the size of the input queue
for kbd_buffer_gcpro.
(syms_of_keyboard): Likewise.
| -rw-r--r-- | src/keyboard.c | 123 |
1 files changed, 75 insertions, 48 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 6763f28dd84..b132075cf6b 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -453,9 +453,10 @@ int meta_key; | |||
| 453 | extern char *pending_malloc_warning; | 453 | extern char *pending_malloc_warning; |
| 454 | 454 | ||
| 455 | /* Circular buffer for pre-read keyboard input. */ | 455 | /* Circular buffer for pre-read keyboard input. */ |
| 456 | |||
| 456 | static struct input_event kbd_buffer[KBD_BUFFER_SIZE]; | 457 | static struct input_event kbd_buffer[KBD_BUFFER_SIZE]; |
| 457 | 458 | ||
| 458 | /* Vector to GCPRO the frames and windows mentioned in kbd_buffer. | 459 | /* Vector to GCPRO the Lisp objects referenced from kbd_buffer. |
| 459 | 460 | ||
| 460 | The interrupt-level event handlers will never enqueue an event on a | 461 | The interrupt-level event handlers will never enqueue an event on a |
| 461 | frame which is not in Vframe_list, and once an event is dequeued, | 462 | frame which is not in Vframe_list, and once an event is dequeued, |
| @@ -474,14 +475,16 @@ static struct input_event kbd_buffer[KBD_BUFFER_SIZE]; | |||
| 474 | Similar things happen when an event on a scroll bar is enqueued; the | 475 | Similar things happen when an event on a scroll bar is enqueued; the |
| 475 | window may be deleted while the event is in the queue. | 476 | window may be deleted while the event is in the queue. |
| 476 | 477 | ||
| 477 | So, we use this vector to protect the frame_or_window field in the | 478 | So, we use this vector to protect the Lisp_Objects in the event |
| 478 | event queue. That way, they'll be dequeued as dead frames or | 479 | queue. That way, they'll be dequeued as dead frames or windows, |
| 479 | windows, but still valid lisp objects. | 480 | but still valid Lisp objects. |
| 480 | 481 | ||
| 481 | If kbd_buffer[i].kind != no_event, then | 482 | If kbd_buffer[i].kind != no_event, then |
| 482 | (XVECTOR (kbd_buffer_frame_or_window)->contents[i] | 483 | |
| 483 | == kbd_buffer[i].frame_or_window. */ | 484 | AREF (kbd_buffer_gcpro, 2 * i) == kbd_buffer[i].frame_or_window. |
| 484 | static Lisp_Object kbd_buffer_frame_or_window; | 485 | AREF (kbd_buffer_gcpro, 2 * i + 1) == kbd_buffer[i].arg. */ |
| 486 | |||
| 487 | static Lisp_Object kbd_buffer_gcpro; | ||
| 485 | 488 | ||
| 486 | /* Pointer to next available character in kbd_buffer. | 489 | /* Pointer to next available character in kbd_buffer. |
| 487 | If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. | 490 | If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. |
| @@ -620,9 +623,11 @@ int flow_control; | |||
| 620 | point to the boundary of the region. But, if a command sets this | 623 | point to the boundary of the region. But, if a command sets this |
| 621 | valiable to non-nil, we suppress this point adjustment. This | 624 | valiable to non-nil, we suppress this point adjustment. This |
| 622 | variable is set to nil before reading a command. */ | 625 | variable is set to nil before reading a command. */ |
| 626 | |||
| 623 | Lisp_Object Vdisable_point_adjustment; | 627 | Lisp_Object Vdisable_point_adjustment; |
| 624 | 628 | ||
| 625 | /* If non-nil, always disable point adjustment. */ | 629 | /* If non-nil, always disable point adjustment. */ |
| 630 | |||
| 626 | Lisp_Object Vglobal_disable_point_adjustment; | 631 | Lisp_Object Vglobal_disable_point_adjustment; |
| 627 | 632 | ||
| 628 | 633 | ||
| @@ -3030,6 +3035,7 @@ kbd_buffer_store_event (event) | |||
| 3030 | { | 3035 | { |
| 3031 | sp->kind = no_event; | 3036 | sp->kind = no_event; |
| 3032 | sp->frame_or_window = Qnil; | 3037 | sp->frame_or_window = Qnil; |
| 3038 | sp->arg = Qnil; | ||
| 3033 | } | 3039 | } |
| 3034 | } | 3040 | } |
| 3035 | return; | 3041 | return; |
| @@ -3077,6 +3083,11 @@ kbd_buffer_store_event (event) | |||
| 3077 | Discard the event if it would fill the last slot. */ | 3083 | Discard the event if it would fill the last slot. */ |
| 3078 | if (kbd_fetch_ptr - 1 != kbd_store_ptr) | 3084 | if (kbd_fetch_ptr - 1 != kbd_store_ptr) |
| 3079 | { | 3085 | { |
| 3086 | int idx; | ||
| 3087 | |||
| 3088 | #if 0 /* The selection_request_event case looks bogus, and it's error | ||
| 3089 | prone to assign individual members for other events, in case | ||
| 3090 | the input_event structure is changed. --2000-07-13, gerd. */ | ||
| 3080 | struct input_event *sp = kbd_store_ptr; | 3091 | struct input_event *sp = kbd_store_ptr; |
| 3081 | sp->kind = event->kind; | 3092 | sp->kind = event->kind; |
| 3082 | if (event->kind == selection_request_event) | 3093 | if (event->kind == selection_request_event) |
| @@ -3087,20 +3098,25 @@ kbd_buffer_store_event (event) | |||
| 3087 | bcopy (event, (char *) sp, sizeof (*event)); | 3098 | bcopy (event, (char *) sp, sizeof (*event)); |
| 3088 | } | 3099 | } |
| 3089 | else | 3100 | else |
| 3101 | |||
| 3090 | { | 3102 | { |
| 3091 | sp->code = event->code; | 3103 | sp->code = event->code; |
| 3092 | sp->part = event->part; | 3104 | sp->part = event->part; |
| 3093 | sp->frame_or_window = event->frame_or_window; | 3105 | sp->frame_or_window = event->frame_or_window; |
| 3106 | sp->arg = event->arg; | ||
| 3094 | sp->modifiers = event->modifiers; | 3107 | sp->modifiers = event->modifiers; |
| 3095 | sp->x = event->x; | 3108 | sp->x = event->x; |
| 3096 | sp->y = event->y; | 3109 | sp->y = event->y; |
| 3097 | sp->timestamp = event->timestamp; | 3110 | sp->timestamp = event->timestamp; |
| 3098 | } | 3111 | } |
| 3099 | (XVECTOR (kbd_buffer_frame_or_window)->contents[kbd_store_ptr | 3112 | #else |
| 3100 | - kbd_buffer] | 3113 | *kbd_store_ptr = *event; |
| 3101 | = event->frame_or_window); | 3114 | #endif |
| 3102 | 3115 | ||
| 3103 | kbd_store_ptr++; | 3116 | idx = 2 * (kbd_store_ptr - kbd_buffer); |
| 3117 | ASET (kbd_buffer_gcpro, idx, event->frame_or_window); | ||
| 3118 | ASET (kbd_buffer_gcpro, idx + 1, event->arg); | ||
| 3119 | ++kbd_store_ptr; | ||
| 3104 | } | 3120 | } |
| 3105 | } | 3121 | } |
| 3106 | 3122 | ||
| @@ -3323,9 +3339,11 @@ kbd_buffer_get_event (kbp, used_mouse_menu) | |||
| 3323 | kbd_fetch_ptr = event + 1; | 3339 | kbd_fetch_ptr = event + 1; |
| 3324 | else if (event->kind == HELP_EVENT) | 3340 | else if (event->kind == HELP_EVENT) |
| 3325 | { | 3341 | { |
| 3326 | /* The car of event->frame_or_window is a frame, | 3342 | /* Event->frame_or_window is a frame, event->arg is the |
| 3327 | the cdr is the help to display. */ | 3343 | help to display. */ |
| 3328 | obj = Fcons (Qhelp_echo, event->frame_or_window); | 3344 | obj = Fcons (Qhelp_echo, |
| 3345 | Fcons (event->frame_or_window, | ||
| 3346 | event->arg)); | ||
| 3329 | kbd_fetch_ptr = event + 1; | 3347 | kbd_fetch_ptr = event + 1; |
| 3330 | } | 3348 | } |
| 3331 | else if (event->kind == FOCUS_IN_EVENT) | 3349 | else if (event->kind == FOCUS_IN_EVENT) |
| @@ -3373,24 +3391,28 @@ kbd_buffer_get_event (kbp, used_mouse_menu) | |||
| 3373 | 3391 | ||
| 3374 | if (NILP (obj)) | 3392 | if (NILP (obj)) |
| 3375 | { | 3393 | { |
| 3394 | int idx; | ||
| 3395 | |||
| 3376 | obj = make_lispy_event (event); | 3396 | obj = make_lispy_event (event); |
| 3397 | |||
| 3377 | #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) | 3398 | #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) |
| 3378 | /* If this was a menu selection, then set the flag to inhibit | 3399 | /* If this was a menu selection, then set the flag to inhibit |
| 3379 | writing to last_nonmenu_event. Don't do this if the event | 3400 | writing to last_nonmenu_event. Don't do this if the event |
| 3380 | we're returning is (menu-bar), though; that indicates the | 3401 | we're returning is (menu-bar), though; that indicates the |
| 3381 | beginning of the menu sequence, and we might as well leave | 3402 | beginning of the menu sequence, and we might as well leave |
| 3382 | that as the `event with parameters' for this selection. */ | 3403 | that as the `event with parameters' for this selection. */ |
| 3383 | if ((event->kind == menu_bar_event | 3404 | if (used_mouse_menu |
| 3384 | || event->kind == TOOL_BAR_EVENT) | 3405 | && !EQ (event->frame_or_window, event->arg) |
| 3385 | && !(CONSP (obj) && EQ (XCAR (obj), Qmenu_bar)) | 3406 | && (event->kind == MENU_BAR_EVENT |
| 3386 | && !(CONSP (obj) && EQ (XCAR (obj), Qtool_bar)) | 3407 | || event->kind == TOOL_BAR_EVENT)) |
| 3387 | && used_mouse_menu) | ||
| 3388 | *used_mouse_menu = 1; | 3408 | *used_mouse_menu = 1; |
| 3389 | #endif | 3409 | #endif |
| 3390 | 3410 | ||
| 3391 | /* Wipe out this event, to catch bugs. */ | 3411 | /* Wipe out this event, to catch bugs. */ |
| 3392 | event->kind = no_event; | 3412 | event->kind = no_event; |
| 3393 | XVECTOR (kbd_buffer_frame_or_window)->contents[event - kbd_buffer] = Qnil; | 3413 | idx = 2 * (event - kbd_buffer); |
| 3414 | ASET (kbd_buffer_gcpro, idx, Qnil); | ||
| 3415 | ASET (kbd_buffer_gcpro, idx + 1, Qnil); | ||
| 3394 | 3416 | ||
| 3395 | kbd_fetch_ptr = event + 1; | 3417 | kbd_fetch_ptr = event + 1; |
| 3396 | } | 3418 | } |
| @@ -4854,25 +4876,26 @@ make_lispy_event (event) | |||
| 4854 | #endif /* HAVE_MOUSE */ | 4876 | #endif /* HAVE_MOUSE */ |
| 4855 | 4877 | ||
| 4856 | #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) | 4878 | #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) |
| 4857 | case menu_bar_event: | 4879 | case MENU_BAR_EVENT: |
| 4858 | /* The event value is in the cdr of the frame_or_window slot. */ | 4880 | if (EQ (event->arg, event->frame_or_window)) |
| 4859 | if (!CONSP (event->frame_or_window)) | 4881 | /* This is the prefix key. We translate this to |
| 4860 | abort (); | 4882 | `(menu_bar)' because the code in keyboard.c for menu |
| 4861 | return XCDR (event->frame_or_window); | 4883 | events, which we use, relies on this. */ |
| 4884 | return Fcons (Qmenu_bar, Qnil); | ||
| 4885 | return event->arg; | ||
| 4862 | #endif | 4886 | #endif |
| 4863 | 4887 | ||
| 4864 | case TOOL_BAR_EVENT: | 4888 | case TOOL_BAR_EVENT: |
| 4865 | { | 4889 | if (EQ (event->arg, event->frame_or_window)) |
| 4866 | Lisp_Object key; | 4890 | /* This is the prefix key. We translate this to |
| 4867 | if (!CONSP (event->frame_or_window)) | 4891 | `(tool_bar)' because the code in keyboard.c for menu |
| 4868 | abort (); | 4892 | events, which we use, relies on this. */ |
| 4869 | key = XCDR (event->frame_or_window); | 4893 | return Fcons (Qtool_bar, Qnil); |
| 4870 | if (SYMBOLP (key)) | 4894 | else if (SYMBOLP (event->arg)) |
| 4871 | key = apply_modifiers (event->modifiers, key); | 4895 | return apply_modifiers (event->modifiers, event->arg); |
| 4872 | return key; | 4896 | return event->arg; |
| 4873 | } | 4897 | |
| 4874 | 4898 | case USER_SIGNAL_EVENT: | |
| 4875 | case user_signal: | ||
| 4876 | /* A user signal. */ | 4899 | /* A user signal. */ |
| 4877 | return *lispy_user_signals[event->code]; | 4900 | return *lispy_user_signals[event->code]; |
| 4878 | 4901 | ||
| @@ -5646,6 +5669,7 @@ record_asynch_buffer_change () | |||
| 5646 | 5669 | ||
| 5647 | event.kind = buffer_switch_event; | 5670 | event.kind = buffer_switch_event; |
| 5648 | event.frame_or_window = Qnil; | 5671 | event.frame_or_window = Qnil; |
| 5672 | event.arg = Qnil; | ||
| 5649 | 5673 | ||
| 5650 | #ifdef subprocesses | 5674 | #ifdef subprocesses |
| 5651 | /* We don't need a buffer-switch event unless Emacs is waiting for input. | 5675 | /* We don't need a buffer-switch event unless Emacs is waiting for input. |
| @@ -5807,6 +5831,7 @@ read_avail_input (expected) | |||
| 5807 | 5831 | ||
| 5808 | buf[i].code = cbuf[i]; | 5832 | buf[i].code = cbuf[i]; |
| 5809 | buf[i].frame_or_window = selected_frame; | 5833 | buf[i].frame_or_window = selected_frame; |
| 5834 | buf[i].arg = Qnil; | ||
| 5810 | } | 5835 | } |
| 5811 | } | 5836 | } |
| 5812 | 5837 | ||
| @@ -9214,7 +9239,7 @@ Also cancel any kbd macro being defined.") | |||
| 9214 | discard_tty_input (); | 9239 | discard_tty_input (); |
| 9215 | 9240 | ||
| 9216 | kbd_fetch_ptr = kbd_store_ptr; | 9241 | kbd_fetch_ptr = kbd_store_ptr; |
| 9217 | Ffillarray (kbd_buffer_frame_or_window, Qnil); | 9242 | Ffillarray (kbd_buffer_gcpro, Qnil); |
| 9218 | input_pending = 0; | 9243 | input_pending = 0; |
| 9219 | 9244 | ||
| 9220 | return Qnil; | 9245 | return Qnil; |
| @@ -9298,20 +9323,25 @@ stuff_buffered_input (stuffstring) | |||
| 9298 | stuff_char (*p++); | 9323 | stuff_char (*p++); |
| 9299 | stuff_char ('\n'); | 9324 | stuff_char ('\n'); |
| 9300 | } | 9325 | } |
| 9326 | |||
| 9301 | /* Anything we have read ahead, put back for the shell to read. */ | 9327 | /* Anything we have read ahead, put back for the shell to read. */ |
| 9302 | /* ?? What should this do when we have multiple keyboards?? | 9328 | /* ?? What should this do when we have multiple keyboards?? |
| 9303 | Should we ignore anything that was typed in at the "wrong" kboard? */ | 9329 | Should we ignore anything that was typed in at the "wrong" kboard? */ |
| 9304 | for (; kbd_fetch_ptr != kbd_store_ptr; kbd_fetch_ptr++) | 9330 | for (; kbd_fetch_ptr != kbd_store_ptr; kbd_fetch_ptr++) |
| 9305 | { | 9331 | { |
| 9332 | int idx; | ||
| 9333 | |||
| 9306 | if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) | 9334 | if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) |
| 9307 | kbd_fetch_ptr = kbd_buffer; | 9335 | kbd_fetch_ptr = kbd_buffer; |
| 9308 | if (kbd_fetch_ptr->kind == ascii_keystroke) | 9336 | if (kbd_fetch_ptr->kind == ascii_keystroke) |
| 9309 | stuff_char (kbd_fetch_ptr->code); | 9337 | stuff_char (kbd_fetch_ptr->code); |
| 9338 | |||
| 9310 | kbd_fetch_ptr->kind = no_event; | 9339 | kbd_fetch_ptr->kind = no_event; |
| 9311 | (XVECTOR (kbd_buffer_frame_or_window)->contents[kbd_fetch_ptr | 9340 | idx = 2 * (kbd_fetch_ptr - kbd_buffer); |
| 9312 | - kbd_buffer] | 9341 | ASET (kbd_buffer_gcpro, idx, Qnil); |
| 9313 | = Qnil); | 9342 | ASET (kbd_buffer_gcpro, idx + 1, Qnil); |
| 9314 | } | 9343 | } |
| 9344 | |||
| 9315 | input_pending = 0; | 9345 | input_pending = 0; |
| 9316 | #endif | 9346 | #endif |
| 9317 | #endif /* BSD_SYSTEM and not BSD4_1 */ | 9347 | #endif /* BSD_SYSTEM and not BSD4_1 */ |
| @@ -9692,8 +9722,7 @@ init_keyboard () | |||
| 9692 | recent_keys_index = 0; | 9722 | recent_keys_index = 0; |
| 9693 | kbd_fetch_ptr = kbd_buffer; | 9723 | kbd_fetch_ptr = kbd_buffer; |
| 9694 | kbd_store_ptr = kbd_buffer; | 9724 | kbd_store_ptr = kbd_buffer; |
| 9695 | kbd_buffer_frame_or_window | 9725 | kbd_buffer_gcpro = Fmake_vector (make_number (2 * KBD_BUFFER_SIZE), Qnil); |
| 9696 | = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil); | ||
| 9697 | #ifdef HAVE_MOUSE | 9726 | #ifdef HAVE_MOUSE |
| 9698 | do_mouse_tracking = Qnil; | 9727 | do_mouse_tracking = Qnil; |
| 9699 | #endif | 9728 | #endif |
| @@ -9711,10 +9740,9 @@ init_keyboard () | |||
| 9711 | init_kboard (current_kboard); | 9740 | init_kboard (current_kboard); |
| 9712 | 9741 | ||
| 9713 | if (initialized) | 9742 | if (initialized) |
| 9714 | Ffillarray (kbd_buffer_frame_or_window, Qnil); | 9743 | Ffillarray (kbd_buffer_gcpro, Qnil); |
| 9715 | 9744 | ||
| 9716 | kbd_buffer_frame_or_window | 9745 | kbd_buffer_gcpro = Fmake_vector (make_number (2 * KBD_BUFFER_SIZE), Qnil); |
| 9717 | = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil); | ||
| 9718 | if (!noninteractive && !read_socket_hook && NILP (Vwindow_system)) | 9746 | if (!noninteractive && !read_socket_hook && NILP (Vwindow_system)) |
| 9719 | { | 9747 | { |
| 9720 | signal (SIGINT, interrupt_signal); | 9748 | signal (SIGINT, interrupt_signal); |
| @@ -9973,9 +10001,8 @@ syms_of_keyboard () | |||
| 9973 | Fset (Qextended_command_history, Qnil); | 10001 | Fset (Qextended_command_history, Qnil); |
| 9974 | staticpro (&Qextended_command_history); | 10002 | staticpro (&Qextended_command_history); |
| 9975 | 10003 | ||
| 9976 | kbd_buffer_frame_or_window | 10004 | kbd_buffer_gcpro = Fmake_vector (make_number (2 * KBD_BUFFER_SIZE), Qnil); |
| 9977 | = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil); | 10005 | staticpro (&kbd_buffer_gcpro); |
| 9978 | staticpro (&kbd_buffer_frame_or_window); | ||
| 9979 | 10006 | ||
| 9980 | accent_key_syms = Qnil; | 10007 | accent_key_syms = Qnil; |
| 9981 | staticpro (&accent_key_syms); | 10008 | staticpro (&accent_key_syms); |