Numerous bugfixes and small improvements.
authorKaroly Lorentey <lorentey@elte.hu>
Sat, 10 Jan 2004 12:56:22 +0000 (12:56 +0000)
committerKaroly Lorentey <lorentey@elte.hu>
Sat, 10 Jan 2004 12:56:22 +0000 (12:56 +0000)
lisp/bindings.el (mode-line-frame-identification): Use %T, not %F.

lisp/faces.el (x-create-frame-with-faces): Added
frame-creation-function parameter.
(tty-create-frame-with-faces): Ditto.

lisp/frame.el (frame-creation-function): Make it frame-local.
(select-frame-set-input-focus): Use the window-system function, not
the variable.

lisp/server.el (server-handle-delete-tty): Make sure the client
process is removed from server-clients after the delete-process call.
It seems that the sentinel is not called.  Added docs.
(server-process-filter): Immediately add the client to server-clients
when a new termcap frame is created.  Fixed a case of `not' called
with two parameters.  Ignore errors while sending the evaluation
result back to the client.
(server-kill-buffer-query-function): Don't ask the user if the server
process is already dead.

lisp/term/x-win.el: Don't change mode-line-frame-identification.

src/buffer.c (syms_of_buffer): Added %T to the docs of mode-line-format.

src/dispnew.c (init_display): Increment the reference count of the new
termcap display.

src/frame.c (make_terminal_frame): Set the old top frame's visibility
to `obscured'.
(Fmake_terminal_frame): Look at the current termcap display's name,
not just the similar frame parameter.  Try to get the type from the
current display first, and only then from Vdefault_frame_alist.

src/keyboard.c (handle_interrupt): New function to separate the signal
handling from C-g processing.
(interrupt_signal): Call handle_interrupt to do the real work.
(kbd_buffer_store_event): Use handle_interrupt instead of interrupt_signal.
(cmd_error_internal): Use FRAME_INITIAL_P instead of ugly hacks.

src/termhooks.h (initial_display): New declaration.

src/xdisp.c (decode_mode_spec): Added '%T' (termcap-only frame name).

git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-49

13 files changed:
README.multi-tty
lisp/bindings.el
lisp/faces.el
lisp/frame.el
lisp/server.el
lisp/term/x-win.el
src/buffer.c
src/dispextern.h
src/dispnew.c
src/frame.c
src/keyboard.c
src/termhooks.h
src/xdisp.c

index cfc1eb9..e797966 100644 (file)
@@ -104,7 +104,7 @@ For the NEWS file:
    specify a terminal device (`tty' parameter) and a terminal type
    (`tty-type' parameter) to `make-terminal-frame'. `tty' must be a
    terminal device created by the updated emacsclient, or there will
-   be problems with terminal input and window resizes.  
+   be problems with terminal input and window resizes.
 
    You can test for the presence of multiple terminal support by
    testing for the `multi-tty' feature.
@@ -138,7 +138,10 @@ THINGS TO DO
    should simply be removed and make-frame changed to do the right
    thing.
 
-** The command `emacsclient -t -e '(delete-frame)'' fails to exit.
+** Fix interactive use of temacs.  There are face-related SEGVs, most
+   likely because of changes in realize_default_face, realize_face.
+
+** Allow opening an X session after -nw.
 
 ** Find out the best way to support suspending Emacs with multiple
    ttys.  My guess: disable it on the controlling tty, but from other
@@ -146,18 +149,11 @@ THINGS TO DO
    extend emacsclient to handle suspend/resume.  A `kill -STOP' almost
    works right now.)
 
-** If there are no frames on its controlling terminal, Emacs should
-   exit if the uses presses C-c there.  (See the SIGTERM comment in
-   interrupt_signal on why this seems to be impossible to solve
-   generally.)
-
-** During an X session, Emacs seems to read from stdin.
+** Exiting Emacs while there are emacsclient frames don't restore the
+   ttys to their default states.
 
 ** Move baud_rate to struct display.
 
-** Do tty output through struct display, like graphical display
-   backends.
-
 ** Implement support for starting an interactive Emacs session without
    an initial frame.  (The user would connect to it and open frames
    later, with emacsclient.)  Not necessarily a good idea.
@@ -212,10 +208,6 @@ THINGS TO DO
    instead of nread > 0 after calling read_socket_hook in
    read_avail_input.
 
-** Define an output_initial value for output_method for the initial
-   frame that is dumped with Emacs.  Checking for this frame (e.g. in
-   cmd_error_internal) is ugly.
-
 ** emacsclient -t from an Emacs term buffer does not work, complains
    about face problems.  This can even lock up Emacs (if the recursive
    frame sets single_kboard).  Update: the face problems are caused by
@@ -227,7 +219,7 @@ DIARY OF CHANGES
 
 (ex-TODO items with explanations.)
 
--- Introduce a new struct for terminal devices.  
+-- Introduce a new struct for terminal devices.
 
    (Done, see struct tty_output.  The list of members is not yet
    complete.)
@@ -251,12 +243,12 @@ DIARY OF CHANGES
    (Update2: After enabling X, they don't.)
 
 -- other-frame should cycle through the frames on the `current'
-   terminal only.  
+   terminal only.
 
    (Done, by trivially modifiying next_frame and prev_frame.)
 
 -- Support different terminal sizes.
-   
+
    (Done, no problem.)
 
 -- Make sure terminal resizes are handled gracefully.  (Could be
@@ -267,12 +259,12 @@ DIARY OF CHANGES
 
 -- Extend emacsclient to automatically open a new tty when it connects
    to Emacs.
-   
+
    (Done.  It's an ugly hack, needs more work.)
 
 -- Redisplay must refresh the topmost frame on *all* terminals, not
    just the initial terminal.
-   
+
    (Done, but introduced an ugly redisplay problems.  Ugh.)
 
 -- Fix redisplay problems.
@@ -343,7 +335,7 @@ DIARY OF CHANGES
    (Done, we do the same as Emacs 21.2 for all terminals.)
 
 -- 'TERM=dumb src/emacs' does not restore the terminal state.
-   
+
    (Done.)
 
 -- C-g should work on secondary terminals.
@@ -500,4 +492,32 @@ DIARY OF CHANGES
    terminal frame during bootstrap which prevented echo_area_display
    from working correctly on a tty frame during a combo session.)
 
+-- If there are no frames on its controlling terminal, Emacs should
+   exit if the uses presses C-c there.
+
+   (Done, as far as possible.  See the SIGTERM comment in
+   interrupt_signal on why this seems to be impossible to solve this
+   in general.)
+
+-- During an X session, Emacs seems to read from stdin.  Also, Emacs
+   fails to start without a controlling tty.
+
+   (Fixed by replacing the troublesome termcap display with a dummy
+   bootstrap display during bootstrap.
+
+-- Do tty output through struct display, like graphical display
+   backends.
+
+   (Done.)
+
+-- Define an output_initial value for output_method for the initial
+   frame that is dumped with Emacs.  Checking for this frame (e.g. in
+   cmd_error_internal) is ugly.
+
+   (Done, broking interactive temacs.)
+
+-- The command `emacsclient -t -e '(delete-frame)'' fails to exit.
+
+   (Fixed.)
+
 ;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
index ed4da74..9d5aa37 100644 (file)
@@ -212,7 +212,7 @@ Major modes that edit things other than ordinary files may change this
 
 (make-variable-buffer-local 'mode-line-buffer-identification)
 
-(defvar mode-line-frame-identification '("-%F  ")
+(defvar mode-line-frame-identification '("-%T  ")
   "Mode-line control to describe the current frame.")
 
 (defvar mode-line-process nil "\
index 1e80cb4..42abb1e 100644 (file)
@@ -1658,7 +1658,8 @@ Value is the new frame created."
   (setq parameters (x-handle-named-frame-geometry parameters))
   (let ((visibility-spec (assq 'visibility parameters))
        (frame-list (frame-list))
-       (frame (x-create-frame (cons '(visibility . nil) parameters)))
+       (frame (x-create-frame `((frame-creation-function . x-create-frame-with-faces)
+                                (visibility . nil) . ,parameters)))
        success)
     (unwind-protect
        (progn
@@ -1744,7 +1745,8 @@ Parameters not specified by PARAMETERS are taken from
 `default-frame-alist'.  If either PARAMETERS or `default-frame-alist'
 contains a `reverse' parameter, handle that.  Value is the new frame
 created."
-  (let ((frame (make-terminal-frame parameters))
+  (let ((frame (make-terminal-frame `((frame-creation-function . tty-create-frame-with-faces) .
+                                     ,parameters)))
        success)
     (unwind-protect
        (progn
index 883ec17..f5c1e64 100644 (file)
@@ -32,6 +32,8 @@
 The window system startup file should set this to its frame creation
 function, which should take an alist of parameters as its argument.")
 
+(make-variable-frame-local 'frame-creation-function)
+
 ;; The initial value given here used to ask for a minibuffer.
 ;; But that's not necessary, because the default is to have one.
 ;; By not specifying it here, we let an X resource specify it.
@@ -706,9 +708,9 @@ automatically."
     (select-frame frame)
     (raise-frame frame)
     ;; Ensure, if possible, that frame gets input focus.
-    (cond ((eq window-system 'x)
+    (cond ((eq (window-system frame) 'x)
           (x-focus-frame frame))
-         ((eq window-system 'w32)
+         ((eq (window-system frame) 'w32)
           (w32-focus-frame frame)))
     (cond (focus-follows-mouse
           (set-mouse-position (selected-frame) (1- (frame-width)) 0))))
index 7b42d0f..315a154 100644 (file)
@@ -212,13 +212,18 @@ are done with it in the server.")
   (server-log (format "Status changed to %s" (process-status proc)) proc))
 
 (defun server-handle-delete-tty (tty)
+  "Delete the client connection when the emacsclient frame is deleted."
   (dolist (entry server-ttys)
     (let ((proc (nth 0 entry))
          (term (nth 1 entry)))
       (when (equal term tty)
        (let ((client (assq proc server-clients)))
          (setq server-ttys (delq entry server-ttys))
-         (delete-process (car client)))))))
+         (delete-process (car client))
+         (when (assq proc server-clients)
+           ;; This seems to be necessary to handle
+           ;; `emacsclient -t -e '(delete-frame)'' correctly.
+           (setq server-clients (delq client server-clients))))))))
 
 (defun server-select-display (display)
   ;; If the current frame is on `display' we're all set.
@@ -336,6 +341,7 @@ PROC is the server process.  Format of STRING is \"PATH PATH PATH... \\n\"."
                              (or file-name-coding-system
                                  default-file-name-coding-system)))
          client nowait eval newframe
+         registered    ; t if the client is already added to server-clients.
          (files nil)
          (lineno 1)
          (columnno 0))
@@ -363,11 +369,13 @@ PROC is the server process.  Format of STRING is \"PATH PATH PATH... \\n\"."
              (condition-case err
                  (let ((frame (make-frame-on-tty tty type)))
                    (setq server-ttys (cons (list (car client) (frame-tty-name frame)) server-ttys))
-                   (sit-for 0)
                    (process-send-string proc (concat "emacs-pid " (number-to-string (emacs-pid)) "\n"))
                    (select-frame frame)
-                   (setq newframe t))
-               (error (ignore-errors (process-send-string proc (concat (nth 1 err) "\n")))
+                   ;; This makes sure that `emacsclient -t -e '(delete-frame)'' works right.
+                   (push client server-clients)
+                   (setq registered t
+                         newframe t))
+               (error (process-send-string proc (concat (nth 1 err) "\n"))
                       (setq request "")))))
           ;; ARG is a line number option.
           ((string-match "\\`\\+[0-9]+\\'" arg)
@@ -386,12 +394,15 @@ PROC is the server process.  Format of STRING is \"PATH PATH PATH... \\n\"."
            (if eval
                (condition-case err
                    (let ((v (eval (car (read-from-string arg)))))
-                     (when (and (not newframe v))
+                     (when (and (not newframe) v)
                        (with-temp-buffer
                          (let ((standard-output (current-buffer)))
                            (pp v)
                            (process-send-region proc (point-min) (point-max))))))
-                 (error (process-send-string proc (concat "*Error* " (error-message-string err)))))
+                 (error
+                  (ignore-errors
+                    (process-send-string
+                     proc (concat "*Error* " (error-message-string err))))))
 
              ;; ARG is a file name.
              ;; Collapse multiple slashes to single slashes.
@@ -410,7 +421,7 @@ PROC is the server process.  Format of STRING is \"PATH PATH PATH... \\n\"."
            (delete-process proc)
            (server-log "Close empty client" proc))
        ;; We visited some buffer for this client.
-       (or nowait (push client server-clients))
+       (or nowait registered (push client server-clients))
        (unless (or isearch-mode (minibufferp))
          (if (and newframe (null (cdr client)))
              (message (substitute-command-keys
@@ -571,6 +582,11 @@ specifically for the clients and did not exist before their request for it."
 ;; using whatever is on disk in that file. -- rms.
 (defun server-kill-buffer-query-function ()
   (or (not server-buffer-clients)
+      (let ((res t))
+       (dolist (proc server-buffer-clients res)
+         (setq proc (assq proc server-clients))
+         (when (and proc (eq (process-status (car proc)) 'open))
+           (setq res nil))))
       (yes-or-no-p (format "Buffer `%s' still has clients; kill it? "
                           (buffer-name (current-buffer))))))
 
index d6260cb..2388b7e 100644 (file)
@@ -2443,9 +2443,6 @@ order until succeed.")
 ;;; that this is only annoying.
 (setq split-window-keep-point t)
 
-;; Don't show the frame name; that's redundant with X.
-(setq-default mode-line-frame-identification "  ")
-
 ;; Motif direct handling of f10 wasn't working right,
 ;; So temporarily we've turned it off in lwlib-Xm.c
 ;; and turned the Emacs f10 back on.
index 533e2c9..d0830c8 100644 (file)
@@ -5364,7 +5364,7 @@ A string is printed verbatim in the mode line except for %-constructs:
   (%-constructs are allowed when the string is the entire mode-line-format
    or when it is found in a cons-cell or a list)
   %b -- print buffer name.      %f -- print visited file name.
-  %F -- print frame name.
+  %F -- print frame name.       %T -- print frame name if on tty.
   %* -- print %, * or hyphen.   %+ -- print *, % or hyphen.
        %& is like %*, but ignore read-only-ness.
        % means buffer is read-only and * means it is modified.
index a30a86f..9aa25b6 100644 (file)
@@ -2750,7 +2750,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 fatal P_ ((/* char *, ... */));
-void cursor_to P_ ((int, int));
+extern void cursor_to P_ ((int, int));
 extern int tty_capable_p P_ ((struct tty_display_info *, unsigned, unsigned long, unsigned long));
 
 /* Defined in scroll.c */
index 72669aa..c692cee 100644 (file)
@@ -6650,6 +6650,7 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
     f->output_method = d->type;
     f->display = d;
 
+    d->reference_count++;
     d->display_info.tty->top_frame = selected_frame;
     change_frame_size (XFRAME (selected_frame), FrameRows (d->display_info.tty), FrameCols (d->display_info.tty), 0, 0, 1);
 
index 57b9af1..ac4f2a5 100644 (file)
@@ -630,6 +630,10 @@ make_terminal_frame (tty_name, tty_type)
 #endif
 
     /* Set the top frame to the newly created frame. */
+    if (FRAME_TTY (f)->top_frame
+        && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
+      XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
+    
     FRAME_TTY (f)->top_frame = frame;
   }
   
@@ -695,19 +699,25 @@ Note that changing the size of one terminal frame automatically affects all.  */
     tty = Fassq (Qtty, parms);
     if (EQ (tty, Qnil))
       tty = Fassq (Qtty, XFRAME (selected_frame)->param_alist);
+    if (EQ (tty, Qnil) && FRAME_TERMCAP_P (XFRAME (selected_frame))
+        && FRAME_TTY (XFRAME (selected_frame))->name)
+      tty = build_string (FRAME_TTY (XFRAME (selected_frame))->name);
     if (EQ (tty, Qnil))
       tty = Fassq (Qtty, Vdefault_frame_alist);
-    if (! EQ (tty, Qnil))
+    if (! EQ (tty, Qnil) && ! STRINGP (tty))
       tty = XCDR (tty);
     if (EQ (tty, Qnil) || !STRINGP (tty))
       tty = Qnil;
 
     tty_type = Fassq (Qtty_type, parms);
-    if (EQ (tty_type, Qnil))
-      tty_type = Fassq (Qtty_type, Vdefault_frame_alist);
     if (EQ (tty_type, Qnil))
       tty_type = Fassq (Qtty, XFRAME (selected_frame)->param_alist);
-    if (! EQ (tty_type, Qnil))
+    if (EQ (tty_type, Qnil) && FRAME_TERMCAP_P (XFRAME (selected_frame))
+        && FRAME_TTY (XFRAME (selected_frame))->type)
+      tty_type = build_string (FRAME_TTY (XFRAME (selected_frame))->type);
+    if (EQ (tty_type, Qnil))
+      tty_type = Fassq (Qtty_type, Vdefault_frame_alist);
+    if (! EQ (tty_type, Qnil) && ! STRINGP (tty_type))
       tty_type = XCDR (tty_type);
     if (EQ (tty_type, Qnil) || !STRINGP (tty_type))
       tty_type = Qnil;
index dd939f3..124eb06 100644 (file)
@@ -692,6 +692,7 @@ static Lisp_Object apply_modifiers P_ ((int, Lisp_Object));
 static void clear_event P_ ((struct input_event *));
 static void any_kboard_state P_ ((void));
 static SIGTYPE interrupt_signal P_ ((int signalnum));
+static void handle_interrupt P_ ((void));
 
 /* Nonzero means don't try to suspend even if the operating system seems
    to support it.  */
@@ -1202,10 +1203,7 @@ cmd_error_internal (data, context)
   if (!sf->glyphs_initialized_p
       /* This is the case of the frame dumped with Emacs, when we're
         running under a window system.  */
-      || (!NILP (Vwindow_system)
-         && !inhibit_window_system
-         && FRAME_TERMCAP_P (sf)
-          && !FRAME_TTY (sf)->type) /* XXX This is ugly. */
+      || FRAME_INITIAL_P (sf)
       || noninteractive)
     {
       stream = Qexternal_debugging_output;
@@ -3606,7 +3604,7 @@ kbd_buffer_store_event (event)
          }
 
          last_event_timestamp = event->timestamp;
-         interrupt_signal (0 /* dummy */);
+         handle_interrupt ();
          return;
        }
 
@@ -10235,10 +10233,10 @@ set_waiting_for_input (time_to_clear)
 {
   input_available_clear_time = time_to_clear;
 
-  /* Tell interrupt_signal to throw back to read_char,  */
+  /* Tell handle_interrupt to throw back to read_char,  */
   waiting_for_input = 1;
 
-  /* If interrupt_signal was called before and buffered a C-g,
+  /* If handle_interrupt was called before and buffered a C-g,
      make it run again now, to avoid timing error. */
   if (!NILP (Vquit_flag))
     quit_throw_to_read_char ();
@@ -10247,7 +10245,7 @@ set_waiting_for_input (time_to_clear)
 void
 clear_waiting_for_input ()
 {
-  /* Tell interrupt_signal not to throw back to read_char,  */
+  /* Tell handle_interrupt not to throw back to read_char,  */
   waiting_for_input = 0;
   input_available_clear_time = 0;
 }
@@ -10263,16 +10261,16 @@ clear_waiting_for_input ()
 
    Otherwise it sets the Lisp variable quit-flag not-nil.  This causes
    eval to throw, when it gets a chance.  If quit-flag is already
-   non-nil, it stops the job right away.  */
+   non-nil, it stops the job right away.
+
+   XXX This comment needs to be updated.  */
 
 static SIGTYPE
 interrupt_signal (signalnum)   /* If we don't have an argument, */
      int signalnum;            /* some compilers complain in signal calls. */
 {
-  char c;
   /* Must preserve main program's value of errno.  */
   int old_errno = errno;
-  struct frame *sf = SELECTED_FRAME ();
 
 #if defined (USG) && !defined (POSIX_SIGNALS)
   /* USG systems forget handlers when they are used;
@@ -10298,6 +10296,20 @@ interrupt_signal (signalnum)   /* If we don't have an argument, */
       return;
     }
 
+  handle_interrupt ();
+
+  errno = old_errno;
+}
+
+/* C-g processing, signal independent code.
+
+   XXX Expand this comment.  */
+static void
+handle_interrupt ()
+{
+  char c; 
+  struct frame *sf = SELECTED_FRAME ();
+
   cancel_echoing ();
 
   /* XXX This code needs to be revised for multi-tty support. */
@@ -10418,8 +10430,6 @@ interrupt_signal (signalnum)    /* If we don't have an argument, */
 
   if (waiting_for_input && !echoing)
     quit_throw_to_read_char ();
-
-  errno = old_errno;
 }
 
 /* Handle a C-g by making read_char return C-g.  */
index 59f19c6..7114621 100644 (file)
@@ -528,5 +528,8 @@ extern struct display *display_list;
 extern struct display *create_display P_ ((void));
 extern void delete_display P_ ((struct display *));
 
+/* The initial display device, created by initial_term_init. */
+extern struct display *initial_display;
+
 /* arch-tag: 33a00ecc-52b5-4186-a410-8801ac9f087d
    (do not change this comment) */
index 65c914d..1164039 100644 (file)
@@ -16213,6 +16213,14 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
       return "T";
 #endif
 
+    case 'T':
+      /* %T is the frame name on a termcap frame, the empty string otherwise. */
+      if (! FRAME_TERMCAP_P (f))
+        return "";
+      if (!NILP (f->title))
+       return (char *) SDATA (f->title);
+      return (char *) SDATA (f->name);
+
     case 'z':
       /* coding-system (not including end-of-line format) */
     case 'Z':