]> git.eshelyaron.com Git - emacs.git/commitdiff
Backport fix for Bug#6571 from trunk. NOTE: May cause merge conflicts.
authorJan Djärv <jan.h.d@swipnet.se>
Mon, 1 Nov 2010 11:30:33 +0000 (12:30 +0100)
committerJan Djärv <jan.h.d@swipnet.se>
Mon, 1 Nov 2010 11:30:33 +0000 (12:30 +0100)
* src/keyboard.c (input_available_signal): Declare.
(kbd_buffer_nr_stored): New function.
(kbd_buffer_store_event_hold): If kbd_buffer_nr_stored returns
more than KBD_BUFFER_SIZE/2, stop reding input (Bug#6571).
(kbd_buffer_get_event): If input is suspended and kbd_buffer_nr_stored
returns less than KBD_BUFFER_SIZE/4, resume reding input (Bug#6571).
(tty_read_avail_input): If input is on hold, return.
Don't read more that free slots in kbd_buffer (Bug#6571).

* src/process.c (kbd_is_on_hold): New variable.
(hold_keyboard_input, unhold_keyboard_input, kbd_on_hold_p):
New functions.
(wait_reading_process_output): If kbd_on_hold_p returns non-zero,
select on empty input mask.
(init_process): Initialize kbd_is_on_hold to 0.

* src/process.h (hold_keyboard_input, unhold_keyboard_input)
(kbd_on_hold_p): Declare.

src/ChangeLog
src/keyboard.c
src/process.c
src/process.h

index 391dc3eaa07739ff205303a3e985a0065038d2c7..33552c0ed5707698bc86ccf9b12139891a09665c 100644 (file)
@@ -1,3 +1,24 @@
+2010-11-01  Jan Djärv  <jan.h.d@swipnet.se>
+
+       * process.c (kbd_is_on_hold): New variable.
+       (hold_keyboard_input, unhold_keyboard_input, kbd_on_hold_p):
+       New functions.
+       (wait_reading_process_output): If kbd_on_hold_p returns non-zero,
+       select on empty input mask.
+       (init_process): Initialize kbd_is_on_hold to 0.
+
+       * process.h (hold_keyboard_input, unhold_keyboard_input)
+       (kbd_on_hold_p): Declare.
+
+       * keyboard.c (input_available_signal): Declare.
+       (kbd_buffer_nr_stored): New function.
+       (kbd_buffer_store_event_hold): If kbd_buffer_nr_stored returns
+       more than KBD_BUFFER_SIZE/2, stop reding input (Bug#6571).
+       (kbd_buffer_get_event): If input is suspended and kbd_buffer_nr_stored
+       returns less than KBD_BUFFER_SIZE/4, resume reding input (Bug#6571).
+       (tty_read_avail_input): If input is on hold, return.
+       Don't read more that free slots in kbd_buffer (Bug#6571).
+
 2010-10-31  Chong Yidong  <cyd@stupidchicken.com>
 
        * xterm.c (x_connection_closed): Print informative error message
index 22c58985a565e7ed3c52dc0c0a549129e87cbefe..311f42fbb3b86c42a4de1fc7853ad3d51a285884 100644 (file)
@@ -642,6 +642,9 @@ static Lisp_Object apply_modifiers P_ ((int, Lisp_Object));
 static void clear_event P_ ((struct input_event *));
 static Lisp_Object restore_kboard_configuration P_ ((Lisp_Object));
 static SIGTYPE interrupt_signal P_ ((int signalnum));
+#ifdef SIGIO
+static SIGTYPE input_available_signal (int signo);
+#endif
 static void handle_interrupt P_ ((void));
 static void timer_start_idle P_ ((void));
 static void timer_stop_idle P_ ((void));
@@ -3780,6 +3783,18 @@ event_to_kboard (event)
     return FRAME_KBOARD (XFRAME (frame));
 }
 
+/* Return the number of slots occupied in kbd_buffer.  */
+
+static int
+kbd_buffer_nr_stored (void)
+{
+  return kbd_fetch_ptr == kbd_store_ptr
+    ? 0
+    : (kbd_fetch_ptr < kbd_store_ptr
+       ? kbd_store_ptr - kbd_fetch_ptr
+       : ((kbd_buffer + KBD_BUFFER_SIZE) - kbd_fetch_ptr
+          + (kbd_store_ptr - kbd_buffer)));
+}
 
 Lisp_Object Vthrow_on_input;
 
@@ -3903,6 +3918,17 @@ kbd_buffer_store_event_hold (event, hold_quit)
     {
       *kbd_store_ptr = *event;
       ++kbd_store_ptr;
+      if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE/2 && ! kbd_on_hold_p ())
+        {
+          /* Don't read keyboard input until we have processed kbd_buffer.
+             This happens when pasting text longer than KBD_BUFFER_SIZE/2.  */
+          hold_keyboard_input ();
+#ifdef SIGIO
+          if (!noninteractive)
+            signal (SIGIO, SIG_IGN);
+#endif
+          stop_polling ();
+        }
     }
 
   /* If we're inside while-no-input, and this event qualifies
@@ -4071,6 +4097,18 @@ kbd_buffer_get_event (kbp, used_mouse_menu, end_time)
   register int c;
   Lisp_Object obj;
 
+  if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE/4)
+    {
+      /* Start reading input again, we have processed enough so we can
+         accept new events again.  */
+      unhold_keyboard_input ();
+#ifdef SIGIO
+      if (!noninteractive)
+        signal (SIGIO, input_available_signal);
+#endif /* SIGIO */
+      start_polling ();
+    }
+
   if (noninteractive
       /* In case we are running as a daemon, only do this before
         detaching from the terminal.  */
@@ -7270,6 +7308,10 @@ tty_read_avail_input (struct terminal *terminal,
   int n_to_read, i;
   struct tty_display_info *tty = terminal->display_info.tty;
   int nread = 0;
+  int buffer_free = KBD_BUFFER_SIZE - kbd_buffer_nr_stored () - 1;
+
+  if (kbd_on_hold_p () || buffer_free <= 0)
+    return 0;
 
   if (!terminal->name)         /* Don't read from a dead terminal. */
     return 0;
@@ -7351,6 +7393,10 @@ tty_read_avail_input (struct terminal *terminal,
 #endif
 #endif
 
+  /* Don't read more than we can store.  */
+  if (n_to_read > buffer_free)
+    n_to_read = buffer_free;
+
   /* Now read; for one reason or another, this will not block.
      NREAD is set to the number of chars read.  */
   do
index 3e2aa61ffe6d9824a11503668f49bc0932b69763..567300e2f64bcfb169069e641c1cd844eaa40c0c 100644 (file)
@@ -346,6 +346,9 @@ static int max_keyboard_desc;
 /* The largest descriptor currently in use for gpm mouse input.  */
 static int max_gpm_desc;
 
+/* Non-zero if keyboard input is on hold, zero otherwise.  */
+static int kbd_is_on_hold;
+
 /* Nonzero means delete a process right away if it exits.  */
 static int delete_exited_processes;
 
@@ -4795,7 +4798,11 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
          SELECT_TYPE Ctemp;
 #endif
 
-         Atemp = input_wait_mask;
+          if (kbd_on_hold_p ())
+            FD_ZERO (&Atemp);
+          else
+            Atemp = input_wait_mask;
+
          IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask);
 
          EMACS_SET_SECS_USECS (timeout, 0, 0);
@@ -7224,6 +7231,31 @@ keyboard_bit_set (mask)
 
   return 0;
 }
+
+/* Stop reading input from keyboard sources.  */
+
+void
+hold_keyboard_input (void)
+{
+  kbd_is_on_hold = 1;
+}
+
+/* Resume reading input from keyboard sources.  */
+
+void
+unhold_keyboard_input (void)
+{
+  kbd_is_on_hold = 0;
+}
+
+/* Return non-zero if keyboard input is on hold, zero otherwise.  */
+
+int
+kbd_on_hold_p (void)
+{
+  return kbd_is_on_hold;
+}
+
 \f
 /* Enumeration of and access to system processes a-la ps(1).  */
 
@@ -8039,6 +8071,7 @@ integer or floating point values.
 void
 init_process ()
 {
+  kbd_is_on_hold = 0;
 }
 
 void
index a8cd0a02da68d24e14e4647e931c954b7e045d4e..12b91d697b9c8cf36b5b110521c1ae0345643f77 100644 (file)
@@ -170,5 +170,9 @@ extern Lisp_Object Qtime, Qctime;
 extern Lisp_Object list_system_processes (void);
 extern Lisp_Object system_process_attributes (Lisp_Object);
 
+extern void hold_keyboard_input (void);
+extern void unhold_keyboard_input (void);
+extern int kbd_on_hold_p (void);
+
 /* arch-tag: dffedfc4-d7bc-4b58-a26f-c16155449c72
    (do not change this comment) */