/* Implementation of GUI terminal on the Microsoft W32 API.
- Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+
+Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include <signal.h>
#include <stdio.h>
-#include <stdlib.h>
#include <setjmp.h>
#include "lisp.h"
#include "blockinput.h"
x_update_window_begin (struct window *w)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- struct w32_display_info *display_info = FRAME_W32_DISPLAY_INFO (f);
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
/* Hide the system caret during an update. */
if (w32_use_visible_system_caret && w32_system_caret_hwnd)
BLOCK_INPUT;
- if (f == display_info->mouse_face_mouse_frame)
+ if (f == hlinfo->mouse_face_mouse_frame)
{
/* Don't do highlighting for mouse motion during the update. */
- display_info->mouse_face_defer = 1;
+ hlinfo->mouse_face_defer = 1;
/* If F needs to be redrawn, simply forget about any prior mouse
highlighting. */
if (FRAME_GARBAGED_P (f))
- display_info->mouse_face_window = Qnil;
+ hlinfo->mouse_face_window = Qnil;
#if 0 /* Rows in a current matrix containing glyphs in mouse-face have
their mouse_face_p flag set, which means that they are always
Likewise, don't do anything if the frame is garbaged;
in that case, the frame's current matrix that we would use
is all wrong, and we will redisplay that line anyway. */
- if (!NILP (display_info->mouse_face_window)
- && w == XWINDOW (display_info->mouse_face_window))
+ if (!NILP (hlinfo->mouse_face_window)
+ && w == XWINDOW (hlinfo->mouse_face_window))
{
int i;
break;
if (i < w->desired_matrix->nrows)
- clear_mouse_face (display_info);
+ clear_mouse_face (hlinfo);
}
#endif /* 0 */
}
x_update_window_end (struct window *w, int cursor_on_p,
int mouse_face_overwritten_p)
{
- struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (XFRAME (w->frame));
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
if (!w->pseudo_window_p)
{
XTframe_up_to_date to redisplay the mouse highlight. */
if (mouse_face_overwritten_p)
{
- dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
- dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
- dpyinfo->mouse_face_window = Qnil;
+ hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
+ hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
+ hlinfo->mouse_face_window = Qnil;
}
/* Unhide the caret. This won't actually show the cursor, unless it
return;
/* Mouse highlight may be displayed again. */
- FRAME_W32_DISPLAY_INFO (f)->mouse_face_defer = 0;
+ MOUSE_HL_INFO (f)->mouse_face_defer = 0;
}
{
if (FRAME_W32_P (f))
{
- struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
- if (dpyinfo->mouse_face_deferred_gc
- || f == dpyinfo->mouse_face_mouse_frame)
+ if (hlinfo->mouse_face_deferred_gc
+ || f == hlinfo->mouse_face_mouse_frame)
{
BLOCK_INPUT;
- if (dpyinfo->mouse_face_mouse_frame)
- note_mouse_highlight (dpyinfo->mouse_face_mouse_frame,
- dpyinfo->mouse_face_mouse_x,
- dpyinfo->mouse_face_mouse_y);
- dpyinfo->mouse_face_deferred_gc = 0;
+ if (hlinfo->mouse_face_mouse_frame)
+ note_mouse_highlight (hlinfo->mouse_face_mouse_frame,
+ hlinfo->mouse_face_mouse_x,
+ hlinfo->mouse_face_mouse_y);
+ hlinfo->mouse_face_deferred_gc = 0;
UNBLOCK_INPUT;
}
}
{
}
-/* This is called when exiting or suspending Emacs. Exiting will make
+/* This is called when exiting or suspending Emacs. Exiting will make
the W32 windows go away, and suspending requires no action. */
static void
struct face *face;
/* What face has to be used last for the mouse face? */
- face_id = FRAME_W32_DISPLAY_INFO (s->f)->mouse_face_face_id;
+ face_id = MOUSE_HL_INFO (s->f)->mouse_face_face_id;
face = FACE_FROM_ID (s->f, face_id);
if (face == NULL)
face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
}
+/* Draw the foreground of glyph string S for glyphless characters. */
+
+static void
+x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
+{
+ struct glyph *glyph = s->first_glyph;
+ XChar2b char2b[8];
+ int x, i, j;
+ int with_background;
+
+ /* If first glyph of S has a left box line, start drawing the text
+ of S to the right of that box line. */
+ if (s->face->box != FACE_NO_BOX
+ && s->first_glyph->left_box_line_p)
+ x = s->x + eabs (s->face->box_line_width);
+ else
+ x = s->x;
+
+ SetTextColor (s->hdc, s->gc->foreground);
+ SetBkColor (s->hdc, s->gc->background);
+ SetTextAlign (s->hdc, TA_BASELINE | TA_LEFT);
+
+ s->char2b = char2b;
+ with_background = ! (s->for_overlaps
+ || (s->background_filled_p && s->hl != DRAW_CURSOR));
+ for (i = 0; i < s->nchars; i++, glyph++)
+ {
+ char buf[7], *str = NULL;
+ int len = glyph->u.glyphless.len;
+
+ if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
+ {
+ if (len > 1
+ && CHAR_TABLE_P (Vglyphless_char_display)
+ && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
+ >= 1))
+ {
+ Lisp_Object acronym
+ = (! glyph->u.glyphless.for_no_font
+ ? CHAR_TABLE_REF (Vglyphless_char_display,
+ glyph->u.glyphless.ch)
+ : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
+ if (STRINGP (acronym))
+ str = (char *) SDATA (acronym);
+ }
+ }
+ else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
+ {
+ sprintf ((char *) buf, "%0*X",
+ glyph->u.glyphless.ch < 0x10000 ? 4 : 6,
+ glyph->u.glyphless.ch);
+ str = buf;
+ }
+
+ if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
+ w32_draw_rectangle (s->hdc, s->gc,
+ x, s->ybase - glyph->ascent,
+ glyph->pixel_width - 1,
+ glyph->ascent + glyph->descent - 1);
+ if (str)
+ {
+ struct font *font = s->font;
+ int upper_len = (len + 1) / 2;
+ unsigned code;
+ HFONT old_font;
+
+ old_font = SelectObject (s->hdc, FONT_HANDLE (font));
+ /* It is certain that all LEN characters in STR are ASCII. */
+ for (j = 0; j < len; j++)
+ {
+ code = font->driver->encode_char (font, str[j]);
+ STORE_XCHAR2B (char2b + j, code >> 8, code & 0xFF);
+ }
+ font->driver->draw (s, 0, upper_len,
+ x + glyph->slice.glyphless.upper_xoff,
+ s->ybase + glyph->slice.glyphless.upper_yoff,
+ with_background);
+ font->driver->draw (s, upper_len, len,
+ x + glyph->slice.glyphless.lower_xoff,
+ s->ybase + glyph->slice.glyphless.lower_yoff,
+ with_background);
+ SelectObject (s->hdc, old_font);
+ }
+ x += glyph->pixel_width;
+ }
+}
+
+
/* Brightness beyond which a color won't have its highlight brightness
boosted.
if (s->hl == DRAW_CURSOR
&& !x_stretch_cursor_p)
{
- /* If `x-stretch-block-cursor' is nil, don't draw a block cursor
- as wide as the stretch glyph. */
+ /* If `x-stretch-cursor' is nil, don't draw a block cursor as
+ wide as the stretch glyph. */
int width, background_width = s->background_width;
- int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+ int x = s->x;
- if (x < left_x)
+ if (!s->row->reversed_p)
{
- background_width -= left_x - x;
- x = left_x;
+ int left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ }
+ else
+ {
+ /* In R2L rows, draw the cursor on the right edge of the
+ stretch glyph. */
+ int right_x = window_box_right_offset (s->w, TEXT_AREA);
+
+ if (x + background_width > right_x)
+ background_width -= x - right_x;
+ x += background_width;
}
width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
+ if (s->row->reversed_p)
+ x -= width;
/* Draw cursor. */
x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
RECT r;
HDC hdc = s->hdc;
- x += width;
+ if (!s->row->reversed_p)
+ x += width;
+ else
+ x = s->x;
if (s->row->mouse_face_p
&& cursor_in_mouse_face_p (s->w))
{
x_draw_composite_glyph_string_foreground (s);
break;
+ case GLYPHLESS_GLYPH:
+ if (s->for_overlaps)
+ s->background_filled_p = 1;
+ else
+ x_draw_glyph_string_background (s, 0);
+ x_draw_glyphless_glyph_string_foreground (s);
+ break;
+
default:
abort ();
}
recursively with different messages by the system.
*/
-int
+static int
w32_read_socket (struct terminal *terminal, int expected,
struct input_event *hold_quit)
{
W32Msg msg;
struct frame *f;
struct w32_display_info *dpyinfo = &one_w32_display_info;
+ Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
if (interrupt_input_blocked)
{
if (f && !f->iconified)
{
- if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
- && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
+ if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+ && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
{
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_hidden = 1;
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_hidden = 1;
}
if (temp_index == sizeof temp_buffer / sizeof (short))
if (f && !f->iconified)
{
- if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
- && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
+ if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+ && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
{
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_hidden = 1;
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_hidden = 1;
}
if (temp_index == sizeof temp_buffer / sizeof (short))
if (f && !f->iconified)
{
- if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
- && !EQ (f->tool_bar_window, dpyinfo->mouse_face_window))
+ if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+ && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
{
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_hidden = 1;
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_hidden = 1;
}
if (temp_index == sizeof temp_buffer / sizeof (short))
else
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
- if (dpyinfo->mouse_face_hidden)
+ if (hlinfo->mouse_face_hidden)
{
- dpyinfo->mouse_face_hidden = 0;
- clear_mouse_face (dpyinfo);
+ hlinfo->mouse_face_hidden = 0;
+ clear_mouse_face (hlinfo);
}
if (f)
int x = LOWORD (msg.msg.lParam);
int y = HIWORD (msg.msg.lParam);
- window = window_from_coordinates (f, x, y, 0, 0, 0, 0);
+ window = window_from_coordinates (f, x, y, 0, 0);
/* Window will be selected only when it is not
selected now and last mouse movement event was
inev.frame_or_window = window;
}
- last_window=window;
+ last_window = window;
}
if (!note_mouse_movement (f, &msg.msg))
help_echo_string = previous_help_echo_string;
{
/* If we move outside the frame, then we're
certainly no longer on any text in the frame. */
- clear_mouse_face (dpyinfo);
+ clear_mouse_face (hlinfo);
}
/* If the contents of the global variable help_echo_string
int x = XFASTINT (inev.x);
int y = XFASTINT (inev.y);
- window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
+ window = window_from_coordinates (f, x, y, 0, 1);
if (EQ (window, f->tool_bar_window))
{
f = x_any_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
- if (f == dpyinfo->mouse_face_mouse_frame)
+ if (f == hlinfo->mouse_face_mouse_frame)
{
/* If we move outside the frame, then we're
certainly no longer on any text in the frame. */
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_mouse_frame = 0;
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_mouse_frame = 0;
}
/* Generate a nil HELP_EVENT to cancel a help-echo.
if (f == dpyinfo->w32_focus_frame)
x_new_focus_frame (dpyinfo, 0);
- if (f == dpyinfo->mouse_face_mouse_frame)
+ if (f == hlinfo->mouse_face_mouse_frame)
{
/* If we move outside the frame, then we're
certainly no longer on any text in the frame. */
- clear_mouse_face (dpyinfo);
- dpyinfo->mouse_face_mouse_frame = 0;
+ clear_mouse_face (hlinfo);
+ hlinfo->mouse_face_mouse_frame = 0;
}
/* Generate a nil HELP_EVENT to cancel a help-echo.
w->phys_cursor_width = width;
+ /* If the character under cursor is R2L, draw the bar cursor
+ on the right of its glyph, rather than on the left. */
+ if ((cursor_glyph->resolved_level & 1) != 0)
+ x += cursor_glyph->pixel_width - width;
+
w32_fill_area (f, hdc, cursor_color, x,
WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y),
width, row->height);
/* Adjust vertical window position in order to avoid being
covered by a task bar placed at the bottom of the desktop. */
SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0);
- GetWindowRect (FRAME_W32_WINDOW(f), &window_rect);
+ GetWindowRect (FRAME_W32_WINDOW (f), &window_rect);
if (window_rect.bottom > workarea_rect.bottom
&& window_rect.top > workarea_rect.top)
f->top_pos = max (window_rect.top
x_free_frame_resources (struct frame *f)
{
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+ Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
BLOCK_INPUT;
if (f == dpyinfo->x_highlight_frame)
dpyinfo->x_highlight_frame = 0;
- if (f == dpyinfo->mouse_face_mouse_frame)
+ if (f == hlinfo->mouse_face_mouse_frame)
{
- dpyinfo->mouse_face_beg_row
- = dpyinfo->mouse_face_beg_col = -1;
- dpyinfo->mouse_face_end_row
- = dpyinfo->mouse_face_end_col = -1;
- dpyinfo->mouse_face_window = Qnil;
- dpyinfo->mouse_face_deferred_gc = 0;
- dpyinfo->mouse_face_mouse_frame = 0;
+ hlinfo->mouse_face_beg_row
+ = hlinfo->mouse_face_beg_col = -1;
+ hlinfo->mouse_face_end_row
+ = hlinfo->mouse_face_end_col = -1;
+ hlinfo->mouse_face_window = Qnil;
+ hlinfo->mouse_face_deferred_gc = 0;
+ hlinfo->mouse_face_mouse_frame = 0;
}
UNBLOCK_INPUT;
w32_initialize_display_info (Lisp_Object display_name)
{
struct w32_display_info *dpyinfo = &one_w32_display_info;
+ Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
memset (dpyinfo, 0, sizeof (*dpyinfo));
dpyinfo->smallest_font_height = 1;
dpyinfo->smallest_char_width = 1;
- dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
- dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
- dpyinfo->mouse_face_face_id = DEFAULT_FACE_ID;
- dpyinfo->mouse_face_window = Qnil;
- dpyinfo->mouse_face_overlay = Qnil;
- dpyinfo->mouse_face_hidden = 0;
+ hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
+ hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
+ hlinfo->mouse_face_face_id = DEFAULT_FACE_ID;
+ hlinfo->mouse_face_window = Qnil;
+ hlinfo->mouse_face_overlay = Qnil;
+ hlinfo->mouse_face_hidden = 0;
dpyinfo->vertical_scroll_bar_cursor = w32_load_cursor (IDC_ARROW);
/* TODO: dpyinfo->gray */
doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
A value of nil means ignore them. If you encounter fonts with bogus
UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
-to 4.1, set this to nil. */);
+to 4.1, set this to nil. You can also use `underline-minimum-offset'
+to override the font's UNDERLINE_POSITION for small font display
+sizes. */);
x_use_underline_position_properties = 0;
DEFVAR_BOOL ("x-underline-at-descent-line",
x_underline_at_descent_line = 0;
DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
- doc: /* If not nil, Emacs uses toolkit scroll bars. */);
+ doc: /* Which toolkit scroll bars Emacs uses, if any.
+A value of nil means Emacs doesn't use toolkit scroll bars.
+With the X Window system, the value is a symbol describing the
+X toolkit. Possible values are: gtk, motif, xaw, or xaw3d.
+With MS Windows, the value is t. */);
Vx_toolkit_scroll_bars = Qt;
staticpro (&last_mouse_motion_frame);
last_mouse_motion_frame = Qnil;
}
-/* arch-tag: 5fa70624-ab86-499c-8a85-473958ee4646
- (do not change this comment) */