Commit 114a8b8c authored by Karoly Lorentey's avatar Karoly Lorentey

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
parent 3224dac1
......@@ -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
......@@ -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 "\
......
......@@ -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
......
......@@ -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))))
......
......@@ -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))))))
......
......@@ -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.
......
......@@ -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.
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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;
......
......@@ -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. */
......
......@@ -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) */
......@@ -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':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment