Mercurial > emacs
diff src/term.c @ 111413:d53ee71e7e89
Unify mouse-highlight code for all GUI and TTY sessions.
term.c: Remove static mouse_face_* variables. All users
changed.
(term_show_mouse_face, term_clear_mouse_face)
(fast_find_position, term_mouse_highlight): Functions deleted.
(tty_draw_row_with_mouse_face): New function.
(term_mouse_movement): Call note_mouse_highlight instead of
term_mouse_highlight.
nsterm.m (ns_update_window_begin, ns_update_window_end)
(ns_update_end, x_destroy_window, ns_frame_up_to_date)
(ns_dumpglyphs_box_or_relief, ns_maybe_dumpglyphs_background)
(ns_dumpglyphs_image, ns_dumpglyphs_stretch)
(ns_initialize_display_info, keyDown, mouseMoved, mouseExited):
Replace Display_Info with Mouse_HLInfo everywhere where
mouse_face_* members were accessed for mouse highlight purposes.
xterm.c (x_update_window_begin, x_update_window_end)
(x_update_end, XTframe_up_to_date, x_set_mouse_face_gc)
(handle_one_xevent, x_free_frame_resources, x_term_init): Replace
Display_Info with Mouse_HLInfo everywhere where mouse_face_*
members were accessed for mouse highlight purposes.
w32term.c (x_update_window_begin, x_update_window_end)
(x_update_end, w32_read_socket, x_free_frame_resources)
(w32_initialize_display_info): Replace Display_Info with
Mouse_HLInfo everywhere where mouse_face_* members were accessed
for mouse highlight purposes.
xdisp.c (show_mouse_face, note_mode_line_or_margin_highlight)
(note_mouse_highlight) [HAVE_WINDOW_SYSTEM]: Don't run GUI code
unless the frame is on a window-system.
(get_tool_bar_item, handle_tool_bar_click)
(note_tool_bar_highlight, draw_glyphs, erase_phys_cursor)
(show_mouse_face, clear_mouse_face, coords_in_mouse_face_p)
(note_mode_line_or_margin_highlight, note_mouse_highlight)
(x_clear_window_mouse_face, cancel_mouse_face, expose_frame):
Replace Display_Info with Mouse_HLInfo everywhere where
mouse_face_* members were accessed for mouse highlight purposes.
(coords_in_mouse_face_p): Move prototype out of the
HAVE_WINDOW_SYSTEM conditional.
(x_y_to_hpos_vpos, frame_to_window_pixel_xy): Move out of the
HAVE_WINDOW_SYSTEM block.
(try_window_id) [HAVE_GPM || MSDOS]: Call
x_clear_window_mouse_face.
(draw_row_with_mouse_face): Implementation for HAVE_WINDOW_SYSTEM
systems. Call tty_draw_row_with_mouse_face for TTY systems.
(show_mouse_face): Call draw_row_with_mouse_face, instead of
calling draw_glyphs directly.
(show_mouse_face, clear_mouse_face, coords_in_mouse_face_p)
(cursor_in_mouse_face_p, rows_from_pos_range)
(mouse_face_from_buffer_pos, mouse_face_from_string_pos)
(note_mode_line_or_margin_highlight, note_mouse_highlight)
(x_clear_window_mouse_face, cancel_mouse_face): Move out of the
HAVE_WINDOW_SYSTEM block. Ifdef away window-system specific
fragments.
(note_mouse_highlight): Call popup_activated for MSDOS as well.
Clear mouse highlight if pointer is over glyphs whose OBJECT is an
integer.
(mouse_face_from_buffer_pos): Add parentheses around && within ||.
(x_consider_frame_title, tool_bar_lines_needed): Move
prototypes to HAVE_WINDOW_SYSTEM-only part.
(get_window_cursor_type): Move inside a HAVE_WINDOW_SYSTEM-only
part. Remove "#ifdef HAVE_WINDOW_SYSTEM" from body of function.
(null_glyph_slice): Move declaration into HAVE_WINDOW_SYSTEM-only
part.
dispnew.c (mirror_make_current): Set Y coordinate of the
mode-line and header-line rows.
(init_display): Setup initial frame's output_data for text
terminal frames.
xmenu.c (popup_activated): Don't define on MSDOS, which now has
its own definition on msdos.c.
msdos.c (show_mouse_face, clear_mouse_face)
(fast_find_position, IT_note_mode_line_highlight)
(IT_note_mouse_highlight): Functions deleted.
(IT_frame_up_to_date, dos_rawgetc): Call note_mouse_highlight
instead of IT_note_mouse_highlight.
(draw_row_with_mouse_face, popup_activated): New functions.
(dos_set_window_size, draw_row_with_mouse_face, IT_update_begin)
(IT_update_end, IT_frame_up_to_date, internal_terminal_init)
(dos_rawgetc): Replace Display_Info with Mouse_HLInfo everywhere
where mouse_face_* members were accessed for mouse highlight
purposes.
msdos.h (initialize_msdos_display): Add prototype.
frame.h (MOUSE_HL_INFO): New macro.
lisp.h (Mouse_HLInfo): New data type.
xterm.h (struct x_display_info):
w32term.h (struct w32_display_info):
nsterm.h (struct ns_display_info):
termchar.h (struct tty_display_info): Use it instead of
mouse_face_* members.
dispextern.h (show_mouse_face, clear_mouse_face): Update type of
1st argument.
(frame_to_window_pixel_xy, note_mouse_highlight)
(x_clear_window_mouse_face, cancel_mouse_face, clear_mouse_face)
(show_mouse_face, cursor_in_mouse_face_p): Move prototypes out of
HAVE_WINDOW_SYSTEM conditional.
(draw_row_with_mouse_face): Declare prototype.
(tty_draw_row_with_mouse_face): Declare prototype.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Sat, 06 Nov 2010 10:28:31 +0200 |
parents | 717c8af799d3 f168d8610334 |
children | 5c986eef8f0d |
line wrap: on
line diff
--- a/src/term.c Fri Nov 05 15:30:18 2010 -0400 +++ b/src/term.c Sat Nov 06 10:28:31 2010 +0200 @@ -184,24 +184,10 @@ #ifdef HAVE_GPM #include <sys/fcntl.h> -static void term_clear_mouse_face (void); -static void term_mouse_highlight (struct frame *f, int x, int y); - /* The device for which we have enabled gpm support (or NULL). */ struct tty_display_info *gpm_tty = NULL; -/* These variables describe the range of text currently shown in its - mouse-face, together with the window they apply to. As long as - the mouse stays within this range, we need not redraw anything on - its account. Rows and columns are glyph matrix positions in - MOUSE_FACE_WINDOW. */ -static int mouse_face_beg_row, mouse_face_beg_col; -static int mouse_face_end_row, mouse_face_end_col; -static int mouse_face_past_end; -static Lisp_Object mouse_face_window; -static int mouse_face_face_id; - -static int pos_x, pos_y; +/* Last recorded mouse coordinates. */ static int last_mouse_x, last_mouse_y; #endif /* HAVE_GPM */ @@ -2686,416 +2672,36 @@ last_mouse_y = y; */ } -static void -term_show_mouse_face (enum draw_glyphs_face draw) -{ - struct window *w = XWINDOW (mouse_face_window); - int save_x, save_y; - int i; - - struct frame *f = XFRAME (w->frame); - struct tty_display_info *tty = FRAME_TTY (f); - - if (/* If window is in the process of being destroyed, don't bother - to do anything. */ - w->current_matrix != NULL - /* Recognize when we are called to operate on rows that don't exist - anymore. This can happen when a window is split. */ - && mouse_face_end_row < w->current_matrix->nrows) - { - /* write_glyphs writes at cursor position, so we need to - temporarily move cursor coordinates to the beginning of - the highlight region. */ - - /* Save current cursor co-ordinates */ - save_y = curY (tty); - save_x = curX (tty); - - /* Note that mouse_face_beg_row etc. are window relative. */ - for (i = mouse_face_beg_row; i <= mouse_face_end_row; i++) - { - int start_hpos, end_hpos, nglyphs; - struct glyph_row *row = MATRIX_ROW (w->current_matrix, i); - - /* Don't do anything if row doesn't have valid contents. */ - if (!row->enabled_p) - continue; - - /* For all but the first row, the highlight starts at column 0. */ - if (i == mouse_face_beg_row) - start_hpos = mouse_face_beg_col; - else - start_hpos = 0; - - if (i == mouse_face_end_row) - end_hpos = mouse_face_end_col; - else - { - end_hpos = row->used[TEXT_AREA]; - if (draw == DRAW_NORMAL_TEXT) - row->fill_line_p = 1; /* Clear to end of line */ - } - - if (end_hpos <= start_hpos) - continue; - /* Record that some glyphs of this row are displayed in - mouse-face. */ - row->mouse_face_p = draw > 0; - - nglyphs = end_hpos - start_hpos; - - if (end_hpos >= row->used[TEXT_AREA]) - nglyphs = row->used[TEXT_AREA] - start_hpos; - - pos_y = row->y + WINDOW_TOP_EDGE_Y (w); - pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos - + WINDOW_LEFT_EDGE_X (w); - - cursor_to (f, pos_y, pos_x); - - if (draw == DRAW_MOUSE_FACE) - { - tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos, - nglyphs, mouse_face_face_id); - } - else /* draw == DRAW_NORMAL_TEXT */ - write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); - } - cursor_to (f, save_y, save_x); - } -} - -static void -term_clear_mouse_face (void) -{ - if (!NILP (mouse_face_window)) - term_show_mouse_face (DRAW_NORMAL_TEXT); - - mouse_face_beg_row = mouse_face_beg_col = -1; - mouse_face_end_row = mouse_face_end_col = -1; - mouse_face_window = Qnil; -} - -/* Find the glyph matrix position of buffer position POS in window W. - *HPOS and *VPOS are set to the positions found. W's current glyphs - must be up to date. If POS is above window start return (0, 0). - If POS is after end of W, return end of last line in W. - - taken from msdos.c */ -static int -fast_find_position (struct window *w, EMACS_INT pos, int *hpos, int *vpos) -{ - int i, lastcol, maybe_next_line_p = 0; - EMACS_INT line_start_position; - int yb = window_text_bottom_y (w); - struct glyph_row *row = MATRIX_ROW (w->current_matrix, 0), *best_row = row; - - while (row->y < yb) - { - if (row->used[TEXT_AREA]) - line_start_position = row->glyphs[TEXT_AREA]->charpos; - else - line_start_position = 0; - - if (line_start_position > pos) - break; - /* If the position sought is the end of the buffer, - don't include the blank lines at the bottom of the window. */ - else if (line_start_position == pos - && pos == BUF_ZV (XBUFFER (w->buffer))) - { - maybe_next_line_p = 1; - break; - } - else if (line_start_position > 0) - best_row = row; - - /* Don't overstep the last matrix row, lest we get into the - never-never land... */ - if (row->y + 1 >= yb) - break; - - ++row; - } - - /* Find the right column within BEST_ROW. */ - lastcol = 0; - row = best_row; - for (i = 0; i < row->used[TEXT_AREA]; i++) - { - struct glyph *glyph = row->glyphs[TEXT_AREA] + i; - EMACS_INT charpos; - - charpos = glyph->charpos; - if (charpos == pos) - { - *hpos = i; - *vpos = row->y; - return 1; - } - else if (charpos > pos) - break; - else if (charpos > 0) - lastcol = i; - } - - /* If we're looking for the end of the buffer, - and we didn't find it in the line we scanned, - use the start of the following line. */ - if (maybe_next_line_p) - { - ++row; - lastcol = 0; - } - - *vpos = row->y; - *hpos = lastcol + 1; - return 0; -} - -static void -term_mouse_highlight (struct frame *f, int x, int y) +/* Implementation of draw_row_with_mouse_face for TTY/GPM. */ +void +tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, + int start_hpos, int end_hpos, + enum draw_glyphs_face draw) { - enum window_part part; - Lisp_Object window; - struct window *w; - struct buffer *b; - - if (NILP (Vmouse_highlight) - || !f->glyphs_initialized_p) - return; - - /* Which window is that in? */ - window = window_from_coordinates (f, x, y, &part, &x, &y, 0); - - /* Not on a window -> return. */ - if (!WINDOWP (window)) - return; - - if (!EQ (window, mouse_face_window)) - term_clear_mouse_face (); - - w = XWINDOW (window); - - /* Are we in a window whose display is up to date? - And verify the buffer's text has not changed. */ - b = XBUFFER (w->buffer); - if (part == ON_TEXT - && EQ (w->window_end_valid, w->buffer) - && XFASTINT (w->last_modified) == BUF_MODIFF (b) - && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b)) - { - int i, nrows = w->current_matrix->nrows; - EMACS_INT pos; - struct glyph_row *row; - struct glyph *glyph; - - /* Find the glyph under X/Y. */ - glyph = NULL; - if (y >= 0 && y < nrows) - { - row = MATRIX_ROW (w->current_matrix, y); - /* Give up if some row before the one we are looking for is - not enabled. */ - for (i = 0; i <= y; i++) - if (!MATRIX_ROW (w->current_matrix, i)->enabled_p) - break; - if (i > y /* all rows upto and including the one at Y are enabled */ - && row->displays_text_p - && x < window_box_width (w, TEXT_AREA)) - { - glyph = row->glyphs[TEXT_AREA]; - if (x >= row->used[TEXT_AREA]) - glyph = NULL; - else - { - glyph += x; - if (!BUFFERP (glyph->object)) - glyph = NULL; - } - } - } - - /* Clear mouse face if X/Y not over text. */ - if (glyph == NULL) - { - term_clear_mouse_face (); - return; - } - - if (!BUFFERP (glyph->object)) - abort (); - pos = glyph->charpos; - - /* Check for mouse-face. */ - { - Lisp_Object mouse_face, overlay, position, *overlay_vec; - int noverlays; - EMACS_INT obegv, ozv; - struct buffer *obuf; - - /* If we get an out-of-range value, return now; avoid an error. */ - if (pos > BUF_Z (b)) - return; - - /* Make the window's buffer temporarily current for - overlays_at and compute_char_face. */ - obuf = current_buffer; - current_buffer = b; - obegv = BEGV; - ozv = ZV; - BEGV = BEG; - ZV = Z; - - /* Is this char mouse-active? */ - XSETINT (position, pos); - - /* Put all the overlays we want in a vector in overlay_vec. */ - GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0); - /* Sort overlays into increasing priority order. */ - noverlays = sort_overlays (overlay_vec, noverlays, w); - - /* Check mouse-face highlighting. */ - if (!(EQ (window, mouse_face_window) - && y >= mouse_face_beg_row - && y <= mouse_face_end_row - && (y > mouse_face_beg_row - || x >= mouse_face_beg_col) - && (y < mouse_face_end_row - || x < mouse_face_end_col - || mouse_face_past_end))) - { - /* Clear the display of the old active region, if any. */ - term_clear_mouse_face (); - - /* Find the highest priority overlay that has a mouse-face - property. */ - overlay = Qnil; - for (i = noverlays - 1; i >= 0; --i) - { - mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face); - if (!NILP (mouse_face)) - { - overlay = overlay_vec[i]; - break; - } - } - - /* If no overlay applies, get a text property. */ - if (NILP (overlay)) - mouse_face = Fget_text_property (position, Qmouse_face, - w->buffer); - - /* Handle the overlay case. */ - if (!NILP (overlay)) - { - /* Find the range of text around this char that - should be active. */ - Lisp_Object before, after; - EMACS_INT ignore; - - - before = Foverlay_start (overlay); - after = Foverlay_end (overlay); - /* Record this as the current active region. */ - fast_find_position (w, XFASTINT (before), - &mouse_face_beg_col, - &mouse_face_beg_row); - - mouse_face_past_end - = !fast_find_position (w, XFASTINT (after), - &mouse_face_end_col, - &mouse_face_end_row); - mouse_face_window = window; - - mouse_face_face_id - = face_at_buffer_position (w, pos, 0, 0, - &ignore, pos + 1, 1, -1); - - /* Display it as active. */ - term_show_mouse_face (DRAW_MOUSE_FACE); - } - /* Handle the text property case. */ - else if (!NILP (mouse_face)) - { - /* Find the range of text around this char that - should be active. */ - Lisp_Object before, after, beginning, end; - EMACS_INT ignore; - - beginning = Fmarker_position (w->start); - XSETINT (end, (BUF_Z (b) - XFASTINT (w->window_end_pos))); - before - = Fprevious_single_property_change (make_number (pos + 1), - Qmouse_face, - w->buffer, beginning); - after - = Fnext_single_property_change (position, Qmouse_face, - w->buffer, end); - - /* Record this as the current active region. */ - fast_find_position (w, XFASTINT (before), - &mouse_face_beg_col, - &mouse_face_beg_row); - mouse_face_past_end - = !fast_find_position (w, XFASTINT (after), - &mouse_face_end_col, - &mouse_face_end_row); - mouse_face_window = window; - - mouse_face_face_id - = face_at_buffer_position (w, pos, 0, 0, - &ignore, pos + 1, 1, -1); - - /* Display it as active. */ - term_show_mouse_face (DRAW_MOUSE_FACE); - } - } - - /* Look for a `help-echo' property. */ - { - Lisp_Object help; - - /* Check overlays first. */ - help = Qnil; - for (i = noverlays - 1; i >= 0 && NILP (help); --i) - { - overlay = overlay_vec[i]; - help = Foverlay_get (overlay, Qhelp_echo); - } - - if (!NILP (help)) - { - help_echo_string = help; - help_echo_window = window; - help_echo_object = overlay; - help_echo_pos = pos; - } - /* Try text properties. */ - else if (NILP (help) - && ((STRINGP (glyph->object) - && glyph->charpos >= 0 - && glyph->charpos < SCHARS (glyph->object)) - || (BUFFERP (glyph->object) - && glyph->charpos >= BEGV - && glyph->charpos < ZV))) - { - help = Fget_text_property (make_number (glyph->charpos), - Qhelp_echo, glyph->object); - if (!NILP (help)) - { - help_echo_string = help; - help_echo_window = window; - help_echo_object = glyph->object; - help_echo_pos = glyph->charpos; - } - } - } - - BEGV = obegv; - ZV = ozv; - current_buffer = obuf; - } - } + int nglyphs = end_hpos - start_hpos; + struct frame *f = XFRAME (WINDOW_FRAME (w)); + struct tty_display_info *tty = FRAME_TTY (f); + int face_id = tty->mouse_highlight.mouse_face_face_id; + int save_x, save_y, pos_x, pos_y; + + if (end_hpos >= row->used[TEXT_AREA]) + nglyphs = row->used[TEXT_AREA] - start_hpos; + + pos_y = row->y + WINDOW_TOP_EDGE_Y (w); + pos_x = row->used[LEFT_MARGIN_AREA] + start_hpos + WINDOW_LEFT_EDGE_X (w); + + /* Save current cursor co-ordinates. */ + save_y = curY (tty); + save_x = curX (tty); + cursor_to (f, pos_y, pos_x); + + if (draw == DRAW_MOUSE_FACE) + tty_write_glyphs_with_face (f, row->glyphs[TEXT_AREA] + start_hpos, + nglyphs, face_id); + else if (draw == DRAW_NORMAL_TEXT) + write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); + + cursor_to (f, save_y, save_x); } static int @@ -3105,7 +2711,7 @@ if (event->x != last_mouse_x || event->y != last_mouse_y) { frame->mouse_moved = 1; - term_mouse_highlight (frame, event->x, event->y); + note_mouse_highlight (frame, event->x, event->y); /* Remember which glyph we're now on. */ last_mouse_x = event->x; last_mouse_y = event->y; @@ -3576,7 +3182,7 @@ #ifdef HAVE_GPM terminal->mouse_position_hook = term_mouse_position; - mouse_face_window = Qnil; + tty->mouse_highlight.mouse_face_window = Qnil; #endif @@ -4211,8 +3817,6 @@ #ifdef HAVE_GPM defsubr (&Sgpm_mouse_start); defsubr (&Sgpm_mouse_stop); - - staticpro (&mouse_face_window); #endif /* HAVE_GPM */ #ifndef DOS_NT