changeset 83021:32bf8e7cc0c2

Fixed tty faces during combo sessions. Plus other assorted bugfixes. lisp/startup.el (command-line): Always call tty-register-default-colors. src/dispextern.h (delete_tty): Added missing prototype. src/keyboard.c (read_avail_input): Close display gracefully if needed. Kill Emacs if the last display is to be closed. (tty_read_avail_input): Don't call delete_tty and don't signal hangup here; return -2 instead to indicate the non-transient failure to read_avail_input. src/term.c (delete_tty): Removed superflous wiping of the deleted frames' output_data field. (delete_display): Check for and close live frames that are still on the display. src/termhooks.h (read_socket_hook, delete_display_hook): Added detailed comment. src/xfaces.c (realize_face): Create a dummy face for the initial frame. (Reported by Robert J. Chassell (bob at rattlenake dot com).) git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-61
author Karoly Lorentey <lorentey@elte.hu>
date Fri, 23 Jan 2004 21:48:58 +0000
parents d617fe346b2b
children abaf78268f22
files README.multi-tty lisp/startup.el src/dispextern.h src/keyboard.c src/term.c src/termhooks.h src/xfaces.c
diffstat 7 files changed, 118 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/README.multi-tty	Thu Jan 22 19:39:51 2004 +0000
+++ b/README.multi-tty	Fri Jan 23 21:48:58 2004 +0000
@@ -142,6 +142,16 @@
 *** The new `initial-window-system' variable contains the
     `window-system' value for the first frame.
 
+THANKS
+------
+
+The following is an (incomplete) list of people who have contributed
+to the project by testing, bug reports, and suggestions.  Thanks!
+
+Robert J. Chassel <bob@rattlesnake.com>
+Romain Francoise <romain@orekobech.com>
+Ami Fischman <ami@fischman.org>
+
 
 CHANGELOG
 ---------
@@ -151,15 +161,19 @@
 THINGS TO DO
 ------------
 
-** emacs -nw --eval '(y-or-n-p "Foobar")' segfaults.
+** Robert J. Chassell reports:
 
-** Fix color handling during tty+X combo sessions.  (It seems that tty
-   sessions automatically convert the face colors to terminal colors
-   when the face is loaded.  This conversion must happen instead on
-   the fly in write_glyphs, which might be problematic, as color
-   approximation is currently done in lisp (term/tty-colors.el).)
-   (Update: hm, colors seem to work fine if I start emacs with -nw and
-   then create an X frame.  Maybe it's just a small buglet somewhere.)
+   >   * After starting the frame in the VC, I saw this message in the
+   >     *Message* buffer
+   >
+   >         error in process filter: server-process-filter: \
+   >         Wrong type argument: sequencep,\
+   >          framep
+   >         error in process filter: Wrong type argument: sequencep, framep
+   >
+   >     This also happens when I start a new frame in an xterm.
+
+** emacs -nw --eval '(y-or-n-p "Foobar")' segfaults.
 
 ** Fix interactive use of temacs.  There are face-related SEGVs, most
    likely because of changes in realize_default_face, realize_face.
@@ -579,5 +593,16 @@
 
    (Done.)
 
+-- Fix color handling during tty+X combo sessions.  (It seems that tty
+   sessions automatically convert the face colors to terminal colors
+   when the face is loaded.  This conversion must happen instead on
+   the fly in write_glyphs, which might be problematic, as color
+   approximation is currently done in lisp (term/tty-colors.el).)
+   (Update: hm, colors seem to work fine if I start emacs with -nw and
+   then create an X frame.  Maybe it's just a small buglet somewhere.)
+
+   (Seems to be fixed.  The problem was in startup.el, it did not
+   initialize tty colors when the initial window system was
+   graphical.)
 
 ;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
--- a/lisp/startup.el	Thu Jan 22 19:39:51 2004 +0000
+++ b/lisp/startup.el	Fri Jan 23 21:48:58 2004 +0000
@@ -872,11 +872,10 @@
 
   ;; Register default TTY colors for the case the terminal hasn't a
   ;; terminal init file.
-  (unless (memq initial-window-system '(x w32))
-    ;; We do this regardles of whether the terminal supports colors
-    ;; or not, since they can switch that support on or off in
-    ;; mid-session by setting the tty-color-mode frame parameter.
-    (tty-register-default-colors))
+  ;; We do this regardles of whether the terminal supports colors
+  ;; or not, since they can switch that support on or off in
+  ;; mid-session by setting the tty-color-mode frame parameter.
+  (tty-register-default-colors)
 
   ;; Record whether the tool-bar is present before the user and site
   ;; init files are processed.  frame-notice-user-settings uses this
--- a/src/dispextern.h	Thu Jan 22 19:39:51 2004 +0000
+++ b/src/dispextern.h	Fri Jan 23 21:48:58 2004 +0000
@@ -2797,6 +2797,7 @@
 extern struct display *get_named_tty_display P_ ((char *));
 extern struct display *init_initial_display P_ ((void));
 extern struct display *term_init P_ ((char *, char *, int));
+extern void delete_tty P_ ((struct display *));
 extern void fatal P_ ((/* char *, ... */));
 extern void cursor_to P_ ((int, int));
 extern int tty_capable_p P_ ((struct tty_display_info *, unsigned, unsigned long, unsigned long));
--- a/src/keyboard.c	Thu Jan 22 19:39:51 2004 +0000
+++ b/src/keyboard.c	Fri Jan 23 21:48:58 2004 +0000
@@ -6580,14 +6580,36 @@
   for (i = 0; i < KBD_BUFFER_SIZE; i++)
     EVENT_INIT (buf[i]);
 
-  for (d = display_list; d; d = d->next_display)
-    {
+  d = display_list;
+  while (d)
+    {
+      struct display *next = d->next_display;
+      
       if (d->read_socket_hook)
         /* No need for FIONREAD or fcntl; just say don't wait.  */
         nread = (*d->read_socket_hook) (d, buf, KBD_BUFFER_SIZE, expected);
 
-      if (nread > 0)
-        break;
+      if (nread == -2)
+        {
+          /* The display device terminated; it should be closed. */
+
+          /* Kill Emacs if this was our last display. */
+          if (! display_list->next_display)
+            kill (getpid (), SIGHUP);
+
+          /* XXX Is calling delete_display safe here?  It calls Fdelete_frame. */
+          if (d->delete_display_hook)
+            (*d->delete_display_hook) (d);
+          else
+            delete_display (d);
+        }
+      else if (nread > 0)
+        {
+          /* We've got input. */
+          break;
+        }
+
+      d = next;
     }
 
   /* Scan the chars for C-g and store them in kbd_buffer.  */
@@ -6609,6 +6631,7 @@
    Note that each terminal device has its own `struct display' object,
    and so this function is called once for each individual termcap
    display.  The first parameter indicates which device to read from.  */
+
 int
 tty_read_avail_input (struct display *display,
                       struct input_event *buf,
@@ -6650,23 +6673,9 @@
   if (ioctl (fileno (TTY_INPUT (tty)), FIONREAD, &n_to_read) < 0)
     {
       if (! noninteractive)
-        {
-          delete_tty (tty); /* XXX I wonder if this is safe here. */
-          
-          /* Formerly simply reported no input, but that sometimes led to
-             a failure of Emacs to terminate.
-             SIGHUP seems appropriate if we can't reach the terminal.  */
-          /* ??? Is it really right to send the signal just to this process
-             rather than to the whole process group?
-             Perhaps on systems with FIONREAD Emacs is alone in its group.  */
-          /* It appears to be the case, see narrow_foreground_group. */
-          if (! tty_list->next)
-            kill (getpid (), SIGHUP); /* This was the last terminal. */
-        }
+        return -2;          /* Close this display. */
       else
-        {
-          n_to_read = 0;
-        }
+        n_to_read = 0;
     }
   if (n_to_read == 0)
     return 0;
@@ -6694,10 +6703,7 @@
          Jeffrey Honig <jch@bsdi.com> says this is generally safe.  */
       if (nread == -1 && errno == EIO)
         {
-          if (! tty_list->next)
-            kill (0, SIGHUP); /* This was the last terminal. */
-          else
-            delete_tty (tty); /* XXX I wonder if this is safe here. */
+          return -2;          /* Close this display. */
         }
 #if defined (AIX) && (! defined (aix386) && defined (_BSD))
       /* The kernel sometimes fails to deliver SIGHUP for ptys.
@@ -6706,10 +6712,7 @@
          and that causes a value other than 0 when there is no input.  */
       if (nread == 0)
         {
-          if (! tty_list->next)
-            kill (0, SIGHUP); /* This was the last terminal. */
-          else
-            delete_tty (tty); /* XXX I wonder if this is safe here. */
+          return -2;          /* Close this display. */
         }
 #endif
     }
--- a/src/term.c	Thu Jan 22 19:39:51 2004 +0000
+++ b/src/term.c	Fri Jan 23 21:48:58 2004 +0000
@@ -2843,7 +2843,6 @@
       if (FRAME_TERMCAP_P (f) && FRAME_LIVE_P (f) && FRAME_TTY (f) == tty)
         {
           Fdelete_frame (frame, Qt);
-          f->output_data.tty = 0;
         }
     }
 
@@ -2968,6 +2967,19 @@
 delete_display (struct display *dev)
 {
   struct display **dp;
+  Lisp_Object tail, frame;
+  
+  /* Check for and close live frames that are still on this
+     display. */
+  FOR_EACH_FRAME (tail, frame)
+    {
+      struct frame *f = XFRAME (frame);
+      if (FRAME_LIVE_P (f) && f->display == dev)
+        {
+          Fdelete_frame (frame, Qt);
+        }
+    }
+
   for (dp = &display_list; *dp != dev; dp = &(*dp)->next_display)
     if (! *dp)
       abort ();
--- a/src/termhooks.h	Thu Jan 22 19:39:51 2004 +0000
+++ b/src/termhooks.h	Fri Jan 23 21:48:58 2004 +0000
@@ -472,8 +472,27 @@
   void (*judge_scroll_bars_hook) P_ ((struct frame *FRAME));
 
 
-  /* Called to read input events.  */
-  int (*read_socket_hook) P_ ((struct display *, struct input_event *, int, int));
+  /* Called to read input events.
+
+     DISPLAY indicates which display to read from.  Input events
+     should be read into BUF, the size of which is given in SIZE.
+     EXPECTED is non-zero if the caller suspects that new input is
+     available.
+
+     A positive return value indicates that that many input events
+     where read into BUF.
+     Zero means no events were immediately available.
+     A value of -1 means a transient read error, while -2 indicates
+     that the display was closed (hangup), and it should be deleted.
+
+     XXX Please note that a non-zero value of EXPECTED only means that
+     there is available input on at least one of the currently opened
+     display devices -- but not necessarily on this device.
+     Therefore, in most cases EXPECTED should be simply ignored.
+  */
+  int (*read_socket_hook) P_ ((struct display *display,
+                               struct input_event *buf,
+                               int size, int expected));
 
   /* Called when a frame's display becomes entirely up to date.  */
   void (*frame_up_to_date_hook) P_ ((struct frame *));
@@ -483,11 +502,16 @@
      on this display. */
   void (*delete_frame_hook) P_ ((struct frame *));
 
-  /* Called after the last frame on this display is deleted.
-     If this is NULL, then the generic delete_frame() is called.
+  /* Called after the last frame on this display is deleted, or when
+     the display device was closed (hangup).
+     
+     If this is NULL, then the generic delete_frame() is called
+     instead.
 
-     Fdelete_frame ensures that there are no live frames on the
-     display when it calls this hook. */
+     The hook must check for and close any live frames that are still
+     on the display.  Fdelete_frame ensures that there are no live
+     frames on the display when it calls this hook, so infinite
+     recursion is prevented.  */
   void (*delete_display_hook) P_ ((struct display *));
 
 };
--- a/src/xfaces.c	Thu Jan 22 19:39:51 2004 +0000
+++ b/src/xfaces.c	Fri Jan 23 21:48:58 2004 +0000
@@ -6830,8 +6830,13 @@
 
   if (FRAME_WINDOW_P (cache->f))
     face = realize_x_face (cache, attrs, c, base_face);
-  else if (FRAME_INITIAL_P (cache->f) || FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
+  else if (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f))
     face = realize_tty_face (cache, attrs, c);
+  else if (FRAME_INITIAL_P (cache->f))
+    {
+      /* Create a dummy face. */
+      face = make_realized_face (attrs);
+    }
   else
     abort ();