comparison src/terminal.c @ 83420:521d3f18b3d1

Reimplement terminal parameters in C; clean up term.c, create terminal.c. * lisp/termdev.el (terminal-parameter-alist, terminal-parameters, terminal-parameter-p) (terminal-parameter, set-terminal-parameter, terminal-handle-delete-frame): Remove. * src/term.c (Vring_bell_function, device_list, initial_device) (next_device_id, ring_bell, update_begin, update_end) (set_terminal_window, cursor_to, raw_cursor_to) (clear_to_end, clear_frame, clear_end_of_line) (write_glyphs, insert_glyphs, delete_glyphs, ins_del_lines) (get_device, Fdisplay_name, create_device, delete_device) (Fdelete_display, Fdisplay_live_p, Fdisplay_list) Move to terminal.c. (syms_of_term): Move their initialization to terminal.c. * src/terminal.c: New file. (device_list, next_device_id, initial_device, Vring_bell_function) (ring_bell, update_begin, update_end, set_terminal_window) (cursor_to, raw_cursor_to, clear_to_end, clear_frame) (clear_end_of_line, write_glyphs, insert_glyphs, delete_glyphs) (ins_del_lines, get_device, create_device, delete_device) (Fdelete_display, Fdisplay_live_p, Fdisplay_list, Fdisplay_name): Move here. (mark_devices, get_terminal_param, store_terminal_param) (Fterminal_parameters, Fterminal_parameter) (Fmodify_terminal_parameters, Fset_terminal_parameter) (init_initial_device, delete_initial_device) (syms_of_terminal): New functions. * lisp/simple.el (normal-erase-is-backspace-setup-frame) (normal-erase-is-backspace-mode): Rephrase things without terminal-parameter-p. * lisp/termdev.el (terminal-getenv, terminal-setenv) (with-terminal-environment): Ditto. * mac/makefile.MPW (EmacsObjects): Add terminal.c.x. ({Src}terminal.c.x): Add dependencies. * src/Makefile.in (obj): Add terminal.o. (terminal.o): Add dependencies. [HAVE_CARBON]: Make terminal.o depend on macgui.h. * src/alloc.c (mark_devices): Declare. (Fgarbage_collect): Call `mark_devices'. * src/dispextern.h (set_scroll_region, turn_off_insert) (turn_off_highlight, background_highlight, clear_end_of_line_raw) (tty_clear_end_of_line, tty_setup_colors, delete_tty): Remove. (raw_cursor_to, clear_to_end, tty_turn_off_insert) (tty_turn_off_highlight): Add declaration. * src/emacs.c (main): Call `syms_of_terminal'. * src/frame.c (get_future_frame_param): New function. (Fmake_terminal_frame): Use it. * src/keyboard.c (pop_kboard): Remove unused variable. (Fset_output_flow_control): Return nil. * src/keymap.h (Fset_keymap_parent): Add EXFUN. * src/lisp.h (syms_of_terminal): Declare it. * src/sysdep.c (reset_sys_modes): Update for renames. * src/term.c (set_scroll_region): Rename to `tty_set_scroll_region'. (turn_on_insert): Rename to `tty_turn_on_insert'. (turn_off_insert): Rename to `tty_turn_off_insert'. (turn_off_highlight): Rename to `tty_turn_off_highlight'. (turn_on_highlight): Rename to `tty_turn_on_highlight'. (toggle_highligh): Rename to `tty_toggle_highlight'. (background_highlight): Rename to `tty_background_highlight'. (highlight_if_desired): Rename to `tty_highlight_if_desired'. (tty_ring_bell, tty_update_end, tty_set_terminal_window) (tty_set_scroll_region, tty_background_highlight) (tty_cursor_to, tty_raw_cursor_to, tty_clear_to_end) (tty_clear_frame, tty_clear_end_of_line, tty_write_glyphs) (tty_insert_glyphs, tty_delete_glyphs, tty_ins_del_lines) (term_get_fkeys, tty_setup_colors, dissociate_if_controlling_tty) (delete_tty): Add static modifier. (tty_reset_terminal_modes, tty_set_terminal_window) (tty_set_scroll_region, tty_background_highlight) (tty_highlight_if_desired, tty_cursor_to) (tty_raw_cursor_to, tty_clear_to_end, tty_clear_frame) (tty_clear_end_of_line, tty_write_glyphs, tty_insert_glyphs) (tty_delete_glyphs, tty_ins_del_lines, turn_on_face): Update for renames. * src/termhooks.h (param_alist): New member to struct device. * src/xterm.h (x_delete_device): Declare. git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-460
author Karoly Lorentey <lorentey@elte.hu>
date Sun, 25 Dec 2005 20:06:58 +0000
parents
children 76396de7f50a
comparison
equal deleted inserted replaced
83419:b658f9b67fc5 83420:521d3f18b3d1
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
31 /* Chain of all displays currently in use. */
32 struct device *device_list;
33
34 /* The first unallocated display id. */
35 static int next_device_id;
36
37 /* The initial display device, created by initial_term_init. */
38 struct device *initial_device;
39
40 /* Function to use to ring the bell. */
41 Lisp_Object Vring_bell_function;
42
43 void delete_initial_device P_ ((struct device *));
44
45
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 }
69 else if (FRAME_DEVICE (f)->ring_bell_hook)
70 (*FRAME_DEVICE (f)->ring_bell_hook) (f);
71 }
72
73 void
74 update_begin (struct frame *f)
75 {
76 if (FRAME_DEVICE (f)->update_begin_hook)
77 (*FRAME_DEVICE (f)->update_begin_hook) (f);
78 }
79
80 void
81 update_end (struct frame *f)
82 {
83 if (FRAME_DEVICE (f)->update_end_hook)
84 (*FRAME_DEVICE (f)->update_end_hook) (f);
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 {
95 if (FRAME_DEVICE (f)->set_terminal_window_hook)
96 (*FRAME_DEVICE (f)->set_terminal_window_hook) (f, size);
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 {
105 if (FRAME_DEVICE (f)->cursor_to_hook)
106 (*FRAME_DEVICE (f)->cursor_to_hook) (f, vpos, hpos);
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 {
114 if (FRAME_DEVICE (f)->raw_cursor_to_hook)
115 (*FRAME_DEVICE (f)->raw_cursor_to_hook) (f, row, col);
116 }
117
118 /* Erase operations */
119
120 /* Clear from cursor to end of frame. */
121 void
122 clear_to_end (struct frame *f)
123 {
124 if (FRAME_DEVICE (f)->clear_to_end_hook)
125 (*FRAME_DEVICE (f)->clear_to_end_hook) (f);
126 }
127
128 /* Clear entire frame */
129
130 void
131 clear_frame (struct frame *f)
132 {
133 if (FRAME_DEVICE (f)->clear_frame_hook)
134 (*FRAME_DEVICE (f)->clear_frame_hook) (f);
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 {
145 if (FRAME_DEVICE (f)->clear_end_of_line_hook)
146 (*FRAME_DEVICE (f)->clear_end_of_line_hook) (f, first_unused_hpos);
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 {
155 if (FRAME_DEVICE (f)->write_glyphs_hook)
156 (*FRAME_DEVICE (f)->write_glyphs_hook) (f, string, len);
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
169 if (FRAME_DEVICE (f)->insert_glyphs_hook)
170 (*FRAME_DEVICE (f)->insert_glyphs_hook) (f, start, len);
171 }
172
173 /* Delete N glyphs at the nominal cursor position. */
174
175 void
176 delete_glyphs (struct frame *f, int n)
177 {
178 if (FRAME_DEVICE (f)->delete_glyphs_hook)
179 (*FRAME_DEVICE (f)->delete_glyphs_hook) (f, n);
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 {
187 if (FRAME_DEVICE (f)->ins_del_lines_hook)
188 (*FRAME_DEVICE (f)->ins_del_lines_hook) (f, vpos, n);
189 }
190
191
192
193
194 /* Return the display object specified by DEVICE. DEVICE may be a
195 display id, a frame, or nil for the display device of the current
196 frame. If THROW is zero, return NULL for failure, otherwise throw
197 an error. */
198
199 struct device *
200 get_device (Lisp_Object device, int throw)
201 {
202 struct device *result = NULL;
203
204 if (NILP (device))
205 device = selected_frame;
206
207 if (INTEGERP (device))
208 {
209 struct device *d;
210
211 for (d = device_list; d; d = d->next_device)
212 {
213 if (d->id == XINT (device))
214 {
215 result = d;
216 break;
217 }
218 }
219 }
220 else if (FRAMEP (device))
221 {
222 result = FRAME_DEVICE (XFRAME (device));
223 }
224
225 if (result == NULL && throw)
226 wrong_type_argument (Qdisplay_live_p, device);
227
228 return result;
229 }
230
231
232
233 /* Create a new device object and add it to the device list. */
234
235 struct device *
236 create_device (void)
237 {
238 struct device *device = (struct device *) xmalloc (sizeof (struct device));
239
240 bzero (device, sizeof (struct device));
241 device->next_device = device_list;
242 device_list = device;
243
244 device->id = next_device_id++;
245
246 device->keyboard_coding =
247 (struct coding_system *) xmalloc (sizeof (struct coding_system));
248 device->terminal_coding =
249 (struct coding_system *) xmalloc (sizeof (struct coding_system));
250
251 setup_coding_system (Qnil, device->keyboard_coding);
252 setup_coding_system (Qnil, device->terminal_coding);
253
254 device->param_alist = Qnil;
255 return device;
256 }
257
258 /* Mark the Lisp pointers in the terminal objects.
259 Called by the Fgarbage_collector. */
260
261 void
262 mark_devices (void)
263 {
264 struct device *d;
265 for (d = device_list; d; d = d->next_device)
266 {
267 mark_object (d->param_alist);
268 }
269 }
270
271
272 /* Remove a device from the device list and free its memory. */
273
274 void
275 delete_device (struct device *device)
276 {
277 struct device **dp;
278 Lisp_Object tail, frame;
279
280 /* Check for and close live frames that are still on this
281 device. */
282 FOR_EACH_FRAME (tail, frame)
283 {
284 struct frame *f = XFRAME (frame);
285 if (FRAME_LIVE_P (f) && f->device == device)
286 {
287 Fdelete_frame (frame, Qt);
288 }
289 }
290
291 for (dp = &device_list; *dp != device; dp = &(*dp)->next_device)
292 if (! *dp)
293 abort ();
294 *dp = device->next_device;
295
296 if (device->keyboard_coding)
297 xfree (device->keyboard_coding);
298 if (device->terminal_coding)
299 xfree (device->terminal_coding);
300 if (device->name)
301 xfree (device->name);
302
303 #ifdef MULTI_KBOARD
304 if (device->kboard && --device->kboard->reference_count == 0)
305 delete_kboard (device->kboard);
306 #endif
307
308 bzero (device, sizeof (struct device));
309 xfree (device);
310 }
311
312 DEFUN ("delete-display", Fdelete_display, Sdelete_display, 0, 2, 0,
313 doc: /* Delete DEVICE by deleting all frames on it and closing the device.
314 DEVICE may be a display device id, a frame, or nil (meaning the
315 selected frame's display device).
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. */)
319 (device, force)
320 Lisp_Object device, force;
321 {
322 struct device *d, *p;
323
324 d = get_device (device, 0);
325
326 if (!d)
327 return Qnil;
328
329 p = device_list;
330 while (p && (p == d || !DEVICE_ACTIVE_P (p)))
331 p = p->next_device;
332
333 if (NILP (force) && !p)
334 error ("Attempt to delete the sole active display device");
335
336 if (d->delete_device_hook)
337 (*d->delete_device_hook) (d);
338 else
339 delete_device (d);
340
341 return Qnil;
342 }
343
344 DEFUN ("display-live-p", Fdisplay_live_p, Sdisplay_live_p, 1, 1, 0,
345 doc: /* Return non-nil if OBJECT is a device which has not been deleted.
346 Value is nil if OBJECT is not a live display device.
347 If object is a live display device, the return value indicates what
348 sort of output device it uses. See the documentation of `framep' for
349 possible return values.
350
351 Display devices are represented by their integer identifiers. */)
352 (object)
353 Lisp_Object object;
354 {
355 struct device *d;
356
357 if (!INTEGERP (object))
358 return Qnil;
359
360 d = get_device (object, 0);
361
362 if (!d)
363 return Qnil;
364
365 switch (d->type)
366 {
367 case output_initial: /* The initial frame is like a termcap frame. */
368 case output_termcap:
369 return Qt;
370 case output_x_window:
371 return Qx;
372 case output_w32:
373 return Qw32;
374 case output_msdos_raw:
375 return Qpc;
376 case output_mac:
377 return Qmac;
378 default:
379 abort ();
380 }
381 }
382
383 DEFUN ("display-list", Fdisplay_list, Sdisplay_list, 0, 0, 0,
384 doc: /* Return a list of all display devices.
385 Display devices are represented by their integer identifiers. */)
386 ()
387 {
388 Lisp_Object devices = Qnil;
389 struct device *d;
390
391 for (d = device_list; d; d = d->next_device)
392 devices = Fcons (make_number (d->id), devices);
393
394 return devices;
395 }
396
397 DEFUN ("display-name", Fdisplay_name, Sdisplay_name, 0, 1, 0,
398 doc: /* Return the name of the display device DEVICE.
399 It is not guaranteed that the returned value is unique among opened devices.
400
401 DEVICE may be a display device id, a frame, or nil (meaning the
402 selected frame's display device). */)
403 (device)
404 Lisp_Object device;
405 {
406 struct device *d = get_device (device, 1);
407
408 if (d->name)
409 return build_string (d->name);
410 else
411 return Qnil;
412 }
413
414
415
416 /* Return the value of terminal parameter PARAM in device D. */
417 Lisp_Object
418 get_terminal_param (d, param)
419 struct device *d;
420 Lisp_Object param;
421 {
422 Lisp_Object tem = Fassq (param, d->param_alist);
423 if (EQ (tem, Qnil))
424 return tem;
425 return Fcdr (tem);
426 }
427
428 /* Set the value of terminal parameter PARAMETER in device D to VALUE.
429 Return the previous value. */
430
431 Lisp_Object
432 store_terminal_param (d, parameter, value)
433 struct device *d;
434 Lisp_Object parameter;
435 Lisp_Object value;
436 {
437 Lisp_Object old_alist_elt = Fassq (parameter, d->param_alist);
438 if (EQ (old_alist_elt, Qnil))
439 {
440 d->param_alist = Fcons (Fcons (parameter, value), d->param_alist);
441 return Qnil;
442 }
443 else
444 {
445 Lisp_Object result = Fcdr (old_alist_elt);
446 Fsetcdr (old_alist_elt, value);
447 return result;
448 }
449 }
450
451
452 DEFUN ("terminal-parameters", Fterminal_parameters, Sterminal_parameters, 0, 1, 0,
453 doc: /* Return the parameter-alist of terminal TERMINAL.
454 The value is a list of elements of the form (PARM . VALUE), where PARM
455 is a symbol.
456
457 TERMINAL can be a terminal if, a frame or nil (meaning the selected
458 frame's terminal). */)
459 (terminal)
460 Lisp_Object terminal;
461 {
462 struct device *d = get_device (terminal, 1);
463 return Fcopy_alist (d->param_alist);
464 }
465
466 DEFUN ("terminal-parameter", Fterminal_parameter, Sterminal_parameter, 2, 2, 0,
467 doc: /* Return TERMINAL's value for parameter PARAMETER.
468 TERMINAL can be a terminal if, a frame or nil (meaning the selected
469 frame's terminal). */)
470 (terminal, parameter)
471 Lisp_Object terminal;
472 Lisp_Object parameter;
473 {
474 Lisp_Object value;
475 struct device *d = get_device (terminal, 1);
476 CHECK_SYMBOL (parameter);
477 value = Fcdr (Fassq (parameter, d->param_alist));
478 return value;
479 }
480
481 DEFUN ("modify-terminal-parameters", Fmodify_terminal_parameters,
482 Smodify_terminal_parameters, 2, 2, 0,
483 doc: /* Modify the parameters of terminal TERMINAL according to ALIST.
484 ALIST is an alist of parameters to change and their new values.
485 Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
486
487 TERMINAL can be a terminal if, a frame or nil (meaning the selected
488 frame's terminal). */)
489 (terminal, alist)
490 Lisp_Object terminal;
491 Lisp_Object alist;
492 {
493 Lisp_Object tail, prop, val;
494 struct device *d = get_device (terminal, 1);
495 int length = XINT (Fsafe_length (alist));
496 int i;
497 Lisp_Object *parms = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
498 Lisp_Object *values = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
499
500 /* Extract parm names and values into those vectors. */
501
502 i = 0;
503 for (tail = alist; CONSP (tail); tail = Fcdr (tail))
504 {
505 Lisp_Object elt;
506
507 elt = Fcar (tail);
508 parms[i] = Fcar (elt);
509 values[i] = Fcdr (elt);
510 i++;
511 }
512
513 /* Now process them in reverse of specified order. */
514 for (i--; i >= 0; i--)
515 {
516 prop = parms[i];
517 val = values[i];
518 store_terminal_param (d, prop, val);
519 }
520 return Qnil;
521 }
522
523 DEFUN ("set-terminal-parameter", Fset_terminal_parameter,
524 Sset_terminal_parameter, 3, 3, 0,
525 doc: /* Set TERMINAL's value for parameter PARAMETER to VALUE.
526 Return the previous value of PARAMETER.
527
528 TERMINAL can be a terminal if, a frame or nil (meaning the selected
529 frame's terminal). */)
530 (terminal, parameter, value)
531 Lisp_Object terminal;
532 Lisp_Object parameter;
533 Lisp_Object value;
534 {
535 struct device *d = get_device (terminal, 1);
536 return store_terminal_param (d, parameter, value);
537 }
538
539
540
541 /* Create the bootstrap display device for the initial frame.
542 Returns a device of type output_initial. */
543
544 struct device *
545 init_initial_device (void)
546 {
547 if (initialized || device_list || tty_list)
548 abort ();
549
550 initial_device = create_device ();
551 initial_device->type = output_initial;
552 initial_device->name = xstrdup ("initial_device");
553 initial_device->kboard = initial_kboard;
554
555 initial_device->delete_device_hook = &delete_initial_device;
556 /* All other hooks are NULL. */
557
558 return initial_device;
559 }
560
561 /* Deletes the bootstrap display device.
562 Called through delete_device_hook. */
563
564 void
565 delete_initial_device (struct device *device)
566 {
567 if (device != initial_device)
568 abort ();
569
570 delete_device (device);
571 initial_device = NULL;
572 }
573
574 void
575 syms_of_terminal ()
576 {
577
578 DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
579 doc: /* Non-nil means call this function to ring the bell.
580 The function should accept no arguments. */);
581 Vring_bell_function = Qnil;
582
583 defsubr (&Sdelete_display);
584 defsubr (&Sdisplay_live_p);
585 defsubr (&Sdisplay_list);
586 defsubr (&Sdisplay_name);
587 defsubr (&Sterminal_parameters);
588 defsubr (&Sterminal_parameter);
589 defsubr (&Smodify_terminal_parameters);
590 defsubr (&Sset_terminal_parameter);
591
592 Fprovide (intern ("multi-tty"), Qnil);
593 }
594
595 /* arch-tag: e9af6f27-b483-47dc-bb1a-730c1c5cab03
596 (do not change this comment) */