/* Keyboard and mouse input; editor command loop.
Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995,
1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GNU Emacs.
during the current critical section. */
int interrupt_input_pending;
-
-#ifdef HAVE_WINDOW_SYSTEM
-/* Make all keyboard buffers much bigger when using X windows. */
-#ifdef MAC_OS8
-/* But not too big (local data > 32K error) if on Mac OS Classic. */
-#define KBD_BUFFER_SIZE 512
-#else
#define KBD_BUFFER_SIZE 4096
-#endif
-#else /* No X-windows, character input */
-#define KBD_BUFFER_SIZE 4096
-#endif /* No X-windows */
-
-/* Following definition copied from eval.c */
-
-struct backtrace
- {
- struct backtrace *next;
- Lisp_Object *function;
- Lisp_Object *args; /* Points to vector of args. */
- int nargs; /* length of vector. If nargs is UNEVALLED,
- args points to slot holding list of
- unevalled args */
- char evalargs;
- /* Nonzero means call value of debugger when done with this operation. */
- char debug_on_exit;
- };
#ifdef MULTI_KBOARD
KBOARD *initial_kboard;
extern int message_enable_multibyte;
-extern struct backtrace *backtrace_list;
-
/* If non-nil, the function that implements the display of help.
It's called with one argument, the help string to display. */
#ifdef MAC_OS
Lisp_Object Qmac_apple_event;
#endif
-
+#ifdef HAVE_DBUS
+Lisp_Object Qdbus_event;
+#endif
/* Lisp_Object Qmouse_movement; - also an event header */
/* Properties of event headers. */
int nonundocount;
Lisp_Object keybuf[30];
int i;
- int no_direct;
int prev_modiff = 0;
struct buffer *prev_buffer = NULL;
#if 0 /* This shouldn't be necessary anymore. --lorentey */
#ifdef MULTI_KBOARD
int was_locked = single_kboard;
#endif
-#endif
+#endif
int already_adjusted = 0;
current_kboard->Vprefix_arg = Qnil;
while (pending_malloc_warning)
display_malloc_warning ();
- no_direct = 0;
-
Vdeactivate_mark = Qnil;
/* If minibuffer on and echo area in use,
}
else
{
- if (NILP (current_kboard->Vprefix_arg) && ! no_direct)
+ if (NILP (current_kboard->Vprefix_arg))
{
/* In case we jump to directly_done. */
Vcurrent_prefix_arg = current_kboard->Vprefix_arg;
/* Save the upper bits here. */
int upper = c & ~0177;
+ if (! ASCII_BYTE_P (c))
+ return c |= ctrl_modifier;
+
c &= 0177;
/* Everything in the columns containing the upper-case letters
USED_MOUSE_MENU is null, we don't dereference it.
Value is -2 when we find input on another keyboard. A second call
- to read_char will read it.
+ to read_char will read it.
If END_TIME is non-null, it is a pointer to an EMACS_TIME
specifying the maximum time to wait until. If no input arrives by
/* if redisplay was requested */
if (commandflag >= 0)
{
+ int echo_current = EQ (echo_message_buffer, echo_area_buffer[0]);
+
/* If there is pending input, process any events which are not
user-visible, such as X selection_request events. */
if (input_pending
swallow_events (0);
/* If that cleared input_pending, try again to redisplay. */
}
+
+ /* Prevent the redisplay we just did
+ from messing up echoing of the input after the prompt. */
+ if (commandflag == 0 && echo_current)
+ echo_message_buffer = echo_area_buffer[0];
+
}
/* Message turns off echoing unless more keystrokes turn it on again.
int count = SPECPDL_INDEX ();
record_single_kboard_state ();
#endif
-
+
last_input_char = c;
Fcommand_execute (tem, Qnil, Fvector (1, &last_input_char), Qt);
events. */
if (CONSP (Vunread_command_events))
break;
-
+
if (kbd_fetch_ptr != kbd_store_ptr)
break;
#if defined (HAVE_MOUSE) || defined (HAVE_GPM)
internal_last_event_frame = frame;
kbd_fetch_ptr = event + 1;
}
+#ifdef HAVE_DBUS
+ else if (event->kind == DBUS_EVENT)
+ {
+ obj = make_lispy_event (event);
+ kbd_fetch_ptr = event + 1;
+ }
+#endif
else
{
/* If this event is on a different frame, return a switch-frame this
{
/* A simple keystroke. */
case ASCII_KEYSTROKE_EVENT:
- {
- Lisp_Object lispy_c;
- int c = event->code & 0377;
- /* Turn ASCII characters into control characters
- when proper. */
- if (event->modifiers & ctrl_modifier)
- c = make_ctrl_char (c);
-
- /* Add in the other modifier bits. We took care of ctrl_modifier
- just above, and the shift key was taken care of by the X code,
- and applied to control characters by make_ctrl_char. */
- c |= (event->modifiers
- & (meta_modifier | alt_modifier
- | hyper_modifier | super_modifier));
- /* Distinguish Shift-SPC from SPC. */
- if ((event->code & 0377) == 040
- && event->modifiers & shift_modifier)
- c |= shift_modifier;
- button_down_time = 0;
- XSETFASTINT (lispy_c, c);
- return lispy_c;
- }
-
case MULTIBYTE_CHAR_KEYSTROKE_EVENT:
{
Lisp_Object lispy_c;
int c = event->code;
+ if (event->kind == ASCII_KEYSTROKE_EVENT)
+ {
+ c &= 0377;
+ eassert (c == event->code);
+ /* Turn ASCII characters into control characters
+ when proper. */
+ if (event->modifiers & ctrl_modifier)
+ {
+ c = make_ctrl_char (c);
+ event->modifiers &= ~ctrl_modifier;
+ }
+ }
- /* Add in the other modifier bits. We took care of ctrl_modifier
- just above, and the shift key was taken care of by the X code,
- and applied to control characters by make_ctrl_char. */
+ /* Add in the other modifier bits. The shift key was taken care
+ of by the X code. */
c |= (event->modifiers
& (meta_modifier | alt_modifier
| hyper_modifier | super_modifier | ctrl_modifier));
- /* What about the `shift' modifier ? */
+ /* Distinguish Shift-SPC from SPC. */
+ if ((event->code) == 040
+ && event->modifiers & shift_modifier)
+ c |= shift_modifier;
button_down_time = 0;
XSETFASTINT (lispy_c, c);
return lispy_c;
}
#endif
+#ifdef HAVE_DBUS
+ case DBUS_EVENT:
+ {
+ return Fcons (Qdbus_event, event->arg);
+ }
+#endif /* HAVE_DBUS */
+
#ifdef HAVE_GPM
case GPM_CLICK_EVENT:
{
SYMBOL's Qevent_symbol_element_mask property, and maintains the
Qevent_symbol_elements property. */
+#define KEY_TO_CHAR(k) (XINT (k) & ((1 << CHARACTERBITS) - 1))
+
Lisp_Object
parse_modifiers (symbol)
Lisp_Object symbol;
{
Lisp_Object elements;
+ if (INTEGERP (symbol))
+ return (Fcons (make_number (KEY_TO_CHAR (symbol)),
+ Fcons (make_number (XINT (symbol) & CHAR_MODIFIER_MASK),
+ Qnil)));
+ else if (!SYMBOLP (symbol))
+ return Qnil;
+
elements = Fget (symbol, Qevent_symbol_element_mask);
if (CONSP (elements))
return elements;
/* Mask out upper bits. We don't know where this value's been. */
modifiers &= INTMASK;
+ if (INTEGERP (base))
+ return make_number (XINT (base) | modifiers);
+
/* The click modifier never figures into cache indices. */
cache = Fget (base, Qmodifier_cache);
XSETFASTINT (index, (modifiers & ~click_modifier));
gobble_input (expected)
int expected;
{
+#ifdef HAVE_DBUS
+ /* Check whether a D-Bus message has arrived. */
+ xd_read_queued_messages ();
+#endif /* HAVE_DBUS */
+
#ifndef VMS
#ifdef SIGIO
if (interrupt_input)
nread += nr;
expected = 0;
}
-
+
if (nr == -1) /* Not OK to read input now. */
{
err = 1;
else if (nr == -2) /* Non-transient error. */
{
/* The terminal device terminated; it should be closed. */
-
+
/* Kill Emacs if this was our last terminal. */
if (!terminal_list->next_terminal)
/* Formerly simply reported no input, but that
group? Perhaps on systems with FIONREAD Emacs is
alone in its group. */
kill (getpid (), SIGHUP);
-
+
/* XXX Is calling delete_terminal safe here? It calls Fdelete_frame. */
if (t->delete_terminal_hook)
(*t->delete_terminal_hook) (t);
if (n_to_read > sizeof cbuf)
n_to_read = sizeof cbuf;
#else /* no FIONREAD */
-#if defined (USG) || defined (DGUX) || 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);
);
#ifndef FIONREAD
-#if defined (USG) || defined (DGUX) || defined (CYGWIN)
+#if defined (USG) || defined (CYGWIN)
fcntl (fileno (tty->input), F_SETFL, 0);
-#endif /* USG or DGUX or CYGWIN */
+#endif /* USG or CYGWIN */
#endif /* no FIONREAD */
if (nread <= 0)
buf.modifiers = meta_modifier;
if (tty->meta_key != 2)
cbuf[i] &= ~0x80;
-
+
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. */
buf.frame_or_window = tty->top_frame;
buf.arg = Qnil;
-
+
kbd_buffer_store_event (&buf);
/* Don't look at input that follows a C-g too closely.
This reduces lossage due to autorepeat on C-g. */
tem = XCDR (cachelist);
if (newcache && !NILP (tem))
{
- tem = concat3 (build_string (" ("), tem, build_string (")"));
+ tem = concat2 (build_string (" "), tem);
+ // tem = concat3 (build_string (" ("), tem, build_string (")"));
XSETCDR (cachelist, tem);
}
last_nonmenu_event = Qnil;
delayed_switch_frame = Qnil;
-
+
if (INTERACTIVE)
{
if (!NILP (prompt))
}
GROW_RAW_KEYBUF;
- XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
+ ASET (raw_keybuf, raw_keybuf_count++, key);
}
/* Clicks in non-text areas get prefixed by the symbol
/* 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. */
+ and is an upper case letter or shifted key,
+ use the corresponding lower-case/unshifted key instead. */
if (first_binding >= nmaps
- && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t
- && INTEGERP (key)
- && ((((XINT (key) & 0x3ffff)
- < XCHAR_TABLE (current_buffer->downcase_table)->size)
- && UPPERCASEP (XINT (key) & 0x3ffff))
- || (XINT (key) & shift_modifier)))
- {
- Lisp_Object new_key;
-
- original_uppercase = key;
- original_uppercase_position = t - 1;
-
- if (XINT (key) & shift_modifier)
- XSETINT (new_key, XINT (key) & ~shift_modifier);
- else
- XSETINT (new_key, (DOWNCASE (XINT (key) & 0x3ffff)
- | (XINT (key) & ~0x3ffff)));
-
- /* We have to do this unconditionally, regardless of whether
- the lower-case char is defined in the keymaps, because they
- might get translated through function-key-map. */
- keybuf[t - 1] = new_key;
- mock_input = max (t, mock_input);
-
- goto replay_sequence;
- }
- /* If KEY is not defined in any of the keymaps,
- and cannot be part of a function key or translation,
- and is a shifted function key,
- use the corresponding unshifted function key instead. */
- if (first_binding >= nmaps
- && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t
- && SYMBOLP (key))
- {
- Lisp_Object breakdown;
- int modifiers;
-
- breakdown = parse_modifiers (key);
- modifiers = XINT (XCAR (XCDR (breakdown)));
- if (modifiers & shift_modifier)
+ && /* indec.start >= t && fkey.start >= t && */ keytran.start >= t)
+ {
+ Lisp_Object breakdown = parse_modifiers (key);
+ int modifiers
+ = CONSP (breakdown) ? (XINT (XCAR (XCDR (breakdown)))) : 0;
+
+ if (modifiers & shift_modifier
+ /* Treat uppercase keys as shifted. */
+ || (INTEGERP (key)
+ && (KEY_TO_CHAR (key)
+ < XCHAR_TABLE (current_buffer->downcase_table)->size)
+ && UPPERCASEP (KEY_TO_CHAR (key))))
{
- Lisp_Object new_key;
+ Lisp_Object new_key
+ = (modifiers & shift_modifier
+ ? apply_modifiers (modifiers & ~shift_modifier,
+ XCAR (breakdown))
+ : make_number (DOWNCASE (KEY_TO_CHAR (key)) | modifiers));
original_uppercase = key;
original_uppercase_position = t - 1;
- modifiers &= ~shift_modifier;
- new_key = apply_modifiers (modifiers,
- XCAR (breakdown));
-
+ /* We have to do this unconditionally, regardless of whether
+ the lower-case char is defined in the keymaps, because they
+ might get translated through function-key-map. */
keybuf[t - 1] = new_key;
mock_input = max (t, mock_input);
+ /* Reset fkey (and consequently keytran) to apply
+ function-key-map on the result, so that S-backspace is
+ correctly mapped to DEL (via backspace). OTOH,
+ input-decode-map doesn't need to go through it again. */
+ fkey.start = fkey.end = 0;
+ keytran.start = keytran.end = 0;
+
goto replay_sequence;
}
}
}
-
if (!dummyflag)
read_key_sequence_cmd = (first_binding < nmaps
? defs[first_binding]
register Lisp_Object final;
register Lisp_Object tem;
Lisp_Object prefixarg;
- struct backtrace backtrace;
extern int debug_on_next_call;
debug_on_next_call = 0;
}
if (CONSP (final) || SUBRP (final) || COMPILEDP (final))
- {
- backtrace.next = backtrace_list;
- backtrace_list = &backtrace;
- backtrace.function = &Qcall_interactively;
- backtrace.args = &cmd;
- backtrace.nargs = 1;
- backtrace.evalargs = 0;
- backtrace.debug_on_exit = 0;
+ /* Don't call Fcall_interactively directly because we want to make
+ sure the backtrace has an entry for `call-interactively'.
+ For the same reason, pass `cmd' rather than `final'. */
+ return call3 (Qcall_interactively, cmd, record_flag, keys);
- tem = Fcall_interactively (cmd, record_flag, keys);
-
- backtrace_list = backtrace.next;
- return tem;
- }
return Qnil;
}
bindings = Qnil;
value = Qnil;
- GCPRO2 (bindings, value);
+ GCPRO3 (bindings, value, function);
value = Fcommand_execute (function, Qt, Qnil, Qnil);
/* If the command has a key binding, print it now. */
new_interrupt_input = 1;
#endif
- if (new_interrupt_input != interrupt_input)
+ if (new_interrupt_input != interrupt_input)
{
#ifdef POLL_FOR_INPUT
stop_polling ();
struct terminal *t = get_terminal (terminal, 1);
struct tty_display_info *tty;
int new_meta;
-
+
if (t == NULL || t->type != output_termcap)
return Qnil;
tty = t->display_info.tty;
else
new_meta = 2;
- if (tty->meta_key != new_meta)
+ if (tty->meta_key != new_meta)
{
#ifndef DOS_NT
/* this causes startup screen to be restored and messes with the mouse */
#endif
tty->meta_key = new_meta;
-
+
#ifndef DOS_NT
init_sys_modes (tty);
#endif
/* this causes startup screen to be restored and messes with the mouse */
reset_sys_modes (tty);
#endif
-
+
/* Don't let this value be out of range. */
quit_char = XINT (quit) & (tty->meta_key == 0 ? 0177 : 0377);
return Qnil;
}
-
+
DEFUN ("set-input-mode", Fset_input_mode, Sset_input_mode, 3, 4, 0,
doc: /* Set mode of reading keyboard input.
First arg INTERRUPT non-nil means use input interrupts;
staticpro (&Qmac_apple_event);
#endif
+#ifdef HAVE_DBUS
+ Qdbus_event = intern ("dbus-event");
+ staticpro (&Qdbus_event);
+#endif
+
Qmenu_enable = intern ("menu-enable");
staticpro (&Qmenu_enable);
Qmenu_alias = intern ("menu-alias");
`local-function-key-map' binding and this variable, then the local
definition will take precendence. */);
Vfunction_key_map = Fmake_sparse_keymap (Qnil);
-
+
DEFVAR_LISP ("key-translation-map", &Vkey_translation_map,
doc: /* Keymap of key translations that can override keymaps.
This keymap works like `function-key-map', but comes after that,
/* Vwindow_system is left at t for now. */
initial_kboard->next_kboard = all_kboards;
all_kboards = initial_kboard;
-#endif
+#endif
}
void
* "handle-select-window"); */
initial_define_lispy_key (Vspecial_event_map, "save-session",
"handle-save-session");
+
+#ifdef HAVE_DBUS
+ /* Define a special event which is raised for dbus callback
+ functions. */
+ initial_define_lispy_key (Vspecial_event_map, "dbus-event",
+ "dbus-handle-event");
+#endif
}
/* Mark the pointers in the kboard objects.