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