aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/keyboard.c181
1 files changed, 72 insertions, 109 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index be727a6549a..59acb2dd083 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -92,7 +92,7 @@ volatile int interrupt_input_blocked;
92 The maybe_quit function checks this. */ 92 The maybe_quit function checks this. */
93volatile bool pending_signals; 93volatile bool pending_signals;
94 94
95#define KBD_BUFFER_SIZE 4096 95enum { KBD_BUFFER_SIZE = 4096 };
96 96
97KBOARD *initial_kboard; 97KBOARD *initial_kboard;
98KBOARD *current_kboard; 98KBOARD *current_kboard;
@@ -286,15 +286,11 @@ static bool input_was_pending;
286static union buffered_input_event kbd_buffer[KBD_BUFFER_SIZE]; 286static union buffered_input_event kbd_buffer[KBD_BUFFER_SIZE];
287 287
288/* Pointer to next available character in kbd_buffer. 288/* Pointer to next available character in kbd_buffer.
289 If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. 289 If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. */
290 This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the
291 next available char is in kbd_buffer[0]. */
292static union buffered_input_event *kbd_fetch_ptr; 290static union buffered_input_event *kbd_fetch_ptr;
293 291
294/* Pointer to next place to store character in kbd_buffer. This 292/* Pointer to next place to store character in kbd_buffer. */
295 may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the next 293static union buffered_input_event *kbd_store_ptr;
296 character should go in kbd_buffer[0]. */
297static union buffered_input_event *volatile kbd_store_ptr;
298 294
299/* The above pair of variables forms a "queue empty" flag. When we 295/* The above pair of variables forms a "queue empty" flag. When we
300 enqueue a non-hook event, we increment kbd_store_ptr. When we 296 enqueue a non-hook event, we increment kbd_store_ptr. When we
@@ -302,8 +298,7 @@ static union buffered_input_event *volatile kbd_store_ptr;
302 there is input available if the two pointers are not equal. 298 there is input available if the two pointers are not equal.
303 299
304 Why not just have a flag set and cleared by the enqueuing and 300 Why not just have a flag set and cleared by the enqueuing and
305 dequeuing functions? Such a flag could be screwed up by interrupts 301 dequeuing functions? The code is a bit simpler this way. */
306 at inopportune times. */
307 302
308static void recursive_edit_unwind (Lisp_Object buffer); 303static void recursive_edit_unwind (Lisp_Object buffer);
309static Lisp_Object command_loop (void); 304static Lisp_Object command_loop (void);
@@ -375,6 +370,20 @@ static void deliver_user_signal (int);
375static char *find_user_signal_name (int); 370static char *find_user_signal_name (int);
376static void store_user_signal_events (void); 371static void store_user_signal_events (void);
377 372
373/* Advance or retreat a buffered input event pointer. */
374
375static union buffered_input_event *
376next_kbd_event (union buffered_input_event *ptr)
377{
378 return ptr == kbd_buffer + KBD_BUFFER_SIZE - 1 ? kbd_buffer : ptr + 1;
379}
380
381static union buffered_input_event *
382prev_kbd_event (union buffered_input_event *ptr)
383{
384 return ptr == kbd_buffer ? kbd_buffer + KBD_BUFFER_SIZE - 1 : ptr - 1;
385}
386
378/* Like EVENT_START, but assume EVENT is an event. 387/* Like EVENT_START, but assume EVENT is an event.
379 This pacifies gcc -Wnull-dereference, which might otherwise 388 This pacifies gcc -Wnull-dereference, which might otherwise
380 complain about earlier checks that EVENT is indeed an event. */ 389 complain about earlier checks that EVENT is indeed an event. */
@@ -3338,8 +3347,6 @@ readable_events (int flags)
3338 3347
3339 do 3348 do
3340 { 3349 {
3341 if (event == kbd_buffer + KBD_BUFFER_SIZE)
3342 event = kbd_buffer;
3343 if (!( 3350 if (!(
3344#ifdef USE_TOOLKIT_SCROLL_BARS 3351#ifdef USE_TOOLKIT_SCROLL_BARS
3345 (flags & READABLE_EVENTS_FILTER_EVENTS) && 3352 (flags & READABLE_EVENTS_FILTER_EVENTS) &&
@@ -3356,7 +3363,7 @@ readable_events (int flags)
3356 && !((flags & READABLE_EVENTS_FILTER_EVENTS) 3363 && !((flags & READABLE_EVENTS_FILTER_EVENTS)
3357 && event->kind == BUFFER_SWITCH_EVENT)) 3364 && event->kind == BUFFER_SWITCH_EVENT))
3358 return 1; 3365 return 1;
3359 event++; 3366 event = next_kbd_event (event);
3360 } 3367 }
3361 while (event != kbd_store_ptr); 3368 while (event != kbd_store_ptr);
3362 } 3369 }
@@ -3410,12 +3417,8 @@ event_to_kboard (struct input_event *event)
3410static int 3417static int
3411kbd_buffer_nr_stored (void) 3418kbd_buffer_nr_stored (void)
3412{ 3419{
3413 return kbd_fetch_ptr == kbd_store_ptr 3420 int n = kbd_store_ptr - kbd_fetch_ptr;
3414 ? 0 3421 return n + (n < 0 ? KBD_BUFFER_SIZE : 0);
3415 : (kbd_fetch_ptr < kbd_store_ptr
3416 ? kbd_store_ptr - kbd_fetch_ptr
3417 : ((kbd_buffer + KBD_BUFFER_SIZE) - kbd_fetch_ptr
3418 + (kbd_store_ptr - kbd_buffer)));
3419} 3422}
3420#endif /* Store an event obtained at interrupt level into kbd_buffer, fifo */ 3423#endif /* Store an event obtained at interrupt level into kbd_buffer, fifo */
3421 3424
@@ -3466,12 +3469,10 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
3466 (kb, list2 (make_lispy_switch_frame (event->ie.frame_or_window), 3469 (kb, list2 (make_lispy_switch_frame (event->ie.frame_or_window),
3467 make_fixnum (c))); 3470 make_fixnum (c)));
3468 kb->kbd_queue_has_data = true; 3471 kb->kbd_queue_has_data = true;
3469 union buffered_input_event *sp;
3470 for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
3471 {
3472 if (sp == kbd_buffer + KBD_BUFFER_SIZE)
3473 sp = kbd_buffer;
3474 3472
3473 for (union buffered_input_event *sp = kbd_fetch_ptr;
3474 sp != kbd_store_ptr; sp = next_kbd_event (sp))
3475 {
3475 if (event_to_kboard (&sp->ie) == kb) 3476 if (event_to_kboard (&sp->ie) == kb)
3476 { 3477 {
3477 sp->ie.kind = NO_EVENT; 3478 sp->ie.kind = NO_EVENT;
@@ -3516,22 +3517,18 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
3516 Just ignore the second one. */ 3517 Just ignore the second one. */
3517 else if (event->kind == BUFFER_SWITCH_EVENT 3518 else if (event->kind == BUFFER_SWITCH_EVENT
3518 && kbd_fetch_ptr != kbd_store_ptr 3519 && kbd_fetch_ptr != kbd_store_ptr
3519 && ((kbd_store_ptr == kbd_buffer 3520 && prev_kbd_event (kbd_store_ptr)->kind == BUFFER_SWITCH_EVENT)
3520 ? kbd_buffer + KBD_BUFFER_SIZE - 1
3521 : kbd_store_ptr - 1)->kind) == BUFFER_SWITCH_EVENT)
3522 return; 3521 return;
3523 3522
3524 if (kbd_store_ptr - kbd_buffer == KBD_BUFFER_SIZE)
3525 kbd_store_ptr = kbd_buffer;
3526
3527 /* Don't let the very last slot in the buffer become full, 3523 /* Don't let the very last slot in the buffer become full,
3528 since that would make the two pointers equal, 3524 since that would make the two pointers equal,
3529 and that is indistinguishable from an empty buffer. 3525 and that is indistinguishable from an empty buffer.
3530 Discard the event if it would fill the last slot. */ 3526 Discard the event if it would fill the last slot. */
3531 if (kbd_fetch_ptr - 1 != kbd_store_ptr) 3527 union buffered_input_event *next_slot = next_kbd_event (kbd_store_ptr);
3528 if (kbd_fetch_ptr != next_slot)
3532 { 3529 {
3533 *kbd_store_ptr = *event; 3530 *kbd_store_ptr = *event;
3534 ++kbd_store_ptr; 3531 kbd_store_ptr = next_slot;
3535#ifdef subprocesses 3532#ifdef subprocesses
3536 if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE / 2 3533 if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE / 2
3537 && ! kbd_on_hold_p ()) 3534 && ! kbd_on_hold_p ())
@@ -3574,11 +3571,8 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
3574void 3571void
3575kbd_buffer_unget_event (struct selection_input_event *event) 3572kbd_buffer_unget_event (struct selection_input_event *event)
3576{ 3573{
3577 if (kbd_fetch_ptr == kbd_buffer)
3578 kbd_fetch_ptr = kbd_buffer + KBD_BUFFER_SIZE;
3579
3580 /* Don't let the very last slot in the buffer become full, */ 3574 /* Don't let the very last slot in the buffer become full, */
3581 union buffered_input_event *kp = kbd_fetch_ptr - 1; 3575 union buffered_input_event *kp = prev_kbd_event (kbd_fetch_ptr);
3582 if (kp != kbd_store_ptr) 3576 if (kp != kbd_store_ptr)
3583 { 3577 {
3584 kp->sie = *event; 3578 kp->sie = *event;
@@ -3666,12 +3660,9 @@ kbd_buffer_store_help_event (Lisp_Object frame, Lisp_Object help)
3666void 3660void
3667discard_mouse_events (void) 3661discard_mouse_events (void)
3668{ 3662{
3669 union buffered_input_event *sp; 3663 for (union buffered_input_event *sp = kbd_fetch_ptr;
3670 for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++) 3664 sp != kbd_store_ptr; sp = next_kbd_event (sp))
3671 { 3665 {
3672 if (sp == kbd_buffer + KBD_BUFFER_SIZE)
3673 sp = kbd_buffer;
3674
3675 if (sp->kind == MOUSE_CLICK_EVENT 3666 if (sp->kind == MOUSE_CLICK_EVENT
3676 || sp->kind == WHEEL_EVENT 3667 || sp->kind == WHEEL_EVENT
3677 || sp->kind == HORIZ_WHEEL_EVENT 3668 || sp->kind == HORIZ_WHEEL_EVENT
@@ -3696,18 +3687,13 @@ discard_mouse_events (void)
3696bool 3687bool
3697kbd_buffer_events_waiting (void) 3688kbd_buffer_events_waiting (void)
3698{ 3689{
3699 union buffered_input_event *sp; 3690 for (union buffered_input_event *sp = kbd_fetch_ptr;
3700 3691 ; sp = next_kbd_event (sp))
3701 for (sp = kbd_fetch_ptr; 3692 if (sp == kbd_store_ptr || sp->kind != NO_EVENT)
3702 sp != kbd_store_ptr && sp->kind == NO_EVENT; 3693 {
3703 ++sp) 3694 kbd_fetch_ptr = sp;
3704 { 3695 return sp != kbd_store_ptr && sp->kind != NO_EVENT;
3705 if (sp == kbd_buffer + KBD_BUFFER_SIZE) 3696 }
3706 sp = kbd_buffer;
3707 }
3708
3709 kbd_fetch_ptr = sp;
3710 return sp != kbd_store_ptr && sp->kind != NO_EVENT;
3711} 3697}
3712 3698
3713 3699
@@ -3836,11 +3822,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3836 mouse movement enabled and available. */ 3822 mouse movement enabled and available. */
3837 if (kbd_fetch_ptr != kbd_store_ptr) 3823 if (kbd_fetch_ptr != kbd_store_ptr)
3838 { 3824 {
3839 union buffered_input_event *event; 3825 union buffered_input_event *event = kbd_fetch_ptr;
3840
3841 event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
3842 ? kbd_fetch_ptr
3843 : kbd_buffer);
3844 3826
3845 *kbp = event_to_kboard (&event->ie); 3827 *kbp = event_to_kboard (&event->ie);
3846 if (*kbp == 0) 3828 if (*kbp == 0)
@@ -3861,7 +3843,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3861 since otherwise swallow_events will see it 3843 since otherwise swallow_events will see it
3862 and process it again. */ 3844 and process it again. */
3863 struct selection_input_event copy = event->sie; 3845 struct selection_input_event copy = event->sie;
3864 kbd_fetch_ptr = event + 1; 3846 kbd_fetch_ptr = next_kbd_event (event);
3865 input_pending = readable_events (0); 3847 input_pending = readable_events (0);
3866 x_handle_selection_event (&copy); 3848 x_handle_selection_event (&copy);
3867#else 3849#else
@@ -3876,7 +3858,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3876 || defined (HAVE_NS) || defined (USE_GTK) 3858 || defined (HAVE_NS) || defined (USE_GTK)
3877 case MENU_BAR_ACTIVATE_EVENT: 3859 case MENU_BAR_ACTIVATE_EVENT:
3878 { 3860 {
3879 kbd_fetch_ptr = event + 1; 3861 kbd_fetch_ptr = next_kbd_event (event);
3880 input_pending = readable_events (0); 3862 input_pending = readable_events (0);
3881 if (FRAME_LIVE_P (XFRAME (event->ie.frame_or_window))) 3863 if (FRAME_LIVE_P (XFRAME (event->ie.frame_or_window)))
3882 x_activate_menubar (XFRAME (event->ie.frame_or_window)); 3864 x_activate_menubar (XFRAME (event->ie.frame_or_window));
@@ -3921,7 +3903,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3921 case SELECT_WINDOW_EVENT: 3903 case SELECT_WINDOW_EVENT:
3922 { 3904 {
3923 obj = make_lispy_event (&event->ie); 3905 obj = make_lispy_event (&event->ie);
3924 kbd_fetch_ptr = event + 1; 3906 kbd_fetch_ptr = next_kbd_event (event);
3925 } 3907 }
3926 break; 3908 break;
3927 default: 3909 default:
@@ -3975,7 +3957,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3975 3957
3976 /* Wipe out this event, to catch bugs. */ 3958 /* Wipe out this event, to catch bugs. */
3977 clear_event (&event->ie); 3959 clear_event (&event->ie);
3978 kbd_fetch_ptr = event + 1; 3960 kbd_fetch_ptr = next_kbd_event (event);
3979 } 3961 }
3980 } 3962 }
3981 } 3963 }
@@ -4042,17 +4024,9 @@ kbd_buffer_get_event (KBOARD **kbp,
4042static void 4024static void
4043process_special_events (void) 4025process_special_events (void)
4044{ 4026{
4045 union buffered_input_event *event; 4027 for (union buffered_input_event *event = kbd_fetch_ptr;
4046 4028 event != kbd_store_ptr; event = next_kbd_event (event))
4047 for (event = kbd_fetch_ptr; event != kbd_store_ptr; ++event)
4048 { 4029 {
4049 if (event == kbd_buffer + KBD_BUFFER_SIZE)
4050 {
4051 event = kbd_buffer;
4052 if (event == kbd_store_ptr)
4053 break;
4054 }
4055
4056 /* If we find a stored X selection request, handle it now. */ 4030 /* If we find a stored X selection request, handle it now. */
4057 if (event->kind == SELECTION_REQUEST_EVENT 4031 if (event->kind == SELECTION_REQUEST_EVENT
4058 || event->kind == SELECTION_CLEAR_EVENT) 4032 || event->kind == SELECTION_CLEAR_EVENT)
@@ -4066,28 +4040,21 @@ process_special_events (void)
4066 cyclically. */ 4040 cyclically. */
4067 4041
4068 struct selection_input_event copy = event->sie; 4042 struct selection_input_event copy = event->sie;
4069 union buffered_input_event *beg 4043 int moved_events;
4070 = (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
4071 ? kbd_buffer : kbd_fetch_ptr;
4072 4044
4073 if (event > beg) 4045 if (event < kbd_fetch_ptr)
4074 memmove (beg + 1, beg, (event - beg) * sizeof *beg);
4075 else if (event < beg)
4076 { 4046 {
4077 if (event > kbd_buffer) 4047 memmove (kbd_buffer + 1, kbd_buffer,
4078 memmove (kbd_buffer + 1, kbd_buffer, 4048 (event - kbd_buffer) * sizeof *kbd_buffer);
4079 (event - kbd_buffer) * sizeof *kbd_buffer); 4049 kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1];
4080 *kbd_buffer = *(kbd_buffer + KBD_BUFFER_SIZE - 1); 4050 moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr;
4081 if (beg < kbd_buffer + KBD_BUFFER_SIZE - 1)
4082 memmove (beg + 1, beg,
4083 (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg) * sizeof *beg);
4084 } 4051 }
4085
4086 if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
4087 kbd_fetch_ptr = kbd_buffer + 1;
4088 else 4052 else
4089 kbd_fetch_ptr++; 4053 moved_events = event - kbd_fetch_ptr;
4090 4054
4055 memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr,
4056 moved_events * sizeof *kbd_fetch_ptr);
4057 kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr);
4091 input_pending = readable_events (0); 4058 input_pending = readable_events (0);
4092 x_handle_selection_event (&copy); 4059 x_handle_selection_event (&copy);
4093#else 4060#else
@@ -10261,11 +10228,10 @@ stuff_buffered_input (Lisp_Object stuffstring)
10261 10228
10262 rms: we should stuff everything back into the kboard 10229 rms: we should stuff everything back into the kboard
10263 it came from. */ 10230 it came from. */
10264 for (; kbd_fetch_ptr != kbd_store_ptr; kbd_fetch_ptr++) 10231 for (; kbd_fetch_ptr != kbd_store_ptr;
10232 kbd_fetch_ptr = next_kbd_event (kbd_fetch_ptr))
10265 { 10233 {
10266 10234
10267 if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
10268 kbd_fetch_ptr = kbd_buffer;
10269 if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT) 10235 if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT)
10270 stuff_char (kbd_fetch_ptr->ie.code); 10236 stuff_char (kbd_fetch_ptr->ie.code);
10271 10237
@@ -12003,21 +11969,18 @@ mark_kboards (void)
12003 mark_object (KVAR (kb, echo_string)); 11969 mark_object (KVAR (kb, echo_string));
12004 mark_object (KVAR (kb, echo_prompt)); 11970 mark_object (KVAR (kb, echo_prompt));
12005 } 11971 }
12006 { 11972
12007 union buffered_input_event *event; 11973 for (union buffered_input_event *event = kbd_fetch_ptr;
12008 for (event = kbd_fetch_ptr; event != kbd_store_ptr; event++) 11974 event != kbd_store_ptr; event = next_kbd_event (event))
12009 { 11975 {
12010 if (event == kbd_buffer + KBD_BUFFER_SIZE) 11976 /* These two special event types have no Lisp_Objects to mark. */
12011 event = kbd_buffer; 11977 if (event->kind != SELECTION_REQUEST_EVENT
12012 /* These two special event types has no Lisp_Objects to mark. */ 11978 && event->kind != SELECTION_CLEAR_EVENT)
12013 if (event->kind != SELECTION_REQUEST_EVENT 11979 {
12014 && event->kind != SELECTION_CLEAR_EVENT) 11980 mark_object (event->ie.x);
12015 { 11981 mark_object (event->ie.y);
12016 mark_object (event->ie.x); 11982 mark_object (event->ie.frame_or_window);
12017 mark_object (event->ie.y); 11983 mark_object (event->ie.arg);
12018 mark_object (event->ie.frame_or_window); 11984 }
12019 mark_object (event->ie.arg); 11985 }
12020 }
12021 }
12022 }
12023} 11986}