/* Circular buffer for pre-read keyboard input. */
-static struct input_event kbd_buffer[KBD_BUFFER_SIZE];
+static union buffered_input_event kbd_buffer[KBD_BUFFER_SIZE];
/* 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
next available char is in kbd_buffer[0]. */
-static struct input_event *kbd_fetch_ptr;
+static union buffered_input_event *kbd_fetch_ptr;
/* Pointer to next place to store character in kbd_buffer. This
may be kbd_buffer + KBD_BUFFER_SIZE, meaning that the next
character should go in kbd_buffer[0]. */
-static struct input_event * volatile kbd_store_ptr;
+static union buffered_input_event *volatile kbd_store_ptr;
/* The above pair of variables forms a "queue empty" flag. When we
enqueue a non-hook event, we increment kbd_store_ptr. When we
static void save_getcjmp (sys_jmp_buf);
static void restore_getcjmp (sys_jmp_buf);
static Lisp_Object apply_modifiers (int, Lisp_Object);
-static void clear_event (struct input_event *);
static void restore_kboard_configuration (int);
-#ifdef USABLE_SIGIO
-static void deliver_input_available_signal (int signo);
-#endif
static void handle_interrupt (bool);
static _Noreturn void quit_throw_to_read_char (bool);
-static void process_special_events (void);
static void timer_start_idle (void);
static void timer_stop_idle (void);
static void timer_resume_idle (void);
static void
kset_echo_string (struct kboard *kb, Lisp_Object val)
{
- kb->INTERNAL_FIELD (echo_string) = val;
+ kb->echo_string_ = val;
}
static void
kset_kbd_queue (struct kboard *kb, Lisp_Object val)
{
- kb->INTERNAL_FIELD (kbd_queue) = val;
+ kb->kbd_queue_ = val;
}
static void
kset_keyboard_translate_table (struct kboard *kb, Lisp_Object val)
{
- kb->INTERNAL_FIELD (Vkeyboard_translate_table) = val;
+ kb->Vkeyboard_translate_table_ = val;
}
static void
kset_last_prefix_arg (struct kboard *kb, Lisp_Object val)
{
- kb->INTERNAL_FIELD (Vlast_prefix_arg) = val;
+ kb->Vlast_prefix_arg_ = val;
}
static void
kset_last_repeatable_command (struct kboard *kb, Lisp_Object val)
{
- kb->INTERNAL_FIELD (Vlast_repeatable_command) = val;
+ kb->Vlast_repeatable_command_ = val;
}
static void
kset_local_function_key_map (struct kboard *kb, Lisp_Object val)
{
- kb->INTERNAL_FIELD (Vlocal_function_key_map) = val;
+ kb->Vlocal_function_key_map_ = val;
}
static void
kset_overriding_terminal_local_map (struct kboard *kb, Lisp_Object val)
{
- kb->INTERNAL_FIELD (Voverriding_terminal_local_map) = val;
+ kb->Voverriding_terminal_local_map_ = val;
}
static void
kset_real_last_command (struct kboard *kb, Lisp_Object val)
{
- kb->INTERNAL_FIELD (Vreal_last_command) = val;
+ kb->Vreal_last_command_ = val;
}
static void
kset_system_key_syms (struct kboard *kb, Lisp_Object val)
{
- kb->INTERNAL_FIELD (system_key_syms) = val;
+ kb->system_key_syms_ = val;
}
\f
\f
DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "",
doc: /* Invoke the editor command loop recursively.
-To get out of the recursive edit, a command can throw to `exit' -- for
-instance `(throw 'exit nil)'.
-If you throw a value other than t, `recursive-edit' returns normally
+To get out of the recursive edit, a command can throw to ‘exit’ -- for
+instance ‘(throw 'exit nil)’.
+If you throw a value other than t, ‘recursive-edit’ returns normally
to the function that called it. Throwing a t value causes
-`recursive-edit' to quit, so that control returns to the command loop
+‘recursive-edit’ to quit, so that control returns to the command loop
one level up.
This function is called by the editor initialization to begin editing. */)
finalize:
if (current_buffer == prev_buffer
+ && XBUFFER (XWINDOW (selected_window)->contents) == current_buffer
&& last_point_position != PT
&& NILP (Vdisable_point_adjustment)
&& NILP (Vglobal_disable_point_adjustment))
bool check_composition = ! modified, check_display = 1, check_invisible = 1;
ptrdiff_t orig_pt = PT;
+ eassert (XBUFFER (XWINDOW (selected_window)->contents) == current_buffer);
+
/* FIXME: cycling is probably not necessary because these properties
can't be usefully combined anyway. */
while (check_composition || check_display || check_invisible)
if (check_display
&& PT > BEGV && PT < ZV
&& !NILP (val = get_char_property_and_overlay
- (make_number (PT), Qdisplay, Qnil, &overlay))
+ (make_number (PT), Qdisplay, selected_window,
+ &overlay))
&& display_prop_intangible_p (val, overlay, PT, PT_BYTE)
&& (!OVERLAYP (overlay)
? get_property_and_range (PT, Qdisplay, &val, &beg, &end, Qnil)
save_getcjmp (save_jump);
restore_getcjmp (local_getcjmp);
if (!end_time)
- timer_start_idle ();
+ timer_start_idle ();
c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
restore_getcjmp (save_jump);
{ /* An encoded byte sequence, let's try to decode it. */
struct coding_system *coding
= TERMINAL_KEYBOARD_CODING (terminal);
- unsigned char src[MAX_ENCODED_BYTES];
- unsigned char dest[MAX_ENCODED_BYTES * MAX_MULTIBYTE_LENGTH];
- int i;
- for (i = 0; i < n; i++)
- src[i] = XINT (events[i]);
- if (meta_key != 2)
- for (i = 0; i < n; i++)
- src[i] &= ~0x80;
- coding->destination = dest;
- coding->dst_bytes = sizeof dest;
- decode_coding_c_string (coding, src, n, Qnil);
- eassert (coding->produced_char <= n);
- if (coding->produced_char == 0)
- { /* The encoded sequence is incomplete. */
- if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */
- continue; /* Read on! */
+
+ if (raw_text_coding_system_p (coding))
+ {
+ int i;
+ if (meta_key != 2)
+ for (i = 0; i < n; i++)
+ events[i] = make_number (XINT (events[i]) & ~0x80);
}
else
{
- const unsigned char *p = coding->destination;
- eassert (coding->carryover_bytes == 0);
- n = 0;
- while (n < coding->produced_char)
- events[n++] = make_number (STRING_CHAR_ADVANCE (p));
+ unsigned char src[MAX_ENCODED_BYTES];
+ unsigned char dest[MAX_ENCODED_BYTES * MAX_MULTIBYTE_LENGTH];
+ int i;
+ for (i = 0; i < n; i++)
+ src[i] = XINT (events[i]);
+ if (meta_key != 2)
+ for (i = 0; i < n; i++)
+ src[i] &= ~0x80;
+ coding->destination = dest;
+ coding->dst_bytes = sizeof dest;
+ decode_coding_c_string (coding, src, n, Qnil);
+ eassert (coding->produced_char <= n);
+ if (coding->produced_char == 0)
+ { /* The encoded sequence is incomplete. */
+ if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */
+ continue; /* Read on! */
+ }
+ else
+ {
+ const unsigned char *p = coding->destination;
+ eassert (coding->carryover_bytes == 0);
+ n = 0;
+ while (n < coding->produced_char)
+ events[n++] = make_number (STRING_CHAR_ADVANCE (p));
+ }
}
}
/* Now `events' should hold decoded events.
Lisp_Object keys;
ptrdiff_t key_count;
bool key_count_reset;
+ ptrdiff_t command_key_start;
struct gcpro gcpro1;
ptrdiff_t count = SPECPDL_INDEX ();
/* Save the this_command_keys status. */
key_count = this_command_key_count;
key_count_reset = this_command_key_count_reset;
+ command_key_start = this_single_command_key_start;
if (key_count > 0)
keys = Fcopy_sequence (this_command_keys);
/* Clear out this_command_keys. */
this_command_key_count = 0;
this_command_key_count_reset = 0;
+ this_single_command_key_start = 0;
/* Now wipe the echo area. */
if (!NILP (echo_area_buffer[0]))
and this_command_keys state. */
this_command_key_count = key_count;
this_command_key_count_reset = key_count_reset;
+ this_single_command_key_start = command_key_start;
if (key_count > 0)
this_command_keys = keys;
cancel_echoing ();
ok_to_echo_at_next_pause = saved_ok_to_echo;
- kset_echo_string (current_kboard, saved_echo_string);
+ /* Do not restore the echo area string when the user is
+ introducing a prefix argument. Otherwise we end with
+ repetitions of the partially introduced prefix
+ argument. (bug#19875) */
+ if (NILP (intern ("prefix-arg")))
+ {
+ kset_echo_string (current_kboard, saved_echo_string);
+ }
current_kboard->echo_after_prompt = saved_echo_after_prompt;
if (saved_immediate_echo)
echo_now ();
#endif
))
{
- struct input_event *event;
+ union buffered_input_event *event;
event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
? kbd_fetch_ptr
&& !((flags & READABLE_EVENTS_IGNORE_SQUEEZABLES)
&& (event->kind == SCROLL_BAR_CLICK_EVENT
|| event->kind == HORIZONTAL_SCROLL_BAR_CLICK_EVENT)
- && event->part == scroll_bar_handle
- && event->modifiers == 0)
+ && event->ie.part == scroll_bar_handle
+ && event->ie.modifiers == 0)
#endif
&& !((flags & READABLE_EVENTS_FILTER_EVENTS)
&& event->kind == BUFFER_SWITCH_EVENT))
subsequent input events have been parsed (and discarded). */
void
-kbd_buffer_store_event_hold (register struct input_event *event,
- struct input_event *hold_quit)
+kbd_buffer_store_buffered_event (union buffered_input_event *event,
+ struct input_event *hold_quit)
{
if (event->kind == NO_EVENT)
emacs_abort ();
if (event->kind == ASCII_KEYSTROKE_EVENT)
{
- register int c = event->code & 0377;
+ int c = event->ie.code & 0377;
- if (event->modifiers & ctrl_modifier)
+ if (event->ie.modifiers & ctrl_modifier)
c = make_ctrl_char (c);
- c |= (event->modifiers
+ c |= (event->ie.modifiers
& (meta_modifier | alt_modifier
| hyper_modifier | super_modifier));
if (c == quit_char)
{
- KBOARD *kb = FRAME_KBOARD (XFRAME (event->frame_or_window));
- struct input_event *sp;
+ KBOARD *kb = FRAME_KBOARD (XFRAME (event->ie.frame_or_window));
if (single_kboard && kb != current_kboard)
{
kset_kbd_queue
- (kb, list2 (make_lispy_switch_frame (event->frame_or_window),
+ (kb, list2 (make_lispy_switch_frame (event->ie.frame_or_window),
make_number (c)));
kb->kbd_queue_has_data = 1;
+ union buffered_input_event *sp;
for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
{
if (sp == kbd_buffer + KBD_BUFFER_SIZE)
sp = kbd_buffer;
- if (event_to_kboard (sp) == kb)
+ if (event_to_kboard (&sp->ie) == kb)
{
- sp->kind = NO_EVENT;
- sp->frame_or_window = Qnil;
- sp->arg = Qnil;
+ sp->ie.kind = NO_EVENT;
+ sp->ie.frame_or_window = Qnil;
+ sp->ie.arg = Qnil;
}
}
return;
if (hold_quit)
{
- *hold_quit = *event;
+ *hold_quit = event->ie;
return;
}
{
Lisp_Object focus;
- focus = FRAME_FOCUS_FRAME (XFRAME (event->frame_or_window));
+ focus = FRAME_FOCUS_FRAME (XFRAME (event->ie.frame_or_window));
if (NILP (focus))
- focus = event->frame_or_window;
+ focus = event->ie.frame_or_window;
internal_last_event_frame = focus;
Vlast_event_frame = focus;
}
/* Don't read keyboard input until we have processed kbd_buffer.
This happens when pasting text longer than KBD_BUFFER_SIZE/2. */
hold_keyboard_input ();
- if (!noninteractive)
- ignore_sigio ();
+ unrequest_sigio ();
stop_polling ();
}
#endif /* subprocesses */
as input, set quit-flag to cause an interrupt. */
if (!NILP (Vthrow_on_input)
&& event->kind != FOCUS_IN_EVENT
+ && event->kind != FOCUS_OUT_EVENT
&& event->kind != HELP_EVENT
+ && event->kind != ICONIFY_EVENT
&& event->kind != DEICONIFY_EVENT)
{
Vquit_flag = Vthrow_on_input;
}
-/* Put an input event back in the head of the event queue. */
+#ifdef HAVE_X11
+
+/* Put a selection input event back in the head of the event queue. */
void
-kbd_buffer_unget_event (register struct input_event *event)
+kbd_buffer_unget_event (struct selection_input_event *event)
{
if (kbd_fetch_ptr == kbd_buffer)
kbd_fetch_ptr = kbd_buffer + KBD_BUFFER_SIZE;
/* Don't let the very last slot in the buffer become full, */
- if (kbd_fetch_ptr - 1 != kbd_store_ptr)
+ union buffered_input_event *kp = kbd_fetch_ptr - 1;
+ if (kp != kbd_store_ptr)
{
- --kbd_fetch_ptr;
- *kbd_fetch_ptr = *event;
+ kp->sie = *event;
+ kbd_fetch_ptr = kp;
}
}
+#endif
+
/* Limit help event positions to this range, to avoid overflow problems. */
#define INPUT_EVENT_POS_MAX \
((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \
void
discard_mouse_events (void)
{
- struct input_event *sp;
+ union buffered_input_event *sp;
for (sp = kbd_fetch_ptr; sp != kbd_store_ptr; sp++)
{
if (sp == kbd_buffer + KBD_BUFFER_SIZE)
bool
kbd_buffer_events_waiting (void)
{
- struct input_event *sp;
+ union buffered_input_event *sp;
for (sp = kbd_fetch_ptr;
sp != kbd_store_ptr && sp->kind == NO_EVENT;
/* Clear input event EVENT. */
static void
-clear_event (struct input_event *event)
+clear_event (union buffered_input_event *event)
{
event->kind = NO_EVENT;
}
/* Start reading input again because we have processed enough to
be able to accept new events again. */
unhold_keyboard_input ();
+ request_sigio ();
start_polling ();
}
#endif /* subprocesses */
if (noninteractive
/* In case we are running as a daemon, only do this before
detaching from the terminal. */
- || (IS_DAEMON && daemon_pipe[1] >= 0))
+ || (IS_DAEMON && DAEMON_RUNNING))
{
int c = getchar ();
XSETINT (obj, c);
mouse movement enabled and available. */
if (kbd_fetch_ptr != kbd_store_ptr)
{
- struct input_event *event;
+ union buffered_input_event *event;
event = ((kbd_fetch_ptr < kbd_buffer + KBD_BUFFER_SIZE)
? kbd_fetch_ptr
: kbd_buffer);
- *kbp = event_to_kboard (event);
+ *kbp = event_to_kboard (&event->ie);
if (*kbp == 0)
*kbp = current_kboard; /* Better than returning null ptr? */
|| event->kind == SELECTION_CLEAR_EVENT)
{
#ifdef HAVE_X11
- struct input_event copy;
-
/* Remove it from the buffer before processing it,
since otherwise swallow_events will see it
and process it again. */
- copy = *event;
+ struct selection_input_event copy = event->sie;
kbd_fetch_ptr = event + 1;
input_pending = readable_events (0);
x_handle_selection_event (©);
#if defined (HAVE_NS)
else if (event->kind == NS_TEXT_EVENT)
{
- if (event->code == KEY_NS_PUT_WORKING_TEXT)
+ if (event->ie.code == KEY_NS_PUT_WORKING_TEXT)
obj = list1 (intern ("ns-put-working-text"));
else
obj = list1 (intern ("ns-unput-working-text"));
else if (event->kind == DELETE_WINDOW_EVENT)
{
/* Make an event (delete-frame (FRAME)). */
- obj = list2 (Qdelete_frame, list1 (event->frame_or_window));
+ obj = list2 (Qdelete_frame, list1 (event->ie.frame_or_window));
kbd_fetch_ptr = event + 1;
}
#endif
else if (event->kind == ICONIFY_EVENT)
{
/* Make an event (iconify-frame (FRAME)). */
- obj = list2 (Qiconify_frame, list1 (event->frame_or_window));
+ obj = list2 (Qiconify_frame, list1 (event->ie.frame_or_window));
kbd_fetch_ptr = event + 1;
}
else if (event->kind == DEICONIFY_EVENT)
{
/* Make an event (make-frame-visible (FRAME)). */
- obj = list2 (Qmake_frame_visible, list1 (event->frame_or_window));
+ obj = list2 (Qmake_frame_visible, list1 (event->ie.frame_or_window));
kbd_fetch_ptr = event + 1;
}
#endif
{
kbd_fetch_ptr = event + 1;
input_pending = readable_events (0);
- if (FRAME_LIVE_P (XFRAME (event->frame_or_window)))
- x_activate_menubar (XFRAME (event->frame_or_window));
+ if (FRAME_LIVE_P (XFRAME (event->ie.frame_or_window)))
+ x_activate_menubar (XFRAME (event->ie.frame_or_window));
}
#endif
#ifdef HAVE_NTGUI
{
/* Make an event (language-change FRAME CODEPAGE LANGUAGE-ID). */
obj = list4 (Qlanguage_change,
- event->frame_or_window,
- make_number (event->code),
- make_number (event->modifiers));
+ event->ie.frame_or_window,
+ make_number (event->ie.code),
+ make_number (event->ie.modifiers));
kbd_fetch_ptr = event + 1;
}
#endif
{
#ifdef HAVE_W32NOTIFY
/* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */
- obj = list3 (Qfile_notify, event->arg, event->frame_or_window);
+ obj = list3 (Qfile_notify, event->ie.arg, event->ie.frame_or_window);
#else
- obj = make_lispy_event (event);
+ obj = make_lispy_event (&event->ie);
#endif
kbd_fetch_ptr = event + 1;
}
#endif /* USE_FILE_NOTIFY */
else if (event->kind == SAVE_SESSION_EVENT)
{
- obj = list2 (Qsave_session, event->arg);
+ obj = list2 (Qsave_session, event->ie.arg);
kbd_fetch_ptr = event + 1;
}
/* Just discard these, by returning nil.
{
Lisp_Object object, position, help, frame, window;
- frame = event->frame_or_window;
- object = event->arg;
- position = make_number (Time_to_position (event->timestamp));
- window = event->x;
- help = event->y;
+ frame = event->ie.frame_or_window;
+ object = event->ie.arg;
+ position = make_number (Time_to_position (event->ie.timestamp));
+ window = event->ie.x;
+ help = event->ie.y;
clear_event (event);
kbd_fetch_ptr = event + 1;
switch-frame event if necessary. */
Lisp_Object frame, focus;
- frame = event->frame_or_window;
+ frame = event->ie.frame_or_window;
focus = FRAME_FOCUS_FRAME (XFRAME (frame));
if (FRAMEP (focus))
frame = focus;
if (
#ifdef HAVE_X11
- ! NILP (event->arg)
+ ! NILP (event->ie.arg)
&&
#endif
!EQ (frame, internal_last_event_frame)
#ifdef HAVE_WINDOW_SYSTEM
Display_Info *di;
- Lisp_Object frame = event->frame_or_window;
+ Lisp_Object frame = event->ie.frame_or_window;
bool focused = false;
for (di = x_display_list; di && ! focused; di = di->next)
#ifdef HAVE_DBUS
else if (event->kind == DBUS_EVENT)
{
- obj = make_lispy_event (event);
+ obj = make_lispy_event (&event->ie);
kbd_fetch_ptr = event + 1;
}
#endif
else if (event->kind == CONFIG_CHANGED_EVENT)
{
- obj = make_lispy_event (event);
+ obj = make_lispy_event (&event->ie);
kbd_fetch_ptr = event + 1;
}
else
Lisp_Object frame;
Lisp_Object focus;
- frame = event->frame_or_window;
+ frame = event->ie.frame_or_window;
if (CONSP (frame))
frame = XCAR (frame);
else if (WINDOWP (frame))
if (NILP (obj))
{
- obj = make_lispy_event (event);
+ obj = make_lispy_event (&event->ie);
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|| defined (HAVE_NS) || defined (USE_GTK)
beginning of the menu sequence, and we might as well leave
that as the `event with parameters' for this selection. */
if (used_mouse_menu
- && !EQ (event->frame_or_window, event->arg)
+ && !EQ (event->ie.frame_or_window, event->ie.arg)
&& (event->kind == MENU_BAR_EVENT
|| event->kind == TOOL_BAR_EVENT))
*used_mouse_menu = 1;
static void
process_special_events (void)
{
- struct input_event *event;
+ union buffered_input_event *event;
for (event = kbd_fetch_ptr; event != kbd_store_ptr; ++event)
{
between kbd_fetch_ptr and EVENT one slot to the right,
cyclically. */
- struct input_event copy = *event;
- struct input_event *beg
+ struct selection_input_event copy = event->sie;
+ union buffered_input_event *beg
= (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
? kbd_buffer : kbd_fetch_ptr;
if (event > beg)
- memmove (beg + 1, beg, (event - beg) * sizeof (struct input_event));
+ memmove (beg + 1, beg, (event - beg) * sizeof *beg);
else if (event < beg)
{
if (event > kbd_buffer)
memmove (kbd_buffer + 1, kbd_buffer,
- (event - kbd_buffer) * sizeof (struct input_event));
+ (event - kbd_buffer) * sizeof *kbd_buffer);
*kbd_buffer = *(kbd_buffer + KBD_BUFFER_SIZE - 1);
if (beg < kbd_buffer + KBD_BUFFER_SIZE - 1)
memmove (beg + 1, beg,
- (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg)
- * sizeof (struct input_event));
+ (kbd_buffer + KBD_BUFFER_SIZE - 1 - beg) * sizeof *beg);
}
if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
timer_idleness_start_time = timer_last_idleness_start_time;
}
-/* This is only for debugging. */
-struct input_event last_timer_event EXTERNALLY_VISIBLE;
-
/* List of elisp functions to call, delayed because they were generated in
a context where Elisp could not be safely run (e.g. redisplay, signal,
...). Each element has the form (FUN . ARGS). */
static bool
decode_timer (Lisp_Object timer, struct timespec *result)
{
- Lisp_Object *vector;
+ Lisp_Object *vec;
if (! (VECTORP (timer) && ASIZE (timer) == 9))
return 0;
- vector = XVECTOR (timer)->contents;
- if (! NILP (vector[0]))
+ vec = XVECTOR (timer)->contents;
+ if (! NILP (vec[0]))
return 0;
- if (! INTEGERP (vector[2]))
+ if (! INTEGERP (vec[2]))
return false;
struct lisp_time t;
- if (! decode_time_components (vector[1], vector[2], vector[3], vector[8],
- &t, 0))
+ if (decode_time_components (vec[1], vec[2], vec[3], vec[8], &t, 0) <= 0)
return false;
*result = lisp_to_timespec (t);
return timespec_valid_p (*result);
/* Set TIMER and TIMER_DIFFERENCE
based on the next ordinary timer.
TIMER_DIFFERENCE is the distance in time from NOW to when
- this timer becomes ripe (negative if it's already ripe).
+ this timer becomes ripe.
Skip past invalid timers and timers already handled. */
if (CONSP (timers))
{
dy = yret = wy;
}
- /* For clicks in the text area, fringes, or margins, call
- buffer_posn_from_coords to extract TEXTPOS, the buffer
- position nearest to the click. */
+ /* For clicks in the text area, fringes, margins, or vertical
+ scroll bar, call buffer_posn_from_coords to extract TEXTPOS,
+ the buffer position nearest to the click. */
if (!textpos)
{
Lisp_Object string2, object2 = Qnil;
int dx2, dy2;
int width2, height2;
/* The pixel X coordinate passed to buffer_posn_from_coords
- is the X coordinate relative to the text area for
- text-area and right-margin clicks, zero otherwise. */
+ is the X coordinate relative to the text area for clicks
+ in text-area, right-margin/fringe and right-side vertical
+ scroll bar, zero otherwise. */
int x2
= (part == ON_TEXT) ? xret
- : (part == ON_RIGHT_FRINGE || part == ON_RIGHT_MARGIN)
+ : (part == ON_RIGHT_FRINGE || part == ON_RIGHT_MARGIN
+ || (part == ON_VERTICAL_SCROLL_BAR
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
? (XINT (x) - window_box_left (w, TEXT_AREA))
: 0;
int y2 = wy;
while (BUFFERP (obj));
kset_defining_kbd_macro (current_kboard, orig_defn_macro);
- if (!INTEGERP (obj) || XINT (obj) == -2)
- return obj;
-
- if (! EQ (obj, menu_prompt_more_char)
- && (!INTEGERP (menu_prompt_more_char)
- || ! EQ (obj, make_number (Ctl (XINT (menu_prompt_more_char))))))
+ if (!INTEGERP (obj) || XINT (obj) == -2
+ || (! EQ (obj, menu_prompt_more_char)
+ && (!INTEGERP (menu_prompt_more_char)
+ || ! EQ (obj, make_number (Ctl (XINT (menu_prompt_more_char)))))))
{
if (!NILP (KVAR (current_kboard, defining_kbd_macro)))
store_kbd_macro_char (obj);
/* Record what part of this_command_keys is the current key sequence. */
this_single_command_key_start = this_command_key_count - t;
+ /* When 'input-method-function' called above causes events to be
+ put on 'unread-post-input-method-events', and as result
+ 'reread' is set to 'true', the value of 't' can become larger
+ than 'this_command_key_count', because 'add_command_key' is
+ not called to update 'this_command_key_count'. If this
+ happens, 'this_single_command_key_start' will become negative
+ above, and any call to 'this-single-command-keys' will return
+ a garbled vector. See bug #20223 for one such situation.
+ Here we force 'this_single_command_key_start' to never become
+ negative, to avoid that. */
+ if (this_single_command_key_start < 0)
+ this_single_command_key_start = 0;
/* Look for this sequence in input-decode-map.
Scan from indec.end until we find a bound suffix. */
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);
+ stuff_char (kbd_fetch_ptr->ie.code);
clear_event (kbd_fetch_ptr);
}
The `posn-' functions access elements of such lists. */)
(Lisp_Object x, Lisp_Object y, Lisp_Object frame_or_window, Lisp_Object whole)
{
- CHECK_NATNUM (x);
+ CHECK_NUMBER (x);
+ /* We allow X of -1, for the newline in a R2L line that overflowed
+ into the left fringe. */
+ if (XINT (x) != -1)
+ CHECK_NATNUM (x);
CHECK_NATNUM (y);
if (NILP (frame_or_window))
Lisp_Object x = XCAR (tem);
Lisp_Object y = XCAR (XCDR (tem));
- /* Point invisible due to hscrolling? */
- if (XINT (x) < 0)
+ /* Point invisible due to hscrolling? X can be -1 when a
+ newline in a R2L line overflows into the left fringe. */
+ if (XINT (x) < -1)
return Qnil;
tem = Fposn_at_x_y (x, y, window, Qnil);
}
tool_bar_items_vector = Qnil;
DEFSYM (Qtimer_event_handler, "timer-event-handler");
- DEFSYM (Qdisabled_command_function, "disabled-command-function");
- DEFSYM (Qself_insert_command, "self-insert-command");
- DEFSYM (Qforward_char, "forward-char");
- DEFSYM (Qbackward_char, "backward-char");
/* Non-nil disable property on a command means do not execute it;
call disabled-command-function's value instead. */
DEFSYM (Qhandle_switch_frame, "handle-switch-frame");
DEFSYM (Qhandle_select_window, "handle-select-window");
- DEFSYM (Qinput_method_function, "input-method-function");
DEFSYM (Qinput_method_exit_on_first_char, "input-method-exit-on-first-char");
DEFSYM (Qinput_method_use_echo_area, "input-method-use-echo-area");
doc: /* Form to evaluate when Emacs starts up.
Useful to set before you dump a modified Emacs. */);
Vtop_level = Qnil;
+ XSYMBOL (Qtop_level)->declared_special = false;
DEFVAR_KBOARD ("keyboard-translate-table", Vkeyboard_translate_table,
doc: /* Translate table for local keyboard input, or nil.
DEFVAR_LISP ("special-event-map", Vspecial_event_map,
doc: /* Keymap defining bindings for special events to execute at low level. */);
- Vspecial_event_map = list1 (intern_c_string ("keymap"));
+ Vspecial_event_map = list1 (Qkeymap);
DEFVAR_LISP ("track-mouse", do_mouse_tracking,
doc: /* Non-nil means generate motion events for mouse motion. */);
The input method function should refer to the variables
`input-method-use-echo-area' and `input-method-exit-on-first-char'
for guidance on what to do. */);
- Vinput_method_function = Qnil;
+ Vinput_method_function = Qlist;
DEFVAR_LISP ("input-method-previous-message",
Vinput_method_previous_message,
mark_object (KVAR (kb, echo_string));
}
{
- struct input_event *event;
+ union buffered_input_event *event;
for (event = kbd_fetch_ptr; event != kbd_store_ptr; event++)
{
if (event == kbd_buffer + KBD_BUFFER_SIZE)
if (event->kind != SELECTION_REQUEST_EVENT
&& event->kind != SELECTION_CLEAR_EVENT)
{
- mark_object (event->x);
- mark_object (event->y);
- mark_object (event->frame_or_window);
- mark_object (event->arg);
+ mark_object (event->ie.x);
+ mark_object (event->ie.y);
+ mark_object (event->ie.frame_or_window);
+ mark_object (event->ie.arg);
}
}
}