summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.multi-tty40
-rw-r--r--lisp/simple.el20
-rw-r--r--lisp/termdev.el66
-rw-r--r--mac/makefile.MPW11
-rw-r--r--src/Makefile.in6
-rw-r--r--src/alloc.c2
-rw-r--r--src/dispextern.h45
-rw-r--r--src/emacs.c1
-rw-r--r--src/frame.c78
-rw-r--r--src/keyboard.c2
-rw-r--r--src/keymap.h1
-rw-r--r--src/lisp.h3
-rw-r--r--src/sysdep.c2
-rw-r--r--src/term.c814
-rw-r--r--src/termhooks.h3
-rw-r--r--src/terminal.c596
-rw-r--r--src/xterm.h1
17 files changed, 951 insertions, 740 deletions
diff --git a/README.multi-tty b/README.multi-tty
index c4e990e5b83..ebe064c2fca 100644
--- a/README.multi-tty
+++ b/README.multi-tty
@@ -401,6 +401,41 @@ is probably not very interesting for anyone else.)
THINGS TO DO
------------
+** Implement automatic forwarding of client environment variables to
+ forked processes, as discussed on the multi-tty list. Terminal
+ parameters are now accessible in C code, so the biggest obstacle is
+ gone. The `getenv_internal' and `child_setup' functions in
+ callproc.c must be changed to support the following variable:
+
+ terminal-local-environment-variables is a variable defined in ...
+
+ Enable or disable terminal-local environment variables.
+
+ If set to t, `getenv', `setenv' and subprocess creation
+ functions use the environment variables of the emacsclient
+ process that created the selected frame, ignoring
+ `process-environment'.
+
+ If set to nil, Emacs uses `process-environment' and ignores
+ the client environment.
+
+ Otherwise, `terminal-local-environment-variables' should be a
+ list of variable names (represented by Lisp strings) to look
+ up in the client environment. The rest will come from
+ `process-environment'.
+
+** (Possibly) create hooks in struct device for creating frames on a
+ specific terminal, and eliminate the hackish terminal-related frame
+ parameters (display, tty, tty-type).
+
+ make_terminal_frame
+ create_tty_output
+
+
+** Move Fsend_string_to_terminal to term.c, and declare get_named_tty
+ as static, removing it from dispextern.h.
+ Move fatal to emacs.c and declare it somewhere.
+
** Search for `suspend-emacs' references and replace them with
`suspend-frame', if necessary. Ditto for `save-buffers-kill-emacs'
vs. `save-buffers-kill-display'.
@@ -450,6 +485,11 @@ THINGS TO DO
** I think `(set-)terminal-local-value' and the terminal parameter
mechanism should be integrated into a single framework.
+ (Update: `(set-)terminal-local-value' is now eliminated, but the
+ terminal-local variables should still be accessible as terminal
+ parameters. This also applies to `display-name' and similar
+ functions.)
+
** Add the following hooks: after-delete-frame-hook (for server.el,
instead of delete-frame-functions),
after-delete-terminal-functions, after-create-terminal-functions.
diff --git a/lisp/simple.el b/lisp/simple.el
index bfbdaf14d28..99487430c88 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5323,10 +5323,8 @@ call `normal-erase-is-backspace-mode' (which see) instead."
"Set up `normal-erase-is-backspace-mode' on FRAME, if necessary."
(unless frame (setq frame (selected-frame)))
(with-selected-frame frame
- (unless (terminal-parameter-p nil 'normal-erase-is-backspace)
- (if (cond ((terminal-parameter-p nil 'normal-erase-is-backspace)
- (terminal-parameter nil 'normal-erase-is-backspace))
- ((eq normal-erase-is-backspace 'maybe)
+ (unless (terminal-parameter nil 'normal-erase-is-backspace)
+ (if (cond ((eq normal-erase-is-backspace 'maybe)
(and (not noninteractive)
(or (memq system-type '(ms-dos windows-nt))
(eq window-system 'mac)
@@ -5376,9 +5374,10 @@ See also `normal-erase-is-backspace'."
(interactive "P")
(set-terminal-parameter
nil 'normal-erase-is-backspace
- (if arg
- (> (prefix-numeric-value arg) 0)
- (not (terminal-parameter nil 'normal-erase-is-backspace))))
+ (if (or (and arg (> (prefix-numeric-value arg) 0))
+ (not (eq 1 (terminal-parameter nil 'normal-erase-is-backspace))))
+ 0
+ 1))
(cond ((or (memq window-system '(x w32 mac pc))
(memq system-type '(ms-dos windows-nt)))
@@ -5390,7 +5389,7 @@ See also `normal-erase-is-backspace'."
[C-delete] [C-backspace])))
(old-state (lookup-key local-function-key-map [delete])))
- (if (terminal-parameter nil 'normal-erase-is-backspace)
+ (if (eq 1 (terminal-parameter nil 'normal-erase-is-backspace))
(progn
(define-key local-function-key-map [delete] [?\C-d])
(define-key local-function-key-map [kp-delete] [?\C-d])
@@ -5412,7 +5411,7 @@ See also `normal-erase-is-backspace'."
(define-key map key1 binding2)
(define-key map key2 binding1)))))))
(t
- (if (terminal-parameter nil 'normal-erase-is-backspace)
+ (if (eq 1 (terminal-parameter nil 'normal-erase-is-backspace))
(progn
(keyboard-translate ?\C-h ?\C-?)
(keyboard-translate ?\C-? ?\C-d))
@@ -5422,7 +5421,8 @@ See also `normal-erase-is-backspace'."
(run-hooks 'normal-erase-is-backspace-hook)
(if (interactive-p)
(message "Delete key deletes %s"
- (if normal-erase-is-backspace "forward" "backward"))))
+ (if (terminal-parameter nil 'normal-erase-is-backspace)
+ "forward" "backward"))))
(defvar vis-mode-saved-buffer-invisibility-spec nil
"Saved value of `buffer-invisibility-spec' when Visible mode is on.")
diff --git a/lisp/termdev.el b/lisp/termdev.el
index 667975b9b8b..f413067d542 100644
--- a/lisp/termdev.el
+++ b/lisp/termdev.el
@@ -48,66 +48,6 @@ device (HOST.SERVER.SCREEN) or a tty device file."
(t
(error "Invalid argument %s in `terminal-id'" terminal))))
-(defvar terminal-parameter-alist nil
- "An alist of terminal parameter alists.")
-
-(defun terminal-parameters (&optional terminal)
- "Return the paramater-alist of terminal TERMINAL.
-It is a list of elements of the form (PARM . VALUE), where PARM is a symbol.
-
-TERMINAL can be a terminal id, a frame, or nil (meaning the
-selected frame's terminal)."
- (cdr (assq (terminal-id terminal) terminal-parameter-alist)))
-
-(defun terminal-parameter-p (terminal parameter)
- "Return non-nil if PARAMETER is a terminal parameter on TERMINAL.
-
-The actual value returned in that case is a cell (PARAMETER . VALUE),
-where VALUE is the current value of PARAMETER.
-
-TERMINAL can be a terminal id, a frame, or nil (meaning the
-selected frame's terminal)."
- (assq parameter (cdr (assq (terminal-id terminal) terminal-parameter-alist))))
-
-(defun terminal-parameter (terminal parameter)
- "Return TERMINAL's value for parameter PARAMETER.
-
-TERMINAL can be a terminal id, a frame, or nil (meaning the
-selected frame's terminal)."
- (cdr (terminal-parameter-p terminal parameter)))
-
-(defun set-terminal-parameter (terminal parameter value)
- "Set TERMINAL's value for parameter PARAMETER to VALUE.
-Returns the previous value of PARAMETER.
-
-TERMINAL can be a terminal id, a frame, or nil (meaning the
-selected frame's terminal)."
- (setq terminal (terminal-id terminal))
- (let* ((alist (assq terminal terminal-parameter-alist))
- (pair (assq parameter (cdr alist)))
- (result (cdr pair)))
- (cond
- (pair (setcdr pair value))
- (alist (setcdr alist (cons (cons parameter value) (cdr alist))))
- (t (setq terminal-parameter-alist
- (cons (cons terminal
- (cons (cons parameter value)
- nil))
- terminal-parameter-alist))))
- result))
-
-(defun terminal-handle-delete-frame (frame)
- "Clean up terminal parameters of FRAME, if it's the last frame on its terminal."
- ;; XXX We assume that the display is closed immediately after the
- ;; last frame is deleted on it. It would be better to create a hook
- ;; called `delete-display-functions', and use it instead.
- (when (and (frame-live-p frame)
- (= 1 (length (frames-on-display-list (frame-display frame)))))
- (setq terminal-parameter-alist
- (assq-delete-all (frame-display frame) terminal-parameter-alist))))
-
-(add-hook 'delete-frame-functions 'terminal-handle-delete-frame)
-
(defun terminal-getenv (variable &optional terminal global-ok)
"Get the value of VARIABLE in the client environment of TERMINAL.
VARIABLE should be a string. Value is nil if VARIABLE is undefined in
@@ -125,7 +65,7 @@ its value in the global environment instead.
TERMINAL can be a terminal id, a frame, or nil (meaning the
selected frame's terminal)."
(setq terminal (terminal-id terminal))
- (if (not (terminal-parameter-p terminal 'environment))
+ (if (null (terminal-parameter terminal 'environment))
(getenv variable)
(if (multibyte-string-p variable)
(setq variable (encode-coding-string variable locale-coding-system)))
@@ -156,7 +96,7 @@ process itself.
TERMINAL can be a terminal id, a frame, or nil (meaning the
selected frame's terminal)."
- (if (not (terminal-parameter-p terminal 'environment))
+ (if (null (terminal-parameter terminal 'environment))
(setenv variable value)
(with-terminal-environment terminal variable
(setenv variable value))))
@@ -222,7 +162,7 @@ then the new variable values will be remembered for TERMINAL, and
(if (stringp ,v)
(setq ,v (list ,v)))
(cond
- ((not (terminal-parameter-p ,term 'environment))
+ ((null (terminal-parameter ,term 'environment))
;; Not a remote terminal; nothing to do.
(progn ,@body))
((eq ,v t)
diff --git a/mac/makefile.MPW b/mac/makefile.MPW
index d63ef5bcde1..031a2dddb06 100644
--- a/mac/makefile.MPW
+++ b/mac/makefile.MPW
@@ -118,6 +118,7 @@ EmacsObjects = ¶
"{Src}sysdep.c.x" ¶
"{Src}term.c.x" ¶
"{Src}termcap.c.x" ¶
+ "{Src}terminal.c.x" ¶
"{Src}textprop.c.x" ¶
"{Src}tparam.c.x" ¶
"{Src}undo.c.x" ¶
@@ -792,6 +793,16 @@ buildobj.lst Ä
"{Src}lisp.h" ¶
"{Includes}sys:file.h"
+{Src}terminal.c.x Ä ¶
+ {CONFIG_H_GROUP} ¶
+ "{Src}lisp.h" ¶
+ "{Src}frame.h" ¶
+ "{Src}termchar.h" ¶
+ "{Src}termhooks.h" ¶
+ "{Src}charset.h" ¶
+ "{Src}coding.h" ¶
+ "{Src}keyboard.h"
+
{Src}textproc.c.x Ä ¶
{CONFIG_H_GROUP} ¶
"{Src}lisp.h" ¶
diff --git a/src/Makefile.in b/src/Makefile.in
index e0ba8a25b66..f8029d5e246 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -577,7 +577,7 @@ emacsappsrc = ${srcdir}/../mac/Emacs.app/
whose initialized data areas should be dumped as pure by dump-emacs. */
obj= dispnew.o frame.o scroll.o xdisp.o $(XMENU_OBJ) window.o \
charset.o coding.o category.o ccl.o \
- cm.o term.o xfaces.o $(XOBJ) $(GTK_OBJ)\
+ cm.o term.o terminal.o xfaces.o $(XOBJ) $(GTK_OBJ)\
emacs.o keyboard.o macros.o keymap.o sysdep.o \
buffer.o filelock.o insdel.o marker.o \
minibuf.o fileio.o dired.o filemode.o \
@@ -1171,6 +1171,8 @@ term.o: term.c termchar.h termhooks.h termopts.h $(config_h) cm.h frame.h \
disptab.h dispextern.h keyboard.h charset.h coding.h ccl.h msdos.h \
window.h keymap.h
termcap.o: termcap.c $(config_h)
+terminal.o: terminal.c frame.h termchar.h termhooks.h charset.h coding.h \
+ keyboard.h $(config_h)
terminfo.o: terminfo.c $(config_h)
tparam.o: tparam.c $(config_h)
undo.o: undo.c buffer.h commands.h $(config_h)
@@ -1250,7 +1252,7 @@ sunfns.o: sunfns.c buffer.h window.h dispextern.h termhooks.h $(config_h)
#ifdef HAVE_CARBON
abbrev.o buffer.o callint.o cmds.o dispnew.o editfns.o fileio.o frame.o \
fontset.o indent.o insdel.o keyboard.o macros.o minibuf.o msdos.o process.o \
- scroll.o sysdep.o term.o widget.o window.o xdisp.o xfaces.o xfns.o xmenu.o \
+ scroll.o sysdep.o term.o terminal.o widget.o window.o xdisp.o xfaces.o xfns.o xmenu.o \
xterm.o xselect.o sound.o: macgui.h
mac.o: mac.c process.h sysselect.h blockinput.h atimer.h systime.h charset.h \
coding.h ccl.h $(config_h)
diff --git a/src/alloc.c b/src/alloc.c
index 83ba06277f1..f8ba5f480ab 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -324,6 +324,7 @@ Lisp_Object Vgc_elapsed; /* accumulated elapsed time in GC */
EMACS_INT gcs_done; /* accumulated GCs */
static void mark_buffer P_ ((Lisp_Object));
+extern void mark_devices P_ ((void));
extern void mark_kboards P_ ((void));
extern void mark_ttys P_ ((void));
extern void mark_backtrace P_ ((void));
@@ -4937,6 +4938,7 @@ returns nil, because real GC can't be done. */)
mark_object (bind->symbol);
mark_object (bind->old_value);
}
+ mark_devices ();
mark_kboards ();
mark_ttys ();
diff --git a/src/dispextern.h b/src/dispextern.h
index f5573efdcc4..b473f9cb16b 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2622,8 +2622,6 @@ void init_iterator_to_row_start P_ ((struct it *, struct window *,
struct glyph_row *));
int get_next_display_element P_ ((struct it *));
void set_iterator_to_next P_ ((struct it *, int));
-void produce_glyphs P_ ((struct it *));
-void produce_special_glyphs P_ ((struct it *, enum display_element_type));
void start_display P_ ((struct it *, struct window *, struct text_pos));
void move_it_to P_ ((struct it *, int, int, int, int, int));
void move_it_vertically P_ ((struct it *, int));
@@ -2905,8 +2903,6 @@ void clear_glyph_row P_ ((struct glyph_row *));
void prepare_desired_row P_ ((struct glyph_row *));
int line_hash_code P_ ((struct glyph_row *));
void set_window_update_flags P_ ((struct window *, int));
-void write_glyphs P_ ((struct frame *, struct glyph *, int));
-void insert_glyphs P_ ((struct frame *, struct glyph *, int));
void redraw_frame P_ ((struct frame *));
void redraw_garbaged_frames P_ ((void));
int scroll_cost P_ ((struct frame *, int, int, int));
@@ -2924,39 +2920,48 @@ void syms_of_display P_ ((void));
extern Lisp_Object Qredisplay_dont_pause;
GLYPH spec_glyph_lookup_face P_ ((struct window *, GLYPH));
-/* Defined in term.c */
+/* Defined in terminal.c */
extern void ring_bell P_ ((struct frame *));
extern void update_begin P_ ((struct frame *));
extern void update_end P_ ((struct frame *));
extern void set_terminal_window P_ ((struct frame *, int));
-extern void set_scroll_region P_ ((struct frame *, int, int));
-extern void turn_off_insert P_ ((struct tty_display_info *));
-extern void turn_off_highlight P_ ((struct tty_display_info *));
-extern void background_highlight P_ ((struct tty_display_info *));
+extern void cursor_to P_ ((struct frame *, int, int));
+
+/* Was not declared before: */
+extern void raw_cursor_to P_ ((struct frame *, int, int));
+extern void clear_to_end P_ ((struct frame *));
+
extern void clear_frame P_ ((struct frame *));
extern void clear_end_of_line P_ ((struct frame *, int));
-extern void clear_end_of_line_raw P_ ((struct frame *, int));
-extern void tty_clear_end_of_line P_ ((struct frame *, int));
+extern void write_glyphs P_ ((struct frame *, struct glyph *, int));
+extern void insert_glyphs P_ ((struct frame *, struct glyph *, int));
extern void delete_glyphs P_ ((struct frame *, int));
extern void ins_del_lines P_ ((struct frame *, int, int));
+
+extern struct device *get_device P_ ((Lisp_Object display, int));
+
+extern struct device *init_initial_device P_ ((void));
+
+
+/* Defined in term.c */
+
+extern void tty_set_terminal_modes P_ ((struct device *));
+extern void tty_reset_terminal_modes P_ ((struct device *));
+extern void tty_turn_off_insert P_ ((struct tty_display_info *));
+extern void tty_turn_off_highlight P_ ((struct tty_display_info *));
extern int string_cost P_ ((char *));
extern int per_line_cost P_ ((char *));
extern void calculate_costs P_ ((struct frame *));
+extern void produce_glyphs P_ ((struct it *));
+extern void produce_special_glyphs P_ ((struct it *, enum display_element_type));
+extern int tty_capable_p P_ ((struct tty_display_info *, unsigned, unsigned long, unsigned long));
extern void set_tty_color_mode P_ ((struct frame *, Lisp_Object));
-extern void tty_setup_colors P_ ((struct tty_display_info *, int));
-extern struct device *get_device P_ ((Lisp_Object display, int));
extern struct device *get_tty_device P_ ((Lisp_Object terminal));
extern struct device *get_named_tty P_ ((char *));
EXFUN (Fdisplay_tty_type, 1);
-extern struct device *init_initial_device P_ ((void));
-extern struct device *init_tty P_ ((char *, char *, int));
-extern void delete_tty P_ ((struct device *));
-extern void cursor_to P_ ((struct frame *, int, int));
-extern int tty_capable_p P_ ((struct tty_display_info *, unsigned, unsigned long, unsigned long));
-extern void tty_set_terminal_modes P_ ((struct device *));
-extern void tty_reset_terminal_modes P_ ((struct device *));
extern void create_tty_output P_ ((struct frame *));
+extern struct device *init_tty P_ ((char *, char *, int));
/* Defined in scroll.c */
diff --git a/src/emacs.c b/src/emacs.c
index ff1a40283fc..28b5f374ccd 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1600,6 +1600,7 @@ main (argc, argv
syms_of_frame ();
#endif
syms_of_syntax ();
+ syms_of_terminal ();
syms_of_term ();
syms_of_undo ();
#ifdef HAVE_SOUND
diff --git a/src/frame.c b/src/frame.c
index 9c83f961267..c3140628cec 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -638,6 +638,33 @@ make_terminal_frame (struct device *device)
return f;
}
+/* Get a suitable value for frame parameter PARAMETER for a newly
+ created frame, based on (1) the user-supplied frame parameter
+ alist SUPPLIED_PARMS, (2) CURRENT_VALUE, and finally, if all else
+ fails, (3) Vdefault_frame_alist. */
+
+static Lisp_Object
+get_future_frame_param (Lisp_Object parameter,
+ Lisp_Object supplied_parms,
+ char *current_value)
+{
+ Lisp_Object result;
+
+ result = Fassq (parameter, supplied_parms);
+ if (NILP (result))
+ result = Fassq (parameter, XFRAME (selected_frame)->param_alist);
+ if (NILP (result) && current_value != NULL)
+ result = build_string (current_value);
+ if (NILP (result))
+ result = Fassq (parameter, Vdefault_frame_alist);
+ if (!NILP (result) && !STRINGP (result))
+ result = XCDR (result);
+ if (NILP (result) || !STRINGP (result))
+ result = Qnil;
+
+ return result;
+}
+
DEFUN ("make-terminal-frame", Fmake_terminal_frame, Smake_terminal_frame,
1, 1, 0,
doc: /* Create an additional terminal frame, possibly on another terminal.
@@ -662,8 +689,6 @@ affects all frames on the same terminal device. */)
struct device *d = NULL;
Lisp_Object frame, tem;
struct frame *sf = SELECTED_FRAME ();
- Lisp_Object tty, tty_type;
- struct gcpro gcpro1, gcpro2;
#ifdef MSDOS
if (sf->output_method != output_msdos_raw
@@ -697,41 +722,24 @@ affects all frames on the same terminal device. */)
if (!d)
{
char *name = 0, *type = 0;
+ Lisp_Object tty, tty_type;
- 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_type, 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))
+ tty = get_future_frame_param
+ (Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
+ ? FRAME_TTY (XFRAME (selected_frame))->name
+ : NULL));
+ if (!NILP (tty))
{
name = (char *) alloca (SBYTES (tty) + 1);
strncpy (name, SDATA (tty), SBYTES (tty));
name[SBYTES (tty)] = 0;
}
- if (! EQ (tty_type, Qnil))
+ tty_type = get_future_frame_param
+ (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
+ ? FRAME_TTY (XFRAME (selected_frame))->type
+ : NULL));
+ if (!NILP (tty_type))
{
type = (char *) alloca (SBYTES (tty_type) + 1);
strncpy (type, SDATA (tty_type), SBYTES (tty_type));
@@ -752,13 +760,15 @@ affects all frames on the same terminal device. */)
adjust_glyphs (f);
calculate_costs (f);
XSETFRAME (frame, f);
- GCPRO2 (tty_type, tty);
Fmodify_frame_parameters (frame, Vdefault_frame_alist);
Fmodify_frame_parameters (frame, parms);
Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qnil), Qnil));
- Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type, tty_type), Qnil));
- Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, tty), Qnil));
- UNGCPRO;
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
+ build_string (d->display_info.tty->type)),
+ Qnil));
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty,
+ build_string (d->display_info.tty->name)),
+ Qnil));
/* Make the frame face alist be frame-specific, so that each
frame could change its face definitions independently. */
diff --git a/src/keyboard.c b/src/keyboard.c
index edce75d774c..95f2daf78ac 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1136,7 +1136,6 @@ pop_kboard ()
#ifdef MULTI_KBOARD
struct device *d;
struct kboard_stack *p = kboard_stack;
- int ok = 0;
current_kboard = NULL;
for (d = device_list; d; d = d->next_device)
{
@@ -10739,6 +10738,7 @@ See also `current-input-mode'. */)
init_sys_modes (tty);
#endif
}
+ return Qnil;
}
DEFUN ("set-input-meta-mode", Fset_input_meta_mode, Sset_input_meta_mode, 1, 2, 0,
diff --git a/src/keymap.h b/src/keymap.h
index bcf14abcd89..a6598558a76 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -37,6 +37,7 @@ EXFUN (Fcurrent_active_maps, 1);
extern Lisp_Object access_keymap P_ ((Lisp_Object, Lisp_Object, int, int, int));
extern Lisp_Object get_keyelt P_ ((Lisp_Object, int));
extern Lisp_Object get_keymap P_ ((Lisp_Object, int, int));
+EXFUN (Fset_keymap_parent, 2);
extern void describe_map_tree P_ ((Lisp_Object, int, Lisp_Object, Lisp_Object,
char *, int, int, int, int));
extern int current_minor_maps P_ ((Lisp_Object **, Lisp_Object **));
diff --git a/src/lisp.h b/src/lisp.h
index a18408bd1a6..4b71cd67e98 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3184,6 +3184,9 @@ extern void syms_of_dired P_ ((void));
extern void syms_of_term P_ ((void));
extern void fatal () NO_RETURN;
+/* Defined in terminal.c */
+extern void syms_of_terminal P_ ((void));
+
#ifdef HAVE_X_WINDOWS
/* Defined in fontset.c */
extern void syms_of_fontset P_ ((void));
diff --git a/src/sysdep.c b/src/sysdep.c
index 0cf6ecb1f36..7f9d189d79a 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1972,7 +1972,7 @@ reset_sys_modes (tty_out)
else
{ /* have to do it the hard way */
int i;
- turn_off_insert (tty_out);
+ tty_turn_off_insert (tty_out);
for (i = curX (tty_out); i < FrameCols (tty_out) - 1; i++)
{
diff --git a/src/term.c b/src/term.c
index 679def93c72..b599e1b97fe 100644
--- a/src/term.c
+++ b/src/term.c
@@ -80,14 +80,14 @@ extern int tgetnum P_ ((char *id));
#define O_NOCTTY 0
#endif
+static void tty_set_scroll_region P_ ((struct frame *f, int start, int stop));
static void turn_on_face P_ ((struct frame *, int face_id));
static void turn_off_face P_ ((struct frame *, int face_id));
static void tty_show_cursor P_ ((struct tty_display_info *));
static void tty_hide_cursor P_ ((struct tty_display_info *));
-
-void delete_initial_device P_ ((struct device *));
-void create_tty_output P_ ((struct frame *));
-void delete_tty_output P_ ((struct frame *));
+static void tty_background_highlight P_ ((struct tty_display_info *tty));
+static void dissociate_if_controlling_tty P_ ((int fd));
+static void delete_tty P_ ((struct device *));
#define OUTPUT(tty, a) \
emacs_tputs ((tty), a, \
@@ -113,22 +113,12 @@ void delete_tty_output P_ ((struct frame *));
extern Lisp_Object Qspace, QCalign_to, QCwidth;
-/* Function to use to ring the bell. */
-
-Lisp_Object Vring_bell_function;
-
/* Functions to call after suspending a tty. */
Lisp_Object Vsuspend_tty_functions;
/* Functions to call after resuming a tty. */
Lisp_Object Vresume_tty_functions;
-/* Chain of all displays currently in use. */
-struct device *device_list;
-
-/* The initial display device, created by initial_term_init. */
-struct device *initial_device;
-
/* Chain of all tty device parameters. */
struct tty_display_info *tty_list;
@@ -138,7 +128,6 @@ struct tty_display_info *tty_list;
else. */
int no_redraw_on_reenter;
-
/* Meaning of bits in no_color_video. Each bit set means that the
corresponding attribute cannot be combined with colors. */
@@ -169,9 +158,6 @@ int max_frame_lines;
should not open a frame on stdout. */
static int no_controlling_tty;
-/* The first unallocated display id. */
-static int next_device_id;
-
/* Provided for lisp packages. */
static int system_uses_terminfo;
@@ -192,35 +178,10 @@ extern char *tgetstr ();
#define FRAME_TERMCAP_P(_f_) 0
#endif /* WINDOWSNT */
-void
-ring_bell (struct frame *f)
-{
- if (!NILP (Vring_bell_function))
- {
- Lisp_Object function;
-
- /* Temporarily set the global variable to nil
- so that if we get an error, it stays nil
- and we don't call it over and over.
-
- We don't specbind it, because that would carefully
- restore the bad value if there's an error
- and make the loop of errors happen anyway. */
-
- function = Vring_bell_function;
- Vring_bell_function = Qnil;
-
- call0 (function);
-
- Vring_bell_function = function;
- }
- else if (FRAME_DEVICE (f)->ring_bell_hook)
- (*FRAME_DEVICE (f)->ring_bell_hook) (f);
-}
/* Ring the bell on a tty. */
-void
+static void
tty_ring_bell (struct frame *f)
{
struct tty_display_info *tty = FRAME_TTY (f);
@@ -272,8 +233,8 @@ tty_reset_terminal_modes (struct device *display)
if (tty->output)
{
- turn_off_highlight (tty);
- turn_off_insert (tty);
+ tty_turn_off_highlight (tty);
+ tty_turn_off_insert (tty);
OUTPUT_IF (tty, tty->TS_end_keypad_mode);
OUTPUT_IF (tty, tty->TS_cursor_normal);
OUTPUT_IF (tty, tty->TS_end_termcap_modes);
@@ -285,59 +246,33 @@ tty_reset_terminal_modes (struct device *display)
}
}
-void
-update_begin (struct frame *f)
-{
- if (FRAME_DEVICE (f)->update_begin_hook)
- (*FRAME_DEVICE (f)->update_begin_hook) (f);
-}
-
-void
-update_end (struct frame *f)
-{
- if (FRAME_DEVICE (f)->update_end_hook)
- (*FRAME_DEVICE (f)->update_end_hook) (f);
-}
-
/* Flag the end of a display update on a termcap display. */
-void
+static void
tty_update_end (struct frame *f)
{
struct tty_display_info *tty = FRAME_TTY (f);
if (!XWINDOW (selected_window)->cursor_off_p)
tty_show_cursor (tty);
- turn_off_insert (tty);
- background_highlight (tty);
-}
-
-/* Specify how many text lines, from the top of the window,
- should be affected by insert-lines and delete-lines operations.
- This, and those operations, are used only within an update
- that is bounded by calls to update_begin and update_end. */
-
-void
-set_terminal_window (struct frame *f, int size)
-{
- if (FRAME_DEVICE (f)->set_terminal_window_hook)
- (*FRAME_DEVICE (f)->set_terminal_window_hook) (f, size);
+ tty_turn_off_insert (tty);
+ tty_background_highlight (tty);
}
/* The implementation of set_terminal_window for termcap frames. */
-void
+static void
tty_set_terminal_window (struct frame *f, int size)
{
struct tty_display_info *tty = FRAME_TTY (f);
tty->specified_window = size ? size : FRAME_LINES (f);
if (FRAME_SCROLL_REGION_OK (f))
- set_scroll_region (f, 0, tty->specified_window);
+ tty_set_scroll_region (f, 0, tty->specified_window);
}
-void
-set_scroll_region (struct frame *f, int start, int stop)
+static void
+tty_set_scroll_region (struct frame *f, int start, int stop)
{
char *buf;
struct tty_display_info *tty = FRAME_TTY (f);
@@ -359,7 +294,7 @@ set_scroll_region (struct frame *f, int start, int stop)
static void
-turn_on_insert (struct tty_display_info *tty)
+tty_turn_on_insert (struct tty_display_info *tty)
{
if (!tty->insert_mode)
OUTPUT (tty, tty->TS_insert_mode);
@@ -367,7 +302,7 @@ turn_on_insert (struct tty_display_info *tty)
}
void
-turn_off_insert (struct tty_display_info *tty)
+tty_turn_off_insert (struct tty_display_info *tty)
{
if (tty->insert_mode)
OUTPUT (tty, tty->TS_end_insert_mode);
@@ -377,7 +312,7 @@ turn_off_insert (struct tty_display_info *tty)
/* Handle highlighting. */
void
-turn_off_highlight (struct tty_display_info *tty)
+tty_turn_off_highlight (struct tty_display_info *tty)
{
if (tty->standout_mode)
OUTPUT_IF (tty, tty->TS_end_standout_mode);
@@ -385,7 +320,7 @@ turn_off_highlight (struct tty_display_info *tty)
}
static void
-turn_on_highlight (struct tty_display_info *tty)
+tty_turn_on_highlight (struct tty_display_info *tty)
{
if (!tty->standout_mode)
OUTPUT_IF (tty, tty->TS_standout_mode);
@@ -393,12 +328,12 @@ turn_on_highlight (struct tty_display_info *tty)
}
static void
-toggle_highlight (struct tty_display_info *tty)
+tty_toggle_highlight (struct tty_display_info *tty)
{
if (tty->standout_mode)
- turn_off_highlight (tty);
+ tty_turn_off_highlight (tty);
else
- turn_on_highlight (tty);
+ tty_turn_on_highlight (tty);
}
@@ -433,38 +368,31 @@ tty_show_cursor (struct tty_display_info *tty)
empty space inside windows. What this is,
depends on the user option inverse-video. */
-void
-background_highlight (struct tty_display_info *tty)
+static void
+tty_background_highlight (struct tty_display_info *tty)
{
if (inverse_video)
- turn_on_highlight (tty);
+ tty_turn_on_highlight (tty);
else
- turn_off_highlight (tty);
+ tty_turn_off_highlight (tty);
}
/* Set standout mode to the mode specified for the text to be output. */
static void
-highlight_if_desired (struct tty_display_info *tty)
+tty_highlight_if_desired (struct tty_display_info *tty)
{
if (inverse_video)
- turn_on_highlight (tty);
+ tty_turn_on_highlight (tty);
else
- turn_off_highlight (tty);
+ tty_turn_off_highlight (tty);
}
/* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
frame-relative coordinates. */
-void
-cursor_to (struct frame *f, int vpos, int hpos)
-{
- if (FRAME_DEVICE (f)->cursor_to_hook)
- (*FRAME_DEVICE (f)->cursor_to_hook) (f, vpos, hpos);
-}
-
-void
+static void
tty_cursor_to (struct frame *f, int vpos, int hpos)
{
struct tty_display_info *tty = FRAME_TTY (f);
@@ -478,22 +406,15 @@ tty_cursor_to (struct frame *f, int vpos, int hpos)
&& curX (tty) == hpos)
return;
if (!tty->TF_standout_motion)
- background_highlight (tty);
+ tty_background_highlight (tty);
if (!tty->TF_insmode_motion)
- turn_off_insert (tty);
+ tty_turn_off_insert (tty);
cmgoto (tty, vpos, hpos);
}
/* Similar but don't take any account of the wasted characters. */
-void
-raw_cursor_to (struct frame *f, int row, int col)
-{
- if (FRAME_DEVICE (f)->raw_cursor_to_hook)
- (*FRAME_DEVICE (f)->raw_cursor_to_hook) (f, row, col);
-}
-
-void
+static void
tty_raw_cursor_to (struct frame *f, int row, int col)
{
struct tty_display_info *tty = FRAME_TTY (f);
@@ -502,25 +423,17 @@ tty_raw_cursor_to (struct frame *f, int row, int col)
&& curX (tty) == col)
return;
if (!tty->TF_standout_motion)
- background_highlight (tty);
+ tty_background_highlight (tty);
if (!tty->TF_insmode_motion)
- turn_off_insert (tty);
+ tty_turn_off_insert (tty);
cmgoto (tty, row, col);
}
/* Erase operations */
-/* Clear from cursor to end of frame. */
-void
-clear_to_end (struct frame *f)
-{
- if (FRAME_DEVICE (f)->clear_to_end_hook)
- (*FRAME_DEVICE (f)->clear_to_end_hook) (f);
-}
-
/* Clear from cursor to end of frame on a termcap device. */
-void
+static void
tty_clear_to_end (struct frame *f)
{
register int i;
@@ -528,7 +441,7 @@ tty_clear_to_end (struct frame *f)
if (tty->TS_clr_to_bottom)
{
- background_highlight (tty);
+ tty_background_highlight (tty);
OUTPUT (tty, tty->TS_clr_to_bottom);
}
else
@@ -541,25 +454,16 @@ tty_clear_to_end (struct frame *f)
}
}
-/* Clear entire frame */
-
-void
-clear_frame (struct frame *f)
-{
- if (FRAME_DEVICE (f)->clear_frame_hook)
- (*FRAME_DEVICE (f)->clear_frame_hook) (f);
-}
-
/* Clear an entire termcap frame. */
-void
+static void
tty_clear_frame (struct frame *f)
{
struct tty_display_info *tty = FRAME_TTY (f);
if (tty->TS_clr_frame)
{
- background_highlight (tty);
+ tty_background_highlight (tty);
OUTPUT (tty, tty->TS_clr_frame);
cmat (tty, 0, 0);
}
@@ -570,23 +474,11 @@ tty_clear_frame (struct frame *f)
}
}
-/* Clear from cursor to end of line.
- Assume that the line is already clear starting at column first_unused_hpos.
-
- Note that the cursor may be moved, on terminals lacking a `ce' string. */
-
-void
-clear_end_of_line (struct frame *f, int first_unused_hpos)
-{
- if (FRAME_DEVICE (f)->clear_end_of_line_hook)
- (*FRAME_DEVICE (f)->clear_end_of_line_hook) (f, first_unused_hpos);
-}
-
/* An implementation of clear_end_of_line for termcap frames.
Note that the cursor may be moved, on terminals lacking a `ce' string. */
-void
+static void
tty_clear_end_of_line (struct frame *f, int first_unused_hpos)
{
register int i;
@@ -599,14 +491,14 @@ tty_clear_end_of_line (struct frame *f, int first_unused_hpos)
if (curX (tty) >= first_unused_hpos)
return;
- background_highlight (tty);
+ tty_background_highlight (tty);
if (tty->TS_clr_line)
{
OUTPUT1 (tty, tty->TS_clr_line);
}
else
{ /* have to do it the hard way */
- turn_off_insert (tty);
+ tty_turn_off_insert (tty);
/* Do not write in last row last col with Auto-wrap on. */
if (AutoWrap (tty)
@@ -743,19 +635,9 @@ encode_terminal_code (src, src_len, coding)
}
-/* Output LEN glyphs starting at STRING at the nominal cursor position.
- Advance the nominal cursor over the text. */
-
-void
-write_glyphs (struct frame *f, struct glyph *string, int len)
-{
- if (FRAME_DEVICE (f)->write_glyphs_hook)
- (*FRAME_DEVICE (f)->write_glyphs_hook) (f, string, len);
-}
-
/* An implementation of write_glyphs for termcap frames. */
-void
+static void
tty_write_glyphs (struct frame *f, struct glyph *string, int len)
{
unsigned char *conversion_buffer;
@@ -763,7 +645,7 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
struct tty_display_info *tty = FRAME_TTY (f);
- turn_off_insert (tty);
+ tty_turn_off_insert (tty);
tty_hide_cursor (tty);
/* Don't dare write in last column of bottom line, if Auto-Wrap,
@@ -798,7 +680,7 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
break;
/* Turn appearance modes of the face of the run on. */
- highlight_if_desired (tty);
+ tty_highlight_if_desired (tty);
turn_on_face (f, face_id);
if (n == len)
@@ -818,29 +700,15 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len)
/* Turn appearance modes off. */
turn_off_face (f, face_id);
- turn_off_highlight (tty);
+ tty_turn_off_highlight (tty);
}
cmcheckmagic (tty);
}
-/* Insert LEN glyphs from START at the nominal cursor position.
-
- If start is zero, insert blanks instead of a string at start */
-
-void
-insert_glyphs (struct frame *f, struct glyph *start, int len)
-{
- if (len <= 0)
- return;
-
- if (FRAME_DEVICE (f)->insert_glyphs_hook)
- (*FRAME_DEVICE (f)->insert_glyphs_hook) (f, start, len);
-}
-
/* An implementation of insert_glyphs for termcap frames. */
-void
+static void
tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
{
char *buf;
@@ -861,7 +729,7 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
return;
}
- turn_on_insert (tty);
+ tty_turn_on_insert (tty);
cmplus (tty, len);
if (! start)
@@ -886,7 +754,7 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
}
else
{
- highlight_if_desired (tty);
+ tty_highlight_if_desired (tty);
turn_on_face (f, start->face_id);
glyph = start;
++start;
@@ -918,25 +786,16 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len)
if (start)
{
turn_off_face (f, glyph->face_id);
- turn_off_highlight (tty);
+ tty_turn_off_highlight (tty);
}
}
cmcheckmagic (tty);
}
-/* Delete N glyphs at the nominal cursor position. */
-
-void
-delete_glyphs (struct frame *f, int n)
-{
- if (FRAME_DEVICE (f)->delete_glyphs_hook)
- (*FRAME_DEVICE (f)->delete_glyphs_hook) (f, n);
-}
-
/* An implementation of delete_glyphs for termcap frames. */
-void
+static void
tty_delete_glyphs (struct frame *f, int n)
{
char *buf;
@@ -946,11 +805,11 @@ tty_delete_glyphs (struct frame *f, int n)
if (tty->delete_in_insert_mode)
{
- turn_on_insert (tty);
+ tty_turn_on_insert (tty);
}
else
{
- turn_off_insert (tty);
+ tty_turn_off_insert (tty);
OUTPUT_IF (tty, tty->TS_delete_mode);
}
@@ -967,18 +826,9 @@ tty_delete_glyphs (struct frame *f, int n)
OUTPUT_IF (tty, tty->TS_end_delete_mode);
}
-/* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
-
-void
-ins_del_lines (struct frame *f, int vpos, int n)
-{
- if (FRAME_DEVICE (f)->ins_del_lines_hook)
- (*FRAME_DEVICE (f)->ins_del_lines_hook) (f, vpos, n);
-}
-
/* An implementation of ins_del_lines for termcap frames. */
-void
+static void
tty_ins_del_lines (struct frame *f, int vpos, int n)
{
struct tty_display_info *tty = FRAME_TTY (f);
@@ -1006,7 +856,7 @@ tty_ins_del_lines (struct frame *f, int vpos, int n)
if (multi)
{
raw_cursor_to (f, vpos, 0);
- background_highlight (tty);
+ tty_background_highlight (tty);
buf = tparam (multi, 0, 0, i);
OUTPUT (tty, buf);
xfree (buf);
@@ -1014,7 +864,7 @@ tty_ins_del_lines (struct frame *f, int vpos, int n)
else if (single)
{
raw_cursor_to (f, vpos, 0);
- background_highlight (tty);
+ tty_background_highlight (tty);
while (--i >= 0)
OUTPUT (tty, single);
if (tty->TF_teleray)
@@ -1022,15 +872,15 @@ tty_ins_del_lines (struct frame *f, int vpos, int n)
}
else
{
- set_scroll_region (f, vpos, tty->specified_window);
+ tty_set_scroll_region (f, vpos, tty->specified_window);
if (n < 0)
raw_cursor_to (f, tty->specified_window - 1, 0);
else
raw_cursor_to (f, vpos, 0);
- background_highlight (tty);
+ tty_background_highlight (tty);
while (--i >= 0)
OUTPUTL (tty, scroll, tty->specified_window - vpos);
- set_scroll_region (f, 0, tty->specified_window);
+ tty_set_scroll_region (f, 0, tty->specified_window);
}
if (!FRAME_SCROLL_REGION_OK (f)
@@ -1331,7 +1181,7 @@ static Lisp_Object term_get_fkeys_1 ();
This function scans the termcap function key sequence entries, and
adds entries to Vfunction_key_map for each function key it finds. */
-void
+static void
term_get_fkeys (address, kboard)
char **address;
KBOARD *kboard;
@@ -1805,13 +1655,13 @@ turn_on_face (f, face_id)
{
if (fg == FACE_TTY_DEFAULT_FG_COLOR
|| bg == FACE_TTY_DEFAULT_BG_COLOR)
- toggle_highlight (tty);
+ tty_toggle_highlight (tty);
}
else
{
if (fg == FACE_TTY_DEFAULT_BG_COLOR
|| bg == FACE_TTY_DEFAULT_FG_COLOR)
- toggle_highlight (tty);
+ tty_toggle_highlight (tty);
}
}
else
@@ -1822,13 +1672,13 @@ turn_on_face (f, face_id)
{
if (fg == FACE_TTY_DEFAULT_FG_COLOR
|| bg == FACE_TTY_DEFAULT_BG_COLOR)
- toggle_highlight (tty);
+ tty_toggle_highlight (tty);
}
else
{
if (fg == FACE_TTY_DEFAULT_BG_COLOR
|| bg == FACE_TTY_DEFAULT_FG_COLOR)
- toggle_highlight (tty);
+ tty_toggle_highlight (tty);
}
}
}
@@ -2031,7 +1881,7 @@ tty_default_color_capabilities (struct tty_display_info *tty, int save)
MODE's value is generally the number of colors which we want to
support; zero means set up for the default capabilities, the ones
we saw at init_tty time; -1 means turn off color support. */
-void
+static void
tty_setup_colors (struct tty_display_info *tty, int mode)
{
/* Canonicalize all negative values of MODE. */
@@ -2124,43 +1974,6 @@ set_tty_color_mode (f, val)
-/* Return the display object specified by DEVICE. DEVICE may be a
- display id, a frame, or nil for the display device of the current
- frame. If THROW is zero, return NULL for failure, otherwise throw
- an error. */
-
-struct device *
-get_device (Lisp_Object device, int throw)
-{
- struct device *result = NULL;
-
- if (NILP (device))
- device = selected_frame;
-
- if (INTEGERP (device))
- {
- struct device *d;
-
- for (d = device_list; d; d = d->next_device)
- {
- if (d->id == XINT (device))
- {
- result = d;
- break;
- }
- }
- }
- else if (FRAMEP (device))
- {
- result = FRAME_DEVICE (XFRAME (device));
- }
-
- if (result == NULL && throw)
- wrong_type_argument (Qdisplay_live_p, device);
-
- return result;
-}
-
/* Return the tty display object specified by DEVICE. */
struct device *
@@ -2204,24 +2017,6 @@ get_named_tty (name)
}
-
-DEFUN ("display-name", Fdisplay_name, Sdisplay_name, 0, 1, 0,
- doc: /* Return the name of the display device DEVICE.
-It is not guaranteed that the returned value is unique among opened devices.
-
-DEVICE may be a display device id, a frame, or nil (meaning the
-selected frame's display device). */)
- (device)
- Lisp_Object device;
-{
- struct device *d = get_device (device, 1);
-
- if (d->name)
- return build_string (d->name);
- else
- return Qnil;
-}
-
DEFUN ("display-tty-type", Fdisplay_tty_type, Sdisplay_tty_type, 0, 1, 0,
doc: /* Return the type of the tty device that DEVICE uses.
@@ -2275,47 +2070,166 @@ selected frame's display device). */)
return Qnil;
}
+
+
+DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
+ doc: /* Suspend the terminal device TTY.
+
+The device is restored to its default state, and Emacs ceases all
+access to the tty device. Frames that use the device are not deleted,
+but input is not read from them and if they change, their display is
+not updated.
+
+TTY may be a terminal id, a frame, or nil for the terminal device of
+the currently selected frame.
+
+This function runs `suspend-tty-functions' after suspending the
+device. The functions are run with one arg, the id of the suspended
+terminal device.
+
+`suspend-tty' does nothing if it is called on a device that is already
+suspended.
+
+A suspended tty may be resumed by calling `resume-tty' on it. */)
+ (tty)
+ Lisp_Object tty;
+{
+ struct device *d = get_tty_device (tty);
+ FILE *f;
+
+ if (!d)
+ error ("Unknown tty device");
+
+ f = d->display_info.tty->input;
+
+ if (f)
+ {
+ reset_sys_modes (d->display_info.tty);
+
+ delete_keyboard_wait_descriptor (fileno (f));
+
+ fclose (f);
+ if (f != d->display_info.tty->output)
+ fclose (d->display_info.tty->output);
+
+ d->display_info.tty->input = 0;
+ d->display_info.tty->output = 0;
+
+ if (FRAMEP (d->display_info.tty->top_frame))
+ FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 0);
+
+ /* Run `suspend-tty-functions'. */
+ if (!NILP (Vrun_hooks))
+ {
+ Lisp_Object args[2];
+ args[0] = intern ("suspend-tty-functions");
+ args[1] = make_number (d->id);
+ Frun_hook_with_args (2, args);
+ }
+ }
+
+ return Qnil;
+}
+
+DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0,
+ doc: /* Resume the previously suspended terminal device TTY.
+The terminal is opened and reinitialized. Frames that are on the
+suspended display are revived.
+
+It is an error to resume a display while another display is active on
+the same device.
+
+This function runs `resume-tty-functions' after resuming the device.
+The functions are run with one arg, the id of the resumed display
+device.
+
+`resume-tty' does nothing if it is called on a device that is not
+suspended.
+
+TTY may be a display device id, a frame, or nil for the display device
+of the currently selected frame. */)
+ (tty)
+ Lisp_Object tty;
+{
+ struct device *d = get_tty_device (tty);
+ int fd;
+
+ if (!d)
+ error ("Unknown tty device");
+
+ if (!d->display_info.tty->input)
+ {
+ if (get_named_tty (d->display_info.tty->name))
+ error ("Cannot resume display while another display is active on the same device");
+
+ fd = emacs_open (d->display_info.tty->name, O_RDWR | O_NOCTTY, 0);
+
+ /* XXX What if open fails? */
+
+ dissociate_if_controlling_tty (fd);
+
+ d->display_info.tty->output = fdopen (fd, "w+");
+ d->display_info.tty->input = d->display_info.tty->output;
+
+ add_keyboard_wait_descriptor (fd);
+
+ if (FRAMEP (d->display_info.tty->top_frame))
+ FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 1);
+
+ init_sys_modes (d->display_info.tty);
+
+ /* Run `suspend-tty-functions'. */
+ if (!NILP (Vrun_hooks))
+ {
+ Lisp_Object args[2];
+ args[0] = intern ("resume-tty-functions");
+ args[1] = make_number (d->id);
+ Frun_hook_with_args (2, args);
+ }
+ }
+
+ return Qnil;
+}
/***********************************************************************
Initialization
***********************************************************************/
-/* Create the bootstrap display device for the initial frame.
- Returns a device of type output_initial. */
+/* Initialize the tty-dependent part of frame F. The frame must
+ already have its device initialized. */
-struct device *
-init_initial_device (void)
+void
+create_tty_output (struct frame *f)
{
- if (initialized || device_list || tty_list)
+ struct tty_output *t;
+
+ if (! FRAME_TERMCAP_P (f))
abort ();
- initial_device = create_device ();
- initial_device->type = output_initial;
- initial_device->name = xstrdup ("initial_device");
- initial_device->kboard = initial_kboard;
+ t = xmalloc (sizeof (struct tty_output));
+ bzero (t, sizeof (struct tty_output));
- initial_device->delete_device_hook = &delete_initial_device;
- /* All other hooks are NULL. */
+ t->display_info = FRAME_DEVICE (f)->display_info.tty;
- return initial_device;
+ f->output_data.tty = t;
}
-/* Deletes the bootstrap display device.
- Called through delete_device_hook. */
+/* Delete the tty-dependent part of frame F. */
-void
-delete_initial_device (struct device *device)
+static void
+delete_tty_output (struct frame *f)
{
- if (device != initial_device)
+ if (! FRAME_TERMCAP_P (f))
abort ();
- delete_device (device);
- initial_device = NULL;
+ xfree (f->output_data.tty);
}
+
+
/* Drop the controlling terminal if fd is the same device. */
-void
+static void
dissociate_if_controlling_tty (int fd)
{
int pgid;
@@ -2974,7 +2888,7 @@ static int deleting_tty = 0;
/* Delete the given terminal device, closing all frames on it. */
-void
+static void
delete_tty (struct device *device)
{
struct tty_display_info *tty;
@@ -3066,44 +2980,11 @@ delete_tty (struct device *device)
-/* Initialize the tty-dependent part of frame F. The frame must
- already have its device initialized. */
-
-void
-create_tty_output (struct frame *f)
-{
- struct tty_output *t;
-
- if (! FRAME_TERMCAP_P (f))
- abort ();
-
- t = xmalloc (sizeof (struct tty_output));
- bzero (t, sizeof (struct tty_output));
-
- t->display_info = FRAME_DEVICE (f)->display_info.tty;
-
- f->output_data.tty = t;
-}
-
-/* Delete the tty-dependent part of frame F. */
-
-void
-delete_tty_output (struct frame *f)
-{
- if (! FRAME_TERMCAP_P (f))
- abort ();
-
- xfree (f->output_data.tty);
-}
-
-
-
-
/* Mark the pointers in the tty_display_info objects.
Called by the Fgarbage_collector. */
void
-mark_ttys ()
+mark_ttys (void)
{
struct tty_display_info *tty;
@@ -3116,279 +2997,6 @@ mark_ttys ()
-/* Create a new device object and add it to the device list. */
-
-struct device *
-create_device (void)
-{
- struct device *device = (struct device *) xmalloc (sizeof (struct device));
-
- bzero (device, sizeof (struct device));
- device->next_device = device_list;
- device_list = device;
-
- device->id = next_device_id++;
-
- device->keyboard_coding =
- (struct coding_system *) xmalloc (sizeof (struct coding_system));
- device->terminal_coding =
- (struct coding_system *) xmalloc (sizeof (struct coding_system));
-
- setup_coding_system (Qnil, device->keyboard_coding);
- setup_coding_system (Qnil, device->terminal_coding);
-
- return device;
-}
-
-/* Remove a device from the device list and free its memory. */
-
-void
-delete_device (struct device *device)
-{
- struct device **dp;
- Lisp_Object tail, frame;
-
- /* Check for and close live frames that are still on this
- device. */
- FOR_EACH_FRAME (tail, frame)
- {
- struct frame *f = XFRAME (frame);
- if (FRAME_LIVE_P (f) && f->device == device)
- {
- Fdelete_frame (frame, Qt);
- }
- }
-
- for (dp = &device_list; *dp != device; dp = &(*dp)->next_device)
- if (! *dp)
- abort ();
- *dp = device->next_device;
-
- if (device->keyboard_coding)
- xfree (device->keyboard_coding);
- if (device->terminal_coding)
- xfree (device->terminal_coding);
- if (device->name)
- xfree (device->name);
-
-#ifdef MULTI_KBOARD
- if (device->kboard && --device->kboard->reference_count == 0)
- delete_kboard (device->kboard);
-#endif
-
- bzero (device, sizeof (struct device));
- xfree (device);
-}
-
-DEFUN ("delete-display", Fdelete_display, Sdelete_display, 0, 2, 0,
- doc: /* Delete DEVICE by deleting all frames on it and closing the device.
-DEVICE may be a display device id, a frame, or nil (meaning the
-selected frame's display device).
-
-Normally, you may not delete a display if all other displays are suspended,
-but if the second argument FORCE is non-nil, you may do so. */)
- (device, force)
- Lisp_Object device, force;
-{
- struct device *d, *p;
-
- d = get_device (device, 0);
-
- if (!d)
- return Qnil;
-
- p = device_list;
- while (p && (p == d || !DEVICE_ACTIVE_P (p)))
- p = p->next_device;
-
- if (NILP (force) && !p)
- error ("Attempt to delete the sole active display device");
-
- if (d->delete_device_hook)
- (*d->delete_device_hook) (d);
- else
- delete_device (d);
-
- return Qnil;
-}
-
-DEFUN ("display-live-p", Fdisplay_live_p, Sdisplay_live_p, 1, 1, 0,
- doc: /* Return non-nil if OBJECT is a device which has not been deleted.
-Value is nil if OBJECT is not a live display device.
-If object is a live display device, the return value indicates what
-sort of output device it uses. See the documentation of `framep' for
-possible return values.
-
-Display devices are represented by their integer identifiers. */)
- (object)
- Lisp_Object object;
-{
- struct device *d;
-
- if (!INTEGERP (object))
- return Qnil;
-
- d = get_device (object, 0);
-
- if (!d)
- return Qnil;
-
- switch (d->type)
- {
- case output_initial: /* The initial frame is like a termcap frame. */
- case output_termcap:
- return Qt;
- case output_x_window:
- return Qx;
- case output_w32:
- return Qw32;
- case output_msdos_raw:
- return Qpc;
- case output_mac:
- return Qmac;
- default:
- abort ();
- }
-}
-
-DEFUN ("display-list", Fdisplay_list, Sdisplay_list, 0, 0, 0,
- doc: /* Return a list of all display devices.
-Display devices are represented by their integer identifiers. */)
- ()
-{
- Lisp_Object devices = Qnil;
- struct device *d;
-
- for (d = device_list; d; d = d->next_device)
- devices = Fcons (make_number (d->id), devices);
-
- return devices;
-}
-
-
-
-
-DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0,
- doc: /* Suspend the terminal device TTY.
-
-The device is restored to its default state, and Emacs ceases all
-access to the tty device. Frames that use the device are not deleted,
-but input is not read from them and if they change, their display is
-not updated.
-
-TTY may be a terminal id, a frame, or nil for the terminal device of
-the currently selected frame.
-
-This function runs `suspend-tty-functions' after suspending the
-device. The functions are run with one arg, the id of the suspended
-terminal device.
-
-`suspend-tty' does nothing if it is called on a device that is already
-suspended.
-
-A suspended tty may be resumed by calling `resume-tty' on it. */)
- (tty)
- Lisp_Object tty;
-{
- struct device *d = get_tty_device (tty);
- FILE *f;
-
- if (!d)
- error ("Unknown tty device");
-
- f = d->display_info.tty->input;
-
- if (f)
- {
- reset_sys_modes (d->display_info.tty);
-
- delete_keyboard_wait_descriptor (fileno (f));
-
- fclose (f);
- if (f != d->display_info.tty->output)
- fclose (d->display_info.tty->output);
-
- d->display_info.tty->input = 0;
- d->display_info.tty->output = 0;
-
- if (FRAMEP (d->display_info.tty->top_frame))
- FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 0);
-
- /* Run `suspend-tty-functions'. */
- if (!NILP (Vrun_hooks))
- {
- Lisp_Object args[2];
- args[0] = intern ("suspend-tty-functions");
- args[1] = make_number (d->id);
- Frun_hook_with_args (2, args);
- }
- }
-
- return Qnil;
-}
-
-
-DEFUN ("resume-tty", Fresume_tty, Sresume_tty, 0, 1, 0,
- doc: /* Resume the previously suspended terminal device TTY.
-The terminal is opened and reinitialized. Frames that are on the
-suspended display are revived.
-
-It is an error to resume a display while another display is active on
-the same device.
-
-This function runs `resume-tty-functions' after resuming the device.
-The functions are run with one arg, the id of the resumed display
-device.
-
-`resume-tty' does nothing if it is called on a device that is not
-suspended.
-
-TTY may be a display device id, a frame, or nil for the display device
-of the currently selected frame. */)
- (tty)
- Lisp_Object tty;
-{
- struct device *d = get_tty_device (tty);
- int fd;
-
- if (!d)
- error ("Unknown tty device");
-
- if (!d->display_info.tty->input)
- {
- if (get_named_tty (d->display_info.tty->name))
- error ("Cannot resume display while another display is active on the same device");
-
- fd = emacs_open (d->display_info.tty->name, O_RDWR | O_NOCTTY, 0);
-
- /* XXX What if open fails? */
-
- dissociate_if_controlling_tty (fd);
-
- d->display_info.tty->output = fdopen (fd, "w+");
- d->display_info.tty->input = d->display_info.tty->output;
-
- add_keyboard_wait_descriptor (fd);
-
- if (FRAMEP (d->display_info.tty->top_frame))
- FRAME_SET_VISIBLE (XFRAME (d->display_info.tty->top_frame), 1);
-
- init_sys_modes (d->display_info.tty);
-
- /* Run `suspend-tty-functions'. */
- if (!NILP (Vrun_hooks))
- {
- Lisp_Object args[2];
- args[0] = intern ("resume-tty-functions");
- args[1] = make_number (d->id);
- Frun_hook_with_args (2, args);
- }
- }
-
- return Qnil;
-}
-
-
void
syms_of_term ()
{
@@ -3401,11 +3009,6 @@ This variable can be used by terminal emulator packages. */);
system_uses_terminfo = 0;
#endif
- DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
- doc: /* Non-nil means call this function to ring the bell.
-The function should accept no arguments. */);
- Vring_bell_function = Qnil;
-
DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions,
doc: /* Functions to be run after suspending a tty.
The functions are run with one argument, the name of the tty to be suspended.
@@ -3422,17 +3025,10 @@ See `resume-tty'. */);
defsubr (&Stty_display_color_p);
defsubr (&Stty_display_color_cells);
defsubr (&Stty_no_underline);
- defsubr (&Sdisplay_name);
defsubr (&Sdisplay_tty_type);
defsubr (&Sdisplay_controlling_tty_p);
- defsubr (&Sdelete_display);
- defsubr (&Sdisplay_live_p);
- defsubr (&Sdisplay_list);
defsubr (&Ssuspend_tty);
defsubr (&Sresume_tty);
-
- Fprovide (intern ("multi-tty"), Qnil);
-
}
diff --git a/src/termhooks.h b/src/termhooks.h
index cb68c9e2c27..824cef60351 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -330,6 +330,9 @@ struct device
the function `set-keyboard-coding-system'. */
struct coding_system *keyboard_coding;
+ /* Parameter alist of this terminal. */
+ Lisp_Object param_alist;
+
/* Terminal characteristics. */
/* XXX Are these really used on non-termcap displays? */
diff --git a/src/terminal.c b/src/terminal.c
new file mode 100644
index 00000000000..83879a43afa
--- /dev/null
+++ b/src/terminal.c
@@ -0,0 +1,596 @@
+/* Functions related to terminal devices.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+#include <config.h>
+
+#include "lisp.h"
+#include "frame.h"
+#include "termchar.h"
+#include "termhooks.h"
+#include "charset.h"
+#include "coding.h"
+#include "keyboard.h"
+
+/* Chain of all displays currently in use. */
+struct device *device_list;
+
+/* The first unallocated display id. */
+static int next_device_id;
+
+/* The initial display device, created by initial_term_init. */
+struct device *initial_device;
+
+/* Function to use to ring the bell. */
+Lisp_Object Vring_bell_function;
+
+void delete_initial_device P_ ((struct device *));
+
+
+
+void
+ring_bell (struct frame *f)
+{
+ if (!NILP (Vring_bell_function))
+ {
+ Lisp_Object function;
+
+ /* Temporarily set the global variable to nil
+ so that if we get an error, it stays nil
+ and we don't call it over and over.
+
+ We don't specbind it, because that would carefully
+ restore the bad value if there's an error
+ and make the loop of errors happen anyway. */
+
+ function = Vring_bell_function;
+ Vring_bell_function = Qnil;
+
+ call0 (function);
+
+ Vring_bell_function = function;
+ }
+ else if (FRAME_DEVICE (f)->ring_bell_hook)
+ (*FRAME_DEVICE (f)->ring_bell_hook) (f);
+}
+
+void
+update_begin (struct frame *f)
+{
+ if (FRAME_DEVICE (f)->update_begin_hook)
+ (*FRAME_DEVICE (f)->update_begin_hook) (f);
+}
+
+void
+update_end (struct frame *f)
+{
+ if (FRAME_DEVICE (f)->update_end_hook)
+ (*FRAME_DEVICE (f)->update_end_hook) (f);
+}
+
+/* Specify how many text lines, from the top of the window,
+ should be affected by insert-lines and delete-lines operations.
+ This, and those operations, are used only within an update
+ that is bounded by calls to update_begin and update_end. */
+
+void
+set_terminal_window (struct frame *f, int size)
+{
+ if (FRAME_DEVICE (f)->set_terminal_window_hook)
+ (*FRAME_DEVICE (f)->set_terminal_window_hook) (f, size);
+}
+
+/* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
+ frame-relative coordinates. */
+
+void
+cursor_to (struct frame *f, int vpos, int hpos)
+{
+ if (FRAME_DEVICE (f)->cursor_to_hook)
+ (*FRAME_DEVICE (f)->cursor_to_hook) (f, vpos, hpos);
+}
+
+/* Similar but don't take any account of the wasted characters. */
+
+void
+raw_cursor_to (struct frame *f, int row, int col)
+{
+ if (FRAME_DEVICE (f)->raw_cursor_to_hook)
+ (*FRAME_DEVICE (f)->raw_cursor_to_hook) (f, row, col);
+}
+
+/* Erase operations */
+
+/* Clear from cursor to end of frame. */
+void
+clear_to_end (struct frame *f)
+{
+ if (FRAME_DEVICE (f)->clear_to_end_hook)
+ (*FRAME_DEVICE (f)->clear_to_end_hook) (f);
+}
+
+/* Clear entire frame */
+
+void
+clear_frame (struct frame *f)
+{
+ if (FRAME_DEVICE (f)->clear_frame_hook)
+ (*FRAME_DEVICE (f)->clear_frame_hook) (f);
+}
+
+/* Clear from cursor to end of line.
+ Assume that the line is already clear starting at column first_unused_hpos.
+
+ Note that the cursor may be moved, on terminals lacking a `ce' string. */
+
+void
+clear_end_of_line (struct frame *f, int first_unused_hpos)
+{
+ if (FRAME_DEVICE (f)->clear_end_of_line_hook)
+ (*FRAME_DEVICE (f)->clear_end_of_line_hook) (f, first_unused_hpos);
+}
+
+/* Output LEN glyphs starting at STRING at the nominal cursor position.
+ Advance the nominal cursor over the text. */
+
+void
+write_glyphs (struct frame *f, struct glyph *string, int len)
+{
+ if (FRAME_DEVICE (f)->write_glyphs_hook)
+ (*FRAME_DEVICE (f)->write_glyphs_hook) (f, string, len);
+}
+
+/* Insert LEN glyphs from START at the nominal cursor position.
+
+ If start is zero, insert blanks instead of a string at start */
+
+void
+insert_glyphs (struct frame *f, struct glyph *start, int len)
+{
+ if (len <= 0)
+ return;
+
+ if (FRAME_DEVICE (f)->insert_glyphs_hook)
+ (*FRAME_DEVICE (f)->insert_glyphs_hook) (f, start, len);
+}
+
+/* Delete N glyphs at the nominal cursor position. */
+
+void
+delete_glyphs (struct frame *f, int n)
+{
+ if (FRAME_DEVICE (f)->delete_glyphs_hook)
+ (*FRAME_DEVICE (f)->delete_glyphs_hook) (f, n);
+}
+
+/* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
+
+void
+ins_del_lines (struct frame *f, int vpos, int n)
+{
+ if (FRAME_DEVICE (f)->ins_del_lines_hook)
+ (*FRAME_DEVICE (f)->ins_del_lines_hook) (f, vpos, n);
+}
+
+
+
+
+/* Return the display object specified by DEVICE. DEVICE may be a
+ display id, a frame, or nil for the display device of the current
+ frame. If THROW is zero, return NULL for failure, otherwise throw
+ an error. */
+
+struct device *
+get_device (Lisp_Object device, int throw)
+{
+ struct device *result = NULL;
+
+ if (NILP (device))
+ device = selected_frame;
+
+ if (INTEGERP (device))
+ {
+ struct device *d;
+
+ for (d = device_list; d; d = d->next_device)
+ {
+ if (d->id == XINT (device))
+ {
+ result = d;
+ break;
+ }
+ }
+ }
+ else if (FRAMEP (device))
+ {
+ result = FRAME_DEVICE (XFRAME (device));
+ }
+
+ if (result == NULL && throw)
+ wrong_type_argument (Qdisplay_live_p, device);
+
+ return result;
+}
+
+
+
+/* Create a new device object and add it to the device list. */
+
+struct device *
+create_device (void)
+{
+ struct device *device = (struct device *) xmalloc (sizeof (struct device));
+
+ bzero (device, sizeof (struct device));
+ device->next_device = device_list;
+ device_list = device;
+
+ device->id = next_device_id++;
+
+ device->keyboard_coding =
+ (struct coding_system *) xmalloc (sizeof (struct coding_system));
+ device->terminal_coding =
+ (struct coding_system *) xmalloc (sizeof (struct coding_system));
+
+ setup_coding_system (Qnil, device->keyboard_coding);
+ setup_coding_system (Qnil, device->terminal_coding);
+
+ device->param_alist = Qnil;
+ return device;
+}
+
+/* Mark the Lisp pointers in the terminal objects.
+ Called by the Fgarbage_collector. */
+
+void
+mark_devices (void)
+{
+ struct device *d;
+ for (d = device_list; d; d = d->next_device)
+ {
+ mark_object (d->param_alist);
+ }
+}
+
+
+/* Remove a device from the device list and free its memory. */
+
+void
+delete_device (struct device *device)
+{
+ struct device **dp;
+ Lisp_Object tail, frame;
+
+ /* Check for and close live frames that are still on this
+ device. */
+ FOR_EACH_FRAME (tail, frame)
+ {
+ struct frame *f = XFRAME (frame);
+ if (FRAME_LIVE_P (f) && f->device == device)
+ {
+ Fdelete_frame (frame, Qt);
+ }
+ }
+
+ for (dp = &device_list; *dp != device; dp = &(*dp)->next_device)
+ if (! *dp)
+ abort ();
+ *dp = device->next_device;
+
+ if (device->keyboard_coding)
+ xfree (device->keyboard_coding);
+ if (device->terminal_coding)
+ xfree (device->terminal_coding);
+ if (device->name)
+ xfree (device->name);
+
+#ifdef MULTI_KBOARD
+ if (device->kboard && --device->kboard->reference_count == 0)
+ delete_kboard (device->kboard);
+#endif
+
+ bzero (device, sizeof (struct device));
+ xfree (device);
+}
+
+DEFUN ("delete-display", Fdelete_display, Sdelete_display, 0, 2, 0,
+ doc: /* Delete DEVICE by deleting all frames on it and closing the device.
+DEVICE may be a display device id, a frame, or nil (meaning the
+selected frame's display device).
+
+Normally, you may not delete a display if all other displays are suspended,
+but if the second argument FORCE is non-nil, you may do so. */)
+ (device, force)
+ Lisp_Object device, force;
+{
+ struct device *d, *p;
+
+ d = get_device (device, 0);
+
+ if (!d)
+ return Qnil;
+
+ p = device_list;
+ while (p && (p == d || !DEVICE_ACTIVE_P (p)))
+ p = p->next_device;
+
+ if (NILP (force) && !p)
+ error ("Attempt to delete the sole active display device");
+
+ if (d->delete_device_hook)
+ (*d->delete_device_hook) (d);
+ else
+ delete_device (d);
+
+ return Qnil;
+}
+
+DEFUN ("display-live-p", Fdisplay_live_p, Sdisplay_live_p, 1, 1, 0,
+ doc: /* Return non-nil if OBJECT is a device which has not been deleted.
+Value is nil if OBJECT is not a live display device.
+If object is a live display device, the return value indicates what
+sort of output device it uses. See the documentation of `framep' for
+possible return values.
+
+Display devices are represented by their integer identifiers. */)
+ (object)
+ Lisp_Object object;
+{
+ struct device *d;
+
+ if (!INTEGERP (object))
+ return Qnil;
+
+ d = get_device (object, 0);
+
+ if (!d)
+ return Qnil;
+
+ switch (d->type)
+ {
+ case output_initial: /* The initial frame is like a termcap frame. */
+ case output_termcap:
+ return Qt;
+ case output_x_window:
+ return Qx;
+ case output_w32:
+ return Qw32;
+ case output_msdos_raw:
+ return Qpc;
+ case output_mac:
+ return Qmac;
+ default:
+ abort ();
+ }
+}
+
+DEFUN ("display-list", Fdisplay_list, Sdisplay_list, 0, 0, 0,
+ doc: /* Return a list of all display devices.
+Display devices are represented by their integer identifiers. */)
+ ()
+{
+ Lisp_Object devices = Qnil;
+ struct device *d;
+
+ for (d = device_list; d; d = d->next_device)
+ devices = Fcons (make_number (d->id), devices);
+
+ return devices;
+}
+
+DEFUN ("display-name", Fdisplay_name, Sdisplay_name, 0, 1, 0,
+ doc: /* Return the name of the display device DEVICE.
+It is not guaranteed that the returned value is unique among opened devices.
+
+DEVICE may be a display device id, a frame, or nil (meaning the
+selected frame's display device). */)
+ (device)
+ Lisp_Object device;
+{
+ struct device *d = get_device (device, 1);
+
+ if (d->name)
+ return build_string (d->name);
+ else
+ return Qnil;
+}
+
+
+
+/* Return the value of terminal parameter PARAM in device D. */
+Lisp_Object
+get_terminal_param (d, param)
+ struct device *d;
+ Lisp_Object param;
+{
+ Lisp_Object tem = Fassq (param, d->param_alist);
+ if (EQ (tem, Qnil))
+ return tem;
+ return Fcdr (tem);
+}
+
+/* Set the value of terminal parameter PARAMETER in device D to VALUE.
+ Return the previous value. */
+
+Lisp_Object
+store_terminal_param (d, parameter, value)
+ struct device *d;
+ Lisp_Object parameter;
+ Lisp_Object value;
+{
+ Lisp_Object old_alist_elt = Fassq (parameter, d->param_alist);
+ if (EQ (old_alist_elt, Qnil))
+ {
+ d->param_alist = Fcons (Fcons (parameter, value), d->param_alist);
+ return Qnil;
+ }
+ else
+ {
+ Lisp_Object result = Fcdr (old_alist_elt);
+ Fsetcdr (old_alist_elt, value);
+ return result;
+ }
+}
+
+
+DEFUN ("terminal-parameters", Fterminal_parameters, Sterminal_parameters, 0, 1, 0,
+ doc: /* Return the parameter-alist of terminal TERMINAL.
+The value is a list of elements of the form (PARM . VALUE), where PARM
+is a symbol.
+
+TERMINAL can be a terminal if, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal)
+ Lisp_Object terminal;
+{
+ struct device *d = get_device (terminal, 1);
+ return Fcopy_alist (d->param_alist);
+}
+
+DEFUN ("terminal-parameter", Fterminal_parameter, Sterminal_parameter, 2, 2, 0,
+ doc: /* Return TERMINAL's value for parameter PARAMETER.
+TERMINAL can be a terminal if, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal, parameter)
+ Lisp_Object terminal;
+ Lisp_Object parameter;
+{
+ Lisp_Object value;
+ struct device *d = get_device (terminal, 1);
+ CHECK_SYMBOL (parameter);
+ value = Fcdr (Fassq (parameter, d->param_alist));
+ return value;
+}
+
+DEFUN ("modify-terminal-parameters", Fmodify_terminal_parameters,
+ Smodify_terminal_parameters, 2, 2, 0,
+ doc: /* Modify the parameters of terminal TERMINAL according to ALIST.
+ALIST is an alist of parameters to change and their new values.
+Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
+
+TERMINAL can be a terminal if, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal, alist)
+ Lisp_Object terminal;
+ Lisp_Object alist;
+{
+ Lisp_Object tail, prop, val;
+ struct device *d = get_device (terminal, 1);
+ int length = XINT (Fsafe_length (alist));
+ int i;
+ Lisp_Object *parms = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
+ Lisp_Object *values = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
+
+ /* Extract parm names and values into those vectors. */
+
+ i = 0;
+ for (tail = alist; CONSP (tail); tail = Fcdr (tail))
+ {
+ Lisp_Object elt;
+
+ elt = Fcar (tail);
+ parms[i] = Fcar (elt);
+ values[i] = Fcdr (elt);
+ i++;
+ }
+
+ /* Now process them in reverse of specified order. */
+ for (i--; i >= 0; i--)
+ {
+ prop = parms[i];
+ val = values[i];
+ store_terminal_param (d, prop, val);
+ }
+ return Qnil;
+}
+
+DEFUN ("set-terminal-parameter", Fset_terminal_parameter,
+ Sset_terminal_parameter, 3, 3, 0,
+ doc: /* Set TERMINAL's value for parameter PARAMETER to VALUE.
+Return the previous value of PARAMETER.
+
+TERMINAL can be a terminal if, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal, parameter, value)
+ Lisp_Object terminal;
+ Lisp_Object parameter;
+ Lisp_Object value;
+{
+ struct device *d = get_device (terminal, 1);
+ return store_terminal_param (d, parameter, value);
+}
+
+
+
+/* Create the bootstrap display device for the initial frame.
+ Returns a device of type output_initial. */
+
+struct device *
+init_initial_device (void)
+{
+ if (initialized || device_list || tty_list)
+ abort ();
+
+ initial_device = create_device ();
+ initial_device->type = output_initial;
+ initial_device->name = xstrdup ("initial_device");
+ initial_device->kboard = initial_kboard;
+
+ initial_device->delete_device_hook = &delete_initial_device;
+ /* All other hooks are NULL. */
+
+ return initial_device;
+}
+
+/* Deletes the bootstrap display device.
+ Called through delete_device_hook. */
+
+void
+delete_initial_device (struct device *device)
+{
+ if (device != initial_device)
+ abort ();
+
+ delete_device (device);
+ initial_device = NULL;
+}
+
+void
+syms_of_terminal ()
+{
+
+ DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
+ doc: /* Non-nil means call this function to ring the bell.
+The function should accept no arguments. */);
+ Vring_bell_function = Qnil;
+
+ defsubr (&Sdelete_display);
+ defsubr (&Sdisplay_live_p);
+ defsubr (&Sdisplay_list);
+ defsubr (&Sdisplay_name);
+ defsubr (&Sterminal_parameters);
+ defsubr (&Sterminal_parameter);
+ defsubr (&Smodify_terminal_parameters);
+ defsubr (&Sset_terminal_parameter);
+
+ Fprovide (intern ("multi-tty"), Qnil);
+}
+
+/* arch-tag: e9af6f27-b483-47dc-bb1a-730c1c5cab03
+ (do not change this comment) */
diff --git a/src/xterm.h b/src/xterm.h
index c96d015be4a..b0464b6cbfa 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -995,6 +995,7 @@ extern void x_wm_set_size_hint P_ ((struct frame *, long, int));
extern void x_wm_set_window_state P_ ((struct frame *, int));
extern void x_wm_set_icon_pixmap P_ ((struct frame *, int));
extern void x_delete_display P_ ((struct x_display_info *));
+extern void x_delete_device P_ ((struct device *device));
extern void x_initialize P_ ((void));
extern unsigned long x_copy_color P_ ((struct frame *, unsigned long));
#ifdef USE_X_TOOLKIT