#include "syssignal.h"
#include "systty.h"
-#include "systime.h"
/* This is to get the definitions of the XK_ symbols. */
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif
+/* Include systime.h after xterm.h to avoid double inclusion of time.h. */
+#include "systime.h"
+
extern int errno;
/* Variables for blockinput.h: */
int interrupt_input_pending;
-#ifdef HAVE_X_WINDOWS
-extern Lisp_Object Vmouse_grabbed;
+/* File descriptor to use for input. */
+extern int input_fd;
+#ifdef HAVE_X_WINDOWS
/* Make all keyboard buffers much bigger when using X windows. */
#define KBD_BUFFER_SIZE 4096
#else /* No X-windows, character input */
/* True while displaying for echoing. Delays C-g throwing. */
static int echoing;
+/* Nonzero means disregard local maps for the menu bar. */
+static int inhibit_local_menu_bar_menus;
+
/* Nonzero means C-g should cause immediate error-signal. */
int immediate_quit;
/* If non-nil, this is a map that overrides all other local maps. */
Lisp_Object Voverriding_local_map;
+/* If non-nil, Voverriding_local_map applies to the menu bar. */
+Lisp_Object Voverriding_local_map_menu_flag;
+
/* Current depth in recursive edits. */
int command_loop_level;
Lisp_Object Vpre_command_hook, Vpost_command_hook;
Lisp_Object Qcommand_hook_internal, Vcommand_hook_internal;
+/* List of deferred actions to be performed at a later time.
+ The precise format isn't relevant here; we just check whether it is nil. */
+Lisp_Object Vdeferred_action_list;
+
+/* Function to call to handle deferred actions, when there are any. */
+Lisp_Object Vdeferred_action_function;
+
/* File in which we write all commands we read. */
FILE *dribble;
/* 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]. */
-#ifdef __STDC__
-volatile
-#endif
-static struct input_event *kbd_store_ptr;
+static volatile struct input_event *kbd_store_ptr;
/* The above pair of variables forms a "queue empty" flag. When we
enqueue a non-hook event, we increment kbd_write_count. When we
dequeuing functions? Such a flag could be screwed up by interrupts
at inopportune times. */
-/* If this flag is non-zero, we check mouse_moved to see when the
- mouse moves, and motion events will appear in the input stream. If
- it is zero, mouse motion is ignored. */
-static int do_mouse_tracking;
+#ifdef HAVE_MOUSE
+/* If this flag is a frame, we check mouse_moved to see when the
+ mouse moves, and motion events will appear in the input stream.
+ Otherwise, mouse motion is ignored. */
+static Lisp_Object do_mouse_tracking;
/* The window system handling code should set this if the mouse has
moved since the last call to the mouse_position_hook. Calling that
is readable input; all the events in the queue might be button-up
events, and do_mouse_tracking might be off. */
#define EVENT_QUEUES_EMPTY \
- ((kbd_fetch_ptr == kbd_store_ptr) && (!do_mouse_tracking || !mouse_moved))
+ ((kbd_fetch_ptr == kbd_store_ptr) \
+ && (! FRAMEP (do_mouse_tracking) || !mouse_moved))
+#else /* Not HAVE_MOUSE. */
+#define EVENT_QUEUES_EMPTY (kbd_fetch_ptr == kbd_store_ptr)
+#endif /* HAVE_MOUSE. */
/* Symbols to head events. */
Lisp_Object Qmouse_movement;
Lisp_Object Qscroll_bar_movement;
Lisp_Object Qswitch_frame;
+Lisp_Object Qdelete_frame;
+Lisp_Object Qiconify_frame;
+Lisp_Object Qmake_frame_visible;
/* Symbols to denote kinds of events. */
Lisp_Object Qfunction_key;
/* Where to append more text to echobuf if we want to. */
static char *echoptr;
+/* If we have echoed a prompt string specified by the user,
+ this is its length. Otherwise this is -1. */
+static int echo_after_prompt;
+
/* Nonzero means don't try to suspend even if the operating system seems
to support it. */
static int cannot_suspend;
char *str;
{
int len = strlen (str);
+
if (len > sizeof echobuf - 4)
len = sizeof echobuf - 4;
bcopy (str, echobuf, len);
echoptr = echobuf + len;
*echoptr = '\0';
+ echo_after_prompt = len;
+
echo ();
}
/* If someone has passed us a composite event, use its head symbol. */
c = EVENT_HEAD (c);
- if (XTYPE (c) == Lisp_Int)
+ if (INTEGERP (c))
{
if (ptr - echobuf > sizeof echobuf - 6)
return;
ptr = push_key_description (XINT (c), ptr);
}
- else if (XTYPE (c) == Lisp_Symbol)
+ else if (SYMBOLP (c))
{
struct Lisp_String *name = XSYMBOL (c)->name;
if (((ptr - echobuf) + name->size + 4) > sizeof echobuf)
{
if (!immediate_echo && echoptr == echobuf)
return;
+ /* Do nothing if we just printed a prompt. */
+ if (echo_after_prompt == echoptr - echobuf)
+ return;
/* Do nothing if not echoing at all. */
if (echoptr == 0)
return;
{
immediate_echo = 0;
echoptr = echobuf;
+ echo_after_prompt = -1;
}
/* Return the length of the current echo string. */
Lisp_Object
cmd_error (data)
Lisp_Object data;
+{
+ Vstandard_output = Qt;
+ Vstandard_input = Qt;
+ Vexecuting_macro = Qnil;
+ cmd_error_internal (data, 0);
+
+ Vquit_flag = Qnil;
+
+ Vinhibit_quit = Qnil;
+
+ return make_number (0);
+}
+
+cmd_error_internal (data, context)
+ Lisp_Object data;
+ char *context;
{
Lisp_Object errmsg, tail, errname, file_error;
Lisp_Object stream;
Vquit_flag = Qnil;
Vinhibit_quit = Qt;
- Vstandard_output = Qt;
- Vstandard_input = Qt;
- Vexecuting_macro = Qnil;
echo_area_glyphs = 0;
/* If the window system or terminal frame hasn't been initialized
stream = Qt;
}
+ if (context != 0)
+ write_string_1 (context, -1, stream);
+
errname = Fcar (data);
if (EQ (errname, Qerror))
if (!NILP (file_error) && !NILP (tail))
errmsg = XCONS (tail)->car, tail = XCONS (tail)->cdr;
- if (XTYPE (errmsg) == Lisp_String)
+ if (STRINGP (errmsg))
Fprinc (errmsg, stream);
else
write_string_1 ("peculiar error", -1, stream);
Fterpri (stream);
Fkill_emacs (make_number (-1));
}
-
- Vquit_flag = Qnil;
-
- Vinhibit_quit = Qnil;
- return make_number (0);
}
\f
Lisp_Object command_loop_1 ();
/* Make sure this hook runs after commands that get errors and
throw to top level. */
- if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
- safe_run_hooks (&Vpost_command_hook);
+ /* Note that the value cell will never directly contain nil
+ if the symbol is a local variable. */
+ if (!NILP (XSYMBOL (Qpost_command_hook)->value) && !NILP (Vrun_hooks))
+ safe_run_hooks (Qpost_command_hook);
+
+ if (!NILP (Vdeferred_action_list))
+ call0 (Vdeferred_action_function);
/* Do this after running Vpost_command_hook, for consistency. */
last_command = this_command;
switch-frame events will take care of this, but if some lisp
code swallows a switch-frame event, we'll fix things up here.
Is this a good idea? */
- if (XTYPE (internal_last_event_frame) == Lisp_Frame
+ if (FRAMEP (internal_last_event_frame)
&& XFRAME (internal_last_event_frame) != selected_frame)
Fselect_frame (internal_last_event_frame, Qnil);
#endif
prev_buffer = current_buffer;
prev_modiff = MODIFF;
last_point_position = PT;
- XSET (last_point_position_buffer, Lisp_Buffer, prev_buffer);
+ XSETBUFFER (last_point_position_buffer, prev_buffer);
/* Execute the command. */
this_command = cmd;
- if (!NILP (Vpre_command_hook) && !NILP (Vrun_hooks))
- safe_run_hooks (&Vpre_command_hook);
+ /* Note that the value cell will never directly contain nil
+ if the symbol is a local variable. */
+ if (!NILP (XSYMBOL (Qpre_command_hook)->value) && !NILP (Vrun_hooks))
+ safe_run_hooks (Qpre_command_hook);
if (NILP (this_command))
{
SET_PT (PT + 1);
if ((dp
? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
- && XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1)
+ ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
+ : (NILP (DISP_CHAR_VECTOR (dp, lose))
+ && (lose >= 0x20 && lose < 0x7f)))
: (lose >= 0x20 && lose < 0x7f))
&& (XFASTINT (XWINDOW (selected_window)->last_modified)
>= MODIFF)
lose = FETCH_CHAR (PT);
if ((dp
? (VECTORP (DISP_CHAR_VECTOR (dp, lose))
- && XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1)
+ ? XVECTOR (DISP_CHAR_VECTOR (dp, lose))->size == 1
+ : (NILP (DISP_CHAR_VECTOR (dp, lose))
+ && (lose >= 0x20 && lose < 0x7f)))
: (lose >= 0x20 && lose < 0x7f))
&& (XFASTINT (XWINDOW (selected_window)->last_modified)
>= MODIFF)
}
else if (EQ (this_command, Qself_insert_command)
/* Try this optimization only on ascii keystrokes. */
- && XTYPE (last_command_char) == Lisp_Int)
+ && INTEGERP (last_command_char))
{
unsigned char c = XINT (last_command_char);
+ int value;
- if (NILP (Vexecuting_macro) &&
- !EQ (minibuf_window, selected_window))
+ if (NILP (Vexecuting_macro)
+ && !EQ (minibuf_window, selected_window))
{
if (!nonundocount || nonundocount >= 20)
{
}
nonundocount++;
}
- lose = (XFASTINT (XWINDOW (selected_window)->last_modified)
- < MODIFF)
- || (XFASTINT (XWINDOW (selected_window)->last_point) != PT)
- || MODIFF <= current_buffer->save_modified
- || windows_or_buffers_changed
- || !EQ (current_buffer->selective_display, Qnil)
- || detect_input_pending ()
- || !NILP (Vexecuting_macro);
- if (internal_self_insert (c, 0))
- {
- lose = 1;
- nonundocount = 0;
- }
- if (!lose &&
- (PT == ZV || FETCH_CHAR (PT) == '\n'))
+ lose = ((XFASTINT (XWINDOW (selected_window)->last_modified)
+ < MODIFF)
+ || (XFASTINT (XWINDOW (selected_window)->last_point)
+ != PT)
+ || MODIFF <= current_buffer->save_modified
+ || windows_or_buffers_changed
+ || !EQ (current_buffer->selective_display, Qnil)
+ || detect_input_pending ()
+ || !NILP (Vexecuting_macro));
+ value = internal_self_insert (c, 0);
+ if (value)
+ lose = 1;
+ if (value == 2)
+ nonundocount = 0;
+
+ if (!lose
+ && (PT == ZV || FETCH_CHAR (PT) == '\n'))
{
struct Lisp_Vector *dp
= window_display_table (XWINDOW (selected_window));
Lisp_Object obj;
obj = DISP_CHAR_VECTOR (dp, lose);
- if (XTYPE (obj) == Lisp_Vector
- && XVECTOR (obj)->size == 1
- && (XTYPE (obj = XVECTOR (obj)->contents[0])
- == Lisp_Int))
- no_redisplay =
- direct_output_for_insert (XINT (obj));
+ if (NILP (obj))
+ {
+ /* Do it only for char codes
+ that by default display as themselves. */
+ if (lose >= 0x20 && lose <= 0x7e)
+ no_redisplay = direct_output_for_insert (lose);
+ }
+ else if (VECTORP (obj)
+ && XVECTOR (obj)->size == 1
+ && (obj = XVECTOR (obj)->contents[0],
+ INTEGERP (obj))
+ /* Insist face not specified in glyph. */
+ && (XINT (obj) & ((-1) << 8)) == 0)
+ no_redisplay
+ = direct_output_for_insert (XINT (obj));
}
else
{
}
directly_done: ;
- if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
- safe_run_hooks (&Vpost_command_hook);
+ /* Note that the value cell will never directly contain nil
+ if the symbol is a local variable. */
+ if (!NILP (XSYMBOL (Qpost_command_hook)->value) && !NILP (Vrun_hooks))
+ safe_run_hooks (Qpost_command_hook);
+
+ if (!NILP (Vdeferred_action_list))
+ call0 (Vdeferred_action_function);
/* If there is a prefix argument,
1) We don't want last_command to be ``universal-argument''
to mysteriously evaporate. */
static void
safe_run_hooks (hook)
- Lisp_Object *hook;
+ Lisp_Object hook;
{
+ Lisp_Object value;
int count = specpdl_ptr - specpdl;
specbind (Qinhibit_quit, Qt);
- Vcommand_hook_internal = *hook;
- *hook = Qnil;
+ /* We read and set the variable with functions,
+ in case it's buffer-local. */
+ value = Vcommand_hook_internal = Fsymbol_value (hook);
+ Fset (hook, Qnil);
call1 (Vrun_hooks, Qcommand_hook_internal);
- *hook = Vcommand_hook_internal;
+ Fset (hook, value);
unbind_to (count, Qnil);
}
/* Nonzero means polling for input is temporarily suppressed. */
int poll_suppress_count;
-#ifdef POLL_FOR_INPUT
+/* Nonzero if polling_for_input is actually being used. */
int polling_for_input;
+#ifdef POLL_FOR_INPUT
+
/* Handle an alarm once each second and read pending input
so as to handle a C-g if it comces in. */
#endif
}
+/* Nonzero if we are using polling to handle input asynchronously. */
+
+int
+input_polling_used ()
+{
+#ifdef POLL_FOR_INPUT
+ return read_socket_hook && !interrupt_input;
+#else
+ return 0;
+#endif
+}
+
/* Turn off polling. */
stop_polling ()
Lisp_Object print_help ();
static Lisp_Object kbd_buffer_get_event ();
+static void record_char ();
/* read a character from the keyboard; call the redisplay if needed */
/* commandflag 0 means do not do auto-saving, but do do redisplay.
register Lisp_Object c;
int count;
jmp_buf save_jump;
+ int key_already_recorded = 0;
+ Lisp_Object also_record;
+ also_record = Qnil;
if (CONSP (Vunread_command_events))
{
if (unread_command_char != -1)
{
- XSET (c, Lisp_Int, unread_command_char);
+ XSETINT (c, unread_command_char);
unread_command_char = -1;
if (this_command_key_count == 0)
if (EQ (Vexecuting_macro, Qt)
|| executing_macro_index >= XFASTINT (Flength (Vexecuting_macro)))
{
- XSET (c, Lisp_Int, -1);
+ XSETINT (c, -1);
return c;
}
c = Faref (Vexecuting_macro, make_number (executing_macro_index));
- if (XTYPE (Vexecuting_macro) == Lisp_String
+ if (STRINGP (Vexecuting_macro)
&& (XINT (c) & 0x80))
- XFASTINT (c) = CHAR_META | (XINT (c) & ~0x80);
+ XSETFASTINT (c, CHAR_META | (XINT (c) & ~0x80));
executing_macro_index++;
if (_setjmp (getcjmp))
{
- XSET (c, Lisp_Int, quit_char);
+ XSETINT (c, quit_char);
#ifdef MULTI_FRAME
- XSET (internal_last_event_frame, Lisp_Frame, selected_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,
{
c = read_char_minibuf_menu_prompt (commandflag, nmaps, maps);
if (! NILP (c))
- return c;
+ {
+ key_already_recorded = 1;
+ goto non_reread;
+ }
}
/* If in middle of key sequence and minibuffer not active,
/* Auto save if enough time goes by without input. */
if (commandflag != 0
&& num_nonmacro_input_chars > last_auto_save
- && XTYPE (Vauto_save_timeout) == Lisp_Int
+ && INTEGERP (Vauto_save_timeout)
&& XINT (Vauto_save_timeout) > 0)
{
Lisp_Object tem0;
if (!NILP (c))
break;
if (commandflag >= 0 && !input_pending && !detect_input_pending ())
- redisplay ();
+ {
+ prepare_menu_bars ();
+ redisplay ();
+ }
}
/* Terminate Emacs in batch mode if at eof. */
- if (noninteractive && XTYPE (c) == Lisp_Int && XINT (c) < 0)
+ if (noninteractive && INTEGERP (c) && XINT (c) < 0)
Fkill_emacs (make_number (1));
- if (XTYPE (c) == Lisp_Int)
+ if (INTEGERP (c))
{
/* Add in any extra modifiers, where appropriate. */
if ((extra_keyboard_modifiers & CHAR_CTL)
start_polling ();
- /* Don't wipe the echo area for a trivial event. */
- if (XTYPE (c) != Lisp_Buffer)
- echo_area_glyphs = 0;
+ /* Buffer switch events are only for internal wakeups
+ so don't show them to the user. */
+ if (BUFFERP (c))
+ return c;
+
+ if (key_already_recorded)
+ return c;
+
+ /* Wipe the echo area. */
+ echo_area_glyphs = 0;
/* Handle things that only apply to characters. */
- if (XTYPE (c) == Lisp_Int)
+ if (INTEGERP (c))
{
/* If kbd_buffer_get_event gave us an EOF, return that. */
if (XINT (c) == -1)
return c;
- if (XTYPE (Vkeyboard_translate_table) == Lisp_String
+ if (STRINGP (Vkeyboard_translate_table)
&& XSTRING (Vkeyboard_translate_table)->size > XFASTINT (c))
XSETINT (c, XSTRING (Vkeyboard_translate_table)->data[XFASTINT (c)]);
}
- total_keys++;
- XVECTOR (recent_keys)->contents[recent_keys_index] = c;
- if (++recent_keys_index >= NUM_RECENT_KEYS)
- recent_keys_index = 0;
-
- /* Write c to the dribble file. If c is a lispy event, write
- the event's symbol to the dribble file, in <brackets>. Bleaugh.
- If you, dear reader, have a better idea, you've got the source. :-) */
- if (dribble)
+ /* If this event is a mouse click in the menu bar,
+ return just menu-bar for now. Modify the mouse click event
+ so we won't do this twice, then queue it up. */
+ if (EVENT_HAS_PARAMETERS (c)
+ && CONSP (XCONS (c)->cdr)
+ && CONSP (EVENT_START (c))
+ && CONSP (XCONS (EVENT_START (c))->cdr))
{
- if (XTYPE (c) == Lisp_Int)
- putc (XINT (c), dribble);
- else
- {
- Lisp_Object dribblee;
+ Lisp_Object posn;
- /* If it's a structured event, take the event header. */
- dribblee = EVENT_HEAD (c);
+ posn = POSN_BUFFER_POSN (EVENT_START (c));
+ /* Handle menu-bar events:
+ insert the dummy prefix event `menu-bar'. */
+ if (EQ (posn, Qmenu_bar))
+ {
+ /* Change menu-bar to (menu-bar) as the event "position". */
+ POSN_BUFFER_POSN (EVENT_START (c)) = Fcons (posn, Qnil);
- if (XTYPE (dribblee) == Lisp_Symbol)
- {
- putc ('<', dribble);
- fwrite (XSYMBOL (dribblee)->name->data, sizeof (char),
- XSYMBOL (dribblee)->name->size,
- dribble);
- putc ('>', dribble);
- }
+ also_record = c;
+ Vunread_command_events = Fcons (c, Vunread_command_events);
+ c = posn;
}
-
- fflush (dribble);
}
- store_kbd_macro_char (c);
-
- num_nonmacro_input_chars++;
+ record_char (c);
+ if (! NILP (also_record))
+ record_char (also_record);
from_macro:
reread_first:
/* Don't echo mouse motion events. */
if (! (EVENT_HAS_PARAMETERS (c)
&& EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_movement)))
- echo_char (c);
+ {
+ echo_char (c);
+ if (! NILP (also_record))
+ echo_char (also_record);
+ }
/* Record this character as part of the current key. */
add_command_key (c);
+ if (! NILP (also_record))
+ add_command_key (also_record);
/* Re-reading in the middle of a command */
reread:
Fcurrent_window_configuration (Qnil));
tem0 = Feval (Vhelp_form);
- if (XTYPE (tem0) == Lisp_String)
+ if (STRINGP (tem0))
internal_with_output_to_temp_buffer ("*Help*", print_help, tem0);
cancel_echoing ();
do
c = read_char (0, 0, 0, Qnil, 0);
- while (XTYPE (c) == Lisp_Buffer);
+ while (BUFFERP (c));
/* Remove the help from the frame */
unbind_to (count, Qnil);
prepare_menu_bars ();
cancel_echoing ();
do
c = read_char (0, 0, 0, Qnil, 0);
- while (XTYPE (c) == Lisp_Buffer);
+ while (BUFFERP (c));
}
}
return c;
}
+/* Record the input event C in various ways. */
+
+static void
+record_char (c)
+ Lisp_Object c;
+{
+ total_keys++;
+ XVECTOR (recent_keys)->contents[recent_keys_index] = c;
+ if (++recent_keys_index >= NUM_RECENT_KEYS)
+ recent_keys_index = 0;
+
+ /* Write c to the dribble file. If c is a lispy event, write
+ the event's symbol to the dribble file, in <brackets>. Bleaugh.
+ If you, dear reader, have a better idea, you've got the source. :-) */
+ if (dribble)
+ {
+ if (INTEGERP (c))
+ {
+ if (XUINT (c) < 0x100)
+ putc (XINT (c), dribble);
+ else
+ fprintf (dribble, " 0x%x", XUINT (c));
+ }
+ else
+ {
+ Lisp_Object dribblee;
+
+ /* If it's a structured event, take the event header. */
+ dribblee = EVENT_HEAD (c);
+
+ if (SYMBOLP (dribblee))
+ {
+ putc ('<', dribble);
+ fwrite (XSYMBOL (dribblee)->name->data, sizeof (char),
+ XSYMBOL (dribblee)->name->size,
+ dribble);
+ putc ('>', dribble);
+ }
+ }
+
+ fflush (dribble);
+ }
+
+ store_kbd_macro_char (c);
+
+ num_nonmacro_input_chars++;
+}
+
Lisp_Object
print_help (object)
Lisp_Object object;
{
+ struct buffer *old = current_buffer;
Fprinc (object, Qnil);
+ set_buffer_internal (XBUFFER (Vstandard_output));
+ call0 (intern ("help-mode"));
+ set_buffer_internal (old);
return Qnil;
}
}
\f
+#ifdef HAVE_MOUSE
+
/* Restore mouse tracking enablement. See Ftrack_mouse for the only use
of this function. */
+
static Lisp_Object
tracking_off (old_value)
Lisp_Object old_value;
{
if (! XFASTINT (old_value))
{
- do_mouse_tracking = 0;
+ do_mouse_tracking = Qnil;
/* Redisplay may have been preempted because there was input
available, and it assumes it will be called again after the
int count = specpdl_ptr - specpdl;
Lisp_Object val;
- XSET (val, Lisp_Int, do_mouse_tracking);
- record_unwind_protect (tracking_off, val);
+ record_unwind_protect (tracking_off, do_mouse_tracking);
if (!input_pending && !detect_input_pending ())
prepare_menu_bars ();
- do_mouse_tracking = 1;
+ XSETFRAME (do_mouse_tracking, selected_frame);
val = Fprogn (args);
return unbind_to (count, val);
}
+
+#endif /* HAVE_MOUSE */
\f
/* Low level keyboard/mouse input.
kbd_buffer_store_event places events in kbd_buffer, and
if (noninteractive)
{
c = getchar ();
- XSET (obj, Lisp_Int, c);
+ XSETINT (obj, c);
return obj;
}
{
Lisp_Object minus_one;
- XSET (minus_one, Lisp_Int, -1);
+ XSETINT (minus_one, -1);
wait_reading_process_input (0, 0, minus_one, 1);
if (!interrupt_input && EVENT_QUEUES_EMPTY)
#ifdef HAVE_X11
else if (event->kind == delete_window_event)
{
- Lisp_Object tail, frame;
- struct frame *f;
-
- /* If the user destroys the only frame, Emacs should exit.
- Count visible frames and iconified frames. */
- for (tail = Vframe_list; CONSP (tail); tail = XCONS (tail)->cdr)
- {
- frame = XCONS (tail)->car;
- if (XTYPE (frame) != Lisp_Frame || EQ (frame, event->frame_or_window))
- continue;
- f = XFRAME (frame);
- if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
- break;
- }
-
- if (! CONSP (tail))
- Fkill_emacs (Qnil);
-
- Fdelete_frame (event->frame_or_window, Qt);
+ /* Make an event (delete-frame (FRAME)). */
+ obj = Fcons (event->frame_or_window, Qnil);
+ obj = Fcons (Qdelete_frame, Fcons (obj, Qnil));
+ kbd_fetch_ptr = event + 1;
+ }
+ else if (event->kind == iconify_event)
+ {
+ /* Make an event (iconify-frame (FRAME)). */
+ obj = Fcons (event->frame_or_window, Qnil);
+ obj = Fcons (Qiconify_frame, Fcons (obj, Qnil));
+ kbd_fetch_ptr = event + 1;
+ }
+ else if (event->kind == deiconify_event)
+ {
+ /* Make an event (make-frame-visible (FRAME)). */
+ obj = Fcons (event->frame_or_window, Qnil);
+ obj = Fcons (Qmake_frame_visible, Fcons (obj, Qnil));
kbd_fetch_ptr = event + 1;
}
#endif
else if (event->kind == buffer_switch_event)
{
/* The value doesn't matter here; only the type is tested. */
- XSET (obj, Lisp_Buffer, current_buffer);
+ XSETBUFFER (obj, current_buffer);
kbd_fetch_ptr = event + 1;
}
/* Just discard these, by returning nil.
Lisp_Object focus;
frame = event->frame_or_window;
- if (XTYPE (frame) == Lisp_Window)
+ if (WINDOWP (frame))
frame = WINDOW_FRAME (XWINDOW (frame));
focus = FRAME_FOCUS_FRAME (XFRAME (frame));
}
}
}
+#ifdef HAVE_MOUSE
/* Try generating a mouse motion event. */
- else if (do_mouse_tracking && mouse_moved)
+ else if (FRAMEP (do_mouse_tracking) && mouse_moved)
{
- FRAME_PTR f = 0;
+ FRAME_PTR f = XFRAME (do_mouse_tracking);
Lisp_Object bar_window;
enum scroll_bar_part part;
Lisp_Object x, y;
unsigned long time;
+ /* Note that this uses F to determine which display to look at.
+ If there is no valid info, it does not store anything
+ so x remains nil. */
+ x = Qnil;
(*mouse_position_hook) (&f, &bar_window, &part, &x, &y, &time);
obj = Qnil;
/* Decide if we should generate a switch-frame event. Don't
generate switch-frame events for motion outside of all Emacs
frames. */
- if (f)
+ if (!NILP (x) && f)
{
Lisp_Object frame;
frame = FRAME_FOCUS_FRAME (f);
if (NILP (frame))
- XSET (frame, Lisp_Frame, f);
+ XSETFRAME (frame, f);
if (! EQ (frame, internal_last_event_frame)
&& XFRAME (frame) != selected_frame)
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. */
- if (NILP (obj))
+ if (!NILP (x) && NILP (obj))
obj = make_lispy_movement (f, bar_window, part, x, y, time);
-#endif
}
+#endif /* HAVE_MOUSE */
else
/* We were promised by the above while loop that there was
something for us to read! */
/* A simple keystroke. */
case ascii_keystroke:
{
+ Lisp_Object lispy_c;
int c = event->code & 0377;
/* Turn ASCII characters into control characters
when proper. */
& (meta_modifier | alt_modifier
| hyper_modifier | super_modifier));
button_down_time = 0;
- return c;
+ XSETFASTINT (lispy_c, c);
+ return lispy_c;
}
/* A function key. The symbol may need to have modifier prefixes
/ sizeof (lispy_function_keys[0])));
break;
-#if defined(MULTI_FRAME) || defined(HAVE_MOUSE)
+#if defined (MULTI_FRAME) || defined (HAVE_MOUSE)
/* A mouse click. Figure out where it is, decide whether it's
a press, click or drag, and build the appropriate structure. */
case mouse_click:
#endif
{
Lisp_Object items, item;
-
-#ifdef USE_X_TOOLKIT
- /* The click happened in the menubar.
- Look for the menu item selected. */
- item = map_event_to_object (event, f);
-
- XFASTINT (event->y) = 1;
-#else /* not USE_X_TOOLKIT */
int hpos;
int i;
+ /* Activate the menu bar on the down event. If the
+ up event comes in before the menu code can deal with it,
+ just ignore it. */
+ if (! (event->modifiers & down_modifier))
+ return Qnil;
+
+#ifndef USE_X_TOOLKIT
item = Qnil;
items = FRAME_MENU_BAR_ITEMS (f);
for (i = 0; i < XVECTOR (items)->size; i += 3)
window = window_from_coordinates (f, column, row, &part);
- if (XTYPE (window) != Lisp_Window)
- posn = Qnil;
+ if (!WINDOWP (window))
+ {
+ window = event->frame_or_window;
+ posn = Qnil;
+ }
else
{
int pixcolumn, pixrow;
else if (part == 2)
posn = Qvertical_line;
else
- XSET (posn, Lisp_Int,
- buffer_posn_from_coords (XWINDOW (window),
- column, row));
+ XSETINT (posn,
+ buffer_posn_from_coords (XWINDOW (window),
+ column, row));
}
position
of the button that chose the menu item
as a separate event. */
- if (XTYPE (start_pos) != Lisp_Cons)
+ if (!CONSP (start_pos))
return Qnil;
event->modifiers &= ~up_modifier;
#if 0 /* Formerly we treated an up with no down as a click event. */
- if (XTYPE (start_pos) != Lisp_Cons)
+ if (!CONSP (start_pos))
event->modifiers |= click_modifier;
else
#endif
if (EQ (event->x, XCONS (down)->car)
&& EQ (event->y, XCONS (down)->cdr))
{
- if (is_double && double_click_count > 1)
- event->modifiers |= ((double_click_count > 2)
- ? triple_modifier
- : double_modifier);
- else
- event->modifiers |= click_modifier;
+ event->modifiers |= click_modifier;
}
else
{
button_down_time = 0;
event->modifiers |= drag_modifier;
}
+ /* Don't check is_double; treat this as multiple
+ if the down-event was multiple. */
+ if (double_click_count > 1)
+ event->modifiers |= ((double_click_count > 2)
+ ? triple_modifier
+ : double_modifier);
}
}
else
}
}
-#ifdef MULTI_FRAME
+#if defined (MULTI_FRAME) || defined (HAVE_MOUSE)
static Lisp_Object
make_lispy_movement (frame, bar_window, part, x, y, time)
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, 0, 1);
else
window = Qnil;
- if (XTYPE (window) == Lisp_Window)
+ if (WINDOWP (window))
{
int pixcolumn, pixrow;
column -= XINT (XWINDOW (window)->left);
else if (area == 2)
posn = Qvertical_line;
else
- XSET (posn, Lisp_Int,
- buffer_posn_from_coords (XWINDOW (window), column, row));
+ XSETINT (posn,
+ buffer_posn_from_coords (XWINDOW (window), column, row));
}
+#ifdef MULTI_FRAME
else if (frame != 0)
{
- XSET (window, Lisp_Frame, frame);
+ XSETFRAME (window, frame);
posn = Qnil;
}
+#endif
else
{
window = Qnil;
posn = Qnil;
- XFASTINT (x) = 0;
- XFASTINT (y) = 0;
+ XSETFASTINT (x, 0);
+ XSETFASTINT (y, 0);
}
return Fcons (Qmouse_movement,
}
}
-#endif /* MULTI_FRAME */
+#endif /* neither MULTI_FRAME nor HAVE_MOUSE */
/* Construct a switch frame event. */
static Lisp_Object
if (modifiers & ~((1<<VALBITS) - 1))
abort ();
- XFASTINT (mask) = modifiers;
+ XSETFASTINT (mask, modifiers);
elements = Fcons (unmodified, Fcons (mask, Qnil));
/* Cache the parsing results on SYMBOL. */
/* The click modifier never figures into cache indices. */
cache = Fget (base, Qmodifier_cache);
- XFASTINT (index) = (modifiers & ~click_modifier);
- entry = Fassq (index, cache);
+ XSETFASTINT (index, (modifiers & ~click_modifier));
+ entry = assq_no_quit (index, cache);
if (CONSP (entry))
new_symbol = XCONS (entry)->cdr;
Fput (base, Qmodifier_cache, Fcons (entry, cache));
/* We have the parsing info now for free, so add it to the caches. */
- XFASTINT (index) = modifiers;
+ XSETFASTINT (index, modifiers);
Fput (new_symbol, Qevent_symbol_element_mask,
Fcons (base, Fcons (index, Qnil)));
Fput (new_symbol, Qevent_symbol_elements,
Lisp_Object value;
Lisp_Object symbol_int;
- XSET (symbol_int, Lisp_Int, symbol_num);
+ XSETINT (symbol_int, symbol_num);
/* Is this a request for a valid symbol? */
if (symbol_num < 0 || symbol_num >= table_size)
- abort ();
+ return Qnil;
if (CONSP (*symbol_table))
value = Fcdr (assq_no_quit (symbol_int, *symbol_table));
{
Lisp_Object size;
- XFASTINT (size) = table_size;
+ XSETFASTINT (size, table_size);
*symbol_table = Fmake_vector (size, Qnil);
}
*addr = !NILP (Vquit_flag) || readable_events ();
}
-/* Interface to read_avail_input, blocking SIGIO if necessary. */
+/* Interface to read_avail_input, blocking SIGIO or SIGALRM if necessary. */
int
gobble_input (expected)
sigsetmask (mask);
}
else
+#ifdef POLL_FOR_INPUT
+ if (read_socket_hook && !interrupt_input && poll_suppress_count == 0)
+ {
+ SIGMASKTYPE mask;
+ mask = sigblockx (SIGALRM);
+ read_avail_input (expected);
+ sigsetmask (mask);
+ }
+ else
+#endif
#endif
read_avail_input (expected);
#endif
record_asynch_buffer_change ()
{
struct input_event event;
+ Lisp_Object tem;
+
event.kind = buffer_switch_event;
event.frame_or_window = Qnil;
+#ifdef subprocesses
+ /* We don't need a buffer-switch event unless Emacs is waiting for input.
+ The purpose of the event is to make read_key_sequence look up the
+ keymaps again. If we aren't in read_key_sequence, we don't need one,
+ and the event could cause trouble by messing up (input-pending-p). */
+ tem = Fwaiting_for_user_input_p ();
+ if (NILP (tem))
+ return;
+#else
+ /* We never need these events if we have no asynchronous subprocesses. */
+ return;
+#endif
+
/* Make sure no interrupt happens while storing the event. */
#ifdef SIGIO
if (interrupt_input)
if (read_socket_hook)
/* No need for FIONREAD or fcntl; just say don't wait. */
- nread = (*read_socket_hook) (0, buf, KBD_BUFFER_SIZE, expected, expected);
+ nread = (*read_socket_hook) (input_fd, buf, KBD_BUFFER_SIZE,
+ expected, expected);
else
{
/* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
int n_to_read;
/* Determine how many characters we should *try* to read. */
+#ifdef WINDOWSNT
+ return 0;
+#else /* not WINDOWSNT */
#ifdef MSDOS
n_to_read = dos_keysns ();
if (n_to_read == 0)
#else /* not MSDOS */
#ifdef FIONREAD
/* Find out how much input is available. */
- if (ioctl (0, FIONREAD, &n_to_read) < 0)
+ if (ioctl (input_fd, FIONREAD, &n_to_read) < 0)
/* Formerly simply reported no input, but that sometimes led to
a failure of Emacs to terminate.
SIGHUP seems appropriate if we can't reach the terminal. */
#if defined(USG) || defined(DGUX)
/* Read some input if available, but don't wait. */
n_to_read = sizeof cbuf;
- fcntl (fileno (stdin), F_SETFL, O_NDELAY);
+ fcntl (input_fd, F_SETFL, O_NDELAY);
#else
you lose;
#endif
#endif
#endif /* not MSDOS */
+#endif /* not WINDOWSNT */
/* Now read; for one reason or another, this will not block.
NREAD is set to the number of chars read. */
cbuf[0] = dos_keyread();
nread = 1;
#else
- nread = read (fileno (stdin), cbuf, n_to_read);
+ nread = read (input_fd, cbuf, n_to_read);
#endif
#if defined (AIX) && (! defined (aix386) && defined (_BSD))
/* The kernel sometimes fails to deliver SIGHUP for ptys.
#ifndef FIONREAD
#if defined (USG) || defined (DGUX)
- fcntl (fileno (stdin), F_SETFL, 0);
+ fcntl (input_fd, F_SETFL, 0);
#endif /* USG or DGUX */
#endif /* no FIONREAD */
for (i = 0; i < nread; i++)
buf[i].modifiers = meta_modifier;
if (meta_key != 2)
cbuf[i] &= ~0x80;
-
- XSET (buf[i].code, Lisp_Int, cbuf[i]);
+
+ buf[i].code = cbuf[i];
#ifdef MULTI_FRAME
- XSET (buf[i].frame_or_window, Lisp_Frame, selected_frame);
+ XSETFRAME (buf[i].frame_or_window, selected_frame);
#else
buf[i].frame_or_window = Qnil;
#endif
/* 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
- && XINT(buf[i].code) == quit_char)
+ && buf[i].code == quit_char)
break;
}
{
register Lisp_Object tem;
tem = Fcar (map);
- if (XTYPE (tem) == Lisp_String)
+ if (STRINGP (tem))
return tem;
map = Fcdr (map);
}
menu_bar_items and its subroutines, and the current index
for storing into that vector. */
static Lisp_Object menu_bar_items_vector;
-static Lisp_Object menu_bar_items_index;
+static int menu_bar_items_index;
/* Return a vector of menu items for a menu bar, appropriate
to the current buffer. Each item has three elements in the vector:
{
Lisp_Object *tmaps;
- if (!NILP (Voverriding_local_map))
+ /* Should overriding-local-map apply, here? */
+ if (!NILP (Voverriding_local_map_menu_flag))
{
- nmaps = 2;
- maps = (Lisp_Object *) alloca (nmaps * sizeof (maps[0]));
- maps[0] = Voverriding_local_map;
+ if (NILP (Voverriding_local_map))
+ {
+ /* Yes, and it is nil. Use just global map. */
+ nmaps = 1;
+ maps = (Lisp_Object *) alloca (nmaps * sizeof (maps[0]));
+ }
+ else
+ {
+ /* Yes, and it is non-nil. Use it and the global map. */
+ nmaps = 2;
+ maps = (Lisp_Object *) alloca (nmaps * sizeof (maps[0]));
+ maps[0] = Voverriding_local_map;
+ }
}
else
{
+ /* No, so use major and minor mode keymaps. */
nmaps = current_minor_maps (0, &tmaps) + 2;
maps = (Lisp_Object *) alloca (nmaps * sizeof (maps[0]));
bcopy (tmaps, maps, (nmaps - 2) * sizeof (maps[0]));
Lisp_Object tail, item, key, binding, item_string, table;
/* Loop over all keymap entries that have menu strings. */
- for (tail = keymap; XTYPE (tail) == Lisp_Cons; tail = XCONS (tail)->cdr)
+ for (tail = keymap; CONSP (tail); tail = XCONS (tail)->cdr)
{
item = XCONS (tail)->car;
- if (XTYPE (item) == Lisp_Cons)
+ if (CONSP (item))
{
key = XCONS (item)->car;
binding = XCONS (item)->cdr;
- if (XTYPE (binding) == Lisp_Cons)
+ if (CONSP (binding))
{
item_string = XCONS (binding)->car;
- if (XTYPE (item_string) == Lisp_String)
+ if (STRINGP (item_string))
menu_bar_item (key, item_string, Fcdr (binding));
}
else if (EQ (binding, Qundefined))
menu_bar_item (key, Qnil, binding);
}
- else if (XTYPE (item) == Lisp_Vector)
+ else if (VECTORP (item))
{
/* Loop over the char values represented in the vector. */
int len = XVECTOR (item)->size;
for (c = 0; c < len; c++)
{
Lisp_Object character;
- XFASTINT (character) = c;
+ XSETFASTINT (character, c);
binding = XVECTOR (item)->contents[c];
- if (XTYPE (binding) == Lisp_Cons)
+ if (CONSP (binding))
{
item_string = XCONS (binding)->car;
- if (XTYPE (item_string) == Lisp_String)
+ if (STRINGP (item_string))
menu_bar_item (key, item_string, Fcdr (binding));
}
else if (EQ (binding, Qundefined))
/* See if this entry is enabled. */
enabled = Qt;
- if (XTYPE (def) == Lisp_Symbol)
+ if (SYMBOLP (def))
{
/* No property, or nil, means enable.
Otherwise, enable if value is not nil. */
if (! menu_prompting)
return Qnil;
+ /* Optionally disregard all but the global map. */
+ if (inhibit_local_menu_bar_menus)
+ {
+ maps += (nmaps - 1);
+ nmaps = 1;
+ }
+
/* Get the menu name from the first map that has one (a prompt string). */
for (mapno = 0; mapno < nmaps; mapno++)
{
if (mapno >= nmaps)
return Qnil;
-#ifdef HAVE_X_WINDOWS
-#ifdef HAVE_X_MENU
+#if (defined (HAVE_X_WINDOWS) && defined (HAVE_X_MENU)) || defined (MSDOS)
/* If we got to this point via a mouse click,
use a real menu for mouse selection. */
if (EVENT_HAS_PARAMETERS (prev_event))
*used_mouse_menu = 1;
return value;
}
-#endif /* HAVE_X_MENU */
-#endif /* HAVE_X_WINDOWS */
+#endif /* (HAVE_X_WINDOWS && HAVE_X_MENU) || MSDOS */
return Qnil ;
}
else
elt = Fcar_safe (rest);
- if (idx < 0 && XTYPE (elt) == Lisp_Vector)
+ if (idx < 0 && VECTORP (elt))
{
/* If we found a dense table in the keymap,
advanced past it, but start scanning its contents. */
s = Fcar_safe (Fcdr_safe (elt)); /* alist */
else
s = Fcar_safe(elt); /* vector */
- if (XTYPE (s) != Lisp_String)
+ if (!STRINGP (s))
/* Ignore the element if it has no prompt string. */
;
/* If we have room for the prompt string, add it to this line.
defining_kbd_macro = 0 ;
do
obj = read_char (commandflag, 0, 0, Qnil, 0);
- while (XTYPE (obj) == Lisp_Buffer);
+ while (BUFFERP (obj));
defining_kbd_macro = orig_defn_macro ;
- if (XTYPE (obj) != Lisp_Int)
+ if (!INTEGERP (obj))
return obj;
else
ch = XINT (obj);
if (! EQ (obj, menu_prompt_more_char)
- && (XTYPE (menu_prompt_more_char) != Lisp_Int
+ && (!INTEGERP (menu_prompt_more_char)
|| ! EQ (obj, make_number (Ctl (XINT (menu_prompt_more_char))))))
{
if ( defining_kbd_macro )
CURRENT with non-prefix bindings for meta-prefix-char become nil in
NEXT.
- When KEY is not defined in any of the keymaps, if it is an upper
- case letter and there are bindings for the corresponding lower-case
- letter, return the bindings for the lower-case letter.
- We store 1 in *CASE_CONVERTED in this case.
- Otherwise, we don't change *CASE_CONVERTED.
-
If KEY has no bindings in any of the CURRENT maps, NEXT is left
unmodified.
NEXT may == CURRENT. */
static int
-follow_key (key, nmaps, current, defs, next, case_converted)
+follow_key (key, nmaps, current, defs, next)
Lisp_Object key;
Lisp_Object *current, *defs, *next;
int nmaps;
- int *case_converted;
{
int i, first_binding;
/* If KEY is a meta ASCII character, treat it like meta-prefix-char
followed by the corresponding non-meta character. */
- if (XTYPE (key) == Lisp_Int && (XINT (key) & CHAR_META))
+ if (INTEGERP (key) && (XINT (key) & CHAR_META))
{
for (i = 0; i < nmaps; i++)
if (! NILP (current[i]))
next[i] = Qnil;
current = next;
- XSET (key, Lisp_Int, XFASTINT (key) & ~CHAR_META);
+ XSETINT (key, XFASTINT (key) & ~CHAR_META);
}
first_binding = nmaps;
defs[i] = Qnil;
}
- /* When KEY is not defined in any of the keymaps, if it is an upper
- case letter and there are bindings for the corresponding
- lower-case letter, return the bindings for the lower-case letter. */
- if (first_binding == nmaps
- && XTYPE (key) == Lisp_Int
- && ((((XINT (key) & 0x3ffff)
- < XSTRING (current_buffer->downcase_table)->size)
- && UPPERCASEP (XINT (key) & 0x3ffff))
- || (XINT (key) & shift_modifier)))
- {
- if (XINT (key) & shift_modifier)
- XSETINT (key, XINT (key) & ~shift_modifier);
- else
- XSETINT (key, (DOWNCASE (XINT (key) & 0x3ffff)
- | (XINT (key) & ~0x3ffff)));
-
- first_binding = nmaps;
- for (i = nmaps - 1; i >= 0; i--)
- {
- if (! NILP (current[i]))
- {
- defs[i] = get_keyelt (access_keymap (current[i], key, 1, 0));
- if (! NILP (defs[i]))
- first_binding = i;
- }
- else
- defs[i] = Qnil;
- }
- if (first_binding != nmaps)
- *case_converted = 1;
- }
-
/* Given the set of bindings we've found, produce the next set of maps. */
if (first_binding < nmaps)
for (i = 0; i < nmaps; i++)
Lisp_Object first_event;
#endif
- struct buffer *starting_buffer;
+ /* Gets around Microsoft compiler limitations. */
+ int dummyFlag = 0;
- /* Nonzero if we found the binding for one of the chars
- in this key sequence by downcasing it. */
- int case_converted = 0;
+ struct buffer *starting_buffer;
/* Nonzero if we seem to have got the beginning of a binding
in function_key_map. */
int function_key_possible = 0;
+ int key_translation_possible = 0;
int junk;
{
if (!NILP (prompt))
echo_prompt (XSTRING (prompt)->data);
- else if (cursor_in_echo_area)
+ else if (cursor_in_echo_area && echo_keystrokes)
/* This doesn't put in a dash if the echo buffer is empty, so
you don't always see a dash hanging out in the minibuffer. */
echo_dash ();
replay_sequence:
starting_buffer = current_buffer;
- case_converted = 0;
function_key_possible = 0;
+ key_translation_possible = 0;
/* Build our list of keymaps.
If we recognize a function key and replace its escape sequence in
&& fkey_start < t
/* mock input is never part of a function key's sequence. */
&& mock_input <= fkey_start)
- || (first_binding >= nmaps
- && keytran_start < t
- /* mock input is never part of a function key's sequence. */
- && mock_input <= keytran_start)
+ || (keytran_start < t && key_translation_possible)
/* Don't return in the middle of a possible function key sequence,
if the only bindings we found were via case conversion.
Thus, if ESC O a has a function-key-map translation
and ESC o has a binding, don't return after ESC O,
so that we can translate ESC O plus the next character. */
- || (function_key_possible && case_converted))
+ )
{
Lisp_Object key;
int used_mouse_menu = 0;
{
key = keybuf[t];
add_command_key (key);
- echo_char (key);
+ if (echo_keystrokes)
+ echo_char (key);
}
/* If not, we should actually read a character. */
/* read_char returns -1 at the end of a macro.
Emacs 18 handles this by returning immediately with a
zero, so that's what we'll do. */
- if (XTYPE (key) == Lisp_Int && XINT (key) == -1)
+ if (INTEGERP (key) && XINT (key) == -1)
{
t = 0;
- goto done;
+ /* The Microsoft C compiler can't handle the goto that
+ would go here. */
+ dummyFlag = 1;
+ break;
}
/* If the current buffer has been changed from under us, the
keymap may have changed, so replay the sequence. */
- if (XTYPE (key) == Lisp_Buffer)
+ if (BUFFERP (key))
{
mock_input = t;
goto replay_sequence;
/* If we have a quit that was typed in another frame, and
quit_throw_to_read_char switched buffers,
replay to get the right keymap. */
- if (EQ (key, quit_char) && current_buffer != starting_buffer)
+ if (XINT (key) == quit_char && current_buffer != starting_buffer)
{
keybuf[t++] = key;
mock_input = t;
window = POSN_WINDOW (EVENT_START (key));
posn = POSN_BUFFER_POSN (EVENT_START (key));
- if (XTYPE (posn) == Lisp_Cons)
+ if (CONSP (posn))
{
/* We're looking at the second event of a
sequence which we expanded before. Set
not the current buffer. If we're at the
beginning of a key sequence, switch buffers. */
if (last_real_key_start == 0
- && XTYPE (window) == Lisp_Window
- && XTYPE (XWINDOW (window)->buffer) == Lisp_Buffer
+ && WINDOWP (window)
+ && BUFFERP (XWINDOW (window)->buffer)
&& XBUFFER (XWINDOW (window)->buffer) != current_buffer)
{
keybuf[t] = key;
set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
goto replay_sequence;
}
- else if (XTYPE (posn) == Lisp_Symbol)
+ else if (SYMBOLP (posn))
{
/* Expand mode-line and scroll-bar events into two events:
use posn as a fake prefix key. */
goto replay_key;
}
}
- else
+ else if (CONSP (XCONS (key)->cdr)
+ && CONSP (EVENT_START (key))
+ && CONSP (XCONS (EVENT_START (key))->cdr))
{
Lisp_Object posn;
mock_input = t + 2;
goto replay_sequence;
}
- else if (XTYPE (posn) == Lisp_Cons)
+ else if (CONSP (posn))
{
/* We're looking at the second event of a
sequence which we expanded before. Set
nmaps - first_binding,
submaps + first_binding,
defs + first_binding,
- submaps + first_binding,
- &case_converted)
+ submaps + first_binding)
+ first_binding);
/* If KEY wasn't bound, we'll try some fallbacks. */
read_key_sequence_cmd = Vprefix_help_command;
keybuf[t++] = key;
last_nonmenu_event = key;
- goto done;
+ /* The Microsoft C compiler can't handle the goto that
+ would go here. */
+ dummyFlag = 1;
}
- if (XTYPE (head) == Lisp_Symbol)
+ if (SYMBOLP (head))
{
Lisp_Object breakdown;
int modifiers;
Lisp_Object new_head, new_click;
if (modifiers & triple_modifier)
modifiers ^= (double_modifier | triple_modifier);
- else if (modifiers & (drag_modifier | double_modifier))
- modifiers &= ~(drag_modifier | double_modifier);
+ else if (modifiers & double_modifier)
+ modifiers &= ~double_modifier;
+ else if (modifiers & drag_modifier)
+ modifiers &= ~drag_modifier;
else
{
/* Dispose of this `down' event by simply jumping
nmaps - local_first_binding,
submaps + local_first_binding,
defs + local_first_binding,
- submaps + local_first_binding,
- &case_converted)
+ submaps + local_first_binding)
+ local_first_binding);
/* If that click is bound, go for it. */
off the end of it. We only want to scan real keyboard input
for function key sequences, so if mock_input says that we're
re-reading old events, don't examine it. */
- if ((first_binding >= nmaps || case_converted)
+ if (first_binding >= nmaps
&& t >= mock_input)
{
Lisp_Object fkey_next;
key = keybuf[fkey_end++];
/* Look up meta-characters by prefixing them
with meta_prefix_char. I hate this. */
- if (XTYPE (key) == Lisp_Int && XINT (key) & meta_modifier)
+ if (INTEGERP (key) && XINT (key) & meta_modifier)
{
fkey_next
= get_keymap_1
(get_keyelt
(access_keymap (fkey_map, meta_prefix_char, 1, 0)),
0, 1);
- XFASTINT (key) = XFASTINT (key) & ~meta_modifier;
+ XSETFASTINT (key, XFASTINT (key) & ~meta_modifier);
}
else
fkey_next = fkey_map;
fkey_next
= get_keyelt (access_keymap (fkey_next, key, 1, 0));
+#if 0 /* I didn't turn this on, because it might cause trouble
+ for the mapping of return into C-m and tab into C-i. */
+ /* Optionally don't map function keys into other things.
+ This enables the user to redefine kp- keys easily. */
+ if (SYMBOLP (key) && !NILP (Vinhibit_function_key_mapping))
+ fkey_next = Qnil;
+#endif
+
/* If the function key map gives a function, not an
array, then call the function with no args and use
its value instead. */
int i;
for (i = 0; i < len; i++)
- XFASTINT (keybuf[fkey_start + i])
- = XSTRING (fkey_next)->data[i];
+ XSETFASTINT (keybuf[fkey_start + i],
+ XSTRING (fkey_next)->data[i]);
}
mock_input = t;
fkey_start = fkey_end = t;
fkey_map = Vfunction_key_map;
+ /* Do pass the results through key-translation-map. */
+ keytran_start = keytran_end = 0;
+ keytran_map = Vkey_translation_map;
+
goto replay_sequence;
}
key = keybuf[keytran_end++];
/* Look up meta-characters by prefixing them
with meta_prefix_char. I hate this. */
- if (XTYPE (key) == Lisp_Int && XINT (key) & meta_modifier)
+ if (INTEGERP (key) && XINT (key) & meta_modifier)
{
keytran_next
= get_keymap_1
(get_keyelt
(access_keymap (keytran_map, meta_prefix_char, 1, 0)),
0, 1);
- XFASTINT (key) = XFASTINT (key) & ~meta_modifier;
+ XSETFASTINT (key, XFASTINT (key) & ~meta_modifier);
}
else
keytran_next = keytran_map;
error ("Function in key-translation-map returns invalid key sequence");
}
+ key_translation_possible = ! NILP (keytran_next);
+
/* If keybuf[keytran_start..keytran_end] is bound in the
key translation map and it's a suffix of the current
sequence (i.e. keytran_end == t), replace it with
int i;
for (i = 0; i < len; i++)
- XFASTINT (keybuf[keytran_start + i])
- = XSTRING (keytran_next)->data[i];
+ XSETFASTINT (keybuf[keytran_start + i],
+ XSTRING (keytran_next)->data[i]);
}
mock_input = t;
keytran_start = keytran_end = t;
keytran_map = Vkey_translation_map;
+ /* Don't pass the results of key-translation-map
+ through function-key-map. */
+ fkey_start = fkey_end = t;
+ fkey_map = Vkey_translation_map;
+
goto replay_sequence;
}
{
keytran_end = ++keytran_start;
keytran_map = Vkey_translation_map;
+ key_translation_possible = 0;
}
}
}
+
+ /* If KEY is not defined in any of the keymaps,
+ and cannot be part of a function key or translation,
+ and is an upper case letter
+ use the corresponding lower-case letter instead. */
+ if (first_binding == nmaps && ! function_key_possible
+ && ! key_translation_possible
+ && INTEGERP (key)
+ && ((((XINT (key) & 0x3ffff)
+ < XSTRING (current_buffer->downcase_table)->size)
+ && UPPERCASEP (XINT (key) & 0x3ffff))
+ || (XINT (key) & shift_modifier)))
+ {
+ if (XINT (key) & shift_modifier)
+ XSETINT (key, XINT (key) & ~shift_modifier);
+ else
+ XSETINT (key, (DOWNCASE (XINT (key) & 0x3ffff)
+ | (XINT (key) & ~0x3ffff)));
+
+ keybuf[t - 1] = key;
+ mock_input = t;
+ goto replay_sequence;
+ }
}
- read_key_sequence_cmd = (first_binding < nmaps
- ? defs[first_binding]
- : Qnil);
+ if (!dummyFlag)
+ read_key_sequence_cmd = (first_binding < nmaps
+ ? defs[first_binding]
+ : Qnil);
- done:
unread_switch_frame = delayed_switch_frame;
unbind_to (count, Qnil);
Better ideas? */
for (; t < mock_input; t++)
{
- echo_char (keybuf[t]);
+ if (echo_keystrokes)
+ echo_char (keybuf[t]);
add_command_key (keybuf[t]);
}
Vcurrent_prefix_arg = prefixarg;
debug_on_next_call = 0;
- if (XTYPE (cmd) == Lisp_Symbol)
+ if (SYMBOLP (cmd))
{
tem = Fget (cmd, Qdisabled);
if (!NILP (tem) && !NILP (Vrun_hooks))
break;
}
- if (XTYPE (final) == Lisp_String
- || XTYPE (final) == Lisp_Vector)
+ if (STRINGP (final) || VECTORP (final))
{
/* If requested, place the macro in the command history. For
other sorts of commands, call-interactively takes care of
return Fexecute_kbd_macro (final, prefixarg);
}
- if (CONSP (final) || XTYPE (final) == Lisp_Subr
- || XTYPE (final) == Lisp_Compiled)
+ if (CONSP (final) || SUBRP (final) || COMPILEDP (final))
{
backtrace.next = backtrace_list;
backtrace_list = &backtrace;
strcpy (buf, "- ");
else if (CONSP (prefixarg) && XINT (XCONS (prefixarg)->car) == 4)
strcpy (buf, "C-u ");
- else if (CONSP (prefixarg) && XTYPE (XCONS (prefixarg)->car) == Lisp_Int)
+ else if (CONSP (prefixarg) && INTEGERP (XCONS (prefixarg)->car))
sprintf (buf, "%d ", XINT (XCONS (prefixarg)->car));
- else if (XTYPE (prefixarg) == Lisp_Int)
+ else if (INTEGERP (prefixarg))
sprintf (buf, "%d ", XINT (prefixarg));
/* This isn't strictly correct if execute-extended-command
str = XSTRING (function);
for (i = 0; i < str->size; i++)
{
- XFASTINT (tem) = str->data[i];
+ XSETFASTINT (tem, str->data[i]);
add_command_key (tem);
}
- XFASTINT (tem) = '\015';
+ XSETFASTINT (tem, '\015');
add_command_key (tem);
}
()
{
Lisp_Object temp;
- XFASTINT (temp) = command_loop_level + minibuf_level;
+ XSETFASTINT (temp, command_loop_level + minibuf_level);
return temp;
}
If optional arg STUFFSTRING is non-nil, its characters are stuffed\n\
to be read as terminal input by Emacs's parent, after suspension.\n\
\n\
-Before suspending, call the functions in `suspend-hook' with no args.\n\
-If any of them returns nil, don't call the rest and don't suspend.\n\
-Otherwise, suspend normally and after resumption run the normal hook\n\
-`suspend-resume-hook' if that is bound and non-nil.\n\
+Before suspending, run the normal hook `suspend-hook'.\n\
+After resumption run the normal hook `suspend-resume-hook'.\n\
\n\
Some operating systems cannot stop the Emacs process and resume it later.\n\
On such systems, Emacs starts a subshell instead of suspending.")
/* stuff_char works only in BSD, versions 4.2 and up. */
#ifdef BSD
#ifndef BSD4_1
- if (XTYPE (stuffstring) == Lisp_String)
+ if (STRINGP (stuffstring))
{
register int count;
int old_errno = errno;
#ifdef USG
- /* USG systems forget handlers when they are used;
- must reestablish each time */
- signal (SIGINT, interrupt_signal);
- signal (SIGQUIT, interrupt_signal);
+ if (!read_socket_hook && NILP (Vwindow_system))
+ {
+ /* USG systems forget handlers when they are used;
+ must reestablish each time */
+ signal (SIGINT, interrupt_signal);
+ signal (SIGQUIT, interrupt_signal);
+ }
#endif /* USG */
cancel_echoing ();
abort ();
#endif
#ifdef MULTI_FRAME
- if (XTYPE (internal_last_event_frame) == Lisp_Frame
+ if (FRAMEP (internal_last_event_frame)
&& XFRAME (internal_last_event_frame) != selected_frame)
Fhandle_switch_frame (make_lispy_switch_frame (internal_last_event_frame));
#endif
Lisp_Object interrupt, flow, meta, quit;
{
if (!NILP (quit)
- && (XTYPE (quit) != Lisp_Int
- || XINT (quit) < 0 || XINT (quit) > 0400))
+ && (!INTEGERP (quit) || XINT (quit) < 0 || XINT (quit) > 0400))
error ("set-input-mode: QUIT must be an ASCII character");
#ifdef POLL_FOR_INPUT
val[0] = interrupt_input ? Qt : Qnil;
val[1] = flow_control ? Qt : Qnil;
val[2] = meta_key == 2 ? make_number (0) : meta_key == 1 ? Qt : Qnil;
- XFASTINT (val[3]) = quit_char;
+ XSETFASTINT (val[3], quit_char);
return Flist (sizeof (val) / sizeof (val[0]), val);
}
recent_keys_index = 0;
kbd_fetch_ptr = kbd_buffer;
kbd_store_ptr = kbd_buffer;
- do_mouse_tracking = 0;
+#ifdef HAVE_MOUSE
+ do_mouse_tracking = Qnil;
+#endif
input_pending = 0;
#ifdef MULTI_FRAME
if (initialized)
Ffillarray (kbd_buffer_frame_or_window, Qnil);
- if (!noninteractive)
+ if (!noninteractive && !read_socket_hook && NILP (Vwindow_system))
{
signal (SIGINT, interrupt_signal);
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
SIGQUIT and we can't tell which one it will give us. */
signal (SIGQUIT, interrupt_signal);
#endif /* HAVE_TERMIO */
+ }
/* Note SIGIO has been undef'd if FIONREAD is missing. */
#ifdef SIGIO
- signal (SIGIO, input_available_signal);
+ if (!noninteractive)
+ signal (SIGIO, input_available_signal);
#endif /* SIGIO */
- }
/* Use interrupt input by default, if it works and noninterrupt input
has deficiencies. */
&Qmouse_movement, "mouse-movement", &Qmouse_movement,
&Qscroll_bar_movement, "scroll-bar-movement", &Qmouse_movement,
&Qswitch_frame, "switch-frame", &Qswitch_frame,
+ &Qdelete_frame, "delete-frame", &Qdelete_frame,
+ &Qiconify_frame, "iconify-frame", &Qiconify_frame,
+ &Qmake_frame_visible, "make-frame-visible", &Qmake_frame_visible,
};
syms_of_keyboard ()
defsubr (&Sread_key_sequence);
defsubr (&Srecursive_edit);
+#ifdef HAVE_MOUSE
defsubr (&Strack_mouse);
+#endif
defsubr (&Sinput_pending_p);
defsubr (&Scommand_execute);
defsubr (&Srecent_keys);
DEFVAR_LISP ("last-command-char", &last_command_char,
"Last input event that was part of a command.");
- DEFVAR_LISP ("last-command-event", &last_command_char,
+ DEFVAR_LISP_NOPRO ("last-command-event", &last_command_char,
"Last input event that was part of a command.");
DEFVAR_LISP ("last-nonmenu-event", &last_nonmenu_event,
DEFVAR_LISP ("last-input-char", &last_input_char,
"Last input event.");
- DEFVAR_LISP ("last-input-event", &last_input_char,
+ DEFVAR_LISP_NOPRO ("last-input-event", &last_input_char,
"Last input event.");
DEFVAR_LISP ("unread-command-events", &Vunread_command_events,
DEFVAR_LISP ("meta-prefix-char", &meta_prefix_char,
"Meta-prefix character code. Meta-foo as command input\n\
turns into this character followed by foo.");
- XSET (meta_prefix_char, Lisp_Int, 033);
+ XSETINT (meta_prefix_char, 033);
DEFVAR_LISP ("last-command", &last_command,
"The last command executed. Normally a symbol with a function definition,\n\
Zero or nil means disable auto-saving due to idleness.\n\
After auto-saving due to this many seconds of idle time,\n\
Emacs also does a garbage collection if that seems to be warranted.");
- XFASTINT (Vauto_save_timeout) = 30;
+ XSETFASTINT (Vauto_save_timeout, 30);
DEFVAR_INT ("echo-keystrokes", &echo_keystrokes,
"*Nonzero means echo unfinished commands after this many seconds of pause.");
by position only.");
Vdouble_click_time = make_number (500);
+ DEFVAR_BOOL ("inhibit-local-menu-bar-menus", &inhibit_local_menu_bar_menus,
+ "*Non-nil means inhibit local map menu bar menus.");
+ inhibit_local_menu_bar_menus = 0;
+
DEFVAR_INT ("num-input-keys", &num_input_keys,
"*Number of complete keys read from the keyboard so far.");
num_input_keys = 0;
"Character to recognize as meaning Help.\n\
When it is read, do `(eval help-form)', and display result if it's a string.\n\
If the value of `help-form' is nil, this char can be read normally.");
- XSET (Vhelp_char, Lisp_Int, Ctl ('H'));
+ XSETINT (Vhelp_char, Ctl ('H'));
DEFVAR_LISP ("help-form", &Vhelp_form,
"Form to execute when character `help-char' is read.\n\
DEFVAR_LISP ("menu-prompt-more-char", &menu_prompt_more_char,
"Character to see next line of menu prompt.\n\
Type this character while in a menu prompt to rotate around the lines of it.");
- XSET (menu_prompt_more_char, Lisp_Int, ' ');
+ XSETINT (menu_prompt_more_char, ' ');
DEFVAR_INT ("extra-keyboard-modifiers", &extra_keyboard_modifiers,
"A mask of additional modifier keys to use with every keyboard character.\n\
buffer's local map, and the minor mode keymaps and text property keymaps.");
Voverriding_local_map = Qnil;
+ DEFVAR_LISP ("overriding-local-map-menu-flag", &Voverriding_local_map_menu_flag,
+ "Non-nil means `overriding-local-map' applies to the menu bar.\n\
+Otherwise, the menu bar continues to reflect the buffer's local map\n\
+and the minor mode maps regardless of `overriding-local-map'.");
+ Voverriding_local_map_menu_flag = Qnil;
+
+#ifdef HAVE_MOUSE
DEFVAR_BOOL ("track-mouse", &do_mouse_tracking,
"*Non-nil means generate motion events for mouse motion.");
+#endif
DEFVAR_LISP ("system-key-alist", &Vsystem_key_alist,
"Alist of system-specific X windows key symbols.\n\
Each element should have the form (N . SYMBOL) where N is the\n\
numeric keysym code (sans the \"system-specific\" bit 1<<28)\n\
and SYMBOL is its name.");
- Vmenu_bar_final_items = Qnil;
+ Vsystem_key_alist = Qnil;
+
+ DEFVAR_LISP ("deferred-action-list", &Vdeferred_action_list,
+ "List of deferred actions to be performed at a later time.\n\
+The precise format isn't relevant here; we just check whether it is nil.");
+ Vdeferred_action_list = Qnil;
+
+ DEFVAR_LISP ("deferred-action-function", &Vdeferred_action_function,
+ "Function to call to handle deferred actions, after each command.\n\
+This function is called with no arguments after each command\n\
+whenever `deferred-action-list' is non-nil.");
+ Vdeferred_action_function = Qnil;
}
keys_of_keyboard ()