changeset 83420:521d3f18b3d1

Reimplement terminal parameters in C; clean up term.c, create terminal.c. * lisp/termdev.el (terminal-parameter-alist, terminal-parameters, terminal-parameter-p) (terminal-parameter, set-terminal-parameter, terminal-handle-delete-frame): Remove. * src/term.c (Vring_bell_function, device_list, initial_device) (next_device_id, ring_bell, update_begin, update_end) (set_terminal_window, cursor_to, raw_cursor_to) (clear_to_end, clear_frame, clear_end_of_line) (write_glyphs, insert_glyphs, delete_glyphs, ins_del_lines) (get_device, Fdisplay_name, create_device, delete_device) (Fdelete_display, Fdisplay_live_p, Fdisplay_list) Move to terminal.c. (syms_of_term): Move their initialization to terminal.c. * src/terminal.c: New file. (device_list, next_device_id, initial_device, Vring_bell_function) (ring_bell, update_begin, update_end, set_terminal_window) (cursor_to, raw_cursor_to, clear_to_end, clear_frame) (clear_end_of_line, write_glyphs, insert_glyphs, delete_glyphs) (ins_del_lines, get_device, create_device, delete_device) (Fdelete_display, Fdisplay_live_p, Fdisplay_list, Fdisplay_name): Move here. (mark_devices, get_terminal_param, store_terminal_param) (Fterminal_parameters, Fterminal_parameter) (Fmodify_terminal_parameters, Fset_terminal_parameter) (init_initial_device, delete_initial_device) (syms_of_terminal): New functions. * lisp/simple.el (normal-erase-is-backspace-setup-frame) (normal-erase-is-backspace-mode): Rephrase things without terminal-parameter-p. * lisp/termdev.el (terminal-getenv, terminal-setenv) (with-terminal-environment): Ditto. * mac/makefile.MPW (EmacsObjects): Add terminal.c.x. ({Src}terminal.c.x): Add dependencies. * src/Makefile.in (obj): Add terminal.o. (terminal.o): Add dependencies. [HAVE_CARBON]: Make terminal.o depend on macgui.h. * src/alloc.c (mark_devices): Declare. (Fgarbage_collect): Call `mark_devices'. * src/dispextern.h (set_scroll_region, turn_off_insert) (turn_off_highlight, background_highlight, clear_end_of_line_raw) (tty_clear_end_of_line, tty_setup_colors, delete_tty): Remove. (raw_cursor_to, clear_to_end, tty_turn_off_insert) (tty_turn_off_highlight): Add declaration. * src/emacs.c (main): Call `syms_of_terminal'. * src/frame.c (get_future_frame_param): New function. (Fmake_terminal_frame): Use it. * src/keyboard.c (pop_kboard): Remove unused variable. (Fset_output_flow_control): Return nil. * src/keymap.h (Fset_keymap_parent): Add EXFUN. * src/lisp.h (syms_of_terminal): Declare it. * src/sysdep.c (reset_sys_modes): Update for renames. * src/term.c (set_scroll_region): Rename to `tty_set_scroll_region'. (turn_on_insert): Rename to `tty_turn_on_insert'. (turn_off_insert): Rename to `tty_turn_off_insert'. (turn_off_highlight): Rename to `tty_turn_off_highlight'. (turn_on_highlight): Rename to `tty_turn_on_highlight'. (toggle_highligh): Rename to `tty_toggle_highlight'. (background_highlight): Rename to `tty_background_highlight'. (highlight_if_desired): Rename to `tty_highlight_if_desired'. (tty_ring_bell, tty_update_end, tty_set_terminal_window) (tty_set_scroll_region, tty_background_highlight) (tty_cursor_to, tty_raw_cursor_to, tty_clear_to_end) (tty_clear_frame, tty_clear_end_of_line, tty_write_glyphs) (tty_insert_glyphs, tty_delete_glyphs, tty_ins_del_lines) (term_get_fkeys, tty_setup_colors, dissociate_if_controlling_tty) (delete_tty): Add static modifier. (tty_reset_terminal_modes, tty_set_terminal_window) (tty_set_scroll_region, tty_background_highlight) (tty_highlight_if_desired, tty_cursor_to) (tty_raw_cursor_to, tty_clear_to_end, tty_clear_frame) (tty_clear_end_of_line, tty_write_glyphs, tty_insert_glyphs) (tty_delete_glyphs, tty_ins_del_lines, turn_on_face): Update for renames. * src/termhooks.h (param_alist): New member to struct device. * src/xterm.h (x_delete_device): Declare. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-460
author Karoly Lorentey <lorentey@elte.hu>
date Sun, 25 Dec 2005 20:06:58 +0000
parents b658f9b67fc5
children bb2edc915032
files README.multi-tty lisp/simple.el lisp/termdev.el mac/makefile.MPW src/Makefile.in src/alloc.c src/dispextern.h src/emacs.c src/frame.c src/keyboard.c src/keymap.h src/lisp.h src/sysdep.c src/term.c src/termhooks.h src/terminal.c src/xterm.h
diffstat 17 files changed, 959 insertions(+), 748 deletions(-) [+]
line wrap: on
line diff
--- a/README.multi-tty	Fri Dec 23 03:36:01 2005 +0000
+++ b/README.multi-tty	Sun Dec 25 20:06:58 2005 +0000
@@ -401,6 +401,41 @@
 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 @@
 ** 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.
--- a/lisp/simple.el	Fri Dec 23 03:36:01 2005 +0000
+++ b/lisp/simple.el	Sun Dec 25 20:06:58 2005 +0000
@@ -5323,10 +5323,8 @@
   "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 @@
   (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 @@
 		    [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 @@
 		   (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 @@
   (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.")
--- a/lisp/termdev.el	Fri Dec 23 03:36:01 2005 +0000
+++ b/lisp/termdev.el	Sun Dec 25 20:06:58 2005 +0000
@@ -48,66 +48,6 @@
    (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 @@
 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 @@
 
 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 @@
        (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)
--- a/mac/makefile.MPW	Fri Dec 23 03:36:01 2005 +0000
+++ b/mac/makefile.MPW	Sun Dec 25 20:06:58 2005 +0000
@@ -118,6 +118,7 @@
 	"{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 @@
 	"{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" ¶
--- a/src/Makefile.in	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/Makefile.in	Sun Dec 25 20:06:58 2005 +0000
@@ -577,7 +577,7 @@
    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 @@
    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 @@
 #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)
--- a/src/alloc.c	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/alloc.c	Sun Dec 25 20:06:58 2005 +0000
@@ -324,6 +324,7 @@
 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 @@
       mark_object (bind->symbol);
       mark_object (bind->old_value);
     }
+  mark_devices ();
   mark_kboards ();
   mark_ttys ();
 
--- a/src/dispextern.h	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/dispextern.h	Sun Dec 25 20:06:58 2005 +0000
@@ -2622,8 +2622,6 @@
 				     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 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 @@
 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 void create_tty_output P_ ((struct frame *));
 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 *));
 
 
 /* Defined in scroll.c */
--- a/src/emacs.c	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/emacs.c	Sun Dec 25 20:06:58 2005 +0000
@@ -1600,6 +1600,7 @@
       syms_of_frame ();
 #endif
       syms_of_syntax ();
+      syms_of_terminal ();
       syms_of_term ();
       syms_of_undo ();
 #ifdef HAVE_SOUND
--- a/src/frame.c	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/frame.c	Sun Dec 25 20:06:58 2005 +0000
@@ -638,6 +638,33 @@
   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 @@
   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 @@
   if (!d)
     { 
       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_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))
+      Lisp_Object tty, tty_type;
+
+      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 @@
   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.  */
--- a/src/keyboard.c	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/keyboard.c	Sun Dec 25 20:06:58 2005 +0000
@@ -1136,7 +1136,6 @@
 #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 @@
       init_sys_modes (tty);
 #endif
     }
+  return Qnil;
 }
 
 DEFUN ("set-input-meta-mode", Fset_input_meta_mode, Sset_input_meta_mode, 1, 2, 0,
--- a/src/keymap.h	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/keymap.h	Sun Dec 25 20:06:58 2005 +0000
@@ -37,6 +37,7 @@
 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 **));
--- a/src/lisp.h	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/lisp.h	Sun Dec 25 20:06:58 2005 +0000
@@ -3184,6 +3184,9 @@
 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));
--- a/src/sysdep.c	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/sysdep.c	Sun Dec 25 20:06:58 2005 +0000
@@ -1972,7 +1972,7 @@
   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++)
         {
--- a/src/term.c	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/term.c	Sun Dec 25 20:06:58 2005 +0000
@@ -80,14 +80,14 @@
 #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 @@
 
 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 @@
    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 @@
    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 @@
 #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 @@
 
   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 @@
     }
 }
 
-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 @@
 
 
 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 @@
 }
 
 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 @@
 /* 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 @@
 }
 
 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 @@
 }
 
 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 @@
    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 @@
       && 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 @@
       && 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 @@
 
   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 @@
     }
 }
 
-/* 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 @@
     }
 }
 
-/* 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 @@
 
   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 @@
 }
 
 
-/* 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 @@
 
   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 @@
 	  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 @@
 
       /* 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 @@
       return;
     }
 
-  turn_on_insert (tty);
+  tty_turn_on_insert (tty);
   cmplus (tty, len);
 
   if (! start)
@@ -886,7 +754,7 @@
 	}
       else
 	{
-	  highlight_if_desired (tty);
+	  tty_highlight_if_desired (tty);
 	  turn_on_face (f, start->face_id);
 	  glyph = start;
 	  ++start;
@@ -918,25 +786,16 @@
       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 @@
 
   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 @@
     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 @@
   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 @@
   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 @@
     }
   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 @@
    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 @@
 	    {
 	      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 @@
 	    {
 	      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 @@
    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 @@
 
 
 
-/* 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 @@
 }
 
 
-
-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 @@
   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.  */
-
-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. */
+/* Initialize the tty-dependent part of frame F.  The frame must
+   already have its device initialized. */
 
 void
-delete_initial_device (struct device *device)
+create_tty_output (struct frame *f)
 {
-  if (device != initial_device)
+  struct tty_output *t;
+
+  if (! FRAME_TERMCAP_P (f))
     abort ();
 
-  delete_device (device);
-  initial_device = NULL;
+  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. */
+
+static void
+delete_tty_output (struct frame *f)
+{
+  if (! FRAME_TERMCAP_P (f))
+    abort ();
+
+  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 @@
 
 /* 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 @@
 
 
 
-/* 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 @@
 
 
 
-/* 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 @@
   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 @@
   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);
-
 }
 
 
--- a/src/termhooks.h	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/termhooks.h	Sun Dec 25 20:06:58 2005 +0000
@@ -330,6 +330,9 @@
      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? */
   
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/terminal.c	Sun Dec 25 20:06:58 2005 +0000
@@ -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) */
--- a/src/xterm.h	Fri Dec 23 03:36:01 2005 +0000
+++ b/src/xterm.h	Sun Dec 25 20:06:58 2005 +0000
@@ -995,6 +995,7 @@
 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