Lisp_Object w32_display_name_list;
-#if _WIN32_WINNT < 0x0500
+#if _WIN32_WINNT < 0x0500 && !defined(_W64)
/* Pre Windows 2000, this was not available, but define it here so
- that Emacs compiled on such a platform will run on newer versions. */
+ that Emacs compiled on such a platform will run on newer versions.
+ MinGW64 (_W64) defines these unconditionally, so avoid redefining. */
typedef struct tagWCRANGE
{
#define WS_EX_LAYERED 0x80000
#endif
+/* SM_CXVIRTUALSCREEN and SM_CYVIRTUALSCREEN are not defined on 95 and
+ NT4. */
+#ifndef SM_CXVIRTUALSCREEN
+#define SM_CXVIRTUALSCREEN 78
+#endif
+#ifndef SM_CYVIRTUALSCREEN
+#define SM_CYVIRTUALSCREEN 79
+#endif
+
/* This is a frame waiting to be autoraised, within w32_read_socket. */
struct frame *pending_autoraise_frame;
int w32_system_caret_height;
int w32_system_caret_x;
int w32_system_caret_y;
+struct window *w32_system_caret_window;
+int w32_system_caret_hdr_height;
+int w32_system_caret_mode_height;
DWORD dwWindowsThreadId = 0;
HANDLE hWindowsThread = NULL;
DWORD dwMainThreadId = 0;
/* Where the mouse was last time we reported a mouse event. */
static RECT last_mouse_glyph;
-static FRAME_PTR last_mouse_glyph_frame;
+static struct frame *last_mouse_glyph_frame;
/* The scroll bar in which the last motion event occurred.
/* Incremented by w32_read_socket whenever it really tries to read
events. */
-#ifdef __STDC__
static int volatile input_signal_count;
-#else
-static int input_signal_count;
-#endif
#ifdef CYGWIN
int w32_message_fd = -1;
#endif
static void my_set_foreground_window (HWND);
static void my_destroy_window (struct frame *, HWND);
+static void w32fullscreen_hook (struct frame *);
#ifdef GLYPH_DEBUG
static void x_check_font (struct frame *, struct font *);
#endif
static Lisp_Object Qvendor_specific_keysyms;
+static Lisp_Object Qadded, Qremoved, Qmodified;
+static Lisp_Object Qrenamed_from, Qrenamed_to;
\f
/***********************************************************************
/* Draw a filled rectangle at the specified position. */
void
-w32_fill_rect (FRAME_PTR f, HDC hdc, COLORREF pix, RECT *lprect)
+w32_fill_rect (struct frame *f, HDC hdc, COLORREF pix, RECT *lprect)
{
HBRUSH hb;
}
void
-w32_clear_window (FRAME_PTR f)
+w32_clear_window (struct frame *f)
{
RECT rect;
HDC hdc = get_frame_dc (f);
int
x_display_pixel_height (struct w32_display_info *dpyinfo)
{
- HDC dc = GetDC (NULL);
- int pixels = GetDeviceCaps (dc, VERTRES);
- ReleaseDC (NULL, dc);
+ int pixels = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+
+ if (pixels == 0)
+ /* Fallback for Windows 95 or NT 4.0. */
+ pixels = GetSystemMetrics (SM_CYSCREEN);
+
return pixels;
}
int
x_display_pixel_width (struct w32_display_info *dpyinfo)
{
- HDC dc = GetDC (NULL);
- int pixels = GetDeviceCaps (dc, HORZRES);
- ReleaseDC (NULL, dc);
+ int pixels = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+
+ if (pixels == 0)
+ /* Fallback for Windows 95 or NT 4.0. */
+ pixels = GetSystemMetrics (SM_CXSCREEN);
+
return pixels;
}
}
-/* Start update of window W. Set the global variable updated_window
- to the window being updated and set output_cursor to the cursor
+/* Start update of window W. Set output_cursor to the cursor
position of W. */
static void
SendMessage (w32_system_caret_hwnd, WM_EMACS_HIDE_CARET, 0, 0);
}
- updated_window = w;
set_output_cursor (&w->cursor);
block_input ();
}
-/* End update of window W (which is equal to updated_window).
+/* End update of window W.
Draw vertical borders between horizontally adjacent windows, and
display W's cursor if CURSOR_ON_P is non-zero.
{
SendMessage (w32_system_caret_hwnd, WM_EMACS_SHOW_CARET, 0, 0);
}
-
- updated_window = NULL;
}
}
-/* This function is called from various places in xdisp.c whenever a
- complete update has been performed. The global variable
- updated_window is not available here. */
+/* This function is called from various places in xdisp.c
+ whenever a complete update has been performed. */
static void
w32_frame_up_to_date (struct frame *f)
{
if (FRAME_W32_P (f))
- {
- Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
-
- if (hlinfo->mouse_face_deferred_gc
- || f == hlinfo->mouse_face_mouse_frame)
- {
- 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 ();
- }
- }
+ FRAME_MOUSE_UPDATE (f);
}
/* Draw truncation mark bitmaps, continuation mark bitmaps, overlay
arrow bitmaps, or clear the fringes if no bitmaps are required
- before DESIRED_ROW is made current. The window being updated is
- found in updated_window. This function is called from
+ before DESIRED_ROW is made current. This function is called from
update_window_line only if it is known that there are differences
between bitmaps to be drawn between current row and DESIRED_ROW. */
static void
-x_after_update_window_line (struct glyph_row *desired_row)
+x_after_update_window_line (struct window *w, struct glyph_row *desired_row)
{
- struct window *w = updated_window;
struct frame *f;
int width, height;
/* When a window has disappeared, make sure that no rest of
full-width rows stays visible in the internal border. Could
- check here if updated_window is the leftmost/rightmost window,
+ check here if updated window is the leftmost/rightmost window,
but I guess it's not worth doing since vertically split windows
are almost never used, internal border is rarely set, and the
overhead is very small. */
if (left_p)
for (i = 0; i < width; ++i)
w32_fill_area (f, hdc, gc.foreground,
- left_x + i, top_y + i, 1,
- bottom_y - top_y - 2 * i + 1);
+ left_x + i, top_y + (i + 1) * top_p, 1,
+ bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1);
if (raised_p)
gc.foreground = f->output_data.w32->black_relief.gc->foreground;
if (right_p)
for (i = 0; i < width; ++i)
w32_fill_area (f, hdc, gc.foreground,
- right_x - i, top_y + i + 1, 1,
- bottom_y - top_y - 2 * i - 1);
+ right_x - i, top_y + (i + 1) * top_p, 1,
+ bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1);
w32_set_clip_rectangle (hdc, NULL);
static void
x_draw_image_relief (struct glyph_string *s)
{
- int x0, y0, x1, y1, thick, raised_p;
+ int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p;
RECT r;
int x = s->x;
int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
raised_p = s->img->relief > 0;
}
- x0 = x - thick;
- y0 = y - thick;
- x1 = x + s->slice.width + thick - 1;
- y1 = y + s->slice.height + thick - 1;
+ x1 = x + s->slice.width - 1;
+ y1 = y + s->slice.height - 1;
+ top_p = bot_p = left_p = right_p = 0;
+
+ if (s->slice.x == 0)
+ x -= thick, left_p = 1;
+ if (s->slice.y == 0)
+ y -= thick, top_p = 1;
+ if (s->slice.x + s->slice.width == s->img->width)
+ x1 += thick, right_p = 1;
+ if (s->slice.y + s->slice.height == s->img->height)
+ y1 += thick, bot_p = 1;
x_setup_relief_colors (s);
get_glyph_string_clip_rect (s, &r);
- w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p,
- s->slice.y == 0,
- s->slice.y + s->slice.height == s->img->height,
- s->slice.x == 0,
- s->slice.x + s->slice.width == s->img->width,
- &r);
+ w32_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
+ top_p, bot_p, left_p, right_p, &r);
}
static void
x_draw_glyph_string (struct glyph_string *s)
{
- int relief_drawn_p = 0;
+ bool relief_drawn_p = 0;
/* If S draws into the background of its successor, draw the
background of the successor first so that S can draw into it.
block_input ();
/* Cursor off. Will be switched on again in x_update_window_end. */
- updated_window = w;
x_clear_cursor (w);
{
&& CONSP (Vframe_list)
&& !NILP (XCDR (Vframe_list)))
{
- bufp->kind = FOCUS_IN_EVENT;
- XSETFRAME (bufp->frame_or_window, frame);
+ bufp->arg = Qt;
}
+ else
+ {
+ bufp->arg = Qnil;
+ }
+
+ bufp->kind = FOCUS_IN_EVENT;
+ XSETFRAME (bufp->frame_or_window, frame);
}
frame->output_data.x->focus_state |= state;
{
dpyinfo->w32_focus_event_frame = 0;
x_new_focus_frame (dpyinfo, 0);
- }
+
+ bufp->kind = FOCUS_OUT_EVENT;
+ XSETFRAME (bufp->frame_or_window, frame);
+ }
/* TODO: IME focus? */
}
HDROP hdrop;
POINT p;
WORD num_files;
- char *name;
+ guichar_t *name;
int i, len;
result->kind = DRAG_N_DROP_EVENT;
for (i = 0; i < num_files; i++)
{
- len = DragQueryFile (hdrop, i, NULL, 0);
+ len = GUI_FN (DragQueryFile) (hdrop, i, NULL, 0);
if (len <= 0)
continue;
- name = alloca (len + 1);
- DragQueryFile (hdrop, i, name, len + 1);
+
+ name = alloca ((len + 1) * sizeof (*name));
+ GUI_FN (DragQueryFile) (hdrop, i, name, len + 1);
+#ifdef NTGUI_UNICODE
+ files = Fcons (from_unicode_buffer (name), files);
+#else
files = Fcons (DECODE_FILE (build_string (name)), files);
+#endif /* NTGUI_UNICODE */
}
DragFinish (hdrop);
return Qnil;
}
+\f
+#if HAVE_W32NOTIFY
+
+/* File event notifications (see w32notify.c). */
+
+Lisp_Object
+lispy_file_action (DWORD action)
+{
+ static char unknown_fmt[] = "unknown-action(%d)";
+ Lisp_Object retval;
+
+ switch (action)
+ {
+ case FILE_ACTION_ADDED:
+ retval = Qadded;
+ break;
+ case FILE_ACTION_REMOVED:
+ retval = Qremoved;
+ break;
+ case FILE_ACTION_MODIFIED:
+ retval = Qmodified;
+ break;
+ case FILE_ACTION_RENAMED_OLD_NAME:
+ retval = Qrenamed_from;
+ break;
+ case FILE_ACTION_RENAMED_NEW_NAME:
+ retval = Qrenamed_to;
+ break;
+ default:
+ {
+ char buf[sizeof(unknown_fmt) - 1 + INT_STRLEN_BOUND (DWORD)];
+
+ sprintf (buf, unknown_fmt, action);
+ retval = intern (buf);
+ }
+ break;
+ }
+
+ return retval;
+}
+
+#ifdef WINDOWSNT
+/* Put file notifications into the Emacs input event queue. This
+ function runs when the WM_EMACS_FILENOTIFY message arrives from a
+ watcher thread. */
+static void
+queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
+ int *evcount)
+{
+ BYTE *p = file_notifications;
+ FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
+ const DWORD min_size
+ = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
+ Lisp_Object frame;
+
+ /* We cannot process notification before Emacs is fully initialized,
+ since we need the UTF-16LE coding-system to be set up. */
+ if (!initialized)
+ {
+ notification_buffer_in_use = 0;
+ return;
+ }
+
+ XSETFRAME (frame, f);
+
+ enter_crit ();
+ if (notification_buffer_in_use)
+ {
+ DWORD info_size = notifications_size;
+ Lisp_Object cs = intern ("utf-16le");
+ Lisp_Object obj = w32_get_watch_object (notifications_desc);
+
+ /* notifications_size could be zero when the buffer of
+ notifications overflowed on the OS level, or when the
+ directory being watched was itself deleted. Do nothing in
+ that case. */
+ if (info_size
+ && !NILP (obj) && CONSP (obj))
+ {
+ Lisp_Object callback = XCDR (obj);
+
+ while (info_size >= min_size)
+ {
+ Lisp_Object utf_16_fn
+ = make_unibyte_string ((char *)fni->FileName,
+ fni->FileNameLength);
+ /* Note: mule-conf is preloaded, so utf-16le must
+ already be defined at this point. */
+ Lisp_Object fname
+ = code_convert_string_norecord (utf_16_fn, cs, 0);
+ Lisp_Object action = lispy_file_action (fni->Action);
+
+ event->kind = FILE_NOTIFY_EVENT;
+ event->code
+ = (ptrdiff_t)XINT (XIL ((EMACS_INT)notifications_desc));
+ event->timestamp = msg->msg.time;
+ event->modifiers = 0;
+ event->frame_or_window = callback;
+ event->arg = Fcons (action, fname);
+ kbd_buffer_store_event (event);
+ (*evcount)++;
+
+ if (!fni->NextEntryOffset)
+ break;
+ p += fni->NextEntryOffset;
+ fni = (PFILE_NOTIFY_INFORMATION)p;
+ info_size -= fni->NextEntryOffset;
+ }
+ }
+ notification_buffer_in_use = 0;
+ }
+ else
+ DebPrint (("We were promised notifications, but in-use flag is zero!\n"));
+ leave_crit ();
+
+ /* We've stuffed all the events ourselves, so w32_read_socket shouldn't. */
+ event->kind = NO_EVENT;
+}
+#endif /* WINDOWSNT */
+#endif /* HAVE_W32NOTIFY */
+
\f
/* Function to report a mouse movement to the mainstream Emacs code.
The input handler calls this.
static Lisp_Object last_mouse_motion_frame;
static int
-note_mouse_movement (FRAME_PTR frame, MSG *msg)
+note_mouse_movement (struct frame *frame, MSG *msg)
{
int mouse_x = LOWORD (msg->lParam);
int mouse_y = HIWORD (msg->lParam);
************************************************************************/
static struct scroll_bar *x_window_to_scroll_bar (Window);
-static void x_scroll_bar_report_motion (FRAME_PTR *, Lisp_Object *,
+static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *,
enum scroll_bar_part *,
Lisp_Object *, Lisp_Object *,
unsigned long *);
movement. */
static void
-w32_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window,
+w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y,
unsigned long *time)
{
- FRAME_PTR f1;
+ struct frame *f1;
block_input ();
static struct scroll_bar *
x_window_to_scroll_bar (Window window_id)
{
- Lisp_Object tail;
+ Lisp_Object tail, frame;
- for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+ FOR_EACH_FRAME (tail, frame)
{
- Lisp_Object frame, bar, condemned;
-
- frame = XCAR (tail);
- /* All elements of Vframe_list should be frames. */
- if (! FRAMEP (frame))
- emacs_abort ();
+ Lisp_Object bar, condemned;
/* Scan this frame's scroll bar list for a scroll bar with the
right window ID. */
/*#define ATTACH_THREADS*/
static BOOL
-my_show_window (FRAME_PTR f, HWND hwnd, int how)
+my_show_window (struct frame *f, HWND hwnd, int how)
{
#ifndef ATTACH_THREADS
return SendMessage (FRAME_W32_WINDOW (f), WM_EMACS_SHOWWINDOW,
HWND hwnd;
SCROLLINFO si;
struct scroll_bar *bar
- = XSCROLL_BAR (Fmake_vector (make_number (SCROLL_BAR_VEC_SIZE), Qnil));
+ = ALLOCATE_PSEUDOVECTOR (struct scroll_bar, fringe_extended_p, PVEC_OTHER);
Lisp_Object barobj;
block_input ();
XSETINT (bar->start, 0);
XSETINT (bar->end, 0);
bar->dragging = Qnil;
- bar->fringe_extended_p = Qnil;
+ bar->fringe_extended_p = 0;
/* Requires geometry to be set before call to create the real window */
static void
x_scroll_bar_remove (struct scroll_bar *bar)
{
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
block_input ();
struct scroll_bar *bar;
int top, height, left, sb_left, width, sb_width;
int window_y, window_height;
- int fringe_extended_p;
+ bool fringe_extended_p;
/* Get window dimensions. */
window_box (w, -1, 0, &window_y, 0, &window_height);
else
sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
- if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
- fringe_extended_p = (WINDOW_LEFTMOST_P (w)
- && WINDOW_LEFT_FRINGE_WIDTH (w)
- && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
- || WINDOW_LEFT_MARGIN_COLS (w) == 0));
- else
- fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
- && WINDOW_RIGHT_FRINGE_WIDTH (w)
- && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
- || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
+ fringe_extended_p = WINDOW_FRINGE_EXTENDED_P (w);
/* Does the scroll bar exist yet? */
if (NILP (w->vertical_scroll_bar))
hwnd = SCROLL_BAR_W32_WINDOW (bar);
/* If already correctly positioned, do nothing. */
- if ( XINT (bar->left) == sb_left
- && XINT (bar->top) == top
- && XINT (bar->width) == sb_width
- && XINT (bar->height) == height
- && !NILP (bar->fringe_extended_p) == fringe_extended_p )
+ if (XINT (bar->left) == sb_left
+ && XINT (bar->top) == top
+ && XINT (bar->width) == sb_width
+ && XINT (bar->height) == height
+ && bar->fringe_extended_p == fringe_extended_p)
{
/* Redraw after clear_frame. */
if (!my_show_window (f, hwnd, SW_NORMAL))
unblock_input ();
}
}
- bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
+ bar->fringe_extended_p = fringe_extended_p;
w32_set_scroll_bar_thumb (bar, portion, position, whole);
XSETVECTOR (barobj, bar);
`*redeem_scroll_bar_hook' is applied to its window before the judgment. */
static void
-w32_condemn_scroll_bars (FRAME_PTR frame)
+w32_condemn_scroll_bars (struct frame *frame)
{
/* Transfer all the scroll bars to FRAME_CONDEMNED_SCROLL_BARS. */
while (! NILP (FRAME_SCROLL_BARS (frame)))
last call to `*condemn_scroll_bars_hook'. */
static void
-w32_judge_scroll_bars (FRAME_PTR f)
+w32_judge_scroll_bars (struct frame *f)
{
Lisp_Object bar, next;
on the scroll bar. */
static void
-x_scroll_bar_report_motion (FRAME_PTR *fp, Lisp_Object *bar_window,
+x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window,
enum scroll_bar_part *part,
Lisp_Object *x, Lisp_Object *y,
unsigned long *time)
{
struct scroll_bar *bar = XSCROLL_BAR (last_mouse_scroll_bar);
Window w = SCROLL_BAR_W32_WINDOW (bar);
- FRAME_PTR f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
+ struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
int pos;
int top_range = VERTICAL_SCROLL_BAR_TOP_RANGE (f, XINT (bar->height));
SCROLLINFO si;
redraw them. */
void
-x_scroll_bar_clear (FRAME_PTR f)
+x_scroll_bar_clear (struct frame *f)
{
Lisp_Object bar;
DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,
SDATA (f->name)));
}
- else if (f->async_visible != 1)
+ else if (FRAME_VISIBLE_P (f) != 1)
{
+ bool iconified = FRAME_ICONIFIED_P (f);
+
/* Definitely not obscured, so mark as visible. */
- f->async_visible = 1;
- f->async_iconified = 0;
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, 0);
SET_FRAME_GARBAGED (f);
- DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
- SDATA (f->name)));
+ if (!f->output_data.w32->asked_for_visible)
+ DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
+ SDATA (f->name)));
/* WM_PAINT serves as MapNotify as well, so report
visibility changes properly. */
- if (f->iconified)
+ if (iconified)
{
inev.kind = DEICONIFY_EVENT;
XSETFRAME (inev.frame_or_window, f);
}
- else if (! NILP (Vframe_list)
- && ! NILP (XCDR (Vframe_list)))
+ else if (!NILP (Vframe_list) && !NILP (XCDR (Vframe_list)))
/* Force a redisplay sooner or later to update the
frame titles in case this is the second frame. */
record_asynch_buffer_change ();
case WM_SYSKEYDOWN:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
- if (f && !f->iconified)
+ if (f && !FRAME_ICONIFIED_P (f))
{
if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
&& !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
case WM_CHAR:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
- if (f && !f->iconified)
+ if (f && !FRAME_ICONIFIED_P (f))
{
if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
&& !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
case WM_APPCOMMAND:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
- if (f && !f->iconified)
+ if (f && !FRAME_ICONIFIED_P (f))
{
if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
&& !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
{
/* If we decide we want to generate an event to be seen
by the rest of Emacs, we put it here. */
- int tool_bar_p = 0;
+ bool tool_bar_p = 0;
int button;
int up;
}
case WM_WINDOWPOSCHANGED:
- f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
- if (f)
- {
- if (f->want_fullscreen & FULLSCREEN_WAIT)
- f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
- }
- check_visibility = 1;
- break;
-
case WM_ACTIVATE:
case WM_ACTIVATEAPP:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
- x_check_fullscreen (f);
+ {
+ /* Run the full-screen hook function also when we are
+ being activated, to actually install the required
+ size in effect, if the WAIT flag is set. This is
+ because when the hook is run from x_set_fullscreen,
+ the frame might not yet be visible, if that call is a
+ result of make-frame, and in that case the hook just
+ sets the WAIT flag. */
+ if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam)
+ && (f->want_fullscreen & FULLSCREEN_WAIT))
+ w32fullscreen_hook (f);
+ x_check_fullscreen (f);
+ }
check_visibility = 1;
break;
case WM_MOVE:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
- if (f && !f->async_iconified)
+ if (f && !FRAME_ICONIFIED_P (f))
{
int x, y;
switch (msg.msg.wParam)
{
case SIZE_MINIMIZED:
- f->async_visible = 0;
- f->async_iconified = 1;
+ SET_FRAME_VISIBLE (f, 0);
+ SET_FRAME_ICONIFIED (f, 1);
inev.kind = ICONIFY_EVENT;
XSETFRAME (inev.frame_or_window, f);
case SIZE_MAXIMIZED:
case SIZE_RESTORED:
- f->async_visible = 1;
- f->async_iconified = 0;
-
- /* wait_reading_process_output will notice this and update
- the frame's display structures. */
- SET_FRAME_GARBAGED (f);
+ {
+ bool iconified = FRAME_ICONIFIED_P (f);
- if (f->iconified)
- {
- int x, y;
+ if (iconified)
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, 0);
- /* Reset top and left positions of the Window
- here since Windows sends a WM_MOVE message
- BEFORE telling us the Window is minimized
- when the Window is iconified, with 3000,3000
- as the co-ords. */
- x_real_positions (f, &x, &y);
- f->left_pos = x;
- f->top_pos = y;
+ /* wait_reading_process_output will notice this
+ and update the frame's display structures. */
+ SET_FRAME_GARBAGED (f);
- inev.kind = DEICONIFY_EVENT;
- XSETFRAME (inev.frame_or_window, f);
- }
- else if (! NILP (Vframe_list)
- && ! NILP (XCDR (Vframe_list)))
- /* Force a redisplay sooner or later
- to update the frame titles
- in case this is the second frame. */
- record_asynch_buffer_change ();
+ if (iconified)
+ {
+ int x, y;
+
+ /* Reset top and left positions of the Window
+ here since Windows sends a WM_MOVE message
+ BEFORE telling us the Window is minimized
+ when the Window is iconified, with 3000,3000
+ as the co-ords. */
+ x_real_positions (f, &x, &y);
+ f->left_pos = x;
+ f->top_pos = y;
+
+ inev.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
+ }
+ else if (! NILP (Vframe_list)
+ && ! NILP (XCDR (Vframe_list)))
+ /* Force a redisplay sooner or later
+ to update the frame titles
+ in case this is the second frame. */
+ record_asynch_buffer_change ();
+ }
break;
}
}
- if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED)
+ if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED)
{
RECT rect;
int rows;
break;
case WM_KILLFOCUS:
+ w32_detect_focus_change (dpyinfo, &msg, &inev);
f = x_top_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
{
- if (f == dpyinfo->w32_focus_event_frame)
- dpyinfo->w32_focus_event_frame = 0;
-
- if (f == dpyinfo->w32_focus_frame)
- x_new_focus_frame (dpyinfo, 0);
-
if (f == hlinfo->mouse_face_mouse_frame)
{
/* If we move outside the frame, then we're
if (f)
{
extern void menubar_selection_callback
- (FRAME_PTR f, void * client_data);
+ (struct frame *f, void * client_data);
menubar_selection_callback (f, (void *)msg.msg.wParam);
}
check_visibility = 1;
break;
+#if HAVE_W32NOTIFY
+ case WM_EMACS_FILENOTIFY:
+ f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
+ if (f)
+ queue_notifications (&inev, &msg, f, &count);
+ break;
+#endif
+
default:
/* Check for messages registered at runtime. */
if (msg.msg.message == msh_mousewheel)
FOR_EACH_FRAME (tail, frame)
{
- FRAME_PTR f = XFRAME (frame);
+ struct frame *f = XFRAME (frame);
/* The tooltip has been drawn already. Avoid the
SET_FRAME_GARBAGED below. */
if (EQ (frame, tip_frame))
continue;
/* Check "visible" frames and mark each as obscured or not.
- Note that async_visible is nonzero for unobscured and
- obscured frames, but zero for hidden and iconified frames. */
- if (FRAME_W32_P (f) && f->async_visible)
+ Note that visible is nonzero for unobscured and obscured
+ frames, but zero for hidden and iconified frames. */
+ if (FRAME_W32_P (f) && FRAME_VISIBLE_P (f))
{
RECT clipbox;
HDC hdc;
+ bool obscured;
enter_crit ();
/* Query clipping rectangle for the entire window area
ReleaseDC (FRAME_W32_WINDOW (f), hdc);
leave_crit ();
- if (clipbox.right == clipbox.left
- || clipbox.bottom == clipbox.top)
+ obscured = FRAME_OBSCURED_P (f);
+
+ if (clipbox.right == clipbox.left || clipbox.bottom == clipbox.top)
{
- /* Frame has become completely obscured so mark as
- such (we do this by setting async_visible to 2 so
- that FRAME_VISIBLE_P is still true, but redisplay
- will skip it). */
- f->async_visible = 2;
+ /* Frame has become completely obscured so mark as such (we
+ do this by setting visible to 2 so that FRAME_VISIBLE_P
+ is still true, but redisplay will skip it). */
+ SET_FRAME_VISIBLE (f, 2);
- if (!FRAME_OBSCURED_P (f))
- {
- DebPrint (("frame %p (%s) obscured\n", f,
- SDATA (f->name)));
- }
+ if (!obscured)
+ DebPrint (("frame %p (%s) obscured\n", f, SDATA (f->name)));
}
else
{
/* Frame is not obscured, so mark it as such. */
- f->async_visible = 1;
+ SET_FRAME_VISIBLE (f, 1);
- if (FRAME_OBSCURED_P (f))
+ if (obscured)
{
SET_FRAME_GARBAGED (f);
- DebPrint (("obscured frame %p (%s) found to be visible\n", f,
- SDATA (f->name)));
+ DebPrint (("obscured frame %p (%s) found to be visible\n",
+ f, SDATA (f->name)));
/* Force a redisplay sooner or later. */
record_asynch_buffer_change ();
the current matrix is invalid or such, give up. */
cursor_glyph = get_phys_cursor_glyph (w);
if (cursor_glyph == NULL)
- return;
+ {
+ DeleteObject (hb);
+ return;
+ }
/* Compute frame-relative coordinates for phys cursor. */
get_phys_cursor_geometry (w, row, cursor_glyph, &left, &top, &h);
w32_system_caret_y
= (WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y)
+ glyph_row->ascent - w->phys_cursor_ascent);
+ w32_system_caret_window = w;
+ w32_system_caret_hdr_height = WINDOW_HEADER_LINE_HEIGHT (w);
+ w32_system_caret_mode_height = WINDOW_MODE_LINE_HEIGHT (w);
PostMessage (hwnd, WM_IME_STARTCOMPOSITION, 0, 0);
FRAME_FONT (f) = font;
FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
FRAME_COLUMN_WIDTH (f) = font->average_width;
- FRAME_SPACE_WIDTH (f) = font->space_width;
FRAME_LINE_HEIGHT (f) = font->height;
compute_fringe_widths (f, 1);
}
}
+static void
+w32fullscreen_hook (struct frame *f)
+{
+ if (FRAME_VISIBLE_P (f))
+ {
+ HWND hwnd = FRAME_W32_WINDOW(f);
+ DWORD dwStyle = GetWindowLong (hwnd, GWL_STYLE);
+ RECT rect;
+
+ block_input();
+ f->want_fullscreen &= ~FULLSCREEN_WAIT;
+
+ if (FRAME_PREV_FSMODE (f) == FULLSCREEN_NONE)
+ GetWindowPlacement (hwnd, &FRAME_NORMAL_PLACEMENT (f));
+
+ if (FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH)
+ {
+ SetWindowLong (hwnd, GWL_STYLE, dwStyle | WS_OVERLAPPEDWINDOW);
+ SetWindowPos (hwnd, NULL, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
+ SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
+ }
+
+ w32_fullscreen_rect (hwnd, f->want_fullscreen,
+ FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect);
+ FRAME_PREV_FSMODE (f) = f->want_fullscreen;
+ if (f->want_fullscreen == FULLSCREEN_MAXIMIZED)
+ PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, 0xf030, 0);
+ else if (f->want_fullscreen == FULLSCREEN_BOTH)
+ {
+ SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW);
+ SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top,
+ SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
+ }
+ else
+ {
+ SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top, 0);
+ }
+
+ f->want_fullscreen = FULLSCREEN_NONE;
+ unblock_input ();
+ }
+ else
+ f->want_fullscreen |= FULLSCREEN_WAIT;
+}
+
/* Call this to change the size of frame F's x-window.
If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
for this size change and subsequent size changes.
unblock_input ();
}
-void
-x_unfocus_frame (struct frame *f)
-{
-}
-
/* Raise frame F. */
void
x_raise_frame (struct frame *f)
}
static void
-w32_frame_raise_lower (FRAME_PTR f, int raise_flag)
+w32_frame_raise_lower (struct frame *f, int raise_flag)
{
if (! FRAME_W32_P (f))
return;
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. */
+ we need it to avoid Bug#5482. It seems that 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_SHOWNORMAL);
+ FRAME_ICONIFIED_P (f) ? SW_RESTORE : SW_SHOWNORMAL);
}
/* Synchronize to ensure Emacs knows the frame is visible
poll_suppress_count = old_poll_suppress_count;
}
}
- FRAME_SAMPLE_VISIBILITY (f);
}
}
So we can't win using the usual strategy of letting
FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
and synchronize with the server to make sure we agree. */
- f->visible = 0;
- FRAME_ICONIFIED_P (f) = 0;
- f->async_visible = 0;
- f->async_iconified = 0;
+ SET_FRAME_VISIBLE (f, 0);
+ SET_FRAME_ICONIFIED (f, 0);
unblock_input ();
}
if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
- if (f->async_iconified)
+ if (FRAME_ICONIFIED_P (f))
return;
block_input ();
/* Simulate the user minimizing the frame. */
SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MINIMIZE, 0);
+ SET_FRAME_VISIBLE (f, 0);
+ SET_FRAME_ICONIFIED (f, 1);
+
unblock_input ();
}
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;
}
leave_crit ();
}
-/* Window manager things */
-void
-x_wm_set_icon_position (struct frame *f, int icon_x, int icon_y)
-{
-#if 0
- Window window = FRAME_W32_WINDOW (f);
-
- f->display.x->wm_hints.flags |= IconPositionHint;
- f->display.x->wm_hints.icon_x = icon_x;
- f->display.x->wm_hints.icon_y = icon_y;
-
- XSetWMHints (FRAME_X_DISPLAY (f), window, &f->display.x->wm_hints);
-#endif
-}
-
-\f
/***********************************************************************
Fonts
***********************************************************************/
terminal->mouse_position_hook = w32_mouse_position;
terminal->frame_rehighlight_hook = w32_frame_rehighlight;
terminal->frame_raise_lower_hook = w32_frame_raise_lower;
- /* terminal->fullscreen_hook = XTfullscreen_hook; */
+ terminal->fullscreen_hook = w32fullscreen_hook;
terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
}
#ifdef CYGWIN
- if ((w32_message_fd = open ("/dev/windows", O_RDWR | O_CLOEXEC)) == -1)
+ if ((w32_message_fd = emacs_open ("/dev/windows", O_RDWR, 0)) == -1)
fatal ("opening /dev/windows: %s", strerror (errno));
#endif /* CYGWIN */
Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
{
- DWORD input_locale_id = (DWORD) GetKeyboardLayout (0);
+ DWORD input_locale_id = ((DWORD_PTR) GetKeyboardLayout (0) & 0xffffffff);
w32_keyboard_codepage =
codepage_for_locale ((LCID) (input_locale_id & 0xffff));
}
DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
+ DEFSYM (Qadded, "added");
+ DEFSYM (Qremoved, "removed");
+ DEFSYM (Qmodified, "modified");
+ DEFSYM (Qrenamed_from, "renamed-from");
+ DEFSYM (Qrenamed_to, "renamed-to");
+
DEFVAR_INT ("w32-num-mouse-buttons",
w32_num_mouse_buttons,
doc: /* Number of physical mouse buttons. */);