aboutsummaryrefslogtreecommitdiffstats
path: root/src/term.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/term.c')
-rw-r--r--src/term.c235
1 files changed, 55 insertions, 180 deletions
diff --git a/src/term.c b/src/term.c
index be23e547514..53458c559dd 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1,5 +1,5 @@
1/* Terminal control module for terminals described by TERMCAP 1/* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2011 2 Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2012
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
@@ -136,10 +136,6 @@ enum no_color_bit
136 136
137static int max_frame_cols; 137static int max_frame_cols;
138 138
139/* The largest frame height in any call to calculate_costs. */
140
141static int max_frame_lines;
142
143/* Non-zero if we have dropped our controlling tty and therefore 139/* Non-zero if we have dropped our controlling tty and therefore
144 should not open a frame on stdout. */ 140 should not open a frame on stdout. */
145static int no_controlling_tty; 141static int no_controlling_tty;
@@ -497,8 +493,8 @@ tty_clear_end_of_line (struct frame *f, int first_unused_hpos)
497static unsigned char *encode_terminal_src; 493static unsigned char *encode_terminal_src;
498static unsigned char *encode_terminal_dst; 494static unsigned char *encode_terminal_dst;
499/* Allocated sizes of the above buffers. */ 495/* Allocated sizes of the above buffers. */
500static int encode_terminal_src_size; 496static ptrdiff_t encode_terminal_src_size;
501static int encode_terminal_dst_size; 497static ptrdiff_t encode_terminal_dst_size;
502 498
503/* Encode SRC_LEN glyphs starting at SRC to terminal output codes. 499/* Encode SRC_LEN glyphs starting at SRC to terminal output codes.
504 Set CODING->produced to the byte-length of the resulting byte 500 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
509{ 505{
510 struct glyph *src_end = src + src_len; 506 struct glyph *src_end = src + src_len;
511 unsigned char *buf; 507 unsigned char *buf;
512 int nchars, nbytes, required; 508 ptrdiff_t nchars, nbytes, required;
513 register int tlen = GLYPH_TABLE_LENGTH; 509 ptrdiff_t tlen = GLYPH_TABLE_LENGTH;
514 register Lisp_Object *tbase = GLYPH_TABLE_BASE; 510 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
515 Lisp_Object charset_list; 511 Lisp_Object charset_list;
516 512
@@ -518,13 +514,13 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
518 multibyte-form. But, it may be enlarged on demand if 514 multibyte-form. But, it may be enlarged on demand if
519 Vglyph_table contains a string or a composite glyph is 515 Vglyph_table contains a string or a composite glyph is
520 encountered. */ 516 encountered. */
521 required = MAX_MULTIBYTE_LENGTH * src_len; 517 if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < src_len)
518 memory_full (SIZE_MAX);
519 required = src_len;
520 required *= MAX_MULTIBYTE_LENGTH;
522 if (encode_terminal_src_size < required) 521 if (encode_terminal_src_size < required)
523 { 522 {
524 if (encode_terminal_src) 523 encode_terminal_src = xrealloc (encode_terminal_src, required);
525 encode_terminal_src = xrealloc (encode_terminal_src, required);
526 else
527 encode_terminal_src = xmalloc (required);
528 encode_terminal_src_size = required; 524 encode_terminal_src_size = required;
529 } 525 }
530 526
@@ -544,19 +540,21 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
544 if (src->u.cmp.automatic) 540 if (src->u.cmp.automatic)
545 { 541 {
546 gstring = composition_gstring_from_id (src->u.cmp.id); 542 gstring = composition_gstring_from_id (src->u.cmp.id);
547 required = src->slice.cmp.to + 1 - src->slice.cmp.from; 543 required = src->slice.cmp.to - src->slice.cmp.from + 1;
548 } 544 }
549 else 545 else
550 { 546 {
551 cmp = composition_table[src->u.cmp.id]; 547 cmp = composition_table[src->u.cmp.id];
552 required = MAX_MULTIBYTE_LENGTH * cmp->glyph_len; 548 required = cmp->glyph_len;
549 required *= MAX_MULTIBYTE_LENGTH;
553 } 550 }
554 551
555 if (encode_terminal_src_size < nbytes + required) 552 if (encode_terminal_src_size - nbytes < required)
556 { 553 {
557 encode_terminal_src_size = nbytes + required; 554 encode_terminal_src =
558 encode_terminal_src = xrealloc (encode_terminal_src, 555 xpalloc (encode_terminal_src, &encode_terminal_src_size,
559 encode_terminal_src_size); 556 required - (encode_terminal_src_size - nbytes),
557 -1, 1);
560 buf = encode_terminal_src + nbytes; 558 buf = encode_terminal_src + nbytes;
561 } 559 }
562 560
@@ -576,6 +574,8 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
576 { 574 {
577 int c = COMPOSITION_GLYPH (cmp, i); 575 int c = COMPOSITION_GLYPH (cmp, i);
578 576
577 /* TAB in a composition means display glyphs with
578 padding space on the left or right. */
579 if (c == '\t') 579 if (c == '\t')
580 continue; 580 continue;
581 if (char_charset (c, charset_list, NULL)) 581 if (char_charset (c, charset_list, NULL))
@@ -627,11 +627,11 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
627 if (NILP (string)) 627 if (NILP (string))
628 { 628 {
629 nbytes = buf - encode_terminal_src; 629 nbytes = buf - encode_terminal_src;
630 if (encode_terminal_src_size < nbytes + MAX_MULTIBYTE_LENGTH) 630 if (encode_terminal_src_size - nbytes < MAX_MULTIBYTE_LENGTH)
631 { 631 {
632 encode_terminal_src_size = nbytes + MAX_MULTIBYTE_LENGTH; 632 encode_terminal_src =
633 encode_terminal_src = xrealloc (encode_terminal_src, 633 xpalloc (encode_terminal_src, &encode_terminal_src_size,
634 encode_terminal_src_size); 634 MAX_MULTIBYTE_LENGTH, -1, 1);
635 buf = encode_terminal_src + nbytes; 635 buf = encode_terminal_src + nbytes;
636 } 636 }
637 if (CHAR_BYTE8_P (c) 637 if (CHAR_BYTE8_P (c)
@@ -659,11 +659,13 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
659 if (! STRING_MULTIBYTE (string)) 659 if (! STRING_MULTIBYTE (string))
660 string = string_to_multibyte (string); 660 string = string_to_multibyte (string);
661 nbytes = buf - encode_terminal_src; 661 nbytes = buf - encode_terminal_src;
662 if (encode_terminal_src_size < nbytes + SBYTES (string)) 662 if (encode_terminal_src_size - nbytes < SBYTES (string))
663 { 663 {
664 encode_terminal_src_size = nbytes + SBYTES (string); 664 encode_terminal_src =
665 encode_terminal_src = xrealloc (encode_terminal_src, 665 xpalloc (encode_terminal_src, &encode_terminal_src_size,
666 encode_terminal_src_size); 666 (SBYTES (string)
667 - (encode_terminal_src_size - nbytes)),
668 -1, 1);
667 buf = encode_terminal_src + nbytes; 669 buf = encode_terminal_src + nbytes;
668 } 670 }
669 memcpy (buf, SDATA (string), SBYTES (string)); 671 memcpy (buf, SDATA (string), SBYTES (string));
@@ -684,12 +686,9 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
684 coding->source = encode_terminal_src; 686 coding->source = encode_terminal_src;
685 if (encode_terminal_dst_size == 0) 687 if (encode_terminal_dst_size == 0)
686 { 688 {
689 encode_terminal_dst = xrealloc (encode_terminal_dst,
690 encode_terminal_src_size);
687 encode_terminal_dst_size = encode_terminal_src_size; 691 encode_terminal_dst_size = encode_terminal_src_size;
688 if (encode_terminal_dst)
689 encode_terminal_dst = xrealloc (encode_terminal_dst,
690 encode_terminal_dst_size);
691 else
692 encode_terminal_dst = xmalloc (encode_terminal_dst_size);
693 } 692 }
694 coding->destination = encode_terminal_dst; 693 coding->destination = encode_terminal_dst;
695 coding->dst_bytes = encode_terminal_dst_size; 694 coding->dst_bytes = encode_terminal_dst_size;
@@ -1156,21 +1155,17 @@ calculate_costs (struct frame *frame)
1156 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because 1155 char_ins_del_vector (i.e., char_ins_del_cost) isn't used because
1157 X turns off char_ins_del_ok. */ 1156 X turns off char_ins_del_ok. */
1158 1157
1159 max_frame_lines = max (max_frame_lines, FRAME_LINES (frame));
1160 max_frame_cols = max (max_frame_cols, FRAME_COLS (frame)); 1158 max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
1159 if ((min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) - 1) / 2
1160 < max_frame_cols)
1161 memory_full (SIZE_MAX);
1161 1162
1162 if (char_ins_del_vector != 0) 1163 char_ins_del_vector =
1163 char_ins_del_vector 1164 xrealloc (char_ins_del_vector,
1164 = (int *) xrealloc (char_ins_del_vector, 1165 (sizeof (int) + 2 * sizeof (int) * max_frame_cols));
1165 (sizeof (int)
1166 + 2 * max_frame_cols * sizeof (int)));
1167 else
1168 char_ins_del_vector
1169 = (int *) xmalloc (sizeof (int)
1170 + 2 * max_frame_cols * sizeof (int));
1171 1166
1172 memset (char_ins_del_vector, 0, 1167 memset (char_ins_del_vector, 0,
1173 (sizeof (int) + 2 * max_frame_cols * sizeof (int))); 1168 (sizeof (int) + 2 * sizeof (int) * max_frame_cols));
1174 1169
1175 1170
1176 if (f && (!tty->TS_ins_line && !tty->TS_del_line)) 1171 if (f && (!tty->TS_ins_line && !tty->TS_del_line))
@@ -1447,7 +1442,6 @@ term_get_fkeys_1 (void)
1447 Character Display Information 1442 Character Display Information
1448 ***********************************************************************/ 1443 ***********************************************************************/
1449static void append_glyph (struct it *); 1444static void append_glyph (struct it *);
1450static void produce_stretch_glyph (struct it *);
1451static void append_composite_glyph (struct it *); 1445static void append_composite_glyph (struct it *);
1452static void produce_composite_glyph (struct it *); 1446static void produce_composite_glyph (struct it *);
1453static void append_glyphless_glyph (struct it *, int, const char *); 1447static void append_glyphless_glyph (struct it *, int, const char *);
@@ -1519,6 +1513,14 @@ append_glyph (struct it *it)
1519 } 1513 }
1520} 1514}
1521 1515
1516/* For external use. */
1517void
1518tty_append_glyph (struct it *it)
1519{
1520 append_glyph (it);
1521}
1522
1523
1522/* Produce glyphs for the display element described by IT. *IT 1524/* Produce glyphs for the display element described by IT. *IT
1523 specifies what we want to produce a glyph for (character, image, ...), 1525 specifies what we want to produce a glyph for (character, image, ...),
1524 and where in the glyph matrix we currently are (glyph row and hpos). 1526 and where in the glyph matrix we currently are (glyph row and hpos).
@@ -1645,83 +1647,6 @@ produce_glyphs (struct it *it)
1645 it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1; 1647 it->descent = it->max_descent = it->phys_descent = it->max_phys_descent = 1;
1646} 1648}
1647 1649
1648
1649/* Produce a stretch glyph for iterator IT. IT->object is the value
1650 of the glyph property displayed. The value must be a list
1651 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
1652 being recognized:
1653
1654 1. `:width WIDTH' specifies that the space should be WIDTH *
1655 canonical char width wide. WIDTH may be an integer or floating
1656 point number.
1657
1658 2. `:align-to HPOS' specifies that the space should be wide enough
1659 to reach HPOS, a value in canonical character units. */
1660
1661static void
1662produce_stretch_glyph (struct it *it)
1663{
1664 /* (space :width WIDTH ...) */
1665 Lisp_Object prop, plist;
1666 int width = 0, align_to = -1;
1667 int zero_width_ok_p = 0;
1668 double tem;
1669
1670 /* List should start with `space'. */
1671 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
1672 plist = XCDR (it->object);
1673
1674 /* Compute the width of the stretch. */
1675 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
1676 && calc_pixel_width_or_height (&tem, it, prop, 0, 1, 0))
1677 {
1678 /* Absolute width `:width WIDTH' specified and valid. */
1679 zero_width_ok_p = 1;
1680 width = (int)(tem + 0.5);
1681 }
1682 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
1683 && calc_pixel_width_or_height (&tem, it, prop, 0, 1, &align_to))
1684 {
1685 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
1686 align_to = (align_to < 0
1687 ? 0
1688 : align_to - window_box_left_offset (it->w, TEXT_AREA));
1689 else if (align_to < 0)
1690 align_to = window_box_left_offset (it->w, TEXT_AREA);
1691 width = max (0, (int)(tem + 0.5) + align_to - it->current_x);
1692 zero_width_ok_p = 1;
1693 }
1694 else
1695 /* Nothing specified -> width defaults to canonical char width. */
1696 width = FRAME_COLUMN_WIDTH (it->f);
1697
1698 if (width <= 0 && (width < 0 || !zero_width_ok_p))
1699 width = 1;
1700
1701 if (width > 0 && it->line_wrap != TRUNCATE
1702 && it->current_x + width > it->last_visible_x)
1703 width = it->last_visible_x - it->current_x - 1;
1704
1705 if (width > 0 && it->glyph_row)
1706 {
1707 Lisp_Object o_object = it->object;
1708 Lisp_Object object = it->stack[it->sp - 1].string;
1709 int n = width;
1710
1711 if (!STRINGP (object))
1712 object = it->w->buffer;
1713 it->object = object;
1714 it->char_to_display = ' ';
1715 it->pixel_width = it->len = 1;
1716 while (n--)
1717 append_glyph (it);
1718 it->object = o_object;
1719 }
1720 it->pixel_width = width;
1721 it->nglyphs = width;
1722}
1723
1724
1725/* Append glyphs to IT's glyph_row for the composition IT->cmp_id. 1650/* Append glyphs to IT's glyph_row for the composition IT->cmp_id.
1726 Called from produce_composite_glyph for terminal frames if 1651 Called from produce_composite_glyph for terminal frames if
1727 IT->glyph_row != NULL. IT->face_id contains the character's 1652 IT->glyph_row != NULL. IT->face_id contains the character's
@@ -1884,7 +1809,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str)
1884 glyphless_display_method in dispextern.h for the details. 1809 glyphless_display_method in dispextern.h for the details.
1885 1810
1886 FOR_NO_FONT is nonzero if and only if this is for a character that 1811 FOR_NO_FONT is nonzero if and only if this is for a character that
1887 is not supproted by the coding system of the terminal. ACRONYM, if 1812 is not supported by the coding system of the terminal. ACRONYM, if
1888 non-nil, is an acronym string for the character. 1813 non-nil, is an acronym string for the character.
1889 1814
1890 The glyphs actually produced are of type CHAR_GLYPH. */ 1815 The glyphs actually produced are of type CHAR_GLYPH. */
@@ -1894,7 +1819,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
1894{ 1819{
1895 int face_id; 1820 int face_id;
1896 int len; 1821 int len;
1897 char buf[9]; 1822 char buf[sizeof "\\x" + max (6, (sizeof it->c * CHAR_BIT + 3) / 4)];
1898 char const *str = " "; 1823 char const *str = " ";
1899 1824
1900 /* Get a face ID for the glyph by utilizing a cache (the same way as 1825 /* Get a face ID for the glyph by utilizing a cache (the same way as
@@ -3097,7 +3022,6 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3097 char *area = NULL; 3022 char *area = NULL;
3098 char **address = &area; 3023 char **address = &area;
3099 int buffer_size = 4096; 3024 int buffer_size = 4096;
3100 register char *p = NULL;
3101 int status; 3025 int status;
3102 struct tty_display_info *tty = NULL; 3026 struct tty_display_info *tty = NULL;
3103 struct terminal *terminal = NULL; 3027 struct terminal *terminal = NULL;
@@ -3146,11 +3070,6 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3146 encode_terminal_src_size = 0; 3070 encode_terminal_src_size = 0;
3147 encode_terminal_dst_size = 0; 3071 encode_terminal_dst_size = 0;
3148 3072
3149#ifdef HAVE_GPM
3150 terminal->mouse_position_hook = term_mouse_position;
3151 tty->mouse_highlight.mouse_face_window = Qnil;
3152#endif
3153
3154 3073
3155#ifndef DOS_NT 3074#ifndef DOS_NT
3156 set_tty_hooks (terminal); 3075 set_tty_hooks (terminal);
@@ -3317,7 +3236,7 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3317 MultiLeft (tty) = tgetstr ("LE", address); 3236 MultiLeft (tty) = tgetstr ("LE", address);
3318 MultiRight (tty) = tgetstr ("RI", address); 3237 MultiRight (tty) = tgetstr ("RI", address);
3319 3238
3320 /* SVr4/ANSI color suppert. If "op" isn't available, don't support 3239 /* SVr4/ANSI color support. If "op" isn't available, don't support
3321 color because we can't switch back to the default foreground and 3240 color because we can't switch back to the default foreground and
3322 background. */ 3241 background. */
3323 tty->TS_orig_pair = tgetstr ("op", address); 3242 tty->TS_orig_pair = tgetstr ("op", address);
@@ -3410,6 +3329,11 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3410 tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */ 3329 tty->TN_max_colors = 16; /* Required to be non-zero for tty-display-color-p */
3411#endif /* DOS_NT */ 3330#endif /* DOS_NT */
3412 3331
3332#ifdef HAVE_GPM
3333 terminal->mouse_position_hook = term_mouse_position;
3334 tty->mouse_highlight.mouse_face_window = Qnil;
3335#endif
3336
3413 terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD)); 3337 terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
3414 init_kboard (terminal->kboard); 3338 init_kboard (terminal->kboard);
3415 KVAR (terminal->kboard, Vwindow_system) = Qnil; 3339 KVAR (terminal->kboard, Vwindow_system) = Qnil;
@@ -3505,55 +3429,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
3505 Down (tty) = 0; 3429 Down (tty) = 0;
3506 } 3430 }
3507 3431
3508 /* Special handling for certain terminal types known to need it */
3509
3510 if (!strcmp (terminal_type, "supdup"))
3511 {
3512 terminal->memory_below_frame = 1;
3513 tty->Wcm->cm_losewrap = 1;
3514 }
3515 if (!strncmp (terminal_type, "c10", 3)
3516 || !strcmp (terminal_type, "perq"))
3517 {
3518 /* Supply a makeshift :wi string.
3519 This string is not valid in general since it works only
3520 for windows starting at the upper left corner;
3521 but that is all Emacs uses.
3522
3523 This string works only if the frame is using
3524 the top of the video memory, because addressing is memory-relative.
3525 So first check the :ti string to see if that is true.
3526
3527 It would be simpler if the :wi string could go in the termcap
3528 entry, but it can't because it is not fully valid.
3529 If it were in the termcap entry, it would confuse other programs. */
3530 if (!tty->TS_set_window)
3531 {
3532 const char *m = tty->TS_termcap_modes;
3533 while (*m && strcmp (m, "\033v "))
3534 m++;
3535 if (*m)
3536 tty->TS_set_window = "\033v%C %C %C %C ";
3537 }
3538 /* Termcap entry often fails to have :in: flag */
3539 terminal->must_write_spaces = 1;
3540 /* :ti string typically fails to have \E^G! in it */
3541 /* This limits scope of insert-char to one line. */
3542 strcpy (area, tty->TS_termcap_modes);
3543 strcat (area, "\033\007!");
3544 tty->TS_termcap_modes = area;
3545 area += strlen (area) + 1;
3546 p = AbsPosition (tty);
3547 /* Change all %+ parameters to %C, to handle
3548 values above 96 correctly for the C100. */
3549 while (*p)
3550 {
3551 if (p[0] == '%' && p[1] == '+')
3552 p[1] = 'C';
3553 p++;
3554 }
3555 }
3556
3557 tty->specified_window = FrameRows (tty); 3432 tty->specified_window = FrameRows (tty);
3558 3433
3559 if (Wcm_init (tty) == -1) /* can't do cursor motion */ 3434 if (Wcm_init (tty) == -1) /* can't do cursor motion */