Mercurial > emacs
diff src/term.c @ 88155:d7ddb3e565de
sync with trunk
author | Henrik Enberg <henrik.enberg@telia.com> |
---|---|
date | Mon, 16 Jan 2006 00:03:54 +0000 |
parents | 23a1cea22d13 |
children |
line wrap: on
line diff
--- a/src/term.c Sun Jan 15 23:02:10 2006 +0000 +++ b/src/term.c Mon Jan 16 00:03:54 2006 +0000 @@ -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 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -16,8 +16,8 @@ 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>. */ @@ -66,23 +66,31 @@ static void tty_hide_cursor P_ ((void)); #define OUTPUT(a) \ - tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) - curY), cmputc) + tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) - curY), cmputc) #define OUTPUT1(a) tputs (a, 1, cmputc) #define OUTPUTL(a, lines) tputs (a, lines, cmputc) #define OUTPUT_IF(a) \ do { \ if (a) \ - tputs (a, (int) (FRAME_HEIGHT (XFRAME (selected_frame)) \ + tputs (a, (int) (FRAME_LINES (XFRAME (selected_frame)) \ - curY), cmputc); \ } while (0) #define OUTPUT1_IF(a) do { if (a) tputs (a, 1, cmputc); } while (0) +/* Display space properties */ + +extern Lisp_Object Qspace, QCalign_to, QCwidth; + /* Function to use to ring the bell. */ 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 */ @@ -131,7 +139,7 @@ void (*write_glyphs_hook) P_ ((struct glyph *, int)); void (*delete_glyphs_hook) P_ ((int)); -int (*read_socket_hook) P_ ((int, struct input_event *, int, int)); +int (*read_socket_hook) P_ ((int, int, struct input_event *)); void (*frame_up_to_date_hook) P_ ((struct frame *)); @@ -235,11 +243,6 @@ void (*judge_scroll_bars_hook) P_ ((FRAME_PTR FRAME)); -/* Hook to call in estimate_mode_line_height, if any. */ - -int (* estimate_mode_line_height_hook) P_ ((struct frame *f, enum face_id)); - - /* Strings, numbers and flags taken from the termcap entry. */ char *TS_ins_line; /* "al" */ @@ -368,11 +371,11 @@ /* The largest frame width in any call to calculate_costs. */ -int max_frame_width; +int max_frame_cols; /* The largest frame height in any call to calculate_costs. */ -int max_frame_height; +int max_frame_lines; static int costs_set; /* Nonzero if costs have been calculated. */ @@ -383,7 +386,7 @@ This is the number of lines, from the top of frame downwards, which can participate in insert-line/delete-line operations. - Effectively it excludes the bottom frame_height - specified_window_size + Effectively it excludes the bottom frame_lines - specified_window_size lines from those operations. */ int specified_window; @@ -450,8 +453,18 @@ { 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 (); } @@ -509,7 +522,7 @@ { if (FRAME_TERMCAP_P (updating_frame)) { - specified_window = size ? size : FRAME_HEIGHT (updating_frame); + specified_window = size ? size : FRAME_LINES (updating_frame); if (scroll_region_ok) set_scroll_region (0, specified_window); } @@ -528,11 +541,11 @@ buf = tparam (TS_set_scroll_region, 0, 0, start, stop - 1); else if (TS_set_scroll_region_1) buf = tparam (TS_set_scroll_region_1, 0, 0, - FRAME_HEIGHT (sf), start, - FRAME_HEIGHT (sf) - stop, - FRAME_HEIGHT (sf)); + FRAME_LINES (sf), start, + FRAME_LINES (sf) - stop, + FRAME_LINES (sf)); else - buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_WIDTH (sf)); + buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_COLS (sf)); OUTPUT (buf); xfree (buf); @@ -606,7 +619,8 @@ { tty_cursor_hidden = 0; OUTPUT_IF (TS_cursor_normal); - OUTPUT_IF (TS_cursor_visible); + if (visible_cursor) + OUTPUT_IF (TS_cursor_visible); } } @@ -706,10 +720,10 @@ } else { - for (i = curY; i < FRAME_HEIGHT (XFRAME (selected_frame)); i++) + for (i = curY; i < FRAME_LINES (XFRAME (selected_frame)); i++) { cursor_to (i, 0); - clear_end_of_line (FRAME_WIDTH (XFRAME (selected_frame))); + clear_end_of_line (FRAME_COLS (XFRAME (selected_frame))); } } } @@ -778,8 +792,8 @@ turn_off_insert (); /* Do not write in last row last col with Auto-wrap on. */ - if (AutoWrap && curY == FRAME_HEIGHT (sf) - 1 - && first_unused_hpos == FRAME_WIDTH (sf)) + if (AutoWrap && curY == FRAME_LINES (sf) - 1 + && first_unused_hpos == FRAME_COLS (sf)) first_unused_hpos--; for (i = curX; i < first_unused_hpos; i++) @@ -792,39 +806,43 @@ } } -/* Encode SRC_LEN glyphs starting at SRC to terminal output codes and - store them at DST. Do not write more than DST_LEN bytes. That may - require stopping before all SRC_LEN input glyphs have been - converted. - - We store the number of glyphs actually converted in *CONSUMED. The - return value is the number of bytes store in DST. */ - -int -encode_terminal_code (src, dst, src_len, dst_len, consumed) +/* Buffer to store the source and result of code conversion for terminal. */ +static unsigned char *encode_terminal_buf; +/* Allocated size of the above buffer. */ +static int encode_terminal_bufsize; + +/* Encode SRC_LEN glyphs starting at SRC to terminal output codes. + Set CODING->produced to the byte-length of the resulting byte + sequence, and return a pointer to that byte sequence. */ + +unsigned char * +encode_terminal_code (src, src_len, coding) struct glyph *src; int src_len; - unsigned char *dst; - int dst_len, *consumed; + struct coding_system *coding; { - struct glyph *src_start = src, *src_end = src + src_len; - unsigned char *dst_start = dst, *dst_end = dst + dst_len; + struct glyph *src_end = src + src_len; register GLYPH g; - unsigned char workbuf[MAX_MULTIBYTE_LENGTH]; - const unsigned char *buf; - int len; + unsigned char *buf; + int nchars, nbytes, required; register int tlen = GLYPH_TABLE_LENGTH; register Lisp_Object *tbase = GLYPH_TABLE_BASE; - int result; - struct coding_system *coding; - - /* If terminal_coding does any conversion, use it, otherwise use - safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here - because it always return 1 if the member src_multibyte is 1. */ - coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK - ? &terminal_coding - : &safe_terminal_coding); - + + /* Allocate sufficient size of buffer to store all characters in + multibyte-form. But, it may be enlarged on demand if + Vglyph_table contains a string. */ + required = MAX_MULTIBYTE_LENGTH * src_len; + if (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; + nchars = 0; while (src < src_end) { /* We must skip glyphs to be padded for a wide character. */ @@ -835,18 +853,11 @@ if (g < 0 || g >= tlen) { /* This glyph doesn't has an entry in Vglyph_table. */ - if (! CHAR_VALID_P (src->u.ch, 0)) - { - len = 1; - buf = " "; - coding->src_multibyte = 0; - } + if (CHAR_VALID_P (src->u.ch, 0)) + buf += CHAR_STRING (src->u.ch, buf); else - { - len = CHAR_STRING (src->u.ch, workbuf); - buf = workbuf; - coding->src_multibyte = 1; - } + *buf++ = SPACEGLYPH; + nchars++; } else { @@ -856,61 +867,72 @@ if (GLYPH_SIMPLE_P (tbase, tlen, g)) { - /* We set the multi-byte form of a character in G - (that should be an ASCII character) at - WORKBUF. */ - workbuf[0] = FAST_GLYPH_CHAR (g); - len = 1; - buf = workbuf; - coding->src_multibyte = 0; + int c = FAST_GLYPH_CHAR (g); + + if (CHAR_VALID_P (c, 0)) + buf += CHAR_STRING (c, buf); + else + *buf++ = SPACEGLYPH; + nchars++; } else { /* We have a string in Vglyph_table. */ - len = GLYPH_LENGTH (tbase, g); - buf = GLYPH_STRING (tbase, g); - coding->src_multibyte = STRING_MULTIBYTE (tbase[g]); + Lisp_Object string; + + string = tbase[g]; + if (! STRING_MULTIBYTE (string)) + string = string_to_multibyte (string); + nbytes = buf - encode_terminal_buf; + if (encode_terminal_bufsize < nbytes + SBYTES (string)) + { + encode_terminal_bufsize = nbytes + SBYTES (string); + encode_terminal_buf = xrealloc (encode_terminal_buf, + encode_terminal_bufsize); + buf = encode_terminal_buf + nbytes; + } + bcopy (SDATA (string), buf, SBYTES (string)); + buf += SBYTES (string); + nchars += SCHARS (string); } } - - result = encode_coding (coding, buf, dst, len, dst_end - dst); - len -= coding->consumed; - dst += coding->produced; - if (result == CODING_FINISH_INSUFFICIENT_DST - || (result == CODING_FINISH_INSUFFICIENT_SRC - && len > dst_end - dst)) - /* The remaining output buffer is too short. We must - break the loop here without increasing SRC so that the - next call of this function starts from the same glyph. */ - break; - - if (len > 0) - { - /* This is the case that a code of the range 0200..0237 - exists in buf. We must just write out such a code. */ - buf += coding->consumed; - while (len--) - *dst++ = *buf++; - } } src++; } - *consumed = src - src_start; - return (dst - dst_start); + nbytes = buf - encode_terminal_buf; + coding->src_multibyte = 1; + coding->dst_multibyte = 0; + if (SYMBOLP (coding->pre_write_conversion) + && ! NILP (Ffboundp (coding->pre_write_conversion))) + { + run_pre_write_conversin_on_c_str (&encode_terminal_buf, + &encode_terminal_bufsize, + nchars, nbytes, coding); + nchars = coding->produced_char; + nbytes = coding->produced; + } + required = nbytes + encoding_buffer_size (coding, nbytes); + if (encode_terminal_bufsize < required) + { + encode_terminal_bufsize = required; + encode_terminal_buf = xrealloc (encode_terminal_buf, required); + } + + encode_coding (coding, encode_terminal_buf, encode_terminal_buf + nbytes, + nbytes, encode_terminal_bufsize - nbytes); + return encode_terminal_buf + nbytes; } - void write_glyphs (string, len) register struct glyph *string; register int len; { - int produced, consumed; struct frame *sf = XFRAME (selected_frame); struct frame *f = updating_frame ? updating_frame : sf; - unsigned char conversion_buffer[1024]; - int conversion_buffer_size = sizeof conversion_buffer; + unsigned char *conversion_buffer; + struct coding_system *coding; if (write_glyphs_hook && ! FRAME_TERMCAP_P (f)) @@ -926,17 +948,22 @@ since that would scroll the whole frame on some terminals. */ if (AutoWrap - && curY + 1 == FRAME_HEIGHT (sf) - && (curX + len) == FRAME_WIDTH (sf)) + && curY + 1 == FRAME_LINES (sf) + && (curX + len) == FRAME_COLS (sf)) len --; if (len <= 0) return; cmplus (len); + /* If terminal_coding does any conversion, use it, otherwise use + safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here + because it always return 1 if the member src_multibyte is 1. */ + coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK + ? &terminal_coding : &safe_terminal_coding); /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */ - terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK; + coding->mode &= ~CODING_MODE_LAST_BLOCK; while (len > 0) { @@ -952,49 +979,26 @@ highlight_if_desired (); turn_on_face (f, face_id); - while (n > 0) + if (n == len) + /* This is the last run. */ + coding->mode |= CODING_MODE_LAST_BLOCK; + conversion_buffer = encode_terminal_code (string, n, coding); + if (coding->produced > 0) { - /* We use a fixed size (1024 bytes) of conversion buffer. - Usually it is sufficient, but if not, we just repeat the - loop. */ - produced = encode_terminal_code (string, conversion_buffer, - n, conversion_buffer_size, - &consumed); - if (produced > 0) - { - fwrite (conversion_buffer, 1, produced, stdout); - if (ferror (stdout)) - clearerr (stdout); - if (termscript) - fwrite (conversion_buffer, 1, produced, termscript); - } - len -= consumed; - n -= consumed; - string += consumed; + fwrite (conversion_buffer, 1, coding->produced, stdout); + if (ferror (stdout)) + clearerr (stdout); + if (termscript) + fwrite (conversion_buffer, 1, coding->produced, termscript); } + len -= n; + string += n; /* Turn appearance modes off. */ turn_off_face (f, face_id); turn_off_highlight (); } - /* We may have to output some codes to terminate the writing. */ - if (CODING_REQUIRE_FLUSHING (&terminal_coding)) - { - terminal_coding.mode |= CODING_MODE_LAST_BLOCK; - encode_coding (&terminal_coding, "", conversion_buffer, - 0, conversion_buffer_size); - if (terminal_coding.produced > 0) - { - fwrite (conversion_buffer, 1, terminal_coding.produced, stdout); - if (ferror (stdout)) - clearerr (stdout); - if (termscript) - fwrite (conversion_buffer, 1, terminal_coding.produced, - termscript); - } - } - cmcheckmagic (); } @@ -1008,6 +1012,9 @@ char *buf; struct glyph *glyph = NULL; struct frame *f, *sf; + unsigned char *conversion_buffer; + unsigned char space[1]; + struct coding_system *coding; if (len <= 0) return; @@ -1033,19 +1040,26 @@ turn_on_insert (); cmplus (len); - /* The bit CODING_MODE_LAST_BLOCK should be set to 1 only at the tail. */ - terminal_coding.mode &= ~CODING_MODE_LAST_BLOCK; + + if (! start) + space[0] = SPACEGLYPH; + + /* If terminal_coding does any conversion, use it, otherwise use + safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here + because it always return 1 if the member src_multibyte is 1. */ + coding = (terminal_coding.common_flags & CODING_REQUIRE_ENCODING_MASK + ? &terminal_coding : &safe_terminal_coding); + /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at + the tail. */ + coding->mode &= ~CODING_MODE_LAST_BLOCK; + while (len-- > 0) { - int produced, consumed; - unsigned char conversion_buffer[1024]; - int conversion_buffer_size = sizeof conversion_buffer; - OUTPUT1_IF (TS_ins_char); if (!start) { - conversion_buffer[0] = SPACEGLYPH; - produced = 1; + conversion_buffer = space; + coding->produced = 1; } else { @@ -1063,21 +1077,18 @@ if (len <= 0) /* This is the last glyph. */ - terminal_coding.mode |= CODING_MODE_LAST_BLOCK; - - /* The size of conversion buffer (1024 bytes) is surely - sufficient for just one glyph. */ - produced = encode_terminal_code (glyph, conversion_buffer, 1, - conversion_buffer_size, &consumed); + coding->mode |= CODING_MODE_LAST_BLOCK; + + conversion_buffer = encode_terminal_code (glyph, 1, coding); } - if (produced > 0) + if (coding->produced > 0) { - fwrite (conversion_buffer, 1, produced, stdout); + fwrite (conversion_buffer, 1, coding->produced, stdout); if (ferror (stdout)) clearerr (stdout); if (termscript) - fwrite (conversion_buffer, 1, produced, termscript); + fwrite (conversion_buffer, 1, coding->produced, termscript); } OUTPUT1_IF (TS_pad_inserted_char); @@ -1158,7 +1169,7 @@ as there will be a matching inslines later that will flush them. */ if (scroll_region_ok && vpos + i >= specified_window) return; - if (!memory_below_frame && vpos + i >= FRAME_HEIGHT (sf)) + if (!memory_below_frame && vpos + i >= FRAME_LINES (sf)) return; if (multi) @@ -1193,7 +1204,7 @@ if (!scroll_region_ok && memory_below_frame && n < 0) { - cursor_to (FRAME_HEIGHT (sf) + n, 0); + cursor_to (FRAME_LINES (sf) + n, 0); clear_to_end (); } } @@ -1243,11 +1254,11 @@ #ifndef old /* char_ins_del_cost[n] is cost of inserting N characters. char_ins_del_cost[-n] is cost of deleting N characters. - The length of this vector is based on max_frame_width. */ + The length of this vector is based on max_frame_cols. */ int *char_ins_del_vector; -#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH ((f))]) +#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_COLS ((f))]) #endif /* ARGSUSED */ @@ -1300,7 +1311,7 @@ /* Delete costs are at negative offsets */ p = &char_ins_del_cost (frame)[0]; - for (i = FRAME_WIDTH (frame); --i >= 0;) + for (i = FRAME_COLS (frame); --i >= 0;) *--p = (del_startup_cost += del_cost_per_char); /* Doing nothing is free */ @@ -1308,7 +1319,7 @@ *p++ = 0; /* Insert costs are at positive offsets */ - for (i = FRAME_WIDTH (frame); --i >= 0;) + for (i = FRAME_COLS (frame); --i >= 0;) *p++ = (ins_startup_cost += ins_cost_per_char); } @@ -1330,8 +1341,8 @@ char_ins_del_vector (i.e., char_ins_del_cost) isn't used because X turns off char_ins_del_ok. */ - max_frame_height = max (max_frame_height, FRAME_HEIGHT (frame)); - max_frame_width = max (max_frame_width, FRAME_WIDTH (frame)); + max_frame_lines = max (max_frame_lines, FRAME_LINES (frame)); + max_frame_cols = max (max_frame_cols, FRAME_COLS (frame)); costs_set = 1; @@ -1339,14 +1350,14 @@ char_ins_del_vector = (int *) xrealloc (char_ins_del_vector, (sizeof (int) - + 2 * max_frame_width * sizeof (int))); + + 2 * max_frame_cols * sizeof (int))); else char_ins_del_vector = (int *) xmalloc (sizeof (int) - + 2 * max_frame_width * sizeof (int)); + + 2 * max_frame_cols * sizeof (int)); bzero (char_ins_del_vector, (sizeof (int) - + 2 * max_frame_width * sizeof (int))); + + 2 * max_frame_cols * sizeof (int))); if (f && (!TS_ins_line && !TS_del_line)) do_line_insertion_deletion_costs (frame, @@ -1365,7 +1376,7 @@ if (TS_repeat && per_line_cost (TS_repeat) * baud_rate < 9000) RPov = string_cost (TS_repeat); else - RPov = FRAME_WIDTH (frame) * 2; + RPov = FRAME_COLS (frame) * 2; cmcostinit (); /* set up cursor motion costs */ } @@ -1455,7 +1466,26 @@ {"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; @@ -1600,6 +1630,7 @@ ***********************************************************************/ 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 @@ -1663,9 +1694,14 @@ /* If a hook is installed, let it do the work. */ xassert (it->what == IT_CHARACTER || it->what == IT_COMPOSITION - || it->what == IT_IMAGE || it->what == IT_STRETCH); + if (it->what == IT_STRETCH) + { + produce_stretch_glyph (it); + goto done; + } + /* Nothing but characters are supported on terminal frames. For a composition sequence, it->c is the first character of the sequence. */ @@ -1739,6 +1775,7 @@ append_glyph (it); } + done: /* Advance current_x by the pixel width as a convenience for the caller. */ if (it->area == TEXT_AREA) @@ -1748,6 +1785,81 @@ } +/* 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 (it) + 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->glyph_row) + { + 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->pixel_width = it->len = 1; + while (n--) + append_glyph (it); + it->object = o_object; + it->c = c; + } + it->pixel_width = width; + it->nglyphs = width; +} + + /* Get information about special display element WHAT in an environment described by IT. WHAT is one of IT_TRUNCATION or IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a @@ -1760,6 +1872,7 @@ enum display_element_type what; { struct it temp_it; + GLYPH glyph; temp_it = *it; temp_it.dp = NULL; @@ -1775,15 +1888,11 @@ && 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) { @@ -1792,33 +1901,22 @@ && 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 (); -} - - -/* Return an estimation of the pixel height of mode or top lines on - frame F. FACE_ID specifies what line's height to estimate. */ - -int -estimate_mode_line_height (f, face_id) - struct frame *f; - enum face_id face_id; -{ - if (estimate_mode_line_height_hook) - return estimate_mode_line_height_hook (f, face_id); - else - return 1; + + 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; } @@ -1837,7 +1935,8 @@ ? (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) @@ -1917,18 +2016,20 @@ if (TN_max_colors > 0) { - char *p; - - if (fg >= 0 && TS_set_foreground) + char *ts, *p; + + 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); } @@ -2086,6 +2187,10 @@ tty_setup_colors (mode) int mode; { + /* Canonicalize all negative values of MODE. */ + if (mode < -1) + mode = -1; + switch (mode) { case -1: /* no colors at all */ @@ -2128,7 +2233,7 @@ tty_color_mode_alist = Fintern_soft (build_string ("tty-color-mode-alist"), Qnil); - if (NATNUMP (val)) + if (INTEGERP (val)) color_mode = val; else { @@ -2136,22 +2241,24 @@ color_mode_spec = Qnil; else color_mode_spec = Fassq (val, XSYMBOL (tty_color_mode_alist)->value); - current_mode_spec = assq_no_quit (Qtty_color_mode, f->param_alist); if (CONSP (color_mode_spec)) color_mode = XCDR (color_mode_spec); else color_mode = Qnil; } + + current_mode_spec = assq_no_quit (Qtty_color_mode, f->param_alist); + if (CONSP (current_mode_spec)) current_mode = XCDR (current_mode_spec); else current_mode = Qnil; - if (NATNUMP (color_mode)) + if (INTEGERP (color_mode)) mode = XINT (color_mode); else mode = 0; /* meaning default */ - if (NATNUMP (current_mode)) + if (INTEGERP (current_mode)) old_mode = XINT (current_mode); else old_mode = 0; @@ -2179,11 +2286,14 @@ { char *area; char **address = &area; - char buffer[2044]; + char *buffer = NULL; + int buffer_size = 4096; register char *p; int status; struct frame *sf = XFRAME (selected_frame); + encode_terminal_bufsize = 0; + #ifdef WINDOWSNT initialize_w32_display (); @@ -2191,12 +2301,9 @@ area = (char *) xmalloc (2044); - if (area == 0) - abort (); - - FrameRows = FRAME_HEIGHT (sf); - FrameCols = FRAME_WIDTH (sf); - specified_window = FRAME_HEIGHT (sf); + FrameRows = FRAME_LINES (sf); + FrameCols = FRAME_COLS (sf); + specified_window = FRAME_LINES (sf); delete_in_insert_mode = 1; @@ -2222,6 +2329,7 @@ Wcm_clear (); + buffer = (char *) xmalloc (buffer_size); status = tgetent (buffer, terminal_type); if (status < 0) { @@ -2249,13 +2357,13 @@ terminal_type); #endif } -#ifdef TERMINFO - area = (char *) xmalloc (2044); -#else - area = (char *) xmalloc (strlen (buffer)); -#endif /* not TERMINFO */ - if (area == 0) + +#ifndef TERMINFO + if (strlen (buffer) >= buffer_size) abort (); + buffer_size = strlen (buffer); +#endif + area = (char *) xmalloc (buffer_size); TS_ins_line = tgetstr ("al", address); TS_ins_multi_lines = tgetstr ("AL", address); @@ -2376,21 +2484,21 @@ { int height, width; get_frame_size (&width, &height); - FRAME_WIDTH (sf) = width; - FRAME_HEIGHT (sf) = height; + FRAME_COLS (sf) = width; + FRAME_LINES (sf) = height; } - if (FRAME_WIDTH (sf) <= 0) - SET_FRAME_WIDTH (sf, tgetnum ("co")); + if (FRAME_COLS (sf) <= 0) + SET_FRAME_COLS (sf, tgetnum ("co")); else /* Keep width and external_width consistent */ - SET_FRAME_WIDTH (sf, FRAME_WIDTH (sf)); - if (FRAME_HEIGHT (sf) <= 0) - FRAME_HEIGHT (sf) = tgetnum ("li"); - - if (FRAME_HEIGHT (sf) < 3 || FRAME_WIDTH (sf) < 3) + SET_FRAME_COLS (sf, FRAME_COLS (sf)); + if (FRAME_LINES (sf) <= 0) + FRAME_LINES (sf) = tgetnum ("li"); + + if (FRAME_LINES (sf) < 3 || FRAME_COLS (sf) < 3) fatal ("Screen size %dx%d is too small", - FRAME_HEIGHT (sf), FRAME_WIDTH (sf)); + FRAME_LINES (sf), FRAME_COLS (sf)); min_padding_speed = tgetnum ("pb"); TabWidth = tgetnum ("tw"); @@ -2513,9 +2621,9 @@ } } - FrameRows = FRAME_HEIGHT (sf); - FrameCols = FRAME_WIDTH (sf); - specified_window = FRAME_HEIGHT (sf); + FrameRows = FRAME_LINES (sf); + FrameCols = FRAME_COLS (sf); + specified_window = FRAME_LINES (sf); if (Wcm_init () == -1) /* can't do cursor motion */ #ifdef VMS @@ -2544,8 +2652,8 @@ terminal_type); # endif /* TERMINFO */ #endif /*VMS */ - if (FRAME_HEIGHT (sf) <= 0 - || FRAME_WIDTH (sf) <= 0) + if (FRAME_LINES (sf) <= 0 + || FRAME_COLS (sf) <= 0) fatal ("The frame size has not been specified"); delete_in_insert_mode @@ -2580,6 +2688,8 @@ FRAME_CAN_HAVE_SCROLL_BARS (sf) = 0; FRAME_VERTICAL_SCROLL_BAR_TYPE (sf) = vertical_scroll_bar_none; #endif /* WINDOWSNT */ + + xfree (buffer); } /* VARARGS 1 */ @@ -2594,6 +2704,16 @@ 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 () { @@ -2611,7 +2731,17 @@ 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 + (do not change this comment) */