#include "process.h"
#include <errno.h>
-#ifdef HAVE_GTK_AND_PTHREAD
+#ifdef HAVE_PTHREAD
#include <pthread.h>
#endif
#ifdef MSDOS
#include "nsterm.h"
#endif
-/* Variables for blockinput.h: */
+/* Variables for blockinput.h: */
/* Non-zero if interrupt input is blocked right now. */
volatile int interrupt_input_blocked;
int quit_char;
/* Current depth in recursive edits. */
-int command_loop_level;
+EMACS_INT command_loop_level;
/* If not Qnil, this is a switch-frame event which we decided to put
off until the end of a key sequence. This should be read as the
/* Last size recorded for a current buffer which is not a minibuffer. */
static EMACS_INT last_non_minibuf_size;
-/* Total number of times read_char has returned, modulo SIZE_MAX + 1. */
-size_t num_input_events;
+/* Total number of times read_char has returned, modulo UINTMAX_MAX + 1. */
+uintmax_t num_input_events;
/* Value of num_nonmacro_input_events as of last auto save. */
/* read_key_sequence stores here the command definition of the
key sequence that it reads. */
static Lisp_Object read_key_sequence_cmd;
+static Lisp_Object read_key_sequence_remapped;
static Lisp_Object Qinput_method_function;
Lisp_Object Qevent_kind;
static Lisp_Object Qevent_symbol_elements;
-/* menu and tool bar item parts */
+/* Menu and tool bar item parts. */
static Lisp_Object Qmenu_enable;
static Lisp_Object QCenable, QCvisible, QChelp, QCkeys, QCkey_sequence;
Lisp_Object QCfilter;
/* If we support a window system, turn on the code to poll periodically
to detect C-g. It isn't actually used when doing interrupt input. */
-#if defined(HAVE_WINDOW_SYSTEM) && !defined(USE_ASYNC_EVENTS)
+#if defined (HAVE_WINDOW_SYSTEM) && !defined (USE_ASYNC_EVENTS)
#define POLL_FOR_INPUT
#endif
static int read_avail_input (int);
static void get_input_pending (int *, int);
static int readable_events (int);
-static Lisp_Object read_char_x_menu_prompt (int, Lisp_Object *,
+static Lisp_Object read_char_x_menu_prompt (ptrdiff_t, Lisp_Object *,
Lisp_Object, int *);
-static Lisp_Object read_char_minibuf_menu_prompt (int, int,
+static Lisp_Object read_char_minibuf_menu_prompt (int, ptrdiff_t,
Lisp_Object *);
static Lisp_Object make_lispy_event (struct input_event *);
#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
static Lisp_Object make_lispy_movement (struct frame *, Lisp_Object,
enum scroll_bar_part,
Lisp_Object, Lisp_Object,
- unsigned long);
+ Time);
#endif
static Lisp_Object modify_event_symbol (EMACS_INT, unsigned, Lisp_Object,
Lisp_Object, const char *const *,
\f
#if 0 /* These two functions are now replaced with
- temporarily_switch_to_single_kboard. */
+ temporarily_switch_to_single_kboard. */
static void
any_kboard_state ()
{
state later.
If Emacs is already in single_kboard mode, and F's keyboard is
- locked, then this function will throw an errow. */
+ locked, then this function will throw an error. */
void
temporarily_switch_to_single_kboard (struct frame *f)
cmd_error (Lisp_Object data)
{
Lisp_Object old_level, old_length;
- char macroerror[50];
+ char macroerror[sizeof "After..kbd macro iterations: "
+ + INT_STRLEN_BOUND (EMACS_INT)];
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
if (executing_kbd_macro_iterations == 1)
sprintf (macroerror, "After 1 kbd macro iteration: ");
else
- sprintf (macroerror, "After %d kbd macro iterations: ",
+ sprintf (macroerror, "After %"pI"d kbd macro iterations: ",
executing_kbd_macro_iterations);
}
else
Vquit_flag = Qnil;
Vinhibit_quit = Qnil;
-#if 0 /* This shouldn't be necessary anymore. --lorentey */
+#if 0 /* This shouldn't be necessary anymore. --lorentey */
if (command_loop_level == 0 && minibuf_level == 0)
any_kboard_state ();
#endif
struct frame *sf = SELECTED_FRAME ();
/* The immediate context is not interesting for Quits,
- since they are asyncronous. */
+ since they are asynchronous. */
if (EQ (XCAR (data), Qquit))
Vsignaling_function = Qnil;
#if 0 /* This shouldn't be necessary anymore. --lorentey */
/* Reset single_kboard in case top-level set it while
evaluating an -f option, or we are stuck there for some
- other reason. */
+ other reason. */
any_kboard_state ();
#endif
internal_catch (Qtop_level, command_loop_2, Qnil);
/* This is the actual command reading loop,
sans error-handling encapsulation. */
-static int read_key_sequence (Lisp_Object *, size_t, Lisp_Object,
+static int read_key_sequence (Lisp_Object *, int, Lisp_Object,
int, int, int);
void safe_run_hooks (Lisp_Object);
static void adjust_point_for_property (EMACS_INT, int);
if (!NILP (Vquit_flag))
{
Vexecuting_kbd_macro = Qt;
- QUIT; /* Make some noise. */
- /* Will return since macro now empty. */
+ QUIT; /* Make some noise. */
+ /* Will return since macro now empty. */
}
}
Vdisable_point_adjustment = Qnil;
/* Process filters and timers may have messed with deactivate-mark.
- reset it before we execute the command. */
+ reset it before we execute the command. */
Vdeactivate_mark = Qnil;
- /* Remap command through active keymaps */
+ /* Remap command through active keymaps. */
Vthis_original_command = cmd;
- if (SYMBOLP (cmd))
- {
- Lisp_Object cmd1;
- if (cmd1 = Fcommand_remapping (cmd, Qnil, Qnil), !NILP (cmd1))
- cmd = cmd1;
- }
+ if (!NILP (read_key_sequence_remapped))
+ cmd = read_key_sequence_remapped;
/* Execute the command. */
message_with_string ("%s is undefined", keys, 0);
KVAR (current_kboard, defining_kbd_macro) = Qnil;
update_mode_lines = 1;
- KVAR (current_kboard, Vprefix_arg) = Qnil;
+ /* If this is a down-mouse event, don't reset prefix-arg;
+ pass it to the command run by the up event. */
+ if (EVENT_HAS_PARAMETERS (last_command_event))
+ {
+ Lisp_Object breakdown
+ = parse_modifiers (EVENT_HEAD (last_command_event));
+ int modifiers = XINT (XCAR (XCDR (breakdown)));
+ if (!(modifiers & down_modifier))
+ KVAR (current_kboard, Vprefix_arg) = Qnil;
+ }
+ else
+ KVAR (current_kboard, Vprefix_arg) = Qnil;
}
else
{
- /* Here for a command that isn't executed directly */
+ /* Here for a command that isn't executed directly. */
#ifdef HAVE_WINDOW_SYSTEM
int scount = SPECPDL_INDEX ();
poll_for_input_1 (void)
{
/* Tell ns_read_socket() it is being called asynchronously so it can avoid
- doing anything dangerous. */
+ doing anything dangerous. */
#ifdef HAVE_NS
++handling_signal;
#endif
#ifdef POLL_FOR_INPUT
/* XXX This condition was (read_socket_hook && !interrupt_input),
but read_socket_hook is not global anymore. Let's pretend that
- it's always set. */
+ it's always set. */
if (!interrupt_input)
{
/* Turn alarm handling on unconditionally. It might have
#ifdef POLL_FOR_INPUT
/* XXX This condition was (read_socket_hook && !interrupt_input),
but read_socket_hook is not global anymore. Let's pretend that
- it's always set. */
+ it's always set. */
return !interrupt_input;
#else
return 0;
#ifdef POLL_FOR_INPUT
/* XXX This condition was (read_socket_hook && !interrupt_input),
but read_socket_hook is not global anymore. Let's pretend that
- it's always set. */
+ it's always set. */
if (!interrupt_input)
++poll_suppress_count;
#endif
Value is t if we showed a menu and the user rejected it. */
Lisp_Object
-read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
+read_char (int commandflag, ptrdiff_t nmaps, Lisp_Object *maps,
+ Lisp_Object prev_event,
int *used_mouse_menu, struct timeval *end_time)
{
volatile Lisp_Object c;
real event came from. Normally, a switch-frame event selects
internal_last_event_frame after each command is read, but
events read from a macro should never cause a new frame to be
- selected. */
+ selected. */
Vlast_event_frame = internal_last_event_frame = Qmacro;
/* Exit the macro if we are at the end.
Try this before the sit-for, because the sit-for
would do the wrong thing if we are supposed to do
menu prompting. If EVENT_HAS_PARAMETERS then we are reading
- after a mouse event so don't try a minibuf menu. */
+ after a mouse event so don't try a minibuf menu. */
c = Qnil;
if (nmaps > 0 && INTERACTIVE
&& !NILP (prev_event) && ! EVENT_HAS_PARAMETERS (prev_event)
kbd_fetch_ptr = event + 1;
}
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
- || defined(HAVE_NS) || defined (USE_GTK)
+ || defined (HAVE_NS) || defined (USE_GTK)
else if (event->kind == MENU_BAR_ACTIVATE_EVENT)
{
kbd_fetch_ptr = event + 1;
obj = make_lispy_event (event);
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
- || defined(HAVE_NS) || defined (USE_GTK)
+ || defined (HAVE_NS) || defined (USE_GTK)
/* If this was a menu selection, then set the flag to inhibit
writing to last_nonmenu_event. Don't do this if the event
we're returning is (menu-bar), though; that indicates the
"break", /* 0xff6b */
0, 0, 0, 0,
- 0, 0, 0, 0, "backtab", 0, 0, 0, /* 0xff70... */
- 0, 0, 0, 0, 0, 0, 0, "kp-numlock", /* 0xff78... */
+ 0, 0, 0, 0, "backtab", 0, 0, 0, /* 0xff70... */
+ 0, 0, 0, 0, 0, 0, 0, "kp-numlock", /* 0xff78... */
"kp-space", /* 0xff80 */ /* IsKeypadKey */
0, 0, 0, 0, 0, 0, 0, 0,
"kp-tab", /* 0xff89 */
static Lisp_Object button_down_location;
/* Information about the most recent up-going button event: Which
- button, what location, and what time. */
+ button, what location, and what time. */
static int last_mouse_button;
static int last_mouse_x;
static int last_mouse_y;
static Time button_down_time;
-/* The number of clicks in this multiple-click. */
+/* The number of clicks in this multiple-click. */
static int double_click_count;
#ifdef HAVE_NS
/* NS_NONKEY_EVENTs are just like NON_ASCII_KEYSTROKE_EVENTs,
- except that they are non-key events (last-nonmenu-event is nil). */
+ except that they are non-key events (last-nonmenu-event is nil). */
case NS_NONKEY_EVENT:
#endif
|| !lispy_function_keys[event->code - FUNCTION_KEY_OFFSET])
{
/* We need to use an alist rather than a vector as the cache
- since we can't make a vector long enuf. */
+ since we can't make a vector long enough. */
if (NILP (KVAR (current_kboard, system_key_syms)))
KVAR (current_kboard, system_key_syms) = Fcons (Qnil, Qnil);
return modify_event_symbol (event->code,
Fcons (make_number (event->timestamp),
Fcons (part, Qnil)))));
- /* Always treat scroll bar events as clicks. */
+ /* Always treat scroll bar events as clicks. */
event->modifiers |= click_modifier;
event->modifiers &= ~up_modifier;
#endif /* HAVE_MOUSE */
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
- || defined(HAVE_NS) || defined (USE_GTK)
+ || defined (HAVE_NS) || defined (USE_GTK)
case MENU_BAR_EVENT:
if (EQ (event->arg, event->frame_or_window))
/* This is the prefix key. We translate this to
}
}
-#if defined(HAVE_MOUSE) || defined(HAVE_GPM)
+#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
static Lisp_Object
make_lispy_movement (FRAME_PTR frame, Lisp_Object bar_window, enum scroll_bar_part part,
value = Fcdr_safe (Fassq (symbol_int, name_alist_or_stem));
else if (STRINGP (name_alist_or_stem))
{
- int len = SBYTES (name_alist_or_stem);
- char *buf = (char *) alloca (len + 50);
- sprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
- XINT (symbol_int) + 1);
+ char *buf;
+ ptrdiff_t len = (SBYTES (name_alist_or_stem)
+ + sizeof "-" + INT_STRLEN_BOUND (EMACS_INT));
+ USE_SAFE_ALLOCA;
+ SAFE_ALLOCA (buf, char *, len);
+ esprintf (buf, "%s-%"pI"d", SDATA (name_alist_or_stem),
+ XINT (symbol_int) + 1);
value = intern (buf);
+ SAFE_FREE ();
}
else if (name_table != 0 && name_table[symbol_num])
value = intern (name_table[symbol_num]);
if (NILP (value))
{
- char buf[20];
+ char buf[sizeof "key-" + INT_STRLEN_BOUND (EMACS_INT)];
sprintf (buf, "key-%"pI"d", symbol_num);
value = intern (buf);
}
If READABLE_EVENTS_FILTER_EVENTS is set in FLAGS, ignore internal
events (FOCUS_IN_EVENT).
If READABLE_EVENTS_IGNORE_SQUEEZABLES is set in FLAGS, ignore mouse
- movements and toolkit scroll bar thumb drags. */
+ movements and toolkit scroll bar thumb drags. */
static void
get_input_pending (int *addr, int flags)
#ifdef POLL_FOR_INPUT
/* XXX This condition was (read_socket_hook && !interrupt_input),
but read_socket_hook is not global anymore. Let's pretend that
- it's always set. */
+ it's always set. */
if (!interrupt_input && poll_suppress_count == 0)
{
SIGMASKTYPE mask;
if (store_user_signal_events ())
expected = 0;
- /* Loop through the available terminals, and call their input hooks. */
+ /* Loop through the available terminals, and call their input hooks. */
t = terminal_list;
while (t)
{
expected = 0;
}
- if (nr == -1) /* Not OK to read input now. */
+ if (nr == -1) /* Not OK to read input now. */
{
err = 1;
}
- else if (nr == -2) /* Non-transient error. */
+ else if (nr == -2) /* Non-transient error. */
{
- /* The terminal device terminated; it should be closed. */
+ /* The terminal device terminated; it should be closed. */
- /* Kill Emacs if this was our last terminal. */
+ /* Kill Emacs if this was our last terminal. */
if (!terminal_list->next_terminal)
/* Formerly simply reported no input, but that
sometimes led to a failure of Emacs to terminate.
alone in its group. */
kill (getpid (), SIGHUP);
- /* XXX Is calling delete_terminal safe here? It calls delete_frame. */
+ /* XXX Is calling delete_terminal safe here? It calls delete_frame. */
{
Lisp_Object tmp;
XSETTERMINAL (tmp, t);
return 0;
#endif /* subprocesses */
- if (!terminal->name) /* Don't read from a dead terminal. */
+ if (!terminal->name) /* Don't read from a dead terminal. */
return 0;
if (terminal->type != output_termcap
abort ();
/* XXX I think the following code should be moved to separate hook
- functions in system-dependent files. */
+ functions in system-dependent files. */
#ifdef WINDOWSNT
return 0;
#else /* not WINDOWSNT */
- if (! tty->term_initted) /* In case we get called during bootstrap. */
+ if (! tty->term_initted) /* In case we get called during bootstrap. */
return 0;
if (! tty->input)
- return 0; /* The terminal is suspended. */
+ return 0; /* The terminal is suspended. */
#ifdef MSDOS
n_to_read = dos_keysns ();
Gpm_GetEvent closes gpm_fd and clears it to -1, which is why
we save it in `fd' so close_gpm can remove it from the
select masks.
- gpm==-1 if a protocol error or EWOULDBLOCK; the latter is normal. */
+ gpm==-1 if a protocol error or EWOULDBLOCK; the latter is normal. */
while (gpm = Gpm_GetEvent (&event), gpm == 1) {
nread += handle_one_term_event (tty, &event, &gpm_hold_quit);
}
if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
{
if (! noninteractive)
- return -2; /* Close this terminal. */
+ return -2; /* Close this terminal. */
else
n_to_read = 0;
}
if (n_to_read > sizeof cbuf)
n_to_read = sizeof cbuf;
#else /* no FIONREAD */
-#if defined (USG) || defined(CYGWIN)
+#if defined (USG) || defined (CYGWIN)
/* Read some input if available, but don't wait. */
n_to_read = sizeof cbuf;
fcntl (fileno (tty->input), F_SETFL, O_NDELAY);
process group won't get SIGHUP's at logout time. BSDI adheres to
this part standard and returns -1 from read (0) with errno==EIO
when the control tty is taken away.
- Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
+ Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
if (nread == -1 && errno == EIO)
- return -2; /* Close this terminal. */
+ return -2; /* Close this terminal. */
#if defined (AIX) && defined (_BSD)
/* The kernel sometimes fails to deliver SIGHUP for ptys.
This looks incorrect, but it isn't, because _BSD causes
O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
and that causes a value other than 0 when there is no input. */
if (nread == 0)
- return -2; /* Close this terminal. */
+ return -2; /* Close this terminal. */
#endif
}
while (
buf.code = cbuf[i];
/* Set the frame corresponding to the active tty. Note that the
value of selected_frame is not reliable here, redisplay tends
- to temporarily change it. */
+ to temporarily change it. */
buf.frame_or_window = tty->top_frame;
buf.arg = Qnil;
pending_signals = pending_atimers;
#endif
/* Tell ns_read_socket() it is being called asynchronously so it can avoid
- doing anything dangerous. */
+ doing anything dangerous. */
#ifdef HAVE_NS
++handling_signal;
#endif
This function exists so that the UNBLOCK_INPUT macro in
blockinput.h can have some way to take care of input we put off
dealing with, without assuming that every file which uses
- UNBLOCK_INPUT also has #included the files necessary to get SIGIO. */
+ UNBLOCK_INPUT also has #included the files necessary to get SIGIO. */
void
reinvoke_input_signal (void)
{
struct user_signal_info *next;
};
-/* List of user signals. */
+/* List of user signals. */
static struct user_signal_info *user_signals = NULL;
void
{
/* The number of keymaps we're scanning right now, and the number of
keymaps we have allocated space for. */
- int nmaps;
+ ptrdiff_t nmaps;
/* maps[0..nmaps-1] are the prefix definitions of KEYBUF[0..t-1]
in the current keymaps, or nil where it is not a prefix. */
Lisp_Object def, tail;
- int mapno;
+ ptrdiff_t mapno;
Lisp_Object oquit;
/* In order to build the menus, we need to call the keymap
recognized when the menu-bar (or mode-line) is updated,
which does not normally happen after every command. */
Lisp_Object tem;
- int nminor;
+ ptrdiff_t nminor;
nminor = current_minor_maps (NULL, &tmaps);
maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
nmaps = 0;
if (CONSP (def))
{
menu_bar_one_keymap_changed_items = Qnil;
- map_keymap (def, menu_bar_item, Qnil, NULL, 1);
+ map_keymap_canonical (def, menu_bar_item, Qnil, NULL);
}
}
{
tem = XCAR (item);
if (SYMBOLP (tem) || STRINGP (tem) || VECTORP (tem))
- /* Be GC protected. Set keyhint to item instead of tem. */
+ /* Be GC protected. Set keyhint to item instead of tem. */
keyhint = item;
}
else if (EQ (tem, QCkeys))
/* If we got no definition, this item is just unselectable text which
is OK in a submenu but not in the menubar. */
if (NILP (def))
- return (inmenubar ? 0 : 1);
+ return (!inmenubar);
/* See if this is a separate pane or a submenu. */
def = AREF (item_properties, ITEM_PROPERTY_DEF);
if (inmenubar > 0)
return 1;
- { /* This is a command. See if there is an equivalent key binding. */
+ { /* This is a command. See if there is an equivalent key binding. */
Lisp_Object keyeq = AREF (item_properties, ITEM_PROPERTY_KEYEQ);
/* The previous code preferred :key-sequence to :keys, so we
tool_bar_items (Lisp_Object reuse, int *nitems)
{
Lisp_Object *maps;
- int nmaps, i;
+ ptrdiff_t nmaps, i;
Lisp_Object oquit;
Lisp_Object *tmaps;
recognized when the tool-bar (or mode-line) is updated,
which does not normally happen after every command. */
Lisp_Object tem;
- int nminor;
+ ptrdiff_t nminor;
nminor = current_minor_maps (NULL, &tmaps);
maps = (Lisp_Object *) alloca ((nminor + 3) * sizeof (maps[0]));
nmaps = 0;
Lisp_Object caption;
int i, have_label = 0;
- /* Defininition looks like `(menu-item CAPTION BINDING PROPS...)'.
+ /* Definition looks like `(menu-item CAPTION BINDING PROPS...)'.
Rule out items that aren't lists, don't start with
`menu-item' or whose rest following `tool-bar-item' is not a
list. */
Lisp_Object tcapt = PROP (TOOL_BAR_ITEM_CAPTION);
const char *label = SYMBOLP (tkey) ? SSDATA (SYMBOL_NAME (tkey)) : "";
const char *capt = STRINGP (tcapt) ? SSDATA (tcapt) : "";
- EMACS_INT max_lbl = 2 * tool_bar_max_label_size;
+ ptrdiff_t max_lbl =
+ 2 * max (0, min (tool_bar_max_label_size, STRING_BYTES_BOUND / 2));
char *buf = (char *) xmalloc (max_lbl + 1);
Lisp_Object new_lbl;
- size_t caption_len = strlen (capt);
+ ptrdiff_t caption_len = strlen (capt);
if (caption_len <= max_lbl && capt[0] != '\0')
{
if (strlen (label) <= max_lbl && label[0] != '\0')
{
- int j;
+ ptrdiff_t j;
if (label != buf)
strcpy (buf, label);
These are done in different ways, depending on how the input will be read.
Menus using X are done after auto-saving in read-char, getting the input
event from Fx_popup_menu; menus using the minibuf use read_char recursively
- and do auto-saving in the inner call of read_char. */
+ and do auto-saving in the inner call of read_char. */
static Lisp_Object
-read_char_x_menu_prompt (int nmaps, Lisp_Object *maps, Lisp_Object prev_event,
- int *used_mouse_menu)
+read_char_x_menu_prompt (ptrdiff_t nmaps, Lisp_Object *maps,
+ Lisp_Object prev_event, int *used_mouse_menu)
{
- int mapno;
+ ptrdiff_t mapno;
if (used_mouse_menu)
*used_mouse_menu = 0;
Lisp_Object *realmaps
= (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
Lisp_Object value;
- int nmaps1 = 0;
+ ptrdiff_t nmaps1 = 0;
/* Use the maps that are not nil. */
for (mapno = 0; mapno < nmaps; mapno++)
We make this bigger when necessary, and never free it. */
static char *read_char_minibuf_menu_text;
/* Size of that buffer. */
-static int read_char_minibuf_menu_width;
+static ptrdiff_t read_char_minibuf_menu_width;
static Lisp_Object
-read_char_minibuf_menu_prompt (int commandflag, int nmaps, Lisp_Object *maps)
+read_char_minibuf_menu_prompt (int commandflag,
+ ptrdiff_t nmaps, Lisp_Object *maps)
{
- int mapno;
+ ptrdiff_t mapno;
register Lisp_Object name;
- int nlength;
+ ptrdiff_t nlength;
/* FIXME: Use the minibuffer's frame width. */
- int width = FRAME_COLS (SELECTED_FRAME ()) - 4;
- int idx = -1;
+ ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4;
+ ptrdiff_t idx = -1;
int nobindings = 1;
Lisp_Object rest, vector;
char *menu;
/* Make sure we have a big enough buffer for the menu text. */
width = max (width, SBYTES (name));
- if (read_char_minibuf_menu_text == 0)
- {
- read_char_minibuf_menu_width = width + 4;
- read_char_minibuf_menu_text = (char *) xmalloc (width + 4);
- }
- else if (width + 4 > read_char_minibuf_menu_width)
+ if (STRING_BYTES_BOUND - 4 < width)
+ memory_full (SIZE_MAX);
+ if (width + 4 > read_char_minibuf_menu_width)
{
- read_char_minibuf_menu_width = width + 4;
read_char_minibuf_menu_text
= (char *) xrealloc (read_char_minibuf_menu_text, width + 4);
+ read_char_minibuf_menu_width = width + 4;
}
menu = read_char_minibuf_menu_text;
while (1)
{
int notfirst = 0;
- int i = nlength;
+ ptrdiff_t i = nlength;
Lisp_Object obj;
Lisp_Object orig_defn_macro;
tem
= XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ];
if (!NILP (tem))
- /* Insert equivalent keybinding. */
+ /* Insert equivalent keybinding. */
s = concat2 (s, tem);
#endif
tem
= XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE];
if (EQ (tem, QCradio) || EQ (tem, QCtoggle))
{
- /* Insert button prefix. */
+ /* Insert button prefix. */
Lisp_Object selected
= XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];
if (EQ (tem, QCradio))
< width
|| !notfirst)
{
- int thiswidth;
+ ptrdiff_t thiswidth;
/* Punctuate between strings. */
if (notfirst)
if (! char_matches)
{
/* Add as much of string as fits. */
- thiswidth = SCHARS (desc);
- if (thiswidth + i > width)
- thiswidth = width - i;
+ thiswidth = min (SCHARS (desc), width - i);
memcpy (menu + i, SDATA (desc), thiswidth);
i += thiswidth;
strcpy (menu + i, " = ");
}
/* Add as much of string as fits. */
- thiswidth = SCHARS (s);
- if (thiswidth + i > width)
- thiswidth = width - i;
+ thiswidth = min (SCHARS (s), width - i);
memcpy (menu + i, SDATA (s), thiswidth);
i += thiswidth;
menu[i] = 0;
NEXT may be the same array as CURRENT. */
static int
-follow_key (Lisp_Object key, int nmaps, Lisp_Object *current, Lisp_Object *defs,
- Lisp_Object *next)
+follow_key (Lisp_Object key, ptrdiff_t nmaps, Lisp_Object *current,
+ Lisp_Object *defs, Lisp_Object *next)
{
- int i, first_binding;
+ ptrdiff_t i, first_binding;
first_binding = nmaps;
for (i = nmaps - 1; i >= 0; i--)
/* Positions [START, END) in the key sequence buffer
are the key that we have scanned so far.
Those events are the ones that we will replace
- if PAREHT maps them into a key sequence. */
+ if PARENT maps them into a key sequence. */
int start, end;
} keyremap;
The return value is non-zero if the remapping actually took place. */
static int
-keyremap_step (Lisp_Object *keybuf, size_t bufsize, volatile keyremap *fkey,
+keyremap_step (Lisp_Object *keybuf, int bufsize, volatile keyremap *fkey,
int input, int doit, int *diff, Lisp_Object prompt)
{
Lisp_Object next, key;
/* If keybuf[fkey->start..fkey->end] is bound in the
map and we're in a position to do the key remapping, replace it with
- the binding and restart with fkey->start at the end. */
+ the binding and restart with fkey->start at the end. */
if ((VECTORP (next) || STRINGP (next)) && doit)
{
int len = XFASTINT (Flength (next));
*diff = len - (fkey->end - fkey->start);
- if (input + *diff >= bufsize)
+ if (bufsize - input <= *diff)
error ("Key sequence too long");
/* Shift the keys that follow fkey->end. */
return 0;
}
+static int
+test_undefined (Lisp_Object binding)
+{
+ return (EQ (binding, Qundefined)
+ || (!NILP (binding) && SYMBOLP (binding)
+ && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
+}
+
/* Read a sequence of keys that ends with a non prefix character,
storing it in KEYBUF, a buffer of size BUFSIZE.
Prompt with PROMPT.
from the selected window's buffer. */
static int
-read_key_sequence (Lisp_Object *keybuf, size_t bufsize, Lisp_Object prompt,
+read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
int dont_downcase_last, int can_return_switch_frame,
int fix_current_buffer)
{
/* The number of keymaps we're scanning right now, and the number of
keymaps we have allocated space for. */
- int nmaps;
- int nmaps_allocated = 0;
+ ptrdiff_t nmaps;
+ ptrdiff_t nmaps_allocated = 0;
/* defs[0..nmaps-1] are the definitions of KEYBUF[0..t-1] in
the current keymaps. */
/* The index in submaps[] of the first keymap that has a binding for
this key sequence. In other words, the lowest i such that
submaps[i] is non-nil. */
- int first_binding;
+ ptrdiff_t first_binding;
/* Index of the first key that has no binding.
It is useless to try fkey.start larger than that. */
int first_unbound;
/* Non-zero if we are trying to map a key by changing an upper-case
letter to lower case, or a shifted function key to an unshifted
- one. */
+ one. */
int shift_translated = 0;
/* If we receive a `switch-frame' or `select-window' event in the middle of
While we're reading, we keep the event here. */
Lisp_Object delayed_switch_frame;
- /* See the comment below... */
+ /* See the comment below... */
#if defined (GOBBLE_FIRST_EVENT)
Lisp_Object first_event;
#endif
}
else
{
- int nminor;
- int total;
+ ptrdiff_t nminor;
+ ptrdiff_t total;
Lisp_Object *maps;
nminor = current_minor_maps (0, &maps);
echo_local_start and keys_local_start allow us to throw away
just one key. */
int echo_local_start IF_LINT (= 0);
- int keys_local_start, local_first_binding;
+ int keys_local_start;
+ ptrdiff_t local_first_binding;
eassert (indec.end == t || (indec.end > t && indec.end <= mock_input));
eassert (indec.start <= indec.end);
if (!found)
{
/* Don't touch interrupted_kboard when it's been
- deleted. */
+ deleted. */
delayed_switch_frame = Qnil;
goto replay_entire_sequence;
}
{
/* If we're at the beginning of a key sequence, and the caller
says it's okay, go ahead and return this event. If we're
- in the midst of a key sequence, delay it until the end. */
+ in the midst of a key sequence, delay it until the end. */
if (t > 0 || !can_return_switch_frame)
{
delayed_switch_frame = key;
&& (NILP (fake_prefixed_keys)
|| NILP (Fmemq (key, fake_prefixed_keys))))
{
- if (t + 1 >= bufsize)
+ if (bufsize - t <= 1)
error ("Key sequence too long");
keybuf[t] = posn;
insert the dummy prefix event `menu-bar'. */
if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
{
- if (t + 1 >= bufsize)
+ if (bufsize - t <= 1)
error ("Key sequence too long");
keybuf[t] = posn;
keybuf[t+1] = key;
Down-clicks are eliminated.
Double-downs reduce to downs, then are eliminated.
Triple-downs reduce to double-downs, then to downs,
- then are eliminated. */
+ then are eliminated. */
if (modifiers & (down_modifier | drag_modifier
| double_modifier | triple_modifier))
{
}
}
- if (first_binding < nmaps && NILP (submaps[first_binding])
+ if (first_binding < nmaps
+ && NILP (submaps[first_binding])
+ && !test_undefined (defs[first_binding])
&& indec.start >= t)
/* There is a binding and it's not a prefix.
(and it doesn't have any input-decode-map translation pending).
/* If there's a binding (i.e.
first_binding >= nmaps) we don't want
to apply this function-key-mapping. */
- fkey.end + 1 == t && first_binding >= nmaps,
+ fkey.end + 1 == t
+ && (first_binding >= nmaps
+ || test_undefined (defs[first_binding])),
&diff, prompt);
UNGCPRO;
if (done)
read_key_sequence_cmd = (first_binding < nmaps
? defs[first_binding]
: Qnil);
+ read_key_sequence_remapped
+ /* Remap command through active keymaps.
+ Do the remapping here, before the unbind_to so it uses the keymaps
+ of the appropriate buffer. */
+ = SYMBOLP (read_key_sequence_cmd)
+ ? Fcommand_remapping (read_key_sequence_cmd, Qnil, Qnil)
+ : Qnil;
unread_switch_frame = delayed_switch_frame;
unbind_to (count, Qnil);
! NILP (can_return_switch_frame), 0);
#if 0 /* The following is fine for code reading a key sequence and
- then proceeding with a lenghty computation, but it's not good
+ then proceeding with a lengthy computation, but it's not good
for code reading keys in a loop, like an input method. */
#ifdef HAVE_WINDOW_SYSTEM
if (display_hourglass_p)
char *newmessage;
int message_p = push_message ();
int count = SPECPDL_INDEX ();
+ ptrdiff_t newmessage_len, newmessage_alloc;
+ USE_SAFE_ALLOCA;
record_unwind_protect (pop_message_unwind, Qnil);
binding = Fkey_description (bindings, Qnil);
-
- newmessage
- = (char *) alloca (SCHARS (SYMBOL_NAME (function))
- + SBYTES (binding)
- + 100);
- sprintf (newmessage, "You can run the command `%s' with %s",
- SDATA (SYMBOL_NAME (function)),
- SDATA (binding));
+ newmessage_alloc =
+ (sizeof "You can run the command `' with "
+ + SBYTES (SYMBOL_NAME (function)) + SBYTES (binding));
+ SAFE_ALLOCA (newmessage, char *, newmessage_alloc);
+ newmessage_len =
+ esprintf (newmessage, "You can run the command `%s' with %s",
+ SDATA (SYMBOL_NAME (function)),
+ SDATA (binding));
message2 (newmessage,
- strlen (newmessage),
+ newmessage_len,
STRING_MULTIBYTE (binding));
if (NUMBERP (Vsuggest_key_bindings))
waited = sit_for (Vsuggest_key_bindings, 0, 2);
if (!NILP (waited) && message_p)
restore_message ();
+ SAFE_FREE ();
unbind_to (count, Qnil);
}
}
(void)
{
Lisp_Object temp;
- XSETFASTINT (temp, command_loop_level + minibuf_level);
+ /* Wrap around reliably on integer overflow. */
+ EMACS_INT sum = (command_loop_level & INTMASK) + (minibuf_level & INTMASK);
+ XSETINT (temp, sum);
return temp;
}
DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1,
"FOpen dribble file: ",
doc: /* Start writing all keyboard characters to a dribble file called FILE.
-If FILE is nil, close any open dribble file. */)
+If FILE is nil, close any open dribble file.
+The file will be closed when Emacs exits. */)
(Lisp_Object file)
{
if (dribble)
waiting_for_input = 1;
/* If handle_interrupt was called before and buffered a C-g,
- make it run again now, to avoid timing error. */
+ make it run again now, to avoid timing error. */
if (!NILP (Vquit_flag))
quit_throw_to_read_char ();
}
static void
interrupt_signal (int signalnum) /* If we don't have an argument, some */
- /* compilers complain in signal calls. */
+ /* compilers complain in signal calls. */
{
/* Must preserve main program's value of errno. */
int old_errno = errno;
SIGNAL_THREAD_CHECK (signalnum);
- /* See if we have an active terminal on our controlling tty. */
+ /* See if we have an active terminal on our controlling tty. */
terminal = get_named_tty ("/dev/tty");
if (!terminal)
{
/* If there are no frames there, let's pretend that we are a
- well-behaving UN*X program and quit. */
- Fkill_emacs (Qnil);
+ well-behaving UN*X program and quit. We cannot do that while
+ GC is in progress, though. */
+ if (!gc_in_progress)
+ Fkill_emacs (Qnil);
+ else
+ Vquit_flag = Qt;
}
else
{
Otherwise it sets the Lisp variable quit-flag not-nil. This causes
eval to throw, when it gets a chance. If quit-flag is already
- non-nil, it stops the job right away. */
+ non-nil, it stops the job right away. */
static void
handle_interrupt (void)
cancel_echoing ();
- /* XXX This code needs to be revised for multi-tty support. */
+ /* XXX This code needs to be revised for multi-tty support. */
if (!NILP (Vquit_flag) && get_named_tty ("/dev/tty"))
{
/* If SIGINT isn't blocked, don't let us be interrupted by
wait_reading_process_output() under HAVE_NS because of the call
to ns_select there (needed because otherwise events aren't picked up
outside of polling since we don't get SIGIO like X and we don't have a
- separate event loop thread like W32. */
+ separate event loop thread like W32. */
#ifndef HAVE_NS
if (waiting_for_input && !echoing)
quit_throw_to_read_char ();
session may have multiple display types, so we always handle
SIGINT. There is special code in interrupt_signal to exit
Emacs on SIGINT when there are no termcap frames on the
- controlling terminal. */
+ controlling terminal. */
signal (SIGINT, interrupt_signal);
#ifndef DOS_NT
/* For systems with SysV TERMIO, C-g is set up for both SIGINT and
read_key_sequence_cmd = Qnil;
staticpro (&read_key_sequence_cmd);
+ read_key_sequence_remapped = Qnil;
+ staticpro (&read_key_sequence_remapped);
menu_bar_one_keymap_changed_items = Qnil;
staticpro (&menu_bar_one_keymap_changed_items);
Function key definitions that apply to all terminal devices should go
here. If a mapping is defined in both the current
`local-function-key-map' binding and this variable, then the local
-definition will take precendence. */);
+definition will take precedence. */);
Vfunction_key_map = Fmake_sparse_keymap (Qnil);
DEFVAR_LISP ("key-translation-map", Vkey_translation_map,
variable are `sigusr1' and `sigusr2'. */);
Vdebug_on_event = intern_c_string ("sigusr2");
- /* Create the initial keyboard. */
+ /* Create the initial keyboard. */
initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
init_kboard (initial_kboard);
/* Vwindow_system is left at t for now. */