aboutsummaryrefslogtreecommitdiffstats
path: root/src/term.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/term.c')
-rw-r--r--src/term.c673
1 files changed, 206 insertions, 467 deletions
diff --git a/src/term.c b/src/term.c
index 4baea231de3..1aefe02421f 100644
--- a/src/term.c
+++ b/src/term.c
@@ -1,6 +1,5 @@
1/* Terminal control module for terminals described by TERMCAP 1/* Terminal control module for terminals described by TERMCAP
2 Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1998, 2000, 2001, 2 Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2011
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
5 4
6This file is part of GNU Emacs. 5This file is part of GNU Emacs.
@@ -25,11 +24,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25#include <ctype.h> 24#include <ctype.h>
26#include <errno.h> 25#include <errno.h>
27#include <sys/file.h> 26#include <sys/file.h>
28
29#ifdef HAVE_UNISTD_H
30#include <unistd.h> 27#include <unistd.h>
31#endif
32
33#include <signal.h> 28#include <signal.h>
34#include <stdarg.h> 29#include <stdarg.h>
35#include <setjmp.h> 30#include <setjmp.h>
@@ -66,6 +61,10 @@ extern int tgetent (char *, const char *);
66extern int tgetflag (char *id); 61extern int tgetflag (char *id);
67extern int tgetnum (char *id); 62extern int tgetnum (char *id);
68 63
64char *tparam (char *, char *, int, int, ...);
65
66extern char *tgetstr (char *, char **);
67
69#include "cm.h" 68#include "cm.h"
70#ifdef HAVE_X_WINDOWS 69#ifdef HAVE_X_WINDOWS
71#include "xterm.h" 70#include "xterm.h"
@@ -121,27 +120,11 @@ static void vfatal (const char *str, va_list ap) NO_RETURN;
121 120
122#define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0) 121#define OUTPUT1_IF(tty, a) do { if (a) emacs_tputs ((tty), a, 1, cmputc); } while (0)
123 122
124/* If true, use "vs", otherwise use "ve" to make the cursor visible. */
125
126static int visible_cursor;
127
128/* Display space properties */ 123/* Display space properties */
129 124
130/* Functions to call after suspending a tty. */
131Lisp_Object Vsuspend_tty_functions;
132
133/* Functions to call after resuming a tty. */
134Lisp_Object Vresume_tty_functions;
135
136/* Chain of all tty device parameters. */ 125/* Chain of all tty device parameters. */
137struct tty_display_info *tty_list; 126struct tty_display_info *tty_list;
138 127
139/* Nonzero means no need to redraw the entire frame on resuming a
140 suspended Emacs. This is useful on terminals with multiple
141 pages, where one page is used for Emacs and another for all
142 else. */
143int no_redraw_on_reenter;
144
145/* Meaning of bits in no_color_video. Each bit set means that the 128/* Meaning of bits in no_color_video. Each bit set means that the
146 corresponding attribute cannot be combined with colors. */ 129 corresponding attribute cannot be combined with colors. */
147 130
@@ -172,36 +155,15 @@ int max_frame_lines;
172 should not open a frame on stdout. */ 155 should not open a frame on stdout. */
173static int no_controlling_tty; 156static int no_controlling_tty;
174 157
175/* Provided for lisp packages. */
176
177static int system_uses_terminfo;
178
179char *tparam (char *, char *, int, int, ...);
180
181extern char *tgetstr (char *, char **);
182 158
183 159
184#ifdef HAVE_GPM 160#ifdef HAVE_GPM
185#include <sys/fcntl.h> 161#include <sys/fcntl.h>
186 162
187static void term_clear_mouse_face (void);
188static void term_mouse_highlight (struct frame *f, int x, int y);
189
190/* The device for which we have enabled gpm support (or NULL). */ 163/* The device for which we have enabled gpm support (or NULL). */
191struct tty_display_info *gpm_tty = NULL; 164struct tty_display_info *gpm_tty = NULL;
192 165
193/* These variables describe the range of text currently shown in its 166/* Last recorded mouse coordinates. */
194 mouse-face, together with the window they apply to. As long as
195 the mouse stays within this range, we need not redraw anything on
196 its account. Rows and columns are glyph matrix positions in
197 MOUSE_FACE_WINDOW. */
198static int mouse_face_beg_row, mouse_face_beg_col;
199static int mouse_face_end_row, mouse_face_end_col;
200static int mouse_face_past_end;
201static Lisp_Object mouse_face_window;
202static int mouse_face_face_id;
203
204static int pos_x, pos_y;
205static int last_mouse_x, last_mouse_y; 167static int last_mouse_x, last_mouse_y;
206#endif /* HAVE_GPM */ 168#endif /* HAVE_GPM */
207 169
@@ -1501,6 +1463,8 @@ static void append_glyph (struct it *);
1501static void produce_stretch_glyph (struct it *); 1463static void produce_stretch_glyph (struct it *);
1502static void append_composite_glyph (struct it *); 1464static void append_composite_glyph (struct it *);
1503static void produce_composite_glyph (struct it *); 1465static void produce_composite_glyph (struct it *);
1466static void append_glyphless_glyph (struct it *, int, char *);
1467static void produce_glyphless_glyph (struct it *, int, Lisp_Object);
1504 1468
1505/* Append glyphs to IT's glyph_row. Called from produce_glyphs for 1469/* Append glyphs to IT's glyph_row. Called from produce_glyphs for
1506 terminal frames if IT->glyph_row != NULL. IT->char_to_display is 1470 terminal frames if IT->glyph_row != NULL. IT->char_to_display is
@@ -1609,6 +1573,12 @@ produce_glyphs (struct it *it)
1609 goto done; 1573 goto done;
1610 } 1574 }
1611 1575
1576 if (it->what == IT_GLYPHLESS)
1577 {
1578 produce_glyphless_glyph (it, 0, Qnil);
1579 goto done;
1580 }
1581
1612 if (it->char_to_display >= 040 && it->char_to_display < 0177) 1582 if (it->char_to_display >= 040 && it->char_to_display < 0177)
1613 { 1583 {
1614 it->pixel_width = it->nglyphs = 1; 1584 it->pixel_width = it->nglyphs = 1;
@@ -1660,11 +1630,22 @@ produce_glyphs (struct it *it)
1660 } 1630 }
1661 else 1631 else
1662 { 1632 {
1663 it->pixel_width = CHAR_WIDTH (it->char_to_display); 1633 Lisp_Object charset_list = FRAME_TERMINAL (it->f)->charset_list;
1664 it->nglyphs = it->pixel_width;
1665 1634
1666 if (it->glyph_row) 1635 if (char_charset (it->char_to_display, charset_list, NULL))
1667 append_glyph (it); 1636 {
1637 it->pixel_width = CHAR_WIDTH (it->char_to_display);
1638 it->nglyphs = it->pixel_width;
1639 if (it->glyph_row)
1640 append_glyph (it);
1641 }
1642 else
1643 {
1644 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
1645
1646 xassert (it->what == IT_GLYPHLESS);
1647 produce_glyphless_glyph (it, 1, acronym);
1648 }
1668 } 1649 }
1669 1650
1670 done: 1651 done:
@@ -1844,6 +1825,152 @@ produce_composite_glyph (struct it *it)
1844} 1825}
1845 1826
1846 1827
1828/* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
1829 is a face ID to be used for the glyph. What is actually appended
1830 are glyphs of type CHAR_GLYPH whose characters are in STR (which
1831 comes from it->nglyphs bytes). */
1832
1833static void
1834append_glyphless_glyph (struct it *it, int face_id, char *str)
1835{
1836 struct glyph *glyph, *end;
1837 int i;
1838
1839 xassert (it->glyph_row);
1840 glyph = it->glyph_row->glyphs[it->area] + it->glyph_row->used[it->area];
1841 end = it->glyph_row->glyphs[1 + it->area];
1842
1843 /* If the glyph row is reversed, we need to prepend the glyph rather
1844 than append it. */
1845 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
1846 {
1847 struct glyph *g;
1848 int move_by = it->pixel_width;
1849
1850 /* Make room for the new glyphs. */
1851 if (move_by > end - glyph) /* don't overstep end of this area */
1852 move_by = end - glyph;
1853 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
1854 g[move_by] = *g;
1855 glyph = it->glyph_row->glyphs[it->area];
1856 end = glyph + move_by;
1857 }
1858
1859 if (glyph >= end)
1860 return;
1861 glyph->type = CHAR_GLYPH;
1862 glyph->pixel_width = 1;
1863 glyph->face_id = face_id;
1864 glyph->padding_p = 0;
1865 glyph->charpos = CHARPOS (it->position);
1866 glyph->object = it->object;
1867 if (it->bidi_p)
1868 {
1869 glyph->resolved_level = it->bidi_it.resolved_level;
1870 if ((it->bidi_it.type & 7) != it->bidi_it.type)
1871 abort ();
1872 glyph->bidi_type = it->bidi_it.type;
1873 }
1874 else
1875 {
1876 glyph->resolved_level = 0;
1877 glyph->bidi_type = UNKNOWN_BT;
1878 }
1879
1880 /* BIDI Note: we put the glyphs of characters left to right, even in
1881 the REVERSED_P case because we write to the terminal
1882 left-to-right. */
1883 for (i = 0; i < it->nglyphs && glyph < end; ++i)
1884 {
1885 if (i > 0)
1886 glyph[0] = glyph[-1];
1887 glyph->u.ch = str[i];
1888 ++it->glyph_row->used[it->area];
1889 ++glyph;
1890 }
1891}
1892
1893/* Produce glyphs for a glyphless character for iterator IT.
1894 IT->glyphless_method specifies which method to use for displaying
1895 the character. See the description of enum
1896 glyphless_display_method in dispextern.h for the details.
1897
1898 FOR_NO_FONT is nonzero if and only if this is for a character that
1899 is not supproted by the coding system of the terminal. ACRONYM, if
1900 non-nil, is an acronym string for the character.
1901
1902 The glyphs actually produced are of type CHAR_GLYPH. */
1903
1904static void
1905produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym)
1906{
1907 int face_id;
1908 int len;
1909 char buf[9], *str = " ";
1910
1911 /* Get a face ID for the glyph by utilizing a cache (the same way as
1912 done for `escape-glyph' in get_next_display_element). */
1913 if (it->f == last_glyphless_glyph_frame
1914 && it->face_id == last_glyphless_glyph_face_id)
1915 {
1916 face_id = last_glyphless_glyph_merged_face_id;
1917 }
1918 else
1919 {
1920 /* Merge the `glyphless-char' face into the current face. */
1921 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
1922 last_glyphless_glyph_frame = it->f;
1923 last_glyphless_glyph_face_id = it->face_id;
1924 last_glyphless_glyph_merged_face_id = face_id;
1925 }
1926
1927 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
1928 {
1929 /* As there's no way to produce a thin space, we produce a space
1930 of canonical width. */
1931 len = 1;
1932 }
1933 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
1934 {
1935 len = CHAR_WIDTH (it->c);
1936 if (len == 0)
1937 len = 1;
1938 else if (len > 4)
1939 len = 4;
1940 sprintf (buf, "[%.*s]", len, str);
1941 len += 2;
1942 str = buf;
1943 }
1944 else
1945 {
1946 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
1947 {
1948 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
1949 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
1950 buf[0] = '[';
1951 str = STRINGP (acronym) ? SSDATA (acronym) : "";
1952 for (len = 0; len < 6 && str[len] && ASCII_BYTE_P (str[len]); len++)
1953 buf[1 + len] = str[len];
1954 buf[1 + len] = ']';
1955 len += 2;
1956 }
1957 else
1958 {
1959 xassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
1960 len = (it->c < 0x10000 ? sprintf (buf, "\\u%04X", it->c)
1961 : it->c <= MAX_UNICODE_CHAR ? sprintf (buf, "\\U%06X", it->c)
1962 : sprintf (buf, "\\x%06X", it->c));
1963 }
1964 str = buf;
1965 }
1966
1967 it->pixel_width = len;
1968 it->nglyphs = len;
1969 if (len > 0 && it->glyph_row)
1970 append_glyphless_glyph (it, face_id, str);
1971}
1972
1973
1847/* Get information about special display element WHAT in an 1974/* Get information about special display element WHAT in an
1848 environment described by IT. WHAT is one of IT_TRUNCATION or 1975 environment described by IT. WHAT is one of IT_TRUNCATION or
1849 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a 1976 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
@@ -2517,416 +2644,36 @@ term_mouse_moveto (int x, int y)
2517 last_mouse_y = y; */ 2644 last_mouse_y = y; */
2518} 2645}
2519 2646
2520static void 2647/* Implementation of draw_row_with_mouse_face for TTY/GPM. */
2521term_show_mouse_face (enum draw_glyphs_face draw) 2648void
2649tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
2650 int start_hpos, int end_hpos,
2651 enum draw_glyphs_face draw)
2522{ 2652{
2523 struct window *w = XWINDOW (mouse_face_window); 2653 int nglyphs = end_hpos - start_hpos;
2524 int save_x, save_y; 2654 struct frame *f = XFRAME (WINDOW_FRAME (w));
2525 int i;
2526
2527 struct frame *f = XFRAME (w->frame);
2528 struct tty_display_info *tty = FRAME_TTY (f); 2655 struct tty_display_info *tty = FRAME_TTY (f);
2656 int face_id = tty->mouse_highlight.mouse_face_face_id;
2657 int save_x, save_y, pos_x, pos_y;
2529 2658
2530 if (/* If window is in the process of being destroyed, don't bother 2659 if (end_hpos >= row->used[TEXT_AREA])
2531 to do anything. */ 2660 nglyphs = row->used[TEXT_AREA] - start_hpos;
2532 w->current_matrix != NULL
2533 /* Recognize when we are called to operate on rows that don't exist
2534 anymore. This can happen when a window is split. */
2535 && mouse_face_end_row < w->current_matrix->nrows)
2536 {
2537 /* write_glyphs writes at cursor position, so we need to
2538 temporarily move cursor coordinates to the beginning of
2539 the highlight region. */
2540
2541 /* Save current cursor co-ordinates */
2542 save_y = curY (tty);
2543 save_x = curX (tty);
2544 2661
2545 /* Note that mouse_face_beg_row etc. are window relative. */ 2662 pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
2546 for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++) 2663 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w);
2547 {
2548 int start_hpos, end_hpos, nglyphs;
2549 struct glyph_row *row = MATRIX_ROW (w->current_matrix, i);
2550 2664
2551 /* Don't do anything if row doesn't have valid contents. */ 2665 /* Save current cursor co-ordinates. */
2552 if (!row->enabled_p) 2666 save_y = curY (tty);
2553 continue; 2667 save_x = curX (tty);
2668 cursor_to (f, pos_y, pos_x);
2554 2669
2555 /* For all but the first row, the highlight starts at column 0. */ 2670 if (draw == DRAW_MOUSE_FACE)
2556 if (i == mouse_face_beg_row) 2671 tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos,
2557 start_hpos = mouse_face_beg_col; 2672 nglyphs, face_id);
2558 else 2673 else if (draw == DRAW_NORMAL_TEXT)
2559 start_hpos = 0; 2674 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
2560 2675
2561 if (i == mouse_face_end_row) 2676 cursor_to (f, save_y, save_x);
2562 end_hpos = mouse_face_end_col;
2563 else
2564 {
2565 end_hpos = row->used[TEXT_AREA];
2566 if (draw == DRAW_NORMAL_TEXT)
2567 row->fill_line_p = 1; /* Clear to end of line */
2568 }
2569
2570 if (end_hpos <= start_hpos)
2571 continue;
2572 /* Record that some glyphs of this row are displayed in
2573 mouse-face. */
2574 row->mouse_face_p = draw > 0;
2575
2576 nglyphs = end_hpos - start_hpos;
2577
2578 if (end_hpos >= row->used[TEXT_AREA])
2579 nglyphs = row->used[TEXT_AREA] - start_hpos;
2580
2581 pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
2582 pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos
2583 + WINDOW_LEFT_EDGE_X (w);
2584
2585 cursor_to (f, pos_y, pos_x);
2586
2587 if (draw == DRAW_MOUSE_FACE)
2588 {
2589 tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos,
2590 nglyphs, mouse_face_face_id);
2591 }
2592 else /* draw == DRAW_NORMAL_TEXT */
2593 write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs);
2594 }
2595 cursor_to (f, save_y, save_x);
2596 }
2597}
2598
2599static void
2600term_clear_mouse_face (void)
2601{
2602 if (!NILP (mouse_face_window))
2603 term_show_mouse_face (DRAW_NORMAL_TEXT);
2604
2605 mouse_face_beg_row = mouse_face_beg_col = -1;
2606 mouse_face_end_row = mouse_face_end_col = -1;
2607 mouse_face_window = Qnil;
2608}
2609
2610/* Find the glyph matrix position of buffer position POS in window W.
2611 *HPOS and *VPOS are set to the positions found. W's current glyphs
2612 must be up to date. If POS is above window start return (0, 0).
2613 If POS is after end of W, return end of last line in W.
2614 - taken from msdos.c */
2615static int
2616fast_find_position (struct window *w, EMACS_INT pos, int *hpos, int *vpos)
2617{
2618 int i, lastcol, maybe_next_line_p = 0;
2619 EMACS_INT line_start_position;
2620 int yb = window_text_bottom_y (w);
2621 struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row;
2622
2623 while (row->y < yb)
2624 {
2625 if (row->used[TEXT_AREA])
2626 line_start_position = row->glyphs[TEXT_AREA]->charpos;
2627 else
2628 line_start_position = 0;
2629
2630 if (line_start_position > pos)
2631 break;
2632 /* If the position sought is the end of the buffer,
2633 don't include the blank lines at the bottom of the window. */
2634 else if (line_start_position == pos
2635 && pos == BUF_ZV (XBUFFER (w->buffer)))
2636 {
2637 maybe_next_line_p = 1;
2638 break;
2639 }
2640 else if (line_start_position > 0)
2641 best_row = row;
2642
2643 /* Don't overstep the last matrix row, lest we get into the
2644 never-never land... */
2645 if (row->y + 1 >= yb)
2646 break;
2647
2648 ++row;
2649 }
2650
2651 /* Find the right column within BEST_ROW. */
2652 lastcol = 0;
2653 row = best_row;
2654 for (i = 0; i < row->used[TEXT_AREA]; i++)
2655 {
2656 struct glyph *glyph = row->glyphs[TEXT_AREA] + i;
2657 EMACS_INT charpos;
2658
2659 charpos = glyph->charpos;
2660 if (charpos == pos)
2661 {
2662 *hpos = i;
2663 *vpos = row->y;
2664 return 1;
2665 }
2666 else if (charpos > pos)
2667 break;
2668 else if (charpos > 0)
2669 lastcol = i;
2670 }
2671
2672 /* If we're looking for the end of the buffer,
2673 and we didn't find it in the line we scanned,
2674 use the start of the following line. */
2675 if (maybe_next_line_p)
2676 {
2677 ++row;
2678 lastcol = 0;
2679 }
2680
2681 *vpos = row->y;
2682 *hpos = lastcol + 1;
2683 return 0;
2684}
2685
2686static void
2687term_mouse_highlight (struct frame *f, int x, int y)
2688{
2689 enum window_part part;
2690 Lisp_Object window;
2691 struct window *w;
2692 struct buffer *b;
2693
2694 if (NILP (Vmouse_highlight)
2695 || !f->glyphs_initialized_p)
2696 return;
2697
2698 /* Which window is that in? */
2699 window = window_from_coordinates (f, x, y, &part, &x, &y, 0);
2700
2701 /* Not on a window -> return. */
2702 if (!WINDOWP (window))
2703 return;
2704
2705 if (!EQ (window, mouse_face_window))
2706 term_clear_mouse_face ();
2707
2708 w = XWINDOW (window);
2709
2710 /* Are we in a window whose display is up to date?
2711 And verify the buffer's text has not changed. */
2712 b = XBUFFER (w->buffer);
2713 if (part == ON_TEXT
2714 && EQ (w->window_end_valid, w->buffer)
2715 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
2716 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
2717 {
2718 int i, nrows = w->current_matrix->nrows;
2719 EMACS_INT pos;
2720 struct glyph_row *row;
2721 struct glyph *glyph;
2722
2723 /* Find the glyph under X/Y. */
2724 glyph = NULL;
2725 if (y >= 0 && y < nrows)
2726 {
2727 row = MATRIX_ROW (w->current_matrix, y);
2728 /* Give up if some row before the one we are looking for is
2729 not enabled. */
2730 for (i = 0; i <= y; i++)
2731 if (!MATRIX_ROW (w->current_matrix, i)->enabled_p)
2732 break;
2733 if (i > y /* all rows upto and including the one at Y are enabled */
2734 && row->displays_text_p
2735 && x < window_box_width (w, TEXT_AREA))
2736 {
2737 glyph = row->glyphs[TEXT_AREA];
2738 if (x >= row->used[TEXT_AREA])
2739 glyph = NULL;
2740 else
2741 {
2742 glyph += x;
2743 if (!BUFFERP (glyph->object))
2744 glyph = NULL;
2745 }
2746 }
2747 }
2748
2749 /* Clear mouse face if X/Y not over text. */
2750 if (glyph == NULL)
2751 {
2752 term_clear_mouse_face ();
2753 return;
2754 }
2755
2756 if (!BUFFERP (glyph->object))
2757 abort ();
2758 pos = glyph->charpos;
2759
2760 /* Check for mouse-face. */
2761 {
2762 Lisp_Object mouse_face, overlay, position, *overlay_vec;
2763 int noverlays;
2764 EMACS_INT obegv, ozv;
2765 struct buffer *obuf;
2766
2767 /* If we get an out-of-range value, return now; avoid an error. */
2768 if (pos > BUF_Z (b))
2769 return;
2770
2771 /* Make the window's buffer temporarily current for
2772 overlays_at and compute_char_face. */
2773 obuf = current_buffer;
2774 current_buffer = b;
2775 obegv = BEGV;
2776 ozv = ZV;
2777 BEGV = BEG;
2778 ZV = Z;
2779
2780 /* Is this char mouse-active? */
2781 XSETINT (position, pos);
2782
2783 /* Put all the overlays we want in a vector in overlay_vec. */
2784 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
2785 /* Sort overlays into increasing priority order. */
2786 noverlays = sort_overlays (overlay_vec, noverlays, w);
2787
2788 /* Check mouse-face highlighting. */
2789 if (!(EQ (window, mouse_face_window)
2790 && y >= mouse_face_beg_row
2791 && y <= mouse_face_end_row
2792 && (y > mouse_face_beg_row
2793 || x >= mouse_face_beg_col)
2794 && (y < mouse_face_end_row
2795 || x < mouse_face_end_col
2796 || mouse_face_past_end)))
2797 {
2798 /* Clear the display of the old active region, if any. */
2799 term_clear_mouse_face ();
2800
2801 /* Find the highest priority overlay that has a mouse-face
2802 property. */
2803 overlay = Qnil;
2804 for (i = noverlays - 1; i >= 0; --i)
2805 {
2806 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
2807 if (!NILP (mouse_face))
2808 {
2809 overlay = overlay_vec[i];
2810 break;
2811 }
2812 }
2813
2814 /* If no overlay applies, get a text property. */
2815 if (NILP (overlay))
2816 mouse_face = Fget_text_property (position, Qmouse_face,
2817 w->buffer);
2818
2819 /* Handle the overlay case. */
2820 if (!NILP (overlay))
2821 {
2822 /* Find the range of text around this char that
2823 should be active. */
2824 Lisp_Object before, after;
2825 EMACS_INT ignore;
2826
2827
2828 before = Foverlay_start (overlay);
2829 after = Foverlay_end (overlay);
2830 /* Record this as the current active region. */
2831 fast_find_position (w, XFASTINT (before),
2832 &mouse_face_beg_col,
2833 &mouse_face_beg_row);
2834
2835 mouse_face_past_end
2836 = !fast_find_position (w, XFASTINT (after),
2837 &mouse_face_end_col,
2838 &mouse_face_end_row);
2839 mouse_face_window = window;
2840
2841 mouse_face_face_id
2842 = face_at_buffer_position (w, pos, 0, 0,
2843 &ignore, pos + 1, 1, -1);
2844
2845 /* Display it as active. */
2846 term_show_mouse_face (DRAW_MOUSE_FACE);
2847 }
2848 /* Handle the text property case. */
2849 else if (!NILP (mouse_face))
2850 {
2851 /* Find the range of text around this char that
2852 should be active. */
2853 Lisp_Object before, after, beginning, end;
2854 EMACS_INT ignore;
2855
2856 beginning = Fmarker_position (w->start);
2857 XSETINT (end, (BUF_Z (b) - XFASTINT (w->window_end_pos)));
2858 before
2859 = Fprevious_single_property_change (make_number (pos + 1),
2860 Qmouse_face,
2861 w->buffer, beginning);
2862 after
2863 = Fnext_single_property_change (position, Qmouse_face,
2864 w->buffer, end);
2865
2866 /* Record this as the current active region. */
2867 fast_find_position (w, XFASTINT (before),
2868 &mouse_face_beg_col,
2869 &mouse_face_beg_row);
2870 mouse_face_past_end
2871 = !fast_find_position (w, XFASTINT (after),
2872 &mouse_face_end_col,
2873 &mouse_face_end_row);
2874 mouse_face_window = window;
2875
2876 mouse_face_face_id
2877 = face_at_buffer_position (w, pos, 0, 0,
2878 &ignore, pos + 1, 1, -1);
2879
2880 /* Display it as active. */
2881 term_show_mouse_face (DRAW_MOUSE_FACE);
2882 }
2883 }
2884
2885 /* Look for a `help-echo' property. */
2886 {
2887 Lisp_Object help;
2888
2889 /* Check overlays first. */
2890 help = Qnil;
2891 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
2892 {
2893 overlay = overlay_vec[i];
2894 help = Foverlay_get (overlay, Qhelp_echo);
2895 }
2896
2897 if (!NILP (help))
2898 {
2899 help_echo_string = help;
2900 help_echo_window = window;
2901 help_echo_object = overlay;
2902 help_echo_pos = pos;
2903 }
2904 /* Try text properties. */
2905 else if (NILP (help)
2906 && ((STRINGP (glyph->object)
2907 && glyph->charpos >= 0
2908 && glyph->charpos < SCHARS (glyph->object))
2909 || (BUFFERP (glyph->object)
2910 && glyph->charpos >= BEGV
2911 && glyph->charpos < ZV)))
2912 {
2913 help = Fget_text_property (make_number (glyph->charpos),
2914 Qhelp_echo, glyph->object);
2915 if (!NILP (help))
2916 {
2917 help_echo_string = help;
2918 help_echo_window = window;
2919 help_echo_object = glyph->object;
2920 help_echo_pos = glyph->charpos;
2921 }
2922 }
2923 }
2924
2925 BEGV = obegv;
2926 ZV = ozv;
2927 current_buffer = obuf;
2928 }
2929 }
2930} 2677}
2931 2678
2932static int 2679static int
@@ -2936,7 +2683,7 @@ term_mouse_movement (FRAME_PTR frame, Gpm_Event *event)
2936 if (event->x != last_mouse_x || event->y != last_mouse_y) 2683 if (event->x != last_mouse_x || event->y != last_mouse_y)
2937 { 2684 {
2938 frame->mouse_moved = 1; 2685 frame->mouse_moved = 1;
2939 term_mouse_highlight (frame, event->x, event->y); 2686 note_mouse_highlight (frame, event->x, event->y);
2940 /* Remember which glyph we're now on. */ 2687 /* Remember which glyph we're now on. */
2941 last_mouse_x = event->x; 2688 last_mouse_x = event->x;
2942 last_mouse_y = event->y; 2689 last_mouse_y = event->y;
@@ -3309,8 +3056,7 @@ static void
3309dissociate_if_controlling_tty (int fd) 3056dissociate_if_controlling_tty (int fd)
3310{ 3057{
3311#ifndef DOS_NT 3058#ifndef DOS_NT
3312 int pgid; 3059 int pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */
3313 EMACS_GET_TTY_PGRP (fd, &pgid); /* If tcgetpgrp succeeds, fd is the ctty. */
3314 if (pgid != -1) 3060 if (pgid != -1)
3315 { 3061 {
3316#if defined (USG5) 3062#if defined (USG5)
@@ -3407,10 +3153,10 @@ init_tty (const char *name, const char *terminal_type, int must_succeed)
3407 3153
3408#ifdef HAVE_GPM 3154#ifdef HAVE_GPM
3409 terminal->mouse_position_hook = term_mouse_position; 3155 terminal->mouse_position_hook = term_mouse_position;
3410 mouse_face_window = Qnil; 3156 tty->mouse_highlight.mouse_face_window = Qnil;
3411#endif 3157#endif
3412 3158
3413 3159
3414#ifndef DOS_NT 3160#ifndef DOS_NT
3415 set_tty_hooks (terminal); 3161 set_tty_hooks (terminal);
3416 3162
@@ -4003,7 +3749,7 @@ mark_ttys (void)
4003void 3749void
4004syms_of_term (void) 3750syms_of_term (void)
4005{ 3751{
4006 DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo, 3752 DEFVAR_BOOL ("system-uses-terminfo", system_uses_terminfo,
4007 doc: /* Non-nil means the system uses terminfo rather than termcap. 3753 doc: /* Non-nil means the system uses terminfo rather than termcap.
4008This variable can be used by terminal emulator packages. */); 3754This variable can be used by terminal emulator packages. */);
4009#ifdef TERMINFO 3755#ifdef TERMINFO
@@ -4012,20 +3758,20 @@ This variable can be used by terminal emulator packages. */);
4012 system_uses_terminfo = 0; 3758 system_uses_terminfo = 0;
4013#endif 3759#endif
4014 3760
4015 DEFVAR_LISP ("suspend-tty-functions", &Vsuspend_tty_functions, 3761 DEFVAR_LISP ("suspend-tty-functions", Vsuspend_tty_functions,
4016 doc: /* Functions to be run after suspending a tty. 3762 doc: /* Functions to be run after suspending a tty.
4017The functions are run with one argument, the terminal object to be suspended. 3763The functions are run with one argument, the terminal object to be suspended.
4018See `suspend-tty'. */); 3764See `suspend-tty'. */);
4019 Vsuspend_tty_functions = Qnil; 3765 Vsuspend_tty_functions = Qnil;
4020 3766
4021 3767
4022 DEFVAR_LISP ("resume-tty-functions", &Vresume_tty_functions, 3768 DEFVAR_LISP ("resume-tty-functions", Vresume_tty_functions,
4023 doc: /* Functions to be run after resuming a tty. 3769 doc: /* Functions to be run after resuming a tty.
4024The functions are run with one argument, the terminal object that was revived. 3770The functions are run with one argument, the terminal object that was revived.
4025See `resume-tty'. */); 3771See `resume-tty'. */);
4026 Vresume_tty_functions = Qnil; 3772 Vresume_tty_functions = Qnil;
4027 3773
4028 DEFVAR_BOOL ("visible-cursor", &visible_cursor, 3774 DEFVAR_BOOL ("visible-cursor", visible_cursor,
4029 doc: /* Non-nil means to make the cursor very visible. 3775 doc: /* Non-nil means to make the cursor very visible.
4030This only has an effect when running in a text terminal. 3776This only has an effect when running in a text terminal.
4031What means \"very visible\" is up to your terminal. It may make the cursor 3777What means \"very visible\" is up to your terminal. It may make the cursor
@@ -4042,8 +3788,6 @@ bigger, or it may make it blink, or it may do nothing at all. */);
4042#ifdef HAVE_GPM 3788#ifdef HAVE_GPM
4043 defsubr (&Sgpm_mouse_start); 3789 defsubr (&Sgpm_mouse_start);
4044 defsubr (&Sgpm_mouse_stop); 3790 defsubr (&Sgpm_mouse_stop);
4045
4046 staticpro (&mouse_face_window);
4047#endif /* HAVE_GPM */ 3791#endif /* HAVE_GPM */
4048 3792
4049#ifndef DOS_NT 3793#ifndef DOS_NT
@@ -4055,8 +3799,3 @@ bigger, or it may make it blink, or it may do nothing at all. */);
4055 encode_terminal_src = NULL; 3799 encode_terminal_src = NULL;
4056 encode_terminal_dst = NULL; 3800 encode_terminal_dst = NULL;
4057} 3801}
4058
4059
4060
4061/* arch-tag: 498e7449-6f2e-45e2-91dd-b7d4ca488193
4062 (do not change this comment) */