Mercurial > emacs
comparison src/keyboard.c @ 1711:4cd44b41f1e3
* 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.
author | Jim Blandy <jimb@redhat.com> |
---|---|
date | Thu, 24 Dec 1992 06:12:04 +0000 |
parents | fe6f6e55182f |
children | 1f18bfe28e2f |
comparison
equal
deleted
inserted
replaced
1710:26054080a152 | 1711:4cd44b41f1e3 |
---|---|
239 extern char *pending_malloc_warning; | 239 extern char *pending_malloc_warning; |
240 | 240 |
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 |
247 next available char is in kbd_buffer[0]. */ | 274 next available char is in kbd_buffer[0]. */ |
248 static struct input_event *kbd_fetch_ptr; | 275 static struct input_event *kbd_fetch_ptr; |
256 static struct input_event *kbd_store_ptr; | 283 static struct input_event *kbd_store_ptr; |
257 | 284 |
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 |
272 moved since the last call to the mouse_position_hook. Calling that | 300 moved since the last call to the mouse_position_hook. Calling that |
273 hook should clear this. Code assumes that if this is set, it can | 301 hook should clear this. Code assumes that if this is set, it can |
284 ((kbd_fetch_ptr == kbd_store_ptr) && (!do_mouse_tracking || !mouse_moved)) | 312 ((kbd_fetch_ptr == kbd_store_ptr) && (!do_mouse_tracking || !mouse_moved)) |
285 | 313 |
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 |
302 /* Symbols to denote kinds of events. */ | 321 /* Symbols to denote kinds of events. */ |
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; |
310 Lisp_Object Qevent_symbol_elements; | 328 Lisp_Object Qevent_symbol_elements; |
311 | 329 |
323 Lisp_Object Qmodifier_cache; | 341 Lisp_Object Qmodifier_cache; |
324 | 342 |
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 (); |
331 | 350 |
332 /* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt | 351 /* Address (if not 0) of EMACS_TIME to zero out if a SIGIO interrupt |
1354 | 1373 |
1355 from_macro: | 1374 from_macro: |
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: |
1364 last_input_char = c; | 1386 last_input_char = c; |
1365 num_input_chars++; | 1387 num_input_chars++; |
1460 } | 1482 } |
1461 } | 1483 } |
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 { |
1472 int count = specpdl_ptr - specpdl; | 1494 int count = specpdl_ptr - specpdl; |
1473 Lisp_Object val; | 1495 Lisp_Object val; |
1502 #ifdef MULTI_FRAME | 1524 #ifdef MULTI_FRAME |
1503 /* If this results in a quit_char being returned to Emacs as | 1525 /* If this results in a quit_char being returned to Emacs as |
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; |
1511 interrupt_signal (); | 1540 interrupt_signal (); |
1512 return; | 1541 return; |
1536 kbd_store_ptr->frame = event->frame; | 1565 kbd_store_ptr->frame = event->frame; |
1537 kbd_store_ptr->modifiers = event->modifiers; | 1566 kbd_store_ptr->modifiers = event->modifiers; |
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 } |
1544 } | 1578 } |
1545 | 1579 |
1608 ? kbd_fetch_ptr | 1642 ? kbd_fetch_ptr |
1609 : kbd_buffer); | 1643 : kbd_buffer); |
1610 | 1644 |
1611 last_event_timestamp = event->timestamp; | 1645 last_event_timestamp = event->timestamp; |
1612 | 1646 |
1647 obj = Qnil; | |
1648 | |
1649 #ifdef MULTI_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. */ | |
1613 { | 1652 { |
1614 #ifdef MULTI_FRAME | 1653 Lisp_Object frame = FRAME_FOCUS_FRAME (event->frame); |
1615 Lisp_Object frame; | 1654 |
1616 | 1655 if (NILP (frame)) |
1617 /* If this event is on a different frame, return a switch-frame this | 1656 XSET (frame, Lisp_Frame, event->frame); |
1618 time, and leave the event in the queue for next time. */ | 1657 |
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; |
1634 | 1676 #ifdef MULTI_FRAME |
1635 kbd_fetch_ptr = event + 1; | 1677 XVECTOR (kbd_buffer_frames)->contents[event - kbd_buffer] = Qnil; |
1636 } | 1678 #endif |
1637 } | 1679 |
1680 kbd_fetch_ptr = event + 1; | |
1681 } | |
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! */ |
1664 abort (); | 1722 abort (); |
1665 | 1723 |
1666 input_pending = readable_events (); | 1724 input_pending = readable_events (); |
1667 | 1725 |
1668 return (obj); | 1726 return (obj); |
1669 } | 1727 } |
1728 | |
1670 | 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; |
1674 | 1733 |
1751 static char *lispy_mouse_names[] = | 1810 static char *lispy_mouse_names[] = |
1752 { | 1811 { |
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 { |
1759 Lisp_Object window; | 1827 Lisp_Object window; |
1760 Lisp_Object buffer_pos; | 1828 Lisp_Object buffer_pos; |
1847 /* Now we're releasing a button - check the co-ordinates to | 1915 /* Now we're releasing a button - check the co-ordinates to |
1848 see if this was a click or a drag. */ | 1916 see if this was a click or a drag. */ |
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 } |
1856 else | 1925 else |
1857 /* Every mouse event should either have the down_modifier or | 1926 /* Every mouse event should either have the down_modifier or |
1862 /* Build the event. */ | 1931 /* Build the event. */ |
1863 { | 1932 { |
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, |
1871 (sizeof (lispy_mouse_names) | 1940 (sizeof (lispy_mouse_names) |
1872 / sizeof (lispy_mouse_names[0]))); | 1941 / sizeof (lispy_mouse_names[0]))); |
1893 Fcons (end, | 1962 Fcons (end, |
1894 Qnil)); | 1963 Qnil)); |
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. */ |
1919 default: | 1993 default: |
1920 abort(); | 1994 abort(); |
1921 } | 1995 } |
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; |
1954 | 2050 } |
1955 XSETINT (x, ix); | 2051 |
1956 XSETINT (y, iy); | 2052 return Fcons (Qmouse_movement, |
1957 return Fcons (Qmouse_movement, | 2053 Fcons (Fcons (window, |
1958 Fcons (Fcons (window, | 2054 Fcons (posn, |
1959 Fcons (posn, | 2055 Fcons (Fcons (x, y), |
1960 Fcons (Fcons (x, y), | 2056 Fcons (make_number (time), |
1961 Fcons (make_number (time), | 2057 Qnil)))), |
1962 Qnil)))), | 2058 Qnil)); |
1963 Qnil)); | 2059 } |
1964 } | 2060 } |
1965 | 2061 |
1966 | 2062 |
1967 /* Construct a switch frame event. */ | 2063 /* Construct a switch frame event. */ |
1968 static Lisp_Object | 2064 static Lisp_Object |
2059 no_more_modifiers: | 2155 no_more_modifiers: |
2060 | 2156 |
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 |
2068 if (modifier_end) | 2164 if (modifier_end) |
2069 *modifier_end = i; | 2165 *modifier_end = i; |
2307 if (symbol_num < 0 || symbol_num >= table_size) | 2403 if (symbol_num < 0 || symbol_num >= table_size) |
2308 abort (); | 2404 abort (); |
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 { |
2316 Lisp_Object size; | 2413 Lisp_Object size; |
2317 | 2414 |
3310 \n\ | 3407 \n\ |
3311 First arg PROMPT is a prompt string. If nil, do not prompt specially.\n\ | 3408 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 { |
3322 Lisp_Object keybuf[30]; | 3440 Lisp_Object keybuf[30]; |
3323 register int i; | 3441 register int i; |
3582 | 3700 |
3583 /* Without the cast, GCC complains that this assignment loses the | 3701 /* Without the cast, GCC complains that this assignment loses the |
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; |
3590 } | 3711 } |
3591 | 3712 |
3674 { | 3795 { |
3675 if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) | 3796 if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) |
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; |
3682 #endif | 3808 #endif |
3683 #endif /* BSD and not BSD4_1 */ | 3809 #endif /* BSD and not BSD4_1 */ |
3883 | 4009 |
3884 #ifdef MULTI_FRAME | 4010 #ifdef MULTI_FRAME |
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) |
3891 { | 4023 { |
3892 signal (SIGINT, interrupt_signal); | 4024 signal (SIGINT, interrupt_signal); |
3935 Lisp_Object *kind; | 4067 Lisp_Object *kind; |
3936 }; | 4068 }; |
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 () |
3952 { | 4077 { |
3953 Qself_insert_command = intern ("self-insert-command"); | 4078 Qself_insert_command = intern ("self-insert-command"); |
3964 | 4089 |
3965 Qfunction_key = intern ("function-key"); | 4090 Qfunction_key = intern ("function-key"); |
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); |
3979 Qevent_symbol_elements = intern ("event-symbol-elements"); | 4111 Qevent_symbol_elements = intern ("event-symbol-elements"); |
3980 staticpro (&Qevent_symbol_elements); | 4112 staticpro (&Qevent_symbol_elements); |
4017 recent_keys = Fmake_vector (make_number (NUM_RECENT_KEYS), Qnil); | 4149 recent_keys = Fmake_vector (make_number (NUM_RECENT_KEYS), Qnil); |
4018 staticpro (&recent_keys); | 4150 staticpro (&recent_keys); |
4019 | 4151 |
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); |
4154 | |
4155 #ifdef MULTI_FRAME | |
4156 kbd_buffer_frames = Fmake_vector (make_number (KBD_BUFFER_SIZE), Qnil); | |
4157 staticpro (&kbd_buffer_frames); | |
4158 #endif | |
4022 | 4159 |
4023 func_key_syms = Qnil; | 4160 func_key_syms = Qnil; |
4024 staticpro (&func_key_syms); | 4161 staticpro (&func_key_syms); |
4025 | 4162 |
4026 mouse_syms = Qnil; | 4163 mouse_syms = Qnil; |