Mercurial > emacs
changeset 83009:b2b37c85b00a
Numerous bugfixes and small improvements.
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
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Sat, 10 Jan 2004 12:56:22 +0000 |
parents | 040dd41ed7d0 |
children | 82554ed1aed8 |
files | 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 |
diffstat | 13 files changed, 124 insertions(+), 55 deletions(-) [+] |
line wrap: on
line diff
--- a/README.multi-tty Fri Jan 09 18:57:53 2004 +0000 +++ b/README.multi-tty Sat Jan 10 12:56:22 2004 +0000 @@ -104,7 +104,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ (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 @@ (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 @@ -- 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 @@ (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 @@ 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
--- a/lisp/bindings.el Fri Jan 09 18:57:53 2004 +0000 +++ b/lisp/bindings.el Sat Jan 10 12:56:22 2004 +0000 @@ -212,7 +212,7 @@ (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 "\
--- a/lisp/faces.el Fri Jan 09 18:57:53 2004 +0000 +++ b/lisp/faces.el Sat Jan 10 12:56:22 2004 +0000 @@ -1658,7 +1658,8 @@ (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 @@ `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
--- a/lisp/frame.el Fri Jan 09 18:57:53 2004 +0000 +++ b/lisp/frame.el Sat Jan 10 12:56:22 2004 +0000 @@ -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 @@ (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))))
--- a/lisp/server.el Fri Jan 09 18:57:53 2004 +0000 +++ b/lisp/server.el Sat Jan 10 12:56:22 2004 +0000 @@ -212,13 +212,18 @@ (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 @@ (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 @@ (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 @@ (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 @@ (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 @@ ;; 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))))))
--- a/lisp/term/x-win.el Fri Jan 09 18:57:53 2004 +0000 +++ b/lisp/term/x-win.el Sat Jan 10 12:56:22 2004 +0000 @@ -2443,9 +2443,6 @@ ;;; 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.
--- a/src/buffer.c Fri Jan 09 18:57:53 2004 +0000 +++ b/src/buffer.c Sat Jan 10 12:56:22 2004 +0000 @@ -5364,7 +5364,7 @@ (%-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.
--- a/src/dispextern.h Fri Jan 09 18:57:53 2004 +0000 +++ b/src/dispextern.h Sat Jan 10 12:56:22 2004 +0000 @@ -2750,7 +2750,7 @@ 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 */
--- a/src/dispnew.c Fri Jan 09 18:57:53 2004 +0000 +++ b/src/dispnew.c Sat Jan 10 12:56:22 2004 +0000 @@ -6650,6 +6650,7 @@ 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);
--- a/src/frame.c Fri Jan 09 18:57:53 2004 +0000 +++ b/src/frame.c Sat Jan 10 12:56:22 2004 +0000 @@ -630,6 +630,10 @@ #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 @@ 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); + tty_type = Fassq (Qtty, XFRAME (selected_frame)->param_alist); + 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, XFRAME (selected_frame)->param_alist); - 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;
--- a/src/keyboard.c Fri Jan 09 18:57:53 2004 +0000 +++ b/src/keyboard.c Sat Jan 10 12:56:22 2004 +0000 @@ -692,6 +692,7 @@ 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 @@ 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 @@ } last_event_timestamp = event->timestamp; - interrupt_signal (0 /* dummy */); + handle_interrupt (); return; } @@ -10235,10 +10233,10 @@ { 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 @@ 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 @@ 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 @@ 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 @@ if (waiting_for_input && !echoing) quit_throw_to_read_char (); - - errno = old_errno; } /* Handle a C-g by making read_char return C-g. */
--- a/src/termhooks.h Fri Jan 09 18:57:53 2004 +0000 +++ b/src/termhooks.h Sat Jan 10 12:56:22 2004 +0000 @@ -528,5 +528,8 @@ 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) */
--- a/src/xdisp.c Fri Jan 09 18:57:53 2004 +0000 +++ b/src/xdisp.c Sat Jan 10 12:56:22 2004 +0000 @@ -16213,6 +16213,14 @@ 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':