/* Keyboard and mouse input; editor command loop.
- Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99,2000,01,02,03
+ Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99,2000,01,02,03,04
Free Software Foundation, Inc.
This file is part of GNU Emacs.
args points to slot holding list of
unevalled args */
char evalargs;
+ /* Nonzero means call value of debugger when done with this operation. */
+ char debug_on_exit;
};
#ifdef MULTI_KBOARD
#endif
/* Non-nil disable property on a command means
- do not execute it; call disabled-command-hook's value instead. */
-Lisp_Object Qdisabled, Qdisabled_command_hook;
+ do not execute it; call disabled-command-function's value instead. */
+Lisp_Object Qdisabled, Qdisabled_command_function;
#define NUM_RECENT_KEYS (100)
int recent_keys_index; /* Index for storing next element into recent_keys */
static struct input_event kbd_buffer[KBD_BUFFER_SIZE];
-/* Vector to GCPRO the Lisp objects referenced from kbd_buffer.
-
- The interrupt-level event handlers will never enqueue an event on a
- frame which is not in Vframe_list, and once an event is dequeued,
- internal_last_event_frame or the event itself points to the frame.
- So that's all fine.
-
- But while the event is sitting in the queue, it's completely
- unprotected. Suppose the user types one command which will run for
- a while and then delete a frame, and then types another event at
- the frame that will be deleted, before the command gets around to
- it. Suppose there are no references to this frame elsewhere in
- Emacs, and a GC occurs before the second event is dequeued. Now we
- have an event referring to a freed frame, which will crash Emacs
- when it is dequeued.
-
- Similar things happen when an event on a scroll bar is enqueued; the
- window may be deleted while the event is in the queue.
-
- So, we use this vector to protect the Lisp_Objects in the event
- queue. That way, they'll be dequeued as dead frames or windows,
- but still valid Lisp objects.
-
- If kbd_buffer[i].kind != NO_EVENT, then
-
- AREF (kbd_buffer_gcpro, 2 * i) == kbd_buffer[i].frame_or_window.
- AREF (kbd_buffer_gcpro, 2 * i + 1) == kbd_buffer[i].arg. */
-
-static Lisp_Object kbd_buffer_gcpro;
-
/* Pointer to next available character in kbd_buffer.
If kbd_fetch_ptr == kbd_store_ptr, the buffer is empty.
This may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the
/* Symbols to denote kinds of events. */
Lisp_Object Qfunction_key;
Lisp_Object Qmouse_click;
-#if defined(MAC_OSX)
-Lisp_Object Qmouse_wheel;
-#endif
#ifdef WINDOWSNT
Lisp_Object Qlanguage_change;
#endif
Lisp_Object Qvertical_scroll_bar;
Lisp_Object Qmenu_bar;
extern Lisp_Object Qleft_margin, Qright_margin;
+extern Lisp_Object Qleft_fringe, Qright_fringe;
+extern Lisp_Object QCmap;
Lisp_Object recursive_edit_unwind (), command_loop ();
Lisp_Object Fthis_command_keys ();
/* We are unable to use interrupts if FIONREAD is not available,
so flush SIGIO so we won't try. */
-#ifndef FIONREAD
+#if !defined (FIONREAD) || defined(HAVE_CARBON)
#ifdef SIGIO
#undef SIGIO
#endif
to support it. */
static int cannot_suspend;
+extern Lisp_Object Qidentity, Qonly;
+\f
/* Install the string STR as the beginning of the string of echoing,
so that it serves as a prompt for the next character.
Also start echoing. */
== SCHARS (current_kboard->echo_string))
return;
+ /* Do nothing if we have already put a dash at the end. */
+ if (SCHARS (current_kboard->echo_string) > 1)
+ {
+ Lisp_Object last_char, prev_char, idx;
+
+ idx = make_number (SCHARS (current_kboard->echo_string) - 2);
+ prev_char = Faref (current_kboard->echo_string, idx);
+
+ idx = make_number (SCHARS (current_kboard->echo_string) - 1);
+ last_char = Faref (current_kboard->echo_string, idx);
+
+ if (XINT (last_char) == '-' && XINT (prev_char) != ' ')
+ return;
+ }
+
/* Put a dash at the end of the buffer temporarily,
but make it go away when the next character is added. */
current_kboard->echo_string = concat2 (current_kboard->echo_string,
int count = SPECPDL_INDEX ();
Lisp_Object buffer;
+ /* If we enter while input is blocked, don't lock up here.
+ This may happen through the debugger during redisplay. */
+ if (INPUT_BLOCKED_P)
+ return Qnil;
+
command_loop_level++;
update_mode_lines = 1;
#endif
}
+/* If we're in single_kboard state for kboard KBOARD,
+ get out of it. */
+
+void
+not_single_kboard_state (kboard)
+ KBOARD *kboard;
+{
+#ifdef MULTI_KBOARD
+ if (kboard == current_kboard)
+ single_kboard = 0;
+#endif
+}
+
/* Maintain a stack of kboards, so other parts of Emacs
can switch temporarily to the kboard of a given frame
and then revert to the previous status. */
Vinhibit_quit = Qnil;
#ifdef MULTI_KBOARD
- any_kboard_state ();
+ if (command_loop_level == 0 && minibuf_level == 0)
+ any_kboard_state ();
#endif
return make_number (0);
while (1)
{
internal_catch (Qtop_level, top_level_1, Qnil);
+ /* Reset single_kboard in case top-level set it while
+ evaluating an -f option, or we are stuck there for some
+ other reason. */
+ any_kboard_state ();
internal_catch (Qtop_level, command_loop_2, Qnil);
executing_macro = Qnil;
if (display_hourglass_p)
cancel_hourglass ();
#endif
+
+ /* Unblock input if we enter with input blocked. This may happen if
+ redisplay traps e.g. during tool-bar update with input blocked. */
+ while (INPUT_BLOCKED_P)
+ UNBLOCK_INPUT;
+
return Fthrow (Qtop_level, Qnil);
}
Lisp_Object arg;
{
cancel_hourglass ();
+ return Qnil;
}
#endif
call1 (Vrun_hooks, intern ("activate-mark-hook"));
}
+ /* Setting transient-mark-mode to `only' is a way of
+ turning it on for just one command. */
+ if (!NILP (current_buffer->mark_active) && !NILP (Vrun_hooks))
+ {
+ if (EQ (Vtransient_mark_mode, Qidentity))
+ Vtransient_mark_mode = Qnil;
+ if (EQ (Vtransient_mark_mode, Qonly))
+ Vtransient_mark_mode = Qidentity;
+ }
+
finalize:
if (current_buffer == prev_buffer
: (PT < last_pt ? beg : end));
check_composition = check_display = 1;
}
+#if 0 /* This assertion isn't correct, because SET_PT may end up setting
+ the point to something other than its argument, due to
+ point-motion hooks, intangibility, etc. */
xassert (PT == beg || PT == end);
+#endif
+
/* Pretend the area doesn't exist if the buffer is not
modified. */
if (!modified && !ellipsis && beg < end)
{
Lisp_Object posn;
- posn = POSN_BUFFER_POSN (EVENT_START (c));
+ posn = POSN_POSN (EVENT_START (c));
/* Handle menu-bar events:
insert the dummy prefix event `menu-bar'. */
if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
{
/* Change menu-bar to (menu-bar) as the event "position". */
- POSN_BUFFER_SET_POSN (EVENT_START (c), Fcons (posn, Qnil));
+ POSN_SET_POSN (EVENT_START (c), Fcons (posn, Qnil));
also_record = c;
Vunread_command_events = Fcons (c, Vunread_command_events);
void
kbd_buffer_store_event (event)
register struct input_event *event;
+{
+ kbd_buffer_store_event_hold (event, 0);
+}
+
+/* Store EVENT obtained at interrupt level into kbd_buffer, fifo.
+
+ If HOLD_QUIT is 0, just stuff EVENT into the fifo.
+ Else, if HOLD_QUIT.kind != NO_EVENT, discard EVENT.
+ Else, if EVENT is a quit event, store the quit event
+ in HOLD_QUIT, and return (thus ignoring further events).
+
+ This is used in read_avail_input to postpone the processing
+ of the quit event until all subsequent input events have been
+ parsed (and discarded).
+ */
+
+void
+kbd_buffer_store_event_hold (event, hold_quit)
+ register struct input_event *event;
+ struct input_event *hold_quit;
{
if (event->kind == NO_EVENT)
abort ();
+ if (hold_quit && hold_quit->kind != NO_EVENT)
+ return;
+
if (event->kind == ASCII_KEYSTROKE_EVENT)
{
register int c = event->code & 0377;
}
#endif
+ if (hold_quit)
+ {
+ bcopy (event, (char *) hold_quit, sizeof (*event));
+ return;
+ }
+
/* If this results in a quit_char being returned to Emacs as
input, set Vlast_event_frame properly. If this doesn't
get returned to Emacs as an event, the next event read
Just ignore the second one. */
else if (event->kind == BUFFER_SWITCH_EVENT
&& kbd_fetch_ptr != kbd_store_ptr
- && kbd_store_ptr->kind == BUFFER_SWITCH_EVENT)
+ && ((kbd_store_ptr == kbd_buffer
+ ? kbd_buffer + KBD_BUFFER_SIZE - 1
+ : kbd_store_ptr - 1)->kind) == BUFFER_SWITCH_EVENT)
return;
if (kbd_store_ptr - kbd_buffer == KBD_BUFFER_SIZE)
Discard the event if it would fill the last slot. */
if (kbd_fetch_ptr - 1 != kbd_store_ptr)
{
- int idx;
#if 0 /* The SELECTION_REQUEST_EVENT case looks bogus, and it's error
prone to assign individual members for other events, in case
*kbd_store_ptr = *event;
#endif
- idx = 2 * (kbd_store_ptr - kbd_buffer);
- ASET (kbd_buffer_gcpro, idx, event->frame_or_window);
- ASET (kbd_buffer_gcpro, idx + 1, event->arg);
++kbd_store_ptr;
}
}
Value is the number of input_events generated. */
-int
-gen_help_event (bufp, size, help, frame, window, object, pos)
- struct input_event *bufp;
- int size;
+void
+gen_help_event (help, frame, window, object, pos)
Lisp_Object help, frame, object, window;
int pos;
{
- if (size >= 1)
- {
- bufp->kind = HELP_EVENT;
- bufp->frame_or_window = frame;
- bufp->arg = object;
- bufp->x = WINDOWP (window) ? window : frame;
- bufp->y = help;
- bufp->code = pos;
- return 1;
- }
- return 0;
+ struct input_event event;
+
+ EVENT_INIT (event);
+
+ event.kind = HELP_EVENT;
+ event.frame_or_window = frame;
+ event.arg = object;
+ event.x = WINDOWP (window) ? window : frame;
+ event.y = help;
+ event.code = pos;
+ kbd_buffer_store_event (&event);
}
clear_event (event)
struct input_event *event;
{
- int idx = 2 * (event - kbd_buffer);
- ASET (kbd_buffer_gcpro, idx, Qnil);
- ASET (kbd_buffer_gcpro, idx + 1, Qnil);
event->kind = NO_EVENT;
}
break;
#endif
{
- Lisp_Object minus_one;
-
- XSETINT (minus_one, -1);
- wait_reading_process_input (0, 0, minus_one, 1);
+ wait_reading_process_output (0, 0, -1, 1, Qnil, NULL, 0);
if (!interrupt_input && kbd_fetch_ptr == kbd_store_ptr)
/* Pass 1 for EXPECT since we just waited to have input. */
else if (event->kind == LANGUAGE_CHANGE_EVENT)
{
/* Make an event (language-change (FRAME CHARSET LCID)). */
- obj = Fcons (event->modifiers, Qnil);
- obj = Fcons (event->code, obj);
- obj = Fcons (event->frame_or_window, obj);
+ obj = Fcons (event->frame_or_window, Qnil);
obj = Fcons (Qlanguage_change, Fcons (obj, Qnil));
kbd_fetch_ptr = event + 1;
}
static Lisp_Object func_key_syms;
static Lisp_Object mouse_syms;
static Lisp_Object wheel_syms;
-#if defined(MAC_OSX)
-static Lisp_Object mouse_wheel_syms;
-#endif
static Lisp_Object drag_n_drop_syms;
/* This is a list of keysym codes for special "accent" characters.
"wheel-up", "wheel-down"
};
-#if defined(MAC_OSX)
-/* mouse-wheel events are generated by the wheel on devices such as
- the MS Intellimouse. The wheel sits in between the left and right
- mouse buttons, and is typically used to scroll or zoom the window
- underneath the pointer. mouse-wheel events specify the object on
- which they operate, and a delta corresponding to the amount and
- direction that the wheel is rotated. Clicking the mouse-wheel
- generates a mouse-2 event. */
-static char *lispy_mouse_wheel_names[] =
-{
- "mouse-wheel"
-};
-
-#endif /* MAC_OSX */
-
/* drag-n-drop events are generated when a set of selected files are
dragged from another application and dropped onto an Emacs window. */
static char *lispy_drag_n_drop_names[] =
int double_click_count;
+/* Return position of a mouse click or wheel event */
+
+static Lisp_Object
+make_lispy_position (f, x, y, time)
+ struct frame *f;
+ Lisp_Object *x, *y;
+ unsigned long time;
+{
+ Lisp_Object window;
+ enum window_part part;
+ Lisp_Object posn = Qnil;
+ Lisp_Object extra_info = Qnil;
+ int wx, wy;
+
+ /* Set `window' to the window under frame pixel coordinates (x,y) */
+ if (f)
+ window = window_from_coordinates (f, XINT (*x), XINT (*y),
+ &part, &wx, &wy, 0);
+ else
+ window = Qnil;
+
+ if (WINDOWP (window))
+ {
+ /* It's a click in window window at frame coordinates (x,y) */
+ struct window *w = XWINDOW (window);
+ Lisp_Object string_info = Qnil;
+ int textpos = -1, rx = -1, ry = -1;
+ int dx = -1, dy = -1;
+ int width = -1, height = -1;
+ Lisp_Object object = Qnil;
+
+ /* Set event coordinates to window-relative coordinates
+ for constructing the Lisp event below. */
+ XSETINT (*x, wx);
+ XSETINT (*y, wy);
+
+ if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
+ {
+ /* Mode line or header line. Look for a string under
+ the mouse that may have a `local-map' property. */
+ Lisp_Object string;
+ int charpos;
+
+ posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line;
+ rx = wx, ry = wy;
+ string = mode_line_string (w, part, &rx, &ry, &charpos,
+ &object, &dx, &dy, &width, &height);
+ if (STRINGP (string))
+ string_info = Fcons (string, make_number (charpos));
+ if (w == XWINDOW (selected_window))
+ textpos = PT;
+ else
+ textpos = XMARKER (w->pointm)->charpos;
+ }
+ else if (part == ON_VERTICAL_BORDER)
+ {
+ posn = Qvertical_line;
+ wx = -1;
+ dx = 0;
+ width = 1;
+ }
+ else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
+ {
+ Lisp_Object string;
+ int charpos;
+
+ posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
+ rx = wx, ry = wy;
+ string = marginal_area_string (w, part, &rx, &ry, &charpos,
+ &object, &dx, &dy, &width, &height);
+ if (STRINGP (string))
+ string_info = Fcons (string, make_number (charpos));
+ }
+ else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
+ {
+ posn = (part == ON_LEFT_FRINGE) ? Qleft_fringe : Qright_fringe;
+ rx = 0;
+ dx = wx;
+ if (part == ON_RIGHT_FRINGE)
+ dx -= (window_box_width (w, LEFT_MARGIN_AREA)
+ + window_box_width (w, TEXT_AREA)
+ + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ ? window_box_width (w, RIGHT_MARGIN_AREA)
+ : 0));
+ else if (!WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
+ dx -= window_box_width (w, LEFT_MARGIN_AREA);
+ }
+
+ if (textpos < 0)
+ {
+ Lisp_Object string2, object2 = Qnil;
+ struct display_pos p;
+ int dx2, dy2;
+ int width2, height2;
+ wx = max (WINDOW_LEFT_MARGIN_WIDTH (w), wx);
+ string2 = buffer_posn_from_coords (w, &wx, &wy, &p,
+ &object2, &dx2, &dy2,
+ &width2, &height2);
+ textpos = CHARPOS (p.pos);
+ if (rx < 0) rx = wx;
+ if (ry < 0) ry = wy;
+ if (dx < 0) dx = dx2;
+ if (dy < 0) dy = dy2;
+ if (width < 0) width = width2;
+ if (height < 0) height = height2;
+
+ if (NILP (posn))
+ {
+ posn = make_number (textpos);
+ if (STRINGP (string2))
+ string_info = Fcons (string2,
+ make_number (CHARPOS (p.string_pos)));
+ }
+ if (NILP (object))
+ object = object2;
+ }
+
+#ifdef HAVE_WINDOW_SYSTEM
+ if (IMAGEP (object))
+ {
+ Lisp_Object image_map, hotspot;
+ if ((image_map = Fplist_get (XCDR (object), QCmap),
+ !NILP (image_map))
+ && (hotspot = find_hot_spot (image_map, dx, dy),
+ CONSP (hotspot))
+ && (hotspot = XCDR (hotspot), CONSP (hotspot)))
+ posn = XCAR (hotspot);
+ }
+#endif
+
+ /* Object info */
+ extra_info = Fcons (object,
+ Fcons (Fcons (make_number (dx),
+ make_number (dy)),
+ Fcons (Fcons (make_number (width),
+ make_number (height)),
+ Qnil)));
+
+ /* String info */
+ extra_info = Fcons (string_info,
+ Fcons (make_number (textpos),
+ Fcons (Fcons (make_number (rx),
+ make_number (ry)),
+ extra_info)));
+ }
+ else if (f != 0)
+ {
+ XSETFRAME (window, f);
+ }
+ else
+ {
+ window = Qnil;
+ XSETFASTINT (*x, 0);
+ XSETFASTINT (*y, 0);
+ }
+
+ return Fcons (window,
+ Fcons (posn,
+ Fcons (Fcons (*x, *y),
+ Fcons (make_number (time),
+ extra_info))));
+}
+
/* Given a struct input_event, build the lisp event which represents
it. If EVENT is 0, build a mouse movement event from the mouse
movement buffer, which should have a movement event in it.
Lisp_Object position;
Lisp_Object *start_pos_ptr;
Lisp_Object start_pos;
- Lisp_Object window;
position = Qnil;
/* Build the position as appropriate for this mouse click. */
if (event->kind == MOUSE_CLICK_EVENT)
{
- enum window_part part;
struct frame *f = XFRAME (event->frame_or_window);
- Lisp_Object posn;
- Lisp_Object string_info = Qnil;
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
int row, column;
- int wx, wy;
+#endif
/* Ignore mouse events that were made on frame that
have been deleted. */
if (! FRAME_LIVE_P (f))
return Qnil;
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* EVENT->x and EVENT->y are frame-relative pixel
coordinates at this place. Under old redisplay, COLUMN
and ROW are set to frame relative glyph coordinates
pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
&column, &row, NULL, 1);
-#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
/* In the non-toolkit version, clicks on the menu bar
are ordinary button events in the event buffer.
Distinguish them, and invoke the menu.
}
#endif /* not USE_X_TOOLKIT && not USE_GTK */
- /* Set `window' to the window under frame pixel coordinates
- event->x/event->y. */
- window = window_from_coordinates (f, XINT (event->x),
- XINT (event->y),
- &part, &wx, &wy, 0);
-
- if (!WINDOWP (window))
- {
- window = event->frame_or_window;
- posn = Qnil;
- }
- else
- {
- /* It's a click in window window at frame coordinates
- event->x/ event->y. */
- struct window *w = XWINDOW (window);
-
- /* Set event coordinates to window-relative coordinates
- for constructing the Lisp event below. */
- XSETINT (event->x, wx);
- XSETINT (event->y, wy);
-
- if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
- {
- /* Mode line or header line. Look for a string under
- the mouse that may have a `local-map' property. */
- Lisp_Object string;
- int charpos;
-
- posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line;
- string = mode_line_string (w, wx, wy, part, &charpos);
- if (STRINGP (string))
- string_info = Fcons (string, make_number (charpos));
- }
- else if (part == ON_VERTICAL_BORDER)
- posn = Qvertical_line;
- else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
- {
- int charpos;
- Lisp_Object object = marginal_area_string (w, wx, wy, part,
- &charpos);
- posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
- if (STRINGP (object))
- string_info = Fcons (object, make_number (charpos));
- }
- else
- {
- Lisp_Object object;
- struct display_pos p;
- buffer_posn_from_coords (w, &wx, &wy, &object, &p);
- posn = make_number (CHARPOS (p.pos));
- if (STRINGP (object))
- string_info
- = Fcons (object,
- make_number (CHARPOS (p.string_pos)));
- }
- }
-
- position
- = Fcons (window,
- Fcons (posn,
- Fcons (Fcons (event->x, event->y),
- Fcons (make_number (event->timestamp),
- (NILP (string_info)
- ? Qnil
- : Fcons (string_info, Qnil))))));
+ position = make_lispy_position (f, &event->x, &event->y,
+ event->timestamp);
}
#ifndef USE_TOOLKIT_SCROLL_BARS
else
{
/* It's a scrollbar click. */
+ Lisp_Object window;
Lisp_Object portion_whole;
Lisp_Object part;
case WHEEL_EVENT:
{
Lisp_Object position;
- Lisp_Object window;
Lisp_Object head;
-
- position = Qnil;
- /* Build the position as appropriate for this mouse click. */
- enum window_part part;
- struct frame *f = XFRAME (event->frame_or_window);
- Lisp_Object posn;
- Lisp_Object string_info = Qnil;
- int row, column;
- int wx, wy;
-
- /* Ignore wheel events that were made on frame that have been
- deleted. */
- if (! FRAME_LIVE_P (f))
- return Qnil;
-
- /* EVENT->x and EVENT->y are frame-relative pixel
- coordinates at this place. Under old redisplay, COLUMN
- and ROW are set to frame relative glyph coordinates
- which are then used to determine whether this click is
- in a menu (non-toolkit version). */
- pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
- &column, &row, NULL, 1);
-
- /* Set `window' to the window under frame pixel coordinates
- event->x/event->y. */
- window = window_from_coordinates (f, XINT (event->x),
- XINT (event->y),
- &part, &wx, &wy, 0);
-
- if (!WINDOWP (window))
- {
- window = event->frame_or_window;
- posn = Qnil;
- }
- else
- {
- /* It's a click in window window at frame coordinates
- event->x/ event->y. */
- struct window *w = XWINDOW (window);
-
- /* Set event coordinates to window-relative coordinates
- for constructing the Lisp event below. */
- XSETINT (event->x, wx);
- XSETINT (event->y, wy);
-
- if (part == ON_MODE_LINE || part == ON_HEADER_LINE)
- {
- /* Mode line or header line. Look for a string under
- the mouse that may have a `local-map' property. */
- Lisp_Object string;
- int charpos;
-
- posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line;
- string = mode_line_string (w, wx, wy, part, &charpos);
- if (STRINGP (string))
- string_info = Fcons (string, make_number (charpos));
- }
- else if (part == ON_VERTICAL_BORDER)
- posn = Qvertical_line;
- else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
- {
- int charpos;
- Lisp_Object object = marginal_area_string (w, wx, wy, part,
- &charpos);
- posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin;
- if (STRINGP (object))
- string_info = Fcons (object, make_number (charpos));
- }
- else
- {
- Lisp_Object object;
- struct display_pos p;
- buffer_posn_from_coords (w, &wx, &wy, &object, &p);
- posn = make_number (CHARPOS (p.pos));
- if (STRINGP (object))
- string_info
- = Fcons (object,
- make_number (CHARPOS (p.string_pos)));
- }
- }
-
- position
- = Fcons (window,
- Fcons (posn,
- Fcons (Fcons (event->x, event->y),
- Fcons (make_number (event->timestamp),
- (NILP (string_info)
- ? Qnil
- : Fcons (string_info, Qnil))))));
-
- /* Set double or triple modifiers to indicate the wheel speed. */
- {
- /* On window-system frames, use the value of
- double-click-fuzz as is. On other frames, interpret it
- as a multiple of 1/8 characters. */
- struct frame *f;
- int fuzz;
- int is_double;
-
- if (WINDOWP (event->frame_or_window))
- f = XFRAME (XWINDOW (event->frame_or_window)->frame);
- else if (FRAMEP (event->frame_or_window))
- f = XFRAME (event->frame_or_window);
- else
- abort ();
-
- if (FRAME_WINDOW_P (f))
- fuzz = double_click_fuzz;
- else
- fuzz = double_click_fuzz / 8;
-
- is_double = (last_mouse_button < 0
- && (abs (XINT (event->x) - last_mouse_x) <= fuzz)
- && (abs (XINT (event->y) - last_mouse_y) <= fuzz)
- && button_down_time != 0
- && (EQ (Vdouble_click_time, Qt)
- || (INTEGERP (Vdouble_click_time)
- && ((int)(event->timestamp - button_down_time)
- < XINT (Vdouble_click_time)))));
- if (is_double)
- {
- double_click_count++;
- event->modifiers |= ((double_click_count > 2)
- ? triple_modifier
- : double_modifier);
- }
- else
- {
- double_click_count = 1;
- event->modifiers |= click_modifier;
- }
-
- button_down_time = event->timestamp;
- /* Use a negative value to distinguish wheel from mouse button. */
- last_mouse_button = -1;
- last_mouse_x = XINT (event->x);
- last_mouse_y = XINT (event->y);
- }
-
- {
- int symbol_num;
-
- if (event->modifiers & up_modifier)
- {
- /* Emit a wheel-up event. */
- event->modifiers &= ~up_modifier;
- symbol_num = 0;
- }
- else if (event->modifiers & down_modifier)
- {
- /* Emit a wheel-down event. */
- event->modifiers &= ~down_modifier;
- symbol_num = 1;
- }
- else
- /* Every wheel event should either have the down_modifier or
- the up_modifier set. */
- abort ();
-
- /* Get the symbol we should use for the wheel event. */
- head = modify_event_symbol (symbol_num,
- event->modifiers,
- Qmouse_click,
- Qnil,
- lispy_wheel_names,
- &wheel_syms,
- ASIZE (wheel_syms));
- }
-
- if (event->modifiers & (double_modifier | triple_modifier))
- return Fcons (head,
- Fcons (position,
- Fcons (make_number (double_click_count),
- Qnil)));
- else
- return Fcons (head,
- Fcons (position,
- Qnil));
+
+ /* Build the position as appropriate for this mouse click. */
+ struct frame *f = XFRAME (event->frame_or_window);
+
+ /* Ignore wheel events that were made on frame that have been
+ deleted. */
+ if (! FRAME_LIVE_P (f))
+ return Qnil;
+
+ position = make_lispy_position (f, &event->x, &event->y,
+ event->timestamp);
+
+ /* Set double or triple modifiers to indicate the wheel speed. */
+ {
+ /* On window-system frames, use the value of
+ double-click-fuzz as is. On other frames, interpret it
+ as a multiple of 1/8 characters. */
+ struct frame *f;
+ int fuzz;
+ int is_double;
+
+ if (WINDOWP (event->frame_or_window))
+ f = XFRAME (XWINDOW (event->frame_or_window)->frame);
+ else if (FRAMEP (event->frame_or_window))
+ f = XFRAME (event->frame_or_window);
+ else
+ abort ();
+
+ if (FRAME_WINDOW_P (f))
+ fuzz = double_click_fuzz;
+ else
+ fuzz = double_click_fuzz / 8;
+
+ is_double = (last_mouse_button < 0
+ && (abs (XINT (event->x) - last_mouse_x) <= fuzz)
+ && (abs (XINT (event->y) - last_mouse_y) <= fuzz)
+ && button_down_time != 0
+ && (EQ (Vdouble_click_time, Qt)
+ || (INTEGERP (Vdouble_click_time)
+ && ((int)(event->timestamp - button_down_time)
+ < XINT (Vdouble_click_time)))));
+ if (is_double)
+ {
+ double_click_count++;
+ event->modifiers |= ((double_click_count > 2)
+ ? triple_modifier
+ : double_modifier);
+ }
+ else
+ {
+ double_click_count = 1;
+ event->modifiers |= click_modifier;
+ }
+
+ button_down_time = event->timestamp;
+ /* Use a negative value to distinguish wheel from mouse button. */
+ last_mouse_button = -1;
+ last_mouse_x = XINT (event->x);
+ last_mouse_y = XINT (event->y);
+ }
+
+ {
+ int symbol_num;
+
+ if (event->modifiers & up_modifier)
+ {
+ /* Emit a wheel-up event. */
+ event->modifiers &= ~up_modifier;
+ symbol_num = 0;
+ }
+ else if (event->modifiers & down_modifier)
+ {
+ /* Emit a wheel-down event. */
+ event->modifiers &= ~down_modifier;
+ symbol_num = 1;
+ }
+ else
+ /* Every wheel event should either have the down_modifier or
+ the up_modifier set. */
+ abort ();
+
+ /* Get the symbol we should use for the wheel event. */
+ head = modify_event_symbol (symbol_num,
+ event->modifiers,
+ Qmouse_click,
+ Qnil,
+ lispy_wheel_names,
+ &wheel_syms,
+ ASIZE (wheel_syms));
+ }
+
+ if (event->modifiers & (double_modifier | triple_modifier))
+ return Fcons (head,
+ Fcons (position,
+ Fcons (make_number (double_click_count),
+ Qnil)));
+ else
+ return Fcons (head,
+ Fcons (position,
+ Qnil));
}
}
}
#endif /* WINDOWSNT */
-#if defined(MAC_OSX)
- case MOUSE_WHEEL_EVENT:
- {
- enum window_part part;
- FRAME_PTR f = XFRAME (event->frame_or_window);
- Lisp_Object window;
- Lisp_Object posn;
- Lisp_Object head, position;
- int row, column;
-
- /* Ignore mouse events that were made on frame that
- have been deleted. */
- if (! FRAME_LIVE_P (f))
- return Qnil;
- pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
- &column, &row, NULL, 1);
- window = window_from_coordinates (f, XINT (event->x),
- XINT (event->y),
- &part, 0, 0, 0);
-
- if (!WINDOWP (window))
- {
- window = event->frame_or_window;
- posn = Qnil;
- }
- else
- {
- int pixcolumn, pixrow;
- column -= WINDOW_LEFT_EDGE_COL (XWINDOW (window));
- row -= WINDOW_TOP_EDGE_LINE (XWINDOW (window));
- glyph_to_pixel_coords (XWINDOW(window), column, row,
- &pixcolumn, &pixrow);
- XSETINT (event->x, pixcolumn);
- XSETINT (event->y, pixrow);
-
- if (part == ON_MODE_LINE)
- posn = Qmode_line;
- else if (part == ON_VERTICAL_BORDER)
- posn = Qvertical_line;
- else if (part == ON_HEADER_LINE)
- posn = Qheader_line;
- else
- {
- Lisp_Object object;
- struct display_pos p;
- buffer_posn_from_coords (XWINDOW (window), &column, &row,
- &object, &p);
- posn = make_number (CHARPOS (p.pos));
- }
- }
-
- {
- Lisp_Object head, position;
-
- position
- = Fcons (window,
- Fcons (posn,
- Fcons (Fcons (event->x, event->y),
- Fcons (make_number (event->timestamp),
- Qnil))));
-
- head = modify_event_symbol (0, event->modifiers,
- Qmouse_wheel, Qnil,
- lispy_mouse_wheel_names,
- &mouse_wheel_syms, 1);
- return Fcons (head,
- Fcons (position,
- /* Insert 1 here so event-click-count works. */
- Fcons (make_number (1),
- Fcons (make_number (event->code),
- Qnil))));
- }
- }
-#endif /* MAC_OSX */
case DRAG_N_DROP_EVENT:
{
- enum window_part part;
FRAME_PTR f;
- Lisp_Object window;
- Lisp_Object posn;
+ Lisp_Object head, position;
Lisp_Object files;
- int wx, wy;
/* The frame_or_window field should be a cons of the frame in
which the event occurred and a list of the filenames
if (! FRAME_LIVE_P (f))
return Qnil;
- window = window_from_coordinates (f, XINT (event->x),
- XINT (event->y),
- &part, &wx, &wy, 0);
-
- if (!WINDOWP (window))
- {
- window = XCAR (event->frame_or_window);
- posn = Qnil;
- }
- else
- {
- /* It's an event in window `window' at frame coordinates
- event->x/ event->y. */
- struct window *w = XWINDOW (window);
-
- /* Set event coordinates to window-relative coordinates
- for constructing the Lisp event below. */
- XSETINT (event->x, wx);
- XSETINT (event->y, wy);
-
- if (part == ON_MODE_LINE)
- posn = Qmode_line;
- else if (part == ON_VERTICAL_BORDER)
- posn = Qvertical_line;
- else if (part == ON_HEADER_LINE)
- posn = Qheader_line;
- else
- {
- Lisp_Object object;
- struct display_pos p;
- buffer_posn_from_coords (w, &wx, &wy, &object, &p);
- posn = make_number (CHARPOS (p.pos));
- }
- }
-
- {
- Lisp_Object head, position;
-
- position
- = Fcons (window,
- Fcons (posn,
- Fcons (Fcons (event->x, event->y),
- Fcons (make_number (event->timestamp),
- Qnil))));
-
- head = modify_event_symbol (0, event->modifiers,
- Qdrag_n_drop, Qnil,
- lispy_drag_n_drop_names,
- &drag_n_drop_syms, 1);
- return Fcons (head,
- Fcons (position,
- Fcons (files,
- Qnil)));
- }
+ position = make_lispy_position (f, &event->x, &event->y,
+ event->timestamp);
+
+ head = modify_event_symbol (0, event->modifiers,
+ Qdrag_n_drop, Qnil,
+ lispy_drag_n_drop_names,
+ &drag_n_drop_syms, 1);
+ return Fcons (head,
+ Fcons (position,
+ Fcons (files,
+ Qnil)));
}
#endif /* HAVE_MOUSE */
/* Or is it an ordinary mouse movement? */
else
{
- enum window_part area;
- Lisp_Object window;
- Lisp_Object posn;
- int wx, wy;
+ Lisp_Object position;
- if (frame)
- /* It's in a frame; which window on that frame? */
- window = window_from_coordinates (frame, XINT (x), XINT (y),
- &area, &wx, &wy, 0);
- else
- window = Qnil;
-
- if (WINDOWP (window))
- {
- struct window *w = XWINDOW (window);
-
- /* Set window relative coordinates. */
- XSETINT (x, wx);
- XSETINT (y, wy);
-
- if (area == ON_MODE_LINE)
- posn = Qmode_line;
- else if (area == ON_VERTICAL_BORDER)
- posn = Qvertical_line;
- else if (area == ON_HEADER_LINE)
- posn = Qheader_line;
- else
- {
- Lisp_Object object;
- struct display_pos p;
- buffer_posn_from_coords (w, &wx, &wy, &object, &p);
- posn = make_number (CHARPOS (p.pos));
- }
- }
- else if (frame != 0)
- {
- XSETFRAME (window, frame);
- posn = Qnil;
- }
- else
- {
- window = Qnil;
- posn = Qnil;
- XSETFASTINT (x, 0);
- XSETFASTINT (y, 0);
- }
+ position = make_lispy_position (frame, &x, &y, time);
return Fcons (Qmouse_movement,
- Fcons (Fcons (window,
- Fcons (posn,
- Fcons (Fcons (x, y),
- Fcons (make_number (time),
- Qnil)))),
+ Fcons (position,
Qnil));
}
}
SBYTES (SYMBOL_NAME (symbol)) - end),
Qnil);
- if (modifiers & ~VALMASK)
+ if (modifiers & ~INTMASK)
abort ();
XSETFASTINT (mask, modifiers);
elements = Fcons (unmodified, Fcons (mask, Qnil));
Lisp_Object cache, index, entry, new_symbol;
/* Mask out upper bits. We don't know where this value's been. */
- modifiers &= VALMASK;
+ modifiers &= INTMASK;
/* The click modifier never figures into cache indices. */
cache = Fget (base, Qmodifier_cache);
{
int len = SBYTES (name_alist_or_stem);
char *buf = (char *) alloca (len + 50);
- if (sizeof (int) == sizeof (EMACS_INT))
- sprintf (buf, "%s-%d", SDATA (name_alist_or_stem),
- XINT (symbol_int) + 1);
- else if (sizeof (long) == sizeof (EMACS_INT))
- sprintf (buf, "%s-%ld", SDATA (name_alist_or_stem),
- XINT (symbol_int) + 1);
+ sprintf (buf, "%s-%ld", SDATA (name_alist_or_stem),
+ (long) XINT (symbol_int) + 1);
value = intern (buf);
}
else if (name_table != 0 && name_table[symbol_num])
{
struct input_event event;
Lisp_Object tem;
+ EVENT_INIT (event);
event.kind = BUFFER_SWITCH_EVENT;
event.frame_or_window = Qnil;
read_avail_input (expected)
int expected;
{
- struct input_event buf[KBD_BUFFER_SIZE];
register int i;
- int nread;
+ int nread = 0;
if (read_socket_hook)
- /* No need for FIONREAD or fcntl; just say don't wait. */
- nread = (*read_socket_hook) (input_fd, buf, KBD_BUFFER_SIZE, expected);
+ {
+ int discard = 0;
+ int nr;
+ struct input_event hold_quit;
+
+ EVENT_INIT (hold_quit);
+ hold_quit.kind = NO_EVENT;
+
+ /* No need for FIONREAD or fcntl; just say don't wait. */
+ while (nr = (*read_socket_hook) (input_fd, expected, &hold_quit), nr > 0)
+ {
+ nread += nr;
+ expected = 0;
+ }
+ if (hold_quit.kind != NO_EVENT)
+ kbd_buffer_store_event (&hold_quit);
+ }
else
{
/* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
/* ??? Is it really right to send the signal just to this process
rather than to the whole process group?
Perhaps on systems with FIONREAD Emacs is alone in its group. */
- kill (getpid (), SIGHUP);
+ {
+ if (! noninteractive)
+ kill (getpid (), SIGHUP);
+ else
+ n_to_read = 0;
+ }
if (n_to_read == 0)
return 0;
if (n_to_read > sizeof cbuf)
#endif /* no FIONREAD */
for (i = 0; i < nread; i++)
{
- buf[i].kind = ASCII_KEYSTROKE_EVENT;
- buf[i].modifiers = 0;
+ struct input_event buf;
+ EVENT_INIT (buf);
+ buf.kind = ASCII_KEYSTROKE_EVENT;
+ buf.modifiers = 0;
if (meta_key == 1 && (cbuf[i] & 0x80))
- buf[i].modifiers = meta_modifier;
+ buf.modifiers = meta_modifier;
if (meta_key != 2)
cbuf[i] &= ~0x80;
- buf[i].code = cbuf[i];
- buf[i].frame_or_window = selected_frame;
- buf[i].arg = Qnil;
- }
- }
+ buf.code = cbuf[i];
+ buf.frame_or_window = selected_frame;
+ buf.arg = Qnil;
- /* Scan the chars for C-g and store them in kbd_buffer. */
- for (i = 0; i < nread; i++)
- {
- kbd_buffer_store_event (&buf[i]);
- /* Don't look at input that follows a C-g too closely.
- This reduces lossage due to autorepeat on C-g. */
- if (buf[i].kind == ASCII_KEYSTROKE_EVENT
- && buf[i].code == quit_char)
- break;
+ kbd_buffer_store_event (&buf);
+ /* Don't look at input that follows a C-g too closely.
+ This reduces lossage due to autorepeat on C-g. */
+ if (buf.kind == ASCII_KEYSTROKE_EVENT
+ && buf.code == quit_char)
+ break;
+ }
}
return nread;
}
#endif /* not VMS */
\f
+void
+handle_async_input ()
+{
+#ifdef BSD4_1
+ extern int select_alarmed;
+#endif
+ interrupt_input_pending = 0;
+
+ while (1)
+ {
+ int nread;
+ nread = read_avail_input (1);
+ /* -1 means it's not ok to read the input now.
+ UNBLOCK_INPUT will read it later; now, avoid infinite loop.
+ 0 means there was no keyboard input available. */
+ if (nread <= 0)
+ break;
+
+#ifdef BSD4_1
+ select_alarmed = 1; /* Force the select emulator back to life */
+#endif
+ }
+}
+
#ifdef SIGIO /* for entire page */
/* Note SIGIO has been undef'd if FIONREAD is missing. */
{
/* Must preserve main program's value of errno. */
int old_errno = errno;
-#ifdef BSD4_1
- extern int select_alarmed;
-#endif
#if defined (USG) && !defined (POSIX_SIGNALS)
/* USG systems forget handlers when they are used;
if (input_available_clear_time)
EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
- while (1)
- {
- int nread;
- nread = read_avail_input (1);
- /* -1 means it's not ok to read the input now.
- UNBLOCK_INPUT will read it later; now, avoid infinite loop.
- 0 means there was no keyboard input available. */
- if (nread <= 0)
- break;
-
-#ifdef BSD4_1
- select_alarmed = 1; /* Force the select emulator back to life */
+#ifdef SYNC_INPUT
+ interrupt_input_pending = 1;
+#else
+ handle_async_input ();
#endif
- }
#ifdef BSD4_1
sigfree ();
reinvoke_input_signal ()
{
#ifdef SIGIO
- kill (getpid (), SIGIO);
+ handle_async_input ();
#endif
}
newcache = chkcache;
if (chkcache)
{
- tem = Fkey_description (tem);
+ tem = Fkey_description (tem, Qnil);
if (CONSP (prefix))
{
if (STRINGP (XCAR (prefix)))
int do_funcall;
{
Lisp_Object next;
-
+
next = access_keymap (map, key, 1, 0, 1);
/* Handle symbol with autoload definition. */
&& (!NILP (Farrayp (XSYMBOL (next)->function))
|| KEYMAPP (XSYMBOL (next)->function)))
next = XSYMBOL (next)->function;
-
+
/* If the keymap gives a function, not an
array, then call the function with one arg and use
its value instead. */
if (EVENT_HAS_PARAMETERS (key))
{
Lisp_Object kind;
+ Lisp_Object string;
kind = EVENT_HEAD_KIND (EVENT_HEAD (key));
if (EQ (kind, Qmouse_click))
Lisp_Object window, posn;
window = POSN_WINDOW (EVENT_START (key));
- posn = POSN_BUFFER_POSN (EVENT_START (key));
+ posn = POSN_POSN (EVENT_START (key));
if (CONSP (posn)
|| (!NILP (fake_prefixed_keys)
localized_local_map = 1;
start = EVENT_START (key);
- if (CONSP (start) && CONSP (XCDR (start)))
+ if (CONSP (start) && POSN_INBUFFER_P (start))
{
pos = POSN_BUFFER_POSN (start);
if (INTEGERP (pos)
/* If on a mode line string with a local keymap,
reconsider the key sequence with that keymap. */
- if (CONSP (POSN_STRING (EVENT_START (key))))
+ if (string = POSN_STRING (EVENT_START (key)),
+ (CONSP (string) && STRINGP (XCAR (string))))
{
- Lisp_Object string, pos, map, map2;
+ Lisp_Object pos, map, map2;
- string = POSN_STRING (EVENT_START (key));
pos = XCDR (string);
string = XCAR (string);
if (XINT (pos) >= 0
goto replay_key;
}
- else if (CONSP (POSN_STRING (EVENT_START (key)))
- && NILP (from_string))
+ else if (NILP (from_string)
+ && (string = POSN_STRING (EVENT_START (key)),
+ (CONSP (string) && STRINGP (XCAR (string)))))
{
/* For a click on a string, i.e. overlay string or a
string displayed via the `display' property,
consider `local-map' and `keymap' properties of
that string. */
- Lisp_Object string, pos, map, map2;
+ Lisp_Object pos, map, map2;
- string = POSN_STRING (EVENT_START (key));
pos = XCDR (string);
string = XCAR (string);
if (XINT (pos) >= 0
{
Lisp_Object posn;
- posn = POSN_BUFFER_POSN (EVENT_START (key));
+ posn = POSN_POSN (EVENT_START (key));
/* Handle menu-bar events:
insert the dummy prefix event `menu-bar'. */
if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
/* Zap the position in key, so we know that we've
expanded it, and don't try to do so again. */
- POSN_BUFFER_SET_POSN (EVENT_START (key),
- Fcons (posn, Qnil));
+ POSN_SET_POSN (EVENT_START (key),
+ Fcons (posn, Qnil));
mock_input = t + 2;
goto replay_sequence;
/* Adjust the function-key-map counters. */
fkey.end += diff;
fkey.start += diff;
-
+
goto replay_sequence;
}
}
keybuf[t - 1] = new_key;
mock_input = max (t, mock_input);
+ fkey.start = fkey.end = KEYMAPP (fkey.map) ? 0 : bufsize + 1;
+ keytran.start = keytran.end = KEYMAPP (keytran.map) ? 0 : bufsize + 1;
goto replay_sequence;
}
tem = Fget (cmd, Qdisabled);
if (!NILP (tem) && !NILP (Vrun_hooks))
{
- tem = Fsymbol_value (Qdisabled_command_hook);
+ tem = Fsymbol_value (Qdisabled_command_function);
if (!NILP (tem))
- return call1 (Vrun_hooks, Qdisabled_command_hook);
+ return call1 (Vrun_hooks, Qdisabled_command_function);
}
}
backtrace.args = &cmd;
backtrace.nargs = 1;
backtrace.evalargs = 0;
+ backtrace.debug_on_exit = 0;
tem = Fcall_interactively (cmd, record_flag, keys);
else if (CONSP (prefixarg) && XINT (XCAR (prefixarg)) == 4)
strcpy (buf, "C-u ");
else if (CONSP (prefixarg) && INTEGERP (XCAR (prefixarg)))
- {
- if (sizeof (int) == sizeof (EMACS_INT))
- sprintf (buf, "%d ", XINT (XCAR (prefixarg)));
- else if (sizeof (long) == sizeof (EMACS_INT))
- sprintf (buf, "%ld ", (long) XINT (XCAR (prefixarg)));
- else
- abort ();
- }
+ sprintf (buf, "%ld ", (long) XINT (XCAR (prefixarg)));
else if (INTEGERP (prefixarg))
- {
- if (sizeof (int) == sizeof (EMACS_INT))
- sprintf (buf, "%d ", XINT (prefixarg));
- else if (sizeof (long) == sizeof (EMACS_INT))
- sprintf (buf, "%ld ", (long) XINT (prefixarg));
- else
- abort ();
- }
+ sprintf (buf, "%ld ", (long) XINT (prefixarg));
/* This isn't strictly correct if execute-extended-command
is bound to anything else. Perhaps it should use
int count = SPECPDL_INDEX ();
record_unwind_protect (pop_message_unwind, Qnil);
- binding = Fkey_description (bindings);
+ binding = Fkey_description (bindings, Qnil);
newmessage
= (char *) alloca (SCHARS (SYMBOL_NAME (function))
}
/* Return nonzero if there are pending requeued events.
- This isn't used yet. The hope is to make wait_reading_process_input
+ This isn't used yet. The hope is to make wait_reading_process_output
call it, and return if it runs Lisp code that unreads something.
The problem is, kbd_buffer_get_event needs to be fixed to know what
to do in that case. It isn't trivial. */
discard_tty_input ();
kbd_fetch_ptr = kbd_store_ptr;
- Ffillarray (kbd_buffer_gcpro, Qnil);
input_pending = 0;
return Qnil;
stuff_buffered_input (stuffstring)
Lisp_Object stuffstring;
{
-/* stuff_char works only in BSD, versions 4.2 and up. */
-#ifdef BSD_SYSTEM
-#ifndef BSD4_1
+#ifdef SIGTSTP /* stuff_char is defined if SIGTSTP. */
register unsigned char *p;
if (STRINGP (stuffstring))
/* Anything we have read ahead, put back for the shell to read. */
/* ?? What should this do when we have multiple keyboards??
- Should we ignore anything that was typed in at the "wrong" kboard? */
+ Should we ignore anything that was typed in at the "wrong" kboard?
+
+ rms: we should stuff everything back into the kboard
+ it came from. */
for (; kbd_fetch_ptr != kbd_store_ptr; kbd_fetch_ptr++)
{
- int idx;
if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
kbd_fetch_ptr = kbd_buffer;
if (kbd_fetch_ptr->kind == ASCII_KEYSTROKE_EVENT)
stuff_char (kbd_fetch_ptr->code);
- kbd_fetch_ptr->kind = NO_EVENT;
- idx = 2 * (kbd_fetch_ptr - kbd_buffer);
- ASET (kbd_buffer_gcpro, idx, Qnil);
- ASET (kbd_buffer_gcpro, idx + 1, Qnil);
+ clear_event (kbd_fetch_ptr);
}
input_pending = 0;
-#endif
-#endif /* BSD_SYSTEM and not BSD4_1 */
+#endif /* SIGTSTP */
}
\f
void
return Flist (sizeof (val) / sizeof (val[0]), val);
}
+DEFUN ("posn-at-x-y", Fposn_at_x_y, Sposn_at_x_y, 2, 3, 0,
+ doc: /* Return position information for pixel coordinates X and Y.
+By default, X and Y are relative to text area of the selected window.
+Optional third arg FRAME_OR_WINDOW non-nil specifies frame or window.
+
+The return value is similar to a mouse click position:
+ (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
+ IMAGE (DX . DY) (WIDTH . HEIGHT))
+The `posn-' functions access elements of such lists. */)
+ (x, y, frame_or_window)
+ Lisp_Object x, y, frame_or_window;
+{
+ if (NILP (frame_or_window))
+ frame_or_window = selected_window;
+
+ if (WINDOWP (frame_or_window))
+ {
+ struct window *w;
+
+ CHECK_LIVE_WINDOW (frame_or_window);
+
+ w = XWINDOW (frame_or_window);
+ XSETINT (x, (WINDOW_TO_FRAME_PIXEL_X (w, XINT (x))
+ + window_box_left_offset (w, TEXT_AREA)));
+ XSETINT (y, WINDOW_TO_FRAME_PIXEL_Y (w, XINT (y)));
+ frame_or_window = w->frame;
+ }
+
+ CHECK_LIVE_FRAME (frame_or_window);
+
+ return make_lispy_position (XFRAME (frame_or_window), &x, &y, 0);
+}
+
+DEFUN ("posn-at-point", Fposn_at_point, Sposn_at_point, 0, 2, 0,
+ doc: /* Return position information for buffer POS in WINDOW.
+POS defaults to point in WINDOW; WINDOW defaults to the selected window.
+
+Return nil if position is not visible in window. Otherwise,
+the return value is similar to that returned by `event-start' for
+a mouse click at the upper left corner of the glyph corresponding
+to the given buffer position:
+ (WINDOW AREA-OR-POS (X . Y) TIMESTAMP OBJECT POS (COL . ROW)
+ IMAGE (DX . DY) (WIDTH . HEIGHT))
+The `posn-' functions access elements of such lists. */*/)
+ (pos, window)
+ Lisp_Object pos, window;
+{
+ Lisp_Object tem;
+
+ tem = Fpos_visible_in_window_p (pos, window, Qt);
+ if (!NILP (tem))
+ tem = Fposn_at_x_y (XCAR (tem), XCAR (XCDR (tem)), window);
+ return tem;
+}
+
\f
/*
* Set up a new kboard object with reasonable initial values.
recent_keys_index = 0;
kbd_fetch_ptr = kbd_buffer;
kbd_store_ptr = kbd_buffer;
- kbd_buffer_gcpro = Fmake_vector (make_number (2 * KBD_BUFFER_SIZE), Qnil);
#ifdef HAVE_MOUSE
do_mouse_tracking = Qnil;
#endif
Qtimer_event_handler = intern ("timer-event-handler");
staticpro (&Qtimer_event_handler);
- Qdisabled_command_hook = intern ("disabled-command-hook");
- staticpro (&Qdisabled_command_hook);
+ Qdisabled_command_function = intern ("disabled-command-function");
+ staticpro (&Qdisabled_command_function);
Qself_insert_command = intern ("self-insert-command");
staticpro (&Qself_insert_command);
staticpro (&Qfunction_key);
Qmouse_click = intern ("mouse-click");
staticpro (&Qmouse_click);
-#if defined(MAC_OSX)
- Qmouse_wheel = intern ("mouse-wheel");
- staticpro (&Qmouse_wheel);
-#endif
#ifdef WINDOWSNT
Qlanguage_change = intern ("language-change");
staticpro (&Qlanguage_change);
Fset (Qextended_command_history, Qnil);
staticpro (&Qextended_command_history);
- kbd_buffer_gcpro = Fmake_vector (make_number (2 * KBD_BUFFER_SIZE), Qnil);
- staticpro (&kbd_buffer_gcpro);
-
accent_key_syms = Qnil;
staticpro (&accent_key_syms);
func_key_syms = Qnil;
staticpro (&func_key_syms);
-#if defined(MAC_OSX)
- mouse_wheel_syms = Qnil;
- staticpro (&mouse_wheel_syms);
drag_n_drop_syms = Qnil;
staticpro (&drag_n_drop_syms);
-#endif
unread_switch_frame = Qnil;
staticpro (&unread_switch_frame);
defsubr (&Sset_input_mode);
defsubr (&Scurrent_input_mode);
defsubr (&Sexecute_extended_command);
+ defsubr (&Sposn_at_point);
+ defsubr (&Sposn_at_x_y);
DEFVAR_LISP ("last-command-char", &last_command_char,
doc: /* Last input event that was part of a command. */);
DEFVAR_LISP ("keyboard-translate-table", &Vkeyboard_translate_table,
doc: /* Translate table for keyboard input, or nil.
-Each character is looked up in this string and the contents used instead.
-The value may be a string, a vector, or a char-table.
-If it is a string or vector of length N,
-character codes N and up are untranslated.
-In a vector or a char-table, an element which is nil means "no translation".
+If non-nil, the value should be a char-table. Each character read
+from the keyboard is looked up in this char-table. If the value found
+there is non-nil, then it is used instead of the actual input character.
+
+The value can also be a string or vector, but this is considered obsolete.
+If it is a string or vector of length N, character codes N and up are left
+untranslated. In a vector, an element which is nil means "no translation".
This is applied to the characters supplied to input methods, not their
output. See also `translation-table-for-input'. */);
doc: /* Per-terminal keymap that overrides all other local keymaps.
If this variable is non-nil, it is used as a keymap instead of the
buffer's local map, and the minor mode keymaps and text property keymaps.
+It also overrides `overriding-local-map'.
This variable is intended to let commands such as `universal-argument'
set up a different keymap for reading the next command. */);
After a command is executed, if point is moved into a region that has
special properties (e.g. composition, display), we adjust point to
-the boundary of the region. But, several special commands sets this
-variable to non-nil, then we suppress the point adjustment.
+the boundary of the region. But, when a command sets this variable to
+non-nil, we suppress the point adjustment.
This variable is set to nil before reading a command, and is checked
just after executing the command. */);
/* Handling it at such a low-level causes read_key_sequence to get
* confused because it doesn't realize that the current_buffer was
* changed by read_char.
- *
+ *
* initial_define_lispy_key (Vspecial_event_map, "select-window",
* "handle-select-window"); */
initial_define_lispy_key (Vspecial_event_map, "save-session",
"handle-save-session");
}
+
+/* Mark the pointers in the kboard objects.
+ Called by the Fgarbage_collector. */
+void
+mark_kboards ()
+{
+ KBOARD *kb;
+ Lisp_Object *p;
+ for (kb = all_kboards; kb; kb = kb->next_kboard)
+ {
+ if (kb->kbd_macro_buffer)
+ for (p = kb->kbd_macro_buffer; p < kb->kbd_macro_ptr; p++)
+ mark_object (*p);
+ mark_object (kb->Voverriding_terminal_local_map);
+ mark_object (kb->Vlast_command);
+ mark_object (kb->Vreal_last_command);
+ mark_object (kb->Vprefix_arg);
+ mark_object (kb->Vlast_prefix_arg);
+ mark_object (kb->kbd_queue);
+ mark_object (kb->defining_kbd_macro);
+ mark_object (kb->Vlast_kbd_macro);
+ mark_object (kb->Vsystem_key_alist);
+ mark_object (kb->system_key_syms);
+ mark_object (kb->Vdefault_minibuffer_frame);
+ mark_object (kb->echo_string);
+ }
+ {
+ struct input_event *event;
+ for (event = kbd_fetch_ptr; event != kbd_store_ptr; event++)
+ {
+ if (event == kbd_buffer + KBD_BUFFER_SIZE)
+ event = kbd_buffer;
+ if (event->kind != SELECTION_REQUEST_EVENT)
+ {
+ mark_object (event->x);
+ mark_object (event->y);
+ }
+ mark_object (event->frame_or_window);
+ mark_object (event->arg);
+ }
+ }
+}
+
+/* arch-tag: 774e34d7-6d31-42f3-8397-e079a4e4c9ca
+ (do not change this comment) */