aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/keyboard.c123
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;
453extern char *pending_malloc_warning; 453extern char *pending_malloc_warning;
454 454
455/* Circular buffer for pre-read keyboard input. */ 455/* Circular buffer for pre-read keyboard input. */
456
456static struct input_event kbd_buffer[KBD_BUFFER_SIZE]; 457static 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.
484static Lisp_Object kbd_buffer_frame_or_window; 485 AREF (kbd_buffer_gcpro, 2 * i + 1) == kbd_buffer[i].arg. */
486
487static 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
623Lisp_Object Vdisable_point_adjustment; 627Lisp_Object Vdisable_point_adjustment;
624 628
625/* If non-nil, always disable point adjustment. */ 629/* If non-nil, always disable point adjustment. */
630
626Lisp_Object Vglobal_disable_point_adjustment; 631Lisp_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);