diff options
| author | Jim Blandy | 1992-12-24 06:12:04 +0000 |
|---|---|---|
| committer | Jim Blandy | 1992-12-24 06:12:04 +0000 |
| commit | 4bb994d1ad30bd0306fa81fb7e1b7b87b713e7d2 (patch) | |
| tree | 8285322f57e594750f53da6316976a0e830629ca /src | |
| parent | 46a5c4874d68d66681a783226a3a5bd139136d21 (diff) | |
| download | emacs-4bb994d1ad30bd0306fa81fb7e1b7b87b713e7d2.tar.gz emacs-4bb994d1ad30bd0306fa81fb7e1b7b87b713e7d2.zip | |
* keyboard.c: Protect all references to kbd_buffer_frames with
#ifdef MULTI_FRAME.
* frame.h (struct frame): New fields `can_have_scrollbars' and
`has_vertical_scrollbars'.
(FRAME_CAN_HAVE_SCROLLBARS, FRAME_HAS_VERTICAL_SCROLLBARS): New
accessors, for both the MULTI_FRAME and non-MULTI_FRAME.
(VERTICAL_SCROLLBAR_WIDTH, WINDOW_VERTICAL_SCROLLBAR,
WINDOW_VERTICAL_SCROLLBAR_COLUMN,
WINDOW_VERTICAL_SCROLLBAR_HEIGHT): New macros.
* window.h (struct window): New field `vertical_scrollbar'.
* xterm.h (struct x_display): vertical_scrollbars,
judge_timestamp, vertical_scrollbar_extra: New fields.
(struct scrollbar): New struct.
(VERTICAL_SCROLLBAR_PIXEL_WIDTH, VERTICAL_SCROLLBAR_PIXEL_HEIGHT,
VERTICAL_SCROLLBAR_LEFT_BORDER, VERTICAL_SCROLLBAR_RIGHT_BORDER,
VERTICAL_SCROLLBAR_TOP_BORDER, VERTICAL_SCROLLBAR_BOTTOM_BORDER,
CHAR_TO_PIXEL_WIDTH, CHAR_TO_PIXEL_HEIGHT, PIXEL_TO_CHAR_WIDTH,
PIXEL_TO_CHAR_HEIGHT): New accessors and macros.
* frame.c (make_frame): Initialize the `can_have_scrollbars' and
`has_vertical_scrollbars' fields of the frame.
* term.c (term_init): Note that TERMCAP terminals don't support
scrollbars.
(mouse_position_hook): Document new args.
(set_vertical_scrollbar_hook, condemn_scrollbars_hook,
redeem_scrollbar_hook, judge_scrollbars_hook): New hooks.
* termhooks.h: Declare and document them.
(enum scrollbar_part): New type.
(struct input_event): Describe the new form of the scrollbar_click
event type. Change `part' from a Lisp_Object to an enum
scrollbar_part. Add a new field `scrollbar'.
* keyboard.c (kbd_buffer_get_event): Pass appropriate new
parameters to *mouse_position_hook, and make_lispy_movement.
* xfns.c (x_set_vertical_scrollbar): New function.
(x_figure_window_size): Use new macros to calculate frame size.
(Fx_create_frame): Note that X Windows frames do support scroll
bars. Default to "yes".
* xterm.c: #include <X11/cursorfont.h> and "window.h".
(x_vertical_scrollbar_cursor): New variable.
(x_term_init): Initialize it.
(last_mouse_bar, last_mouse_bar_frame, last_mouse_part,
last_mouse_scroll_range_start, last_mouse_scroll_range_end): New
variables.
(XTmouse_position): Use them to return scrollbar movement events.
Take new arguments, for that purpose.
(x_window_to_scrollbar, x_scrollbar_create,
x_scrollbar_set_handle, x_scrollbar_remove, x_scrollbar_move,
XTset_scrollbar, XTcondemn_scrollbars, XTredeem_scrollbar,
XTjudge_scrollbars, x_scrollbar_expose,
x_scrollbar_background_expose, x_scrollbar_handle_click,
x_scrollbar_handle_motion): New functions to implement scrollbars.
(x_term_init): Set the termhooks.h hooks to point to them.
(x_set_window_size): Use new macros to calculate frame size. Set
vertical_scrollbar_extra field.
(x_make_frame_visible): Use the frame accessor
FRAME_HAS_VERTICAL_SCROLLBARS to decide if we need to map the
frame's subwindows as well.
(XTread_socket): Use new size-calculation macros from xterm.h when
processing ConfigureNotify events.
(x_wm_set_size_hint): Use PIXEL_TO_CHAR_WIDTH and
PIXEL_TO_CHAR_HEIGHT macros.
* ymakefile (xdisp.o): This now depends on termhooks.h.
(xterm.o): This now depends on window.h.
* keyboard.c (Qscrollbar_movement, Qvertical_scrollbar,
Qabove_handle, Qhandle, Qbelow_handle): New symbols.
(make_lispy_event): New code to build scrollbar clicks.
(make_lispy_movement): New code to handle scrollbar movement.
(head_table): Include Qscrollbar_movement in the event heads.
(syms_of_keyboard): Init and staticpro Qvertical_scrollbar,
Qabove_handle, Qhandle, and Qbelow_handle.
* keyboard.h (Qscrollbar_movement): Declare this along with the
other event types.
* lisp.h (Qvertical_scrollbar): Declare this.
* window.c (window_from_scrollbar): New function.
* xterm.h (struct x_display): Delete v_scrollbar, v_thumbup,
v_thumbdown, v_slider, h_scrollbar, h_thumbup,
h_thumbdown, h_slider, v_scrollbar_width, h_scrollbar_height
fields.
* keyboard.c (Qvscrollbar_part, Qvslider_part, Qvthumbup_part,
Qvthumbdown_part, Qhscrollbar_part, Qhslider_part, Qhthumbup_part,
Qhthumbdown_part, Qscrollbar_click): Deleted; part of an obsolete
interface.
(head_table): Removed from here as well.
(syms_of_keyboard): And here.
* keyboard.h: And here.
(POSN_SCROLLBAR_BUTTON): Removed.
* xscrollbar.h: File removed - no longer necessary.
* xfns.c: Don't #include it any more.
(Qhorizontal_scroll_bar, Qvertical_scroll_bar): Deleted.
(syms_of_xfns): Don't initialize or staticpro them.
(gray_bits): Salvaged from xscrollbar.h.
(x_window_to_scrollbar): Deleted.
(x_set_horizontal_scrollbar): Deleted.
(enum x_frame_parm, x_frame_parms): Remove references to
x_set_horizontal_scrollbar.
(x_set_foreground_color, x_set_background_color,
x_set_border_pixel): Remove special code to support scrollbars.
(Fx_create_frame): Remove old scrollbar setup code.
(install_vertical_scrollbar, install_horizontal_scrollbar,
adjust_scrollbars, x_resize_scrollbars): Deleted.
* xterm.c (construct_mouse_click): This doesn't need to take care of
scrollbar clicks anymore.
(XTread_socket): Remove old code to support scrollbars. Call new
functions instead for events which occur in scrollbar windows.
(XTupdate_end): Remove call to adjust_scrollbars; the main
redisplay code takes care of that now.
(enum window_type): Deleted.
* ymakefile: Note that xfns.o no longer depends on xscrollbar.h.
* keyboard.c (Fread_key_sequence): Doc fix.
* keyboard.c (make_lispy_event): Buttons are numbered starting
with zero now.
* keyboard.c (make_lispy_event): Use the proper accessors when
manipulating the `x' and `y' fields of struct input_event.
* keyboard.c (parse_modifiers_uncached): Remember that strncmp
returns zero if the two substrings are equal.
* keyboard.c (do_mouse_tracking, Ftrack_mouse): Doc fix.
* keyboard.c (read_char): Don't put mouse movements in
this_command_keys.
Change the meaning of focus redirection to make switching windows
work properly. Fredirect_frame_focus has the details.
* frame.h (focus_frame): Doc fix.
[not MULTI_FRAME] (FRAME_FOCUS_FRAME): Make this Qnil, which
indicates no focus redirection, instead of zero, which is
selected_frame.
* frame.c (make_frame): Initialize f->focus_frame to Qnil, rather
than making it point to frame itself.
(Fselect_frame): If changing the selected frame from FOO to BAR,
make all redirections to FOO shift to BAR as well. Doc fix.
(Fredirect_frame_focus): Doc fix. Accept nil as a valid
redirection, not just as a default for FRAME.
(Fframe_focus): Doc fix.
* keyboard.c (kbd_buffer_store_event, kbd_buffer_get_event): Deal
with focus redirections being nil.
* xterm.c (XTframe_rehighlight): Doc fix. Deal with focus
redirections being nil.
* keyboard.c (kbd_buffer_frames): New vector, to GCPRO frames in
kbd_buffer.
(kbd_buffer_store_event): When we add an event to kbd_buffer, make
sure to store its frame in kbd_buffer_frames.
(kbd_buffer_get_event): When we remove an event from kbd_buffer,
make sure to set the corresponding element of kbd_buffer_frames to
Qnil, to allow the frame to get GC'd.
(Fdiscard_input, init_keyboard): Clear all elements of
kbd_buffer_frames to nil.
(syms_of_keyboard): Create and staticpro kbd_buffer_frames.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 365 |
1 files changed, 251 insertions, 114 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index c0d8bfa5a97..a3817a94bd3 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -241,6 +241,33 @@ extern char *pending_malloc_warning; | |||
| 241 | /* Circular buffer for pre-read keyboard input. */ | 241 | /* Circular buffer for pre-read keyboard input. */ |
| 242 | static struct input_event kbd_buffer[KBD_BUFFER_SIZE]; | 242 | static struct input_event kbd_buffer[KBD_BUFFER_SIZE]; |
| 243 | 243 | ||
| 244 | #ifdef MULTI_FRAME | ||
| 245 | /* Vector of frames, to GCPRO the frames mentioned in kbd_buffer. | ||
| 246 | |||
| 247 | The interrupt-level event handlers will never enqueue a frame which | ||
| 248 | is not in Vframe_list, and once an event is dequeued, | ||
| 249 | Vlast_event_frame or the event itself points to the frame. So | ||
| 250 | that's all fine. | ||
| 251 | |||
| 252 | But while the event is sitting in the queue, it's completely | ||
| 253 | unprotected. Suppose the user types one command which will run for | ||
| 254 | a while and then delete a frame, and then types another event at | ||
| 255 | the frame that will be deleted, before the command gets around to | ||
| 256 | it. Suppose there are no references to this frame elsewhere in | ||
| 257 | Emacs, and a GC occurs before the second event is dequeued. Now we | ||
| 258 | have an event referring to a freed frame, which will crash Emacs | ||
| 259 | when it is dequeued. | ||
| 260 | |||
| 261 | So, we use this vector to protect any frames in the event queue. | ||
| 262 | That way, they'll be dequeued as dead frames, but still valid lisp | ||
| 263 | objects. | ||
| 264 | |||
| 265 | If kbd_buffer[i] != 0, then | ||
| 266 | (XFRAME (XVECTOR (kbd_buffer_frames)->contents[i]) | ||
| 267 | == kbd_buffer[i].frame). */ | ||
| 268 | static Lisp_Object kbd_buffer_frames; | ||
| 269 | #endif | ||
| 270 | |||
| 244 | /* Pointer to next available character in kbd_buffer. | 271 | /* Pointer to next available character in kbd_buffer. |
| 245 | If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. | 272 | If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty. |
| 246 | This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the the | 273 | This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the the |
| @@ -258,14 +285,15 @@ static struct input_event *kbd_store_ptr; | |||
| 258 | /* The above pair of variables forms a "queue empty" flag. When we | 285 | /* The above pair of variables forms a "queue empty" flag. When we |
| 259 | enqueue a non-hook event, we increment kbd_write_count. When we | 286 | enqueue a non-hook event, we increment kbd_write_count. When we |
| 260 | dequeue a non-hook event, we increment kbd_read_count. We say that | 287 | dequeue a non-hook event, we increment kbd_read_count. We say that |
| 261 | there is input available iff the two counters are equal. | 288 | there is input available iff the two counters are not equal. |
| 262 | 289 | ||
| 263 | Why not just have a flag set and cleared by the enqueuing and | 290 | Why not just have a flag set and cleared by the enqueuing and |
| 264 | dequeuing functions? Such a flag could be screwed up by interrupts | 291 | dequeuing functions? Such a flag could be screwed up by interrupts |
| 265 | at inopportune times. */ | 292 | at inopportune times. */ |
| 266 | 293 | ||
| 267 | /* If this flag is non-zero, mouse movement events will appear in the | 294 | /* If this flag is non-zero, we will check mouse_moved to see when the |
| 268 | input stream. If is zero, mouse movement will be ignored. */ | 295 | mouse moves, and motion events will appear in the input stream. If |
| 296 | it is zero, mouse motion will be ignored. */ | ||
| 269 | int do_mouse_tracking; | 297 | int do_mouse_tracking; |
| 270 | 298 | ||
| 271 | /* The window system handling code should set this if the mouse has | 299 | /* The window system handling code should set this if the mouse has |
| @@ -286,16 +314,7 @@ int mouse_moved; | |||
| 286 | 314 | ||
| 287 | /* Symbols to head events. */ | 315 | /* Symbols to head events. */ |
| 288 | Lisp_Object Qmouse_movement; | 316 | Lisp_Object Qmouse_movement; |
| 289 | 317 | Lisp_Object Qscrollbar_movement; | |
| 290 | Lisp_Object Qvscrollbar_part; | ||
| 291 | Lisp_Object Qvslider_part; | ||
| 292 | Lisp_Object Qvthumbup_part; | ||
| 293 | Lisp_Object Qvthumbdown_part; | ||
| 294 | |||
| 295 | Lisp_Object Qhscrollbar_part; | ||
| 296 | Lisp_Object Qhslider_part; | ||
| 297 | Lisp_Object Qhthumbleft_part; | ||
| 298 | Lisp_Object Qhthumbright_part; | ||
| 299 | 318 | ||
| 300 | Lisp_Object Qswitch_frame; | 319 | Lisp_Object Qswitch_frame; |
| 301 | 320 | ||
| @@ -303,7 +322,6 @@ Lisp_Object Qswitch_frame; | |||
| 303 | Lisp_Object Qfunction_key; | 322 | Lisp_Object Qfunction_key; |
| 304 | Lisp_Object Qmouse_click; | 323 | Lisp_Object Qmouse_click; |
| 305 | /* Lisp_Object Qmouse_movement; - also an event header */ | 324 | /* Lisp_Object Qmouse_movement; - also an event header */ |
| 306 | Lisp_Object Qscrollbar_click; | ||
| 307 | 325 | ||
| 308 | /* Properties of event headers. */ | 326 | /* Properties of event headers. */ |
| 309 | Lisp_Object Qevent_kind; | 327 | Lisp_Object Qevent_kind; |
| @@ -325,6 +343,7 @@ Lisp_Object Qmodifier_cache; | |||
| 325 | /* Symbols to use for non-text mouse positions. */ | 343 | /* Symbols to use for non-text mouse positions. */ |
| 326 | Lisp_Object Qmode_line; | 344 | Lisp_Object Qmode_line; |
| 327 | Lisp_Object Qvertical_line; | 345 | Lisp_Object Qvertical_line; |
| 346 | Lisp_Object Qvertical_scrollbar; | ||
| 328 | 347 | ||
| 329 | Lisp_Object recursive_edit_unwind (), command_loop (); | 348 | Lisp_Object recursive_edit_unwind (), command_loop (); |
| 330 | Lisp_Object Fthis_command_keys (); | 349 | Lisp_Object Fthis_command_keys (); |
| @@ -1356,8 +1375,11 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) | |||
| 1356 | reread_first: | 1375 | reread_first: |
| 1357 | echo_char (c); | 1376 | echo_char (c); |
| 1358 | 1377 | ||
| 1359 | /* Record this character as part of the current key. */ | 1378 | /* Record this character as part of the current key. |
| 1360 | add_command_key (c); | 1379 | Don't record mouse motion; it should never matter. */ |
| 1380 | if (! (EVENT_HAS_PARAMETERS (c) | ||
| 1381 | && EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement))) | ||
| 1382 | add_command_key (c); | ||
| 1361 | 1383 | ||
| 1362 | /* Re-reading in the middle of a command */ | 1384 | /* Re-reading in the middle of a command */ |
| 1363 | reread: | 1385 | reread: |
| @@ -1462,10 +1484,10 @@ tracking_off (old_value) | |||
| 1462 | } | 1484 | } |
| 1463 | 1485 | ||
| 1464 | DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0, | 1486 | DEFUN ("track-mouse", Ftrack_mouse, Strack_mouse, 0, UNEVALLED, 0, |
| 1465 | "Evaluate BODY with mouse movement and button release events enabled.\n\ | 1487 | "Evaluate BODY with mouse movement events enabled.\n\ |
| 1466 | Within a `track-mouse', mouse motion and button releases generate input\n\ | 1488 | Within a `track-mouse' form, mouse motion generates input events that\n\ |
| 1467 | events that you can read with `read-event'.\n\ | 1489 | you can read with `read-event'.\n\ |
| 1468 | Normally, these occurrences don't generate events.") | 1490 | Normally, mouse motion is ignored.") |
| 1469 | (args) | 1491 | (args) |
| 1470 | Lisp_Object args; | 1492 | Lisp_Object args; |
| 1471 | { | 1493 | { |
| @@ -1504,7 +1526,14 @@ kbd_buffer_store_event (event) | |||
| 1504 | input, set last-event-frame properly. If this doesn't | 1526 | input, set last-event-frame properly. If this doesn't |
| 1505 | get returned to Emacs as an event, the next event read | 1527 | get returned to Emacs as an event, the next event read |
| 1506 | will set Vlast_event_frame again, so this is safe to do. */ | 1528 | will set Vlast_event_frame again, so this is safe to do. */ |
| 1507 | Vlast_event_frame = FRAME_FOCUS_FRAME (event->frame); | 1529 | { |
| 1530 | Lisp_Object focus = FRAME_FOCUS_FRAME (event->frame); | ||
| 1531 | |||
| 1532 | if (NILP (focus)) | ||
| 1533 | Vlast_event_frame = focus; | ||
| 1534 | else | ||
| 1535 | XSET (Vlast_event_frame, Lisp_Frame, event->frame); | ||
| 1536 | } | ||
| 1508 | #endif | 1537 | #endif |
| 1509 | 1538 | ||
| 1510 | last_event_timestamp = event->timestamp; | 1539 | last_event_timestamp = event->timestamp; |
| @@ -1538,6 +1567,11 @@ kbd_buffer_store_event (event) | |||
| 1538 | kbd_store_ptr->x = event->x; | 1567 | kbd_store_ptr->x = event->x; |
| 1539 | kbd_store_ptr->y = event->y; | 1568 | kbd_store_ptr->y = event->y; |
| 1540 | kbd_store_ptr->timestamp = event->timestamp; | 1569 | kbd_store_ptr->timestamp = event->timestamp; |
| 1570 | #ifdef MULTI_FRAME | ||
| 1571 | XSET (XVECTOR (kbd_buffer_frames)->contents[kbd_store_ptr - kbd_buffer], | ||
| 1572 | Lisp_Frame, | ||
| 1573 | event->frame); | ||
| 1574 | #endif | ||
| 1541 | 1575 | ||
| 1542 | kbd_store_ptr++; | 1576 | kbd_store_ptr++; |
| 1543 | } | 1577 | } |
| @@ -1610,54 +1644,78 @@ kbd_buffer_get_event () | |||
| 1610 | 1644 | ||
| 1611 | last_event_timestamp = event->timestamp; | 1645 | last_event_timestamp = event->timestamp; |
| 1612 | 1646 | ||
| 1613 | { | 1647 | obj = Qnil; |
| 1648 | |||
| 1614 | #ifdef MULTI_FRAME | 1649 | #ifdef MULTI_FRAME |
| 1615 | Lisp_Object frame; | 1650 | /* If this event is on a different frame, return a switch-frame this |
| 1651 | time, and leave the event in the queue for next time. */ | ||
| 1652 | { | ||
| 1653 | Lisp_Object frame = FRAME_FOCUS_FRAME (event->frame); | ||
| 1654 | |||
| 1655 | if (NILP (frame)) | ||
| 1656 | XSET (frame, Lisp_Frame, event->frame); | ||
| 1616 | 1657 | ||
| 1617 | /* If this event is on a different frame, return a switch-frame this | ||
| 1618 | time, and leave the event in the queue for next time. */ | ||
| 1619 | XSET (frame, Lisp_Frame, XFRAME (FRAME_FOCUS_FRAME (event->frame))); | ||
| 1620 | if (! EQ (frame, Vlast_event_frame)) | 1658 | if (! EQ (frame, Vlast_event_frame)) |
| 1621 | { | 1659 | { |
| 1622 | Vlast_event_frame = frame; | 1660 | Vlast_event_frame = frame; |
| 1623 | obj = make_lispy_switch_frame (frame); | 1661 | obj = make_lispy_switch_frame (frame); |
| 1624 | } | 1662 | } |
| 1625 | else | 1663 | } |
| 1626 | #endif | 1664 | #endif |
| 1627 | { | 1665 | |
| 1628 | obj = make_lispy_event (event); | 1666 | /* If we didn't decide to make a switch-frame event, go ahead |
| 1629 | if (XTYPE (obj) == Lisp_Int) | 1667 | and build a real event from the queue entry. */ |
| 1630 | XSET (obj, Lisp_Int, XINT (obj) & (meta_key ? 0377 : 0177)); | 1668 | if (NILP (obj)) |
| 1669 | { | ||
| 1670 | obj = make_lispy_event (event); | ||
| 1671 | if (XTYPE (obj) == Lisp_Int) | ||
| 1672 | XSET (obj, Lisp_Int, XINT (obj) & (meta_key ? 0377 : 0177)); | ||
| 1631 | 1673 | ||
| 1632 | /* Wipe out this event, to catch bugs. */ | 1674 | /* Wipe out this event, to catch bugs. */ |
| 1633 | event->kind = no_event; | 1675 | event->kind = no_event; |
| 1676 | #ifdef MULTI_FRAME | ||
| 1677 | XVECTOR (kbd_buffer_frames)->contents[event - kbd_buffer] = Qnil; | ||
| 1678 | #endif | ||
| 1634 | 1679 | ||
| 1635 | kbd_fetch_ptr = event + 1; | 1680 | kbd_fetch_ptr = event + 1; |
| 1636 | } | 1681 | } |
| 1637 | } | ||
| 1638 | } | 1682 | } |
| 1639 | else if (do_mouse_tracking && mouse_moved) | 1683 | else if (do_mouse_tracking && mouse_moved) |
| 1640 | { | 1684 | { |
| 1641 | FRAME_PTR frame; | 1685 | FRAME_PTR f; |
| 1686 | struct scrollbar *bar; | ||
| 1687 | enum scrollbar_part part; | ||
| 1642 | Lisp_Object x, y; | 1688 | Lisp_Object x, y; |
| 1643 | unsigned long time; | 1689 | unsigned long time; |
| 1644 | 1690 | ||
| 1645 | (*mouse_position_hook) (&frame, &x, &y, &time); | 1691 | (*mouse_position_hook) (&f, &bar, &part, &x, &y, &time); |
| 1692 | |||
| 1693 | obj = Qnil; | ||
| 1646 | 1694 | ||
| 1647 | #ifdef MULTI_FRAME | 1695 | #ifdef MULTI_FRAME |
| 1648 | /* Decide if we should generate a switch-frame event. Don't generate | 1696 | /* Decide if we should generate a switch-frame event. Don't |
| 1649 | switch-frame events for motion outside of all Emacs frames. */ | 1697 | generate switch-frame events for motion outside of all Emacs |
| 1650 | if (frame | 1698 | frames. */ |
| 1651 | && (XTYPE (Vlast_event_frame) != Lisp_Frame | 1699 | if (f) |
| 1652 | || frame != XFRAME (Vlast_event_frame))) | ||
| 1653 | { | 1700 | { |
| 1654 | XSET (Vlast_event_frame, Lisp_Frame, frame); | 1701 | Lisp_Object frame = FRAME_FOCUS_FRAME (f); |
| 1655 | obj = make_lispy_switch_frame (Vlast_event_frame); | 1702 | |
| 1703 | if (NILP (frame)) | ||
| 1704 | XSET (frame, Lisp_Frame, f); | ||
| 1705 | |||
| 1706 | if (! EQ (frame, Vlast_event_frame)) | ||
| 1707 | { | ||
| 1708 | XSET (Vlast_event_frame, Lisp_Frame, frame); | ||
| 1709 | obj = make_lispy_switch_frame (Vlast_event_frame); | ||
| 1710 | } | ||
| 1656 | } | 1711 | } |
| 1657 | else | ||
| 1658 | #endif | 1712 | #endif |
| 1659 | obj = make_lispy_movement (frame, x, y, time); | 1713 | |
| 1660 | } | 1714 | /* If we didn't decide to make a switch-frame event, go ahead and |
| 1715 | return a mouse-motion event. */ | ||
| 1716 | if (NILP (obj)) | ||
| 1717 | obj = make_lispy_movement (f, bar, part, x, y, time); | ||
| 1718 | } | ||
| 1661 | else | 1719 | else |
| 1662 | /* We were promised by the above while loop that there was | 1720 | /* We were promised by the above while loop that there was |
| 1663 | something for us to read! */ | 1721 | something for us to read! */ |
| @@ -1668,6 +1726,7 @@ kbd_buffer_get_event () | |||
| 1668 | return (obj); | 1726 | return (obj); |
| 1669 | } | 1727 | } |
| 1670 | 1728 | ||
| 1729 | |||
| 1671 | /* Caches for modify_event_symbol. */ | 1730 | /* Caches for modify_event_symbol. */ |
| 1672 | static Lisp_Object func_key_syms; | 1731 | static Lisp_Object func_key_syms; |
| 1673 | static Lisp_Object mouse_syms; | 1732 | static Lisp_Object mouse_syms; |
| @@ -1753,6 +1812,15 @@ static char *lispy_mouse_names[] = | |||
| 1753 | "mouse-1", "mouse-2", "mouse-3", "mouse-4", "mouse-5" | 1812 | "mouse-1", "mouse-2", "mouse-3", "mouse-4", "mouse-5" |
| 1754 | }; | 1813 | }; |
| 1755 | 1814 | ||
| 1815 | /* Scrollbar parts. */ | ||
| 1816 | Lisp_Object Qabove_handle, Qhandle, Qbelow_handle; | ||
| 1817 | |||
| 1818 | /* An array of scrollbar parts, indexed by an enum scrollbar_part value. */ | ||
| 1819 | Lisp_Object *scrollbar_parts[] = { | ||
| 1820 | &Qabove_handle, &Qhandle, &Qbelow_handle | ||
| 1821 | }; | ||
| 1822 | |||
| 1823 | |||
| 1756 | /* make_lispy_event stores the down-going location of the currently | 1824 | /* make_lispy_event stores the down-going location of the currently |
| 1757 | depressed buttons in button_down_locations. */ | 1825 | depressed buttons in button_down_locations. */ |
| 1758 | struct mouse_position { | 1826 | struct mouse_position { |
| @@ -1849,7 +1917,8 @@ make_lispy_event (event) | |||
| 1849 | else if (event->modifiers & up_modifier) | 1917 | else if (event->modifiers & up_modifier) |
| 1850 | { | 1918 | { |
| 1851 | event->modifiers &= ~up_modifier; | 1919 | event->modifiers &= ~up_modifier; |
| 1852 | event->modifiers |= ((event->x == loc->x && event->y == loc->y) | 1920 | event->modifiers |= ((EQ (event->x, loc->x) |
| 1921 | && EQ (event->y, loc->y)) | ||
| 1853 | ? click_modifier | 1922 | ? click_modifier |
| 1854 | : drag_modifier); | 1923 | : drag_modifier); |
| 1855 | } | 1924 | } |
| @@ -1864,7 +1933,7 @@ make_lispy_event (event) | |||
| 1864 | Lisp_Object head, start, end; | 1933 | Lisp_Object head, start, end; |
| 1865 | 1934 | ||
| 1866 | /* Build the components of the event. */ | 1935 | /* Build the components of the event. */ |
| 1867 | head = modify_event_symbol (button - 1, | 1936 | head = modify_event_symbol (button, |
| 1868 | event->modifiers, | 1937 | event->modifiers, |
| 1869 | Qmouse_click, | 1938 | Qmouse_click, |
| 1870 | lispy_mouse_names, &mouse_syms, | 1939 | lispy_mouse_names, &mouse_syms, |
| @@ -1895,24 +1964,29 @@ make_lispy_event (event) | |||
| 1895 | } | 1964 | } |
| 1896 | } | 1965 | } |
| 1897 | 1966 | ||
| 1898 | /* A scrollbar click. Build a list containing the relevant | 1967 | /* A scrollbar click. Build a scrollbar click list. */ |
| 1899 | information. */ | ||
| 1900 | case scrollbar_click: | 1968 | case scrollbar_click: |
| 1901 | { | 1969 | { |
| 1902 | Lisp_Object button | 1970 | Lisp_Object button = |
| 1903 | = modify_event_symbol (XFASTINT (event->code) - 1, | 1971 | modify_event_symbol (button, |
| 1904 | event->modifiers, | 1972 | event->modifiers, |
| 1905 | Qmouse_click, | 1973 | Qmouse_click, |
| 1906 | lispy_mouse_names, &mouse_syms, | 1974 | lispy_mouse_names, &mouse_syms, |
| 1907 | (sizeof (lispy_mouse_names) | 1975 | (sizeof (lispy_mouse_names) |
| 1908 | / sizeof (lispy_mouse_names[0]))); | 1976 | / sizeof (lispy_mouse_names[0]))); |
| 1909 | return Fcons (event->part, | 1977 | Lisp_Object window = |
| 1910 | Fcons (FRAME_SELECTED_WINDOW (event->frame), | 1978 | window_from_scrollbar (event->frame, event->scrollbar); |
| 1911 | Fcons (button, | 1979 | Lisp_Object portion_whole = Fcons (event->x, event->y); |
| 1912 | Fcons (Fcons (event->x, event->y), | 1980 | Lisp_Object part = *scrollbar_parts[(int) event->part]; |
| 1913 | Fcons (make_number | 1981 | Lisp_Object total_posn = |
| 1914 | (event->timestamp), | 1982 | Fcons (window, |
| 1915 | Qnil))))); | 1983 | Fcons (Qvertical_scrollbar, |
| 1984 | Fcons (portion_whole, | ||
| 1985 | Fcons (make_number (event->timestamp), | ||
| 1986 | Fcons (part, | ||
| 1987 | Qnil))))); | ||
| 1988 | |||
| 1989 | return Fcons (button, Fcons (total_posn, Qnil)); | ||
| 1916 | } | 1990 | } |
| 1917 | 1991 | ||
| 1918 | /* The 'kind' field of the event is something we don't recognize. */ | 1992 | /* The 'kind' field of the event is something we don't recognize. */ |
| @@ -1922,45 +1996,67 @@ make_lispy_event (event) | |||
| 1922 | } | 1996 | } |
| 1923 | 1997 | ||
| 1924 | static Lisp_Object | 1998 | static Lisp_Object |
| 1925 | make_lispy_movement (frame, x, y, time) | 1999 | make_lispy_movement (frame, bar, part, x, y, time) |
| 1926 | FRAME_PTR frame; | 2000 | FRAME_PTR frame; |
| 2001 | struct scrollbar *bar; | ||
| 2002 | enum scrollbar_part part; | ||
| 1927 | Lisp_Object x, y; | 2003 | Lisp_Object x, y; |
| 1928 | unsigned long time; | 2004 | unsigned long time; |
| 1929 | { | 2005 | { |
| 1930 | Lisp_Object window; | 2006 | /* Is it a scrollbar movement? */ |
| 1931 | int ix, iy; | 2007 | if (bar) |
| 1932 | Lisp_Object posn; | 2008 | { |
| 1933 | int part; | 2009 | Lisp_Object window = window_from_scrollbar (frame, bar); |
| 1934 | 2010 | Lisp_Object part = *scrollbar_parts[(int) part]; | |
| 1935 | ix = XINT (x); | 2011 | |
| 1936 | iy = XINT (y); | 2012 | return Fcons (Qscrollbar_movement, |
| 1937 | window = (frame | 2013 | (Fcons (Fcons (window, |
| 1938 | ? window_from_coordinates (frame, ix, iy, &part) | 2014 | Fcons (Qvertical_scrollbar, |
| 1939 | : Qnil); | 2015 | Fcons (Fcons (x, y), |
| 1940 | if (XTYPE (window) != Lisp_Window) | 2016 | Fcons (make_number (time), |
| 1941 | posn = Qnil; | 2017 | Fcons (part, |
| 2018 | Qnil))))), | ||
| 2019 | Qnil))); | ||
| 2020 | } | ||
| 2021 | |||
| 2022 | /* Or is it an ordinary mouse movement? */ | ||
| 1942 | else | 2023 | else |
| 1943 | { | 2024 | { |
| 1944 | ix -= XINT (XWINDOW (window)->left); | 2025 | int area; |
| 1945 | iy -= XINT (XWINDOW (window)->top); | 2026 | Lisp_Object window = |
| 1946 | if (part == 1) | 2027 | (frame |
| 1947 | posn = Qmode_line; | 2028 | ? window_from_coordinates (frame, XINT (x), XINT (y), &area) |
| 1948 | else if (part == 2) | 2029 | : Qnil); |
| 1949 | posn = Qvertical_line; | 2030 | Lisp_Object posn; |
| 2031 | |||
| 2032 | if (XTYPE (window) == Lisp_Window) | ||
| 2033 | { | ||
| 2034 | XSETINT (x, XINT (x) - XINT (XWINDOW (window)->left)); | ||
| 2035 | XSETINT (y, XINT (y) - XINT (XWINDOW (window)->top)); | ||
| 2036 | |||
| 2037 | if (area == 1) | ||
| 2038 | posn = Qmode_line; | ||
| 2039 | else if (area == 2) | ||
| 2040 | posn = Qvertical_line; | ||
| 2041 | else | ||
| 2042 | XSET (posn, Lisp_Int, | ||
| 2043 | buffer_posn_from_coords (XWINDOW (window), | ||
| 2044 | XINT (x), XINT (y))); | ||
| 2045 | } | ||
| 1950 | else | 2046 | else |
| 1951 | XSET (posn, Lisp_Int, buffer_posn_from_coords (XWINDOW (window), | 2047 | { |
| 1952 | ix, iy)); | 2048 | window = Qnil; |
| 1953 | } | 2049 | posn = Qnil; |
| 2050 | } | ||
| 1954 | 2051 | ||
| 1955 | XSETINT (x, ix); | 2052 | return Fcons (Qmouse_movement, |
| 1956 | XSETINT (y, iy); | 2053 | Fcons (Fcons (window, |
| 1957 | return Fcons (Qmouse_movement, | 2054 | Fcons (posn, |
| 1958 | Fcons (Fcons (window, | 2055 | Fcons (Fcons (x, y), |
| 1959 | Fcons (posn, | 2056 | Fcons (make_number (time), |
| 1960 | Fcons (Fcons (x, y), | 2057 | Qnil)))), |
| 1961 | Fcons (make_number (time), | 2058 | Qnil)); |
| 1962 | Qnil)))), | 2059 | } |
| 1963 | Qnil)); | ||
| 1964 | } | 2060 | } |
| 1965 | 2061 | ||
| 1966 | 2062 | ||
| @@ -2061,7 +2157,7 @@ parse_modifiers_uncached (symbol, modifier_end) | |||
| 2061 | /* Should we include the `click' modifier? */ | 2157 | /* Should we include the `click' modifier? */ |
| 2062 | if (! (modifiers & (down_modifier | drag_modifier)) | 2158 | if (! (modifiers & (down_modifier | drag_modifier)) |
| 2063 | && i + 7 == name->size | 2159 | && i + 7 == name->size |
| 2064 | && strncmp (name->data + i, "mouse-", 6) | 2160 | && strncmp (name->data + i, "mouse-", 6) == 0 |
| 2065 | && ('0' <= name->data[i + 6] && name->data[i + 6] <= '9')) | 2161 | && ('0' <= name->data[i + 6] && name->data[i + 6] <= '9')) |
| 2066 | modifiers |= click_modifier; | 2162 | modifiers |= click_modifier; |
| 2067 | 2163 | ||
| @@ -2309,7 +2405,8 @@ modify_event_symbol (symbol_num, modifiers, symbol_kind, name_table, | |||
| 2309 | 2405 | ||
| 2310 | /* If *symbol_table doesn't seem to be initialized properly, fix that. | 2406 | /* If *symbol_table doesn't seem to be initialized properly, fix that. |
| 2311 | *symbol_table should be a lisp vector TABLE_SIZE elements long, | 2407 | *symbol_table should be a lisp vector TABLE_SIZE elements long, |
| 2312 | where the Nth element is the symbol for NAME_TABLE[N]. */ | 2408 | where the Nth element is the symbol for NAME_TABLE[N], or nil if |
| 2409 | we've never used that symbol before. */ | ||
| 2313 | if (XTYPE (*symbol_table) != Lisp_Vector | 2410 | if (XTYPE (*symbol_table) != Lisp_Vector |
| 2314 | || XVECTOR (*symbol_table)->size != table_size) | 2411 | || XVECTOR (*symbol_table)->size != table_size) |
| 2315 | { | 2412 | { |
| @@ -3312,10 +3409,31 @@ First arg PROMPT is a prompt string. If nil, do not prompt specially.\n\ | |||
| 3312 | Second (optional) arg CONTINUE-ECHO, if non-nil, means this key echos\n\ | 3409 | Second (optional) arg CONTINUE-ECHO, if non-nil, means this key echos\n\ |
| 3313 | as a continuation of the previous key.\n\ | 3410 | as a continuation of the previous key.\n\ |
| 3314 | \n\ | 3411 | \n\ |
| 3315 | If Emacs is running on multiple frames, switching between frames in\n\ | 3412 | |
| 3316 | the midst of a keystroke will toss any prefix typed so far. A C-g\n\ | 3413 | A C-g typed while in this function is treated like any other character, |
| 3317 | typed while in this function is treated like any other character, and\n\ | 3414 | and `quit-flag' is not set. |
| 3318 | `quit-flag' is not set.") | 3415 | |
| 3416 | If the key sequence starts with a mouse click, then the sequence is read | ||
| 3417 | using the keymaps of the buffer of the window clicked in, not the buffer | ||
| 3418 | of the selected window as normal. | ||
| 3419 | |||
| 3420 | `read-key-sequence' drops unbound button-down events, since you normally | ||
| 3421 | only care about the click or drag events which follow them. If a drag | ||
| 3422 | event is unbound, but the corresponding click event would be bound, | ||
| 3423 | `read-key-sequence' turns the drag event into a click event at the | ||
| 3424 | drag's starting position. This means that you don't have to distinguish | ||
| 3425 | between click and drag events unless you want to. | ||
| 3426 | |||
| 3427 | `read-key-sequence' prefixes mouse events on mode lines, the vertical | ||
| 3428 | lines separating windows, and scrollbars with imaginary keys | ||
| 3429 | `mode-line', `vertical-line', and `vertical-scrollbar'. | ||
| 3430 | |||
| 3431 | If the user switches frames in the middle of a key sequence, the | ||
| 3432 | frame-switch event is put off until after the current key sequence. | ||
| 3433 | |||
| 3434 | `read-key-sequence' checks `function-key-map' for function key | ||
| 3435 | sequences, where they wouldn't conflict with ordinary bindings. See | ||
| 3436 | `function-key-map' for more details.") | ||
| 3319 | (prompt, continue_echo) | 3437 | (prompt, continue_echo) |
| 3320 | Lisp_Object prompt, continue_echo; | 3438 | Lisp_Object prompt, continue_echo; |
| 3321 | { | 3439 | { |
| @@ -3584,6 +3702,9 @@ Also cancel any kbd macro being defined.") | |||
| 3584 | volatile qualifier of kbd_store_ptr. Is there anything wrong | 3702 | volatile qualifier of kbd_store_ptr. Is there anything wrong |
| 3585 | with that? */ | 3703 | with that? */ |
| 3586 | kbd_fetch_ptr = (struct input_event *) kbd_store_ptr; | 3704 | kbd_fetch_ptr = (struct input_event *) kbd_store_ptr; |
| 3705 | #ifdef MULTI_FRAME | ||
| 3706 | Ffillarray (kbd_buffer_frames, Qnil); | ||
| 3707 | #endif | ||
| 3587 | input_pending = 0; | 3708 | input_pending = 0; |
| 3588 | 3709 | ||
| 3589 | return Qnil; | 3710 | return Qnil; |
| @@ -3676,6 +3797,11 @@ stuff_buffered_input (stuffstring) | |||
| 3676 | kbd_fetch_ptr = kbd_buffer; | 3797 | kbd_fetch_ptr = kbd_buffer; |
| 3677 | if (kbd_fetch_ptr->kind == ascii_keystroke) | 3798 | if (kbd_fetch_ptr->kind == ascii_keystroke) |
| 3678 | stuff_char (XINT (kbd_fetch_ptr->code)); | 3799 | stuff_char (XINT (kbd_fetch_ptr->code)); |
| 3800 | kbd_fetch_ptr->kind = no_event; | ||
| 3801 | #ifdef MULTI_FRAME | ||
| 3802 | XVECTOR (kbd_buffer_frames)->contents[kbd_fetch_ptr - kbd_buffer] | ||
| 3803 | = Qnil; | ||
| 3804 | #endif | ||
| 3679 | kbd_fetch_ptr++; | 3805 | kbd_fetch_ptr++; |
| 3680 | } | 3806 | } |
| 3681 | input_pending = 0; | 3807 | input_pending = 0; |
| @@ -3885,6 +4011,12 @@ init_keyboard () | |||
| 3885 | /* This means that command_loop_1 won't try to select anything the first | 4011 | /* This means that command_loop_1 won't try to select anything the first |
| 3886 | time through. */ | 4012 | time through. */ |
| 3887 | Vlast_event_frame = Qnil; | 4013 | Vlast_event_frame = Qnil; |
| 4014 | |||
| 4015 | /* If we're running an undumped Emacs, kbd_buffer_frames isn't set | ||
| 4016 | yet. When it does get initialized, it will be filled with the | ||
| 4017 | right value, so it's okay not to fret about it here. */ | ||
| 4018 | if (initialized) | ||
| 4019 | Ffillarray (kbd_buffer_frames, Qnil); | ||
| 3888 | #endif | 4020 | #endif |
| 3889 | 4021 | ||
| 3890 | if (!noninteractive) | 4022 | if (!noninteractive) |
| @@ -3937,15 +4069,8 @@ struct event_head { | |||
| 3937 | 4069 | ||
| 3938 | struct event_head head_table[] = { | 4070 | struct event_head head_table[] = { |
| 3939 | &Qmouse_movement, "mouse-movement", &Qmouse_movement, | 4071 | &Qmouse_movement, "mouse-movement", &Qmouse_movement, |
| 3940 | &Qvscrollbar_part, "vscrollbar-part", &Qscrollbar_click, | 4072 | &Qswitch_frame, "switch-frame", &Qswitch_frame, |
| 3941 | &Qvslider_part, "vslider-part", &Qscrollbar_click, | 4073 | &Qscrollbar_movement, "scrollbar-movement", &Qscrollbar_movement, |
| 3942 | &Qvthumbup_part, "vthumbup-part", &Qscrollbar_click, | ||
| 3943 | &Qvthumbdown_part, "vthumbdown-part", &Qscrollbar_click, | ||
| 3944 | &Qhscrollbar_part, "hscrollbar-part", &Qscrollbar_click, | ||
| 3945 | &Qhslider_part, "hslider-part", &Qscrollbar_click, | ||
| 3946 | &Qhthumbleft_part, "hthumbleft-part", &Qscrollbar_click, | ||
| 3947 | &Qhthumbright_part,"hthumbright-part", &Qscrollbar_click, | ||
| 3948 | &Qswitch_frame, "switch-frame", &Qswitch_frame | ||
| 3949 | }; | 4074 | }; |
| 3950 | 4075 | ||
| 3951 | syms_of_keyboard () | 4076 | syms_of_keyboard () |
| @@ -3966,13 +4091,20 @@ syms_of_keyboard () | |||
| 3966 | staticpro (&Qfunction_key); | 4091 | staticpro (&Qfunction_key); |
| 3967 | Qmouse_click = intern ("mouse-click"); | 4092 | Qmouse_click = intern ("mouse-click"); |
| 3968 | staticpro (&Qmouse_click); | 4093 | staticpro (&Qmouse_click); |
| 3969 | Qmouse_movement = intern ("scrollbar-click"); | ||
| 3970 | staticpro (&Qmouse_movement); | ||
| 3971 | 4094 | ||
| 3972 | Qmode_line = intern ("mode-line"); | 4095 | Qmode_line = intern ("mode-line"); |
| 3973 | staticpro (&Qmode_line); | 4096 | staticpro (&Qmode_line); |
| 3974 | Qvertical_line = intern ("vertical-line"); | 4097 | Qvertical_line = intern ("vertical-line"); |
| 3975 | staticpro (&Qvertical_line); | 4098 | staticpro (&Qvertical_line); |
| 4099 | Qvertical_scrollbar = intern ("vertical-scrollbar"); | ||
| 4100 | staticpro (&Qvertical_scrollbar); | ||
| 4101 | |||
| 4102 | Qabove_handle = intern ("above-handle"); | ||
| 4103 | staticpro (&Qabove_handle); | ||
| 4104 | Qhandle = intern ("handle"); | ||
| 4105 | staticpro (&Qhandle); | ||
| 4106 | Qbelow_handle = intern ("below-handle"); | ||
| 4107 | staticpro (&Qbelow_handle); | ||
| 3976 | 4108 | ||
| 3977 | Qevent_kind = intern ("event-kind"); | 4109 | Qevent_kind = intern ("event-kind"); |
| 3978 | staticpro (&Qevent_kind); | 4110 | staticpro (&Qevent_kind); |
| @@ -4020,6 +4152,11 @@ syms_of_keyboard () | |||
| 4020 | this_command_keys = Fmake_vector (make_number (40), Qnil); | 4152 | this_command_keys = Fmake_vector (make_number (40), Qnil); |
| 4021 | staticpro (&this_command_keys); | 4153 | staticpro (&this_command_keys); |
| 4022 | 4154 | ||
| 4155 | #ifdef MULTI_FRAME | ||
| 4156 | kbd_buffer_frames = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil); | ||
| 4157 | staticpro (&kbd_buffer_frames); | ||
| 4158 | #endif | ||
| 4159 | |||
| 4023 | func_key_syms = Qnil; | 4160 | func_key_syms = Qnil; |
| 4024 | staticpro (&func_key_syms); | 4161 | staticpro (&func_key_syms); |
| 4025 | 4162 | ||