do { if (polling_stopped_here) start_polling (); \
polling_stopped_here = 0; } while (0)
+static Lisp_Object
+read_event_from_main_queue (EMACS_TIME *end_time,
+ sys_jmp_buf local_getcjmp,
+ bool *used_mouse_menu)
+{
+ Lisp_Object c = Qnil;
+ sys_jmp_buf save_jump;
+ KBOARD *kb IF_LINT (= NULL);
+
+ start:
+
+ /* Read from the main queue, and if that gives us something we can't use yet,
+ we put it on the appropriate side queue and try again. */
+
+ if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
+ return c;
+
+ /* Actually read a character, waiting if necessary. */
+ save_getcjmp (save_jump);
+ restore_getcjmp (local_getcjmp);
+ if (!end_time)
+ timer_start_idle ();
+ c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
+ restore_getcjmp (save_jump);
+
+ if (! NILP (c) && (kb != current_kboard))
+ {
+ Lisp_Object last = KVAR (kb, kbd_queue);
+ if (CONSP (last))
+ {
+ while (CONSP (XCDR (last)))
+ last = XCDR (last);
+ if (!NILP (XCDR (last)))
+ emacs_abort ();
+ }
+ if (!CONSP (last))
+ kset_kbd_queue (kb, Fcons (c, Qnil));
+ else
+ XSETCDR (last, Fcons (c, Qnil));
+ kb->kbd_queue_has_data = 1;
+ c = Qnil;
+ if (single_kboard)
+ goto start;
+ current_kboard = kb;
+ /* This is going to exit from read_char
+ so we had better get rid of this frame's stuff. */
+ return make_number (-2);
+ }
+
+ /* Terminate Emacs in batch mode if at eof. */
+ if (noninteractive && INTEGERP (c) && XINT (c) < 0)
+ Fkill_emacs (make_number (1));
+
+ if (INTEGERP (c))
+ {
+ /* Add in any extra modifiers, where appropriate. */
+ if ((extra_keyboard_modifiers & CHAR_CTL)
+ || ((extra_keyboard_modifiers & 0177) < ' '
+ && (extra_keyboard_modifiers & 0177) != 0))
+ XSETINT (c, make_ctrl_char (XINT (c)));
+
+ /* Transfer any other modifier bits directly from
+ extra_keyboard_modifiers to c. Ignore the actual character code
+ in the low 16 bits of extra_keyboard_modifiers. */
+ XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
+ }
+
+ /* FIXME: Decode tty keyboard input here. */
+ return c;
+}
+
+
+
+/* Like `read_event_from_main_queue' but applies keyboard-coding-system
+ to tty input. */
+static Lisp_Object
+read_decoded_event_from_main_queue (EMACS_TIME *end_time,
+ sys_jmp_buf local_getcjmp,
+ Lisp_Object prev_event,
+ bool *used_mouse_menu)
+{
+#define MAX_ENCODED_BYTES 16
+ Lisp_Object events[MAX_ENCODED_BYTES];
+ int n = 0;
+ while (true)
+ {
+ Lisp_Object nextevt
+ = read_event_from_main_queue (end_time, local_getcjmp,
+ used_mouse_menu);
+#ifdef WINDOWSNT
+ /* w32_console already returns decoded events. */
+ return nextevt;
+#else
+ struct frame *frame = XFRAME (selected_frame);
+ struct terminal *terminal = frame->terminal;
+ if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
+ /* Don't apply decoding if we're just reading a raw event
+ (e.g. reading bytes sent by the xterm to specify the position
+ of a mouse click). */
+ && (!EQ (prev_event, Qt))
+ && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
+ & CODING_REQUIRE_DECODING_MASK)))
+ return nextevt; /* No decoding needed. */
+ else
+ {
+ int meta_key = terminal->display_info.tty->meta_key;
+ eassert (n < MAX_ENCODED_BYTES);
+ events[n++] = nextevt;
+ if (NATNUMP (nextevt)
+ && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
+ { /* An encoded byte sequence, let's try to decode it. */
+ struct coding_system *coding
+ = TERMINAL_KEYBOARD_CODING (terminal);
+ unsigned char *src = alloca (n);
+ int i;
+ for (i = 0; i < n; i++)
+ src[i] = XINT (events[i]);
+ if (meta_key != 2)
+ for (i = 0; i < n; i++)
+ src[i] &= ~0x80;
+ coding->destination = alloca (n * 4);
+ coding->dst_bytes = n * 4;
+ decode_coding_c_string (coding, src, n, Qnil);
+ eassert (coding->produced_char <= n);
+ if (coding->produced_char == 0)
+ { /* The encoded sequence is incomplete. */
+ if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */
+ continue; /* Read on! */
+ }
+ else
+ {
+ const unsigned char *p = coding->destination;
+ eassert (coding->carryover_bytes == 0);
+ n = 0;
+ while (n < coding->produced_char)
+ events[n++] = make_number (STRING_CHAR_ADVANCE (p));
+ }
+ }
+ /* Now `events' should hold decoded events.
+ Normally, n should be equal to 1, but better not rely on it.
+ We can only return one event here, so return the first we
+ had and keep the others (if any) for later. */
+ while (n > 1)
+ Vunread_command_events
+ = Fcons (events[--n], Vunread_command_events);
+ return events[0];
+ }
+#endif
+ }
+}
+
/* Read a character from the keyboard; call the redisplay if needed. */
/* commandflag 0 means do not autosave, but do redisplay.
-1 means do not redisplay, but do autosave.
STOP_POLLING;
- /* Finally, we read from the main queue,
- and if that gives us something we can't use yet, we put it on the
- appropriate side queue and try again. */
-
if (NILP (c))
{
- KBOARD *kb IF_LINT (= NULL);
-
+ c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
+ prev_event, used_mouse_menu);
if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
- goto exit;
-
- /* Actually read a character, waiting if necessary. */
- save_getcjmp (save_jump);
- restore_getcjmp (local_getcjmp);
- if (!end_time)
- timer_start_idle ();
- c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
- restore_getcjmp (save_jump);
-
- if (! NILP (c) && (kb != current_kboard))
- {
- Lisp_Object last = KVAR (kb, kbd_queue);
- if (CONSP (last))
- {
- while (CONSP (XCDR (last)))
- last = XCDR (last);
- if (!NILP (XCDR (last)))
- emacs_abort ();
- }
- if (!CONSP (last))
- kset_kbd_queue (kb, Fcons (c, Qnil));
- else
- XSETCDR (last, Fcons (c, Qnil));
- kb->kbd_queue_has_data = 1;
- c = Qnil;
- if (single_kboard)
- goto wrong_kboard;
- current_kboard = kb;
+ goto exit;
+ if (EQ (c, make_number (-2)))
+ {
/* This is going to exit from read_char
so we had better get rid of this frame's stuff. */
UNGCPRO;
- return make_number (-2);
- }
- }
-
- /* Terminate Emacs in batch mode if at eof. */
- if (noninteractive && INTEGERP (c) && XINT (c) < 0)
- Fkill_emacs (make_number (1));
-
- if (INTEGERP (c))
- {
- /* Add in any extra modifiers, where appropriate. */
- if ((extra_keyboard_modifiers & CHAR_CTL)
- || ((extra_keyboard_modifiers & 0177) < ' '
- && (extra_keyboard_modifiers & 0177) != 0))
- XSETINT (c, make_ctrl_char (XINT (c)));
-
- /* Transfer any other modifier bits directly from
- extra_keyboard_modifiers to c. Ignore the actual character code
- in the low 16 bits of extra_keyboard_modifiers. */
- XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
- }
+ return c;
+ }
+ }
non_reread:
&& EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
}
-/* Like `read_char' but applies keyboard-coding-system to tty input. */
-static Lisp_Object
-read_decoded_char (int commandflag, Lisp_Object map,
- Lisp_Object prev_event, bool *used_mouse_menu)
-{
-#define MAX_ENCODED_BYTES 16
- Lisp_Object events[MAX_ENCODED_BYTES];
- int n = 0;
- while (true)
- {
- Lisp_Object nextevt
- = read_char (commandflag, map, prev_event, used_mouse_menu, NULL);
-#ifdef WINDOWSNT
- /* w32_console already returns decoded events. */
- return nextevt;
-#else
- struct frame *frame = XFRAME (selected_frame);
- struct terminal *terminal = frame->terminal;
- if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
- && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
- & CODING_REQUIRE_DECODING_MASK)))
- return nextevt; /* No decoding needed. */
- else
- {
- int meta_key = terminal->display_info.tty->meta_key;
- eassert (n < MAX_ENCODED_BYTES);
- events[n++] = nextevt;
- if (NATNUMP (nextevt)
- && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
- { /* An encoded byte sequence, let's try to decode it. */
- struct coding_system *coding
- = TERMINAL_KEYBOARD_CODING (terminal);
- unsigned char *src = alloca (n);
- int i;
- for (i = 0; i < n; i++)
- src[i] = XINT (events[i]);
- if (meta_key != 2)
- for (i = 0; i < n; i++)
- src[i] &= ~0x80;
- coding->destination = alloca (n * 4);
- coding->dst_bytes = n * 4;
- decode_coding_c_string (coding, src, n, Qnil);
- eassert (coding->produced_char <= n);
- if (coding->produced_char == 0)
- { /* The encoded sequence is incomplete. */
- if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */
- continue; /* Read on! */
- }
- else
- {
- const unsigned char *p = coding->destination;
- eassert (coding->carryover_bytes == 0);
- n = 0;
- while (n < coding->produced_char)
- events[n++] = make_number (STRING_CHAR_ADVANCE (p));
- }
- }
- /* Now `events' should hold decoded events.
- Normally, n should be equal to 1, but better not rely on it.
- We can only return one event here, so return the first we
- had and keep the others (if any) for later. */
- while (n > 1)
- Vunread_command_events
- = Fcons (events[--n], Vunread_command_events);
- return events[0];
- }
-#endif
- }
-}
-
/* Read a sequence of keys that ends with a non prefix character,
storing it in KEYBUF, a buffer of size BUFSIZE.
Prompt with PROMPT.
{
KBOARD *interrupted_kboard = current_kboard;
struct frame *interrupted_frame = SELECTED_FRAME ();
- key = read_decoded_char (NILP (prompt),
- current_binding, last_nonmenu_event,
- &used_mouse_menu);
+ key = read_char (NILP (prompt),
+ current_binding, last_nonmenu_event,
+ &used_mouse_menu, NULL);
if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
/* When switching to a new tty (with a new keyboard),
read_char returns the new buffer, rather than -2