emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to src/terminal.c


From: Miles Bader
Subject: [Emacs-diffs] Changes to src/terminal.c
Date: Wed, 29 Aug 2007 05:28:51 +0000

CVSROOT:        /cvsroot/emacs
Module name:    emacs
Changes by:     Miles Bader <miles>     07/08/29 05:28:10

Index: src/terminal.c
===================================================================
RCS file: src/terminal.c
diff -N src/terminal.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ src/terminal.c      29 Aug 2007 05:27:54 -0000      1.2
@@ -0,0 +1,629 @@
+/* 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 <stdio.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 terminals currently in use. */
+struct terminal *terminal_list;
+
+/* The first unallocated terminal id. */
+static int next_terminal_id;
+
+/* The initial terminal device, created by initial_term_init. */
+struct terminal *initial_terminal;
+
+/* Function to use to ring the bell.  */
+Lisp_Object Vring_bell_function;
+
+static void delete_initial_terminal P_ ((struct terminal *));
+
+
+
+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_TERMINAL (f)->ring_bell_hook)
+    (*FRAME_TERMINAL (f)->ring_bell_hook) (f);
+}
+
+void
+update_begin (struct frame *f)
+{
+  if (FRAME_TERMINAL (f)->update_begin_hook)
+    (*FRAME_TERMINAL (f)->update_begin_hook) (f);
+}
+
+void
+update_end (struct frame *f)
+{
+  if (FRAME_TERMINAL (f)->update_end_hook)
+    (*FRAME_TERMINAL (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_TERMINAL (f)->set_terminal_window_hook)
+    (*FRAME_TERMINAL (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_TERMINAL (f)->cursor_to_hook)
+    (*FRAME_TERMINAL (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_TERMINAL (f)->raw_cursor_to_hook)
+    (*FRAME_TERMINAL (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_TERMINAL (f)->clear_to_end_hook)
+    (*FRAME_TERMINAL (f)->clear_to_end_hook) (f);
+}
+
+/* Clear entire frame */
+
+void
+clear_frame (struct frame *f)
+{
+  if (FRAME_TERMINAL (f)->clear_frame_hook)
+    (*FRAME_TERMINAL (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_TERMINAL (f)->clear_end_of_line_hook)
+    (*FRAME_TERMINAL (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_TERMINAL (f)->write_glyphs_hook)
+    (*FRAME_TERMINAL (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_TERMINAL (f)->insert_glyphs_hook)
+    (*FRAME_TERMINAL (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_TERMINAL (f)->delete_glyphs_hook)
+    (*FRAME_TERMINAL (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_TERMINAL (f)->ins_del_lines_hook)
+    (*FRAME_TERMINAL (f)->ins_del_lines_hook) (f, vpos, n);
+}
+
+
+
+
+/* Return the terminal object specified by TERMINAL.  TERMINAL may be a
+   terminal id, a frame, or nil for the terminal device of the current
+   frame.  If THROW is zero, return NULL for failure, otherwise throw
+   an error.  */
+
+struct terminal *
+get_terminal (Lisp_Object terminal, int throw)
+{
+  struct terminal *result = NULL;
+
+  if (NILP (terminal))
+    terminal = selected_frame;
+
+  if (INTEGERP (terminal))
+    {
+      struct terminal *t;
+
+      for (t = terminal_list; t; t = t->next_terminal)
+        {
+          if (t->id == XINT (terminal))
+            {
+              result = t;
+              break;
+            }
+        }
+    }
+  else if (FRAMEP (terminal))
+    {
+      result = FRAME_TERMINAL (XFRAME (terminal));
+    }
+
+  if (result == NULL && throw)
+    wrong_type_argument (Qterminal_live_p, terminal);
+
+  return result;
+}
+
+
+
+/* Create a new terminal object and add it to the terminal list. */
+
+struct terminal *
+create_terminal (void)
+{
+  struct terminal *terminal = (struct terminal *) xmalloc (sizeof (struct 
terminal));
+  
+  bzero (terminal, sizeof (struct terminal));
+  terminal->next_terminal = terminal_list;
+  terminal_list = terminal;
+
+  terminal->id = next_terminal_id++;
+
+  terminal->keyboard_coding =
+    (struct coding_system *) xmalloc (sizeof (struct coding_system));
+  terminal->terminal_coding =
+    (struct coding_system *) xmalloc (sizeof (struct coding_system));
+
+  setup_coding_system (Qnil, terminal->keyboard_coding);
+  setup_coding_system (Qnil, terminal->terminal_coding);
+
+  terminal->param_alist = Qnil;
+  return terminal;
+}
+
+/* Mark the Lisp pointers in the terminal objects.
+   Called by the Fgarbage_collector.  */
+
+void
+mark_terminals (void)
+{
+  struct terminal *t;
+  for (t = terminal_list; t; t = t->next_terminal)
+    {
+      mark_object (t->param_alist);
+    }
+}
+
+
+/* Low-level function to close all frames on a terminal, remove it
+   from the terminal list and free its memory.  */
+
+void
+delete_terminal (struct terminal *terminal)
+{
+  struct terminal **tp;
+  Lisp_Object tail, frame;
+
+  /* Protect against recursive calls.  Fdelete_frame calls the
+     delete_terminal_hook when we delete our last frame.  */
+  if (terminal->deleted)
+    return;
+  terminal->deleted = 1;
+
+  /* Check for live frames that are still on this terminal. */
+  FOR_EACH_FRAME (tail, frame)
+    {
+      struct frame *f = XFRAME (frame);
+      if (FRAME_LIVE_P (f) && f->terminal == terminal)
+        {
+          Fdelete_frame (frame, Qt);
+        }
+    }
+
+  for (tp = &terminal_list; *tp != terminal; tp = &(*tp)->next_terminal)
+    if (! *tp)
+      abort ();
+  *tp = terminal->next_terminal;
+
+  if (terminal->keyboard_coding)
+    xfree (terminal->keyboard_coding);
+  if (terminal->terminal_coding)
+    xfree (terminal->terminal_coding);
+  if (terminal->name)
+    xfree (terminal->name);
+  
+#ifdef MULTI_KBOARD
+  if (terminal->kboard && --terminal->kboard->reference_count == 0)
+    delete_kboard (terminal->kboard);
+#endif
+  
+  bzero (terminal, sizeof (struct terminal));
+  xfree (terminal);
+}
+
+DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0,
+       doc: /* Delete TERMINAL by deleting all frames on it and closing the 
terminal.
+TERMINAL may be a terminal id, a frame, or nil (meaning the selected
+frame's terminal).
+
+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. */)
+  (terminal, force)
+     Lisp_Object terminal, force;
+{
+  struct terminal *t, *p;
+
+  t = get_terminal (terminal, 0);
+
+  if (!t)
+    return Qnil;
+
+  p = terminal_list;
+  while (p && (p == t || !TERMINAL_ACTIVE_P (p)))
+    p = p->next_terminal;
+  
+  if (NILP (force) && !p)
+    error ("Attempt to delete the sole active display terminal");
+
+  if (t->delete_terminal_hook)
+    (*t->delete_terminal_hook) (t);
+  else
+    delete_terminal (t);
+
+  return Qnil;
+}
+
+
+DEFUN ("frame-terminal", Fframe_terminal, Sframe_terminal, 0, 1, 0,
+       doc: /* Return the terminal that FRAME is displayed on.
+If FRAME is nil, the selected frame is used.
+
+The terminal device is represented by its integer identifier.  */)
+  (frame)
+     Lisp_Object frame;
+{
+  struct terminal *t;
+
+  if (NILP (frame))
+    frame = selected_frame;
+
+  CHECK_LIVE_FRAME (frame);
+
+  t = get_terminal (frame, 0);
+
+  if (!t)
+    return Qnil;
+  else
+    return make_number (t->id);
+}
+
+DEFUN ("terminal-live-p", Fterminal_live_p, Sterminal_live_p, 1, 1, 0,
+       doc: /* Return non-nil if OBJECT is a terminal which has not been 
deleted.
+Value is nil if OBJECT is not a live display terminal.
+If object is a live display terminal, the return value indicates what
+sort of output terminal it uses.  See the documentation of `framep' for
+possible return values.
+
+Display terminals are represented by their integer identifiers. */)
+     (object)
+     Lisp_Object object;
+{
+  struct terminal *t;
+  
+  if (!INTEGERP (object))
+    return Qnil;
+
+  t = get_terminal (object, 0);
+
+  if (!t)
+    return Qnil;
+
+  switch (t->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 ("terminal-list", Fterminal_list, Sterminal_list, 0, 0, 0,
+       doc: /* Return a list of all terminal devices.
+Terminal devices are represented by their integer identifiers. */)
+  ()
+{
+  Lisp_Object terminals = Qnil;
+  struct terminal *t;
+
+  for (t = terminal_list; t; t = t->next_terminal)
+    terminals = Fcons (make_number (t->id), terminals);
+
+  return terminals;
+}
+
+DEFUN ("terminal-name", Fterminal_name, Sterminal_name, 0, 1, 0,
+       doc: /* Return the name of the terminal device TERMINAL.
+It is not guaranteed that the returned value is unique among opened devices.
+
+TERMINAL may be a terminal id, a frame, or nil (meaning the
+selected frame's terminal). */)
+  (terminal)
+     Lisp_Object terminal;
+{
+  struct terminal *t = get_terminal (terminal, 1);
+
+  if (t->name)
+    return build_string (t->name);
+  else
+    return Qnil;
+}
+
+
+
+/* Return the value of terminal parameter PARAM in terminal T.  */
+Lisp_Object
+get_terminal_param (t, param)
+     struct terminal *t;
+     Lisp_Object param;
+{
+  Lisp_Object tem = Fassq (param, t->param_alist);
+  if (EQ (tem, Qnil))
+    return tem;
+  return Fcdr (tem);
+}
+
+/* Set the value of terminal parameter PARAMETER in terminal D to VALUE.
+   Return the previous value.  */
+
+Lisp_Object
+store_terminal_param (t, parameter, value)
+     struct terminal *t;
+     Lisp_Object parameter;
+     Lisp_Object value;
+{
+  Lisp_Object old_alist_elt = Fassq (parameter, t->param_alist);
+  if (EQ (old_alist_elt, Qnil))
+    {
+      t->param_alist = Fcons (Fcons (parameter, value), t->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 id, a frame or nil (meaning the selected
+frame's terminal).  */)
+     (terminal)
+     Lisp_Object terminal;
+{
+  struct terminal *t = get_terminal (terminal, 1);
+  return Fcopy_alist (t->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 id, a frame or nil (meaning the selected
+frame's terminal).  */)
+     (terminal, parameter)
+     Lisp_Object terminal;
+     Lisp_Object parameter;
+{
+  Lisp_Object value;
+  struct terminal *t = get_terminal (terminal, 1);
+  CHECK_SYMBOL (parameter);
+  value = Fcdr (Fassq (parameter, t->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 id, a frame or nil (meaning the selected
+frame's terminal).  */)
+     (terminal, alist)
+     Lisp_Object terminal;
+     Lisp_Object alist;
+{
+  Lisp_Object tail, prop, val;
+  struct terminal *t = get_terminal (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 (t, 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 id, a frame or nil (meaning the selected
+frame's terminal).  */)
+     (terminal, parameter, value)
+     Lisp_Object terminal;
+     Lisp_Object parameter;
+     Lisp_Object value;
+{
+  struct terminal *t = get_terminal (terminal, 1);
+  return store_terminal_param (t, parameter, value);
+}
+
+
+
+/* Create the bootstrap display terminal for the initial frame.
+   Returns a terminal of type output_initial.  */
+
+struct terminal *
+init_initial_terminal (void)
+{
+  if (initialized || terminal_list || tty_list)
+    abort ();
+
+  initial_terminal = create_terminal ();
+  initial_terminal->type = output_initial;
+  initial_terminal->name = xstrdup ("initial_terminal");
+#ifdef MULTI_KBOARD
+  initial_terminal->kboard = initial_kboard;
+#endif
+  initial_terminal->delete_terminal_hook = &delete_initial_terminal;
+  /* All other hooks are NULL. */
+
+  return initial_terminal;
+}
+
+/* Deletes the bootstrap terminal device.
+   Called through delete_terminal_hook. */
+
+static void
+delete_initial_terminal (struct terminal *terminal)
+{
+  if (terminal != initial_terminal)
+    abort ();
+
+  delete_terminal (terminal);
+  initial_terminal = 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_terminal);
+  defsubr (&Sframe_terminal);
+  defsubr (&Sterminal_live_p);
+  defsubr (&Sterminal_list);
+  defsubr (&Sterminal_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) */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]