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

* w32term.c: Remove consolidated defines and code.

(BETWEEN): Remove unused macro.
(w32_draw_vertical_window_border, w32_shift_glyphs_for_insert)
(w32_define_frame_cursor, w32_clear_frame_area)
(w32_draw_window_cursor): New W32-specific functions for RIF.
(w32_redisplay_interface): Add new members.
parent d165fbde
......@@ -59,30 +59,17 @@ Boston, MA 02111-1307, USA. */
#define abs(x) ((x) < 0 ? -(x) : (x))
#define BETWEEN(X, LOWER, UPPER) ((X) >= (LOWER) && (X) < (UPPER))
/* Fringe bitmaps. */
static HBITMAP fringe_bmp[MAX_FRINGE_BITMAPS];
extern Lisp_Object Qhelp_echo;
/* Non-nil means Emacs uses toolkit scroll bars. */
Lisp_Object Vx_toolkit_scroll_bars;
/* If a string, w32_read_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 variables for w32_read_socket. */
static Lisp_Object previous_help_echo;
static int last_mousemove_x = 0;
static int last_mousemove_y = 0;
......@@ -91,23 +78,9 @@ static int last_mousemove_y = 0;
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;
extern unsigned int msh_mousewheel;
extern void free_frame_menubar ();
......@@ -143,12 +116,6 @@ extern struct frame *updating_frame;
/* This is a frame waiting to be autoraised, within w32_read_socket. */
struct frame *pending_autoraise_frame;
/* 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;
/* The handle of the frame that currently owns the system caret. */
HWND w32_system_caret_hwnd;
int w32_system_caret_height;
......@@ -202,7 +169,6 @@ int last_scroll_bar_drag_pos;
/* Where the mouse was last time we reported a mouse event. */
FRAME_PTR last_mouse_frame;
static RECT last_mouse_glyph;
static Lisp_Object last_mouse_press_frame;
......@@ -261,25 +227,9 @@ extern int errno;
extern EMACS_INT extra_keyboard_modifiers;
static void x_update_window_end P_ ((struct window *, int, int));
static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
void w32_delete_display P_ ((struct w32_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 w32_handle_tool_bar_click P_ ((struct frame *,
struct input_event *));
static void show_mouse_face P_ ((struct w32_display_info *,
enum draw_glyphs_face));
static int cursor_in_mouse_face_p P_ ((struct window *));
static int clear_mouse_face P_ ((struct w32_display_info *));
void w32_define_cursor P_ ((Window, Cursor));
void x_lower_frame P_ ((struct frame *));
......@@ -292,18 +242,11 @@ void x_wm_set_icon_pixmap P_ ((struct frame *, int));
void w32_initialize P_ ((void));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
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 w32_frame_up_to_date P_ ((struct frame *));
static void w32_set_terminal_modes P_ ((void));
static void w32_reset_terminal_modes P_ ((void));
static void w32_cursor_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 w32_display_info *,
......@@ -313,24 +256,8 @@ static void x_frame_rehighlight P_ ((struct w32_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 void expose_frame P_ ((struct frame *, int, int, int, int));
static int expose_window_tree P_ ((struct window *, RECT *));
static void expose_overlaps P_ ((struct window *, struct glyph_row *,
struct glyph_row *));
static int expose_window P_ ((struct window *, RECT *));
static void expose_area P_ ((struct window *, struct glyph_row *,
RECT *, enum glyph_row_area));
static int expose_line P_ ((struct window *, struct glyph_row *,
RECT *));
void x_update_cursor P_ ((struct frame *, int));
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_cursor P_ ((struct window *w, int, int, int, int, int));
void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int));
static void w32_clip_to_row P_ ((struct window *, struct glyph_row *,
HDC, int));
static int x_phys_cursor_in_rect_p P_ ((struct window *, RECT *));
static Lisp_Object Qvendor_specific_keysyms;
......@@ -557,36 +484,25 @@ x_update_window_begin (w)
UNBLOCK_INPUT;
}
/* 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)
w32_draw_vertical_window_border (w, x, y0, y1)
struct window *w;
int x, y0, y1;
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
RECT r;
HDC hdc;
r.left = x;
r.right = x + 1;
r.top = y0;
r.bottom = y1;
/* 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. */
if (!WINDOW_RIGHTMOST_P (w)
&& !FRAME_HAS_VERTICAL_SCROLL_BARS (f))
{
RECT r;
HDC hdc;
window_box_edges (w, -1, (int *) &r.left, (int *) &r.top,
(int *) &r.right, (int *) &r.bottom);
r.left = r.right + FRAME_X_RIGHT_FRINGE_WIDTH (f);
r.right = r.left + 1;
r.bottom -= 1;
hdc = get_frame_dc (f);
w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
release_frame_dc (f, hdc);
}
hdc = get_frame_dc (f);
w32_fill_rect (f, hdc, FRAME_FOREGROUND_PIXEL (f), &r);
release_frame_dc (f, hdc);
}
......@@ -608,17 +524,16 @@ x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
struct window *w;
int cursor_on_p, mouse_face_overwritten_p;
{
struct w32_display_info *dpyinfo
= FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
if (!w->pseudo_window_p)
{
BLOCK_INPUT;
if (cursor_on_p)
x_display_and_set_cursor (w, 1, output_cursor.hpos,
output_cursor.vpos,
output_cursor.x, output_cursor.y);
display_and_set_cursor (w, 1, output_cursor.hpos,
output_cursor.vpos,
output_cursor.x, output_cursor.y);
x_draw_vertical_border (w);
UNBLOCK_INPUT;
......@@ -671,6 +586,7 @@ w32_frame_up_to_date (f)
if (FRAME_W32_P (f))
{
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
if (dpyinfo->mouse_face_deferred_gc
|| f == dpyinfo->mouse_face_mouse_frame)
{
......@@ -725,6 +641,7 @@ x_after_update_window_line (desired_row)
height > 0))
{
int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
/* Internal border is drawn below the tool bar. */
if (WINDOWP (f->tool_bar_window)
&& w == XWINDOW (f->tool_bar_window))
......@@ -816,64 +733,6 @@ w32_reset_terminal_modes (void)
}
/***********************************************************************
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
w32_cursor_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;
else
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)
{
BLOCK_INPUT;
x_display_cursor (w, 1, hpos, vpos, x, y);
UNBLOCK_INPUT;
}
}
/***********************************************************************
Display Iterator
......@@ -1231,33 +1090,6 @@ w32_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. */
int
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. */
if (FRAME_FACE_CACHE (f))
{
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
......@@ -1312,8 +1144,6 @@ static void w32_draw_relief_rect P_ ((struct frame *, int, int, int, int,
int, int, int, int, RECT *));
static void w32_draw_box_rect P_ ((struct glyph_string *, int, int, int, int,
int, int, int, RECT *));
static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *,
enum glyph_row_area));
#if GLYPH_DEBUG
static void x_check_font P_ ((struct frame *, XFontStruct *));
......@@ -1484,91 +1314,6 @@ x_set_glyph_string_gc (s)
}
/* Return in *R the clipping rectangle for glyph string S. */
static void
w32_get_glyph_string_clip_rect (s, r)
struct glyph_string *s;
RECT *r;
{
int r_height, r_width;
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->left = WINDOW_LEFT_MARGIN (s->w) * canon_x;
r_width = XFASTINT (s->w->width) * canon_x;
if (FRAME_HAS_VERTICAL_SCROLL_BARS (s->f))
{
int width = FRAME_SCROLL_BAR_WIDTH (s->f) * canon_x;
if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (s->f))
r->left -= width;
}
r->left += FRAME_INTERNAL_BORDER_WIDTH (s->f);
/* 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;
else
r_height = s->height;
}
else
{
/* This is a text line that may be partially visible. */
r->left = 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->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
r_height = window_text_bottom_y (s->w) - r->top;
}
else
{
/* 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
&& MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
r->top = WINDOW_DISPLAY_HEADER_LINE_HEIGHT (s->w);
else
r->top = 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->top -= s->f->output_data.w32->internal_border_width;
}
r->top = WINDOW_TO_FRAME_PIXEL_Y (s->w, r->top);
/* If drawing the cursor, don't let glyph draw outside its
advertised boundaries. Cleartype does this under some circumstances. */
if (s->hl == DRAW_CURSOR)
{
if (s->x > r->left)
{
r_width -= s->x - r->left;
r->left = s->x;
}
r_width = min (r_width, s->first_glyph->pixel_width);
}
r->bottom = r->top + r_height;
r->right = r->left + r_width;
}
/* 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. */
......@@ -1577,7 +1322,7 @@ x_set_glyph_string_clipping (s)
struct glyph_string *s;
{
RECT r;
w32_get_glyph_string_clip_rect (s, &r);
get_glyph_string_clip_rect (s, &r);
w32_set_clip_rectangle (s->hdc, &r);
}
......@@ -2115,7 +1860,7 @@ x_draw_glyph_string_box (s)
&& (s->next == NULL
|| s->next->hl != s->hl)));
w32_get_glyph_string_clip_rect (s, &clip_rect);
get_glyph_string_clip_rect (s, &clip_rect);
if (s->face->box == FACE_SIMPLE_BOX)
w32_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
......@@ -2261,7 +2006,7 @@ x_draw_image_relief (s)
y1 = y + s->img->height + thick - 1;
x_setup_relief_colors (s);
w32_get_glyph_string_clip_rect (s, &r);
get_glyph_string_clip_rect (s, &r);
w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 1, 1, &r);
}
......@@ -2534,7 +2279,7 @@ x_draw_stretch_glyph_string (s)
else
gc = s->face->gc;
w32_get_glyph_string_clip_rect (s, &r);
get_glyph_string_clip_rect (s, &r);
w32_set_clip_rectangle (hdc, &r);
#if 0 /* TODO: stipple */
......@@ -2698,147 +2443,20 @@ x_draw_glyph_string (s)
}
/* 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;
BLOCK_INPUT;
if (area == LEFT_MARGIN_AREA)
x = 0;
else if (area == TEXT_AREA)
x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
else
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;
do
{
x += row->glyphs[area][i].pixel_width;
++i;
}
while (i < row->used[area]
&& row->glyphs[area][i].overlaps_vertically_p);
x_draw_glyphs (w, start_x, row, area, start, i,
DRAW_NORMAL_TEXT, 1);
}
else
{
x += row->glyphs[area][i].pixel_width;
++i;
}
}
UNBLOCK_INPUT;
}
/* 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. */
/* Shift display to make room for inserted glyphs. */
static void
x_write_glyphs (start, len)
struct glyph *start;
int len;
{
int x, hpos;
xassert (updated_window && updated_row);
BLOCK_INPUT;
/* 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,
DRAW_NORMAL_TEXT, 0);
/* 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;
UNBLOCK_INPUT;
/* 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;
void
w32_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;
HDC hdc;
xassert (updated_window && updated_row);
BLOCK_INPUT;
w = updated_window;
f = XFRAME (WINDOW_FRAME (w));
hdc = get_frame_dc (f);
BitBlt (hdc, x + shift_by, y, width, height,
hdc, x, y, SRCCOPY);
/* 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);
BitBlt (hdc, frame_x + shift_by_width, frame_y,
shifted_region_width, line_height,
hdc, frame_x, frame_y, SRCCOPY);
/* Write the glyphs. */
hpos = start - row->glyphs[updated_area];
x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
DRAW_NORMAL_TEXT, 0);
/* Advance the output cursor. */
output_cursor.hpos += len;
output_cursor.x += shift_by_width;
release_frame_dc (f, hdc);
UNBLOCK_INPUT;
}
......@@ -2863,86 +2481,6 @@ x_delete_glyphs (n)
}
/* 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);
if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)
&& !w->pseudo_window_p)
max_x += FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f);
}
else
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)
return;
else if (to_x < 0)
to_x = max_x;
else
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,
updated_row->y,
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);
}
else
{