diff options
| author | Chong Yidong | 2012-02-24 16:34:09 +0800 |
|---|---|---|
| committer | Chong Yidong | 2012-02-24 16:34:09 +0800 |
| commit | 9486df08b798f31960779d86c60cc341e606b864 (patch) | |
| tree | c1eb77ae3b5d9c0cabcd23da3be59f07364cc231 /src | |
| parent | 4bb82fa8b7a8360d9877b63794eba778405e2962 (diff) | |
| download | emacs-9486df08b798f31960779d86c60cc341e606b864.tar.gz emacs-9486df08b798f31960779d86c60cc341e606b864.zip | |
Process multiple X selection requests in process_special_events.
* src/keyboard.c (process_special_events): Handle all X selection
requests in kbd_buffer, not just the next one.
Fixes: debbugs:8869
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/keyboard.c | 60 |
2 files changed, 47 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 5c297eb1e33..8e439f1a1d4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2012-02-24 Chong Yidong <cyd@gnu.org> | ||
| 2 | |||
| 3 | * keyboard.c (process_special_events): Handle all X selection | ||
| 4 | requests in kbd_buffer, not just the next one (Bug#8869). | ||
| 5 | |||
| 1 | 2012-02-23 Chong Yidong <cyd@gnu.org> | 6 | 2012-02-23 Chong Yidong <cyd@gnu.org> |
| 2 | 7 | ||
| 3 | * xfns.c (Fx_create_frame): Avoid window-configuration-change-hook | 8 | * xfns.c (Fx_create_frame): Avoid window-configuration-change-hook |
diff --git a/src/keyboard.c b/src/keyboard.c index d4ff3c58f9b..f791773c352 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -4154,29 +4154,55 @@ kbd_buffer_get_event (KBOARD **kbp, | |||
| 4154 | static void | 4154 | static void |
| 4155 | process_special_events (void) | 4155 | process_special_events (void) |
| 4156 | { | 4156 | { |
| 4157 | while (kbd_fetch_ptr != kbd_store_ptr) | 4157 | struct input_event *event; |
| 4158 | { | ||
| 4159 | struct input_event *event; | ||
| 4160 | 4158 | ||
| 4161 | event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE) | 4159 | for (event = kbd_fetch_ptr; event != kbd_store_ptr; ++event) |
| 4162 | ? kbd_fetch_ptr | 4160 | { |
| 4163 | : kbd_buffer); | 4161 | if (event == kbd_buffer + KBD_BUFFER_SIZE) |
| 4164 | 4162 | { | |
| 4165 | last_event_timestamp = event->timestamp; | 4163 | event = kbd_buffer; |
| 4164 | if (event == kbd_store_ptr) | ||
| 4165 | break; | ||
| 4166 | } | ||
| 4166 | 4167 | ||
| 4167 | /* These two kinds of events get special handling | 4168 | /* If we find a stored X selection request, handle it now. */ |
| 4168 | and don't actually appear to the command loop. */ | ||
| 4169 | if (event->kind == SELECTION_REQUEST_EVENT | 4169 | if (event->kind == SELECTION_REQUEST_EVENT |
| 4170 | || event->kind == SELECTION_CLEAR_EVENT) | 4170 | || event->kind == SELECTION_CLEAR_EVENT) |
| 4171 | { | 4171 | { |
| 4172 | #ifdef HAVE_X11 | 4172 | #ifdef HAVE_X11 |
| 4173 | struct input_event copy; | ||
| 4174 | 4173 | ||
| 4175 | /* Remove it from the buffer before processing it, | 4174 | /* Remove the event from the fifo buffer before processing; |
| 4176 | since otherwise swallow_events called recursively could see it | 4175 | otherwise swallow_events called recursively could see it |
| 4177 | and process it again. */ | 4176 | and process it again. To do this, we move the events |
| 4178 | copy = *event; | 4177 | between kbd_fetch_ptr and EVENT one slot to the right, |
| 4179 | kbd_fetch_ptr = event + 1; | 4178 | cyclically. */ |
| 4179 | |||
| 4180 | struct input_event copy = *event; | ||
| 4181 | struct input_event *beg | ||
| 4182 | = (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) | ||
| 4183 | ? kbd_buffer : kbd_fetch_ptr; | ||
| 4184 | |||
| 4185 | if (event > beg) | ||
| 4186 | memmove (beg + 1, beg, (event - beg) * sizeof (struct input_event)); | ||
| 4187 | else if (event < beg) | ||
| 4188 | { | ||
| 4189 | if (event > kbd_buffer) | ||
| 4190 | memmove (kbd_buffer + 1, kbd_buffer, | ||
| 4191 | (event - kbd_buffer) * sizeof (struct input_event)); | ||
| 4192 | *kbd_buffer = *(kbd_buffer + KBD_BUFFER_SIZE - 1); | ||
| 4193 | if (beg < kbd_buffer + KBD_BUFFER_SIZE - 1) | ||
| 4194 | memmove (beg + 1, beg, | ||
| 4195 | (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg) | ||
| 4196 | * sizeof (struct input_event)); | ||
| 4197 | } | ||
| 4198 | |||
| 4199 | if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) | ||
| 4200 | kbd_fetch_ptr = kbd_buffer + 1; | ||
| 4201 | else | ||
| 4202 | kbd_fetch_ptr++; | ||
| 4203 | |||
| 4204 | /* X wants last_event_timestamp for selection ownership. */ | ||
| 4205 | last_event_timestamp = copy.timestamp; | ||
| 4180 | input_pending = readable_events (0); | 4206 | input_pending = readable_events (0); |
| 4181 | x_handle_selection_event (©); | 4207 | x_handle_selection_event (©); |
| 4182 | #else | 4208 | #else |
| @@ -4185,8 +4211,6 @@ process_special_events (void) | |||
| 4185 | abort (); | 4211 | abort (); |
| 4186 | #endif | 4212 | #endif |
| 4187 | } | 4213 | } |
| 4188 | else | ||
| 4189 | break; | ||
| 4190 | } | 4214 | } |
| 4191 | } | 4215 | } |
| 4192 | 4216 | ||