diff options
| author | Jim Blandy | 1992-10-02 23:55:39 +0000 |
|---|---|---|
| committer | Jim Blandy | 1992-10-02 23:55:39 +0000 |
| commit | 88cb06568fc329c9d4220abe74722a82c2d7fc80 (patch) | |
| tree | 5e52bf8f8832514b73b210c7f7ae4f692d4a906d /src | |
| parent | f9969361bd98a6def908db1670f15d7c8dad1785 (diff) | |
| download | emacs-88cb06568fc329c9d4220abe74722a82c2d7fc80.tar.gz emacs-88cb06568fc329c9d4220abe74722a82c2d7fc80.zip | |
* keyboard.c (echo_char, read_char): Apply EVENT_HEAD without first
testing for EVENT_HAS_PARAMETERS; EVENT_HEAD works properly on
all sorts of events now.
(read_key_sequence): Use the new accessors to decide in which window
an event occurred.
* keyboard.c (Qevent_unmodified): Replaced by...
(Qevent_symbol_elements): New property.
(syms_of_keyboard): initialize and staticpro the latter, not the
former.
* keyboard.c (readable_events): This doesn't need to scan and
discard mouse release events anymore; it just uses
EVENT_QUEUES_EMPTY.
(kbd_buffer_get_event): No need to skip past mouse release events.
* keyboard.c (button_down_location): New variable, which
stores the location at which each button was pressed, so we
can build a complete drag event when the button is released.
(make_lispy_event): When a button is pressed, record its
location in button_down_location, and turn it into a `down'
event. When a button is released, compare its release
location with its press location, and decide whether to call
it a `click' or `drag' event.
Change mouse movement events to be arranged like click events.
(format_modifiers): Note that the click modifier has no
written representation.
(modifier_names, modifer_symbols): New variables, used to
create the Qevent_symbol_elements property.
(modify_event_symbol): Change the format of the modified
symbol cache; there are too many modifier bits now to use a
vector indexed by a modifier mask. Use an assoc-list instead.
Document the format of the cache.
Put the Qevent_symbol_elements property on each new symbol,
instead of a Qevent_unmodified property.
(symbols_of_keyboard): Put Qevent_symbol_elements properties on
the symbols specified in head_table, not Qevent_unmodifed properties.
Initialize and staticpro modifier_symbols, and staticpro the
window elements of button_down_location.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 334 |
1 files changed, 201 insertions, 133 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index df53edd4138..d0b4b526a14 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -293,7 +293,7 @@ Lisp_Object Qscrollbar_click; | |||
| 293 | 293 | ||
| 294 | /* Properties of event headers. */ | 294 | /* Properties of event headers. */ |
| 295 | Lisp_Object Qevent_kind; | 295 | Lisp_Object Qevent_kind; |
| 296 | Lisp_Object Qevent_unmodified; | 296 | Lisp_Object Qevent_symbol_elements; |
| 297 | 297 | ||
| 298 | /* Symbols to use for non-text mouse positions. */ | 298 | /* Symbols to use for non-text mouse positions. */ |
| 299 | Lisp_Object Qmode_line; | 299 | Lisp_Object Qmode_line; |
| @@ -392,8 +392,7 @@ echo_char (c) | |||
| 392 | *ptr++ = ' '; | 392 | *ptr++ = ' '; |
| 393 | 393 | ||
| 394 | /* If someone has passed us a composite event, use its head symbol. */ | 394 | /* If someone has passed us a composite event, use its head symbol. */ |
| 395 | if (EVENT_HAS_PARAMETERS (c)) | 395 | c = EVENT_HEAD (c); |
| 396 | c = EVENT_HEAD (c); | ||
| 397 | 396 | ||
| 398 | if (XTYPE (c) == Lisp_Int) | 397 | if (XTYPE (c) == Lisp_Int) |
| 399 | { | 398 | { |
| @@ -1283,8 +1282,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1283 | Lisp_Object dribblee = c; | 1282 | Lisp_Object dribblee = c; |
| 1284 | 1283 | ||
| 1285 | /* If it's a structured event, take the event header. */ | 1284 | /* If it's a structured event, take the event header. */ |
| 1286 | if (EVENT_HAS_PARAMETERS (dribblee)) | 1285 | dribblee = EVENT_HEAD (dribblee); |
| 1287 | dribblee = EVENT_HEAD (dribblee); | ||
| 1288 | 1286 | ||
| 1289 | if (XTYPE (c) == Lisp_Symbol) | 1287 | if (XTYPE (c) == Lisp_Symbol) |
| 1290 | { | 1288 | { |
| @@ -1385,30 +1383,7 @@ extern int frame_garbaged; | |||
| 1385 | static int | 1383 | static int |
| 1386 | readable_events () | 1384 | readable_events () |
| 1387 | { | 1385 | { |
| 1388 | struct input_event *ep; | 1386 | return ! EVENT_QUEUES_EMPTY; |
| 1389 | |||
| 1390 | if (EVENT_QUEUES_EMPTY) | ||
| 1391 | return 0; | ||
| 1392 | |||
| 1393 | if (do_mouse_tracking) | ||
| 1394 | return 1; | ||
| 1395 | |||
| 1396 | /* Mouse tracking is disabled, so we need to actually scan the | ||
| 1397 | input queue to see if any events are currently readable. */ | ||
| 1398 | for (ep = kbd_fetch_ptr; ep != kbd_store_ptr; ep++) | ||
| 1399 | { | ||
| 1400 | if (ep == kbd_buffer + KBD_BUFFER_SIZE) | ||
| 1401 | ep = kbd_buffer; | ||
| 1402 | |||
| 1403 | /* Skip button-up events. */ | ||
| 1404 | if ((ep->kind == mouse_click || ep->kind == scrollbar_click) | ||
| 1405 | && (ep->modifiers & up_modifier)) | ||
| 1406 | continue; | ||
| 1407 | |||
| 1408 | return 1; | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | return 0; | ||
| 1412 | } | 1387 | } |
| 1413 | 1388 | ||
| 1414 | 1389 | ||
| @@ -1537,28 +1512,6 @@ kbd_buffer_get_event () | |||
| 1537 | /* Wait until there is input available. */ | 1512 | /* Wait until there is input available. */ |
| 1538 | for (;;) | 1513 | for (;;) |
| 1539 | { | 1514 | { |
| 1540 | |||
| 1541 | /* Process or toss any events that we don't want to return as | ||
| 1542 | input. The fact that we remove undesirable events here | ||
| 1543 | allows us to use EVENT_QUEUES_EMPTY in the rest of this loop. */ | ||
| 1544 | if (! do_mouse_tracking) | ||
| 1545 | while (kbd_fetch_ptr != kbd_store_ptr) | ||
| 1546 | { | ||
| 1547 | if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) | ||
| 1548 | kbd_fetch_ptr = kbd_buffer; | ||
| 1549 | |||
| 1550 | if (kbd_fetch_ptr->kind == mouse_click | ||
| 1551 | || kbd_fetch_ptr->kind == scrollbar_click) | ||
| 1552 | { | ||
| 1553 | if ((kbd_fetch_ptr->modifiers & up_modifier) == 0) | ||
| 1554 | break; | ||
| 1555 | } | ||
| 1556 | else | ||
| 1557 | break; | ||
| 1558 | |||
| 1559 | kbd_fetch_ptr++; | ||
| 1560 | } | ||
| 1561 | |||
| 1562 | if (!EVENT_QUEUES_EMPTY) | 1515 | if (!EVENT_QUEUES_EMPTY) |
| 1563 | break; | 1516 | break; |
| 1564 | 1517 | ||
| @@ -1720,9 +1673,23 @@ static char *lispy_mouse_names[] = | |||
| 1720 | "mouse-1", "mouse-2", "mouse-3", "mouse-4", "mouse-5" | 1673 | "mouse-1", "mouse-2", "mouse-3", "mouse-4", "mouse-5" |
| 1721 | }; | 1674 | }; |
| 1722 | 1675 | ||
| 1676 | /* make_lispy_event stores the down-going location of the currently | ||
| 1677 | depressed buttons in button_down_locations. */ | ||
| 1678 | struct mouse_position { | ||
| 1679 | Lisp_Object window; | ||
| 1680 | Lisp_Object buffer_pos; | ||
| 1681 | Lisp_Object x, y; | ||
| 1682 | Lisp_Object timestamp; | ||
| 1683 | }; | ||
| 1684 | static struct mouse_position button_down_location[NUM_MOUSE_BUTTONS]; | ||
| 1685 | |||
| 1723 | /* Given a struct input_event, build the lisp event which represents | 1686 | /* Given a struct input_event, build the lisp event which represents |
| 1724 | it. If EVENT is 0, build a mouse movement event from the mouse | 1687 | it. If EVENT is 0, build a mouse movement event from the mouse |
| 1725 | movement buffer, which should have a movement event in it. */ | 1688 | movement buffer, which should have a movement event in it. |
| 1689 | |||
| 1690 | Note that events must be passed to this function in the order they | ||
| 1691 | are received; this function stores the location of button presses | ||
| 1692 | in order to build drag events when the button is released. */ | ||
| 1726 | 1693 | ||
| 1727 | static Lisp_Object | 1694 | static Lisp_Object |
| 1728 | make_lispy_event (event) | 1695 | make_lispy_event (event) |
| @@ -1734,7 +1701,6 @@ make_lispy_event (event) | |||
| 1734 | switch (event->kind) | 1701 | switch (event->kind) |
| 1735 | #endif | 1702 | #endif |
| 1736 | { | 1703 | { |
| 1737 | |||
| 1738 | /* A simple keystroke. */ | 1704 | /* A simple keystroke. */ |
| 1739 | case ascii_keystroke: | 1705 | case ascii_keystroke: |
| 1740 | return event->code; | 1706 | return event->code; |
| @@ -1750,16 +1716,22 @@ make_lispy_event (event) | |||
| 1750 | / sizeof (lispy_function_keys[0]))); | 1716 | / sizeof (lispy_function_keys[0]))); |
| 1751 | break; | 1717 | break; |
| 1752 | 1718 | ||
| 1753 | /* A mouse click - build a list of the relevant information. */ | 1719 | /* A mouse click. Figure out where it is, decide whether it's |
| 1720 | a press, click or drag, and build the appropriate structure. */ | ||
| 1754 | case mouse_click: | 1721 | case mouse_click: |
| 1755 | { | 1722 | { |
| 1756 | int part; | 1723 | int part; |
| 1757 | Lisp_Object window = | 1724 | Lisp_Object window; |
| 1758 | window_from_coordinates (event->frame, | ||
| 1759 | XINT (event->x), XINT (event->y), | ||
| 1760 | &part); | ||
| 1761 | Lisp_Object posn; | 1725 | Lisp_Object posn; |
| 1726 | struct mouse_position *loc; | ||
| 1762 | 1727 | ||
| 1728 | if (event->code < 0 || event->code >= NUM_MOUSE_BUTTONS) | ||
| 1729 | abort (); | ||
| 1730 | |||
| 1731 | /* Where did this mouse click occur? */ | ||
| 1732 | window = window_from_coordinates (event->frame, | ||
| 1733 | XINT (event->x), XINT (event->y), | ||
| 1734 | &part); | ||
| 1763 | if (XTYPE (window) != Lisp_Window) | 1735 | if (XTYPE (window) != Lisp_Window) |
| 1764 | posn = Qnil; | 1736 | posn = Qnil; |
| 1765 | else | 1737 | else |
| @@ -1768,7 +1740,6 @@ make_lispy_event (event) | |||
| 1768 | - XINT (XWINDOW (window)->left))); | 1740 | - XINT (XWINDOW (window)->left))); |
| 1769 | XSETINT (event->y, (XINT (event->y) | 1741 | XSETINT (event->y, (XINT (event->y) |
| 1770 | - XINT (XWINDOW (window)->top))); | 1742 | - XINT (XWINDOW (window)->top))); |
| 1771 | |||
| 1772 | if (part == 1) | 1743 | if (part == 1) |
| 1773 | posn = Qmode_line; | 1744 | posn = Qmode_line; |
| 1774 | else if (part == 2) | 1745 | else if (part == 2) |
| @@ -1780,18 +1751,67 @@ make_lispy_event (event) | |||
| 1780 | XINT (event->y))); | 1751 | XINT (event->y))); |
| 1781 | } | 1752 | } |
| 1782 | 1753 | ||
| 1783 | return Fcons (modify_event_symbol (XFASTINT (event->code) - 1, | 1754 | /* If this is a button press, squirrel away the location, so we |
| 1784 | event->modifiers, | 1755 | can decide later whether it was a click or a drag. */ |
| 1785 | Qmouse_click, | 1756 | loc = button_down_location + event->code; |
| 1786 | lispy_mouse_names, &mouse_syms, | 1757 | if (event->modifiers & down_modifier) |
| 1787 | (sizeof (lispy_mouse_names) | 1758 | { |
| 1788 | / sizeof (lispy_mouse_names[0]))), | 1759 | loc->window = window; |
| 1789 | Fcons (window, | 1760 | loc->buffer_pos = posn; |
| 1790 | Fcons (posn, | 1761 | loc->x = event->x; |
| 1791 | Fcons (Fcons (event->x, event->y), | 1762 | loc->y = event->y; |
| 1792 | Fcons (make_number | 1763 | loc->timestamp = event->timestamp; |
| 1793 | (event->timestamp), | 1764 | } |
| 1794 | Qnil))))); | 1765 | |
| 1766 | /* Now we're releasing a button - check the co-ordinates to | ||
| 1767 | see if this was a click or a drag. */ | ||
| 1768 | else if (event->modifiers & up_modifier) | ||
| 1769 | { | ||
| 1770 | event->modifiers &= ~up_modifier; | ||
| 1771 | event->modifiers |= ((event->x == loc->x && event->y == loc->y) | ||
| 1772 | ? click_modifier | ||
| 1773 | : drag_modifier); | ||
| 1774 | } | ||
| 1775 | else | ||
| 1776 | /* Every mouse event should either have the down_modifier or | ||
| 1777 | the up_modifier set. */ | ||
| 1778 | abort (); | ||
| 1779 | |||
| 1780 | |||
| 1781 | /* Build the event. */ | ||
| 1782 | { | ||
| 1783 | Lisp_Object head, start, end; | ||
| 1784 | |||
| 1785 | /* Build the components of the event. */ | ||
| 1786 | head = modify_event_symbol (XFASTINT (event->code) - 1, | ||
| 1787 | event->modifiers, | ||
| 1788 | Qmouse_click, | ||
| 1789 | lispy_mouse_names, &mouse_syms, | ||
| 1790 | (sizeof (lispy_mouse_names) | ||
| 1791 | / sizeof (lispy_mouse_names[0]))); | ||
| 1792 | end = Fcons (window, | ||
| 1793 | Fcons (posn, | ||
| 1794 | Fcons (Fcons (event->x, event->y), | ||
| 1795 | Fcons (make_number (event->timestamp), | ||
| 1796 | Qnil)))); | ||
| 1797 | if (event->modifiers & drag_modifier) | ||
| 1798 | start = Fcons (loc->window, | ||
| 1799 | Fcons (loc->buffer_pos, | ||
| 1800 | Fcons (Fcons (loc->x, loc->y), | ||
| 1801 | Fcons (make_number (loc->timestamp), | ||
| 1802 | Qnil)))); | ||
| 1803 | |||
| 1804 | /* Assemble the pieces. */ | ||
| 1805 | if (event->modifiers & drag_modifier) | ||
| 1806 | return Fcons (head, | ||
| 1807 | Fcons (start, | ||
| 1808 | Fcons (end, | ||
| 1809 | Qnil))); | ||
| 1810 | else | ||
| 1811 | return Fcons (head, | ||
| 1812 | Fcons (end, | ||
| 1813 | Qnil)); | ||
| 1814 | } | ||
| 1795 | } | 1815 | } |
| 1796 | 1816 | ||
| 1797 | /* A scrollbar click. Build a list containing the relevant | 1817 | /* A scrollbar click. Build a list containing the relevant |
| @@ -1854,10 +1874,12 @@ make_lispy_movement (frame, x, y, time) | |||
| 1854 | XSETINT (x, ix); | 1874 | XSETINT (x, ix); |
| 1855 | XSETINT (y, iy); | 1875 | XSETINT (y, iy); |
| 1856 | return Fcons (Qmouse_movement, | 1876 | return Fcons (Qmouse_movement, |
| 1857 | Fcons (window, | 1877 | Fcons (Fcons (window, |
| 1858 | Fcons (posn, | 1878 | Fcons (posn, |
| 1859 | Fcons (Fcons (x, y), | 1879 | Fcons (Fcons (x, y), |
| 1860 | Fcons (make_number (time), Qnil))))); | 1880 | Fcons (make_number (time), |
| 1881 | Qnil)))), | ||
| 1882 | Qnil)); | ||
| 1861 | } | 1883 | } |
| 1862 | 1884 | ||
| 1863 | 1885 | ||
| @@ -1872,8 +1894,8 @@ format_modifiers (modifiers, buf) | |||
| 1872 | { | 1894 | { |
| 1873 | char *p = buf; | 1895 | char *p = buf; |
| 1874 | 1896 | ||
| 1875 | /* Events with the `up' modifier should always be turned into | 1897 | /* Only the event queue may use the `up' modifier; it should always |
| 1876 | click or drag events. */ | 1898 | be turned into a click or drag event before presented to lisp code. */ |
| 1877 | if (modifiers & up_modifier) | 1899 | if (modifiers & up_modifier) |
| 1878 | abort (); | 1900 | abort (); |
| 1879 | 1901 | ||
| @@ -1885,6 +1907,7 @@ format_modifiers (modifiers, buf) | |||
| 1885 | if (modifiers & super_modifier) { strcpy (p, "super-"); p += 6; } | 1907 | if (modifiers & super_modifier) { strcpy (p, "super-"); p += 6; } |
| 1886 | if (modifiers & down_modifier) { strcpy (p, "down-"); p += 5; } | 1908 | if (modifiers & down_modifier) { strcpy (p, "down-"); p += 5; } |
| 1887 | if (modifiers & drag_modifier) { strcpy (p, "drag-"); p += 5; } | 1909 | if (modifiers & drag_modifier) { strcpy (p, "drag-"); p += 5; } |
| 1910 | /* The click modifier is denoted by the absence of other modifiers. */ | ||
| 1888 | *p = '\0'; | 1911 | *p = '\0'; |
| 1889 | 1912 | ||
| 1890 | return p - buf; | 1913 | return p - buf; |
| @@ -1894,7 +1917,7 @@ format_modifiers (modifiers, buf) | |||
| 1894 | /* Given a symbol whose name begins with modifiers ("C-", "M-", etc), | 1917 | /* Given a symbol whose name begins with modifiers ("C-", "M-", etc), |
| 1895 | return a symbol with the modifiers placed in the canonical order. | 1918 | return a symbol with the modifiers placed in the canonical order. |
| 1896 | Canonical order is alphabetical, except for down and drag, which | 1919 | Canonical order is alphabetical, except for down and drag, which |
| 1897 | always come last. | 1920 | always come last. The 'click' modifier is never written out. |
| 1898 | 1921 | ||
| 1899 | Fdefine_key calls this to make sure that (for example) C-M-foo | 1922 | Fdefine_key calls this to make sure that (for example) C-M-foo |
| 1900 | and M-C-foo end up being equivalent in the keymap. */ | 1923 | and M-C-foo end up being equivalent in the keymap. */ |
| @@ -2029,7 +2052,19 @@ reorder_modifiers (symbol) | |||
| 2029 | whose prefixes should be applied to the symbol name. | 2052 | whose prefixes should be applied to the symbol name. |
| 2030 | 2053 | ||
| 2031 | SYMBOL_KIND is the value to be placed in the event_kind property of | 2054 | SYMBOL_KIND is the value to be placed in the event_kind property of |
| 2032 | the returned symbol. */ | 2055 | the returned symbol. |
| 2056 | |||
| 2057 | The symbols we create are supposed to have an | ||
| 2058 | `event-symbol-elements' propery, which lists the modifiers present | ||
| 2059 | in the symbol's name. */ | ||
| 2060 | |||
| 2061 | static char *modifier_names[] = | ||
| 2062 | { | ||
| 2063 | "up", "alt", "ctrl", "hyper", "meta", "shift", "super", "down", "drag", | ||
| 2064 | "click" | ||
| 2065 | }; | ||
| 2066 | |||
| 2067 | static Lisp_Object modifier_symbols; | ||
| 2033 | 2068 | ||
| 2034 | static Lisp_Object | 2069 | static Lisp_Object |
| 2035 | modify_event_symbol (symbol_num, modifiers, symbol_kind, name_table, | 2070 | modify_event_symbol (symbol_num, modifiers, symbol_kind, name_table, |
| @@ -2041,76 +2076,89 @@ modify_event_symbol (symbol_num, modifiers, symbol_kind, name_table, | |||
| 2041 | Lisp_Object *symbol_table; | 2076 | Lisp_Object *symbol_table; |
| 2042 | int table_size; | 2077 | int table_size; |
| 2043 | { | 2078 | { |
| 2044 | Lisp_Object *slot, *unmodified_slot; | 2079 | Lisp_Object *slot; |
| 2080 | Lisp_Object unmodified; | ||
| 2081 | Lisp_Object temp; | ||
| 2045 | 2082 | ||
| 2046 | /* Is this a request for a valid symbol? */ | 2083 | /* Is this a request for a valid symbol? */ |
| 2047 | if (symbol_num < 0 || symbol_num >= table_size | 2084 | if (symbol_num < 0 || symbol_num >= table_size) |
| 2048 | || modifiers >= NUM_MODIFIER_COMBOS) | ||
| 2049 | abort (); | 2085 | abort (); |
| 2050 | 2086 | ||
| 2051 | /* If *symbol_table is not a vector of the appropriate size, | 2087 | /* If *symbol_table doesn't seem to be initialized property, fix that. |
| 2052 | set it to one. */ | 2088 | |
| 2089 | *symbol_table should be a lisp vector TABLE_SIZE elements long, | ||
| 2090 | where the Nth element is an alist for modified versions of | ||
| 2091 | name_table[N]; the alist maps modifier masks onto the modified | ||
| 2092 | symbols. The click modifier is always omitted from the mask; it | ||
| 2093 | is indicated implicitly on a mouse event by the absence of the | ||
| 2094 | down_ and drag_ modifiers. */ | ||
| 2053 | if (XTYPE (*symbol_table) != Lisp_Vector | 2095 | if (XTYPE (*symbol_table) != Lisp_Vector |
| 2054 | || XVECTOR (*symbol_table)->size != table_size) | 2096 | || XVECTOR (*symbol_table)->size != table_size) |
| 2055 | *symbol_table = Fmake_vector (make_number (table_size), Qnil); | 2097 | { |
| 2098 | XFASTINT (temp) = table_size; | ||
| 2099 | *symbol_table = Fmake_vector (temp, Qnil); | ||
| 2100 | } | ||
| 2056 | 2101 | ||
| 2057 | unmodified_slot = slot = & XVECTOR (*symbol_table)->contents[symbol_num]; | 2102 | slot = & XVECTOR (*symbol_table)->contents[symbol_num]; |
| 2058 | 2103 | ||
| 2059 | /* If there are modifier keys, there had better be a vector in | 2104 | /* Have we already modified this symbol? */ |
| 2060 | this symbol's position of the symbol_table. */ | 2105 | XFASTINT (temp) = modifiers & ~(click_modifier); |
| 2061 | if (modifiers != 0) | 2106 | temp = Fassq (temp, *slot); |
| 2062 | { | 2107 | if (CONSP (temp)) |
| 2063 | Lisp_Object slot_contents = *slot; | 2108 | return (XCONS (temp)->cdr); |
| 2064 | 2109 | ||
| 2065 | /* If there isn't the right sort of vector there, put one in. */ | 2110 | /* We don't have an entry for the symbol; we have to build it. */ |
| 2066 | if (XTYPE (slot_contents) != Lisp_Vector | ||
| 2067 | || XVECTOR (slot_contents)->size != NUM_MODIFIER_COMBOS) | ||
| 2068 | { | ||
| 2069 | *slot = Fmake_vector (make_number (NUM_MODIFIER_COMBOS), Qnil); | ||
| 2070 | 2111 | ||
| 2071 | /* Make sure that the vector has an entry for the unmodified | 2112 | /* Make sure there's an assoc for the unmodified symbol. |
| 2072 | symbol, so we can put it on the event_unmodified property. */ | 2113 | Any non-empty alist should contain an entry for the unmodified symbol. */ |
| 2073 | if (! NILP (slot_contents)) | 2114 | XFASTINT (temp) = 0; |
| 2074 | XVECTOR (*slot)->contents[0] = slot_contents; | ||
| 2075 | else | ||
| 2076 | XVECTOR (*slot)->contents[0] = intern (name_table [symbol_num]); | ||
| 2077 | } | ||
| 2078 | } | ||
| 2079 | 2115 | ||
| 2080 | /* If this entry has been filled in with a modified symbol vector, | 2116 | if (NILP (*slot)) |
| 2081 | point to the appropriate slot within that. */ | ||
| 2082 | if (XTYPE (*slot) == Lisp_Vector) | ||
| 2083 | { | 2117 | { |
| 2084 | unmodified_slot = & XVECTOR (*slot)->contents[0]; | 2118 | unmodified = intern (name_table [symbol_num]); |
| 2085 | slot = & XVECTOR (*slot)->contents[modifiers]; | 2119 | *slot = Fcons (Fcons (temp, unmodified), Qnil); |
| 2120 | Fput (unmodified, Qevent_kind, symbol_kind); | ||
| 2121 | Fput (unmodified, Qevent_symbol_elements, Fcons (unmodified, Qnil)); | ||
| 2086 | } | 2122 | } |
| 2087 | 2123 | else | |
| 2088 | /* Make sure we have an unmodified version of the symbol in its | ||
| 2089 | proper place? */ | ||
| 2090 | if (NILP (*unmodified_slot)) | ||
| 2091 | { | 2124 | { |
| 2092 | *unmodified_slot = intern (name_table [symbol_num]); | 2125 | temp = Fassq (temp, *slot); |
| 2093 | Fput (*unmodified_slot, Qevent_kind, symbol_kind); | 2126 | if (NILP (temp)) |
| 2094 | Fput (*unmodified_slot, Qevent_unmodified, *unmodified_slot); | 2127 | abort (); |
| 2128 | unmodified = XCONS (temp)->cdr; | ||
| 2095 | } | 2129 | } |
| 2096 | 2130 | ||
| 2097 | /* Have we already created a symbol for this combination of modifiers? */ | 2131 | /* Create a modified version of the symbol, and add it to the alist. */ |
| 2098 | if (NILP (*slot)) | 2132 | { |
| 2133 | Lisp_Object modified; | ||
| 2134 | char *modified_name | ||
| 2135 | = (char *) alloca (sizeof ("A-C-H-M-S-super-U-down-drag") | ||
| 2136 | + strlen (name_table [symbol_num])); | ||
| 2137 | |||
| 2138 | strcpy (modified_name + format_modifiers (modifiers, modified_name), | ||
| 2139 | name_table [symbol_num]); | ||
| 2140 | |||
| 2141 | modified = intern (modified_name); | ||
| 2142 | XFASTINT (temp) = modifiers & ~click_modifier; | ||
| 2143 | *slot = Fcons (Fcons (temp, modified), *slot); | ||
| 2144 | Fput (modified, Qevent_kind, symbol_kind); | ||
| 2145 | |||
| 2099 | { | 2146 | { |
| 2100 | /* No, let's create one. */ | 2147 | Lisp_Object modifier_list; |
| 2101 | char *modified_name | 2148 | int i; |
| 2102 | = (char *) alloca (sizeof ("C-M-S-U-") | ||
| 2103 | + strlen (name_table [symbol_num])); | ||
| 2104 | 2149 | ||
| 2105 | strcpy (modified_name + format_modifiers (modifiers, modified_name), | 2150 | modifier_list = Qnil; |
| 2106 | name_table [symbol_num]); | 2151 | for (i = 0; (1<<i) <= modifiers; i++) |
| 2152 | if (modifiers & (1<<i)) | ||
| 2153 | modifier_list = Fcons (XVECTOR (modifier_symbols)->contents[i], | ||
| 2154 | modifier_list); | ||
| 2107 | 2155 | ||
| 2108 | *slot = intern (modified_name); | 2156 | Fput (modified, Qevent_symbol_elements, |
| 2109 | Fput (*slot, Qevent_kind, symbol_kind); | 2157 | Fcons (unmodified, modifier_list)); |
| 2110 | Fput (*slot, Qevent_unmodified, *unmodified_slot); | ||
| 2111 | } | 2158 | } |
| 2112 | 2159 | ||
| 2113 | return *slot; | 2160 | return modified; |
| 2161 | } | ||
| 2114 | } | 2162 | } |
| 2115 | 2163 | ||
| 2116 | DEFUN ("mouse-click-p", Fmouse_click_p, Smouse_click_p, 1, 1, 0, | 2164 | DEFUN ("mouse-click-p", Fmouse_click_p, Smouse_click_p, 1, 1, 0, |
| @@ -2546,6 +2594,9 @@ read_char_menu_prompt (nmaps, maps, prev_event, used_mouse_menu) | |||
| 2546 | case letter and there are bindings for the corresponding lower-case | 2594 | case letter and there are bindings for the corresponding lower-case |
| 2547 | letter, return the bindings for the lower-case letter. | 2595 | letter, return the bindings for the lower-case letter. |
| 2548 | 2596 | ||
| 2597 | If KEY has no bindings in any of the CURRENT maps, NEXT is left | ||
| 2598 | unmodified. | ||
| 2599 | |||
| 2549 | NEXT may == CURRENT. */ | 2600 | NEXT may == CURRENT. */ |
| 2550 | 2601 | ||
| 2551 | static int | 2602 | static int |
| @@ -2786,7 +2837,7 @@ read_key_sequence (keybuf, bufsize, prompt) | |||
| 2786 | } | 2837 | } |
| 2787 | else if (EVENT_HAS_PARAMETERS (key)) | 2838 | else if (EVENT_HAS_PARAMETERS (key)) |
| 2788 | { | 2839 | { |
| 2789 | Lisp_Object window = EVENT_WINDOW (key); | 2840 | Lisp_Object window = POSN_WINDOW (EVENT_START (key)); |
| 2790 | 2841 | ||
| 2791 | if (NILP (window)) | 2842 | if (NILP (window)) |
| 2792 | abort (); | 2843 | abort (); |
| @@ -3568,8 +3619,8 @@ syms_of_keyboard () | |||
| 3568 | 3619 | ||
| 3569 | Qevent_kind = intern ("event-type"); | 3620 | Qevent_kind = intern ("event-type"); |
| 3570 | staticpro (&Qevent_kind); | 3621 | staticpro (&Qevent_kind); |
| 3571 | Qevent_unmodified = intern ("event-unmodified"); | 3622 | Qevent_symbol_elements = intern ("event-symbol-elements"); |
| 3572 | staticpro (&Qevent_unmodified); | 3623 | staticpro (&Qevent_symbol_elements); |
| 3573 | 3624 | ||
| 3574 | { | 3625 | { |
| 3575 | struct event_head *p; | 3626 | struct event_head *p; |
| @@ -3581,10 +3632,27 @@ syms_of_keyboard () | |||
| 3581 | *p->var = intern (p->name); | 3632 | *p->var = intern (p->name); |
| 3582 | staticpro (p->var); | 3633 | staticpro (p->var); |
| 3583 | Fput (*p->var, Qevent_kind, *p->kind); | 3634 | Fput (*p->var, Qevent_kind, *p->kind); |
| 3584 | Fput (*p->var, Qevent_unmodified, *p->var); | 3635 | Fput (*p->var, Qevent_symbol_elements, Fcons (*p->var, Qnil)); |
| 3585 | } | 3636 | } |
| 3586 | } | 3637 | } |
| 3587 | 3638 | ||
| 3639 | { | ||
| 3640 | int i; | ||
| 3641 | |||
| 3642 | for (i = 0; i < NUM_MOUSE_BUTTONS; i++) | ||
| 3643 | staticpro (&button_down_location[i].window); | ||
| 3644 | } | ||
| 3645 | |||
| 3646 | { | ||
| 3647 | int i; | ||
| 3648 | int len = sizeof (modifier_names) / sizeof (modifier_names[0]); | ||
| 3649 | |||
| 3650 | modifier_symbols = Fmake_vector (make_number (len), Qnil); | ||
| 3651 | for (i = 0; i < len; i++) | ||
| 3652 | XVECTOR (modifier_symbols)->contents[i] = intern (modifier_names[i]); | ||
| 3653 | staticpro (&modifier_symbols); | ||
| 3654 | } | ||
| 3655 | |||
| 3588 | recent_keys = Fmake_vector (make_number (NUM_RECENT_KEYS), Qnil); | 3656 | recent_keys = Fmake_vector (make_number (NUM_RECENT_KEYS), Qnil); |
| 3589 | staticpro (&recent_keys); | 3657 | staticpro (&recent_keys); |
| 3590 | 3658 | ||