Merge from trunk.
[bpt/emacs.git] / src / term.c
index 9205719..1041609 100644 (file)
@@ -136,10 +136,6 @@ enum no_color_bit
 
 static int max_frame_cols;
 
-/* The largest frame height in any call to calculate_costs.  */
-
-static int max_frame_lines;
-
 /* Non-zero if we have dropped our controlling tty and therefore
    should not open a frame on stdout. */
 static int no_controlling_tty;
@@ -497,8 +493,8 @@ tty_clear_end_of_line (struct frame *f, int first_unused_hpos)
 static unsigned char *encode_terminal_src;
 static unsigned char *encode_terminal_dst;
 /* Allocated sizes of the above buffers.  */
-static int encode_terminal_src_size;
-static int encode_terminal_dst_size;
+static ptrdiff_t encode_terminal_src_size;
+static ptrdiff_t encode_terminal_dst_size;
 
 /* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
    Set CODING->produced to the byte-length of the resulting byte
@@ -509,8 +505,8 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
 {
   struct glyph *src_end = src + src_len;
   unsigned char *buf;
-  int nchars, nbytes, required;
-  register int tlen = GLYPH_TABLE_LENGTH;
+  ptrdiff_t nchars, nbytes, required;
+  ptrdiff_t tlen = GLYPH_TABLE_LENGTH;
   register Lisp_Object *tbase = GLYPH_TABLE_BASE;
   Lisp_Object charset_list;
 
@@ -518,13 +514,13 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
      multibyte-form.  But, it may be enlarged on demand if
      Vglyph_table contains a string or a composite glyph is
      encountered.  */
-  required = MAX_MULTIBYTE_LENGTH * src_len;
+  if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < src_len)
+    memory_full (SIZE_MAX);
+  required = src_len;
+  required *= MAX_MULTIBYTE_LENGTH;
   if (encode_terminal_src_size < required)
     {
-      if (encode_terminal_src)
-       encode_terminal_src = xrealloc (encode_terminal_src, required);
-      else
-       encode_terminal_src = xmalloc (required);
+      encode_terminal_src = xrealloc (encode_terminal_src, required);
       encode_terminal_src_size = required;
     }
 
@@ -544,19 +540,21 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
          if (src->u.cmp.automatic)
            {
              gstring = composition_gstring_from_id (src->u.cmp.id);
-             required = src->slice.cmp.to + 1 - src->slice.cmp.from;
+             required = src->slice.cmp.to - src->slice.cmp.from + 1;
            }
          else
            {
              cmp = composition_table[src->u.cmp.id];
-             required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len;
+             required = cmp->glyph_len;
+             required *= MAX_MULTIBYTE_LENGTH;
            }
 
-         if (encode_terminal_src_size < nbytes + required)
+         if (encode_terminal_src_size - nbytes < required)
            {
-             encode_terminal_src_size = nbytes + required;
-             encode_terminal_src = xrealloc (encode_terminal_src,
-                                             encode_terminal_src_size);
+             encode_terminal_src =
+               xpalloc (encode_terminal_src, &encode_terminal_src_size,
+                        required - (encode_terminal_src_size - nbytes),
+                        -1, 1);
              buf = encode_terminal_src + nbytes;
            }
 
@@ -627,11 +625,11 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
          if (NILP (string))
            {
              nbytes = buf - encode_terminal_src;
-             if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH)
+             if (encode_terminal_src_size - nbytes < MAX_MULTIBYTE_LENGTH)
                {
-                 encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH;
-                 encode_terminal_src = xrealloc (encode_terminal_src,
-                                                 encode_terminal_src_size);
+                 encode_terminal_src =
+                   xpalloc (encode_terminal_src, &encode_terminal_src_size,
+                            MAX_MULTIBYTE_LENGTH, -1, 1);
                  buf = encode_terminal_src + nbytes;
                }
              if (CHAR_BYTE8_P (c)
@@ -659,11 +657,13 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
              if (! STRING_MULTIBYTE (string))
                string = string_to_multibyte (string);
              nbytes = buf - encode_terminal_src;
-             if (encode_terminal_src_size < nbytes + SBYTES (string))
+             if (encode_terminal_src_size - nbytes < SBYTES (string))
                {
-                 encode_terminal_src_size = nbytes + SBYTES (string);
-                 encode_terminal_src = xrealloc (encode_terminal_src,
-                                                 encode_terminal_src_size);
+                 encode_terminal_src =
+                   xpalloc (encode_terminal_src, &encode_terminal_src_size,
+                            (SBYTES (string)
+                             - (encode_terminal_src_size - nbytes)),
+                            -1, 1);
                  buf = encode_terminal_src + nbytes;
                }
              memcpy (buf, SDATA (string), SBYTES (string));
@@ -684,12 +684,9 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
   coding->source = encode_terminal_src;
   if (encode_terminal_dst_size == 0)
     {
+      encode_terminal_dst = xrealloc (encode_terminal_dst,
+                                     encode_terminal_src_size);
       encode_terminal_dst_size = encode_terminal_src_size;
-      if (encode_terminal_dst)
-       encode_terminal_dst = xrealloc (encode_terminal_dst,
-                                       encode_terminal_dst_size);
-      else
-       encode_terminal_dst = xmalloc (encode_terminal_dst_size);
     }
   coding->destination = encode_terminal_dst;
   coding->dst_bytes = encode_terminal_dst_size;
@@ -1156,21 +1153,17 @@ calculate_costs (struct frame *frame)
          char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
          X turns off char_ins_del_ok. */
 
-      max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
       max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
+      if ((min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) - 1) / 2
+         < max_frame_cols)
+       memory_full (SIZE_MAX);
 
-      if (char_ins_del_vector != 0)
-        char_ins_del_vector
-          = (int *) xrealloc (char_ins_del_vector,
-                              (sizeof (int)
-                               + 2 * max_frame_cols * sizeof (int)));
-      else
-        char_ins_del_vector
-          = (int *) xmalloc (sizeof (int)
-                             + 2 * max_frame_cols * sizeof (int));
+      char_ins_del_vector =
+       xrealloc (char_ins_del_vector,
+                 (sizeof (int) + 2 * sizeof (int) * max_frame_cols));
 
       memset (char_ins_del_vector, 0,
-             (sizeof (int) + 2 * max_frame_cols * sizeof (int)));
+             (sizeof (int) + 2 * sizeof (int) * max_frame_cols));
 
 
       if (f && (!tty->TS_ins_line && !tty->TS_del_line))
@@ -1447,7 +1440,6 @@ term_get_fkeys_1 (void)
                       Character Display Information
  ***********************************************************************/
 static void append_glyph (struct it *);
-static void produce_stretch_glyph (struct it *);
 static void append_composite_glyph (struct it *);
 static void produce_composite_glyph (struct it *);
 static void append_glyphless_glyph (struct it *, int, const char *);
@@ -1519,6 +1511,14 @@ append_glyph (struct it *it)
     }
 }
 
+/* For external use.  */
+void
+tty_append_glyph (struct it *it)
+{
+  append_glyph (it);
+}
+
+
 /* Produce glyphs for the display element described by IT.  *IT
    specifies what we want to produce a glyph for (character, image, ...),
    and where in the glyph matrix we currently are (glyph row and hpos).
@@ -1546,7 +1546,8 @@ produce_glyphs (struct it *it)
   /* Nothing but characters are supported on terminal frames.  */
   xassert (it->what == IT_CHARACTER
           || it->what == IT_COMPOSITION
-          || it->what == IT_STRETCH);
+          || it->what == IT_STRETCH
+          || it->what == IT_GLYPHLESS);
 
   if (it->what == IT_STRETCH)
     {
@@ -1644,83 +1645,6 @@ produce_glyphs (struct it *it)
   it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
 }
 
-
-/* Produce a stretch glyph for iterator IT.  IT->object is the value
-   of the glyph property displayed.  The value must be a list
-   `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
-   being recognized:
-
-   1. `:width WIDTH' specifies that the space should be WIDTH *
-   canonical char width wide.  WIDTH may be an integer or floating
-   point number.
-
-   2. `:align-to HPOS' specifies that the space should be wide enough
-   to reach HPOS, a value in canonical character units.  */
-
-static void
-produce_stretch_glyph (struct it *it)
-{
-  /* (space :width WIDTH ...)  */
-  Lisp_Object prop, plist;
-  int width = 0, align_to = -1;
-  int zero_width_ok_p = 0;
-  double tem;
-
-  /* List should start with `space'.  */
-  xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
-  plist = XCDR (it->object);
-
-  /* Compute the width of the stretch.  */
-  if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
-      && calc_pixel_width_or_height (&tem, it, prop, 0, 1, 0))
-    {
-      /* Absolute width `:width WIDTH' specified and valid.  */
-      zero_width_ok_p = 1;
-      width = (int)(tem + 0.5);
-    }
-  else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
-          && 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
-                   ? 0
-                   : align_to - window_box_left_offset (it->w, TEXT_AREA));
-      else if (align_to < 0)
-       align_to = window_box_left_offset (it->w, TEXT_AREA);
-      width = max (0, (int)(tem + 0.5) + align_to - it->current_x);
-      zero_width_ok_p = 1;
-    }
-  else
-    /* Nothing specified -> width defaults to canonical char width.  */
-    width = FRAME_COLUMN_WIDTH (it->f);
-
-  if (width <= 0 && (width < 0 || !zero_width_ok_p))
-    width = 1;
-
-  if (width > 0 && it->line_wrap != TRUNCATE
-      && it->current_x + width > it->last_visible_x)
-    width = it->last_visible_x - it->current_x - 1;
-
-  if (width > 0 && it->glyph_row)
-    {
-      Lisp_Object o_object = it->object;
-      Lisp_Object object = it->stack[it->sp - 1].string;
-      int n = width;
-
-      if (!STRINGP (object))
-       object = it->w->buffer;
-      it->object = object;
-      it->char_to_display = ' ';
-      it->pixel_width = it->len = 1;
-      while (n--)
-       append_glyph (it);
-      it->object = o_object;
-    }
-  it->pixel_width = width;
-  it->nglyphs = width;
-}
-
-
 /* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
    Called from produce_composite_glyph for terminal frames if
    IT->glyph_row != NULL.  IT->face_id contains the character's
@@ -1893,7 +1817,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
 {
   int face_id;
   int len;
-  char buf[9];
+  char buf[sizeof "\\x" + max (6, (sizeof it->c * CHAR_BIT + 3) / 4)];
   char const *str = "    ";
 
   /* Get a face ID for the glyph by utilizing a cache (the same way as
@@ -3096,7 +3020,6 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
   char *area = NULL;
   char **address = &area;
   int buffer_size = 4096;
-  register char *p = NULL;
   int status;
   struct tty_display_info *tty = NULL;
   struct terminal *terminal = NULL;
@@ -3145,11 +3068,6 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
   encode_terminal_src_size = 0;
   encode_terminal_dst_size = 0;
 
-#ifdef HAVE_GPM
-  terminal->mouse_position_hook = term_mouse_position;
-  tty->mouse_highlight.mouse_face_window = Qnil;
-#endif
-
 
 #ifndef DOS_NT
   set_tty_hooks (terminal);
@@ -3409,6 +3327,11 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
   tty->TN_max_colors = 16;  /* Required to be non-zero for tty-display-color-p */
 #endif /* DOS_NT */
 
+#ifdef HAVE_GPM
+  terminal->mouse_position_hook = term_mouse_position;
+  tty->mouse_highlight.mouse_face_window = Qnil;
+#endif
+
   terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
   init_kboard (terminal->kboard);
   KVAR (terminal->kboard, Vwindow_system) = Qnil;
@@ -3504,55 +3427,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
       Down (tty) = 0;
     }
 
-  /* Special handling for certain terminal types known to need it */
-
-  if (!strcmp (terminal_type, "supdup"))
-    {
-      terminal->memory_below_frame = 1;
-      tty->Wcm->cm_losewrap = 1;
-    }
-  if (!strncmp (terminal_type, "c10", 3)
-      || !strcmp (terminal_type, "perq"))
-    {
-      /* Supply a makeshift :wi string.
-        This string is not valid in general since it works only
-        for windows starting at the upper left corner;
-        but that is all Emacs uses.
-
-        This string works only if the frame is using
-        the top of the video memory, because addressing is memory-relative.
-        So first check the :ti string to see if that is true.
-
-        It would be simpler if the :wi string could go in the termcap
-        entry, but it can't because it is not fully valid.
-        If it were in the termcap entry, it would confuse other programs.  */
-      if (!tty->TS_set_window)
-       {
-         const char *m = tty->TS_termcap_modes;
-         while (*m && strcmp (m, "\033v  "))
-           m++;
-         if (*m)
-           tty->TS_set_window = "\033v%C %C %C %C ";
-       }
-      /* Termcap entry often fails to have :in: flag */
-      terminal->must_write_spaces = 1;
-      /* :ti string typically fails to have \E^G! in it */
-      /* This limits scope of insert-char to one line.  */
-      strcpy (area, tty->TS_termcap_modes);
-      strcat (area, "\033\007!");
-      tty->TS_termcap_modes = area;
-      area += strlen (area) + 1;
-      p = AbsPosition (tty);
-      /* Change all %+ parameters to %C, to handle
-         values above 96 correctly for the C100.  */
-      while (*p)
-        {
-          if (p[0] == '%' && p[1] == '+')
-            p[1] = 'C';
-          p++;
-        }
-    }
-
   tty->specified_window = FrameRows (tty);
 
   if (Wcm_init (tty) == -1)    /* can't do cursor motion */