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