changeset 83417:fe870a866ce7

Don't let x_initialize break 8-bit input on ttys. (Reported by Joakim Verona.) Split `set-input-mode'. * lisp/international/encoded-kb.el (encoded-kbd-setup-display): Use `set-input-meta-mode'. * lisp/linux.el (terminal-init-linux): Ditto. * src/keyboard.c (Fset_input_interrupt_mode, Fset_output_flow_control) (syms_of_keyboard): Defsubr them. (Fset_input_meta_mode, Fset_quit_char): New functions. (Fset_input_mode): Split to above functions. * lisp.h: EXFUN the new functions. * xterm.c (x_initialize): Use Fset_input_interrupt_mode. * macterm.c (mac_initialize): Ditto. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-457
author Karoly Lorentey <lorentey@elte.hu>
date Fri, 23 Dec 2005 03:00:55 +0000
parents 4513d8dcdfd5
children 50fd371bed05
files README.multi-tty lisp/international/encoded-kb.el lisp/term/linux.el src/keyboard.c src/lisp.h src/macterm.c src/xterm.c
diffstat 7 files changed, 201 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/README.multi-tty	Thu Dec 22 21:02:45 2005 +0000
+++ b/README.multi-tty	Fri Dec 23 03:00:55 2005 +0000
@@ -55,6 +55,7 @@
 Mark Plaksin <happy@mcplaksin.org>
 Frank Ruell <stoerte@dreamwarrior.net>
 Tom Schutzer-Weissmann <trmsw@yahoo.co.uk>
+Joakim Verona <joakim@verona.se>
 Dan Waber <dwaber@logolalia.com>
 and many others.
 
--- a/lisp/international/encoded-kb.el	Thu Dec 22 21:02:45 2005 +0000
+++ b/lisp/international/encoded-kb.el	Fri Dec 23 03:00:55 2005 +0000
@@ -276,25 +276,22 @@
 		  result)
 	      (set-keymap-parent keymap local-key-translation-map)
 	      (setq local-key-translation-map keymap)
-	      (unless (terminal-parameter nil 'encoded-kbd-saved-input-mode)
-		(set-terminal-parameter nil 'encoded-kbd-saved-input-mode cim))
+	      (unless (terminal-parameter nil 'encoded-kbd-saved-input-meta-mode)
+		(set-terminal-parameter nil 'encoded-kbd-saved-input-mode (nth 2 cim)))
 	      (setq result (and coding (encoded-kbd-setup-keymap keymap coding)))
 	      (if result
 		  (when (and (eq result 8)
 			     (memq (nth 2 cim) '(t nil)))
-		    (set-input-mode
-		     (nth 0 cim)
-		     (nth 1 cim)
-		     'use-8th-bit
-		     (nth 3 cim)))
-		(set-terminal-parameter nil 'encoded-kbd-saved-input-mode nil)
+		    (set-input-meta-mode 'use-8th-bit))
+		(set-terminal-parameter nil 'encoded-kbd-saved-input-meta-mode nil)
 		(error "Unsupported coding system in Encoded-kbd mode: %S"
 		       coding)))
 	  ;; We are turning off Encoded-kbd mode.
-	  (unless (equal (current-input-mode)
-			 (terminal-parameter nil 'encoded-kbd-saved-input-mode))
-	       (apply 'set-input-mode (terminal-parameter nil 'encoded-kbd-saved-input-mode)))
-	  (set-terminal-parameter nil 'saved-input-mode nil))))))
+	  (when (and (terminal-parameter nil 'encoded-kbd-saved-input-meta-mode)
+		     (not (equal (nth 2 (current-input-mode))
+				 (terminal-parameter nil 'encoded-kbd-saved-input-meta-mode))))
+	    (set-input-meta-mode (terminal-parameter nil 'encoded-kbd-saved-input-meta-mode)))
+	  (set-terminal-parameter nil 'saved-input-meta-mode nil))))))
 
 (provide 'encoded-kb)
 
--- a/lisp/term/linux.el	Thu Dec 22 21:02:45 2005 +0000
+++ b/lisp/term/linux.el	Fri Dec 23 03:00:55 2005 +0000
@@ -13,9 +13,8 @@
   ;; Meta will continue to work, because the kernel
   ;; turns that into Escape.
 
-  (let ((value (current-input-mode)))
-    ;; The third arg only matters in that it is not t or nil.
-    (set-input-mode (nth 0 value) (nth 1 value) 'iso-latin-1 (nth 3 value))))
+  ;; The arg only matters in that it is not t or nil.
+  (set-input-meta-mode 'iso-latin-1))
 
 ;;; arch-tag: 5d0c4f63-739b-4862-abf3-041fe42adb8f
 ;;; linux.el ends here
--- a/src/keyboard.c	Thu Dec 22 21:02:45 2005 +0000
+++ b/src/keyboard.c	Fri Dec 23 03:00:55 2005 +0000
@@ -10649,6 +10649,181 @@
   _longjmp (getcjmp, 1);
 }
 
+DEFUN ("set-input-interrupt-mode", Fset_input_interrupt_mode, Sset_input_interrupt_mode, 1, 1, 0,
+       doc: /* Set interrupt mode of reading keyboard input.
+If INTERRUPT is non-nil, Emacs will use input interrupts;
+otherwise Emacs uses CBREAK mode.
+
+See also `current-input-mode'.  */)
+     (interrupt)
+     Lisp_Object interrupt;
+{
+  int new_interrupt_input;
+#ifdef SIGIO
+/* Note SIGIO has been undef'd if FIONREAD is missing.  */
+  if (x_display_list != NULL)
+    {
+      /* When using X, don't give the user a real choice,
+	 because we haven't implemented the mechanisms to support it.  */
+#ifdef NO_SOCK_SIGIO
+      new_interrupt_input = 0;
+#else /* not NO_SOCK_SIGIO */
+      new_interrupt_input = 1;
+#endif /* NO_SOCK_SIGIO */
+    }
+  else
+    new_interrupt_input = !NILP (interrupt);
+#else /* not SIGIO */
+  new_interrupt_input = 0;
+#endif /* not SIGIO */
+
+/* Our VMS input only works by interrupts, as of now.  */
+#ifdef VMS
+  new_interrupt_input = 1;
+#endif
+
+  if (new_interrupt_input != interrupt_input) 
+    {
+#ifdef POLL_FOR_INPUT
+      stop_polling ();
+#endif
+#ifndef DOS_NT
+      /* this causes startup screen to be restored and messes with the mouse */
+      reset_all_sys_modes ();
+#endif
+      interrupt_input = new_interrupt_input;
+#ifndef DOS_NT
+      init_all_sys_modes ();
+#endif
+
+#ifdef POLL_FOR_INPUT
+      poll_suppress_count = 1;
+      start_polling ();
+#endif
+    }
+  return Qnil;
+}
+  
+DEFUN ("set-output-flow-control", Fset_output_flow_control, Sset_output_flow_control, 1, 2, 0,
+       doc: /* Enable or disable ^S/^Q flow control for output to TERMINAL.
+If FLOW is non-nil, flow control is enabled and you cannot use C-s or
+C-q in key sequences.
+
+This setting only has an effect on tty display devices and only when
+Emacs reads input in CBREAK mode; see `set-input-interrupt-mode'.
+
+See also `current-input-mode'.  */)
+       (flow, terminal)
+       Lisp_Object flow, terminal;
+{
+  struct device *d = get_device (terminal, 1);
+  struct tty_display_info *tty;
+  if (d == NULL || d->type != output_termcap)
+    return Qnil;
+  tty = d->display_info.tty;
+
+  if (tty->flow_control != !NILP (flow))
+    {
+#ifndef DOS_NT
+      /* this causes startup screen to be restored and messes with the mouse */
+      reset_sys_modes (tty);
+#endif
+
+      tty->flow_control = !NILP (flow);
+
+#ifndef DOS_NT
+      init_sys_modes (tty);
+#endif
+    }
+}
+
+DEFUN ("set-input-meta-mode", Fset_input_meta_mode, Sset_input_meta_mode, 1, 2, 0,
+       doc: /* Enable or disable 8-bit input on TERMINAL.
+If META is t, Emacs will accept 8-bit input, and interpret the 8th
+bit as the Meta modifier.
+
+If META is nil, Emacs will ignore the top bit, on the assumption it is
+parity.
+
+Otherwise, Emacs will accept and pass through 8-bit input without
+specially interpreting the top bit.
+
+This setting only has an effect on tty display devices.
+
+Optional parameter TERMINAL specifies the tty display device to use.
+It may be a terminal id, a frame, or nil for the terminal used by the
+currently selected frame.
+
+See also `current-input-mode'.  */)
+       (meta, terminal)
+       Lisp_Object meta, terminal;
+{
+  struct device *d = get_device (terminal, 1);
+  struct tty_display_info *tty;
+  int new_meta;
+  
+  if (d == NULL || d->type != output_termcap)
+    return Qnil;
+  tty = d->display_info.tty;
+
+  if (NILP (meta))
+    new_meta = 0;
+  else if (EQ (meta, Qt))
+    new_meta = 1;
+  else
+    new_meta = 2;
+
+  if (tty->meta_key != new_meta) 
+    {
+#ifndef DOS_NT
+      /* this causes startup screen to be restored and messes with the mouse */
+      reset_sys_modes (tty);
+#endif
+
+      tty->meta_key = new_meta;
+  
+#ifndef DOS_NT
+      init_sys_modes (tty);
+#endif
+    }
+  return Qnil;
+}
+
+DEFUN ("set-quit-char", Fset_quit_char, Sset_quit_char, 1, 1, 0,
+       doc: /* Specify character used for quitting.
+QUIT must be an ASCII character.
+
+This function only has an effect on the tty display on the controlling
+tty of the Emacs process.
+
+See also `current-input-mode'.  */)
+       (quit)
+       Lisp_Object quit;
+{
+  struct device *d = get_named_tty (NULL);
+  struct tty_display_info *tty;
+  if (d == NULL || d->type != output_termcap)
+    return Qnil;
+  tty = d->display_info.tty;
+
+#ifndef DOS_NT
+  /* this causes startup screen to be restored and messes with the mouse */
+  reset_sys_modes (tty);
+#endif
+  
+  if (NILP (quit) || !INTEGERP (quit) || XINT (quit) < 0 || XINT (quit) > 0400)
+    error ("QUIT must be an ASCII character");
+
+  /* Don't let this value be out of range.  */
+  quit_char = XINT (quit) & (tty->meta_key == 0 ? 0177 : 0377);
+
+#ifndef DOS_NT
+  init_sys_modes (tty);
+#endif
+
+  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;
@@ -10663,73 +10838,10 @@
      (interrupt, flow, meta, quit)
      Lisp_Object interrupt, flow, meta, quit;
 {
-  /* XXX This function needs to be revised for multi-device support.
-     Currently it compiles fine, but its semantics are wrong.  It sets
-     global parameters (e.g. interrupt_input) based on only the
-     current frame's device. */
-
-  if (!NILP (quit)
-      && (!INTEGERP (quit) || XINT (quit) < 0 || XINT (quit) > 0400))
-    error ("set-input-mode: QUIT must be an ASCII character");
-
-#ifdef POLL_FOR_INPUT
-  stop_polling ();
-#endif
-
-#ifndef DOS_NT
-  if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
-    /* this causes startup screen to be restored and messes with the mouse */
-    reset_sys_modes (CURTTY ());
-#endif
-
-#ifdef SIGIO
-/* Note SIGIO has been undef'd if FIONREAD is missing.  */
-  if (FRAME_DEVICE (SELECTED_FRAME ())->read_socket_hook)
-    {
-      /* When using X, don't give the user a real choice,
-	 because we haven't implemented the mechanisms to support it.  */
-#ifdef NO_SOCK_SIGIO
-      interrupt_input = 0;
-#else /* not NO_SOCK_SIGIO */
-      interrupt_input = 1;
-#endif /* NO_SOCK_SIGIO */
-    }
-  else
-    interrupt_input = !NILP (interrupt);
-#else /* not SIGIO */
-  interrupt_input = 0;
-#endif /* not SIGIO */
-
-/* Our VMS input only works by interrupts, as of now.  */
-#ifdef VMS
-  interrupt_input = 1;
-#endif
-
-  if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
-    {
-      struct tty_display_info *tty = CURTTY ();
-      tty->flow_control = !NILP (flow);
-      if (NILP (meta))
-        tty->meta_key = 0;
-      else if (EQ (meta, Qt))
-        tty->meta_key = 1;
-      else
-        tty->meta_key = 2;
-    }
-
-  if (!NILP (quit))
-    /* Don't let this value be out of range.  */
-    quit_char = XINT (quit) & (NILP (meta) ? 0177 : 0377);
-
-#ifndef DOS_NT
-  if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
-    init_sys_modes (CURTTY ());
-#endif
-
-#ifdef POLL_FOR_INPUT
-  poll_suppress_count = 1;
-  start_polling ();
-#endif
+  Fset_input_interrupt_mode (interrupt);
+  Fset_output_flow_control (flow, Qnil);
+  Fset_input_meta_mode (meta, Qnil);
+  Fset_quit_char (quit);
   return Qnil;
 }
 
@@ -11281,6 +11393,10 @@
   defsubr (&Stop_level);
   defsubr (&Sdiscard_input);
   defsubr (&Sopen_dribble_file);
+  defsubr (&Sset_input_interrupt_mode);
+  defsubr (&Sset_output_flow_control);
+  defsubr (&Sset_input_meta_mode);
+  defsubr (&Sset_quit_char);
   defsubr (&Sset_input_mode);
   defsubr (&Scurrent_input_mode);
   defsubr (&Sexecute_extended_command);
--- a/src/lisp.h	Thu Dec 22 21:02:45 2005 +0000
+++ b/src/lisp.h	Fri Dec 23 03:00:55 2005 +0000
@@ -2939,6 +2939,10 @@
 extern void discard_mouse_events P_ ((void));
 EXFUN (Fevent_convert_list, 1);
 EXFUN (Fread_key_sequence, 5);
+EXFUN (Fset_input_interrupt_mode, 1);
+EXFUN (Fset_output_flow_control, 2);
+EXFUN (Fset_input_meta_mode, 2);
+EXFUN (Fset_quit_char, 1);
 EXFUN (Fset_input_mode, 4);
 extern int detect_input_pending P_ ((void));
 extern int detect_input_pending_ignore_squeezables P_ ((void));
--- a/src/macterm.c	Thu Dec 22 21:02:45 2005 +0000
+++ b/src/macterm.c	Fri Dec 23 03:00:55 2005 +0000
@@ -10630,7 +10630,7 @@
   any_help_event_p = 0;
 
   /* Try to use interrupt input; if we can't, then start polling.  */
-  Fset_input_mode (Qt, Qnil, Qt, Qnil);
+  Fset_input_interrupt_mode (Qt);
 
   BLOCK_INPUT;
 
--- a/src/xterm.c	Thu Dec 22 21:02:45 2005 +0000
+++ b/src/xterm.c	Fri Dec 23 03:00:55 2005 +0000
@@ -10868,7 +10868,7 @@
 #endif
 
   /* Try to use interrupt input; if we can't, then start polling.  */
-  Fset_input_mode (Qt, Qnil, Qt, Qnil);
+  Fset_input_interrupt_mode (Qt);
 
 #ifdef USE_X_TOOLKIT
   XtToolkitInitialize ();