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 */
/* 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)
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)
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);
}
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;
}
{
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,
{
Lisp_Object position;
Lisp_Object head;
-
+
/* Build the position as appropriate for this mouse click. */
struct frame *f = XFRAME (event->frame_or_window);
{
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])
\f
#ifndef VMS
-/* We make the read_avail_input buffer static to avoid zeroing out the
- whole struct input_event buf on every call. */
-static struct input_event read_avail_input_buf[KBD_BUFFER_SIZE];
-
-/* I don't know whether it is necessary, but make read_avail_input
- re-entrant. */
-static int in_read_avail_input = 0;
-
/* Read any terminal input already buffered up by the system
into the kbd_buffer, but do not wait.
read_avail_input (expected)
int expected;
{
- struct input_event *buf = read_avail_input_buf;
register int i;
- int nread;
-
- /* Trivial hack to make read_avail_input re-entrant. */
- if (in_read_avail_input)
- return 0;
- in_read_avail_input = 1;
+ 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
/* Determine how many characters we should *try* to read. */
#ifdef WINDOWSNT
- return (in_read_avail_input = 0);
+ return 0;
#else /* not WINDOWSNT */
#ifdef MSDOS
n_to_read = dos_keysns ();
if (n_to_read == 0)
- return (in_read_avail_input = 0);
+ return 0;
#else /* not MSDOS */
#ifdef FIONREAD
/* Find out how much input is available. */
n_to_read = 0;
}
if (n_to_read == 0)
- return (in_read_avail_input = 0);
+ return 0;
if (n_to_read > sizeof cbuf)
n_to_read = sizeof cbuf;
#else /* no FIONREAD */
#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;
+ }
}
- /* Clear used events */
- for (i = 0; i < nread; i++)
- EVENT_INIT (buf[i]);
-
- in_read_avail_input = 0;
return nread;
}
#endif /* not VMS */
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. */
/* Adjust the function-key-map counters. */
fkey.end += diff;
fkey.start += diff;
-
+
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))
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++)
{
}
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.
do_mouse_tracking = Qnil;
#endif
input_pending = 0;
-#ifndef VMS
- {
- int i;
- for (i = 0; i < KBD_BUFFER_SIZE; i++)
- EVENT_INIT (read_avail_input_buf[i]);
- }
-#endif
-
/* This means that command_loop_1 won't try to select anything the first
time through. */
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);
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",
{
if (event == kbd_buffer + KBD_BUFFER_SIZE)
event = kbd_buffer;
- mark_object (event->x);
- mark_object (event->y);
+ if (event->kind != SELECTION_REQUEST_EVENT)
+ {
+ mark_object (event->x);
+ mark_object (event->y);
+ }
mark_object (event->frame_or_window);
mark_object (event->arg);
}