Rename `struct device' to `struct terminal'. Rename some terminal-related functions...
[bpt/emacs.git] / src / terminal.c
CommitLineData
ed8dad6b
KL
1/* Functions related to terminal devices.
2 Copyright (C) 2005 Free Software Foundation, Inc.
3
4This file is part of GNU Emacs.
5
6GNU Emacs is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Emacs is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Emacs; see the file COPYING. If not, write to
18the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19Boston, 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. */
32struct terminal *terminal_list;
ed8dad6b 33
6ed8eeff
KL
34/* The first unallocated terminal id. */
35static int next_terminal_id;
ed8dad6b 36
6ed8eeff
KL
37/* The initial terminal device, created by initial_term_init. */
38struct terminal *initial_terminal;
ed8dad6b
KL
39
40/* Function to use to ring the bell. */
41Lisp_Object Vring_bell_function;
42
6ed8eeff 43static void delete_initial_terminal P_ ((struct terminal *));
ed8dad6b
KL
44
45\f
46
47void
48ring_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
73void
74update_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
80void
81update_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
92void
93set_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
102void
103cursor_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
111void
112raw_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. */
121void
122clear_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
130void
131clear_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
142void
143clear_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
152void
153write_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
163void
164insert_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
175void
176delete_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
184void
185ins_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
199struct terminal *
200get_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
235struct terminal *
236create_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
261void
6ed8eeff 262mark_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
274void
6ed8eeff 275delete_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
312DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0,
313 doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal.
314TERMINAL may be a terminal id, a frame, or nil (meaning the selected
315frame's terminal).
ed8dad6b
KL
316
317Normally, you may not delete a display if all other displays are suspended,
318but 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
345DEFUN ("frame-terminal", Fframe_terminal, Sframe_terminal, 0, 1, 0,
346 doc: /* Return the terminal that FRAME is displayed on.
347If FRAME is nil, the selected frame is used.
348
349The 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
368DEFUN ("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.
370Value is nil if OBJECT is not a live display terminal.
371If object is a live display terminal, the return value indicates what
372sort of output terminal it uses. See the documentation of `framep' for
ed8dad6b
KL
373possible return values.
374
6ed8eeff 375Display 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
407DEFUN ("terminal-list", Fterminal_list, Sterminal_list, 0, 0, 0,
408 doc: /* Return a list of all terminal devices.
409Terminal 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
421DEFUN ("terminal-name", Fterminal_name, Sterminal_name, 0, 1, 0,
422 doc: /* Return the name of the terminal device TERMINAL.
ed8dad6b
KL
423It is not guaranteed that the returned value is unique among opened devices.
424
6ed8eeff
KL
425TERMINAL may be a terminal id, a frame, or nil (meaning the
426selected 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 441Lisp_Object
6ed8eeff
KL
442get_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
455Lisp_Object
6ed8eeff
KL
456store_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
476DEFUN ("terminal-parameters", Fterminal_parameters, Sterminal_parameters, 0, 1, 0,
477 doc: /* Return the parameter-alist of terminal TERMINAL.
478The value is a list of elements of the form (PARM . VALUE), where PARM
479is a symbol.
480
6ed8eeff 481TERMINAL can be a terminal id, a frame or nil (meaning the selected
ed8dad6b
KL
482frame'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
490DEFUN ("terminal-parameter", Fterminal_parameter, Sterminal_parameter, 2, 2, 0,
491 doc: /* Return TERMINAL's value for parameter PARAMETER.
6ed8eeff 492TERMINAL can be a terminal id, a frame or nil (meaning the selected
ed8dad6b
KL
493frame'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
505DEFUN ("modify-terminal-parameters", Fmodify_terminal_parameters,
506 Smodify_terminal_parameters, 2, 2, 0,
507 doc: /* Modify the parameters of terminal TERMINAL according to ALIST.
508ALIST is an alist of parameters to change and their new values.
509Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
510
6ed8eeff 511TERMINAL can be a terminal id, a frame or nil (meaning the selected
ed8dad6b
KL
512frame'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
547DEFUN ("set-terminal-parameter", Fset_terminal_parameter,
548 Sset_terminal_parameter, 3, 3, 0,
549 doc: /* Set TERMINAL's value for parameter PARAMETER to VALUE.
550Return the previous value of PARAMETER.
551
6ed8eeff 552TERMINAL can be a terminal id, a frame or nil (meaning the selected
ed8dad6b
KL
553frame'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
568struct terminal *
569init_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
588static void
589delete_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
598void
599syms_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.
604The 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) */