diff options
| author | Karl Heuer | 1995-02-22 07:26:40 +0000 |
|---|---|---|
| committer | Karl Heuer | 1995-02-22 07:26:40 +0000 |
| commit | beecf6a1d16afdf34dfecd38cc5cfbb05c0b59a6 (patch) | |
| tree | 696c726ddcf6784c0060684ae6614711dac8a76c | |
| parent | 4cb35c394ac6a1feb2f06b8d0057822b8b75aa98 (diff) | |
| download | emacs-beecf6a1d16afdf34dfecd38cc5cfbb05c0b59a6.tar.gz emacs-beecf6a1d16afdf34dfecd38cc5cfbb05c0b59a6.zip | |
(kbd_buffer_frame_or_window): Restored old var.
(kbd_buffer, kbd_fetch_ptr, kbd_store_ptr): Likewise.
(read_char_perdisplay): New var.
(read_char): Search all appropriate perdisplay objects, and do the right thing
if the next event comes from a different source.
(read_key_sequence): If there's a change of display in mid-stream, retreat and
try reading the new display.
(find_active_event_queue): Function deleted. All callers changed to just test
the main kbd_buffer instead.
(kbd_buffer_store_event): Write to the main kbd_buffer again.
(kbd_buffer_get_event): Read from the main kbd_buffer again.
Now returns a perdisplay pointer in addition to a lispy event.
(Fdiscard_input, swallow_events): Use the main kbd_buffer again.
(stuff_buffered_input): Likewise.
(init_perdisplay): Initialize member kbd_queue.
Remove references to obsolete members.
(wipe_perdisplay): Remove obsolete reference.
(init_keyboard, syms_of_keyboard): Restore initialization of vars.
| -rw-r--r-- | src/keyboard.c | 361 |
1 files changed, 245 insertions, 116 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 5b1b408cc26..f256c825f35 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -22,7 +22,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 22 | 22 | ||
| 23 | #include <config.h> | 23 | #include <config.h> |
| 24 | #include <stdio.h> | 24 | #include <stdio.h> |
| 25 | #undef NULL | ||
| 26 | #include "termchar.h" | 25 | #include "termchar.h" |
| 27 | #include "termopts.h" | 26 | #include "termopts.h" |
| 28 | #include "lisp.h" | 27 | #include "lisp.h" |
| @@ -318,6 +317,57 @@ int meta_key; | |||
| 318 | 317 | ||
| 319 | extern char *pending_malloc_warning; | 318 | extern char *pending_malloc_warning; |
| 320 | 319 | ||
| 320 | /* Circular buffer for pre-read keyboard input. */ | ||
| 321 | static struct input_event kbd_buffer[KBD_BUFFER_SIZE]; | ||
| 322 | |||
| 323 | /* Vector to GCPRO the frames and windows mentioned in kbd_buffer. | ||
| 324 | |||
| 325 | The interrupt-level event handlers will never enqueue an event on a | ||
| 326 | frame which is not in Vframe_list, and once an event is dequeued, | ||
| 327 | internal_last_event_frame or the event itself points to the frame. | ||
| 328 | So that's all fine. | ||
| 329 | |||
| 330 | But while the event is sitting in the queue, it's completely | ||
| 331 | unprotected. Suppose the user types one command which will run for | ||
| 332 | a while and then delete a frame, and then types another event at | ||
| 333 | the frame that will be deleted, before the command gets around to | ||
| 334 | it. Suppose there are no references to this frame elsewhere in | ||
| 335 | Emacs, and a GC occurs before the second event is dequeued. Now we | ||
| 336 | have an event referring to a freed frame, which will crash Emacs | ||
| 337 | when it is dequeued. | ||
| 338 | |||
| 339 | Similar things happen when an event on a scroll bar is enqueued; the | ||
| 340 | window may be deleted while the event is in the queue. | ||
| 341 | |||
| 342 | So, we use this vector to protect the frame_or_window field in the | ||
| 343 | event queue. That way, they'll be dequeued as dead frames or | ||
| 344 | windows, but still valid lisp objects. | ||
| 345 | |||
| 346 | If kbd_buffer[i].kind != no_event, then | ||
| 347 | (XVECTOR (kbd_buffer_frame_or_window)->contents[i] | ||
| 348 | == kbd_buffer[i].frame_or_window. */ | ||
| 349 | static Lisp_Object kbd_buffer_frame_or_window; | ||
| 350 | |||
| 351 | /* Pointer to next available character in kbd_buffer. | ||
| 352 | If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. | ||
| 353 | This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the the | ||
| 354 | next available char is in kbd_buffer[0]. */ | ||
| 355 | static struct input_event *kbd_fetch_ptr; | ||
| 356 | |||
| 357 | /* Pointer to next place to store character in kbd_buffer. This | ||
| 358 | may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the next | ||
| 359 | character should go in kbd_buffer[0]. */ | ||
| 360 | static volatile struct input_event *kbd_store_ptr; | ||
| 361 | |||
| 362 | /* The above pair of variables forms a "queue empty" flag. When we | ||
| 363 | enqueue a non-hook event, we increment kbd_store_ptr. When we | ||
| 364 | dequeue a non-hook event, we increment kbd_fetch_ptr. We say that | ||
| 365 | there is input available iff the two pointers are not equal. | ||
| 366 | |||
| 367 | Why not just have a flag set and cleared by the enqueuing and | ||
| 368 | dequeuing functions? Such a flag could be screwed up by interrupts | ||
| 369 | at inopportune times. */ | ||
| 370 | |||
| 321 | #ifdef HAVE_MOUSE | 371 | #ifdef HAVE_MOUSE |
| 322 | /* If this flag is a frame, we check mouse_moved to see when the | 372 | /* If this flag is a frame, we check mouse_moved to see when the |
| 323 | mouse moves, and motion events will appear in the input stream. | 373 | mouse moves, and motion events will appear in the input stream. |
| @@ -1022,7 +1072,7 @@ command_loop_1 () | |||
| 1022 | cases identified below that set no_redisplay to 1. | 1072 | cases identified below that set no_redisplay to 1. |
| 1023 | (actually, there's currently no way to prevent the redisplay, | 1073 | (actually, there's currently no way to prevent the redisplay, |
| 1024 | and no_redisplay is ignored. | 1074 | and no_redisplay is ignored. |
| 1025 | Perhaps someday we will really implement it. */ | 1075 | Perhaps someday we will really implement it.) */ |
| 1026 | no_redisplay = 0; | 1076 | no_redisplay = 0; |
| 1027 | 1077 | ||
| 1028 | prev_buffer = current_buffer; | 1078 | prev_buffer = current_buffer; |
| @@ -1407,6 +1457,9 @@ Lisp_Object print_help (); | |||
| 1407 | static Lisp_Object kbd_buffer_get_event (); | 1457 | static Lisp_Object kbd_buffer_get_event (); |
| 1408 | static void record_char (); | 1458 | static void record_char (); |
| 1409 | 1459 | ||
| 1460 | static PERDISPLAY *read_char_perdisplay; | ||
| 1461 | static jmp_buf wrong_display_jmpbuf; | ||
| 1462 | |||
| 1410 | /* read a character from the keyboard; call the redisplay if needed */ | 1463 | /* read a character from the keyboard; call the redisplay if needed */ |
| 1411 | /* commandflag 0 means do not do auto-saving, but do do redisplay. | 1464 | /* commandflag 0 means do not do auto-saving, but do do redisplay. |
| 1412 | -1 means do not do redisplay, but do do autosaving. | 1465 | -1 means do not do redisplay, but do do autosaving. |
| @@ -1664,19 +1717,74 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1664 | } | 1717 | } |
| 1665 | } | 1718 | } |
| 1666 | 1719 | ||
| 1667 | /* Actually read a character, waiting if necessary. */ | 1720 | if (NILP (c)) |
| 1668 | while (NILP (c)) | ||
| 1669 | { | 1721 | { |
| 1670 | c = kbd_buffer_get_event (); | 1722 | PERDISPLAY *perd; |
| 1671 | if (!NILP (c)) | 1723 | /* Check for something on one of the side queues. If we're already |
| 1672 | break; | 1724 | locked to a particular display, just check that one; otherwise |
| 1673 | if (commandflag >= 0 && !input_pending && !detect_input_pending ()) | 1725 | check all of them, but give priority to the most recently used |
| 1726 | display. */ | ||
| 1727 | if (current_perdisplay) | ||
| 1674 | { | 1728 | { |
| 1675 | prepare_menu_bars (); | 1729 | if (CONSP (current_perdisplay->kbd_queue)) |
| 1676 | redisplay (); | 1730 | perd = current_perdisplay; |
| 1731 | else | ||
| 1732 | perd = 0; | ||
| 1733 | } | ||
| 1734 | else if (read_char_perdisplay && CONSP (read_char_perdisplay->kbd_queue)) | ||
| 1735 | perd = read_char_perdisplay; | ||
| 1736 | else | ||
| 1737 | { | ||
| 1738 | for (perd = all_perdisplays; perd; perd = perd->next_perdisplay) | ||
| 1739 | if (CONSP (perd->kbd_queue)) | ||
| 1740 | break; | ||
| 1677 | } | 1741 | } |
| 1678 | } | ||
| 1679 | 1742 | ||
| 1743 | /* If we found something on a side queue, use that. | ||
| 1744 | Otherwise, read from the main queue, and if that gives us | ||
| 1745 | something we can't use yet, put it on the side queue and | ||
| 1746 | try again. */ | ||
| 1747 | if (perd) | ||
| 1748 | { | ||
| 1749 | c = XCONS (perd->kbd_queue)->car; | ||
| 1750 | perd->kbd_queue = XCONS (perd->kbd_queue)->cdr; | ||
| 1751 | } | ||
| 1752 | else | ||
| 1753 | { | ||
| 1754 | wrong_display: | ||
| 1755 | /* Actually read a character, waiting if necessary. */ | ||
| 1756 | while (c = kbd_buffer_get_event (&perd), NILP (c)) | ||
| 1757 | { | ||
| 1758 | if (commandflag >= 0 | ||
| 1759 | && !input_pending && !detect_input_pending ()) | ||
| 1760 | { | ||
| 1761 | prepare_menu_bars (); | ||
| 1762 | redisplay (); | ||
| 1763 | } | ||
| 1764 | } | ||
| 1765 | if (current_perdisplay && perd != current_perdisplay) | ||
| 1766 | { | ||
| 1767 | Lisp_Object *tailp = &perd->kbd_queue; | ||
| 1768 | while (CONSP (*tailp)) | ||
| 1769 | tailp = &XCONS (*tailp)->cdr; | ||
| 1770 | if (!NILP (*tailp)) | ||
| 1771 | abort (); | ||
| 1772 | *tailp = Fcons (c, Qnil); | ||
| 1773 | goto wrong_display; | ||
| 1774 | } | ||
| 1775 | } | ||
| 1776 | if (!read_char_perdisplay) | ||
| 1777 | read_char_perdisplay = perd; | ||
| 1778 | if (perd != read_char_perdisplay) | ||
| 1779 | { | ||
| 1780 | /* We shouldn't get here if we were locked onto one display! */ | ||
| 1781 | if (current_perdisplay) | ||
| 1782 | abort (); | ||
| 1783 | perd->kbd_queue = Fcons (c, perd->kbd_queue); | ||
| 1784 | read_char_perdisplay = perd; | ||
| 1785 | longjmp (wrong_display_jmpbuf, 1); | ||
| 1786 | } | ||
| 1787 | } | ||
| 1680 | /* Terminate Emacs in batch mode if at eof. */ | 1788 | /* Terminate Emacs in batch mode if at eof. */ |
| 1681 | if (noninteractive && INTEGERP (c) && XINT (c) < 0) | 1789 | if (noninteractive && INTEGERP (c) && XINT (c) < 0) |
| 1682 | Fkill_emacs (make_number (1)); | 1790 | Fkill_emacs (make_number (1)); |
| @@ -1942,30 +2050,18 @@ Normally, mouse motion is ignored.") | |||
| 1942 | mouse_moved indicates when the mouse has moved again, and | 2050 | mouse_moved indicates when the mouse has moved again, and |
| 1943 | *mouse_position_hook provides the mouse position. */ | 2051 | *mouse_position_hook provides the mouse position. */ |
| 1944 | 2052 | ||
| 1945 | static PERDISPLAY * | ||
| 1946 | find_active_event_queue (check_mouse) | ||
| 1947 | int check_mouse; | ||
| 1948 | { | ||
| 1949 | PERDISPLAY *perd; | ||
| 1950 | |||
| 1951 | for (perd = all_perdisplays; perd; perd = perd->next_perdisplay) | ||
| 1952 | { | ||
| 1953 | if (perd->kbd_fetch_ptr != perd->kbd_store_ptr) | ||
| 1954 | return perd; | ||
| 1955 | #ifdef HAVE_MOUSE | ||
| 1956 | if (check_mouse && FRAMEP (do_mouse_tracking) && mouse_moved) | ||
| 1957 | return perd; | ||
| 1958 | #endif | ||
| 1959 | } | ||
| 1960 | return 0; | ||
| 1961 | } | ||
| 1962 | |||
| 1963 | /* Return true iff there are any events in the queue that read-char | 2053 | /* Return true iff there are any events in the queue that read-char |
| 1964 | would return. If this returns false, a read-char would block. */ | 2054 | would return. If this returns false, a read-char would block. */ |
| 1965 | static int | 2055 | static int |
| 1966 | readable_events () | 2056 | readable_events () |
| 1967 | { | 2057 | { |
| 1968 | return find_active_event_queue (1) != NULL; | 2058 | if (kbd_fetch_ptr != kbd_store_ptr) |
| 2059 | return 1; | ||
| 2060 | #ifdef HAVE_MOUSE | ||
| 2061 | if (FRAMEP (do_mouse_tracking) && mouse_moved) | ||
| 2062 | return 1; | ||
| 2063 | #endif | ||
| 2064 | return 0; | ||
| 1969 | } | 2065 | } |
| 1970 | 2066 | ||
| 1971 | /* Set this for debugging, to have a way to get out */ | 2067 | /* Set this for debugging, to have a way to get out */ |
| @@ -1977,8 +2073,6 @@ void | |||
| 1977 | kbd_buffer_store_event (event) | 2073 | kbd_buffer_store_event (event) |
| 1978 | register struct input_event *event; | 2074 | register struct input_event *event; |
| 1979 | { | 2075 | { |
| 1980 | PERDISPLAY *perd = get_perdisplay (XFRAME (event->frame_or_window)); | ||
| 1981 | |||
| 1982 | if (event->kind == no_event) | 2076 | if (event->kind == no_event) |
| 1983 | abort (); | 2077 | abort (); |
| 1984 | 2078 | ||
| @@ -2004,13 +2098,14 @@ kbd_buffer_store_event (event) | |||
| 2004 | will set Vlast_event_frame again, so this is safe to do. */ | 2098 | will set Vlast_event_frame again, so this is safe to do. */ |
| 2005 | { | 2099 | { |
| 2006 | Lisp_Object focus; | 2100 | Lisp_Object focus; |
| 2101 | PERDISPLAY *perd; | ||
| 2007 | 2102 | ||
| 2008 | focus = FRAME_FOCUS_FRAME (XFRAME (event->frame_or_window)); | 2103 | focus = FRAME_FOCUS_FRAME (XFRAME (event->frame_or_window)); |
| 2009 | if (NILP (focus)) | 2104 | if (NILP (focus)) |
| 2010 | perd->internal_last_event_frame = event->frame_or_window; | 2105 | focus = event->frame_or_window; |
| 2011 | else | 2106 | perd = get_perdisplay (XFRAME (focus)); |
| 2012 | perd->internal_last_event_frame = focus; | 2107 | perd->internal_last_event_frame = focus; |
| 2013 | perd->Vlast_event_frame = perd->internal_last_event_frame; | 2108 | perd->Vlast_event_frame = focus; |
| 2014 | } | 2109 | } |
| 2015 | #endif | 2110 | #endif |
| 2016 | 2111 | ||
| @@ -2026,16 +2121,16 @@ kbd_buffer_store_event (event) | |||
| 2026 | } | 2121 | } |
| 2027 | } | 2122 | } |
| 2028 | 2123 | ||
| 2029 | if (perd->kbd_store_ptr - perd->kbd_buffer == KBD_BUFFER_SIZE) | 2124 | if (kbd_store_ptr - kbd_buffer == KBD_BUFFER_SIZE) |
| 2030 | perd->kbd_store_ptr = perd->kbd_buffer; | 2125 | kbd_store_ptr = kbd_buffer; |
| 2031 | 2126 | ||
| 2032 | /* Don't let the very last slot in the buffer become full, | 2127 | /* Don't let the very last slot in the buffer become full, |
| 2033 | since that would make the two pointers equal, | 2128 | since that would make the two pointers equal, |
| 2034 | and that is indistinguishable from an empty buffer. | 2129 | and that is indistinguishable from an empty buffer. |
| 2035 | Discard the event if it would fill the last slot. */ | 2130 | Discard the event if it would fill the last slot. */ |
| 2036 | if (perd->kbd_fetch_ptr - 1 != perd->kbd_store_ptr) | 2131 | if (kbd_fetch_ptr - 1 != kbd_store_ptr) |
| 2037 | { | 2132 | { |
| 2038 | volatile struct input_event *sp = perd->kbd_store_ptr; | 2133 | volatile struct input_event *sp = kbd_store_ptr; |
| 2039 | sp->kind = event->kind; | 2134 | sp->kind = event->kind; |
| 2040 | if (event->kind == selection_request_event) | 2135 | if (event->kind == selection_request_event) |
| 2041 | { | 2136 | { |
| @@ -2054,11 +2149,11 @@ kbd_buffer_store_event (event) | |||
| 2054 | sp->y = event->y; | 2149 | sp->y = event->y; |
| 2055 | sp->timestamp = event->timestamp; | 2150 | sp->timestamp = event->timestamp; |
| 2056 | } | 2151 | } |
| 2057 | (XVECTOR (perd->kbd_buffer_frame_or_window)->contents[perd->kbd_store_ptr | 2152 | (XVECTOR (kbd_buffer_frame_or_window)->contents[kbd_store_ptr |
| 2058 | - perd->kbd_buffer] | 2153 | - kbd_buffer] |
| 2059 | = event->frame_or_window); | 2154 | = event->frame_or_window); |
| 2060 | 2155 | ||
| 2061 | perd->kbd_store_ptr++; | 2156 | kbd_store_ptr++; |
| 2062 | } | 2157 | } |
| 2063 | } | 2158 | } |
| 2064 | 2159 | ||
| @@ -2069,9 +2164,8 @@ kbd_buffer_store_event (event) | |||
| 2069 | We always read and discard one event. */ | 2164 | We always read and discard one event. */ |
| 2070 | 2165 | ||
| 2071 | static Lisp_Object | 2166 | static Lisp_Object |
| 2072 | kbd_buffer_get_event () | 2167 | kbd_buffer_get_event (PERDISPLAY **perdp) |
| 2073 | { | 2168 | { |
| 2074 | PERDISPLAY *perd; | ||
| 2075 | register int c; | 2169 | register int c; |
| 2076 | Lisp_Object obj; | 2170 | Lisp_Object obj; |
| 2077 | 2171 | ||
| @@ -2079,15 +2173,19 @@ kbd_buffer_get_event () | |||
| 2079 | { | 2173 | { |
| 2080 | c = getchar (); | 2174 | c = getchar (); |
| 2081 | XSETINT (obj, c); | 2175 | XSETINT (obj, c); |
| 2176 | *perdp = all_perdisplays; /* There'd better be exactly one! */ | ||
| 2082 | return obj; | 2177 | return obj; |
| 2083 | } | 2178 | } |
| 2084 | 2179 | ||
| 2085 | /* Wait until there is input available. */ | 2180 | /* Wait until there is input available. */ |
| 2086 | for (;;) | 2181 | for (;;) |
| 2087 | { | 2182 | { |
| 2088 | perd = find_active_event_queue (1); | 2183 | if (kbd_fetch_ptr != kbd_store_ptr) |
| 2089 | if (perd) | 2184 | break; |
| 2185 | #ifdef HAVE_MOUSE | ||
| 2186 | if (FRAMEP (do_mouse_tracking) && mouse_moved) | ||
| 2090 | break; | 2187 | break; |
| 2188 | #endif | ||
| 2091 | 2189 | ||
| 2092 | /* If the quit flag is set, then read_char will return | 2190 | /* If the quit flag is set, then read_char will return |
| 2093 | quit_char, so that counts as "available input." */ | 2191 | quit_char, so that counts as "available input." */ |
| @@ -2104,34 +2202,50 @@ kbd_buffer_get_event () | |||
| 2104 | #ifdef SIGIO | 2202 | #ifdef SIGIO |
| 2105 | gobble_input (0); | 2203 | gobble_input (0); |
| 2106 | #endif /* SIGIO */ | 2204 | #endif /* SIGIO */ |
| 2107 | perd = find_active_event_queue (1); | 2205 | if (kbd_fetch_ptr != kbd_store_ptr) |
| 2108 | if (!perd) | 2206 | break; |
| 2109 | { | 2207 | #ifdef HAVE_MOUSE |
| 2110 | Lisp_Object minus_one; | 2208 | if (FRAMEP (do_mouse_tracking) && mouse_moved) |
| 2209 | break; | ||
| 2210 | #endif | ||
| 2211 | { | ||
| 2212 | Lisp_Object minus_one; | ||
| 2111 | 2213 | ||
| 2112 | XSETINT (minus_one, -1); | 2214 | XSETINT (minus_one, -1); |
| 2113 | wait_reading_process_input (0, 0, minus_one, 1); | 2215 | wait_reading_process_input (0, 0, minus_one, 1); |
| 2114 | 2216 | ||
| 2115 | if (!interrupt_input && find_active_event_queue (0) == NULL) | 2217 | if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr) |
| 2116 | /* Pass 1 for EXPECT since we just waited to have input. */ | 2218 | /* Pass 1 for EXPECT since we just waited to have input. */ |
| 2117 | read_avail_input (1); | 2219 | read_avail_input (1); |
| 2118 | } | 2220 | } |
| 2119 | #endif /* not VMS */ | 2221 | #endif /* not VMS */ |
| 2120 | } | 2222 | } |
| 2121 | 2223 | ||
| 2122 | /* At this point, we know that there is a readable event available | 2224 | /* At this point, we know that there is a readable event available |
| 2123 | somewhere. If the event queue is empty, then there must be a | 2225 | somewhere. If the event queue is empty, then there must be a |
| 2124 | mouse movement enabled and available. */ | 2226 | mouse movement enabled and available. */ |
| 2125 | if (perd->kbd_fetch_ptr != perd->kbd_store_ptr) | 2227 | if (kbd_fetch_ptr != kbd_store_ptr) |
| 2126 | { | 2228 | { |
| 2127 | struct input_event *event; | 2229 | struct input_event *event; |
| 2128 | 2230 | ||
| 2129 | event = ((perd->kbd_fetch_ptr < perd->kbd_buffer + KBD_BUFFER_SIZE) | 2231 | event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE) |
| 2130 | ? perd->kbd_fetch_ptr | 2232 | ? kbd_fetch_ptr |
| 2131 | : perd->kbd_buffer); | 2233 | : kbd_buffer); |
| 2132 | 2234 | ||
| 2133 | last_event_timestamp = event->timestamp; | 2235 | last_event_timestamp = event->timestamp; |
| 2134 | 2236 | ||
| 2237 | { | ||
| 2238 | Lisp_Object frame; | ||
| 2239 | frame = event->frame_or_window; | ||
| 2240 | if (CONSP (frame)) | ||
| 2241 | frame = XCONS (frame)->car; | ||
| 2242 | else if (WINDOWP (frame)) | ||
| 2243 | frame = WINDOW_FRAME (XWINDOW (frame)); | ||
| 2244 | if (!FRAMEP (frame)) | ||
| 2245 | abort (); | ||
| 2246 | *perdp = get_perdisplay (XFRAME (frame)); | ||
| 2247 | } | ||
| 2248 | |||
| 2135 | obj = Qnil; | 2249 | obj = Qnil; |
| 2136 | 2250 | ||
| 2137 | /* These two kinds of events get special handling | 2251 | /* These two kinds of events get special handling |
| @@ -2144,7 +2258,7 @@ kbd_buffer_get_event () | |||
| 2144 | /* Remove it from the buffer before processing it, | 2258 | /* Remove it from the buffer before processing it, |
| 2145 | since otherwise swallow_events will see it | 2259 | since otherwise swallow_events will see it |
| 2146 | and process it again. */ | 2260 | and process it again. */ |
| 2147 | perd->kbd_fetch_ptr = event + 1; | 2261 | kbd_fetch_ptr = event + 1; |
| 2148 | x_handle_selection_request (©); | 2262 | x_handle_selection_request (©); |
| 2149 | #else | 2263 | #else |
| 2150 | /* We're getting selection request events, but we don't have | 2264 | /* We're getting selection request events, but we don't have |
| @@ -2157,7 +2271,7 @@ kbd_buffer_get_event () | |||
| 2157 | { | 2271 | { |
| 2158 | #ifdef HAVE_X11 | 2272 | #ifdef HAVE_X11 |
| 2159 | x_handle_selection_clear (event); | 2273 | x_handle_selection_clear (event); |
| 2160 | perd->kbd_fetch_ptr = event + 1; | 2274 | kbd_fetch_ptr = event + 1; |
| 2161 | #else | 2275 | #else |
| 2162 | /* We're getting selection request events, but we don't have | 2276 | /* We're getting selection request events, but we don't have |
| 2163 | a window system. */ | 2277 | a window system. */ |
| @@ -2170,40 +2284,42 @@ kbd_buffer_get_event () | |||
| 2170 | /* Make an event (delete-frame (FRAME)). */ | 2284 | /* Make an event (delete-frame (FRAME)). */ |
| 2171 | obj = Fcons (event->frame_or_window, Qnil); | 2285 | obj = Fcons (event->frame_or_window, Qnil); |
| 2172 | obj = Fcons (Qdelete_frame, Fcons (obj, Qnil)); | 2286 | obj = Fcons (Qdelete_frame, Fcons (obj, Qnil)); |
| 2173 | perd->kbd_fetch_ptr = event + 1; | 2287 | kbd_fetch_ptr = event + 1; |
| 2174 | } | 2288 | } |
| 2175 | else if (event->kind == iconify_event) | 2289 | else if (event->kind == iconify_event) |
| 2176 | { | 2290 | { |
| 2177 | /* Make an event (iconify-frame (FRAME)). */ | 2291 | /* Make an event (iconify-frame (FRAME)). */ |
| 2178 | obj = Fcons (event->frame_or_window, Qnil); | 2292 | obj = Fcons (event->frame_or_window, Qnil); |
| 2179 | obj = Fcons (Qiconify_frame, Fcons (obj, Qnil)); | 2293 | obj = Fcons (Qiconify_frame, Fcons (obj, Qnil)); |
| 2180 | perd->kbd_fetch_ptr = event + 1; | 2294 | kbd_fetch_ptr = event + 1; |
| 2181 | } | 2295 | } |
| 2182 | else if (event->kind == deiconify_event) | 2296 | else if (event->kind == deiconify_event) |
| 2183 | { | 2297 | { |
| 2184 | /* Make an event (make-frame-visible (FRAME)). */ | 2298 | /* Make an event (make-frame-visible (FRAME)). */ |
| 2185 | obj = Fcons (event->frame_or_window, Qnil); | 2299 | obj = Fcons (event->frame_or_window, Qnil); |
| 2186 | obj = Fcons (Qmake_frame_visible, Fcons (obj, Qnil)); | 2300 | obj = Fcons (Qmake_frame_visible, Fcons (obj, Qnil)); |
| 2187 | perd->kbd_fetch_ptr = event + 1; | 2301 | kbd_fetch_ptr = event + 1; |
| 2188 | } | 2302 | } |
| 2189 | #endif | 2303 | #endif |
| 2190 | else if (event->kind == menu_bar_event) | 2304 | else if (event->kind == menu_bar_event) |
| 2191 | { | 2305 | { |
| 2192 | /* The event value is in the frame_or_window slot. */ | 2306 | /* The event value is in the cdr of the frame_or_window slot. */ |
| 2193 | obj = event->frame_or_window; | 2307 | if (!CONSP (event->frame_or_window)) |
| 2194 | perd->kbd_fetch_ptr = event + 1; | 2308 | abort (); |
| 2309 | obj = XCONS (event->frame_or_window)->cdr; | ||
| 2310 | kbd_fetch_ptr = event + 1; | ||
| 2195 | } | 2311 | } |
| 2196 | else if (event->kind == buffer_switch_event) | 2312 | else if (event->kind == buffer_switch_event) |
| 2197 | { | 2313 | { |
| 2198 | /* The value doesn't matter here; only the type is tested. */ | 2314 | /* The value doesn't matter here; only the type is tested. */ |
| 2199 | XSETBUFFER (obj, current_buffer); | 2315 | XSETBUFFER (obj, current_buffer); |
| 2200 | perd->kbd_fetch_ptr = event + 1; | 2316 | kbd_fetch_ptr = event + 1; |
| 2201 | } | 2317 | } |
| 2202 | /* Just discard these, by returning nil. | 2318 | /* Just discard these, by returning nil. |
| 2203 | (They shouldn't be found in the buffer, | 2319 | (They shouldn't be found in the buffer, |
| 2204 | but on some machines it appears they do show up.) */ | 2320 | but on some machines it appears they do show up.) */ |
| 2205 | else if (event->kind == no_event) | 2321 | else if (event->kind == no_event) |
| 2206 | perd->kbd_fetch_ptr = event + 1; | 2322 | kbd_fetch_ptr = event + 1; |
| 2207 | 2323 | ||
| 2208 | /* If this event is on a different frame, return a switch-frame this | 2324 | /* If this event is on a different frame, return a switch-frame this |
| 2209 | time, and leave the event in the queue for next time. */ | 2325 | time, and leave the event in the queue for next time. */ |
| @@ -2221,10 +2337,10 @@ kbd_buffer_get_event () | |||
| 2221 | if (! NILP (focus)) | 2337 | if (! NILP (focus)) |
| 2222 | frame = focus; | 2338 | frame = focus; |
| 2223 | 2339 | ||
| 2224 | if (! EQ (frame, perd->internal_last_event_frame) | 2340 | if (! EQ (frame, (*perdp)->internal_last_event_frame) |
| 2225 | && XFRAME (frame) != selected_frame) | 2341 | && XFRAME (frame) != selected_frame) |
| 2226 | obj = make_lispy_switch_frame (frame); | 2342 | obj = make_lispy_switch_frame (frame); |
| 2227 | perd->internal_last_event_frame = frame; | 2343 | (*perdp)->internal_last_event_frame = frame; |
| 2228 | #endif /* MULTI_FRAME */ | 2344 | #endif /* MULTI_FRAME */ |
| 2229 | 2345 | ||
| 2230 | /* If we didn't decide to make a switch-frame event, go ahead | 2346 | /* If we didn't decide to make a switch-frame event, go ahead |
| @@ -2236,9 +2352,9 @@ kbd_buffer_get_event () | |||
| 2236 | 2352 | ||
| 2237 | /* Wipe out this event, to catch bugs. */ | 2353 | /* Wipe out this event, to catch bugs. */ |
| 2238 | event->kind = no_event; | 2354 | event->kind = no_event; |
| 2239 | XVECTOR (perd->kbd_buffer_frame_or_window)->contents[event - perd->kbd_buffer] = Qnil; | 2355 | XVECTOR (kbd_buffer_frame_or_window)->contents[event - kbd_buffer] = Qnil; |
| 2240 | 2356 | ||
| 2241 | perd->kbd_fetch_ptr = event + 1; | 2357 | kbd_fetch_ptr = event + 1; |
| 2242 | } | 2358 | } |
| 2243 | } | 2359 | } |
| 2244 | } | 2360 | } |
| @@ -2252,6 +2368,10 @@ kbd_buffer_get_event () | |||
| 2252 | Lisp_Object x, y; | 2368 | Lisp_Object x, y; |
| 2253 | unsigned long time; | 2369 | unsigned long time; |
| 2254 | 2370 | ||
| 2371 | if (!current_perdisplay) | ||
| 2372 | abort (); | ||
| 2373 | |||
| 2374 | *perdp = current_perdisplay; | ||
| 2255 | /* Note that this uses F to determine which display to look at. | 2375 | /* Note that this uses F to determine which display to look at. |
| 2256 | If there is no valid info, it does not store anything | 2376 | If there is no valid info, it does not store anything |
| 2257 | so x remains nil. */ | 2377 | so x remains nil. */ |
| @@ -2272,10 +2392,10 @@ kbd_buffer_get_event () | |||
| 2272 | if (NILP (frame)) | 2392 | if (NILP (frame)) |
| 2273 | XSETFRAME (frame, f); | 2393 | XSETFRAME (frame, f); |
| 2274 | 2394 | ||
| 2275 | if (! EQ (frame, perd->internal_last_event_frame) | 2395 | if (! EQ (frame, (*perdp)->internal_last_event_frame) |
| 2276 | && XFRAME (frame) != selected_frame) | 2396 | && XFRAME (frame) != selected_frame) |
| 2277 | obj = make_lispy_switch_frame (frame); | 2397 | obj = make_lispy_switch_frame (frame); |
| 2278 | perd->internal_last_event_frame = frame; | 2398 | (*perdp)->internal_last_event_frame = frame; |
| 2279 | } | 2399 | } |
| 2280 | #endif | 2400 | #endif |
| 2281 | 2401 | ||
| @@ -2293,7 +2413,7 @@ kbd_buffer_get_event () | |||
| 2293 | input_pending = readable_events (); | 2413 | input_pending = readable_events (); |
| 2294 | 2414 | ||
| 2295 | #ifdef MULTI_FRAME | 2415 | #ifdef MULTI_FRAME |
| 2296 | perd->Vlast_event_frame = perd->internal_last_event_frame; | 2416 | (*perdp)->Vlast_event_frame = (*perdp)->internal_last_event_frame; |
| 2297 | #endif | 2417 | #endif |
| 2298 | 2418 | ||
| 2299 | return (obj); | 2419 | return (obj); |
| @@ -2305,14 +2425,13 @@ kbd_buffer_get_event () | |||
| 2305 | void | 2425 | void |
| 2306 | swallow_events () | 2426 | swallow_events () |
| 2307 | { | 2427 | { |
| 2308 | PERDISPLAY *perd; | 2428 | while (kbd_fetch_ptr != kbd_store_ptr) |
| 2309 | while ((perd = find_active_event_queue (0)) != NULL) | ||
| 2310 | { | 2429 | { |
| 2311 | struct input_event *event; | 2430 | struct input_event *event; |
| 2312 | 2431 | ||
| 2313 | event = ((perd->kbd_fetch_ptr < perd->kbd_buffer + KBD_BUFFER_SIZE) | 2432 | event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE) |
| 2314 | ? perd->kbd_fetch_ptr | 2433 | ? kbd_fetch_ptr |
| 2315 | : perd->kbd_buffer); | 2434 | : kbd_buffer); |
| 2316 | 2435 | ||
| 2317 | last_event_timestamp = event->timestamp; | 2436 | last_event_timestamp = event->timestamp; |
| 2318 | 2437 | ||
| @@ -2323,7 +2442,7 @@ swallow_events () | |||
| 2323 | #ifdef HAVE_X11 | 2442 | #ifdef HAVE_X11 |
| 2324 | struct input_event copy; | 2443 | struct input_event copy; |
| 2325 | copy = *event; | 2444 | copy = *event; |
| 2326 | perd->kbd_fetch_ptr = event + 1; | 2445 | kbd_fetch_ptr = event + 1; |
| 2327 | x_handle_selection_request (©); | 2446 | x_handle_selection_request (©); |
| 2328 | #else | 2447 | #else |
| 2329 | /* We're getting selection request events, but we don't have | 2448 | /* We're getting selection request events, but we don't have |
| @@ -2336,7 +2455,7 @@ swallow_events () | |||
| 2336 | { | 2455 | { |
| 2337 | #ifdef HAVE_X11 | 2456 | #ifdef HAVE_X11 |
| 2338 | x_handle_selection_clear (event); | 2457 | x_handle_selection_clear (event); |
| 2339 | perd->kbd_fetch_ptr = event + 1; | 2458 | kbd_fetch_ptr = event + 1; |
| 2340 | #else | 2459 | #else |
| 2341 | /* We're getting selection request events, but we don't have | 2460 | /* We're getting selection request events, but we don't have |
| 2342 | a window system. */ | 2461 | a window system. */ |
| @@ -4701,8 +4820,19 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last) | |||
| 4701 | { | 4820 | { |
| 4702 | struct buffer *buf = current_buffer; | 4821 | struct buffer *buf = current_buffer; |
| 4703 | 4822 | ||
| 4704 | key = read_char (NILP (prompt), nmaps, submaps, last_nonmenu_event, | 4823 | { |
| 4705 | &used_mouse_menu); | 4824 | PERDISPLAY *interrupted_perdisplay = read_char_perdisplay; |
| 4825 | if (setjmp (wrong_display_jmpbuf)) | ||
| 4826 | { | ||
| 4827 | while (t > 0) | ||
| 4828 | interrupted_perdisplay->kbd_queue | ||
| 4829 | = Fcons (keybuf[--t], interrupted_perdisplay->kbd_queue); | ||
| 4830 | mock_input = 0; | ||
| 4831 | goto replay_sequence; | ||
| 4832 | } | ||
| 4833 | key = read_char (NILP (prompt), nmaps, submaps, last_nonmenu_event, | ||
| 4834 | &used_mouse_menu); | ||
| 4835 | } | ||
| 4706 | 4836 | ||
| 4707 | /* read_char returns t when it shows a menu and the user rejects it. | 4837 | /* read_char returns t when it shows a menu and the user rejects it. |
| 4708 | Just return -1. */ | 4838 | Just return -1. */ |
| @@ -5660,9 +5790,8 @@ Also cancel any kbd macro being defined.") | |||
| 5660 | /* Without the cast, GCC complains that this assignment loses the | 5790 | /* Without the cast, GCC complains that this assignment loses the |
| 5661 | volatile qualifier of kbd_store_ptr. Is there anything wrong | 5791 | volatile qualifier of kbd_store_ptr. Is there anything wrong |
| 5662 | with that? */ | 5792 | with that? */ |
| 5663 | current_perdisplay->kbd_fetch_ptr | 5793 | kbd_fetch_ptr = (struct input_event *) kbd_store_ptr; |
| 5664 | = (struct input_event *) current_perdisplay->kbd_store_ptr; | 5794 | Ffillarray (kbd_buffer_frame_or_window, Qnil); |
| 5665 | Ffillarray (current_perdisplay->kbd_buffer_frame_or_window, Qnil); | ||
| 5666 | input_pending = 0; | 5795 | input_pending = 0; |
| 5667 | 5796 | ||
| 5668 | return Qnil; | 5797 | return Qnil; |
| @@ -5735,7 +5864,6 @@ stuff_buffered_input (stuffstring) | |||
| 5735 | #ifdef BSD | 5864 | #ifdef BSD |
| 5736 | #ifndef BSD4_1 | 5865 | #ifndef BSD4_1 |
| 5737 | register unsigned char *p; | 5866 | register unsigned char *p; |
| 5738 | PERDISPLAY *perd; | ||
| 5739 | 5867 | ||
| 5740 | if (STRINGP (stuffstring)) | 5868 | if (STRINGP (stuffstring)) |
| 5741 | { | 5869 | { |
| @@ -5748,25 +5876,18 @@ stuff_buffered_input (stuffstring) | |||
| 5748 | stuff_char ('\n'); | 5876 | stuff_char ('\n'); |
| 5749 | } | 5877 | } |
| 5750 | /* Anything we have read ahead, put back for the shell to read. */ | 5878 | /* Anything we have read ahead, put back for the shell to read. */ |
| 5751 | #ifndef MULTI_PERDISPLAY | 5879 | /* ?? What should this do when we have multiple keyboards?? |
| 5752 | perd = &the_only_perdisplay; | 5880 | Should we ignore anything that was typed in at the "wrong" display? */ |
| 5753 | #else | 5881 | for (; kbd_fetch_ptr != kbd_store_ptr; kbd_fetch_ptr++) |
| 5754 | /* ?? What should this do when we have multiple keyboards?? */ | ||
| 5755 | perd = current_perdisplay; | ||
| 5756 | if (!perd) | ||
| 5757 | return; | ||
| 5758 | #endif | ||
| 5759 | while (perd->kbd_fetch_ptr != perd->kbd_store_ptr) | ||
| 5760 | { | 5882 | { |
| 5761 | if (perd->kbd_fetch_ptr == perd->kbd_buffer + KBD_BUFFER_SIZE) | 5883 | if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) |
| 5762 | perd->kbd_fetch_ptr = perd->kbd_buffer; | 5884 | kbd_fetch_ptr = kbd_buffer; |
| 5763 | if (perd->kbd_fetch_ptr->kind == ascii_keystroke) | 5885 | if (kbd_fetch_ptr->kind == ascii_keystroke) |
| 5764 | stuff_char (perd->kbd_fetch_ptr->code); | 5886 | stuff_char (kbd_fetch_ptr->code); |
| 5765 | perd->kbd_fetch_ptr->kind = no_event; | 5887 | kbd_fetch_ptr->kind = no_event; |
| 5766 | (XVECTOR (perd->kbd_buffer_frame_or_window)->contents[perd->kbd_fetch_ptr | 5888 | (XVECTOR (kbd_buffer_frame_or_window)->contents[kbd_fetch_ptr |
| 5767 | - perd->kbd_buffer] | 5889 | - kbd_buffer] |
| 5768 | = Qnil); | 5890 | = Qnil); |
| 5769 | perd->kbd_fetch_ptr++; | ||
| 5770 | } | 5891 | } |
| 5771 | input_pending = 0; | 5892 | input_pending = 0; |
| 5772 | #endif | 5893 | #endif |
| @@ -6042,18 +6163,12 @@ init_perdisplay (perd) | |||
| 6042 | { | 6163 | { |
| 6043 | perd->Vprefix_arg = Qnil; | 6164 | perd->Vprefix_arg = Qnil; |
| 6044 | perd->Vcurrent_prefix_arg = Qnil; | 6165 | perd->Vcurrent_prefix_arg = Qnil; |
| 6045 | perd->kbd_buffer | ||
| 6046 | = (struct input_event *)xmalloc (KBD_BUFFER_SIZE | ||
| 6047 | * sizeof (struct input_event)); | ||
| 6048 | perd->kbd_fetch_ptr = perd->kbd_buffer; | ||
| 6049 | perd->kbd_store_ptr = perd->kbd_buffer; | ||
| 6050 | perd->kbd_buffer_frame_or_window | ||
| 6051 | = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil); | ||
| 6052 | #ifdef MULTI_FRAME | 6166 | #ifdef MULTI_FRAME |
| 6053 | /* This means that command_loop_1 won't try to select anything the first | 6167 | /* This means that command_loop_1 won't try to select anything the first |
| 6054 | time through. */ | 6168 | time through. */ |
| 6055 | perd->internal_last_event_frame = Qnil; | 6169 | perd->internal_last_event_frame = Qnil; |
| 6056 | #endif | 6170 | #endif |
| 6171 | perd->kbd_queue = Qnil; | ||
| 6057 | perd->Vlast_event_frame = Qnil; | 6172 | perd->Vlast_event_frame = Qnil; |
| 6058 | perd->immediate_echo = 0; | 6173 | perd->immediate_echo = 0; |
| 6059 | perd->echoptr = perd->echobuf; | 6174 | perd->echoptr = perd->echobuf; |
| @@ -6069,7 +6184,8 @@ void | |||
| 6069 | wipe_perdisplay (perd) | 6184 | wipe_perdisplay (perd) |
| 6070 | PERDISPLAY *perd; | 6185 | PERDISPLAY *perd; |
| 6071 | { | 6186 | { |
| 6072 | xfree (perd->kbd_buffer); | 6187 | /* Free anything that was malloc'd in init_perdisplay. */ |
| 6188 | /* Placeholder -- currently no action required. */ | ||
| 6073 | } | 6189 | } |
| 6074 | 6190 | ||
| 6075 | init_keyboard () | 6191 | init_keyboard () |
| @@ -6082,6 +6198,10 @@ init_keyboard () | |||
| 6082 | unread_command_char = -1; | 6198 | unread_command_char = -1; |
| 6083 | total_keys = 0; | 6199 | total_keys = 0; |
| 6084 | recent_keys_index = 0; | 6200 | recent_keys_index = 0; |
| 6201 | kbd_fetch_ptr = kbd_buffer; | ||
| 6202 | kbd_store_ptr = kbd_buffer; | ||
| 6203 | kbd_buffer_frame_or_window | ||
| 6204 | = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil); | ||
| 6085 | #ifdef HAVE_MOUSE | 6205 | #ifdef HAVE_MOUSE |
| 6086 | do_mouse_tracking = Qnil; | 6206 | do_mouse_tracking = Qnil; |
| 6087 | #endif | 6207 | #endif |
| @@ -6093,6 +6213,11 @@ init_keyboard () | |||
| 6093 | init_perdisplay (&the_only_perdisplay); | 6213 | init_perdisplay (&the_only_perdisplay); |
| 6094 | #endif | 6214 | #endif |
| 6095 | 6215 | ||
| 6216 | if (initialized) | ||
| 6217 | Ffillarray (kbd_buffer_frame_or_window, Qnil); | ||
| 6218 | |||
| 6219 | kbd_buffer_frame_or_window | ||
| 6220 | = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil); | ||
| 6096 | if (!noninteractive && !read_socket_hook && NILP (Vwindow_system)) | 6221 | if (!noninteractive && !read_socket_hook && NILP (Vwindow_system)) |
| 6097 | { | 6222 | { |
| 6098 | signal (SIGINT, interrupt_signal); | 6223 | signal (SIGINT, interrupt_signal); |
| @@ -6262,6 +6387,10 @@ syms_of_keyboard () | |||
| 6262 | Fset (Qextended_command_history, Qnil); | 6387 | Fset (Qextended_command_history, Qnil); |
| 6263 | staticpro (&Qextended_command_history); | 6388 | staticpro (&Qextended_command_history); |
| 6264 | 6389 | ||
| 6390 | kbd_buffer_frame_or_window | ||
| 6391 | = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil); | ||
| 6392 | staticpro (&kbd_buffer_frame_or_window); | ||
| 6393 | |||
| 6265 | accent_key_syms = Qnil; | 6394 | accent_key_syms = Qnil; |
| 6266 | staticpro (&accent_key_syms); | 6395 | staticpro (&accent_key_syms); |
| 6267 | 6396 | ||