#include "window.h"
#include "commands.h"
#include "buffer.h"
+#include "charset.h"
#include "disptab.h"
#include "dispextern.h"
#include "keyboard.h"
Lisp_Object this_command_keys;
int this_command_key_count;
+/* Number of elements of this_command_keys
+ that precede this key sequence. */
+int this_single_command_key_start;
+
/* Record values of this_command_key_count and echo_length ()
before this command was read. */
static int before_command_key_count;
/* The buffer that was current when the last command was started. */
Lisp_Object last_point_position_buffer;
-#ifdef MULTI_FRAME
/* The frame in which the last input event occurred, or Qmacro if the
last event came from a macro. We use this to determine when to
generate switch-frame events. This may be cleared by functions
like Fselect_frame, to make sure that a switch-frame event is
generated by the next character. */
Lisp_Object internal_last_event_frame;
-#endif
/* A user-visible version of the above, intended to allow users to
figure out where the last event came from, if the event doesn't
Lisp_Object Vlucid_menu_bar_dirty_flag;
Lisp_Object Qrecompute_lucid_menubar, Qactivate_menubar_hook;
+Lisp_Object Qecho_area_clear_hook;
+
/* Hooks to run before and after each command. */
Lisp_Object Qpre_command_hook, Vpre_command_hook;
Lisp_Object Qpost_command_hook, Vpost_command_hook;
extern char *x_get_keysym_name ();
+static void record_menu_key ();
+
Lisp_Object Qpolling_period;
/* List of absolute timers. Appears in order of next scheduled event. */
#ifdef HAVE_WINDOW_SYSTEM
#define POLL_FOR_INPUT
#endif
-
-/* Non-nil enables Column Number mode. */
-Lisp_Object Vcolumn_number_mode;
\f
/* Global variable declarations. */
if (before_command_restore_flag)
{
this_command_key_count = before_command_key_count_1;
+ if (this_command_key_count < this_single_command_key_start)
+ this_single_command_key_start = this_command_key_count;
echo_truncate (before_command_echo_length_1);
before_command_restore_flag = 0;
}
val = command_loop ();
if (EQ (val, Qt))
Fsignal (Qquit, Qnil);
+ /* Handle throw from read_minibuf when using minibuffer
+ while it's active but we're in another window. */
+ if (STRINGP (val))
+ Fsignal (Qerror, Fcons (val, Qnil));
return unbind_to (count, Qnil);
}
Lisp_Object data;
{
Lisp_Object old_level, old_length;
+ char macroerror[50];
+
+ if (!NILP (executing_macro))
+ {
+ if (executing_macro_iterations == 1)
+ sprintf (macroerror, "After 1 kbd macro iteration: ");
+ else
+ sprintf (macroerror, "After %d kbd macro iterations: ",
+ executing_macro_iterations);
+ }
+ else
+ *macroerror = 0;
Vstandard_output = Qt;
Vstandard_input = Qt;
Vexecuting_macro = Qnil;
+ executing_macro = Qnil;
current_kboard->Vprefix_arg = Qnil;
cancel_echoing ();
old_length = Vprint_length;
XSETFASTINT (Vprint_level, 10);
XSETFASTINT (Vprint_length, 10);
- cmd_error_internal (data, NULL);
+ cmd_error_internal (data, macroerror);
Vprint_level = old_level;
Vprint_length = old_length;
command_loop_1 ()
{
Lisp_Object cmd, tem;
- int lose;
+ int lose, lose2;
int nonundocount;
Lisp_Object keybuf[30];
int i;
nonundocount = 0;
no_redisplay = 0;
this_command_key_count = 0;
+ this_single_command_key_start = 0;
/* Make sure this hook runs after commands that get errors and
throw to top level. */
rather than quitting back to the minibuffer. */
int count = specpdl_ptr - specpdl;
specbind (Qinhibit_quit, Qt);
- Fsit_for (make_number (2), Qnil, Qnil);
- unbind_to (count, Qnil);
+ Fsit_for (make_number (2), Qnil, Qnil);
/* Clear the echo area. */
message2 (0);
+ safe_run_hooks (Qecho_area_clear_hook);
+
+ unbind_to (count, Qnil);
/* If a C-g came in before, treat it as input now. */
if (!NILP (Vquit_flag))
#endif /* C_ALLOCA */
#if 0
-#ifdef MULTI_FRAME
/* Select the frame that the last event came from. Usually,
switch-frame events will take care of this, but if some lisp
code swallows a switch-frame event, we'll fix things up here.
if (FRAMEP (internal_last_event_frame)
&& XFRAME (internal_last_event_frame) != selected_frame)
Fselect_frame (internal_last_event_frame, Qnil);
-#endif
#endif
/* If it has changed current-menubar from previous value,
really recompute the menubar from the value. */
i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0],
Qnil, 0, 1);
+ /* A filter may have run while we were reading the input. */
+ if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
+ set_buffer_internal (XBUFFER (XWINDOW (selected_window)->buffer));
+
++num_input_keys;
/* Now we have read a key sequence of length I,
{
cancel_echoing ();
this_command_key_count = 0;
+ this_single_command_key_start = 0;
goto finalize;
}
{
struct Lisp_Char_Table *dp
= window_display_table (XWINDOW (selected_window));
- lose = FETCH_CHAR (PT);
- SET_PT (PT + 1);
+ lose = FETCH_BYTE (PT);
+ SET_PT (forward_point (1));
if ((dp
? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
: (NILP (DISP_CHAR_VECTOR (dp, lose))
&& (lose >= 0x20 && lose < 0x7f)))
: (lose >= 0x20 && lose < 0x7f))
+ /* To extract the case of continuation on
+ wide-column characters. */
+ && (WIDTH_BY_CHAR_HEAD (FETCH_BYTE (PT)) == 1)
&& (XFASTINT (XWINDOW (selected_window)->last_modified)
>= MODIFF)
+ && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
+ >= OVERLAY_MODIFF)
&& (XFASTINT (XWINDOW (selected_window)->last_point)
== PT - 1)
&& !windows_or_buffers_changed
&& EQ (current_buffer->selective_display, Qnil)
&& !detect_input_pending ()
- && NILP (Vcolumn_number_mode)
+ && NILP (XWINDOW (selected_window)->column_number_displayed)
&& NILP (Vexecuting_macro))
no_redisplay = direct_output_forward_char (1);
goto directly_done;
{
struct Lisp_Char_Table *dp
= window_display_table (XWINDOW (selected_window));
- SET_PT (PT - 1);
- lose = FETCH_CHAR (PT);
+ SET_PT (forward_point (-1));
+ lose = FETCH_BYTE (PT);
if ((dp
? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
: (lose >= 0x20 && lose < 0x7f))
&& (XFASTINT (XWINDOW (selected_window)->last_modified)
>= MODIFF)
+ && (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
+ >= OVERLAY_MODIFF)
&& (XFASTINT (XWINDOW (selected_window)->last_point)
== PT + 1)
&& !windows_or_buffers_changed
&& EQ (current_buffer->selective_display, Qnil)
&& !detect_input_pending ()
- && NILP (Vcolumn_number_mode)
+ && NILP (XWINDOW (selected_window)->column_number_displayed)
&& NILP (Vexecuting_macro))
no_redisplay = direct_output_forward_char (-1);
goto directly_done;
}
lose = ((XFASTINT (XWINDOW (selected_window)->last_modified)
< MODIFF)
+ || (XFASTINT (XWINDOW (selected_window)->last_overlay_modified)
+ < OVERLAY_MODIFF)
|| (XFASTINT (XWINDOW (selected_window)->last_point)
!= PT)
|| MODIFF <= SAVE_MODIFF
|| windows_or_buffers_changed
|| !EQ (current_buffer->selective_display, Qnil)
|| detect_input_pending ()
- || !NILP (Vcolumn_number_mode)
+ || !NILP (XWINDOW (selected_window)->column_number_displayed)
|| !NILP (Vexecuting_macro));
value = internal_self_insert (c, 0);
if (value)
nonundocount = 0;
if (!lose
- && (PT == ZV || FETCH_CHAR (PT) == '\n'))
+ && (PT == ZV || FETCH_BYTE (PT) == '\n'))
{
struct Lisp_Char_Table *dp
= window_display_table (XWINDOW (selected_window));
}
directly_done: ;
- /* Note that the value cell will never directly contain nil
- if the symbol is a local variable. */
- if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
- safe_run_hooks (Qpost_command_hook);
-
- if (!NILP (Vdeferred_action_list))
- safe_run_hooks (Qdeferred_action_function);
-
- if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks))
- {
- if (NILP (Vunread_command_events)
- && NILP (Vexecuting_macro)
- && !NILP (sit_for (0, post_command_idle_delay, 0, 1)))
- safe_run_hooks (Qpost_command_idle_hook);
- }
-
/* If there is a prefix argument,
1) We don't want Vlast_command to be ``universal-argument''
(that would be dumb), so don't set Vlast_command,
current_kboard->Vlast_command = this_command;
cancel_echoing ();
this_command_key_count = 0;
+ this_single_command_key_start = 0;
+ }
+
+ /* Note that the value cell will never directly contain nil
+ if the symbol is a local variable. */
+ if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
+ safe_run_hooks (Qpost_command_hook);
+
+ if (!NILP (Vdeferred_action_list))
+ safe_run_hooks (Qdeferred_action_function);
+
+ if (!NILP (Vpost_command_idle_hook) && !NILP (Vrun_hooks))
+ {
+ if (NILP (Vunread_command_events)
+ && NILP (Vexecuting_macro)
+ && !NILP (sit_for (0, post_command_idle_delay, 0, 1)))
+ safe_run_hooks (Qpost_command_idle_hook);
}
if (!NILP (current_buffer->mark_active) && !NILP (Vrun_hooks))
if (!NILP (Vexecuting_macro))
{
-#ifdef MULTI_FRAME
/* We set this to Qmacro; since that's not a frame, nobody will
try to switch frames on us, and the selected window will
remain unchanged.
events read from a macro should never cause a new frame to be
selected. */
Vlast_event_frame = internal_last_event_frame = Qmacro;
-#endif
/* Exit the macro if we are at the end.
Also, some things replace the macro with t
if (_setjmp (local_getcjmp))
{
XSETINT (c, quit_char);
-#ifdef MULTI_FRAME
XSETFRAME (internal_last_event_frame, selected_frame);
Vlast_event_frame = internal_last_event_frame;
-#endif
/* If we report the quit char as an event,
don't do so more than once. */
if (!NILP (Vinhibit_quit))
/* Don't bring up a menu if we already have another event. */
&& NILP (Vunread_command_events)
&& unread_command_char < 0)
- c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
+ {
+ c = read_char_x_menu_prompt (nmaps, maps, prev_event, used_mouse_menu);
+
+ /* Now that we have read an event, Emacs is not idle. */
+ timer_stop_idle ();
+
+ return c;
+ }
/* Maybe autosave and/or garbage collect due to idleness. */
if (NILP (current_kboard->kbd_queue))
current_kboard->kbd_queue_has_data = 0;
input_pending = readable_events (0);
-#ifdef MULTI_FRAME
if (EVENT_HAS_PARAMETERS (c)
&& EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qswitch_frame))
internal_last_event_frame = XCONS (XCONS (c)->cdr)->car;
Vlast_event_frame = internal_last_event_frame;
-#endif
}
}
}
/* Wipe the echo area. */
+ if (echo_area_glyphs)
+ safe_run_hooks (Qecho_area_clear_hook);
echo_area_glyphs = 0;
/* Handle things that only apply to characters. */
return c;
if (STRINGP (Vkeyboard_translate_table)
- && XSTRING (Vkeyboard_translate_table)->size > XFASTINT (c))
+ && XSTRING (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
XSETINT (c, XSTRING (Vkeyboard_translate_table)->data[XFASTINT (c)]);
else if ((VECTORP (Vkeyboard_translate_table)
- && XVECTOR (Vkeyboard_translate_table)->size > XFASTINT (c))
- || CHAR_TABLE_P (Vkeyboard_translate_table))
+ && XVECTOR (Vkeyboard_translate_table)->size > (unsigned) XFASTINT (c))
+ || (CHAR_TABLE_P (Vkeyboard_translate_table)
+ && CHAR_TABLE_ORDINARY_SLOTS > (unsigned) XFASTINT (c)))
{
Lisp_Object d;
d = Faref (Vkeyboard_translate_table, c);
return c;
}
+/* Record a key that came from a mouse menu.
+ Record it for echoing, for this-command-keys, and so on. */
+
+static void
+record_menu_key (c)
+ Lisp_Object c;
+{
+ /* Wipe the echo area. */
+ echo_area_glyphs = 0;
+
+ record_char (c);
+
+ before_command_key_count = this_command_key_count;
+ before_command_echo_length = echo_length ();
+
+ /* Don't echo mouse motion events. */
+ if (echo_keystrokes)
+ {
+ echo_char (c);
+
+ /* Once we reread a character, echoing can happen
+ the next time we pause to read a new one. */
+ ok_to_echo_at_next_pause = 0;
+ }
+
+ /* Record this character as part of the current key. */
+ add_command_key (c);
+
+ /* Re-reading in the middle of a command */
+ last_input_char = c;
+ num_input_chars++;
+}
+
/* Return 1 if should recognize C as "the help character". */
int
}
#endif
-#ifdef MULTI_FRAME
/* 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
internal_last_event_frame = focus;
Vlast_event_frame = focus;
}
-#endif
last_event_timestamp = event->timestamp;
interrupt_signal ();
{
kbd_fetch_ptr = event + 1;
input_pending = readable_events (0);
- x_activate_menubar (XFRAME (event->frame_or_window));
+ if (FRAME_LIVE_P (XFRAME (event->frame_or_window)))
+ x_activate_menubar (XFRAME (event->frame_or_window));
}
#endif
/* Just discard these, by returning nil.
time, and leave the event in the queue for next time. */
else
{
-#ifdef MULTI_FRAME
Lisp_Object frame;
Lisp_Object focus;
&& XFRAME (frame) != selected_frame)
obj = make_lispy_switch_frame (frame);
internal_last_event_frame = frame;
-#endif /* MULTI_FRAME */
/* If we didn't decide to make a switch-frame event, go ahead
and build a real event from the queue entry. */
obj = Qnil;
-#ifdef MULTI_FRAME
/* Decide if we should generate a switch-frame event. Don't
generate switch-frame events for motion outside of all Emacs
frames. */
obj = make_lispy_switch_frame (frame);
internal_last_event_frame = frame;
}
-#endif
/* If we didn't decide to make a switch-frame event, go ahead and
return a mouse-motion event. */
input_pending = readable_events (0);
-#ifdef MULTI_FRAME
Vlast_event_frame = internal_last_event_frame;
-#endif
return (obj);
}
#define FUNCTION_KEY_OFFSET 0xff00
+#ifdef XK_kana_A
+static char *lispy_kana_keys[] =
+ {
+ /* X Keysym value */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x400 .. 0x40f */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x410 .. 0x41f */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x420 .. 0x42f */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x430 .. 0x43f */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x440 .. 0x44f */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x450 .. 0x45f */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x460 .. 0x46f */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,"overline",0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x480 .. 0x48f */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x490 .. 0x49f */
+ 0, "kana-fullstop", "kana-openingbracket", "kana-closingbracket",
+ "kana-comma", "kana-conjunctive", "kana-WO", "kana-a",
+ "kana-i", "kana-u", "kana-e", "kana-o",
+ "kana-ya", "kana-yu", "kana-yo", "kana-tsu",
+ "prolongedsound", "kana-A", "kana-I", "kana-U",
+ "kana-E", "kana-O", "kana-KA", "kana-KI",
+ "kana-KU", "kana-KE", "kana-KO", "kana-SA",
+ "kana-SHI", "kana-SU", "kana-SE", "kana-SO",
+ "kana-TA", "kana-CHI", "kana-TSU", "kana-TE",
+ "kana-TO", "kana-NA", "kana-NI", "kana-NU",
+ "kana-NE", "kana-NO", "kana-HA", "kana-HI",
+ "kana-FU", "kana-HE", "kana-HO", "kana-MA",
+ "kana-MI", "kana-MU", "kana-ME", "kana-MO",
+ "kana-YA", "kana-YU", "kana-YO", "kana-RA",
+ "kana-RI", "kana-RU", "kana-RE", "kana-RO",
+ "kana-WA", "kana-N", "voicedsound", "semivoicedsound",
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x4e0 .. 0x4ef */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x4f0 .. 0x4ff */
+ };
+#endif /* XK_kana_A */
+
/* You'll notice that this table is arranged to be conveniently
indexed by X Windows keysym values. */
static char *lispy_function_keys[] =
0, 0, 0, 0, 0, 0, 0,
"escape",
0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xff20...2f */
+ 0, "kanji", "muhenkan",
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xff20...2f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xff30...3f */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xff40...4f */
/* Scroll bar parts. */
Lisp_Object Qabove_handle, Qhandle, Qbelow_handle;
+Lisp_Object Qup, Qdown;
/* An array of scroll bar parts, indexed by an enum scroll_bar_part value. */
Lisp_Object *scroll_bar_parts[] = {
- &Qabove_handle, &Qhandle, &Qbelow_handle
+ &Qabove_handle, &Qhandle, &Qbelow_handle,
+ &Qup, &Qdown,
};
(unsigned)-1);
}
+#ifdef XK_kana_A
+ if (event->code >= 0x400 && event->code < 0x500)
+ return modify_event_symbol (event->code - 0x400,
+ event->modifiers & ~shift_modifier,
+ Qfunction_key, Qnil,
+ lispy_kana_keys, &func_key_syms,
+ (sizeof (lispy_kana_keys)
+ / sizeof (lispy_kana_keys[0])));
+#endif /* XK_kana_A */
+
return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET,
event->modifiers,
Qfunction_key, Qnil,
else
{
int pixcolumn, pixrow;
- column -= XINT (XWINDOW (window)->left);
+ column -= WINDOW_LEFT_MARGIN (XWINDOW (window));
row -= XINT (XWINDOW (window)->top);
glyph_to_pixel_coords (f, column, row, &pixcolumn, &pixrow);
XSETINT (event->x, pixcolumn);
portion_whole = Fcons (event->x, event->y);
part = *scroll_bar_parts[(int) event->part];
- position =
- Fcons (window,
- Fcons (Qvertical_scroll_bar,
- Fcons (portion_whole,
- Fcons (make_number (event->timestamp),
- Fcons (part, Qnil)))));
+ position
+ = Fcons (window,
+ Fcons (Qvertical_scroll_bar,
+ Fcons (portion_whole,
+ Fcons (make_number (event->timestamp),
+ Fcons (part, Qnil)))));
}
start_pos_ptr = &XVECTOR (button_down_location)->contents[button];
Qnil));
}
}
+
+#ifdef WINDOWSNT
+ case w32_scroll_bar_click:
+ {
+ int button = event->code;
+ int is_double;
+ Lisp_Object position;
+ Lisp_Object *start_pos_ptr;
+ Lisp_Object start_pos;
+
+ if (button < 0 || button >= NUM_MOUSE_BUTTONS)
+ abort ();
+
+ {
+ Lisp_Object window;
+ Lisp_Object portion_whole;
+ Lisp_Object part;
+
+ window = event->frame_or_window;
+ portion_whole = Fcons (event->x, event->y);
+ part = *scroll_bar_parts[(int) event->part];
+
+ position =
+ Fcons (window,
+ Fcons (Qvertical_scroll_bar,
+ Fcons (portion_whole,
+ Fcons (make_number (event->timestamp),
+ Fcons (part, Qnil)))));
+ }
+
+ /* Always treat W32 scroll bar events as clicks. */
+ event->modifiers |= click_modifier;
+
+ {
+ /* Get the symbol we should use for the mouse click. */
+ Lisp_Object head;
+
+ head = modify_event_symbol (button,
+ event->modifiers,
+ Qmouse_click, Qnil,
+ lispy_mouse_names, &mouse_syms,
+ (sizeof (lispy_mouse_names)
+ / sizeof (lispy_mouse_names[0])));
+ return Fcons (head,
+ Fcons (position,
+ Qnil));
+ }
+ }
+#endif
+
#endif /* HAVE_MOUSE */
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI)
Lisp_Object x, y;
unsigned long time;
{
-#ifdef MULTI_FRAME
/* Is it a scroll bar movement? */
if (frame && ! NILP (bar_window))
{
/* Or is it an ordinary mouse movement? */
else
-#endif /* MULTI_FRAME */
{
int area;
Lisp_Object window;
Lisp_Object posn;
int column, row;
-#ifdef MULTI_FRAME
if (frame)
-#else
- if (1)
-#endif
{
/* It's in a frame; which window on that frame? */
pixel_to_glyph_coords (frame, XINT (x), XINT (y), &column, &row,
if (WINDOWP (window))
{
int pixcolumn, pixrow;
- column -= XINT (XWINDOW (window)->left);
+ column -= WINDOW_LEFT_MARGIN (XWINDOW (window));
row -= XINT (XWINDOW (window)->top);
glyph_to_pixel_coords (frame, column, row, &pixcolumn, &pixrow);
XSETINT (x, pixcolumn);
XSETINT (posn,
buffer_posn_from_coords (XWINDOW (window), column, row));
}
-#ifdef MULTI_FRAME
else if (frame != 0)
{
XSETFRAME (window, frame);
posn = Qnil;
}
-#endif
else
{
window = Qnil;
/* No; let's create it. */
if (!NILP (name_alist))
value = Fcdr_safe (Fassq (symbol_int, name_alist));
- else if (name_table[symbol_num])
+ else if (name_table != 0 && name_table[symbol_num])
value = intern (name_table[symbol_num]);
#ifdef HAVE_WINDOW_SYSTEM
}
if (CONSP (*symbol_table))
- *symbol_table = Fcons (value, *symbol_table);
+ *symbol_table = Fcons (Fcons (symbol_int, value), *symbol_table);
else
XVECTOR (*symbol_table)->contents[symbol_num] = value;
"Convert the event description list EVENT-DESC to an event type.\n\
EVENT-DESC should contain one base event type (a character or symbol)\n\
and zero or more modifier names (control, meta, hyper, super, shift, alt,\n\
-drag, down, double or triple).\n\
+drag, down, double or triple). The base must be last.\n\
The return value is an event type (a character or symbol) which\n\
has the same base event type and all the specified modifiers.")
(event_desc)
int this = 0;
elt = XCONS (rest)->car;
+ rest = XCONS (rest)->cdr;
/* Given a symbol, see if it is a modifier name. */
- if (SYMBOLP (elt))
+ if (SYMBOLP (elt) && CONSP (rest))
this = parse_solitary_modifier (elt);
if (this != 0)
else
base = elt;
- rest = XCONS (rest)->cdr;
}
/* Let the symbol A refer to the character A. */
if (interrupt_input)
{
SIGMASKTYPE mask;
- mask = sigblockx (SIGIO);
+ mask = sigblock (sigmask (SIGIO));
read_avail_input (expected);
sigsetmask (mask);
}
if (read_socket_hook && !interrupt_input && poll_suppress_count == 0)
{
SIGMASKTYPE mask;
- mask = sigblockx (SIGALRM);
+ mask = sigblock (sigmask (SIGALRM));
read_avail_input (expected);
sigsetmask (mask);
}
if (interrupt_input)
{
SIGMASKTYPE mask;
- mask = sigblockx (SIGIO);
+ mask = sigblock (sigmask (SIGIO));
kbd_buffer_store_event (&event);
sigsetmask (mask);
}
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, expected);
+ nread = (*read_socket_hook) (input_fd, buf, KBD_BUFFER_SIZE, expected);
else
{
/* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
cbuf[i] &= ~0x80;
buf[i].code = cbuf[i];
-#ifdef MULTI_FRAME
XSETFRAME (buf[i].frame_or_window, selected_frame);
-#else
- buf[i].frame_or_window = Qnil;
-#endif
}
}
extern int select_alarmed;
#endif
-#ifdef USG
+#if defined (USG) && !defined (POSIX_SIGNALS)
/* USG systems forget handlers when they are used;
must reestablish each time */
signal (signo, input_available_signal);
}
}
- /* Add nil, nil, nil at the end. */
+ /* Add nil, nil, nil, nil at the end. */
i = menu_bar_items_index;
if (i + 4 > XVECTOR (menu_bar_items_vector)->size)
{
Lisp_Object enabled;
int i;
+ /* Skip menu-bar equiv keys data. */
+ if (CONSP (def) && CONSP (XCONS (def)->car))
+ def = XCONS (def)->cdr;
+
if (EQ (def, Qundefined))
{
/* If a map has an explicit `undefined' as definition,
{
Lisp_Object tem;
+ record_menu_key (XCONS (value)->car);
+
/* If we got multiple events, unread all but
the first.
There is no way to prevent those unread events
they won't confuse things. */
for (tem = XCONS (value)->cdr; !NILP (tem);
tem = XCONS (tem)->cdr)
- if (SYMBOLP (XCONS (tem)->car)
- || INTEGERP (XCONS (tem)->car))
- XCONS (tem)->car
- = Fcons (XCONS (tem)->car, Qnil);
+ {
+ record_menu_key (XCONS (tem)->car);
+ if (SYMBOLP (XCONS (tem)->car)
+ || INTEGERP (XCONS (tem)->car))
+ XCONS (tem)->car
+ = Fcons (XCONS (tem)->car, Qnil);
+ }
/* If we got more than one event, put all but the first
onto this list to be read later.
if (INTERACTIVE)
echo_start = echo_length ();
keys_start = this_command_key_count;
+ this_single_command_key_start = keys_start;
#if defined (GOBBLE_FIRST_EVENT)
/* This doesn't quite work, because some of the things that read_char
if (!used_mouse_menu)
last_nonmenu_event = key;
+ /* Record what part of this_command_keys is the current key sequence. */
+ this_single_command_key_start = this_command_key_count - t;
+
prev_fkey_map = fkey_map;
prev_fkey_start = fkey_start;
prev_fkey_end = fkey_end;
(To ignore it safely, we would need to gcpro a bunch of
other variables.) */
if (! (VECTORP (fkey_next) || STRINGP (fkey_next)))
- error ("Function in function-key-map returns invalid key sequence");
+ error ("Function in key-translation-map returns invalid key sequence");
}
function_key_possible = ! NILP (fkey_next);
gcpro1.nvars = (sizeof keybuf/sizeof (keybuf[0]));
if (NILP (continue_echo))
- this_command_key_count = 0;
+ {
+ this_command_key_count = 0;
+ this_single_command_key_start = 0;
+ }
i = read_key_sequence (keybuf, (sizeof keybuf/sizeof (keybuf[0])),
prompt, ! NILP (dont_downcase_last),
means unconditionally put this command in `command-history'.\n\
Otherwise, that is done only if an arg is read using the minibuffer.\n\
The argument KEYS specifies the value to use instead of (this-command-keys)\n\
-when reading the arguments; if it is nil, (this_command_key_count) is used.\n\
+when reading the arguments; if it is nil, (this-command-keys) is used.\n\
The argument SPECIAL, if non-nil, means that this command is executing\n\
a special event, so ignore the prefix argument and don't clear it.")
(cmd, record_flag, keys, special)
final = Findirect_function (cmd);
if (CONSP (final) && (tem = Fcar (final), EQ (tem, Qautoload)))
- do_autoload (final, cmd);
+ {
+ struct gcpro gcpro1, gcpro2;
+
+ GCPRO2 (cmd, prefixarg);
+ do_autoload (final, cmd);
+ UNGCPRO;
+ }
else
break;
}
Lisp_Object function;
char buf[40];
Lisp_Object saved_keys;
- struct gcpro gcpro1;
+ Lisp_Object bindings, value;
+ struct gcpro gcpro1, gcpro2;
saved_keys = Fvector (this_command_key_count,
XVECTOR (this_command_keys)->contents);
buf[0] = 0;
- GCPRO1 (saved_keys);
+ GCPRO2 (saved_keys, prefixarg);
if (EQ (prefixarg, Qminus))
strcpy (buf, "- ");
Lisp_Object tem;
this_command_key_count = 0;
+ this_single_command_key_start = 0;
keys = XVECTOR (saved_keys)->contents;
for (i = 0; i < XVECTOR (saved_keys)->size; i++)
/* If enabled, show which key runs this command. */
if (!NILP (Vsuggest_key_bindings)
+ && NILP (Vexecuting_macro)
&& SYMBOLP (function))
- {
- Lisp_Object bindings;
+ bindings = Fwhere_is_internal (function, Voverriding_local_map,
+ Qt, Qnil);
+ else
+ bindings = Qnil;
- bindings = Fwhere_is_internal (function, Voverriding_local_map,
- Qt, Qnil);
+ value = Qnil;
+ GCPRO2 (bindings, value);
+ value = Fcommand_execute (function, Qt, Qnil, Qnil);
- if (!NILP (bindings))
+ /* If the command has a key binding, print it now. */
+ if (!NILP (bindings))
+ {
+ /* But first wait, and skip the message if there is input. */
+ if (!NILP (Fsit_for ((NUMBERP (Vsuggest_key_bindings)
+ ? Vsuggest_key_bindings : make_number (2)),
+ Qnil, Qnil)))
{
- message ("You can run the command `%s' by typing %s",
+ Lisp_Object binding;
+ char *newmessage;
+ char *oldmessage = echo_area_glyphs;
+ int oldmessage_len = echo_area_glyphs_length;
+
+ binding = Fkey_description (bindings);
+
+ newmessage
+ = (char *) alloca (XSYMBOL (function)->name->size
+ + XSTRING (binding)->size
+ + 100);
+ sprintf (newmessage, "You can run the command `%s' by typing %s",
XSYMBOL (function)->name->data,
- XSTRING (Fkey_description (bindings))->data);
- Fsit_for ((NUMBERP (Vsuggest_key_bindings)
- ? Vsuggest_key_bindings : make_number (2)),
- Qnil, Qnil);
+ XSTRING (binding)->data);
+ message1_nolog (newmessage);
+ if (!NILP (Fsit_for ((NUMBERP (Vsuggest_key_bindings)
+ ? Vsuggest_key_bindings : make_number (2)),
+ Qnil, Qnil)))
+ message2_nolog (oldmessage, oldmessage_len);
}
}
- return Fcommand_execute (function, Qt, Qnil, Qnil);
+ RETURN_UNGCPRO (value);
}
/* Find the set of keymaps now active.
return input_pending;
}
-/* Return nonzero if input events are pending.
- Execute timers immediately; don't make events for them. */
+/* Return nonzero if input events are pending, and run any pending timers. */
detect_input_pending_run_timers (do_display)
int do_display;
input_pending = 0;
}
+/* Return nonzero if there are pending requeued events.
+ This isn't used yet. The hope is to make wait_reading_process_input
+ call it, and return 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. */
+
+requeued_events_pending_p ()
+{
+ return (!NILP (Vunread_command_events) || unread_command_char != -1);
+}
+
+
DEFUN ("input-pending-p", Finput_pending_p, Sinput_pending_p, 0, 0, 0,
"T if command input is currently available with no waiting.\n\
Actually, the value is nil only if we can be sure that no input is available.")
XVECTOR (this_command_keys)->contents);
}
+DEFUN ("this-single-command-keys", Fthis_single_command_keys,
+ Sthis_single_command_keys, 0, 0, 0,
+ "Return the key sequence that invoked this command.\n\
+Unlike `this-command-keys', this function's value\n\
+does not include prefix arguments.\n\
+The value is a string or a vector.")
+ ()
+{
+ return make_event_array (this_command_key_count
+ - this_single_command_key_start,
+ (XVECTOR (this_command_keys)->contents
+ + this_single_command_key_start));
+}
+
DEFUN ("reset-this-command-lengths", Freset_this_command_lengths,
Sreset_this_command_lengths, 0, 0, 0,
"Used for complicated reasons in `universal-argument-other-key'.\n\
Lisp_Object stuffstring;
{
/* stuff_char works only in BSD, versions 4.2 and up. */
-#ifdef BSD
+#ifdef BSD_SYSTEM
#ifndef BSD4_1
register unsigned char *p;
}
input_pending = 0;
#endif
-#endif /* BSD and not BSD4_1 */
+#endif /* BSD_SYSTEM and not BSD4_1 */
}
\f
set_waiting_for_input (time_to_clear)
/* Must preserve main program's value of errno. */
int old_errno = errno;
-#ifdef USG
+#if defined (USG) && !defined (POSIX_SIGNALS)
if (!read_socket_hook && NILP (Vwindow_system))
{
/* USG systems forget handlers when they are used;
cancel_echoing ();
- if (!NILP (Vquit_flag) && FRAME_TERMCAP_P (selected_frame))
+ if (!NILP (Vquit_flag)
+ && (FRAME_TERMCAP_P (selected_frame) || FRAME_MSDOS_P (selected_frame)))
{
+ /* If SIGINT isn't blocked, don't let us be interrupted by
+ another SIGINT, it might be harmful due to non-reentrancy
+ in I/O functions. */
+ sigblock (sigmask (SIGINT));
+
fflush (stdout);
reset_sys_modes ();
- sigfree ();
+
#ifdef SIGTSTP /* Support possible in later USG versions */
/*
* On systems which can suspend the current process and return to the original
#endif /* not MSDOS */
fflush (stdout);
init_sys_modes ();
+ sigfree ();
}
else
{
abort ();
#endif
#endif
-#ifdef MULTI_FRAME
if (FRAMEP (internal_last_event_frame)
&& XFRAME (internal_last_event_frame) != selected_frame)
do_switch_frame (make_lispy_switch_frame (internal_last_event_frame),
Qnil, 0);
-#endif
_longjmp (getcjmp, 1);
}
#endif
input_pending = 0;
-#ifdef MULTI_FRAME
/* This means that command_loop_1 won't try to select anything the first
time through. */
internal_last_event_frame = Qnil;
Vlast_event_frame = internal_last_event_frame;
-#endif
#ifdef MULTI_KBOARD
current_kboard = initial_kboard;
staticpro (&Qhandle);
Qbelow_handle = intern ("below-handle");
staticpro (&Qbelow_handle);
+ Qup = intern ("up");
+ staticpro (&Qup);
+ Qdown = intern ("down");
+ staticpro (&Qdown);
Qevent_kind = intern ("event-kind");
staticpro (&Qevent_kind);
unread_switch_frame = Qnil;
staticpro (&unread_switch_frame);
+ internal_last_event_frame = Qnil;
+ staticpro (&internal_last_event_frame);
+
+ read_key_sequence_cmd = Qnil;
+ staticpro (&read_key_sequence_cmd);
+
defsubr (&Sevent_convert_list);
defsubr (&Sread_key_sequence);
defsubr (&Srecursive_edit);
defsubr (&Scommand_execute);
defsubr (&Srecent_keys);
defsubr (&Sthis_command_keys);
+ defsubr (&Sthis_single_command_keys);
defsubr (&Sreset_this_command_lengths);
defsubr (&Ssuspend_emacs);
defsubr (&Sabort_recursive_edit);
inhibit_local_menu_bar_menus = 0;
DEFVAR_INT ("num-input-keys", &num_input_keys,
- "Number of complete keys read from the keyboard so far.");
+ "Number of complete key sequences read from the keyboard so far.\n\
+This includes key sequences read from keyboard macros.\n\
+The number is effectively the number of interactive command invocations.");
num_input_keys = 0;
DEFVAR_LISP ("last-event-frame", &Vlast_event_frame,
This is measured in microseconds.");
post_command_idle_delay = 100000;
+#if 0
+ DEFVAR_LISP ("echo-area-clear-hook", ...,
+ "Normal hook run when clearing the echo area.");
+#endif
+ Qecho_area_clear_hook = intern ("echo-area-clear-hook");
+ XSYMBOL (Qecho_area_clear_hook)->value = Qnil;
+
DEFVAR_LISP ("lucid-menu-bar-dirty-flag", &Vlucid_menu_bar_dirty_flag,
"t means menu bar, specified Lucid style, needs to be recomputed.");
Vlucid_menu_bar_dirty_flag = Qnil;
If the value is non-nil and not a number, we wait 2 seconds.");
Vsuggest_key_bindings = Qt;
- DEFVAR_LISP ("column-number-mode", &Vcolumn_number_mode,
- "Non-nil enables display of the current column number in the mode line.");
- Vcolumn_number_mode = Qnil;
-
DEFVAR_LISP ("timer-list", &Vtimer_list,
"List of active absolute time timers in order of increasing time");
Vtimer_list = Qnil;