/* Implementation of GUI terminal on the Microsoft W32 API.
-Copyright (C) 1989, 1993-2011 Free Software Foundation, Inc.
+Copyright (C) 1989, 1993-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
static void my_set_foreground_window (HWND);
static void my_destroy_window (struct frame *, HWND);
+#ifdef GLYPH_DEBUG
+static void x_check_font (struct frame *, struct font *);
+#endif
+
static Lisp_Object Qvendor_specific_keysyms;
\f
SelectClipRgn (hdc, NULL);
}
+/* Restore clipping rectangle in S */
+static void
+w32_restore_glyph_string_clip (struct glyph_string *s)
+{
+ RECT *r = s->clip;
+ int n = s->num_clips;
+
+ if (n == 1)
+ w32_set_clip_rectangle (s->hdc, r);
+ else if (n > 1)
+ {
+ HRGN clip1 = CreateRectRgnIndirect (r);
+ HRGN clip2 = CreateRectRgnIndirect (r + 1);
+ if (CombineRgn (clip1, clip1, clip2, RGN_OR) != ERROR)
+ SelectClipRgn (s->hdc, clip1);
+ DeleteObject (clip1);
+ DeleteObject (clip2);
+ }
+}
+
+/*
+ Draw a wavy line under S. The wave fills wave_height pixels from y0.
+
+ x0 wave_length = 2
+ --
+ y0 * * * * *
+ |* * * * * * * * *
+ wave_height = 3 | * * * *
+
+*/
+
+void
+w32_draw_underwave (struct glyph_string *s, COLORREF color)
+{
+ int wave_height = 2, wave_length = 3;
+ int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
+ XRectangle wave_clip, string_clip, final_clip;
+ RECT w32_final_clip, w32_string_clip;
+ HPEN hp, oldhp;
+
+ dx = wave_length;
+ dy = wave_height - 1;
+ x0 = s->x;
+ y0 = s->ybase + 1;
+ width = s->width;
+ xmax = x0 + width;
+
+ /* Find and set clipping rectangle */
+
+ wave_clip = (XRectangle){ x0, y0, width, wave_height };
+ get_glyph_string_clip_rect (s, &w32_string_clip);
+ CONVERT_TO_XRECT (string_clip, w32_string_clip);
+
+ if (!x_intersect_rectangles (&wave_clip, &string_clip, &final_clip))
+ return;
+
+ hp = CreatePen (PS_SOLID, 0, color);
+ oldhp = SelectObject (s->hdc, hp);
+ CONVERT_FROM_XRECT (final_clip, w32_final_clip);
+ w32_set_clip_rectangle (s->hdc, &w32_final_clip);
+
+ /* Draw the waves */
+
+ x1 = x0 - (x0 % dx);
+ x2 = x1 + dx;
+ odd = (x1/dx) % 2;
+ y1 = y2 = y0;
+
+ if (odd)
+ y1 += dy;
+ else
+ y2 += dy;
+
+ MoveToEx (s->hdc, x1, y1, NULL);
+
+ while (x1 <= xmax)
+ {
+ LineTo (s->hdc, x2, y2);
+ x1 = x2, y1 = y2;
+ x2 += dx, y2 = y0 + odd*dy;
+ odd = !odd;
+ }
+
+ /* Restore previous pen and clipping rectangle(s) */
+ w32_restore_glyph_string_clip (s);
+ SelectObject (s->hdc, oldhp);
+ DeleteObject (hp);
+}
/* Draw a hollow rectangle at the specified position. */
void
struct frame *f;
int width, height;
- xassert (w);
+ eassert (w);
if (!desired_row->mode_line_p && !w->pseudo_window_p)
desired_row->redraw_fringe_bitmaps_p = 1;
s->gc = FRAME_W32_DISPLAY_INFO (s->f)->scratch_cursor_gc;
}
- xassert (s->gc != 0);
+ eassert (s->gc != 0);
}
}
/* GC must have been set. */
- xassert (s->gc != 0);
+ eassert (s->gc != 0);
}
delta /= 256;
/* Change RGB values by specified FACTOR. Avoid overflow! */
- xassert (factor >= 0);
+ eassert (factor >= 0);
new = PALETTERGB (min (0xff, factor * GetRValue (*color)),
min (0xff, factor * GetGValue (*color)),
min (0xff, factor * GetBValue (*color)));
static void
x_draw_stretch_glyph_string (struct glyph_string *s)
{
- xassert (s->first_glyph->type == STRETCH_GLYPH);
+ eassert (s->first_glyph->type == STRETCH_GLYPH);
if (s->hl == DRAW_CURSOR
&& !x_stretch_cursor_p)
/* Draw underline. */
if (s->face->underline_p)
{
- unsigned long thickness, position;
- int y;
-
- if (s->prev && s->prev->face->underline_p)
+ if (s->face->underline_type == FACE_UNDER_WAVE)
{
- /* We use the same underline style as the previous one. */
- thickness = s->prev->underline_thickness;
- position = s->prev->underline_position;
+ COLORREF color;
+
+ if (s->face->underline_defaulted_p)
+ color = s->gc->foreground;
+ else
+ color = s->face->underline_color;
+
+ w32_draw_underwave (s, color);
}
- else
+ else if (s->face->underline_type == FACE_UNDER_LINE)
{
- /* Get the underline thickness. Default is 1 pixel. */
- if (s->font && s->font->underline_thickness > 0)
- thickness = s->font->underline_thickness;
+ unsigned long thickness, position;
+ int y;
+
+ if (s->prev && s->prev->face->underline_p)
+ {
+ /* We use the same underline style as the previous one. */
+ thickness = s->prev->underline_thickness;
+ position = s->prev->underline_position;
+ }
else
- thickness = 1;
- if (x_underline_at_descent_line)
- position = (s->height - thickness) - (s->ybase - s->y);
+ {
+ /* Get the underline thickness. Default is 1 pixel. */
+ if (s->font && s->font->underline_thickness > 0)
+ thickness = s->font->underline_thickness;
+ else
+ thickness = 1;
+ if (x_underline_at_descent_line)
+ position = (s->height - thickness) - (s->ybase - s->y);
+ else
+ {
+ /* Get the underline position. This is the recommended
+ vertical offset in pixels from the baseline to the top of
+ the underline. This is a signed value according to the
+ specs, and its default is
+
+ ROUND ((maximum_descent) / 2), with
+ ROUND (x) = floor (x + 0.5) */
+
+ if (x_use_underline_position_properties
+ && s->font && s->font->underline_position >= 0)
+ position = s->font->underline_position;
+ else if (s->font)
+ position = (s->font->descent + 1) / 2;
+ }
+ position = max (position, underline_minimum_offset);
+ }
+ /* Check the sanity of thickness and position. We should
+ avoid drawing underline out of the current line area. */
+ if (s->y + s->height <= s->ybase + position)
+ position = (s->height - 1) - (s->ybase - s->y);
+ if (s->y + s->height < s->ybase + position + thickness)
+ thickness = (s->y + s->height) - (s->ybase + position);
+ s->underline_thickness = thickness;
+ s->underline_position =position;
+ y = s->ybase + position;
+ if (s->face->underline_defaulted_p)
+ {
+ w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
+ y, s->width, 1);
+ }
else
{
- /* Get the underline position. This is the recommended
- vertical offset in pixels from the baseline to the top of
- the underline. This is a signed value according to the
- specs, and its default is
-
- ROUND ((maximum_descent) / 2), with
- ROUND (x) = floor (x + 0.5) */
-
- if (x_use_underline_position_properties
- && s->font && s->font->underline_position >= 0)
- position = s->font->underline_position;
- else if (s->font)
- position = (s->font->descent + 1) / 2;
+ w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
+ y, s->width, 1);
}
- position = max (position, underline_minimum_offset);
- }
- /* Check the sanity of thickness and position. We should
- avoid drawing underline out of the current line area. */
- if (s->y + s->height <= s->ybase + position)
- position = (s->height - 1) - (s->ybase - s->y);
- if (s->y + s->height < s->ybase + position + thickness)
- thickness = (s->y + s->height) - (s->ybase + position);
- s->underline_thickness = thickness;
- s->underline_position =position;
- y = s->ybase + position;
- if (s->face->underline_defaulted_p)
- {
- w32_fill_area (s->f, s->hdc, s->gc->foreground, s->x,
- y, s->width, 1);
- }
- else
- {
- w32_fill_area (s->f, s->hdc, s->face->underline_color, s->x,
- y, s->width, 1);
}
}
/* Draw overline. */
}
else
{
- /* Scolling down. Make sure we don't copy over the mode line.
+ /* Scrolling down. Make sure we don't copy over the mode line.
at the bottom. */
if (to_y + run->height > bottom_y)
height = bottom_y - to_y;
***********************************************************************/
/* Handle mouse button event on the tool-bar of frame F, at
- frame-relative coordinates X/Y. EVENT_TYPE is either ButtionPress
- or ButtonRelase. */
+ frame-relative coordinates X/Y. EVENT_TYPE is either ButtonPress
+ or ButtonRelease. */
static void
w32_handle_tool_bar_click (struct frame *f, struct input_event *button_event)
if (whole)
{
/* Position scroll bar at rock bottom if the bottom of the
- buffer is visible. This avoids shinking the thumb away
+ buffer is visible. This avoids shrinking the thumb away
to nothing if it is held at the bottom of the buffer. */
if (position + portion >= whole && !draggingp)
{
(WPARAM) hwnd, 0);
}
+static void
+my_bring_window_to_top (HWND hwnd)
+{
+ SendMessage (hwnd, WM_EMACS_BRINGTOTOP, (WPARAM) hwnd, 0);
+}
+
/* Create a scroll bar and return the scroll bar vector for it. W is
the Emacs window on which to create the scroll bar. TOP, LEFT,
WIDTH and HEIGHT are the pixel coordinates and dimensions of the
/* Destroy the window. */
my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
- /* Disassociate this scroll bar from its window. */
+ /* Dissociate this scroll bar from its window. */
XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
UNBLOCK_INPUT;
/* Generate a language change event. */
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
- /* lParam contains the input lang ID. Use it to update our
- record of the keyboard codepage. */
+ /* lParam contains the input language ID in its low 16 bits.
+ Use it to update our record of the keyboard codepage. */
keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam
& 0xffff));
{
inev.kind = LANGUAGE_CHANGE_EVENT;
XSETFRAME (inev.frame_or_window, f);
- inev.code = msg.msg.wParam;
+ inev.code = keyboard_codepage;
inev.modifiers = msg.msg.lParam & 0xffff;
}
break;
/* If the contents of the global variable help_echo_string
has changed, generate a HELP_EVENT. */
-#if 0 /* The below is an invalid comparison when USE_LISP_UNION_TYPE.
+#if 0 /* The below is an invalid comparison when CHECK_LISP_OBJECT_TYPE.
But it was originally changed to this to fix a bug, so I have
not removed it completely in case the bug is still there. */
if (help_echo_string != previous_help_echo_string ||
}
/* If window has been obscured or exposed by another window
- being maximised or minimised/restored, then recheck
+ being maximized or minimized/restored, then recheck
visibility of all frames. Direct changes to our own
windows get handled by WM_SIZE. */
#if 0
input focus anyway (so the window with focus will never be
completely obscured) - if not, then just moving the mouse over it
is sufficient to give it focus. On Windows, the user must actually
- click on the frame (preferrably the title bar so as not to move
+ click on the frame (preferably the title bar so as not to move
point), which is more awkward. Also, no other Windows program
raises a window to the top but leaves another window (possibly now
completely obscured) with input focus.
HDWP handle = BeginDeferWindowPos (2);
if (handle)
{
- DeferWindowPos (handle,
- FRAME_W32_WINDOW (f),
- HWND_TOP,
- 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
-
- DeferWindowPos (handle,
- GetForegroundWindow (),
- FRAME_W32_WINDOW (f),
- 0, 0, 0, 0,
- SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
-
- EndDeferWindowPos (handle);
+ handle = DeferWindowPos (handle,
+ FRAME_W32_WINDOW (f),
+ HWND_TOP,
+ 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
+ if (handle)
+ {
+ handle = DeferWindowPos (handle,
+ GetForegroundWindow (),
+ FRAME_W32_WINDOW (f),
+ 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE |
+ SWP_NOACTIVATE);
+ if (handle)
+ EndDeferWindowPos (handle);
+ }
}
}
else
{
- my_set_foreground_window (FRAME_W32_WINDOW (f));
+ my_bring_window_to_top (FRAME_W32_WINDOW (f));
}
UNBLOCK_INPUT;
f->output_data.w32->asked_for_visible = 1;
- /* The first of these seems to give more expected behavior, but
- was added as a commented out line in Sept 1997, with the
- second version remaining uncommented. There may have been
- some problem with it that led to it not being enabled,
- so the old version remains commented out below in case we
- decide we need to go back to it [23.0.60 2008-06-09]. */
+ /* According to a report in emacs-devel 2008-06-03, SW_SHOWNORMAL
+ causes unexpected behavior when unminimizing frames that were
+ previously maximized. But only SW_SHOWNORMAL works properly for
+ frames that were truely hidden (using make-frame-invisible), so
+ we need it to avoid Bug#5482. It seems that async_iconified
+ is only set for minimized windows that are still visible, so
+ use that to determine the appropriate flag to pass ShowWindow. */
my_show_window (f, FRAME_W32_WINDOW (f),
- f->async_iconified ? SW_RESTORE : SW_SHOW);
- /* my_show_window (f, FRAME_W32_WINDOW (f), SW_SHOWNORMAL); */
+ f->async_iconified ? SW_RESTORE : SW_SHOWNORMAL);
}
/* Synchronize to ensure Emacs knows the frame is visible
}
\f
+/***********************************************************************
+ Fonts
+ ***********************************************************************/
+
+#ifdef GLYPH_DEBUG
+
+/* Check that FONT is valid on frame F. It is if it can be found in F's
+ font table. */
+
+static void
+x_check_font (struct frame *f, struct font *font)
+{
+ eassert (font != NULL && ! NILP (font->props[FONT_TYPE_INDEX]));
+ if (font->driver->check)
+ eassert (font->driver->check (f, font) == 0);
+}
+
+#endif /* GLYPH_DEBUG */
+
+
+\f
/***********************************************************************
Initialization
***********************************************************************/
dpyinfo->has_palette = GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE;
ReleaseDC (NULL, hdc);
- /* initialise palette with white and black */
+ /* initialize palette with white and black */
{
XColor color;
w32_defined_color (0, "white", &color, 1);
from cus-start.el and other places, like "M-x set-variable". */
DEFVAR_BOOL ("x-use-underline-position-properties",
x_use_underline_position_properties,
- doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
+ 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. You can also use `underline-minimum-offset'
DEFVAR_BOOL ("x-underline-at-descent-line",
x_underline_at_descent_line,
- doc: /* *Non-nil means to draw the underline at the same place as the descent line.
+ doc: /* Non-nil means to draw the underline at the same place as the descent line.
A value of nil means to draw the underline according to the value of the
variable `x-use-underline-position-properties', which is usually at the
baseline level. The default value is nil. */);
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. */);
+With MS Windows or Nextstep, the value is t. */);
Vx_toolkit_scroll_bars = Qt;
staticpro (&last_mouse_motion_frame);