emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r112692: Don't apply keyboard decodin


From: Stefan Monnier
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r112692: Don't apply keyboard decoding to unread-command-events.
Date: Thu, 23 May 2013 13:25:42 -0400
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 112692
fixes bug: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=14403
committer: Stefan Monnier <address@hidden>
branch nick: trunk
timestamp: Thu 2013-05-23 13:25:42 -0400
message:
  Don't apply keyboard decoding to unread-command-events.
  * src/keyboard.c: Apply keyboard decoding only to events that come directly
  from the tty, not from unread-command-events (bug#14368).
  (read_event_from_main_queue): New function, extracted from read_char).
  (read_decoded_char): Remove.
  (read_decoded_event_from_main_queue): New function to replace it.
  (read_char): Use it.
  (read_key_sequence): Use read_char rather than read_decoded_char.
modified:
  src/ChangeLog
  src/keyboard.c
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-05-23 13:23:45 +0000
+++ b/src/ChangeLog     2013-05-23 17:25:42 +0000
@@ -1,5 +1,13 @@
 2013-05-23  Stefan Monnier  <address@hidden>
 
+       * keyboard.c: Apply keyboard decoding only to events that come directly
+       from the tty, not from unread-command-events (bug#14368).
+       (read_event_from_main_queue): New function, extracted from read_char).
+       (read_decoded_char): Remove.
+       (read_decoded_event_from_main_queue): New function to replace it.
+       (read_char): Use it.
+       (read_key_sequence): Use read_char rather than read_decoded_char.
+
        * keyboard.c (read_decoded_char): Don't decode under w32 (bug#14403).
 
 2013-05-22  Barry OReilly  <address@hidden>  (tiny change)

=== modified file 'src/keyboard.c'
--- a/src/keyboard.c    2013-05-23 13:23:45 +0000
+++ b/src/keyboard.c    2013-05-23 17:25:42 +0000
@@ -2222,6 +2222,157 @@
 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.
@@ -2739,68 +2890,20 @@
 
   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:
 
@@ -8690,76 +8793,6 @@
              && 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.
@@ -9037,9 +9070,9 @@
          {
            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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]