Commit | Line | Data |
---|---|---|
ed8dad6b | 1 | /* Functions related to terminal devices. |
ab422c4d | 2 | Copyright (C) 2005-2013 Free Software Foundation, Inc. |
ed8dad6b KL |
3 | |
4 | This file is part of GNU Emacs. | |
5 | ||
9ec0b715 | 6 | GNU Emacs is free software: you can redistribute it and/or modify |
ed8dad6b | 7 | it under the terms of the GNU General Public License as published by |
9ec0b715 GM |
8 | the Free Software Foundation, either version 3 of the License, or |
9 | (at your option) any later version. | |
ed8dad6b KL |
10 | |
11 | GNU Emacs is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
9ec0b715 | 17 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ |
ed8dad6b KL |
18 | |
19 | #include <config.h> | |
3f22b86f PE |
20 | |
21 | #define TERMHOOKS_INLINE EXTERN_INLINE | |
22 | ||
60f5c938 | 23 | #include <stdio.h> |
ed8dad6b KL |
24 | |
25 | #include "lisp.h" | |
26 | #include "frame.h" | |
27 | #include "termchar.h" | |
28 | #include "termhooks.h" | |
29 | #include "charset.h" | |
30 | #include "coding.h" | |
31 | #include "keyboard.h" | |
32 | ||
6ed8eeff KL |
33 | /* Chain of all terminals currently in use. */ |
34 | struct terminal *terminal_list; | |
ed8dad6b | 35 | |
6ed8eeff KL |
36 | /* The first unallocated terminal id. */ |
37 | static int next_terminal_id; | |
ed8dad6b | 38 | |
6ed8eeff KL |
39 | /* The initial terminal device, created by initial_term_init. */ |
40 | struct terminal *initial_terminal; | |
ed8dad6b | 41 | |
959067a1 DA |
42 | static Lisp_Object Qterminal_live_p; |
43 | ||
f57e2426 | 44 | static void delete_initial_terminal (struct terminal *); |
ed8dad6b | 45 | |
3f22b86f | 46 | /* This setter is used only in this file, so it can be private. */ |
b0ab8123 | 47 | static void |
3f22b86f PE |
48 | tset_param_alist (struct terminal *t, Lisp_Object val) |
49 | { | |
50 | t->param_alist = val; | |
51 | } | |
52 | ||
ed8dad6b KL |
53 | \f |
54 | ||
55 | void | |
56 | ring_bell (struct frame *f) | |
57 | { | |
58 | if (!NILP (Vring_bell_function)) | |
59 | { | |
60 | Lisp_Object function; | |
61 | ||
62 | /* Temporarily set the global variable to nil | |
63 | so that if we get an error, it stays nil | |
64 | and we don't call it over and over. | |
65 | ||
66 | We don't specbind it, because that would carefully | |
67 | restore the bad value if there's an error | |
68 | and make the loop of errors happen anyway. */ | |
69 | ||
70 | function = Vring_bell_function; | |
71 | Vring_bell_function = Qnil; | |
72 | ||
73 | call0 (function); | |
74 | ||
75 | Vring_bell_function = function; | |
76 | } | |
6ed8eeff KL |
77 | else if (FRAME_TERMINAL (f)->ring_bell_hook) |
78 | (*FRAME_TERMINAL (f)->ring_bell_hook) (f); | |
ed8dad6b KL |
79 | } |
80 | ||
81 | void | |
82 | update_begin (struct frame *f) | |
83 | { | |
6ed8eeff KL |
84 | if (FRAME_TERMINAL (f)->update_begin_hook) |
85 | (*FRAME_TERMINAL (f)->update_begin_hook) (f); | |
ed8dad6b KL |
86 | } |
87 | ||
88 | void | |
89 | update_end (struct frame *f) | |
90 | { | |
6ed8eeff KL |
91 | if (FRAME_TERMINAL (f)->update_end_hook) |
92 | (*FRAME_TERMINAL (f)->update_end_hook) (f); | |
ed8dad6b KL |
93 | } |
94 | ||
95 | /* Specify how many text lines, from the top of the window, | |
96 | should be affected by insert-lines and delete-lines operations. | |
97 | This, and those operations, are used only within an update | |
98 | that is bounded by calls to update_begin and update_end. */ | |
99 | ||
100 | void | |
101 | set_terminal_window (struct frame *f, int size) | |
102 | { | |
6ed8eeff KL |
103 | if (FRAME_TERMINAL (f)->set_terminal_window_hook) |
104 | (*FRAME_TERMINAL (f)->set_terminal_window_hook) (f, size); | |
ed8dad6b KL |
105 | } |
106 | ||
107 | /* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are | |
108 | frame-relative coordinates. */ | |
109 | ||
110 | void | |
111 | cursor_to (struct frame *f, int vpos, int hpos) | |
112 | { | |
6ed8eeff KL |
113 | if (FRAME_TERMINAL (f)->cursor_to_hook) |
114 | (*FRAME_TERMINAL (f)->cursor_to_hook) (f, vpos, hpos); | |
ed8dad6b KL |
115 | } |
116 | ||
117 | /* Similar but don't take any account of the wasted characters. */ | |
118 | ||
119 | void | |
120 | raw_cursor_to (struct frame *f, int row, int col) | |
121 | { | |
6ed8eeff | 122 | if (FRAME_TERMINAL (f)->raw_cursor_to_hook) |
426994c3 | 123 | (*FRAME_TERMINAL (f)->raw_cursor_to_hook) (f, row, col); |
ed8dad6b KL |
124 | } |
125 | ||
126 | /* Erase operations */ | |
127 | ||
128 | /* Clear from cursor to end of frame. */ | |
129 | void | |
130 | clear_to_end (struct frame *f) | |
131 | { | |
6ed8eeff KL |
132 | if (FRAME_TERMINAL (f)->clear_to_end_hook) |
133 | (*FRAME_TERMINAL (f)->clear_to_end_hook) (f); | |
ed8dad6b KL |
134 | } |
135 | ||
136 | /* Clear entire frame */ | |
137 | ||
138 | void | |
139 | clear_frame (struct frame *f) | |
140 | { | |
6ed8eeff KL |
141 | if (FRAME_TERMINAL (f)->clear_frame_hook) |
142 | (*FRAME_TERMINAL (f)->clear_frame_hook) (f); | |
ed8dad6b KL |
143 | } |
144 | ||
145 | /* Clear from cursor to end of line. | |
146 | Assume that the line is already clear starting at column first_unused_hpos. | |
147 | ||
148 | Note that the cursor may be moved, on terminals lacking a `ce' string. */ | |
149 | ||
150 | void | |
151 | clear_end_of_line (struct frame *f, int first_unused_hpos) | |
152 | { | |
6ed8eeff KL |
153 | if (FRAME_TERMINAL (f)->clear_end_of_line_hook) |
154 | (*FRAME_TERMINAL (f)->clear_end_of_line_hook) (f, first_unused_hpos); | |
ed8dad6b KL |
155 | } |
156 | ||
157 | /* Output LEN glyphs starting at STRING at the nominal cursor position. | |
158 | Advance the nominal cursor over the text. */ | |
159 | ||
160 | void | |
161 | write_glyphs (struct frame *f, struct glyph *string, int len) | |
162 | { | |
6ed8eeff KL |
163 | if (FRAME_TERMINAL (f)->write_glyphs_hook) |
164 | (*FRAME_TERMINAL (f)->write_glyphs_hook) (f, string, len); | |
ed8dad6b KL |
165 | } |
166 | ||
167 | /* Insert LEN glyphs from START at the nominal cursor position. | |
168 | ||
169 | If start is zero, insert blanks instead of a string at start */ | |
170 | ||
171 | void | |
172 | insert_glyphs (struct frame *f, struct glyph *start, int len) | |
173 | { | |
174 | if (len <= 0) | |
175 | return; | |
176 | ||
6ed8eeff KL |
177 | if (FRAME_TERMINAL (f)->insert_glyphs_hook) |
178 | (*FRAME_TERMINAL (f)->insert_glyphs_hook) (f, start, len); | |
ed8dad6b KL |
179 | } |
180 | ||
181 | /* Delete N glyphs at the nominal cursor position. */ | |
182 | ||
183 | void | |
184 | delete_glyphs (struct frame *f, int n) | |
185 | { | |
6ed8eeff KL |
186 | if (FRAME_TERMINAL (f)->delete_glyphs_hook) |
187 | (*FRAME_TERMINAL (f)->delete_glyphs_hook) (f, n); | |
ed8dad6b KL |
188 | } |
189 | ||
190 | /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */ | |
191 | ||
192 | void | |
193 | ins_del_lines (struct frame *f, int vpos, int n) | |
194 | { | |
6ed8eeff KL |
195 | if (FRAME_TERMINAL (f)->ins_del_lines_hook) |
196 | (*FRAME_TERMINAL (f)->ins_del_lines_hook) (f, vpos, n); | |
ed8dad6b KL |
197 | } |
198 | ||
199 | ||
200 | \f | |
201 | ||
e0c3684a CY |
202 | /* Return the terminal object specified by TERMINAL. TERMINAL may be |
203 | a terminal object, a frame, or nil for the terminal device of the | |
653d4f43 | 204 | current frame. If THROW is false, return NULL for failure, |
e0c3684a | 205 | otherwise throw an error. */ |
ed8dad6b | 206 | |
6ed8eeff | 207 | struct terminal * |
653d4f43 | 208 | get_terminal (Lisp_Object terminal, bool throw) |
ed8dad6b | 209 | { |
6ed8eeff | 210 | struct terminal *result = NULL; |
ed8dad6b | 211 | |
6ed8eeff KL |
212 | if (NILP (terminal)) |
213 | terminal = selected_frame; | |
ed8dad6b | 214 | |
d30a25b3 SM |
215 | if (TERMINALP (terminal)) |
216 | result = XTERMINAL (terminal); | |
6ed8eeff | 217 | else if (FRAMEP (terminal)) |
e0c3684a | 218 | result = FRAME_TERMINAL (XFRAME (terminal)); |
ed8dad6b | 219 | |
d30a25b3 SM |
220 | if (result && !result->name) |
221 | result = NULL; | |
222 | ||
ed8dad6b | 223 | if (result == NULL && throw) |
6ed8eeff | 224 | wrong_type_argument (Qterminal_live_p, terminal); |
ed8dad6b KL |
225 | |
226 | return result; | |
227 | } | |
228 | ||
229 | \f | |
230 | ||
6ed8eeff | 231 | /* Create a new terminal object and add it to the terminal list. */ |
ed8dad6b | 232 | |
6ed8eeff KL |
233 | struct terminal * |
234 | create_terminal (void) | |
ed8dad6b | 235 | { |
d30a25b3 | 236 | struct terminal *terminal = allocate_terminal (); |
d6de49a1 | 237 | Lisp_Object terminal_coding, keyboard_coding; |
d30a25b3 | 238 | |
6ed8eeff KL |
239 | terminal->next_terminal = terminal_list; |
240 | terminal_list = terminal; | |
ed8dad6b | 241 | |
6ed8eeff | 242 | terminal->id = next_terminal_id++; |
ed8dad6b | 243 | |
23f86fce DA |
244 | terminal->keyboard_coding = xmalloc (sizeof (struct coding_system)); |
245 | terminal->terminal_coding = xmalloc (sizeof (struct coding_system)); | |
ed8dad6b | 246 | |
d6de49a1 EZ |
247 | /* If default coding systems for the terminal and the keyboard are |
248 | already defined, use them in preference to the defaults. This is | |
249 | needed when Emacs runs in daemon mode. */ | |
250 | keyboard_coding = | |
251 | find_symbol_value (intern ("default-keyboard-coding-system")); | |
252 | if (NILP (keyboard_coding) | |
253 | || EQ (keyboard_coding, Qunbound) | |
254 | || NILP (Fcoding_system_p (keyboard_coding))) | |
255 | keyboard_coding = Qno_conversion; | |
256 | terminal_coding = | |
257 | find_symbol_value (intern ("default-terminal-coding-system")); | |
258 | if (NILP (terminal_coding) | |
259 | || EQ (terminal_coding, Qunbound) | |
260 | || NILP (Fcoding_system_p (terminal_coding))) | |
261 | terminal_coding = Qundecided; | |
262 | ||
263 | setup_coding_system (keyboard_coding, terminal->keyboard_coding); | |
264 | setup_coding_system (terminal_coding, terminal->terminal_coding); | |
ed8dad6b | 265 | |
6ed8eeff | 266 | return terminal; |
ed8dad6b KL |
267 | } |
268 | ||
ab797f65 KL |
269 | /* Low-level function to close all frames on a terminal, remove it |
270 | from the terminal list and free its memory. */ | |
ed8dad6b KL |
271 | |
272 | void | |
6ed8eeff | 273 | delete_terminal (struct terminal *terminal) |
ed8dad6b | 274 | { |
6ed8eeff | 275 | struct terminal **tp; |
ed8dad6b | 276 | Lisp_Object tail, frame; |
a98f1617 | 277 | |
56f2de10 | 278 | /* Protect against recursive calls. delete_frame calls the |
ab797f65 | 279 | delete_terminal_hook when we delete our last frame. */ |
d30a25b3 | 280 | if (!terminal->name) |
a98f1617 | 281 | return; |
d30a25b3 SM |
282 | xfree (terminal->name); |
283 | terminal->name = NULL; | |
a98f1617 | 284 | |
cbae07d5 | 285 | /* Check for live frames that are still on this terminal. */ |
ed8dad6b KL |
286 | FOR_EACH_FRAME (tail, frame) |
287 | { | |
288 | struct frame *f = XFRAME (frame); | |
6ed8eeff | 289 | if (FRAME_LIVE_P (f) && f->terminal == terminal) |
ed8dad6b | 290 | { |
56f2de10 MR |
291 | /* Pass Qnoelisp rather than Qt. */ |
292 | delete_frame (frame, Qnoelisp); | |
ed8dad6b KL |
293 | } |
294 | } | |
295 | ||
6ed8eeff KL |
296 | for (tp = &terminal_list; *tp != terminal; tp = &(*tp)->next_terminal) |
297 | if (! *tp) | |
1088b922 | 298 | emacs_abort (); |
6ed8eeff KL |
299 | *tp = terminal->next_terminal; |
300 | ||
d30a25b3 SM |
301 | xfree (terminal->keyboard_coding); |
302 | terminal->keyboard_coding = NULL; | |
303 | xfree (terminal->terminal_coding); | |
304 | terminal->terminal_coding = NULL; | |
56f2de10 | 305 | |
6ed8eeff | 306 | if (terminal->kboard && --terminal->kboard->reference_count == 0) |
d30a25b3 SM |
307 | { |
308 | delete_kboard (terminal->kboard); | |
309 | terminal->kboard = NULL; | |
310 | } | |
ed8dad6b KL |
311 | } |
312 | ||
58555d81 SM |
313 | Lisp_Object Qrun_hook_with_args; |
314 | static Lisp_Object Qdelete_terminal_functions; | |
a7ca3326 | 315 | DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0, |
6ed8eeff | 316 | doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal. |
e173bbce CY |
317 | TERMINAL may be a terminal object, a frame, or nil (meaning the |
318 | selected frame's terminal). | |
ed8dad6b KL |
319 | |
320 | Normally, you may not delete a display if all other displays are suspended, | |
321 | but if the second argument FORCE is non-nil, you may do so. */) | |
5842a27b | 322 | (Lisp_Object terminal, Lisp_Object force) |
ed8dad6b | 323 | { |
5b8de9c5 | 324 | struct terminal *t = get_terminal (terminal, 0); |
ed8dad6b | 325 | |
6ed8eeff | 326 | if (!t) |
ed8dad6b KL |
327 | return Qnil; |
328 | ||
5b8de9c5 SM |
329 | if (NILP (force)) |
330 | { | |
331 | struct terminal *p = terminal_list; | |
332 | while (p && (p == t || !TERMINAL_ACTIVE_P (p))) | |
333 | p = p->next_terminal; | |
56f2de10 | 334 | |
5b8de9c5 SM |
335 | if (!p) |
336 | error ("Attempt to delete the sole active display terminal"); | |
337 | } | |
ed8dad6b | 338 | |
58555d81 SM |
339 | if (NILP (Vrun_hooks)) |
340 | ; | |
341 | else if (EQ (force, Qnoelisp)) | |
342 | pending_funcalls | |
343 | = Fcons (list3 (Qrun_hook_with_args, | |
344 | Qdelete_terminal_functions, terminal), | |
345 | pending_funcalls); | |
346 | else | |
347 | safe_call2 (Qrun_hook_with_args, Qdelete_terminal_functions, terminal); | |
348 | ||
6ed8eeff KL |
349 | if (t->delete_terminal_hook) |
350 | (*t->delete_terminal_hook) (t); | |
ed8dad6b | 351 | else |
6ed8eeff | 352 | delete_terminal (t); |
ed8dad6b KL |
353 | |
354 | return Qnil; | |
355 | } | |
356 | ||
6ed8eeff | 357 | \f |
a7ca3326 | 358 | DEFUN ("frame-terminal", Fframe_terminal, Sframe_terminal, 0, 1, 0, |
6ed8eeff KL |
359 | doc: /* Return the terminal that FRAME is displayed on. |
360 | If FRAME is nil, the selected frame is used. | |
361 | ||
362 | The terminal device is represented by its integer identifier. */) | |
5842a27b | 363 | (Lisp_Object frame) |
6ed8eeff | 364 | { |
d9f07150 | 365 | struct terminal *t = FRAME_TERMINAL (decode_live_frame (frame)); |
6ed8eeff KL |
366 | |
367 | if (!t) | |
368 | return Qnil; | |
369 | else | |
d30a25b3 SM |
370 | { |
371 | Lisp_Object terminal; | |
372 | XSETTERMINAL (terminal, t); | |
373 | return terminal; | |
374 | } | |
6ed8eeff KL |
375 | } |
376 | ||
377 | DEFUN ("terminal-live-p", Fterminal_live_p, Sterminal_live_p, 1, 1, 0, | |
378 | doc: /* Return non-nil if OBJECT is a terminal which has not been deleted. | |
379 | Value is nil if OBJECT is not a live display terminal. | |
380 | If object is a live display terminal, the return value indicates what | |
381 | sort of output terminal it uses. See the documentation of `framep' for | |
d30a25b3 | 382 | possible return values. */) |
5842a27b | 383 | (Lisp_Object object) |
ed8dad6b | 384 | { |
6ed8eeff | 385 | struct terminal *t; |
56f2de10 | 386 | |
6ed8eeff | 387 | t = get_terminal (object, 0); |
ed8dad6b | 388 | |
6ed8eeff | 389 | if (!t) |
ed8dad6b KL |
390 | return Qnil; |
391 | ||
6ed8eeff | 392 | switch (t->type) |
ed8dad6b KL |
393 | { |
394 | case output_initial: /* The initial frame is like a termcap frame. */ | |
395 | case output_termcap: | |
396 | return Qt; | |
397 | case output_x_window: | |
398 | return Qx; | |
399 | case output_w32: | |
400 | return Qw32; | |
401 | case output_msdos_raw: | |
402 | return Qpc; | |
edfda783 AR |
403 | case output_ns: |
404 | return Qns; | |
ed8dad6b | 405 | default: |
1088b922 | 406 | emacs_abort (); |
ed8dad6b KL |
407 | } |
408 | } | |
409 | ||
6ed8eeff | 410 | DEFUN ("terminal-list", Fterminal_list, Sterminal_list, 0, 0, 0, |
d30a25b3 | 411 | doc: /* Return a list of all terminal devices. */) |
5842a27b | 412 | (void) |
ed8dad6b | 413 | { |
d30a25b3 | 414 | Lisp_Object terminal, terminals = Qnil; |
6ed8eeff | 415 | struct terminal *t; |
ed8dad6b | 416 | |
6ed8eeff | 417 | for (t = terminal_list; t; t = t->next_terminal) |
d30a25b3 SM |
418 | { |
419 | XSETTERMINAL (terminal, t); | |
420 | terminals = Fcons (terminal, terminals); | |
421 | } | |
ed8dad6b | 422 | |
6ed8eeff | 423 | return terminals; |
ed8dad6b KL |
424 | } |
425 | ||
6ed8eeff KL |
426 | DEFUN ("terminal-name", Fterminal_name, Sterminal_name, 0, 1, 0, |
427 | doc: /* Return the name of the terminal device TERMINAL. | |
ed8dad6b KL |
428 | It is not guaranteed that the returned value is unique among opened devices. |
429 | ||
e173bbce | 430 | TERMINAL may be a terminal object, a frame, or nil (meaning the |
6ed8eeff | 431 | selected frame's terminal). */) |
5842a27b | 432 | (Lisp_Object terminal) |
ed8dad6b | 433 | { |
c5911e55 SM |
434 | struct terminal *t |
435 | = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1); | |
ed8dad6b | 436 | |
c5911e55 | 437 | return t->name ? build_string (t->name) : Qnil; |
ed8dad6b KL |
438 | } |
439 | ||
440 | ||
441 | \f | |
6ed8eeff | 442 | /* Set the value of terminal parameter PARAMETER in terminal D to VALUE. |
ed8dad6b KL |
443 | Return the previous value. */ |
444 | ||
426994c3 | 445 | static Lisp_Object |
971de7fb | 446 | store_terminal_param (struct terminal *t, Lisp_Object parameter, Lisp_Object value) |
ed8dad6b | 447 | { |
6ed8eeff | 448 | Lisp_Object old_alist_elt = Fassq (parameter, t->param_alist); |
ed8dad6b KL |
449 | if (EQ (old_alist_elt, Qnil)) |
450 | { | |
3f22b86f | 451 | tset_param_alist (t, Fcons (Fcons (parameter, value), t->param_alist)); |
ed8dad6b KL |
452 | return Qnil; |
453 | } | |
454 | else | |
455 | { | |
456 | Lisp_Object result = Fcdr (old_alist_elt); | |
457 | Fsetcdr (old_alist_elt, value); | |
458 | return result; | |
459 | } | |
460 | } | |
461 | ||
462 | ||
463 | DEFUN ("terminal-parameters", Fterminal_parameters, Sterminal_parameters, 0, 1, 0, | |
464 | doc: /* Return the parameter-alist of terminal TERMINAL. | |
465 | The value is a list of elements of the form (PARM . VALUE), where PARM | |
466 | is a symbol. | |
467 | ||
e173bbce CY |
468 | TERMINAL can be a terminal object, a frame, or nil (meaning the |
469 | selected frame's terminal). */) | |
5842a27b | 470 | (Lisp_Object terminal) |
ed8dad6b | 471 | { |
c5911e55 SM |
472 | struct terminal *t |
473 | = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1); | |
6ed8eeff | 474 | return Fcopy_alist (t->param_alist); |
ed8dad6b KL |
475 | } |
476 | ||
477 | DEFUN ("terminal-parameter", Fterminal_parameter, Sterminal_parameter, 2, 2, 0, | |
478 | doc: /* Return TERMINAL's value for parameter PARAMETER. | |
e173bbce CY |
479 | TERMINAL can be a terminal object, a frame, or nil (meaning the |
480 | selected frame's terminal). */) | |
5842a27b | 481 | (Lisp_Object terminal, Lisp_Object parameter) |
ed8dad6b KL |
482 | { |
483 | Lisp_Object value; | |
c5911e55 SM |
484 | struct terminal *t |
485 | = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1); | |
ed8dad6b | 486 | CHECK_SYMBOL (parameter); |
6ed8eeff | 487 | value = Fcdr (Fassq (parameter, t->param_alist)); |
ed8dad6b KL |
488 | return value; |
489 | } | |
490 | ||
ed8dad6b KL |
491 | DEFUN ("set-terminal-parameter", Fset_terminal_parameter, |
492 | Sset_terminal_parameter, 3, 3, 0, | |
493 | doc: /* Set TERMINAL's value for parameter PARAMETER to VALUE. | |
494 | Return the previous value of PARAMETER. | |
495 | ||
e173bbce CY |
496 | TERMINAL can be a terminal object, a frame or nil (meaning the |
497 | selected frame's terminal). */) | |
5842a27b | 498 | (Lisp_Object terminal, Lisp_Object parameter, Lisp_Object value) |
ed8dad6b | 499 | { |
c5911e55 SM |
500 | struct terminal *t |
501 | = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1); | |
6ed8eeff | 502 | return store_terminal_param (t, parameter, value); |
ed8dad6b KL |
503 | } |
504 | ||
505 | \f | |
506 | ||
6ed8eeff KL |
507 | /* Create the bootstrap display terminal for the initial frame. |
508 | Returns a terminal of type output_initial. */ | |
ed8dad6b | 509 | |
6ed8eeff KL |
510 | struct terminal * |
511 | init_initial_terminal (void) | |
ed8dad6b | 512 | { |
6ed8eeff | 513 | if (initialized || terminal_list || tty_list) |
1088b922 | 514 | emacs_abort (); |
ed8dad6b | 515 | |
6ed8eeff KL |
516 | initial_terminal = create_terminal (); |
517 | initial_terminal->type = output_initial; | |
518 | initial_terminal->name = xstrdup ("initial_terminal"); | |
519 | initial_terminal->kboard = initial_kboard; | |
6ed8eeff | 520 | initial_terminal->delete_terminal_hook = &delete_initial_terminal; |
ed8dad6b KL |
521 | /* All other hooks are NULL. */ |
522 | ||
6ed8eeff | 523 | return initial_terminal; |
ed8dad6b KL |
524 | } |
525 | ||
6ed8eeff KL |
526 | /* Deletes the bootstrap terminal device. |
527 | Called through delete_terminal_hook. */ | |
ed8dad6b | 528 | |
6ed8eeff KL |
529 | static void |
530 | delete_initial_terminal (struct terminal *terminal) | |
ed8dad6b | 531 | { |
6ed8eeff | 532 | if (terminal != initial_terminal) |
1088b922 | 533 | emacs_abort (); |
ed8dad6b | 534 | |
6ed8eeff KL |
535 | delete_terminal (terminal); |
536 | initial_terminal = NULL; | |
ed8dad6b KL |
537 | } |
538 | ||
539 | void | |
971de7fb | 540 | syms_of_terminal (void) |
ed8dad6b KL |
541 | { |
542 | ||
29208e82 | 543 | DEFVAR_LISP ("ring-bell-function", Vring_bell_function, |
ed8dad6b KL |
544 | doc: /* Non-nil means call this function to ring the bell. |
545 | The function should accept no arguments. */); | |
546 | Vring_bell_function = Qnil; | |
547 | ||
29208e82 | 548 | DEFVAR_LISP ("delete-terminal-functions", Vdelete_terminal_functions, |
58555d81 SM |
549 | doc: /* Special hook run when a terminal is deleted. |
550 | Each function is called with argument, the terminal. | |
551 | This may be called just before actually deleting the terminal, | |
552 | or some time later. */); | |
553 | Vdelete_terminal_functions = Qnil; | |
959067a1 DA |
554 | |
555 | DEFSYM (Qterminal_live_p, "terminal-live-p"); | |
cd3520a4 JB |
556 | DEFSYM (Qdelete_terminal_functions, "delete-terminal-functions"); |
557 | DEFSYM (Qrun_hook_with_args, "run-hook-with-args"); | |
58555d81 | 558 | |
6ed8eeff KL |
559 | defsubr (&Sdelete_terminal); |
560 | defsubr (&Sframe_terminal); | |
561 | defsubr (&Sterminal_live_p); | |
562 | defsubr (&Sterminal_list); | |
563 | defsubr (&Sterminal_name); | |
ed8dad6b KL |
564 | defsubr (&Sterminal_parameters); |
565 | defsubr (&Sterminal_parameter); | |
ed8dad6b KL |
566 | defsubr (&Sset_terminal_parameter); |
567 | ||
d67b4f80 | 568 | Fprovide (intern_c_string ("multi-tty"), Qnil); |
ed8dad6b | 569 | } |