-/* Implementation of GUI terminal on the Microsoft W32 API.
+/* Implementation of GUI terminal on the Microsoft Windows API.
-Copyright (C) 1989, 1993-2012 Free Software Foundation, Inc.
+Copyright (C) 1989, 1993-2013 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include <signal.h>
#include <stdio.h>
-#include <setjmp.h>
#include "lisp.h"
#include "blockinput.h"
#include "w32term.h"
#include "atimer.h"
#include "keymap.h"
+#ifdef WINDOWSNT
#include "w32heap.h"
+#endif
+
+#ifndef WINDOWSNT
+#include <io.h> /* for get_osfhandle */
+#endif
+
#include <shellapi.h>
#include "font.h"
Lisp_Object w32_display_name_list;
-#ifndef GLYPHSET
+#if _WIN32_WINNT < 0x0500
/* Pre Windows 2000, this was not available, but define it here so
that Emacs compiled on such a platform will run on newer versions. */
WCRANGE ranges[1];
} GLYPHSET;
-#endif
+#endif /* compiling for pre-Win2k */
/* Dynamic linking to SetLayeredWindowAttribute (only since 2000). */
BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD);
int last_scroll_bar_drag_pos;
+/* Keyboard code page - may be changed by language-change events. */
+int w32_keyboard_codepage;
+
/* Mouse movement. */
/* Where the mouse was last time we reported a mouse event. */
static int input_signal_count;
#endif
-/* Keyboard code page - may be changed by language-change events. */
-static int keyboard_codepage;
+#ifdef CYGWIN
+int w32_message_fd = -1;
+#endif /* CYGWIN */
static void x_update_window_end (struct window *, int, int);
static void w32_handle_tool_bar_click (struct frame *,
void x_lower_frame (struct frame *);
void x_scroll_bar_clear (struct frame *);
-void x_wm_set_size_hint (struct frame *, long, int);
+void x_wm_set_size_hint (struct frame *, long, bool);
void x_raise_frame (struct frame *);
void x_set_window_size (struct frame *, int, int, int);
void x_wm_set_window_state (struct frame *, int);
static void my_set_foreground_window (HWND);
static void my_destroy_window (struct frame *, HWND);
-#if GLYPH_DEBUG
+#ifdef GLYPH_DEBUG
static void x_check_font (struct frame *, struct font *);
#endif
XGCValues *
XCreateGC (void *ignore, Window window, unsigned long mask, XGCValues *xgcv)
{
- XGCValues *gc = (XGCValues *) xmalloc (sizeof (XGCValues));
- memset (gc, 0, sizeof (XGCValues));
+ XGCValues *gc = xzalloc (sizeof (XGCValues));
XChangeGC (ignore, gc, mask, xgcv);
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 = 3, wave_length = 2;
+ 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 - wave_height + 3;
+ width = s->width;
+ xmax = x0 + width;
+
+ /* Find and set clipping rectangle */
+
+ wave_clip.x = x0;
+ wave_clip.y = y0;
+ wave_clip.width = width;
+ wave_clip.height = 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
updated_window = w;
set_output_cursor (&w->cursor);
- BLOCK_INPUT;
+ block_input ();
if (f == hlinfo->mouse_face_mouse_frame)
{
#endif /* 0 */
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Draw a vertical window border from (x,y0) to (x,y1) */
if (!w->pseudo_window_p)
{
- BLOCK_INPUT;
+ block_input ();
if (cursor_on_p)
display_and_set_cursor (w, 1, output_cursor.hpos,
if (draw_window_fringes (w, 1))
x_draw_vertical_border (w);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* If a row with mouse-face was overwritten, arrange for
if (hlinfo->mouse_face_deferred_gc
|| f == hlinfo->mouse_face_mouse_frame)
{
- BLOCK_INPUT;
+ block_input ();
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;
+ unblock_input ();
}
}
}
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;
{
int y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, desired_row->y));
- BLOCK_INPUT;
+ block_input ();
{
HDC hdc = get_frame_dc (f);
w32_clear_area (f, hdc, 0, y, width, height);
y, width, height);
release_frame_dc (f, hdc);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
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)
break;
default:
- abort ();
+ emacs_abort ();
}
if (!s->for_overlaps)
/* 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
+ && s->prev->face->underline_type == FACE_UNDER_LINE)
+ {
+ /* 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. */
w32_set_clip_rectangle (next->hdc, NULL);
next->hl = save;
next->num_clips = 0;
+ next->clip_head = s->next;
}
}
}
if (! FRAME_W32_P (f))
return;
- abort ();
+ emacs_abort ();
}
/* We don't set the output cursor here because there will always
follow an explicit cursor_to. */
- BLOCK_INPUT;
+ block_input ();
w32_clear_window (f);
colors or something like that, then they should be notified. */
x_scroll_bar_clear (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
static void
w32_ring_bell (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
if (FRAME_W32_P (f) && visible_bell)
{
else
w32_sys_ring_bell (f);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
if (! FRAME_W32_P (f))
return;
- abort ();
+ emacs_abort ();
}
expect_dirty = CreateRectRgn (x, y, x + width, to_y);
}
- BLOCK_INPUT;
+ block_input ();
/* Cursor off. Will be switched on again in x_update_window_end. */
updated_window = w;
DeleteObject (combined);
}
- UNBLOCK_INPUT;
+ unblock_input ();
DeleteObject (expect_dirty);
}
: dpyinfo->w32_focus_frame);
if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
{
- FRAME_FOCUS_FRAME (dpyinfo->w32_focus_frame) = Qnil;
+ fset_focus_frame (dpyinfo->w32_focus_frame, Qnil);
dpyinfo->x_highlight_frame = dpyinfo->w32_focus_frame;
}
}
/* Make static so we can always return it */
static char value[100];
- BLOCK_INPUT;
+ block_input ();
GetKeyNameText (keysym, value, 100);
- UNBLOCK_INPUT;
+ unblock_input ();
return value;
}
{
FRAME_PTR f1;
- BLOCK_INPUT;
+ block_input ();
if (! NILP (last_mouse_scroll_bar) && insist == 0)
x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
frame = XCAR (tail);
/* All elements of Vframe_list should be frames. */
if (! FRAMEP (frame))
- abort ();
+ emacs_abort ();
/* Scan this frame's scroll bar list for a scroll bar with the
right window ID. */
if (draggingp)
{
int near_bottom_p;
- BLOCK_INPUT;
+ block_input ();
si.cbSize = sizeof (si);
si.fMask = SIF_POS | SIF_PAGE;
GetScrollInfo (w, SB_CTL, &si);
near_bottom_p = si.nPos + si.nPage >= range;
- UNBLOCK_INPUT;
+ unblock_input ();
if (!near_bottom_p)
return;
}
sb_page = max (sb_page, VERTICAL_SCROLL_BAR_MIN_HANDLE);
- BLOCK_INPUT;
+ block_input ();
si.cbSize = sizeof (si);
si.fMask = SIF_PAGE | SIF_POS;
SetScrollInfo (w, SB_CTL, &si, TRUE);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
(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
SCROLLINFO si;
struct scroll_bar *bar
= XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
+ Lisp_Object barobj;
- BLOCK_INPUT;
+ block_input ();
XSETWINDOW (bar->window, w);
XSETINT (bar->top, top);
/* Add bar to its frame's list of scroll bars. */
bar->next = FRAME_SCROLL_BARS (f);
bar->prev = Qnil;
- XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
+ XSETVECTOR (barobj, bar);
+ fset_scroll_bars (f, barobj);
if (! NILP (bar->next))
XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
- UNBLOCK_INPUT;
+ unblock_input ();
return bar;
}
{
FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
- BLOCK_INPUT;
+ block_input ();
/* Destroy the window. */
my_destroy_window (f, SCROLL_BAR_W32_WINDOW (bar));
/* Dissociate this scroll bar from its window. */
- XWINDOW (bar->window)->vertical_scroll_bar = Qnil;
+ wset_vertical_scroll_bar (XWINDOW (bar->window), Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Set the handle of the vertical scroll bar for WINDOW to indicate
int portion, int whole, int position)
{
struct frame *f = XFRAME (w->frame);
+ Lisp_Object barobj;
struct scroll_bar *bar;
int top, height, left, sb_left, width, sb_width;
int window_y, window_height;
if (NILP (w->vertical_scroll_bar))
{
HDC hdc;
- BLOCK_INPUT;
+ block_input ();
if (width > 0 && height > 0)
{
hdc = get_frame_dc (f);
w32_clear_area (f, hdc, left, top, width, height);
release_frame_dc (f, hdc);
}
- UNBLOCK_INPUT;
+ unblock_input ();
bar = x_scroll_bar_create (w, top, sb_left, sb_width, height);
}
HDC hdc;
SCROLLINFO si;
- BLOCK_INPUT;
+ block_input ();
if (width && height)
{
hdc = get_frame_dc (f);
XSETINT (bar->width, sb_width);
XSETINT (bar->height, height);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
w32_set_scroll_bar_thumb (bar, portion, position, whole);
-
- XSETVECTOR (w->vertical_scroll_bar, bar);
+ XSETVECTOR (barobj, bar);
+ wset_vertical_scroll_bar (w, barobj);
}
{
Lisp_Object bar;
bar = FRAME_SCROLL_BARS (frame);
- FRAME_SCROLL_BARS (frame) = XSCROLL_BAR (bar)->next;
+ fset_scroll_bars (frame, XSCROLL_BAR (bar)->next);
XSCROLL_BAR (bar)->next = FRAME_CONDEMNED_SCROLL_BARS (frame);
XSCROLL_BAR (bar)->prev = Qnil;
if (! NILP (FRAME_CONDEMNED_SCROLL_BARS (frame)))
XSCROLL_BAR (FRAME_CONDEMNED_SCROLL_BARS (frame))->prev = bar;
- FRAME_CONDEMNED_SCROLL_BARS (frame) = bar;
+ fset_condemned_scroll_bars (frame, bar);
}
}
w32_redeem_scroll_bar (struct window *window)
{
struct scroll_bar *bar;
+ Lisp_Object barobj;
struct frame *f;
/* We can't redeem this window's scroll bar if it doesn't have one. */
if (NILP (window->vertical_scroll_bar))
- abort ();
+ emacs_abort ();
bar = XSCROLL_BAR (window->vertical_scroll_bar);
return;
else if (EQ (FRAME_CONDEMNED_SCROLL_BARS (f),
window->vertical_scroll_bar))
- FRAME_CONDEMNED_SCROLL_BARS (f) = bar->next;
+ fset_condemned_scroll_bars (f, bar->next);
else
/* If its prev pointer is nil, it must be at the front of
one or the other! */
- abort ();
+ emacs_abort ();
}
else
XSCROLL_BAR (bar->prev)->next = bar->next;
bar->next = FRAME_SCROLL_BARS (f);
bar->prev = Qnil;
- XSETVECTOR (FRAME_SCROLL_BARS (f), bar);
+ XSETVECTOR (barobj, bar);
+ fset_scroll_bars (f, barobj);
if (! NILP (bar->next))
XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
}
/* Clear out the condemned list now so we won't try to process any
more events on the hapless scroll bars. */
- FRAME_CONDEMNED_SCROLL_BARS (f) = Qnil;
+ fset_condemned_scroll_bars (f, Qnil);
for (; ! NILP (bar); bar = next)
{
struct input_event *emacs_event)
{
if (! WINDOWP (bar->window))
- abort ();
+ emacs_abort ();
emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
emacs_event->code = 0;
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
SCROLLINFO si;
- BLOCK_INPUT;
+ block_input ();
*fp = f;
*bar_window = bar->window;
*time = last_mouse_movement_time;
- UNBLOCK_INPUT;
+ unblock_input ();
}
This routine is called by the SIGIO handler.
We return as soon as there are no more events to be read.
+ For an overview of how Emacs input works on MS-Windows, see the
+ commentary before w32_msg_pump in w32fns.c.
+
We return the number of characters stored into the buffer,
thus pretending to be `read'.
- EXPECTED is nonzero if the caller knows input is available.
-
Some of these messages are reposted back to the message queue since the
system calls the windows proc directly in a context where we cannot return
the data nor can we guarantee the state we are in. So if we dispatch them
*/
static int
-w32_read_socket (struct terminal *terminal, int expected,
+w32_read_socket (struct terminal *terminal,
struct input_event *hold_quit)
{
int count = 0;
struct frame *f;
struct w32_display_info *dpyinfo = &one_w32_display_info;
Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
+ static char buf[1];
- if (interrupt_input_blocked)
- {
- interrupt_input_pending = 1;
- return -1;
- }
-
- interrupt_input_pending = 0;
- BLOCK_INPUT;
+ block_input ();
/* So people can tell when we have read the available input. */
input_signal_count++;
+ /* Process any incoming thread messages. */
+ drain_message_queue ();
+
/* TODO: ghostscript integration. */
while (get_next_msg (&msg, FALSE))
{
struct input_event inev;
int do_help = 0;
+ /* DebPrint (("w32_read_socket: %s time:%u\n", */
+ /* w32_name_of_message (msg.msg.message), */
+ /* msg.msg.time)); */
+
EVENT_INIT (inev);
inev.kind = NO_EVENT;
inev.arg = Qnil;
/* 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. */
- keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam
- & 0xffff));
+ /* lParam contains the input language ID in its low 16 bits.
+ Use it to update our record of the keyboard codepage. */
+ w32_keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam
+ & 0xffff));
if (f)
{
inev.kind = LANGUAGE_CHANGE_EVENT;
XSETFRAME (inev.frame_or_window, f);
- inev.code = msg.msg.wParam;
+ inev.code = w32_keyboard_codepage;
inev.modifiers = msg.msg.lParam & 0xffff;
}
break;
{
dbcs[0] = dbcs_lead;
dbcs_lead = 0;
- if (!MultiByteToWideChar (keyboard_codepage, 0,
+ if (!MultiByteToWideChar (w32_keyboard_codepage, 0,
dbcs, 2, &code, 1))
{
/* Garbage */
break;
}
}
- else if (IsDBCSLeadByteEx (keyboard_codepage,
+ else if (IsDBCSLeadByteEx (w32_keyboard_codepage,
(BYTE) msg.msg.wParam))
{
dbcs_lead = (char) msg.msg.wParam;
}
else
{
- if (!MultiByteToWideChar (keyboard_codepage, 0,
+ if (!MultiByteToWideChar (w32_keyboard_codepage, 0,
&dbcs[1], 1, &code, 1))
{
/* What to do with garbage? */
/* 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 ||
}
}
- UNBLOCK_INPUT;
+ unblock_input ();
return count;
}
break;
default:
- abort ();
+ emacs_abort ();
}
}
}
}
x_calc_absolute_position (f);
- BLOCK_INPUT;
+ block_input ();
x_wm_set_size_hint (f, (long) 0, 0);
modified_left = f->left_pos;
modified_left, modified_top,
0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Check if we need to resize the frame due to a fullscreen request.
- If so needed, resize the frame. */
+ If so needed, resize the frame. */
static void
x_check_fullscreen (struct frame *f)
{
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
- /* Wait for the change of frame size to occur */
+ /* Wait for the change of frame size to occur. */
f->want_fullscreen |= FULLSCREEN_WAIT;
}
}
{
int pixelwidth, pixelheight;
- BLOCK_INPUT;
+ block_input ();
check_frame_size (f, &rows, &cols);
f->scroll_bar_actual_width
cancel_mouse_face (f);
#endif
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
/* Mouse warping. */
RECT rect;
POINT pt;
- BLOCK_INPUT;
+ block_input ();
GetClientRect (FRAME_W32_WINDOW (f), &rect);
pt.x = rect.left + pix_x;
SetCursorPos (pt.x, pt.y);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
struct w32_display_info *dpyinfo = &one_w32_display_info;
/* Give input focus to frame. */
- BLOCK_INPUT;
+ block_input ();
#if 0
/* Try not to change its Z-order if possible. */
if (x_window_to_frame (dpyinfo, GetForegroundWindow ()))
else
#endif
my_set_foreground_window (FRAME_W32_WINDOW (f));
- UNBLOCK_INPUT;
+ unblock_input ();
}
void
void
x_raise_frame (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
/* Strictly speaking, raise-frame should only change the frame's Z
order, leaving input focus unchanged. This is reasonable behavior
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;
+ unblock_input ();
}
/* Lower frame F. */
void
x_lower_frame (struct frame *f)
{
- BLOCK_INPUT;
+ block_input ();
my_set_window_pos (FRAME_W32_WINDOW (f),
HWND_BOTTOM,
0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
- UNBLOCK_INPUT;
+ unblock_input ();
}
static void
{
Lisp_Object type;
- BLOCK_INPUT;
+ block_input ();
type = x_icon_type (f);
if (!NILP (type))
int count;
/* This must come after we set COUNT. */
- UNBLOCK_INPUT;
+ unblock_input ();
XSETFRAME (frame, f);
if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
- BLOCK_INPUT;
+ block_input ();
my_show_window (f, FRAME_W32_WINDOW (f), SW_HIDE);
f->async_visible = 0;
f->async_iconified = 0;
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Change window state from mapped to iconified. */
if (f->async_iconified)
return;
- BLOCK_INPUT;
+ block_input ();
type = x_icon_type (f);
if (!NILP (type))
/* Simulate the user minimizing the frame. */
SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
- UNBLOCK_INPUT;
+ unblock_input ();
}
\f
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
- BLOCK_INPUT;
+ block_input ();
/* We must free faces before destroying windows because some
font-driver (e.g. xft) access a window while finishing a
hlinfo->mouse_face_mouse_frame = 0;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Set the normal size hints for the window manager, for frame F.
FLAGS is the flags word to use--or 0 meaning preserve the flags
that the window now has.
- If USER_POSITION is nonzero, we set the USPosition
+ If USER_POSITION, set the USPosition
flag (this is useful when FLAGS is 0). */
void
-x_wm_set_size_hint (struct frame *f, long flags, int user_position)
+x_wm_set_size_hint (struct frame *f, long flags, bool user_position)
{
Window window = FRAME_W32_WINDOW (f);
Fonts
***********************************************************************/
-#if GLYPH_DEBUG
+#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)
{
- xassert (font != NULL && ! NILP (font->props[FONT_TYPE_INDEX]));
+ eassert (font != NULL && ! NILP (font->props[FONT_TYPE_INDEX]));
if (font->driver->check)
- xassert (font->driver->check (f, font) == 0);
+ eassert (font->driver->check (f, font) == 0);
}
-#endif /* GLYPH_DEBUG != 0 */
+#endif /* GLYPH_DEBUG */
\f
w32_display_name_list);
dpyinfo->name_list_element = XCAR (w32_display_name_list);
- dpyinfo->w32_id_name
- = (char *) xmalloc (SCHARS (Vinvocation_name)
- + SCHARS (Vsystem_name)
- + 2);
+ dpyinfo->w32_id_name = xmalloc (SCHARS (Vinvocation_name)
+ + SCHARS (Vsystem_name) + 2);
sprintf (dpyinfo->w32_id_name, "%s@%s",
SDATA (Vinvocation_name), SDATA (Vsystem_name));
/* We don't yet support separate terminals on W32, so don't try to share
keyboards between virtual terminals that are on the same physical
terminal like X does. */
- terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+ terminal->kboard = xmalloc (sizeof (KBOARD));
init_kboard (terminal->kboard);
- KVAR (terminal->kboard, Vwindow_system) = intern ("w32");
+ kset_window_system (terminal->kboard, intern ("w32"));
terminal->kboard->next_kboard = all_kboards;
all_kboards = terminal->kboard;
/* Don't let the initial kboard remain current longer than necessary.
if (!terminal->name)
return;
- BLOCK_INPUT;
+ block_input ();
x_delete_display (dpyinfo);
- UNBLOCK_INPUT;
+ unblock_input ();
}
struct w32_display_info *
struct terminal *terminal;
HDC hdc;
- BLOCK_INPUT;
+ block_input ();
if (!w32_initialized)
{
terminal = w32_create_terminal (dpyinfo);
/* Set the name of the terminal. */
- terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+ terminal->name = xmalloc (SBYTES (display_name) + 1);
strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
terminal->name[SBYTES (display_name)] = 0;
w32_defined_color (0, "black", &color, 1);
}
- /* Add the default keyboard. */
+#ifdef WINDOWSNT
+ /* Add the default keyboard. When !WINDOWSNT, we're using the
+ standard Emacs console handling machinery and don't need an
+ explicit FD here. */
add_keyboard_wait_descriptor (0);
+#elif CYGWIN
+ /* /dev/windows wakes us up when we have a thread message pending. */
+ add_keyboard_wait_descriptor (w32_message_fd);
+#endif
/* Create Fringe Bitmaps and store them for later use.
the bitmaps. */
w32_init_fringe (terminal->rif);
-#ifdef F_SETOWN
- fcntl (connection, F_SETOWN, getpid ());
-#endif /* ! defined (F_SETOWN) */
-
-#ifdef SIGIO
- if (interrupt_input)
- init_sigio (connection);
-#endif /* ! defined (SIGIO) */
-
- UNBLOCK_INPUT;
+ unblock_input ();
return dpyinfo;
}
w32_reset_fringes ();
}
+
\f
/* Set up use of W32. */
set_user_model (L"GNU.Emacs");
}
+#ifdef CYGWIN
+ if ((w32_message_fd = open ("/dev/windows", O_RDWR | O_CLOEXEC)) == -1)
+ fatal ("opening /dev/windows: %s", strerror (errno));
+#endif /* CYGWIN */
+
/* Initialize w32_use_visible_system_caret based on whether a screen
reader is in use. */
if (!SystemParametersInfo (SPI_GETSCREENREADER, 0,
{
DWORD input_locale_id = (DWORD) GetKeyboardLayout (0);
- keyboard_codepage = codepage_for_locale ((LCID) (input_locale_id & 0xffff));
+ w32_keyboard_codepage =
+ codepage_for_locale ((LCID) (input_locale_id & 0xffff));
}
/* Create the window thread - it will terminate itself when the app
staticpro (&last_mouse_motion_frame);
last_mouse_motion_frame = Qnil;
+
+ Fprovide (intern_c_string ("w32"), Qnil);
}