]> code.delx.au - gnu-emacs/blobdiff - src/term.c
(archive-l-e): New optional argument `float' means generate a float value.
[gnu-emacs] / src / term.c
index c40197337d8634889ec38212724804a57f480b74..603305c8f1736e80ac9c54dcd4615f7f30921814 100644 (file)
@@ -1,6 +1,6 @@
 /* Terminal control module for terminals described by TERMCAP
-   Copyright (C) 1985, 86, 87, 93, 94, 95, 98, 2000, 2001, 2002
-   Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001,
+                 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -16,8 +16,8 @@ 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., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>.  */
 
@@ -87,6 +87,10 @@ extern Lisp_Object Qspace, QCalign_to, QCwidth;
 
 Lisp_Object Vring_bell_function;
 
+/* If true, use "vs", otherwise use "ve" to make the cursor visible.  */
+
+static int visible_cursor;
+
 /* Terminal characteristics that higher levels want to look at.
    These are all extern'd in termchar.h */
 
@@ -449,8 +453,18 @@ set_terminal_modes ()
 {
   if (FRAME_TERMCAP_P (XFRAME (selected_frame)))
     {
-      OUTPUT_IF (TS_termcap_modes);
-      OUTPUT_IF (TS_cursor_visible);
+      if (TS_termcap_modes)
+       OUTPUT (TS_termcap_modes);
+      else
+       {
+         /* Output enough newlines to scroll all the old screen contents
+            off the screen, so it won't be overwritten and lost.  */
+         int i;
+         for (i = 0; i < FRAME_LINES (XFRAME (selected_frame)); i++)
+           putchar ('\n');
+       }
+
+      OUTPUT_IF (visible_cursor ? TS_cursor_visible : TS_cursor_normal);
       OUTPUT_IF (TS_keypad_mode);
       losecursor ();
     }
@@ -605,7 +619,8 @@ tty_show_cursor ()
     {
       tty_cursor_hidden = 0;
       OUTPUT_IF (TS_cursor_normal);
-      OUTPUT_IF (TS_cursor_visible);
+      if (visible_cursor)
+       OUTPUT_IF (TS_cursor_visible);
     }
 }
 
@@ -806,7 +821,7 @@ encode_terminal_code (src, src_len, coding)
      int src_len;
      struct coding_system *coding;
 {
-  struct glyph *src_start = src, *src_end = src + src_len;
+  struct glyph *src_end = src + src_len;
   register GLYPH g;
   unsigned char *buf;
   int nchars, nbytes, required;
@@ -819,11 +834,11 @@ encode_terminal_code (src, src_len, coding)
   required = MAX_MULTIBYTE_LENGTH * src_len;
   if (encode_terminal_bufsize < required)
     {
-      encode_terminal_bufsize = required;
       if (encode_terminal_bufsize == 0)
        encode_terminal_buf = xmalloc (required);
       else
        encode_terminal_buf = xrealloc (encode_terminal_buf, required);
+      encode_terminal_bufsize = required;
     }
 
   buf = encode_terminal_buf;
@@ -869,7 +884,7 @@ encode_terminal_code (src, src_len, coding)
                  if (! STRING_MULTIBYTE (string))
                    string = string_to_multibyte (string);
                  nbytes = buf - encode_terminal_buf;
-                 if (nbytes + SBYTES (string) < encode_terminal_bufsize)
+                 if (encode_terminal_bufsize < nbytes + SBYTES (string))
                    {
                      encode_terminal_bufsize = nbytes + SBYTES (string);
                      encode_terminal_buf = xrealloc (encode_terminal_buf,
@@ -891,7 +906,7 @@ encode_terminal_code (src, src_len, coding)
   if (SYMBOLP (coding->pre_write_conversion)
       && ! NILP (Ffboundp (coding->pre_write_conversion)))
     {
-      run_pre_write_conversin_on_c_str (&encode_terminal_buf, 
+      run_pre_write_conversin_on_c_str (&encode_terminal_buf,
                                        &encode_terminal_bufsize,
                                        nchars, nbytes, coding);
       nchars = coding->produced_char;
@@ -1451,7 +1466,26 @@ static struct fkey_table keys[] =
   {"k6", "f6"},
   {"k7", "f7"},
   {"k8", "f8"},
-  {"k9", "f9"}
+  {"k9", "f9"},
+
+  {"&0", "S-cancel"},    /*shifted cancel key*/
+  {"&9", "S-begin"},     /*shifted begin key*/
+  {"*0", "S-find"},      /*shifted find key*/
+  {"*1", "S-execute"},   /*shifted execute? actually shifted command key*/
+  {"*4", "S-delete"},    /*shifted delete-character key*/
+  {"*7", "S-end"},       /*shifted end key*/
+  {"*8", "S-clearline"}, /*shifted clear-to end-of-line key*/
+  {"#1", "S-help"},      /*shifted help key*/
+  {"#2", "S-home"},      /*shifted home key*/
+  {"#3", "S-insert"},    /*shifted insert-character key*/
+  {"#4", "S-left"},      /*shifted left-arrow key*/
+  {"%d", "S-menu"},      /*shifted menu? actually shifted options key*/
+  {"%c", "S-next"},      /*shifted next key*/
+  {"%e", "S-prior"},     /*shifted previous key*/
+  {"%f", "S-print"},     /*shifted print key*/
+  {"%g", "S-redo"},      /*shifted redo key*/
+  {"%i", "S-right"},     /*shifted right-arrow key*/
+  {"!3", "S-undo"}       /*shifted undo key*/
   };
 
 static char **term_get_fkeys_arg;
@@ -1595,15 +1629,21 @@ term_get_fkeys_1 ()
                       Character Display Information
  ***********************************************************************/
 
+/* Avoid name clash with functions defined in xterm.c */
+#ifdef static
+#define append_glyph append_glyph_term
+#define produce_stretch_glyph produce_stretch_glyph_term
+#endif
+
 static void append_glyph P_ ((struct it *));
 static void produce_stretch_glyph P_ ((struct it *));
 
 
 /* Append glyphs to IT's glyph_row.  Called from produce_glyphs for
-   terminal frames if IT->glyph_row != NULL.  IT->c is the character
-   for which to produce glyphs; IT->face_id contains the character's
-   face.  Padding glyphs are appended if IT->c has a IT->pixel_width >
-   1.  */
+   terminal frames if IT->glyph_row != NULL.  IT->char_to_display is
+   the character for which to produce glyphs; IT->face_id contains the
+   character's face.  Padding glyphs are appended if IT->c has a
+   IT->pixel_width > 1.  */
 
 static void
 append_glyph (it)
@@ -1623,7 +1663,7 @@ append_glyph (it)
     {
       glyph->type = CHAR_GLYPH;
       glyph->pixel_width = 1;
-      glyph->u.ch = it->c;
+      glyph->u.ch = it->char_to_display;
       glyph->face_id = it->face_id;
       glyph->padding_p = i > 0;
       glyph->charpos = CHARPOS (it->position);
@@ -1674,6 +1714,9 @@ produce_glyphs (it)
   xassert (it->what == IT_CHARACTER
           || it->what == IT_COMPOSITION);
 
+  /* Maybe translate single-byte characters to multibyte.  */
+  it->char_to_display = it->c;
+
   if (it->c >= 040 && it->c < 0177)
     {
       it->pixel_width = it->nglyphs = 1;
@@ -1703,13 +1746,11 @@ produce_glyphs (it)
        {
          int n = nspaces;
 
-         it->c = ' ';
+         it->char_to_display = ' ';
          it->pixel_width = it->len = 1;
 
          while (n--)
            append_glyph (it);
-
-         it->c = '\t';
        }
 
       it->pixel_width = nspaces;
@@ -1717,14 +1758,30 @@ produce_glyphs (it)
     }
   else if (SINGLE_BYTE_CHAR_P (it->c))
     {
-      /* Coming here means that it->c is from display table, thus we
-        must send the code as is to the terminal.  Although there's
-        no way to know how many columns it occupies on a screen, it
-        is a good assumption that a single byte code has 1-column
-        width.  */
-      it->pixel_width = it->nglyphs = 1;
-      if (it->glyph_row)
-       append_glyph (it);
+      if (unibyte_display_via_language_environment
+         && (it->c >= 0240
+             || !NILP (Vnonascii_translation_table)))
+       {
+         int charset;
+
+         it->char_to_display = unibyte_char_to_multibyte (it->c);
+         charset = CHAR_CHARSET (it->char_to_display);
+         it->pixel_width = CHARSET_WIDTH (charset);
+         it->nglyphs = it->pixel_width;
+         if (it->glyph_row)
+           append_glyph (it);
+       }
+      else
+       {
+         /* Coming here means that it->c is from display table, thus we
+            must send the code as is to the terminal.  Although there's
+            no way to know how many columns it occupies on a screen, it
+            is a good assumption that a single byte code has 1-column
+            width.  */
+         it->pixel_width = it->nglyphs = 1;
+         if (it->glyph_row)
+           append_glyph (it);
+       }
     }
   else
     {
@@ -1789,7 +1846,7 @@ produce_stretch_glyph (it)
           && calc_pixel_width_or_height (&tem, it, prop, 0, 1, &align_to))
     {
       if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
-       align_to = (align_to < 0 
+       align_to = (align_to < 0
                    ? 0
                    : align_to - window_box_left_offset (it->w, TEXT_AREA));
       else if (align_to < 0)
@@ -1809,17 +1866,15 @@ produce_stretch_glyph (it)
       Lisp_Object o_object = it->object;
       Lisp_Object object = it->stack[it->sp - 1].string;
       int n = width;
-      int c = it->c;
 
       if (!STRINGP (object))
        object = it->w->buffer;
       it->object = object;
-      it->c = ' ';
+      it->char_to_display = ' ';
       it->pixel_width = it->len = 1;
       while (n--)
        append_glyph (it);
       it->object = o_object;
-      it->c = c;
     }
   it->pixel_width = width;
   it->nglyphs = width;
@@ -1838,6 +1893,7 @@ produce_special_glyphs (it, what)
      enum display_element_type what;
 {
   struct it temp_it;
+  GLYPH glyph;
 
   temp_it = *it;
   temp_it.dp = NULL;
@@ -1853,15 +1909,11 @@ produce_special_glyphs (it, what)
          && INTEGERP (DISP_CONTINUE_GLYPH (it->dp))
          && GLYPH_CHAR_VALID_P (XINT (DISP_CONTINUE_GLYPH (it->dp))))
        {
-         temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_CONTINUE_GLYPH (it->dp)));
-         temp_it.len = CHAR_BYTES (temp_it.c);
+         glyph = XINT (DISP_CONTINUE_GLYPH (it->dp));
+         glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph);
        }
       else
-       temp_it.c = '\\';
-
-      produce_glyphs (&temp_it);
-      it->pixel_width = temp_it.pixel_width;
-      it->nglyphs = temp_it.pixel_width;
+       glyph = '\\';
     }
   else if (what == IT_TRUNCATION)
     {
@@ -1870,18 +1922,22 @@ produce_special_glyphs (it, what)
          && INTEGERP (DISP_TRUNC_GLYPH (it->dp))
          && GLYPH_CHAR_VALID_P (XINT (DISP_TRUNC_GLYPH (it->dp))))
        {
-         temp_it.c = FAST_GLYPH_CHAR (XINT (DISP_TRUNC_GLYPH (it->dp)));
-         temp_it.len = CHAR_BYTES (temp_it.c);
+         glyph = XINT (DISP_TRUNC_GLYPH (it->dp));
+         glyph = spec_glyph_lookup_face (XWINDOW (it->window), glyph);
        }
       else
-       temp_it.c = '$';
-
-      produce_glyphs (&temp_it);
-      it->pixel_width = temp_it.pixel_width;
-      it->nglyphs = temp_it.pixel_width;
+       glyph = '$';
     }
   else
     abort ();
+
+  temp_it.c = FAST_GLYPH_CHAR (glyph);
+  temp_it.face_id = FAST_GLYPH_FACE (glyph);
+  temp_it.len = CHAR_BYTES (temp_it.c);
+
+  produce_glyphs (&temp_it);
+  it->pixel_width = temp_it.pixel_width;
+  it->nglyphs = temp_it.pixel_width;
 }
 
 
@@ -1900,7 +1956,8 @@ produce_special_glyphs (it, what)
       ? (TN_no_color_video & (ATTR)) == 0      \
       : 1)
 
-/* Turn appearances of face FACE_ID on tty frame F on.  */
+/* Turn appearances of face FACE_ID on tty frame F on.
+   FACE_ID is a realized face ID number, in the face cache.  */
 
 static void
 turn_on_face (f, face_id)
@@ -1980,18 +2037,20 @@ turn_on_face (f, face_id)
 
   if (TN_max_colors > 0)
     {
-      char *p;
+      char *ts, *p;
 
-      if (fg >= 0 && TS_set_foreground)
+      ts = standout_mode ? TS_set_background : TS_set_foreground;
+      if (fg >= 0 && ts)
        {
-         p = tparam (TS_set_foreground, NULL, 0, (int) fg);
+         p = tparam (ts, NULL, 0, (int) fg);
          OUTPUT (p);
          xfree (p);
        }
 
-      if (bg >= 0 && TS_set_background)
+      ts = standout_mode ? TS_set_foreground : TS_set_background;
+      if (bg >= 0 && ts)
        {
-         p = tparam (TS_set_background, NULL, 0, (int) bg);
+         p = tparam (ts, NULL, 0, (int) bg);
          OUTPUT (p);
          xfree (p);
        }
@@ -2666,6 +2725,16 @@ fatal (str, arg1, arg2)
   exit (1);
 }
 
+DEFUN ("tty-no-underline", Ftty_no_underline, Stty_no_underline, 0, 0, 0,
+       doc: /* Declare that this terminal does not handle underlining.
+This is used to override the terminfo data, for certain terminals that
+do not really do underlining, but say that they do.  */)
+  ()
+{
+  TS_enter_underline_mode = 0;
+  return Qnil;
+}
+
 void
 syms_of_term ()
 {
@@ -2683,8 +2752,16 @@ This variable can be used by terminal emulator packages.  */);
 The function should accept no arguments.  */);
   Vring_bell_function = Qnil;
 
+  DEFVAR_BOOL ("visible-cursor", &visible_cursor,
+              doc: /* Non-nil means to make the cursor very visible.
+This only has an effect when running in a text terminal.
+What means \"very visible\" is up to your terminal.  It may make the cursor
+bigger, or it may make it blink, or it may do nothing at all.  */);
+  visible_cursor = 1;
+
   defsubr (&Stty_display_color_p);
   defsubr (&Stty_display_color_cells);
+  defsubr (&Stty_no_underline);
 }
 
 /* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193