X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/67f3ad67ee317226cb5d1bb139de0cfd883fdc5e..d66c02414328a8aa8c305853cea8c591c0278a11:/src/terminal.c diff --git a/src/terminal.c b/src/terminal.c index a02e65cd65..0b1e9f3257 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -1,12 +1,12 @@ /* Functions related to terminal devices. - Copyright (C) 2005 Free Software Foundation, Inc. + Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GNU Emacs. -GNU Emacs is free software; you can redistribute it and/or modify +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. +the Free Software Foundation, either version 3 of the License, 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 @@ -14,9 +14,7 @@ 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. */ +along with GNU Emacs. If not, see . */ #include #include @@ -205,24 +203,17 @@ get_terminal (Lisp_Object terminal, int throw) if (NILP (terminal)) terminal = selected_frame; - if (INTEGERP (terminal)) - { - struct terminal *t; + if (TERMINALP (terminal)) + result = XTERMINAL (terminal); - for (t = terminal_list; t; t = t->next_terminal) - { - if (t->id == XINT (terminal)) - { - result = t; - break; - } - } - } else if (FRAMEP (terminal)) { result = FRAME_TERMINAL (XFRAME (terminal)); } + if (result && !result->name) + result = NULL; + if (result == NULL && throw) wrong_type_argument (Qterminal_live_p, terminal); @@ -236,9 +227,9 @@ get_terminal (Lisp_Object terminal, int throw) struct terminal * create_terminal (void) { - struct terminal *terminal = (struct terminal *) xmalloc (sizeof (struct terminal)); - - bzero (terminal, sizeof (struct terminal)); + struct terminal *terminal = allocate_terminal (); + + terminal->name = NULL; terminal->next_terminal = terminal_list; terminal_list = terminal; @@ -249,27 +240,13 @@ create_terminal (void) terminal->terminal_coding = (struct coding_system *) xmalloc (sizeof (struct coding_system)); - setup_coding_system (Qnil, terminal->keyboard_coding); - setup_coding_system (Qnil, terminal->terminal_coding); + setup_coding_system (Qno_conversion, terminal->keyboard_coding); + setup_coding_system (Qundecided, terminal->terminal_coding); terminal->param_alist = Qnil; return terminal; } -/* Mark the Lisp pointers in the terminal objects. - Called by the Fgarbage_collector. */ - -void -mark_terminals (void) -{ - struct terminal *t; - for (t = terminal_list; t; t = t->next_terminal) - { - mark_object (t->param_alist); - } -} - - /* Low-level function to close all frames on a terminal, remove it from the terminal list and free its memory. */ @@ -279,11 +256,12 @@ delete_terminal (struct terminal *terminal) struct terminal **tp; Lisp_Object tail, frame; - /* Protect against recursive calls. Fdelete_frame calls the + /* Protect against recursive calls. delete_frame calls the delete_terminal_hook when we delete our last frame. */ - if (terminal->deleted) + if (!terminal->name) return; - terminal->deleted = 1; + xfree (terminal->name); + terminal->name = NULL; /* Check for live frames that are still on this terminal. */ FOR_EACH_FRAME (tail, frame) @@ -291,7 +269,8 @@ delete_terminal (struct terminal *terminal) struct frame *f = XFRAME (frame); if (FRAME_LIVE_P (f) && f->terminal == terminal) { - Fdelete_frame (frame, Qt); + /* Pass Qnoelisp rather than Qt. */ + delete_frame (frame, Qnoelisp); } } @@ -300,22 +279,22 @@ delete_terminal (struct terminal *terminal) abort (); *tp = terminal->next_terminal; - if (terminal->keyboard_coding) - xfree (terminal->keyboard_coding); - if (terminal->terminal_coding) - xfree (terminal->terminal_coding); - if (terminal->name) - xfree (terminal->name); - -#ifdef MULTI_KBOARD + xfree (terminal->keyboard_coding); + terminal->keyboard_coding = NULL; + xfree (terminal->terminal_coding); + terminal->terminal_coding = NULL; + if (terminal->kboard && --terminal->kboard->reference_count == 0) - delete_kboard (terminal->kboard); -#endif - - bzero (terminal, sizeof (struct terminal)); - xfree (terminal); + { + delete_kboard (terminal->kboard); + terminal->kboard = NULL; + } } +Lisp_Object Qrun_hook_with_args; +static Lisp_Object Qdelete_terminal_functions; +static Lisp_Object Vdelete_terminal_functions; + DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0, doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal. TERMINAL may be a terminal id, a frame, or nil (meaning the selected @@ -326,19 +305,30 @@ but if the second argument FORCE is non-nil, you may do so. */) (terminal, force) Lisp_Object terminal, force; { - struct terminal *t, *p; - - t = get_terminal (terminal, 0); + struct terminal *t = get_terminal (terminal, 0); if (!t) return Qnil; - p = terminal_list; - while (p && (p == t || !TERMINAL_ACTIVE_P (p))) - p = p->next_terminal; - - if (NILP (force) && !p) - error ("Attempt to delete the sole active display terminal"); + if (NILP (force)) + { + struct terminal *p = terminal_list; + while (p && (p == t || !TERMINAL_ACTIVE_P (p))) + p = p->next_terminal; + + if (!p) + error ("Attempt to delete the sole active display terminal"); + } + + if (NILP (Vrun_hooks)) + ; + else if (EQ (force, Qnoelisp)) + pending_funcalls + = Fcons (list3 (Qrun_hook_with_args, + Qdelete_terminal_functions, terminal), + pending_funcalls); + else + safe_call2 (Qrun_hook_with_args, Qdelete_terminal_functions, terminal); if (t->delete_terminal_hook) (*t->delete_terminal_hook) (t); @@ -364,12 +354,16 @@ The terminal device is represented by its integer identifier. */) CHECK_LIVE_FRAME (frame); - t = get_terminal (frame, 0); + t = FRAME_TERMINAL (XFRAME (frame)); if (!t) return Qnil; else - return make_number (t->id); + { + Lisp_Object terminal; + XSETTERMINAL (terminal, t); + return terminal; + } } DEFUN ("terminal-live-p", Fterminal_live_p, Sterminal_live_p, 1, 1, 0, @@ -377,16 +371,11 @@ DEFUN ("terminal-live-p", Fterminal_live_p, Sterminal_live_p, 1, 1, 0, Value is nil if OBJECT is not a live display terminal. If object is a live display terminal, the return value indicates what sort of output terminal it uses. See the documentation of `framep' for -possible return values. - -Display terminals are represented by their integer identifiers. */) +possible return values. */) (object) Lisp_Object object; { struct terminal *t; - - if (!INTEGERP (object)) - return Qnil; t = get_terminal (object, 0); @@ -406,21 +395,25 @@ Display terminals are represented by their integer identifiers. */) return Qpc; case output_mac: return Qmac; + case output_ns: + return Qns; default: abort (); } } DEFUN ("terminal-list", Fterminal_list, Sterminal_list, 0, 0, 0, - doc: /* Return a list of all terminal devices. -Terminal devices are represented by their integer identifiers. */) + doc: /* Return a list of all terminal devices. */) () { - Lisp_Object terminals = Qnil; + Lisp_Object terminal, terminals = Qnil; struct terminal *t; for (t = terminal_list; t; t = t->next_terminal) - terminals = Fcons (make_number (t->id), terminals); + { + XSETTERMINAL (terminal, t); + terminals = Fcons (terminal, terminals); + } return terminals; } @@ -434,12 +427,10 @@ selected frame's terminal). */) (terminal) Lisp_Object terminal; { - struct terminal *t = get_terminal (terminal, 1); + struct terminal *t + = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1); - if (t->name) - return build_string (t->name); - else - return Qnil; + return t->name ? build_string (t->name) : Qnil; } @@ -490,7 +481,8 @@ frame's terminal). */) (terminal) Lisp_Object terminal; { - struct terminal *t = get_terminal (terminal, 1); + struct terminal *t + = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1); return Fcopy_alist (t->param_alist); } @@ -503,54 +495,13 @@ frame's terminal). */) Lisp_Object parameter; { Lisp_Object value; - struct terminal *t = get_terminal (terminal, 1); + struct terminal *t + = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1); CHECK_SYMBOL (parameter); value = Fcdr (Fassq (parameter, t->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 id, a frame or nil (meaning the selected -frame's terminal). */) - (terminal, alist) - Lisp_Object terminal; - Lisp_Object alist; -{ - Lisp_Object tail, prop, val; - struct terminal *t = get_terminal (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 (t, 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. @@ -563,7 +514,8 @@ frame's terminal). */) Lisp_Object parameter; Lisp_Object value; { - struct terminal *t = get_terminal (terminal, 1); + struct terminal *t + = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1); return store_terminal_param (t, parameter, value); } @@ -581,9 +533,7 @@ init_initial_terminal (void) initial_terminal = create_terminal (); initial_terminal->type = output_initial; initial_terminal->name = xstrdup ("initial_terminal"); -#ifdef MULTI_KBOARD initial_terminal->kboard = initial_kboard; -#endif initial_terminal->delete_terminal_hook = &delete_initial_terminal; /* All other hooks are NULL. */ @@ -612,6 +562,17 @@ syms_of_terminal () The function should accept no arguments. */); Vring_bell_function = Qnil; + DEFVAR_LISP ("delete-terminal-functions", &Vdelete_terminal_functions, + doc: /* Special hook run when a terminal is deleted. +Each function is called with argument, the terminal. +This may be called just before actually deleting the terminal, +or some time later. */); + Vdelete_terminal_functions = Qnil; + Qdelete_terminal_functions = intern ("delete-terminal-functions"); + staticpro (&Qdelete_terminal_functions); + Qrun_hook_with_args = intern ("run-hook-with-args"); + staticpro (&Qrun_hook_with_args); + defsubr (&Sdelete_terminal); defsubr (&Sframe_terminal); defsubr (&Sterminal_live_p); @@ -619,7 +580,6 @@ The function should accept no arguments. */); defsubr (&Sterminal_name); defsubr (&Sterminal_parameters); defsubr (&Sterminal_parameter); - defsubr (&Smodify_terminal_parameters); defsubr (&Sset_terminal_parameter); Fprovide (intern ("multi-tty"), Qnil);