Commit b6660415 authored by Karoly Lorentey's avatar Karoly Lorentey

Implemented display ids for multiple emacsclients on the same tty. Plus assorted bugfixes.

* lisp/frame.el (make-frame-on-display): Update doc.
(make-frame): Handle display-id parameter.  Update doc.
(frames-on-display-list): Update for display ids.
(framep-on-display): Ditto.
(suspend-frame): Use display-name, not frame-tty-name.
(selected-display): New function.

* lisp/server.el (server-delete-client): Use delete-display, not delete-tty.
(server-tty-live-p, server-handle-delete-tty): Removed.
(server-handle-delete-frame): Delete tty clients, if needed.
(server-process-filter): Set the display parameter, and use it when appropriate.
(server-handle-suspend-tty): Use the display parameter.
(server-start, server-unload-hook): Removed obsolete delete-tty hook.

* lisp/talk.el (talk): Always use talk-add-display.
(talk-add-tty-frame, talk-handle-delete-tty): Removed.
(talk-handle-delete-frame): New function.
(talk-add-display): Open a new frame only if parameter was not a frame.

* src/dispextern.h (get_display, Fdisplay_tty_type):  New prototypes.
(Fframe_tty_type): Removed.

* src/dispnew.c (init_display): Use Fdisplay_tty_type, not Fframe_tty_type.

* src/frame.c (Qdisplay_id, Qdisplay_live_p): New symbols.
(make_terminal_frame): Get display as a parameter.
(Fmake_terminal_frame): Get/create display here; pass it to
make_terminal_frame.
(Fframe_display): New function.
(Fdelete_frame): Stop if the hook deleted the frame.
(syms_of_frame): Register new stuff.

* src/frame.h (Qdisplay_id, Qdisplay_live_p, make_terminal_frame):
Updated prototypes.

* src/keyboard.c (interrupt_signal): Updated comment.

* src/term.c (Vdelete_tty_after_functions): Removed variable.
(Qframe_tty_name, Qframe_tty_type): Removed.
(next_display_id): New var.
(tty_ring_bell): Don't do anything on suspended frames.
(Ftty_display_color_p, Ftty_display_color_cells): Doc update.
(get_display): New function.
(get_tty_display): Use it.
(get_named_tty_display): Ignore suspended displays.
(Fframe_tty_name): Renamed to Fdisplay_name.  Handle all kinds of
displays.
(Fframe_tty_type): Renamed to Fdisplay_tty_type.
(init_initial_display): Set display name.
(term_init): Allow more displays on the same device.  Set display name.
(Fdelete_tty): Removed.
(delete_tty): Don't run hooks.
(create_display): Set display id.
(delete_display): Free display name.
(Fdelete_display, Fdisplay_live_p, Fdisplay_list): New functions.
(Fsuspend_tty): Call hook with display id.  Doc update.
(Fresume_tty): Refuse to resume when there is already an active display
on the same device.  Call hook with display id.  Doc update.
(syms_of_term): Reflect above changes.

* src/termhooks.h (struct display): Added `id' and `name' members.
(DISPLAY_ACTIVE_P): New macro.

* src/xfns.c (check_x_display_info): Handle display ids.
(Fx_create_frame): Try to get display from `display-id' parameter.

* src/xterm.c (x_term_init): Set display name.
(x_delete_display): Handle the case when `font_table' is NULL.

git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-207
parent 91b726f0
......@@ -206,6 +206,9 @@ See arch logs.
THINGS TO DO
------------
** Hunt down display-related functions in frame.el and extend them all
to accept display ids.
** Have a look at fatal_error_hook.
** Check if we got term-setup-hook right.
......@@ -255,45 +258,6 @@ THINGS TO DO
** Miles Bader suggests that C-x C-c on an emacsclient frame should
only close the frame, not exit the entire Emacs session.
** Make `struct display' accessible to Lisp programs. Accessor functions:
(displayp OBJECT): Returns t if OBJECT is a display.
(display-list): Returns list of currently active displays.
(selected-display): Returns the display object of the selected frame.
(frame-display FRAME): Returns the display object of FRAME.
(display-frames DISPLAY): Returns a list of frames on DISPLAY.
(display-type DISPLAY): Returns the type of DISPLAY, as a
symbol. (See `framep'.)
(display-device DISPLAY): Returns the name of the device that
DISPLAY uses, as a string. (E.g: "/dev/pts/16", or
":0.0")
etc.
See next issue why this is necessary.
(Update: The consensus on emacs-devel seems to be to do this via
integer identifiers. That's fine by me.)
** The following needs to be supported:
$ emacsclient -t
C-z
$ emacsclient -t
(This fails now.)
The cleanest way to solve this is to allow multiple displays on the
same terminal device; each new emacsclient process should create
its own display. As displays are currently identified by their
device names, this is not possible until struct display becomes
accessible as a Lisp-level object.
** Very strange bug: visible-bell does not work on secondary
terminals in xterm and konsole. The screen does flicker a bit,
but it's so quick it isn't noticable.
......@@ -813,4 +777,55 @@ DIARY OF CHANGES
(Fixed. Emacs now uses the locale settings as seen by the
emacsclient process for server tty frames.)
-- Make `struct display' accessible to Lisp programs. Accessor functions:
(displayp OBJECT): Returns t if OBJECT is a display.
=> Implemented as display-live-p.
(display-list): Returns list of currently active displays.
=> Implemented.
(selected-display): Returns the display object of the selected frame.
=> Not strictly necessary, but implemented anyway.
(frame-display FRAME): Returns the display object of FRAME.
=> Implemented.
(display-frames DISPLAY): Returns a list of frames on DISPLAY.
=> Already implemented, see frames-on-display-list.
(display-type DISPLAY): Returns the type of DISPLAY, as a
symbol. (See `framep'.)
=> Implemented as display-live-p.
(display-device DISPLAY): Returns the name of the device that
DISPLAY uses, as a string. (E.g: "/dev/pts/16", or
":0.0")
=> Implemented as display-name.
etc.
See next issue why this is necessary.
(Update: The consensus on emacs-devel seems to be to do this via
integer identifiers. That's fine by me.)
(Done.)
-- The following needs to be supported:
$ emacsclient -t
C-z
$ emacsclient -t
(This fails now.)
The cleanest way to solve this is to allow multiple displays on the
same terminal device; each new emacsclient process should create
its own display. As displays are currently identified by their
device names, this is not possible until struct display becomes
accessible as a Lisp-level object.
(Done.)
;;; arch-tag: 8da1619e-2e79-41a8-9ac9-a0485daad17d
......@@ -577,7 +577,7 @@ is not considered (see `next-frame')."
(select-frame-set-input-focus (selected-frame)))
(defun make-frame-on-display (display &optional parameters)
"Make a frame on display DISPLAY.
"Make a frame on X display DISPLAY.
The optional second argument PARAMETERS specifies additional frame parameters."
(interactive "sMake frame on display: ")
(or (string-match "\\`[^:]*:[0-9]+\\(\\.[0-9]+\\)?\\'" display)
......@@ -638,13 +638,22 @@ You cannot specify either `width' or `height', you must use neither or both.
(window-system . nil) The frame should be displayed on a terminal device.
(window-system . x) The frame should be displayed in an X window.
(display-id . ID) The frame should use the display identified by ID.
Before the frame is created (via `frame-creation-function-alist'), functions on the
hook `before-make-frame-hook' are run. After the frame is created, functions
on `after-make-frame-functions' are run with one arg, the newly created frame."
(interactive)
(let* ((w (if (assq 'window-system parameters)
(cdr (assq 'window-system parameters))
window-system))
(let* ((w (cond
((assq 'display-id parameters)
(let ((type (display-live-p (cdr (assq 'display-id parameters)))))
(cond
((eq type t) nil)
((eq type nil) (error "Display %s does not exist" (cdr (assq 'display-id parameters))))
(t type))))
((assq 'window-system parameters)
(cdr (assq 'window-system parameters)))
(t window-system)))
(frame-creation-function (cdr (assq w frame-creation-function-alist)))
frame)
(unless frame-creation-function
......@@ -674,20 +683,25 @@ on `after-make-frame-functions' are run with one arg, the newly created frame."
(defun frames-on-display-list (&optional display)
"Return a list of all frames on DISPLAY.
DISPLAY is a name of a display, a string of the form HOST:SERVER.SCREEN.
DISPLAY should be a display identifier (an integer), but it may
also be a name of a display, a string of the form HOST:SERVER.SCREEN.
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
(let* ((display (or display (frame-parameter nil 'display)))
(let* ((display (or display (frame-display)))
(func #'(lambda (frame)
(equal (frame-parameter frame 'display) display))))
(or (eq (frame-display frame) display)
(equal (frame-parameter frame 'display) display)))))
(filtered-frame-list func)))
(defun framep-on-display (&optional display)
"Return the type of frames on DISPLAY.
DISPLAY may be a display name or a frame. If it is a frame, its type is
returned.
DISPLAY may be a display id, a display name or a frame. If it is
a frame, its type is returned.
If DISPLAY is omitted or nil, it defaults to the selected frame's display.
All frames on a given display are of the same type."
(or (framep display)
(or (display-live-p display)
(framep display)
(framep (car (frames-on-display-list display)))))
(defun frame-remove-geometry-params (param-list)
......@@ -774,7 +788,7 @@ Calls `suspend-emacs' if invoked from the controlling terminal,
(cond
((eq type 'x) (iconify-or-deiconify-frame))
((eq type t)
(if (frame-tty-name)
(if (display-name)
(suspend-tty)
(suspend-emacs)))
(t (suspend-emacs)))))
......@@ -1023,6 +1037,10 @@ bars (top, bottom, or nil)."
(cons vert hor)))
;;;; Frame/display capabilities.
(defun selected-display ()
"Return the display that is now selected."
(frame-display (selected-frame)))
(defun display-mouse-p (&optional display)
"Return non-nil if DISPLAY has a mouse available.
DISPLAY can be a display name, a frame, or nil (meaning the selected
......
......@@ -234,9 +234,9 @@ If NOFRAME is non-nil, let the frames live. (To be used from
(kill-buffer (current-buffer))))))
;; Delete the client's tty.
(let ((tty (server-client-get client 'tty)))
(when (and tty (server-tty-live-p tty))
(delete-tty tty)))
(let ((display-id (server-client-get client 'display)))
(when (eq (display-live-p display-id) t)
(delete-display display-id)))
;; Delete the client's frames.
(unless noframe
......@@ -264,38 +264,32 @@ If NOFRAME is non-nil, let the frames live. (To be used from
string)
(or (bolp) (newline)))))
(defun server-tty-live-p (tty)
"Return non-nil if the tty device named TTY has a live frame."
(let (result)
(dolist (frame (frame-list) result)
(when (and (eq (frame-live-p frame) t)
(equal (frame-tty-name frame) tty))
(setq result t)))))
(defun server-sentinel (proc msg)
"The process sentinel for Emacs server connections."
(server-log (format "Status changed to %s: %s" (process-status proc) msg) proc)
(server-delete-client proc))
(defun server-handle-delete-tty (tty)
"Delete the client connection when the emacsclient terminal device is closed."
(dolist (proc (server-clients-with 'tty tty))
(server-log (format "server-handle-delete-tty, tty %s" tty) proc)
(server-delete-client proc)))
(defun server-handle-delete-frame (frame)
"Delete the client connection when the emacsclient frame is deleted."
(let ((proc (frame-parameter frame 'client)))
(when (and proc (window-system frame))
;; (Closing a terminal frame must not trigger a delete;
;; we must wait for delete-tty-after-functions.)
(when (and proc
(or (window-system frame)
;; A terminal display must not yet be deleted if
;; there are other frames on it.
(< 0 (let ((frame-num 0))
(mapc (lambda (f)
(when (eq (frame-display f)
(frame-display frame))
(setq frame-num (1+ frame-num))))
(frame-list))
frame-num))))
(server-log (format "server-handle-delete-frame, frame %s" frame) proc)
(server-delete-client proc 'noframe)))) ; Let delete-frame delete the frame later.
(defun server-handle-suspend-tty (tty)
(defun server-handle-suspend-tty (display)
"Notify the emacsclient process to suspend itself when its tty device is suspended."
(dolist (proc (server-clients-with 'tty tty))
(server-log (format "server-handle-suspend-tty, tty %s" tty) proc)
(dolist (proc (server-clients-with 'display display))
(server-log (format "server-handle-suspend-tty, display %s" display) proc)
(process-send-string proc "-suspend \n")))
(defun server-select-display (display)
......@@ -395,7 +389,6 @@ Prefix arg means just kill any existing server communications subprocess."
(server-log (message "Restarting server"))
(server-log (message "Starting server")))
(letf (((default-file-modes) ?\700))
(add-hook 'delete-tty-after-functions 'server-handle-delete-tty)
(add-hook 'suspend-tty-functions 'server-handle-suspend-tty)
(add-hook 'delete-frame-functions 'server-handle-delete-frame)
(add-hook 'kill-buffer-query-functions 'server-kill-buffer-query-function)
......@@ -496,21 +489,24 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"."
(modify-frame-parameters frame (list (cons 'client proc)))
(select-frame frame)
(server-client-set client 'frame frame)
(server-client-set client 'display (frame-display frame))
(setq dontkill t))
;; -resume: Resume a suspended tty frame.
((equal "-resume" arg)
(let ((tty (server-client-get client 'tty)))
(let ((display-id (server-client-get client 'display)))
(setq dontkill t)
(when tty (resume-tty tty))))
(when (eq (display-live-p display-id) t)
(resume-tty display-id))))
;; -suspend: Suspend the client's frame. (In case we
;; get out of sync, and a C-z sends a SIGTSTP to
;; emacsclient.)
((equal "-suspend" arg)
(let ((tty (server-client-get client 'tty)))
(let ((display-id (server-client-get client 'display)))
(setq dontkill t)
(when tty (suspend-tty tty))))
(when (eq (display-live-p display-id) t)
(suspend-tty display-id))))
;; -ignore COMMENT: Noop; useful for debugging emacsclient.
;; (The given comment appears in the server log.)
......@@ -528,7 +524,8 @@ PROC is the server process. Format of STRING is \"PATH PATH PATH... \\n\"."
(setq frame (make-frame-on-tty tty type (list (cons 'client proc))))
(select-frame frame)
(server-client-set client 'frame frame)
(server-client-set client 'tty (frame-tty-name frame))
(server-client-set client 'tty (display-name frame))
(server-client-set client 'display (frame-display frame))
;; Set up display for the remote locale.
(configure-display-for-locale)
;; Reply with our pid.
......@@ -912,7 +909,6 @@ If FRAME is nil or missing, then the selected frame is used."
(defun server-unload-hook ()
(server-start t)
(remove-hook 'delete-tty-after-functions 'server-handle-delete-tty)
(remove-hook 'suspend-tty-functions 'server-handle-suspend-tty)
(remove-hook 'delete-frame-functions 'server-handle-delete-frame)
(remove-hook 'kill-buffer-query-functions 'server-kill-buffer-query-function)
......
......@@ -49,41 +49,39 @@ Each element has the form (DISPLAY FRAME BUFFER).")
(defun talk ()
"Connect to the Emacs talk group from the current X display or tty frame."
(interactive)
(let ((type (frame-live-p (selected-frame))))
(if (eq type t)
;; Termcap frame
(talk-add-tty-frame (selected-frame))
(if (eq type 'x)
;; X frame
(talk-add-display (frame-parameter (selected-frame) 'display))
(error "Could not determine frame type"))))
(let ((type (frame-live-p (selected-frame)))
(display (frame-display (selected-frame))))
(cond
((eq type t)
(talk-add-display (selected-frame)))
((eq type 'x)
(talk-add-display (frame-display (selected-frame))))
(t
(error "Unknown frame type"))))
(talk-update-buffers))
(defun talk-add-display (display)
(let* ((elt (assoc display talk-display-alist))
(name (concat "*talk-" display "*"))
buffer frame)
(if (not (and elt (frame-live-p (setq frame (nth 1 elt)))))
(setq frame (make-frame-on-display display (list (cons 'name name)))))
(if (not (and elt (buffer-name (get-buffer (setq buffer (nth 2 elt))))))
(setq buffer (get-buffer-create name)))
(setq talk-display-alist
(cons (list display frame buffer) (delq elt talk-display-alist)))))
(defun talk-add-tty-frame (frame)
(let* ((elt (assoc (frame-tty-name frame) talk-display-alist))
(name (concat "*talk-" (frame-tty-name frame) "*"))
(defun talk-add-display (frame)
(let* ((display (if (frame-live-p frame)
(frame-display frame)
frame))
(elt (assoc display talk-display-alist))
(name (concat "*talk-" (display-name display) "*"))
buffer)
(unless (frame-live-p frame)
(setq frame (make-frame-on-display display (list (cons 'name name)))))
(if (and elt (frame-live-p (nth 1 elt)))
(setq frame (nth 1 elt)))
(if (not (and elt (buffer-name (get-buffer (setq buffer (nth 2 elt))))))
(setq buffer (get-buffer-create name)))
(add-to-list 'delete-tty-after-functions 'talk-handle-delete-tty)
(add-to-list 'delete-frame-functions 'talk-handle-delete-frame)
(setq talk-display-alist
(cons (list (frame-tty-name frame) frame buffer) (delq elt talk-display-alist)))))
(cons (list display frame buffer) (delq elt talk-display-alist)))))
(defun talk-handle-delete-tty (tty)
(let ((elt (assoc tty talk-display-alist)))
(setq talk-display-alist (delq elt talk-display-alist))
(talk-update-buffers)))
(defun talk-handle-delete-frame (frame)
(dolist (d talk-display-alist)
(when (eq (nth 1 d) frame)
(setq talk-display-alist (delq d talk-display-alist))
(talk-update-buffers))))
(defun talk-disconnect ()
"Disconnect this display from the Emacs talk group."
......
......@@ -2859,8 +2859,9 @@ extern int per_line_cost P_ ((char *));
extern void calculate_costs P_ ((struct frame *));
extern void set_tty_color_mode P_ ((struct frame *, Lisp_Object));
extern void tty_setup_colors P_ ((struct tty_display_info *, int));
extern struct display *get_display P_ ((Lisp_Object display));
extern struct display *get_named_tty_display P_ ((char *));
extern Lisp_Object Fframe_tty_type P_ ((Lisp_Object));
EXFUN (Fdisplay_tty_type, 1);
extern struct display *init_initial_display P_ ((void));
extern struct display *term_init P_ ((char *, char *, int));
extern void delete_tty P_ ((struct display *));
......
......@@ -6757,7 +6757,7 @@ For types not defined in VMS, use define emacs_term \"TYPE\".\n\
/* Update frame parameters to reflect the new type. */
Fmodify_frame_parameters
(selected_frame, Fcons (Fcons (Qtty_type,
Fframe_tty_type (selected_frame)), Qnil));
Fdisplay_tty_type (selected_frame)), Qnil));
}
{
......
......@@ -76,6 +76,8 @@ Lisp_Object Qinhibit_default_face_x_resources;
Lisp_Object Qx_frame_parameter;
Lisp_Object Qx_resource_name;
Lisp_Object Qdisplay_id;
Lisp_Object Qdisplay_live_p;
/* Frame parameters (set or reported). */
......@@ -558,19 +560,12 @@ make_initial_frame (void)
struct frame *
make_terminal_frame (tty_name, tty_type)
char *tty_name;
char *tty_type;
make_terminal_frame (struct display *display)
{
register struct frame *f;
struct display *display;
Lisp_Object frame;
char name[20];
/* Open the display before creating the new frame, because
create_tty_display might throw an error. */
display = term_init (tty_name, tty_type, 0); /* Errors are not fatal. */
f = make_frame (1);
XSETFRAME (frame, f);
......@@ -673,6 +668,7 @@ affects all frames on the same terminal device. */)
Lisp_Object parms;
{
struct frame *f;
struct display *d = NULL;
Lisp_Object frame, tem;
struct frame *sf = SELECTED_FRAME ();
......@@ -692,53 +688,70 @@ affects all frames on the same terminal device. */)
#endif
#endif
#endif /* not MSDOS */
{
Lisp_Object display_device;
{
Lisp_Object tty, tty_type;
char *name = 0, *type = 0;
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) && ! 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, 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_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;
if (! EQ (tty, Qnil))
{
name = (char *) alloca (SBYTES (tty) + 1);
strncpy (name, SDATA (tty), SBYTES (tty));
name[SBYTES (tty)] = 0;
}
if (! EQ (tty_type, Qnil))
display_device = Fassq (Qdisplay_id, parms);
if (!NILP (display_device))
{
type = (char *) alloca (SBYTES (tty_type) + 1);
strncpy (type, SDATA (tty_type), SBYTES (tty_type));
type[SBYTES (tty_type)] = 0;
display_device = XCDR (display_device);
CHECK_NUMBER (display_device);
d = get_display (XINT (display_device));
if (!d)
wrong_type_argument (Qdisplay_live_p, display_device);
}
f = make_terminal_frame (name, type);
}
if (!d)
{
Lisp_Object tty, tty_type;
char *name = 0, *type = 0;
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) && ! 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, 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_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;
if (! EQ (tty, Qnil))
{
name = (char *) alloca (SBYTES (tty) + 1);
strncpy (name, SDATA (tty), SBYTES (tty));
name[SBYTES (tty)] = 0;
}
if (! EQ (tty_type, Qnil))
{
type = (char *) alloca (SBYTES (tty_type) + 1);
strncpy (type, SDATA (tty_type), SBYTES (tty_type));
type[SBYTES (tty_type)] = 0;
}
d = term_init (name, type, 0); /* Errors are not fatal. */
}
f = make_terminal_frame (d);
{
int width, height;
......@@ -1045,6 +1058,31 @@ If FRAME is the selected frame, this makes WINDOW the selected window. */)
return XFRAME (frame)->selected_window = window;
}
DEFUN ("frame-display", Fframe_display, Sframe_display, 0, 1, 0,
doc: /* Return the display device that FRAME is displayed on.
If FRAME is nil, the selected frame is used.
The display device is represented by its integer identifier. */)
(frame)
Lisp_Object frame;
{
struct display *d;
if (NILP (frame))
frame = selected_frame;
CHECK_LIVE_FRAME (frame);
d = get_display (frame);
if (!d)
return Qnil;
else
return make_number (d->id);
}
DEFUN ("frame-list", Fframe_list, Sframe_list,
0, 0, 0,
......@@ -1387,6 +1425,10 @@ The functions are run with one arg, the frame to be deleted. */)
Frun_hook_with_args (2, args);
}
/* The hook may sometimes (indirectly) cause the frame to be deleted. */
if (! FRAME_LIVE_P (f))
return Qnil;
minibuffer_selected = EQ (minibuf_window, selected_window);
/* Don't let the frame remain selected. */
......@@ -4154,6 +4196,11 @@ syms_of_frame ()
Qx_frame_parameter = intern ("x-frame-parameter");
staticpro (&Qx_frame_parameter);
Qdisplay_id = intern ("display-id");
staticpro (&Qdisplay_id);
Qdisplay_live_p = intern ("display-live-p");
staticpro (&Qdisplay_live_p);
{
int i;
......@@ -4286,6 +4333,7 @@ This variable is local to the current terminal and cannot be buffer-local. */);
defsubr (&Sframe_first_window);
defsubr (&Sframe_selected_window);
defsubr (&Sset_frame_selected_window);
defsubr (&Sframe_display);
defsubr (&Sframe_list);
defsubr (&Snext_frame);
defsubr (&Sprevious_frame);
......
......@@ -775,11 +775,12 @@ typedef struct frame *FRAME_PTR;
extern Lisp_Object Qframep, Qframe_live_p;
extern Lisp_Object Qtty, Qtty_type;
extern Lisp_Object Qdisplay_id, Qdisplay_live_p;
extern struct frame *last_nonminibuf_frame;
extern struct frame *make_initial_frame P_ ((void));
extern struct frame *make_terminal_frame P_ ((char *, char *));
extern struct frame *make_terminal_frame P_ ((struct display *));
extern struct frame *make_frame P_ ((int));
#ifdef HAVE_WINDOW_SYSTEM
extern struct frame *make_minibuffer_frame P_ ((void));
......
......@@ -10317,7 +10317,7 @@ interrupt_signal (signalnum) /* If we don't have an argument, */
signal (SIGQUIT, interrupt_signal);
#endif /* USG */
/* See if we have a display on our controlling terminal. */
/* See if we have an active display on our controlling terminal. */
display = get_named_tty_display (NULL);
if (!display)
{
......
This diff is collapsed.
......@@ -282,12 +282,18 @@ struct display
/* Chain of all displays. */
struct display *next_display;