Commit 442a09ea authored by Kim F. Storm's avatar Kim F. Storm
Browse files

* xterm.c: Remove consolidated defines and code.

(BETWEEN): Remove unused macro.
(x_draw_vertical_window_border, x_shift_glyphs_for_insert)
(x_define_frame_cursor, x_clear_frame_area)
(x_draw_window_cursor): New X-specific functions for RIF.
(x_redisplay_interface): Add new members.
parent 3d970f28
......@@ -158,46 +158,20 @@ extern void _XEditResCheckMessages ();
#define abs(x) ((x) < 0 ? -(x) : (x))
#define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
extern Lisp_Object Qhelp_echo;
/* Non-nil means Emacs uses toolkit scroll bars. */
Lisp_Object Vx_toolkit_scroll_bars;
/* If a string, XTread_socket generates an event to display that string.
(The display is done in read_char.) */
static Lisp_Object help_echo;
static Lisp_Object help_echo_window;
static Lisp_Object help_echo_object;
static int help_echo_pos;
/* Temporary variable for XTread_socket. */
static Lisp_Object previous_help_echo;
/* Non-zero means that a HELP_EVENT has been generated since Emacs
start. */
static int any_help_event_p;
/* Non-zero means autoselect window with the mouse cursor. */
int mouse_autoselect_window;
/* Last window where we saw the mouse. Used by mouse-autoselect-window. */
static Lisp_Object last_window;
/* Non-zero means draw block and hollow cursor as wide as the glyph
under it. For example, if a block cursor is over a tab, it will be
drawn as wide as that tab on the display. */
int x_stretch_cursor_p;
/* Non-zero means make use of UNDERLINE_POSITION font properties. */
int x_use_underline_position_properties;
......@@ -231,12 +205,6 @@ XtAppContext Xt_app_con;
static String Xt_default_resources[] = {0};
#endif /* USE_X_TOOLKIT */
/* Nominal cursor position -- where to draw output.
HPOS and VPOS are window relative glyph matrix coordinates.
X and Y are window relative pixel coordinates. */
struct cursor_pos output_cursor;
/* Non-zero means user is interacting with a toolkit scroll bar. */
static int toolkit_scroll_bar_interaction;
......@@ -263,7 +231,6 @@ static int toolkit_scroll_bar_interaction;
/* Where the mouse was last time we reported a mouse event. */
FRAME_PTR last_mouse_frame;
static XRectangle last_mouse_glyph;
static Lisp_Object last_mouse_press_frame;
......@@ -333,30 +300,13 @@ extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
extern Lisp_Object x_icon_type P_ ((struct frame *));
static int cursor_in_mouse_face_p P_ ((struct window *));
static int clear_mouse_face P_ ((struct x_display_info *));
static int x_alloc_nearest_color_1 P_ ((Display *, Colormap, XColor *));
static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
static const XColor *x_color_cells P_ ((Display *, int *));
static void x_update_window_end P_ ((struct window *, int, int));
static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
void x_delete_display P_ ((struct x_display_info *));
static unsigned int x_x_to_emacs_modifiers P_ ((struct x_display_info *,
static int fast_find_position P_ ((struct window *, int, int *, int *,
int *, int *, Lisp_Object));
static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object,
int *, int *, int *, int *, int));
static void set_output_cursor P_ ((struct cursor_pos *));
static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int,
int *, int *, int *, int));
static void note_mode_line_or_margin_highlight P_ ((struct window *, int,
int, int));
static void note_mouse_highlight P_ ((struct frame *, int, int));
static void note_tool_bar_highlight P_ ((struct frame *f, int, int));
static void x_handle_tool_bar_click P_ ((struct frame *, XButtonEvent *));
static void show_mouse_face P_ ((struct x_display_info *,
enum draw_glyphs_face));
static int x_io_error_quitter P_ ((Display *));
int x_catch_errors P_ ((Display *));
void x_uncatch_errors P_ ((Display *, int));
......@@ -371,18 +321,11 @@ void x_wm_set_icon_pixmap P_ ((struct frame *, int));
void x_initialize P_ ((void));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
static int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_draw_phys_cursor_glyph P_ ((struct window *,
struct glyph_row *,
enum draw_glyphs_face));
static void x_update_end P_ ((struct frame *));
static void XTframe_up_to_date P_ ((struct frame *));
static void XTset_terminal_modes P_ ((void));
static void XTreset_terminal_modes P_ ((void));
static void XTcursor_to P_ ((int, int, int, int));
static void x_write_glyphs P_ ((struct glyph *, int));
static void x_clear_end_of_line P_ ((int));
static void x_clear_frame P_ ((void));
static void x_clear_cursor P_ ((struct window *));
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
......@@ -401,29 +344,12 @@ static void x_frame_rehighlight P_ ((struct x_display_info *));
static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int,
enum text_cursor_kinds));
static int x_intersect_rectangles P_ ((XRectangle *, XRectangle *,
XRectangle *));
static void expose_frame P_ ((struct frame *, int, int, int, int));
static int expose_window_tree P_ ((struct window *, XRectangle *));
static void expose_overlaps P_ ((struct window *, struct glyph_row *,
struct glyph_row *));
static int expose_window P_ ((struct window *, XRectangle *));
static void expose_area P_ ((struct window *, struct glyph_row *,
XRectangle *, enum glyph_row_area));
static int expose_line P_ ((struct window *, struct glyph_row *,
XRectangle *));
static void x_update_cursor_in_window_tree P_ ((struct window *, int));
static void x_update_window_cursor P_ ((struct window *, int));
static void x_erase_phys_cursor P_ ((struct window *));
void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
static void x_clip_to_row P_ ((struct window *, struct glyph_row *,
GC, int));
static int x_phys_cursor_in_rect_p P_ ((struct window *, XRectangle *));
static void x_flush P_ ((struct frame *f));
static void x_update_begin P_ ((struct frame *));
static void x_update_window_begin P_ ((struct window *));
static void x_draw_vertical_border P_ ((struct window *));
static void x_after_update_window_line P_ ((struct glyph_row *));
static INLINE void take_vertical_position_into_account P_ ((struct it *));
static struct scroll_bar *x_window_to_scroll_bar P_ ((Window));
......@@ -596,34 +522,19 @@ x_update_window_begin (w)
/* Draw a vertical window border to the right of window W if W doesn't
have vertical scroll bars. */
/* Draw a vertical window border from (x,y0) to (x,y1) */
static void
x_draw_vertical_border (w)
x_draw_vertical_window_border (w, x, y0, y1)
struct window *w;
int x, y0, y1;
struct frame *f = XFRAME (WINDOW_FRAME (w));
/* Redraw borders between horizontally adjacent windows. Don't
do it for frames with vertical scroll bars because either the
right scroll bar of a window, or the left scroll bar of its
neighbor will suffice as a border. */
int x0, x1, y0, y1;
window_box_edges (w, -1, &x0, &y0, &x1, &y1);
y1 -= 1;
f->output_data.x->normal_gc, x1, y0, x1, y1);
f->output_data.x->normal_gc, x, y0, x, y1);
/* End update of window W (which is equal to updated_window).
Draw vertical borders between horizontally adjacent windows, and
......@@ -649,9 +560,9 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
if (cursor_on_p)
x_display_and_set_cursor (w, 1, output_cursor.hpos,
output_cursor.x, output_cursor.y);
display_and_set_cursor (w, 1, output_cursor.hpos,
output_cursor.x, output_cursor.y);
x_draw_vertical_border (w);
......@@ -680,9 +591,11 @@ x_update_end (f)
/* Mouse highlight may be displayed again. */
FRAME_X_DISPLAY_INFO (f)->mouse_face_defer = 0;
#ifndef XFlush
......@@ -841,65 +754,6 @@ XTreset_terminal_modes ()
Output Cursor
/* Set the global variable output_cursor to CURSOR. All cursor
positions are relative to updated_window. */
static void
set_output_cursor (cursor)
struct cursor_pos *cursor;
output_cursor.hpos = cursor->hpos;
output_cursor.vpos = cursor->vpos;
output_cursor.x = cursor->x;
output_cursor.y = cursor->y;
/* Set a nominal cursor position.
HPOS and VPOS are column/row positions in a window glyph matrix. X
and Y are window text area relative pixel positions.
If this is done during an update, updated_window will contain the
window that is being updated and the position is the future output
cursor position for that window. If updated_window is null, use
selected_window and display the cursor at the given position. */
static void
XTcursor_to (vpos, hpos, y, x)
int vpos, hpos, y, x;
struct window *w;
/* If updated_window is not set, work on selected_window. */
if (updated_window)
w = updated_window;
w = XWINDOW (selected_window);
/* Set the output cursor. */
output_cursor.hpos = hpos;
output_cursor.vpos = vpos;
output_cursor.x = x;
output_cursor.y = y;
/* If not called as part of an update, really display the cursor.
This will also set the cursor position of W. */
if (updated_window == NULL)
x_display_cursor (w, 1, hpos, vpos, x, y);
Display Iterator
......@@ -1046,33 +900,6 @@ x_encode_char (c, char2b, font_info, two_byte_p)
/* Estimate the pixel height of the mode or top line on frame F.
FACE_ID specifies what line's height to estimate. */
x_estimate_mode_line_height (f, face_id)
struct frame *f;
enum face_id face_id;
int height = FONT_HEIGHT (FRAME_FONT (f));
/* This function is called so early when Emacs starts that the face
cache and mode line face are not yet initialized. */
struct face *face = FACE_FROM_ID (f, face_id);
if (face)
if (face->font)
height = FONT_HEIGHT (face->font);
if (face->box_line_width > 0)
height += 2 * face->box_line_width;
return height;
Glyph display
......@@ -1107,8 +934,6 @@ static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int,
int, int, int, int, XRectangle *));
static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
int, int, int, XRectangle *));
static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
enum glyph_row_area));
static void x_check_font P_ ((struct frame *, XFontStruct *));
......@@ -1281,74 +1106,6 @@ x_set_glyph_string_gc (s)
/* Return in *R the clipping rectangle for glyph string S. */
static void
x_get_glyph_string_clip_rect (s, r)
struct glyph_string *s;
XRectangle *r;
if (s->row->full_width_p)
/* Draw full-width. X coordinates are relative to S->w->left. */
int canon_x = CANON_X_UNIT (s->f);
r->x = WINDOW_LEFT_MARGIN (s->w) * canon_x;
r->width = XFASTINT (s->w->width) * canon_x;
int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
r->x -= width;
/* Unless displaying a mode or menu bar line, which are always
fully visible, clip to the visible part of the row. */
if (s->w->pseudo_window_p)
r->height = s->row->visible_height;
r->height = s->height;
/* This is a text line that may be partially visible. */
r->x = WINDOW_AREA_TO_FRAME_PIXEL_X (s->w, s->area, 0);
r->width = window_box_width (s->w, s->area);
r->height = s->row->visible_height;
/* If S draws overlapping rows, it's sufficient to use the top and
bottom of the window for clipping because this glyph string
intentionally draws over other lines. */
if (s->for_overlaps_p)
r->height = window_text_bottom_y (s->w) - r->y;
/* Don't use S->y for clipping because it doesn't take partially
visible lines into account. For example, it can be negative for
partially visible lines at the top of a window. */
if (!s->row->full_width_p
r->y = max (0, s->row->y);
/* If drawing a tool-bar window, draw it over the internal border
at the top of the window. */
if (s->w == XWINDOW (s->f->tool_bar_window))
r->y -= s->f->output_data.x->internal_border_width;
r->y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->y);
/* Set clipping for output of glyph string S. S may be part of a mode
line or menu if we don't have X toolkit support. */
......@@ -1357,7 +1114,7 @@ x_set_glyph_string_clipping (s)
struct glyph_string *s;
XRectangle r;
x_get_glyph_string_clip_rect (s, &r);
get_glyph_string_clip_rect (s, &r);
XSetClipRectangles (s->display, s->gc, 0, 0, &r, 1, Unsorted);
......@@ -2349,7 +2106,7 @@ x_draw_glyph_string_box (s)
&& (s->next == NULL
|| s->next->hl != s->hl)));
x_get_glyph_string_clip_rect (s, &clip_rect);
get_glyph_string_clip_rect (s, &clip_rect);
if (s->face->box == FACE_SIMPLE_BOX)
x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
......@@ -2405,7 +2162,7 @@ x_draw_image_foreground (s)
xgcv.function = GXcopy;
XChangeGC (s->display, s->gc, mask, &xgcv);
x_get_glyph_string_clip_rect (s, &clip_rect);
get_glyph_string_clip_rect (s, &clip_rect);
image_rect.x = x;
image_rect.y = y;
image_rect.width = s->img->width;
......@@ -2418,7 +2175,7 @@ x_draw_image_foreground (s)
XRectangle clip_rect, image_rect, r;
x_get_glyph_string_clip_rect (s, &clip_rect);
get_glyph_string_clip_rect (s, &clip_rect);
image_rect.x = x;
image_rect.y = y;
image_rect.width = s->img->width;
......@@ -2491,7 +2248,7 @@ x_draw_image_relief (s)
y1 = y + s->img->height + thick - 1;
x_setup_relief_colors (s);
x_get_glyph_string_clip_rect (s, &r);
get_glyph_string_clip_rect (s, &r);
x_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
......@@ -2733,7 +2490,7 @@ x_draw_stretch_glyph_string (s)
gc = s->face->gc;
x_get_glyph_string_clip_rect (s, &r);
get_glyph_string_clip_rect (s, &r);
XSetClipRectangles (s->display, gc, 0, 0, &r, 1, Unsorted);
if (s->face->stipple)
......@@ -2920,149 +2677,19 @@ x_draw_glyph_string (s)
XSetClipMask (s->display, s->gc, None);
/* Shift display to make room for inserted glyphs. */
/* Fix the display of area AREA of overlapping row ROW in window W. */
static void
x_fix_overlapping_area (w, row, area)
struct window *w;
struct glyph_row *row;
enum glyph_row_area area;
int i, x;
if (area == LEFT_MARGIN_AREA)
x = 0;
else if (area == TEXT_AREA)
x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
x = (window_box_width (w, LEFT_MARGIN_AREA)
+ window_box_width (w, TEXT_AREA));
for (i = 0; i < row->used[area];)
if (row->glyphs[area][i].overlaps_vertically_p)
int start = i, start_x = x;
x += row->glyphs[area][i].pixel_width;
while (i < row->used[area]
&& row->glyphs[area][i].overlaps_vertically_p);
x_draw_glyphs (w, start_x, row, area, start, i,
x += row->glyphs[area][i].pixel_width;
/* Output LEN glyphs starting at START at the nominal cursor position.
Advance the nominal cursor over the text. The global variable
updated_window contains the window being updated, updated_row is
the glyph row being updated, and updated_area is the area of that
row being updated. */
static void
x_write_glyphs (start, len)
struct glyph *start;
int len;
int x, hpos;
xassert (updated_window && updated_row);
/* Write glyphs. */
hpos = start - updated_row->glyphs[updated_area];
x = x_draw_glyphs (updated_window, output_cursor.x,
updated_row, updated_area,
hpos, hpos + len,
/* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
if (updated_area == TEXT_AREA
&& updated_window->phys_cursor_on_p
&& updated_window->phys_cursor.vpos == output_cursor.vpos
&& updated_window->phys_cursor.hpos >= hpos
&& updated_window->phys_cursor.hpos < hpos + len)
updated_window->phys_cursor_on_p = 0;
/* Advance the output cursor. */
output_cursor.hpos += len;
output_cursor.x = x;
/* Insert LEN glyphs from START at the nominal cursor position. */
static void
x_insert_glyphs (start, len)
struct glyph *start;
register int len;
x_shift_glyphs_for_insert (f, x, y, width, height, shift_by)
struct frame *f;
int x, y, width, height, shift_by;
struct frame *f;
struct window *w;
int line_height, shift_by_width, shifted_region_width;
struct glyph_row *row;
struct glyph *glyph;
int frame_x, frame_y, hpos;
xassert (updated_window && updated_row);
w = updated_window;
/* Get the height of the line we are in. */
row = updated_row;
line_height = row->height;
/* Get the width of the glyphs to insert. */
shift_by_width = 0;
for (glyph = start; glyph < start + len; ++glyph)
shift_by_width += glyph->pixel_width;
/* Get the width of the region to shift right. */
shifted_region_width = (window_box_width (w, updated_area)
- output_cursor.x
- shift_by_width);
/* Shift right. */
frame_x = window_box_left (w, updated_area) + output_cursor.x;
frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
frame_x, frame_y,
shifted_region_width, line_height,
frame_x + shift_by_width, frame_y);
/* Write the glyphs. */
hpos = start - row->glyphs[updated_area];
x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
/* Advance the output cursor. */
output_cursor.hpos += len;
output_cursor.x += shift_by_width;
x, y, width, height,
x + shift_by, y);
/* Delete N glyphs at the nominal cursor position. Not implemented
for X frames. */
......@@ -3090,84 +2717,6 @@ x_clear_area (dpy, window, x, y, width, height, exposures)
/* Erase the current text line from the nominal cursor position
(inclusive) to pixel column TO_X (exclusive). The idea is that
everything from TO_X onward is already erased.
TO_X is a pixel position relative to updated_area of
updated_window. TO_X == -1 means clear to the end of this area. */
static void
x_clear_end_of_line (to_x)
int to_x;
struct frame *f;
struct window *w = updated_window;
int max_x, min_y, max_y;
int from_x, from_y, to_y;
xassert (updated_window && updated_row);
f = XFRAME (w->frame);
if (updated_row->full_width_p)
max_x = XFASTINT (w->width) * CANON_X_UNIT (f);
&& !w->pseudo_window_p)
max_x = window_box_width (w, updated_area);
max_y = window_text_bottom_y (w);
/* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
of window. For TO_X > 0, truncate to end of drawing area. */
if (to_x == 0)
else if (to_x < 0)
to_x = max_x;
to_x = min (to_x, max_x);
to_y = min (max_y, output_cursor.y + updated_row->height);
/* Notice if the cursor will be cleared by this operation. */
if (!updated_row->full_width_p)
notice_overwritten_cursor (w, updated_area,
output_cursor.x, -1,
MATRIX_ROW_BOTTOM_Y (updated_row));
from_x = output_cursor.x;
/* Translate to frame coordinates. */
if (updated_row->full_width_p)
from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
from_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, from_x);
to_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, updated_area, to_x);
from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
/* Prevent inadvertently clearing to end of the X window. */
if (to_x > from_x && to_y > from_y)
x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
from_x, from_y, to_x - from_x, to_y - from_y,