diff src/term.c @ 53341:d4e6a050c9b1

Bugfix festival. lib-src/emacsclient.c (main_argc, main_argv): New variables. (main): Initialize them. (fail): Use them. (window_change, copy_from_to): Don't kill if emacs_pid is zero. (pty_conversation): Watch the command socket, too. Read emacs_pid here. Emacs and emacsclient could deadlock if Emacs tried to do a reset_sys_modes before sending its pid. lisp/server.el: Automatically delete the client frame when done editing. (server-frames): New variable. (server-process-filter, server-sentinel, server-buffer-done): Use it. (server-process-filter): Do a redisplay before evaluating other parameters. (Prevents "emacsclient -h -e '(delete-frame)'" from messing up the system. src/dispextern.h: Update prototypes. src/dispnew.c (window_change_signal): Do nothing if !term_initted. (init_display): Set the frame size from the tty data after term_init. src/emacs.c (main): Make sure things that init_sys_modes needs are initialized before init_display (which calls init_sys_modes now). (sort_args): Use xfree, not free. (shut_down_emacs) [!EMACS_HAVE_TTY_PGRP]: Use reset_all_sys_modes instead of reset_sys_modes. src/frame.c (make_terminal_frame): Sigh. Move terminal initialization back to the middle of frame setup. Handle errors by making sure that the delete_tty() called from term_init() will see and delete this frame. (Fdelete_frame): Kill the frame before calling delete_tty(). Fix condition for tty deletion. src/keyboard.c (Fset_input_mode): Use reset_sys_modes on the current terminal only. src/lisp.h: Remove duplicate prototypes. src/msdos.c (croak): use reset_all_sys_modes(). src/sysdeps.c (init_baud_rate): Added tty parameter, use it instead of CURTTY. (child_setup_tty): Reset sigio on stdin, not CURTTY(). (reset_sigio): Added fd parameter, put explicit fcntl there. (request_sigio, unrequest_sigio)[FASYNC]: Simply block/unblock the SIGIO signal, don't touch the file params. There are multiple ttys now, and we can't disable the SIGIO from emacsclient. (get_tty_size)[VMS]: Use tty_out instead of CURTTY(). (reset_sys_modes): Don't call cursor_to, clear_end_of_line; call cmgoto and tty_clear_end_of_line instead. The frame may already be dead. Updated reset_sigio call. src/term.c (clear_and_of_line): Separate tty-dependent stuff to tty_clear_end_of_line() for reset_sys_modes. (tty_clear_end_of_line): New function. (term_init): Added frame parameter, don't use selected_frame. Set the frame's output_data.tty value (in case there is an error later). Set the frame size in Wcm, not in the frame. Only free the termcap buffer if there is a termcap-related error. Call init_sys_modes last, not first. (deleting_tty): New variable. (delete_tty): Use it for handling recursive calls. Free deleted tty, except its Wcm (there is still a dangling reference somewhere). git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-19
author Karoly Lorentey <lorentey@elte.hu>
date Mon, 29 Dec 2003 07:16:26 +0000
parents db645482d6bc
children 1682917e56b4
line wrap: on
line diff
--- a/src/term.c	Sun Dec 28 22:28:52 2003 +0000
+++ b/src/term.c	Mon Dec 29 07:16:26 2003 +0000
@@ -651,8 +651,6 @@
 clear_end_of_line (first_unused_hpos)
      int first_unused_hpos;
 {
-  register int i;
-
   struct frame *f = (updating_frame ? updating_frame : XFRAME (selected_frame));
   struct tty_output *tty;
   
@@ -663,8 +661,13 @@
       return;
     }
 
-  tty = FRAME_TTY (f);
-
+  tty_clear_end_of_line (FRAME_TTY (f), first_unused_hpos);
+}
+
+void
+tty_clear_end_of_line (struct tty_output *tty, int first_unused_hpos)
+{
+  register int i;
   /* Detect the case where we are called from reset_sys_modes
      and the costs have never been calculated.  Do nothing.  */
   if (! tty->costs_set)
@@ -683,8 +686,8 @@
 
       /* Do not write in last row last col with Auto-wrap on. */
       if (AutoWrap (tty)
-          && curY (tty) == FRAME_LINES (f) - 1
-	  && first_unused_hpos == FRAME_COLS (f))
+          && curY (tty) == FrameRows (tty) - 1
+	  && first_unused_hpos == FrameCols (tty))
 	first_unused_hpos--;
 
       for (i = curX (tty); i < first_unused_hpos; i++)
@@ -2124,9 +2127,7 @@
 
 
 struct tty_output *
-term_init (name, terminal_type)
-     char *name;
-     char *terminal_type;
+term_init (Lisp_Object frame, char *name, char *terminal_type)
 {
   char *area;
   char **address = &area;
@@ -2134,20 +2135,16 @@
   int buffer_size = 4096;
   register char *p;
   int status;
-  struct frame *sf = XFRAME (selected_frame);
-
+  struct frame *f = XFRAME (frame);
   struct tty_output *tty;
 
   tty = get_named_tty (name);
   if (tty)
     {
-      /* Return the previously initialized terminal, except if it is the dummy
-         terminal created for the initial frame. */
+      /* Return the previously initialized terminal, except if it is
+         the dummy terminal created for the initial frame. */
       if (tty->type)
         return tty;
-
-      /* In the latter case, initialize top_frame to the current terminal. */
-      tty->top_frame = selected_frame;
     }
   else
     {
@@ -2160,21 +2157,25 @@
   if (! tty->Wcm)
       tty->Wcm = (struct cm *) xmalloc (sizeof (struct cm));
 
+  /* Make sure the frame is live; if an error happens, it must be
+     deleted. */
+  f->output_method = output_termcap;
+  f->output_data.tty = tty;
+  
   if (name)
     {
       int fd;
-      FILE *f;
+      FILE *file;
       fd = emacs_open (name, O_RDWR, 0);
       if (fd < 0)
         {
-          tty_list = tty->next;
-          xfree (tty);
+          delete_tty (tty);
           error ("Could not open file: %s", name);
         }
-      f = fdopen (fd, "w+");
+      file = fdopen (fd, "w+");
       TTY_NAME (tty) = xstrdup (name);
-      TTY_INPUT (tty) = f;
-      TTY_OUTPUT (tty) = f;
+      TTY_INPUT (tty) = file;
+      TTY_OUTPUT (tty) = file;
     }
   else
     {
@@ -2185,8 +2186,6 @@
 
   TTY_TYPE (tty) = xstrdup (terminal_type);
 
-  init_sys_modes (tty);
-  
 #ifdef WINDOWSNT
   initialize_w32_display ();
 
@@ -2194,9 +2193,9 @@
 
   area = (char *) xmalloc (2044);
 
-  FrameRows = FRAME_LINES (sf);
-  FrameCols = FRAME_COLS (sf);
-  specified_window = FRAME_LINES (sf);
+  FrameRows = FRAME_LINES (f);
+  FrameCols = FRAME_COLS (f);
+  specified_window = FRAME_LINES (f);
 
   delete_in_insert_mode = 1;
 
@@ -2213,8 +2212,8 @@
 
   baud_rate = 19200;
 
-  FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
-  FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
+  FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
+  FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
   TN_max_colors = 16;  /* Required to be non-zero for tty-display-color-p */
 
   return tty;
@@ -2229,6 +2228,7 @@
 #ifdef TERMINFO
       if (name)
         {
+          xfree (buffer);
           delete_tty (tty);
           error ("Cannot open terminfo database file");
         }
@@ -2237,6 +2237,7 @@
 #else
       if (name)
         {
+          xfree (buffer);
           delete_tty (tty);
           error ("Cannot open termcap database file");
         }
@@ -2249,12 +2250,13 @@
 #ifdef TERMINFO
       if (name)
         {
+          xfree (buffer);
           delete_tty (tty);
           error ("Terminal type %s is not defined", terminal_type);
         }
       else
         fatal ("Terminal type %s is not defined.\n\
-If that is not the actual type of terminal you have,\n          \
+If that is not the actual type of terminal you have,\n\
 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
 `setenv TERM ...') to specify the correct type.  It may be necessary\n\
 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
@@ -2262,12 +2264,13 @@
 #else
       if (name)
         {
+          xfree (buffer);
           delete_tty (tty);
           error ("Terminal type %s is not defined", terminal_type);
         }
       else
         fatal ("Terminal type %s is not defined.\n\
-If that is not the actual type of terminal you have,\n          \
+If that is not the actual type of terminal you have,\n\
 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
 `setenv TERM ...') to specify the correct type.  It may be necessary\n\
 to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.",
@@ -2401,21 +2404,29 @@
   {
     int height, width;
     get_tty_size (tty, &width, &height);
-    FRAME_COLS (sf) = width;
-    FRAME_LINES (sf) = height;
+    FrameCols (tty) = width;
+    FrameRows (tty) = height;
   }
 
-  if (FRAME_COLS (sf) <= 0)
-    SET_FRAME_COLS (sf, tgetnum ("co"));
-  else
-    /* Keep width and external_width consistent */
-    SET_FRAME_COLS (sf, FRAME_COLS (sf));
-  if (FRAME_LINES (sf) <= 0)
-    FRAME_LINES (sf) = tgetnum ("li");
-
-  if (FRAME_LINES (sf) < 3 || FRAME_COLS (sf) < 3)
-    fatal ("Screen size %dx%d is too small",
-           FRAME_LINES (sf), FRAME_COLS (sf));
+  if (FrameCols (tty) <= 0)
+    FrameCols (tty) = tgetnum ("co");
+  if (FrameRows (tty) <= 0)
+    FrameRows (tty) = tgetnum ("li");
+
+  if (FrameRows (tty) < 3 || FrameCols (tty) < 3)
+    {
+      if (initialized)
+        {
+          delete_tty (tty);
+          error ("Screen size %dx%d is too small",
+                 FrameCols (tty), FrameRows (tty));
+        }
+      else
+        {
+          fatal ("Screen size %dx%d is too small",
+                 FrameCols (tty), FrameRows (tty));
+        }
+    }
 
 #if 0  /* This is not used anywhere. */
   TTY_MIN_PADDING_SPEED (tty) = tgetnum ("pb");
@@ -2541,15 +2552,14 @@
         }
     }
 
-  FrameRows (tty) = FRAME_LINES (sf);
-  FrameCols (tty) = FRAME_COLS (sf);
-  tty->specified_window = FRAME_LINES (sf);
+  tty->specified_window = FrameRows (tty);
 
   if (Wcm_init (tty) == -1)	/* can't do cursor motion */
     if (name)
       {
         delete_tty (tty);
-        error ("Terminal type \"%s\" is not powerful enough to run Emacs");
+        error ("Terminal type \"%s\" is not powerful enough to run Emacs",
+               terminal_type);
       }
     else {
 #ifdef VMS
@@ -2562,15 +2572,15 @@
 #else /* not VMS */
 # ifdef TERMINFO
       fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
-It lacks the ability to position the cursor.\n                          \
-If that is not the actual type of terminal you have,\n                  \
+It lacks the ability to position the cursor.\n\
+If that is not the actual type of terminal you have,\n\
 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
 `setenv TERM ...') to specify the correct type.  It may be necessary\n\
 to do `unset TERMINFO' (C-shell: `unsetenv TERMINFO') as well.",
              terminal_type);
 # else /* TERMCAP */
       fatal ("Terminal type \"%s\" is not powerful enough to run Emacs.\n\
-It lacks the ability to position the cursor.\n                       \
+It lacks the ability to position the cursor.\n\
 If that is not the actual type of terminal you have,\n\
 use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
 `setenv TERM ...') to specify the correct type.  It may be necessary\n\
@@ -2580,8 +2590,7 @@
 #endif /*VMS */
     }
   
-  if (FRAME_LINES (sf) <= 0
-      || FRAME_COLS (sf) <= 0)
+  if (FrameRows (tty) <= 0 || FrameCols (tty) <= 0)
     {
       if (name)
         {
@@ -2619,20 +2628,29 @@
 
   TTY_FAST_CLEAR_END_OF_LINE (tty) = tty->TS_clr_line != 0;
 
-  init_baud_rate ();
+  init_baud_rate (tty);
   if (read_socket_hook)		/* Baudrate is somewhat
                                    meaningless in this case */
     baud_rate = 9600;
 
-  FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0;
-  FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none;
-#endif /* WINDOWSNT */
-
-  xfree (buffer);
-
+  FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
+  FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
+
+  /* Don't do this.  I think termcap may still need the buffer. */
+  /* xfree (buffer); */
+
+  tty->top_frame = frame;
+  
+  tty->foreground_pixel = FACE_TTY_DEFAULT_FG_COLOR;
+  tty->background_pixel = FACE_TTY_DEFAULT_BG_COLOR;
+  
+  /* Init system terminal modes (RAW or CBREAK, etc.).  */
+  init_sys_modes (tty);
+  
   tty_set_terminal_modes (tty);
 
   return tty;
+#endif /* WINDOWSNT */
 }
 
 /* VARARGS 1 */
@@ -2670,11 +2688,20 @@
   Fprovide (intern ("multi-tty"), Qnil);
 }
 
+static int deleting_tty = 0;
+
 void
 delete_tty (struct tty_output *tty)
 {
   Lisp_Object tail, frame;
-
+  
+  if (deleting_tty)
+    /* We get a recursive call when we delete the last frame on this
+       tty. */
+    return;
+
+  deleting_tty = 1;
+  
   if (tty == tty_list)
     tty_list = tty->next;
   else
@@ -2687,7 +2714,8 @@
         /* This should not happen. */
         abort ();
 
-      p->next = p->next->next;
+      p->next = tty->next;
+      tty->next = 0;
     }
 
   FOR_EACH_FRAME (tail, frame)
@@ -2700,46 +2728,31 @@
         }
     }
   
-  /* This hangs. */
-  /*
   reset_sys_modes (tty);
 
   if (tty->name)
     xfree (tty->name);
   if (tty->type)
     xfree (tty->type);
-  */
+
   if (tty->input)
     fclose (tty->input);
   if (tty->output)
     fclose (tty->output);
   if (tty->termscript)
     fclose (tty->termscript);
-
-  tty->input = 0;
-  tty->output = 0;
-  tty->termscript = 0;
   
-  /*
   if (tty->old_tty)
-    {
-      memset (tty->old_tty, 'Z', sizeof (struct emacs_tty));
-      tty->old_tty = 0;
-    }
-  
-    
-    /*    xfree (tty->old_tty);
-
-    if (tty->Wcm)
-    {
-      bzero (tty->Wcm, sizeof (struct cm));
-    }
+    xfree (tty->old_tty);
+
+#if 0  /* XXX There is a dangling reference somewhere into this. */
+  if (tty->Wcm)
     xfree (tty->Wcm); 
+#endif
   
   bzero (tty, sizeof (struct tty_output));
-  
   xfree (tty);
-  */
+  deleting_tty = 0;
 }