summaryrefslogtreecommitdiff
path: root/src/terminal.c
diff options
context:
space:
mode:
authorKaroly Lorentey <lorentey@elte.hu>2005-12-25 20:06:58 +0000
committerKaroly Lorentey <lorentey@elte.hu>2005-12-25 20:06:58 +0000
commited8dad6b616204b4dd4e853801f41da6f4c3b0a7 (patch)
treed260111171143cc889b7c801b911a07cf05da67c /src/terminal.c
parent4beb2d71ea5cbd7f451b8958c3cd21b3cd4d6edc (diff)
downloademacs-ed8dad6b616204b4dd4e853801f41da6f4c3b0a7.tar.gz
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
Diffstat (limited to 'src/terminal.c')
-rw-r--r--src/terminal.c596
1 files changed, 596 insertions, 0 deletions
diff --git a/src/terminal.c b/src/terminal.c
new file mode 100644
index 00000000000..83879a43afa
--- /dev/null
+++ b/src/terminal.c
@@ -0,0 +1,596 @@
+/* Functions related to terminal devices.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Emacs.
+
+GNU Emacs is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+#include <config.h>
+
+#include "lisp.h"
+#include "frame.h"
+#include "termchar.h"
+#include "termhooks.h"
+#include "charset.h"
+#include "coding.h"
+#include "keyboard.h"
+
+/* Chain of all displays currently in use. */
+struct device *device_list;
+
+/* The first unallocated display id. */
+static int next_device_id;
+
+/* The initial display device, created by initial_term_init. */
+struct device *initial_device;
+
+/* Function to use to ring the bell. */
+Lisp_Object Vring_bell_function;
+
+void delete_initial_device P_ ((struct device *));
+
+
+
+void
+ring_bell (struct frame *f)
+{
+ if (!NILP (Vring_bell_function))
+ {
+ Lisp_Object function;
+
+ /* Temporarily set the global variable to nil
+ so that if we get an error, it stays nil
+ and we don't call it over and over.
+
+ We don't specbind it, because that would carefully
+ restore the bad value if there's an error
+ and make the loop of errors happen anyway. */
+
+ function = Vring_bell_function;
+ Vring_bell_function = Qnil;
+
+ call0 (function);
+
+ Vring_bell_function = function;
+ }
+ else if (FRAME_DEVICE (f)->ring_bell_hook)
+ (*FRAME_DEVICE (f)->ring_bell_hook) (f);
+}
+
+void
+update_begin (struct frame *f)
+{
+ if (FRAME_DEVICE (f)->update_begin_hook)
+ (*FRAME_DEVICE (f)->update_begin_hook) (f);
+}
+
+void
+update_end (struct frame *f)
+{
+ if (FRAME_DEVICE (f)->update_end_hook)
+ (*FRAME_DEVICE (f)->update_end_hook) (f);
+}
+
+/* Specify how many text lines, from the top of the window,
+ should be affected by insert-lines and delete-lines operations.
+ This, and those operations, are used only within an update
+ that is bounded by calls to update_begin and update_end. */
+
+void
+set_terminal_window (struct frame *f, int size)
+{
+ if (FRAME_DEVICE (f)->set_terminal_window_hook)
+ (*FRAME_DEVICE (f)->set_terminal_window_hook) (f, size);
+}
+
+/* Move cursor to row/column position VPOS/HPOS. HPOS/VPOS are
+ frame-relative coordinates. */
+
+void
+cursor_to (struct frame *f, int vpos, int hpos)
+{
+ if (FRAME_DEVICE (f)->cursor_to_hook)
+ (*FRAME_DEVICE (f)->cursor_to_hook) (f, vpos, hpos);
+}
+
+/* Similar but don't take any account of the wasted characters. */
+
+void
+raw_cursor_to (struct frame *f, int row, int col)
+{
+ if (FRAME_DEVICE (f)->raw_cursor_to_hook)
+ (*FRAME_DEVICE (f)->raw_cursor_to_hook) (f, row, col);
+}
+
+/* Erase operations */
+
+/* Clear from cursor to end of frame. */
+void
+clear_to_end (struct frame *f)
+{
+ if (FRAME_DEVICE (f)->clear_to_end_hook)
+ (*FRAME_DEVICE (f)->clear_to_end_hook) (f);
+}
+
+/* Clear entire frame */
+
+void
+clear_frame (struct frame *f)
+{
+ if (FRAME_DEVICE (f)->clear_frame_hook)
+ (*FRAME_DEVICE (f)->clear_frame_hook) (f);
+}
+
+/* Clear from cursor to end of line.
+ Assume that the line is already clear starting at column first_unused_hpos.
+
+ Note that the cursor may be moved, on terminals lacking a `ce' string. */
+
+void
+clear_end_of_line (struct frame *f, int first_unused_hpos)
+{
+ if (FRAME_DEVICE (f)->clear_end_of_line_hook)
+ (*FRAME_DEVICE (f)->clear_end_of_line_hook) (f, first_unused_hpos);
+}
+
+/* Output LEN glyphs starting at STRING at the nominal cursor position.
+ Advance the nominal cursor over the text. */
+
+void
+write_glyphs (struct frame *f, struct glyph *string, int len)
+{
+ if (FRAME_DEVICE (f)->write_glyphs_hook)
+ (*FRAME_DEVICE (f)->write_glyphs_hook) (f, string, len);
+}
+
+/* Insert LEN glyphs from START at the nominal cursor position.
+
+ If start is zero, insert blanks instead of a string at start */
+
+void
+insert_glyphs (struct frame *f, struct glyph *start, int len)
+{
+ if (len <= 0)
+ return;
+
+ if (FRAME_DEVICE (f)->insert_glyphs_hook)
+ (*FRAME_DEVICE (f)->insert_glyphs_hook) (f, start, len);
+}
+
+/* Delete N glyphs at the nominal cursor position. */
+
+void
+delete_glyphs (struct frame *f, int n)
+{
+ if (FRAME_DEVICE (f)->delete_glyphs_hook)
+ (*FRAME_DEVICE (f)->delete_glyphs_hook) (f, n);
+}
+
+/* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */
+
+void
+ins_del_lines (struct frame *f, int vpos, int n)
+{
+ if (FRAME_DEVICE (f)->ins_del_lines_hook)
+ (*FRAME_DEVICE (f)->ins_del_lines_hook) (f, vpos, n);
+}
+
+
+
+
+/* Return the display object specified by DEVICE. DEVICE may be a
+ display id, a frame, or nil for the display device of the current
+ frame. If THROW is zero, return NULL for failure, otherwise throw
+ an error. */
+
+struct device *
+get_device (Lisp_Object device, int throw)
+{
+ struct device *result = NULL;
+
+ if (NILP (device))
+ device = selected_frame;
+
+ if (INTEGERP (device))
+ {
+ struct device *d;
+
+ for (d = device_list; d; d = d->next_device)
+ {
+ if (d->id == XINT (device))
+ {
+ result = d;
+ break;
+ }
+ }
+ }
+ else if (FRAMEP (device))
+ {
+ result = FRAME_DEVICE (XFRAME (device));
+ }
+
+ if (result == NULL && throw)
+ wrong_type_argument (Qdisplay_live_p, device);
+
+ return result;
+}
+
+
+
+/* Create a new device object and add it to the device list. */
+
+struct device *
+create_device (void)
+{
+ struct device *device = (struct device *) xmalloc (sizeof (struct device));
+
+ bzero (device, sizeof (struct device));
+ device->next_device = device_list;
+ device_list = device;
+
+ device->id = next_device_id++;
+
+ device->keyboard_coding =
+ (struct coding_system *) xmalloc (sizeof (struct coding_system));
+ device->terminal_coding =
+ (struct coding_system *) xmalloc (sizeof (struct coding_system));
+
+ setup_coding_system (Qnil, device->keyboard_coding);
+ setup_coding_system (Qnil, device->terminal_coding);
+
+ device->param_alist = Qnil;
+ return device;
+}
+
+/* Mark the Lisp pointers in the terminal objects.
+ Called by the Fgarbage_collector. */
+
+void
+mark_devices (void)
+{
+ struct device *d;
+ for (d = device_list; d; d = d->next_device)
+ {
+ mark_object (d->param_alist);
+ }
+}
+
+
+/* Remove a device from the device list and free its memory. */
+
+void
+delete_device (struct device *device)
+{
+ struct device **dp;
+ Lisp_Object tail, frame;
+
+ /* Check for and close live frames that are still on this
+ device. */
+ FOR_EACH_FRAME (tail, frame)
+ {
+ struct frame *f = XFRAME (frame);
+ if (FRAME_LIVE_P (f) && f->device == device)
+ {
+ Fdelete_frame (frame, Qt);
+ }
+ }
+
+ for (dp = &device_list; *dp != device; dp = &(*dp)->next_device)
+ if (! *dp)
+ abort ();
+ *dp = device->next_device;
+
+ if (device->keyboard_coding)
+ xfree (device->keyboard_coding);
+ if (device->terminal_coding)
+ xfree (device->terminal_coding);
+ if (device->name)
+ xfree (device->name);
+
+#ifdef MULTI_KBOARD
+ if (device->kboard && --device->kboard->reference_count == 0)
+ delete_kboard (device->kboard);
+#endif
+
+ bzero (device, sizeof (struct device));
+ xfree (device);
+}
+
+DEFUN ("delete-display", Fdelete_display, Sdelete_display, 0, 2, 0,
+ doc: /* Delete DEVICE by deleting all frames on it and closing the device.
+DEVICE may be a display device id, a frame, or nil (meaning the
+selected frame's display device).
+
+Normally, you may not delete a display if all other displays are suspended,
+but if the second argument FORCE is non-nil, you may do so. */)
+ (device, force)
+ Lisp_Object device, force;
+{
+ struct device *d, *p;
+
+ d = get_device (device, 0);
+
+ if (!d)
+ return Qnil;
+
+ p = device_list;
+ while (p && (p == d || !DEVICE_ACTIVE_P (p)))
+ p = p->next_device;
+
+ if (NILP (force) && !p)
+ error ("Attempt to delete the sole active display device");
+
+ if (d->delete_device_hook)
+ (*d->delete_device_hook) (d);
+ else
+ delete_device (d);
+
+ return Qnil;
+}
+
+DEFUN ("display-live-p", Fdisplay_live_p, Sdisplay_live_p, 1, 1, 0,
+ doc: /* Return non-nil if OBJECT is a device which has not been deleted.
+Value is nil if OBJECT is not a live display device.
+If object is a live display device, the return value indicates what
+sort of output device it uses. See the documentation of `framep' for
+possible return values.
+
+Display devices are represented by their integer identifiers. */)
+ (object)
+ Lisp_Object object;
+{
+ struct device *d;
+
+ if (!INTEGERP (object))
+ return Qnil;
+
+ d = get_device (object, 0);
+
+ if (!d)
+ return Qnil;
+
+ switch (d->type)
+ {
+ case output_initial: /* The initial frame is like a termcap frame. */
+ case output_termcap:
+ return Qt;
+ case output_x_window:
+ return Qx;
+ case output_w32:
+ return Qw32;
+ case output_msdos_raw:
+ return Qpc;
+ case output_mac:
+ return Qmac;
+ default:
+ abort ();
+ }
+}
+
+DEFUN ("display-list", Fdisplay_list, Sdisplay_list, 0, 0, 0,
+ doc: /* Return a list of all display devices.
+Display devices are represented by their integer identifiers. */)
+ ()
+{
+ Lisp_Object devices = Qnil;
+ struct device *d;
+
+ for (d = device_list; d; d = d->next_device)
+ devices = Fcons (make_number (d->id), devices);
+
+ return devices;
+}
+
+DEFUN ("display-name", Fdisplay_name, Sdisplay_name, 0, 1, 0,
+ doc: /* Return the name of the display device DEVICE.
+It is not guaranteed that the returned value is unique among opened devices.
+
+DEVICE may be a display device id, a frame, or nil (meaning the
+selected frame's display device). */)
+ (device)
+ Lisp_Object device;
+{
+ struct device *d = get_device (device, 1);
+
+ if (d->name)
+ return build_string (d->name);
+ else
+ return Qnil;
+}
+
+
+
+/* Return the value of terminal parameter PARAM in device D. */
+Lisp_Object
+get_terminal_param (d, param)
+ struct device *d;
+ Lisp_Object param;
+{
+ Lisp_Object tem = Fassq (param, d->param_alist);
+ if (EQ (tem, Qnil))
+ return tem;
+ return Fcdr (tem);
+}
+
+/* Set the value of terminal parameter PARAMETER in device D to VALUE.
+ Return the previous value. */
+
+Lisp_Object
+store_terminal_param (d, parameter, value)
+ struct device *d;
+ Lisp_Object parameter;
+ Lisp_Object value;
+{
+ Lisp_Object old_alist_elt = Fassq (parameter, d->param_alist);
+ if (EQ (old_alist_elt, Qnil))
+ {
+ d->param_alist = Fcons (Fcons (parameter, value), d->param_alist);
+ return Qnil;
+ }
+ else
+ {
+ Lisp_Object result = Fcdr (old_alist_elt);
+ Fsetcdr (old_alist_elt, value);
+ return result;
+ }
+}
+
+
+DEFUN ("terminal-parameters", Fterminal_parameters, Sterminal_parameters, 0, 1, 0,
+ doc: /* Return the parameter-alist of terminal TERMINAL.
+The value is a list of elements of the form (PARM . VALUE), where PARM
+is a symbol.
+
+TERMINAL can be a terminal if, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal)
+ Lisp_Object terminal;
+{
+ struct device *d = get_device (terminal, 1);
+ return Fcopy_alist (d->param_alist);
+}
+
+DEFUN ("terminal-parameter", Fterminal_parameter, Sterminal_parameter, 2, 2, 0,
+ doc: /* Return TERMINAL's value for parameter PARAMETER.
+TERMINAL can be a terminal if, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal, parameter)
+ Lisp_Object terminal;
+ Lisp_Object parameter;
+{
+ Lisp_Object value;
+ struct device *d = get_device (terminal, 1);
+ CHECK_SYMBOL (parameter);
+ value = Fcdr (Fassq (parameter, d->param_alist));
+ return value;
+}
+
+DEFUN ("modify-terminal-parameters", Fmodify_terminal_parameters,
+ Smodify_terminal_parameters, 2, 2, 0,
+ doc: /* Modify the parameters of terminal TERMINAL according to ALIST.
+ALIST is an alist of parameters to change and their new values.
+Each element of ALIST has the form (PARM . VALUE), where PARM is a symbol.
+
+TERMINAL can be a terminal if, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal, alist)
+ Lisp_Object terminal;
+ Lisp_Object alist;
+{
+ Lisp_Object tail, prop, val;
+ struct device *d = get_device (terminal, 1);
+ int length = XINT (Fsafe_length (alist));
+ int i;
+ Lisp_Object *parms = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
+ Lisp_Object *values = (Lisp_Object *) alloca (length * sizeof (Lisp_Object));
+
+ /* Extract parm names and values into those vectors. */
+
+ i = 0;
+ for (tail = alist; CONSP (tail); tail = Fcdr (tail))
+ {
+ Lisp_Object elt;
+
+ elt = Fcar (tail);
+ parms[i] = Fcar (elt);
+ values[i] = Fcdr (elt);
+ i++;
+ }
+
+ /* Now process them in reverse of specified order. */
+ for (i--; i >= 0; i--)
+ {
+ prop = parms[i];
+ val = values[i];
+ store_terminal_param (d, prop, val);
+ }
+ return Qnil;
+}
+
+DEFUN ("set-terminal-parameter", Fset_terminal_parameter,
+ Sset_terminal_parameter, 3, 3, 0,
+ doc: /* Set TERMINAL's value for parameter PARAMETER to VALUE.
+Return the previous value of PARAMETER.
+
+TERMINAL can be a terminal if, a frame or nil (meaning the selected
+frame's terminal). */)
+ (terminal, parameter, value)
+ Lisp_Object terminal;
+ Lisp_Object parameter;
+ Lisp_Object value;
+{
+ struct device *d = get_device (terminal, 1);
+ return store_terminal_param (d, parameter, value);
+}
+
+
+
+/* Create the bootstrap display device for the initial frame.
+ Returns a device of type output_initial. */
+
+struct device *
+init_initial_device (void)
+{
+ if (initialized || device_list || tty_list)
+ abort ();
+
+ initial_device = create_device ();
+ initial_device->type = output_initial;
+ initial_device->name = xstrdup ("initial_device");
+ initial_device->kboard = initial_kboard;
+
+ initial_device->delete_device_hook = &delete_initial_device;
+ /* All other hooks are NULL. */
+
+ return initial_device;
+}
+
+/* Deletes the bootstrap display device.
+ Called through delete_device_hook. */
+
+void
+delete_initial_device (struct device *device)
+{
+ if (device != initial_device)
+ abort ();
+
+ delete_device (device);
+ initial_device = NULL;
+}
+
+void
+syms_of_terminal ()
+{
+
+ DEFVAR_LISP ("ring-bell-function", &Vring_bell_function,
+ doc: /* Non-nil means call this function to ring the bell.
+The function should accept no arguments. */);
+ Vring_bell_function = Qnil;
+
+ defsubr (&Sdelete_display);
+ defsubr (&Sdisplay_live_p);
+ defsubr (&Sdisplay_list);
+ defsubr (&Sdisplay_name);
+ defsubr (&Sterminal_parameters);
+ defsubr (&Sterminal_parameter);
+ defsubr (&Smodify_terminal_parameters);
+ defsubr (&Sset_terminal_parameter);
+
+ Fprovide (intern ("multi-tty"), Qnil);
+}
+
+/* arch-tag: e9af6f27-b483-47dc-bb1a-730c1c5cab03
+ (do not change this comment) */