Commit | Line | Data |
---|---|---|
ed8dad6b KL |
1 | /* Functions related to terminal devices. |
2 | Copyright (C) 2005 Free Software Foundation, Inc. | |
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 | |
8 | the Free Software Foundation; either version 2, or (at your option) | |
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> | |
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 | ||
6ed8eeff | 43 | static void delete_initial_terminal P_ ((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 | ||
6ed8eeff KL |
194 | /* Return the terminal object specified by TERMINAL. TERMINAL may be a |
195 | terminal id, a frame, or nil for the terminal device of the current | |
ed8dad6b KL |
196 | frame. If THROW is zero, return NULL for failure, otherwise throw |
197 | an error. */ | |
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 | |
6ed8eeff | 207 | if (INTEGERP (terminal)) |
ed8dad6b | 208 | { |
6ed8eeff | 209 | struct terminal *t; |
ed8dad6b | 210 | |
6ed8eeff | 211 | for (t = terminal_list; t; t = t->next_terminal) |
ed8dad6b | 212 | { |
6ed8eeff | 213 | if (t->id == XINT (terminal)) |
ed8dad6b | 214 | { |
6ed8eeff | 215 | result = t; |
ed8dad6b KL |
216 | break; |
217 | } | |
218 | } | |
219 | } | |
6ed8eeff | 220 | else if (FRAMEP (terminal)) |
ed8dad6b | 221 | { |
6ed8eeff | 222 | result = FRAME_TERMINAL (XFRAME (terminal)); |
ed8dad6b KL |
223 | } |
224 | ||
225 | if (result == NULL && throw) | |
6ed8eeff | 226 | wrong_type_argument (Qterminal_live_p, terminal); |
ed8dad6b KL |
227 | |
228 | return result; | |
229 | } | |
230 | ||
231 | \f | |
232 | ||
6ed8eeff | 233 | /* Create a new terminal object and add it to the terminal list. */ |
ed8dad6b | 234 | |
6ed8eeff KL |
235 | struct terminal * |
236 | create_terminal (void) | |
ed8dad6b | 237 | { |
6ed8eeff | 238 | struct terminal *terminal = (struct terminal *) xmalloc (sizeof (struct terminal)); |
ed8dad6b | 239 | |
6ed8eeff KL |
240 | bzero (terminal, sizeof (struct terminal)); |
241 | terminal->next_terminal = terminal_list; | |
242 | terminal_list = terminal; | |
ed8dad6b | 243 | |
6ed8eeff | 244 | terminal->id = next_terminal_id++; |
ed8dad6b | 245 | |
6ed8eeff | 246 | terminal->keyboard_coding = |
ed8dad6b | 247 | (struct coding_system *) xmalloc (sizeof (struct coding_system)); |
6ed8eeff | 248 | terminal->terminal_coding = |
ed8dad6b KL |
249 | (struct coding_system *) xmalloc (sizeof (struct coding_system)); |
250 | ||
6ed8eeff KL |
251 | setup_coding_system (Qnil, terminal->keyboard_coding); |
252 | setup_coding_system (Qnil, terminal->terminal_coding); | |
ed8dad6b | 253 | |
6ed8eeff KL |
254 | terminal->param_alist = Qnil; |
255 | return terminal; | |
ed8dad6b KL |
256 | } |
257 | ||
258 | /* Mark the Lisp pointers in the terminal objects. | |
259 | Called by the Fgarbage_collector. */ | |
260 | ||
261 | void | |
6ed8eeff | 262 | mark_terminals (void) |
ed8dad6b | 263 | { |
6ed8eeff KL |
264 | struct terminal *t; |
265 | for (t = terminal_list; t; t = t->next_terminal) | |
ed8dad6b | 266 | { |
6ed8eeff | 267 | mark_object (t->param_alist); |
ed8dad6b KL |
268 | } |
269 | } | |
270 | ||
271 | ||
6ed8eeff | 272 | /* Remove a terminal from the terminal list and free its memory. */ |
ed8dad6b KL |
273 | |
274 | void | |
6ed8eeff | 275 | delete_terminal (struct terminal *terminal) |
ed8dad6b | 276 | { |
6ed8eeff | 277 | struct terminal **tp; |
ed8dad6b KL |
278 | Lisp_Object tail, frame; |
279 | ||
280 | /* Check for and close live frames that are still on this | |
6ed8eeff | 281 | terminal. */ |
ed8dad6b KL |
282 | FOR_EACH_FRAME (tail, frame) |
283 | { | |
284 | struct frame *f = XFRAME (frame); | |
6ed8eeff | 285 | if (FRAME_LIVE_P (f) && f->terminal == terminal) |
ed8dad6b KL |
286 | { |
287 | Fdelete_frame (frame, Qt); | |
288 | } | |
289 | } | |
290 | ||
6ed8eeff KL |
291 | for (tp = &terminal_list; *tp != terminal; tp = &(*tp)->next_terminal) |
292 | if (! *tp) | |
ed8dad6b | 293 | abort (); |
6ed8eeff KL |
294 | *tp = terminal->next_terminal; |
295 | ||
296 | if (terminal->keyboard_coding) | |
297 | xfree (terminal->keyboard_coding); | |
298 | if (terminal->terminal_coding) | |
299 | xfree (terminal->terminal_coding); | |
300 | if (terminal->name) | |
301 | xfree (terminal->name); | |
ed8dad6b KL |
302 | |
303 | #ifdef MULTI_KBOARD | |
6ed8eeff KL |
304 | if (terminal->kboard && --terminal->kboard->reference_count == 0) |
305 | delete_kboard (terminal->kboard); | |
ed8dad6b KL |
306 | #endif |
307 | ||
6ed8eeff KL |
308 | bzero (terminal, sizeof (struct terminal)); |
309 | xfree (terminal); | |
ed8dad6b KL |
310 | } |
311 | ||
6ed8eeff KL |
312 | DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0, |
313 | doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal. | |
314 | TERMINAL may be a terminal id, a frame, or nil (meaning the selected | |
315 | frame's terminal). | |
ed8dad6b KL |
316 | |
317 | Normally, you may not delete a display if all other displays are suspended, | |
318 | but if the second argument FORCE is non-nil, you may do so. */) | |
6ed8eeff KL |
319 | (terminal, force) |
320 | Lisp_Object terminal, force; | |
ed8dad6b | 321 | { |
6ed8eeff | 322 | struct terminal *t, *p; |
ed8dad6b | 323 | |
6ed8eeff | 324 | t = get_terminal (terminal, 0); |
ed8dad6b | 325 | |
6ed8eeff | 326 | if (!t) |
ed8dad6b KL |
327 | return Qnil; |
328 | ||
6ed8eeff KL |
329 | p = terminal_list; |
330 | while (p && (p == t || !TERMINAL_ACTIVE_P (p))) | |
331 | p = p->next_terminal; | |
ed8dad6b KL |
332 | |
333 | if (NILP (force) && !p) | |
6ed8eeff | 334 | error ("Attempt to delete the sole active display terminal"); |
ed8dad6b | 335 | |
6ed8eeff KL |
336 | if (t->delete_terminal_hook) |
337 | (*t->delete_terminal_hook) (t); | |
ed8dad6b | 338 | else |
6ed8eeff | 339 | delete_terminal (t); |
ed8dad6b KL |
340 | |
341 | return Qnil; | |
342 | } | |
343 | ||
6ed8eeff KL |
344 | \f |
345 | DEFUN ("frame-terminal", Fframe_terminal, Sframe_terminal, 0, 1, 0, | |
346 | doc: /* Return the terminal that FRAME is displayed on. | |
347 | If FRAME is nil, the selected frame is used. | |
348 | ||
349 | The terminal device is represented by its integer identifier. */) | |
350 | (frame) | |
351 | Lisp_Object frame; | |
352 | { | |
353 | struct terminal *t; | |
354 | ||
355 | if (NILP (frame)) | |
356 | frame = selected_frame; | |
357 | ||
358 | CHECK_LIVE_FRAME (frame); | |
359 | ||
360 | t = get_terminal (frame, 0); | |
361 | ||
362 | if (!t) | |
363 | return Qnil; | |
364 | else | |
365 | return make_number (t->id); | |
366 | } | |
367 | ||
368 | DEFUN ("terminal-live-p", Fterminal_live_p, Sterminal_live_p, 1, 1, 0, | |
369 | doc: /* Return non-nil if OBJECT is a terminal which has not been deleted. | |
370 | Value is nil if OBJECT is not a live display terminal. | |
371 | If object is a live display terminal, the return value indicates what | |
372 | sort of output terminal it uses. See the documentation of `framep' for | |
ed8dad6b KL |
373 | possible return values. |
374 | ||
6ed8eeff | 375 | Display terminals are represented by their integer identifiers. */) |
ed8dad6b KL |
376 | (object) |
377 | Lisp_Object object; | |
378 | { | |
6ed8eeff | 379 | struct terminal *t; |
ed8dad6b KL |
380 | |
381 | if (!INTEGERP (object)) | |
382 | return Qnil; | |
383 | ||
6ed8eeff | 384 | t = get_terminal (object, 0); |
ed8dad6b | 385 | |
6ed8eeff | 386 | if (!t) |
ed8dad6b KL |
387 | return Qnil; |
388 | ||
6ed8eeff | 389 | switch (t->type) |
ed8dad6b KL |
390 | { |
391 | case output_initial: /* The initial frame is like a termcap frame. */ | |
392 | case output_termcap: | |
393 | return Qt; | |
394 | case output_x_window: | |
395 | return Qx; | |
396 | case output_w32: | |
397 | return Qw32; | |
398 | case output_msdos_raw: | |
399 | return Qpc; | |
400 | case output_mac: | |
401 | return Qmac; | |
402 | default: | |
403 | abort (); | |
404 | } | |
405 | } | |
406 | ||
6ed8eeff KL |
407 | DEFUN ("terminal-list", Fterminal_list, Sterminal_list, 0, 0, 0, |
408 | doc: /* Return a list of all terminal devices. | |
409 | Terminal devices are represented by their integer identifiers. */) | |
ed8dad6b KL |
410 | () |
411 | { | |
6ed8eeff KL |
412 | Lisp_Object terminals = Qnil; |
413 | struct terminal *t; | |
ed8dad6b | 414 | |
6ed8eeff KL |
415 | for (t = terminal_list; t; t = t->next_terminal) |
416 | terminals = Fcons (make_number (t->id), terminals); | |
ed8dad6b | 417 | |
6ed8eeff | 418 | return terminals; |
ed8dad6b KL |
419 | } |
420 | ||
6ed8eeff KL |
421 | DEFUN ("terminal-name", Fterminal_name, Sterminal_name, 0, 1, 0, |
422 | doc: /* Return the name of the terminal device TERMINAL. | |
ed8dad6b KL |
423 | It is not guaranteed that the returned value is unique among opened devices. |
424 | ||
6ed8eeff KL |
425 | TERMINAL may be a terminal id, a frame, or nil (meaning the |
426 | selected frame's terminal). */) | |
427 | (terminal) | |
428 | Lisp_Object terminal; | |
ed8dad6b | 429 | { |
6ed8eeff | 430 | struct terminal *t = get_terminal (terminal, 1); |
ed8dad6b | 431 | |
6ed8eeff KL |
432 | if (t->name) |
433 | return build_string (t->name); | |
ed8dad6b KL |
434 | else |
435 | return Qnil; | |
436 | } | |
437 | ||
438 | ||
439 | \f | |
6ed8eeff | 440 | /* Return the value of terminal parameter PARAM in terminal T. */ |
ed8dad6b | 441 | Lisp_Object |
6ed8eeff KL |
442 | get_terminal_param (t, param) |
443 | struct terminal *t; | |
ed8dad6b KL |
444 | Lisp_Object param; |
445 | { | |
6ed8eeff | 446 | Lisp_Object tem = Fassq (param, t->param_alist); |
ed8dad6b KL |
447 | if (EQ (tem, Qnil)) |
448 | return tem; | |
449 | return Fcdr (tem); | |
450 | } | |
451 | ||
6ed8eeff | 452 | /* Set the value of terminal parameter PARAMETER in terminal D to VALUE. |
ed8dad6b KL |
453 | Return the previous value. */ |
454 | ||
455 | Lisp_Object | |
6ed8eeff KL |
456 | store_terminal_param (t, parameter, value) |
457 | struct terminal *t; | |
ed8dad6b KL |
458 | Lisp_Object parameter; |
459 | Lisp_Object value; | |
460 | { | |
6ed8eeff | 461 | Lisp_Object old_alist_elt = Fassq (parameter, t->param_alist); |
ed8dad6b KL |
462 | if (EQ (old_alist_elt, Qnil)) |
463 | { | |
6ed8eeff | 464 | t->param_alist = Fcons (Fcons (parameter, value), t->param_alist); |
ed8dad6b KL |
465 | return Qnil; |
466 | } | |
467 | else | |
468 | { | |
469 | Lisp_Object result = Fcdr (old_alist_elt); | |
470 | Fsetcdr (old_alist_elt, value); | |
471 | return result; | |
472 | } | |
473 | } | |
474 | ||
475 | ||
476 | DEFUN ("terminal-parameters", Fterminal_parameters, Sterminal_parameters, 0, 1, 0, | |
477 | doc: /* Return the parameter-alist of terminal TERMINAL. | |
478 | The value is a list of elements of the form (PARM . VALUE), where PARM | |
479 | is a symbol. | |
480 | ||
6ed8eeff | 481 | TERMINAL can be a terminal id, a frame or nil (meaning the selected |
ed8dad6b KL |
482 | frame's terminal). */) |
483 | (terminal) | |
484 | Lisp_Object terminal; | |
485 | { | |
6ed8eeff KL |
486 | struct terminal *t = get_terminal (terminal, 1); |
487 | return Fcopy_alist (t->param_alist); | |
ed8dad6b KL |
488 | } |
489 | ||
490 | DEFUN ("terminal-parameter", Fterminal_parameter, Sterminal_parameter, 2, 2, 0, | |
491 | doc: /* Return TERMINAL's value for parameter PARAMETER. | |
6ed8eeff | 492 | TERMINAL can be a terminal id, a frame or nil (meaning the selected |
ed8dad6b KL |
493 | frame's terminal). */) |
494 | (terminal, parameter) | |
495 | Lisp_Object terminal; | |
496 | Lisp_Object parameter; | |
497 | { | |
498 | Lisp_Object value; | |
6ed8eeff | 499 | struct terminal *t = get_terminal (terminal, 1); |
ed8dad6b | 500 | CHECK_SYMBOL (parameter); |
6ed8eeff | 501 | value = Fcdr (Fassq (parameter, t->param_alist)); |
ed8dad6b KL |
502 | return value; |
503 | } | |
504 | ||
505 | DEFUN ("modify-terminal-parameters", Fmodify_terminal_parameters, | |
506 | Smodify_terminal_parameters, 2, 2, 0, | |
507 | doc: /* Modify the parameters of terminal TERMINAL according to ALIST. | |
508 | ALIST is an alist of parameters to change and their new values. | |
509 | Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol. | |
510 | ||
6ed8eeff | 511 | TERMINAL can be a terminal id, a frame or nil (meaning the selected |
ed8dad6b KL |
512 | frame's terminal). */) |
513 | (terminal, alist) | |
514 | Lisp_Object terminal; | |
515 | Lisp_Object alist; | |
516 | { | |
517 | Lisp_Object tail, prop, val; | |
6ed8eeff | 518 | struct terminal *t = get_terminal (terminal, 1); |
ed8dad6b KL |
519 | int length = XINT (Fsafe_length (alist)); |
520 | int i; | |
521 | Lisp_Object *parms = (Lisp_Object *) alloca (length * sizeof (Lisp_Object)); | |
522 | Lisp_Object *values = (Lisp_Object *) alloca (length * sizeof (Lisp_Object)); | |
523 | ||
524 | /* Extract parm names and values into those vectors. */ | |
525 | ||
526 | i = 0; | |
527 | for (tail = alist; CONSP (tail); tail = Fcdr (tail)) | |
528 | { | |
529 | Lisp_Object elt; | |
530 | ||
531 | elt = Fcar (tail); | |
532 | parms[i] = Fcar (elt); | |
533 | values[i] = Fcdr (elt); | |
534 | i++; | |
535 | } | |
536 | ||
537 | /* Now process them in reverse of specified order. */ | |
538 | for (i--; i >= 0; i--) | |
539 | { | |
540 | prop = parms[i]; | |
541 | val = values[i]; | |
6ed8eeff | 542 | store_terminal_param (t, prop, val); |
ed8dad6b KL |
543 | } |
544 | return Qnil; | |
545 | } | |
546 | ||
547 | DEFUN ("set-terminal-parameter", Fset_terminal_parameter, | |
548 | Sset_terminal_parameter, 3, 3, 0, | |
549 | doc: /* Set TERMINAL's value for parameter PARAMETER to VALUE. | |
550 | Return the previous value of PARAMETER. | |
551 | ||
6ed8eeff | 552 | TERMINAL can be a terminal id, a frame or nil (meaning the selected |
ed8dad6b KL |
553 | frame's terminal). */) |
554 | (terminal, parameter, value) | |
555 | Lisp_Object terminal; | |
556 | Lisp_Object parameter; | |
557 | Lisp_Object value; | |
558 | { | |
6ed8eeff KL |
559 | struct terminal *t = get_terminal (terminal, 1); |
560 | return store_terminal_param (t, parameter, value); | |
ed8dad6b KL |
561 | } |
562 | ||
563 | \f | |
564 | ||
6ed8eeff KL |
565 | /* Create the bootstrap display terminal for the initial frame. |
566 | Returns a terminal of type output_initial. */ | |
ed8dad6b | 567 | |
6ed8eeff KL |
568 | struct terminal * |
569 | init_initial_terminal (void) | |
ed8dad6b | 570 | { |
6ed8eeff | 571 | if (initialized || terminal_list || tty_list) |
ed8dad6b KL |
572 | abort (); |
573 | ||
6ed8eeff KL |
574 | initial_terminal = create_terminal (); |
575 | initial_terminal->type = output_initial; | |
576 | initial_terminal->name = xstrdup ("initial_terminal"); | |
577 | initial_terminal->kboard = initial_kboard; | |
ed8dad6b | 578 | |
6ed8eeff | 579 | initial_terminal->delete_terminal_hook = &delete_initial_terminal; |
ed8dad6b KL |
580 | /* All other hooks are NULL. */ |
581 | ||
6ed8eeff | 582 | return initial_terminal; |
ed8dad6b KL |
583 | } |
584 | ||
6ed8eeff KL |
585 | /* Deletes the bootstrap terminal device. |
586 | Called through delete_terminal_hook. */ | |
ed8dad6b | 587 | |
6ed8eeff KL |
588 | static void |
589 | delete_initial_terminal (struct terminal *terminal) | |
ed8dad6b | 590 | { |
6ed8eeff | 591 | if (terminal != initial_terminal) |
ed8dad6b KL |
592 | abort (); |
593 | ||
6ed8eeff KL |
594 | delete_terminal (terminal); |
595 | initial_terminal = NULL; | |
ed8dad6b KL |
596 | } |
597 | ||
598 | void | |
599 | syms_of_terminal () | |
600 | { | |
601 | ||
602 | DEFVAR_LISP ("ring-bell-function", &Vring_bell_function, | |
603 | doc: /* Non-nil means call this function to ring the bell. | |
604 | The function should accept no arguments. */); | |
605 | Vring_bell_function = Qnil; | |
606 | ||
6ed8eeff KL |
607 | defsubr (&Sdelete_terminal); |
608 | defsubr (&Sframe_terminal); | |
609 | defsubr (&Sterminal_live_p); | |
610 | defsubr (&Sterminal_list); | |
611 | defsubr (&Sterminal_name); | |
ed8dad6b KL |
612 | defsubr (&Sterminal_parameters); |
613 | defsubr (&Sterminal_parameter); | |
614 | defsubr (&Smodify_terminal_parameters); | |
615 | defsubr (&Sset_terminal_parameter); | |
616 | ||
617 | Fprovide (intern ("multi-tty"), Qnil); | |
618 | } | |
619 | ||
620 | /* arch-tag: e9af6f27-b483-47dc-bb1a-730c1c5cab03 | |
621 | (do not change this comment) */ |