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
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.
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
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.
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
(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.)
(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
-- 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.
(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.
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
(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 "\
(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
`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
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.
(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))))
(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.
(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))
(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)
(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.
(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
;; 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))))))
;;; 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.
(%-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.
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 */
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);
#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;
}
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;
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. */
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;
}
last_event_timestamp = event->timestamp;
- interrupt_signal (0 /* dummy */);
+ handle_interrupt ();
return;
}
{
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 ();
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;
}
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;
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. */
if (waiting_for_input && !echoing)
quit_throw_to_read_char ();
-
- errno = old_errno;
}
/* Handle a C-g by making read_char return C-g. */
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) */
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':