aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32term.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/w32term.c')
-rw-r--r--src/w32term.c458
1 files changed, 348 insertions, 110 deletions
diff --git a/src/w32term.c b/src/w32term.c
index ab6afd32c75..5f7952c2ec2 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -1,6 +1,6 @@
1/* Implementation of GUI terminal on the Microsoft Windows API. 1/* Implementation of GUI terminal on the Microsoft Windows API.
2 2
3Copyright (C) 1989, 1993-2012 Free Software Foundation, Inc. 3Copyright (C) 1989, 1993-2013 Free Software Foundation, Inc.
4 4
5This file is part of GNU Emacs. 5This file is part of GNU Emacs.
6 6
@@ -109,9 +109,10 @@ struct w32_display_info *x_display_list;
109Lisp_Object w32_display_name_list; 109Lisp_Object w32_display_name_list;
110 110
111 111
112#if _WIN32_WINNT < 0x0500 112#if _WIN32_WINNT < 0x0500 && !defined(_W64)
113/* Pre Windows 2000, this was not available, but define it here so 113/* Pre Windows 2000, this was not available, but define it here so
114 that Emacs compiled on such a platform will run on newer versions. */ 114 that Emacs compiled on such a platform will run on newer versions.
115 MinGW64 (_W64) defines these unconditionally, so avoid redefining. */
115 116
116typedef struct tagWCRANGE 117typedef struct tagWCRANGE
117{ 118{
@@ -191,11 +192,7 @@ static Time last_mouse_movement_time;
191 192
192/* Incremented by w32_read_socket whenever it really tries to read 193/* Incremented by w32_read_socket whenever it really tries to read
193 events. */ 194 events. */
194#ifdef __STDC__
195static int volatile input_signal_count; 195static int volatile input_signal_count;
196#else
197static int input_signal_count;
198#endif
199 196
200#ifdef CYGWIN 197#ifdef CYGWIN
201int w32_message_fd = -1; 198int w32_message_fd = -1;
@@ -240,12 +237,15 @@ static void my_set_focus (struct frame *, HWND);
240#endif 237#endif
241static void my_set_foreground_window (HWND); 238static void my_set_foreground_window (HWND);
242static void my_destroy_window (struct frame *, HWND); 239static void my_destroy_window (struct frame *, HWND);
240static void w32fullscreen_hook (FRAME_PTR);
243 241
244#ifdef GLYPH_DEBUG 242#ifdef GLYPH_DEBUG
245static void x_check_font (struct frame *, struct font *); 243static void x_check_font (struct frame *, struct font *);
246#endif 244#endif
247 245
248static Lisp_Object Qvendor_specific_keysyms; 246static Lisp_Object Qvendor_specific_keysyms;
247static Lisp_Object Qadded, Qremoved, Qmodified;
248static Lisp_Object Qrenamed_from, Qrenamed_to;
249 249
250 250
251/*********************************************************************** 251/***********************************************************************
@@ -356,7 +356,7 @@ w32_restore_glyph_string_clip (struct glyph_string *s)
356void 356void
357w32_draw_underwave (struct glyph_string *s, COLORREF color) 357w32_draw_underwave (struct glyph_string *s, COLORREF color)
358{ 358{
359 int wave_height = 2, wave_length = 3; 359 int wave_height = 3, wave_length = 2;
360 int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax; 360 int dx, dy, x0, y0, width, x1, y1, x2, y2, odd, xmax;
361 XRectangle wave_clip, string_clip, final_clip; 361 XRectangle wave_clip, string_clip, final_clip;
362 RECT w32_final_clip, w32_string_clip; 362 RECT w32_final_clip, w32_string_clip;
@@ -365,7 +365,7 @@ w32_draw_underwave (struct glyph_string *s, COLORREF color)
365 dx = wave_length; 365 dx = wave_length;
366 dy = wave_height - 1; 366 dy = wave_height - 1;
367 x0 = s->x; 367 x0 = s->x;
368 y0 = s->ybase + 1; 368 y0 = s->ybase - wave_height + 3;
369 width = s->width; 369 width = s->width;
370 xmax = x0 + width; 370 xmax = x0 + width;
371 371
@@ -1738,8 +1738,8 @@ w32_draw_relief_rect (struct frame *f,
1738 if (left_p) 1738 if (left_p)
1739 for (i = 0; i < width; ++i) 1739 for (i = 0; i < width; ++i)
1740 w32_fill_area (f, hdc, gc.foreground, 1740 w32_fill_area (f, hdc, gc.foreground,
1741 left_x + i, top_y + i, 1, 1741 left_x + i, top_y + (i + 1) * top_p, 1,
1742 bottom_y - top_y - 2 * i + 1); 1742 bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1);
1743 1743
1744 if (raised_p) 1744 if (raised_p)
1745 gc.foreground = f->output_data.w32->black_relief.gc->foreground; 1745 gc.foreground = f->output_data.w32->black_relief.gc->foreground;
@@ -1757,8 +1757,8 @@ w32_draw_relief_rect (struct frame *f,
1757 if (right_p) 1757 if (right_p)
1758 for (i = 0; i < width; ++i) 1758 for (i = 0; i < width; ++i)
1759 w32_fill_area (f, hdc, gc.foreground, 1759 w32_fill_area (f, hdc, gc.foreground,
1760 right_x - i, top_y + i + 1, 1, 1760 right_x - i, top_y + (i + 1) * top_p, 1,
1761 bottom_y - top_y - 2 * i - 1); 1761 bottom_y - top_y - (i + 1) * (bot_p + top_p) + 1);
1762 1762
1763 w32_set_clip_rectangle (hdc, NULL); 1763 w32_set_clip_rectangle (hdc, NULL);
1764 1764
@@ -1952,7 +1952,7 @@ x_draw_image_foreground (struct glyph_string *s)
1952static void 1952static void
1953x_draw_image_relief (struct glyph_string *s) 1953x_draw_image_relief (struct glyph_string *s)
1954{ 1954{
1955 int x0, y0, x1, y1, thick, raised_p; 1955 int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p;
1956 RECT r; 1956 RECT r;
1957 int x = s->x; 1957 int x = s->x;
1958 int y = s->ybase - image_ascent (s->img, s->face, &s->slice); 1958 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
@@ -1984,19 +1984,23 @@ x_draw_image_relief (struct glyph_string *s)
1984 raised_p = s->img->relief > 0; 1984 raised_p = s->img->relief > 0;
1985 } 1985 }
1986 1986
1987 x0 = x - thick; 1987 x1 = x + s->slice.width - 1;
1988 y0 = y - thick; 1988 y1 = y + s->slice.height - 1;
1989 x1 = x + s->slice.width + thick - 1; 1989 top_p = bot_p = left_p = right_p = 0;
1990 y1 = y + s->slice.height + thick - 1; 1990
1991 if (s->slice.x == 0)
1992 x -= thick, left_p = 1;
1993 if (s->slice.y == 0)
1994 y -= thick, top_p = 1;
1995 if (s->slice.x + s->slice.width == s->img->width)
1996 x1 += thick, right_p = 1;
1997 if (s->slice.y + s->slice.height == s->img->height)
1998 y1 += thick, bot_p = 1;
1991 1999
1992 x_setup_relief_colors (s); 2000 x_setup_relief_colors (s);
1993 get_glyph_string_clip_rect (s, &r); 2001 get_glyph_string_clip_rect (s, &r);
1994 w32_draw_relief_rect (s->f, x0, y0, x1, y1, thick, raised_p, 2002 w32_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
1995 s->slice.y == 0, 2003 top_p, bot_p, left_p, right_p, &r);
1996 s->slice.y + s->slice.height == s->img->height,
1997 s->slice.x == 0,
1998 s->slice.x + s->slice.width == s->img->width,
1999 &r);
2000} 2004}
2001 2005
2002 2006
@@ -2450,7 +2454,8 @@ x_draw_glyph_string (struct glyph_string *s)
2450 unsigned long thickness, position; 2454 unsigned long thickness, position;
2451 int y; 2455 int y;
2452 2456
2453 if (s->prev && s->prev->face->underline_p) 2457 if (s->prev && s->prev->face->underline_p
2458 && s->prev->face->underline_type == FACE_UNDER_LINE)
2454 { 2459 {
2455 /* We use the same underline style as the previous one. */ 2460 /* We use the same underline style as the previous one. */
2456 thickness = s->prev->underline_thickness; 2461 thickness = s->prev->underline_thickness;
@@ -3158,7 +3163,7 @@ construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f)
3158 HDROP hdrop; 3163 HDROP hdrop;
3159 POINT p; 3164 POINT p;
3160 WORD num_files; 3165 WORD num_files;
3161 char *name; 3166 guichar_t *name;
3162 int i, len; 3167 int i, len;
3163 3168
3164 result->kind = DRAG_N_DROP_EVENT; 3169 result->kind = DRAG_N_DROP_EVENT;
@@ -3183,12 +3188,17 @@ construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f)
3183 3188
3184 for (i = 0; i < num_files; i++) 3189 for (i = 0; i < num_files; i++)
3185 { 3190 {
3186 len = DragQueryFile (hdrop, i, NULL, 0); 3191 len = GUI_FN (DragQueryFile) (hdrop, i, NULL, 0);
3187 if (len <= 0) 3192 if (len <= 0)
3188 continue; 3193 continue;
3189 name = alloca (len + 1); 3194
3190 DragQueryFile (hdrop, i, name, len + 1); 3195 name = alloca ((len + 1) * sizeof (*name));
3196 GUI_FN (DragQueryFile) (hdrop, i, name, len + 1);
3197#ifdef NTGUI_UNICODE
3198 files = Fcons (from_unicode_buffer (name), files);
3199#else
3191 files = Fcons (DECODE_FILE (build_string (name)), files); 3200 files = Fcons (DECODE_FILE (build_string (name)), files);
3201#endif /* NTGUI_UNICODE */
3192 } 3202 }
3193 3203
3194 DragFinish (hdrop); 3204 DragFinish (hdrop);
@@ -3200,6 +3210,124 @@ construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f)
3200} 3210}
3201 3211
3202 3212
3213/* File event notifications (see w32notify.c). */
3214
3215Lisp_Object
3216lispy_file_action (DWORD action)
3217{
3218 static char unknown_fmt[] = "unknown-action(%d)";
3219 Lisp_Object retval;
3220
3221 switch (action)
3222 {
3223 case FILE_ACTION_ADDED:
3224 retval = Qadded;
3225 break;
3226 case FILE_ACTION_REMOVED:
3227 retval = Qremoved;
3228 break;
3229 case FILE_ACTION_MODIFIED:
3230 retval = Qmodified;
3231 break;
3232 case FILE_ACTION_RENAMED_OLD_NAME:
3233 retval = Qrenamed_from;
3234 break;
3235 case FILE_ACTION_RENAMED_NEW_NAME:
3236 retval = Qrenamed_to;
3237 break;
3238 default:
3239 {
3240 char buf[sizeof(unknown_fmt) - 1 + INT_STRLEN_BOUND (DWORD)];
3241
3242 sprintf (buf, unknown_fmt, action);
3243 retval = intern (buf);
3244 }
3245 break;
3246 }
3247
3248 return retval;
3249}
3250
3251#ifdef WINDOWSNT
3252/* Put file notifications into the Emacs input event queue. This
3253 function runs when the WM_EMACS_FILENOTIFY message arrives from a
3254 watcher thread. */
3255static void
3256queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
3257 int *evcount)
3258{
3259 BYTE *p = file_notifications;
3260 FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
3261 const DWORD min_size
3262 = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
3263 Lisp_Object frame;
3264
3265 /* We cannot process notification before Emacs is fully initialized,
3266 since we need the UTF-16LE coding-system to be set up. */
3267 if (!initialized)
3268 {
3269 notification_buffer_in_use = 0;
3270 return;
3271 }
3272
3273 XSETFRAME (frame, f);
3274
3275 enter_crit ();
3276 if (notification_buffer_in_use)
3277 {
3278 DWORD info_size = notifications_size;
3279 Lisp_Object cs = intern ("utf-16le");
3280 Lisp_Object obj = w32_get_watch_object (notifications_desc);
3281
3282 /* notifications_size could be zero when the buffer of
3283 notifications overflowed on the OS level, or when the
3284 directory being watched was itself deleted. Do nothing in
3285 that case. */
3286 if (info_size
3287 && !NILP (obj) && CONSP (obj))
3288 {
3289 Lisp_Object callback = XCDR (obj);
3290
3291 while (info_size >= min_size)
3292 {
3293 Lisp_Object utf_16_fn
3294 = make_unibyte_string ((char *)fni->FileName,
3295 fni->FileNameLength);
3296 /* Note: mule-conf is preloaded, so utf-16le must
3297 already be defined at this point. */
3298 Lisp_Object fname
3299 = code_convert_string_norecord (utf_16_fn, cs, 0);
3300 Lisp_Object action = lispy_file_action (fni->Action);
3301
3302 event->kind = FILE_NOTIFY_EVENT;
3303 event->code
3304 = (ptrdiff_t)XINT (XIL ((EMACS_INT)notifications_desc));
3305 event->timestamp = msg->msg.time;
3306 event->modifiers = 0;
3307 event->frame_or_window = callback;
3308 event->arg = Fcons (action, fname);
3309 kbd_buffer_store_event (event);
3310 (*evcount)++;
3311
3312 if (!fni->NextEntryOffset)
3313 break;
3314 p += fni->NextEntryOffset;
3315 fni = (PFILE_NOTIFY_INFORMATION)p;
3316 info_size -= fni->NextEntryOffset;
3317 }
3318 }
3319 notification_buffer_in_use = 0;
3320 }
3321 else
3322 DebPrint (("We were promised notifications, but in-use flag is zero!\n"));
3323 leave_crit ();
3324
3325 /* We've stuffed all the events ourselves, so w32_read_socket shouldn't. */
3326 event->kind = NO_EVENT;
3327}
3328#endif
3329
3330
3203/* Function to report a mouse movement to the mainstream Emacs code. 3331/* Function to report a mouse movement to the mainstream Emacs code.
3204 The input handler calls this. 3332 The input handler calls this.
3205 3333
@@ -4194,24 +4322,25 @@ w32_read_socket (struct terminal *terminal,
4194 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f, 4322 DebPrint (("clipped frame %p (%s) got WM_PAINT - ignored\n", f,
4195 SDATA (f->name))); 4323 SDATA (f->name)));
4196 } 4324 }
4197 else if (f->async_visible != 1) 4325 else if (FRAME_VISIBLE_P (f) != 1)
4198 { 4326 {
4327 bool iconified = FRAME_ICONIFIED_P (f);
4328
4199 /* Definitely not obscured, so mark as visible. */ 4329 /* Definitely not obscured, so mark as visible. */
4200 f->async_visible = 1; 4330 SET_FRAME_VISIBLE (f, 1);
4201 f->async_iconified = 0; 4331 SET_FRAME_ICONIFIED (f, 0);
4202 SET_FRAME_GARBAGED (f); 4332 SET_FRAME_GARBAGED (f);
4203 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f, 4333 DebPrint (("frame %p (%s) reexposed by WM_PAINT\n", f,
4204 SDATA (f->name))); 4334 SDATA (f->name)));
4205 4335
4206 /* WM_PAINT serves as MapNotify as well, so report 4336 /* WM_PAINT serves as MapNotify as well, so report
4207 visibility changes properly. */ 4337 visibility changes properly. */
4208 if (f->iconified) 4338 if (iconified)
4209 { 4339 {
4210 inev.kind = DEICONIFY_EVENT; 4340 inev.kind = DEICONIFY_EVENT;
4211 XSETFRAME (inev.frame_or_window, f); 4341 XSETFRAME (inev.frame_or_window, f);
4212 } 4342 }
4213 else if (! NILP (Vframe_list) 4343 else if (!NILP (Vframe_list) && !NILP (XCDR (Vframe_list)))
4214 && ! NILP (XCDR (Vframe_list)))
4215 /* Force a redisplay sooner or later to update the 4344 /* Force a redisplay sooner or later to update the
4216 frame titles in case this is the second frame. */ 4345 frame titles in case this is the second frame. */
4217 record_asynch_buffer_change (); 4346 record_asynch_buffer_change ();
@@ -4254,7 +4383,7 @@ w32_read_socket (struct terminal *terminal,
4254 case WM_SYSKEYDOWN: 4383 case WM_SYSKEYDOWN:
4255 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 4384 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4256 4385
4257 if (f && !f->iconified) 4386 if (f && !FRAME_ICONIFIED_P (f))
4258 { 4387 {
4259 if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) 4388 if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
4260 && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) 4389 && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
@@ -4279,7 +4408,7 @@ w32_read_socket (struct terminal *terminal,
4279 case WM_CHAR: 4408 case WM_CHAR:
4280 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 4409 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4281 4410
4282 if (f && !f->iconified) 4411 if (f && !FRAME_ICONIFIED_P (f))
4283 { 4412 {
4284 if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) 4413 if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
4285 && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) 4414 && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
@@ -4357,7 +4486,7 @@ w32_read_socket (struct terminal *terminal,
4357 case WM_APPCOMMAND: 4486 case WM_APPCOMMAND:
4358 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 4487 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4359 4488
4360 if (f && !f->iconified) 4489 if (f && !FRAME_ICONIFIED_P (f))
4361 { 4490 {
4362 if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight) 4491 if (!hlinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
4363 && !EQ (f->tool_bar_window, hlinfo->mouse_face_window)) 4492 && !EQ (f->tool_bar_window, hlinfo->mouse_face_window))
@@ -4577,27 +4706,30 @@ w32_read_socket (struct terminal *terminal,
4577 } 4706 }
4578 4707
4579 case WM_WINDOWPOSCHANGED: 4708 case WM_WINDOWPOSCHANGED:
4580 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4581 if (f)
4582 {
4583 if (f->want_fullscreen & FULLSCREEN_WAIT)
4584 f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
4585 }
4586 check_visibility = 1;
4587 break;
4588
4589 case WM_ACTIVATE: 4709 case WM_ACTIVATE:
4590 case WM_ACTIVATEAPP: 4710 case WM_ACTIVATEAPP:
4591 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 4711 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4592 if (f) 4712 if (f)
4593 x_check_fullscreen (f); 4713 {
4714 /* Run the full-screen hook function also when we are
4715 being activated, to actually install the required
4716 size in effect, if the WAIT flag is set. This is
4717 because when the hook is run from x_set_fullscreen,
4718 the frame might not yet be visible, if that call is a
4719 result of make-frame, and in that case the hook just
4720 sets the WAIT flag. */
4721 if ((msg.msg.message == WM_WINDOWPOSCHANGED || msg.msg.wParam)
4722 && (f->want_fullscreen & FULLSCREEN_WAIT))
4723 w32fullscreen_hook (f);
4724 x_check_fullscreen (f);
4725 }
4594 check_visibility = 1; 4726 check_visibility = 1;
4595 break; 4727 break;
4596 4728
4597 case WM_MOVE: 4729 case WM_MOVE:
4598 f = x_window_to_frame (dpyinfo, msg.msg.hwnd); 4730 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4599 4731
4600 if (f && !f->async_iconified) 4732 if (f && !FRAME_ICONIFIED_P (f))
4601 { 4733 {
4602 int x, y; 4734 int x, y;
4603 4735
@@ -4645,8 +4777,8 @@ w32_read_socket (struct terminal *terminal,
4645 switch (msg.msg.wParam) 4777 switch (msg.msg.wParam)
4646 { 4778 {
4647 case SIZE_MINIMIZED: 4779 case SIZE_MINIMIZED:
4648 f->async_visible = 0; 4780 SET_FRAME_VISIBLE (f, 0);
4649 f->async_iconified = 1; 4781 SET_FRAME_ICONIFIED (f, 1);
4650 4782
4651 inev.kind = ICONIFY_EVENT; 4783 inev.kind = ICONIFY_EVENT;
4652 XSETFRAME (inev.frame_or_window, f); 4784 XSETFRAME (inev.frame_or_window, f);
@@ -4654,40 +4786,44 @@ w32_read_socket (struct terminal *terminal,
4654 4786
4655 case SIZE_MAXIMIZED: 4787 case SIZE_MAXIMIZED:
4656 case SIZE_RESTORED: 4788 case SIZE_RESTORED:
4657 f->async_visible = 1; 4789 {
4658 f->async_iconified = 0; 4790 bool iconified = FRAME_ICONIFIED_P (f);
4659
4660 /* wait_reading_process_output will notice this and update
4661 the frame's display structures. */
4662 SET_FRAME_GARBAGED (f);
4663 4791
4664 if (f->iconified) 4792 SET_FRAME_VISIBLE (f, 1);
4665 { 4793 SET_FRAME_ICONIFIED (f, 0);
4666 int x, y;
4667 4794
4668 /* Reset top and left positions of the Window 4795 /* wait_reading_process_output will notice this
4669 here since Windows sends a WM_MOVE message 4796 and update the frame's display structures. */
4670 BEFORE telling us the Window is minimized 4797 SET_FRAME_GARBAGED (f);
4671 when the Window is iconified, with 3000,3000
4672 as the co-ords. */
4673 x_real_positions (f, &x, &y);
4674 f->left_pos = x;
4675 f->top_pos = y;
4676 4798
4677 inev.kind = DEICONIFY_EVENT; 4799 if (iconified)
4678 XSETFRAME (inev.frame_or_window, f); 4800 {
4679 } 4801 int x, y;
4680 else if (! NILP (Vframe_list) 4802
4681 && ! NILP (XCDR (Vframe_list))) 4803 /* Reset top and left positions of the Window
4682 /* Force a redisplay sooner or later 4804 here since Windows sends a WM_MOVE message
4683 to update the frame titles 4805 BEFORE telling us the Window is minimized
4684 in case this is the second frame. */ 4806 when the Window is iconified, with 3000,3000
4685 record_asynch_buffer_change (); 4807 as the co-ords. */
4808 x_real_positions (f, &x, &y);
4809 f->left_pos = x;
4810 f->top_pos = y;
4811
4812 inev.kind = DEICONIFY_EVENT;
4813 XSETFRAME (inev.frame_or_window, f);
4814 }
4815 else if (! NILP (Vframe_list)
4816 && ! NILP (XCDR (Vframe_list)))
4817 /* Force a redisplay sooner or later
4818 to update the frame titles
4819 in case this is the second frame. */
4820 record_asynch_buffer_change ();
4821 }
4686 break; 4822 break;
4687 } 4823 }
4688 } 4824 }
4689 4825
4690 if (f && !f->async_iconified && msg.msg.wParam != SIZE_MINIMIZED) 4826 if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED)
4691 { 4827 {
4692 RECT rect; 4828 RECT rect;
4693 int rows; 4829 int rows;
@@ -4832,6 +4968,14 @@ w32_read_socket (struct terminal *terminal,
4832 check_visibility = 1; 4968 check_visibility = 1;
4833 break; 4969 break;
4834 4970
4971#ifdef WINDOWSNT
4972 case WM_EMACS_FILENOTIFY:
4973 f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
4974 if (f)
4975 queue_notifications (&inev, &msg, f, &count);
4976 break;
4977#endif
4978
4835 default: 4979 default:
4836 /* Check for messages registered at runtime. */ 4980 /* Check for messages registered at runtime. */
4837 if (msg.msg.message == msh_mousewheel) 4981 if (msg.msg.message == msh_mousewheel)
@@ -4907,12 +5051,13 @@ w32_read_socket (struct terminal *terminal,
4907 continue; 5051 continue;
4908 5052
4909 /* Check "visible" frames and mark each as obscured or not. 5053 /* Check "visible" frames and mark each as obscured or not.
4910 Note that async_visible is nonzero for unobscured and 5054 Note that visible is nonzero for unobscured and obscured
4911 obscured frames, but zero for hidden and iconified frames. */ 5055 frames, but zero for hidden and iconified frames. */
4912 if (FRAME_W32_P (f) && f->async_visible) 5056 if (FRAME_W32_P (f) && FRAME_VISIBLE_P (f))
4913 { 5057 {
4914 RECT clipbox; 5058 RECT clipbox;
4915 HDC hdc; 5059 HDC hdc;
5060 bool obscured;
4916 5061
4917 enter_crit (); 5062 enter_crit ();
4918 /* Query clipping rectangle for the entire window area 5063 /* Query clipping rectangle for the entire window area
@@ -4926,31 +5071,28 @@ w32_read_socket (struct terminal *terminal,
4926 ReleaseDC (FRAME_W32_WINDOW (f), hdc); 5071 ReleaseDC (FRAME_W32_WINDOW (f), hdc);
4927 leave_crit (); 5072 leave_crit ();
4928 5073
4929 if (clipbox.right == clipbox.left 5074 obscured = FRAME_OBSCURED_P (f);
4930 || clipbox.bottom == clipbox.top) 5075
5076 if (clipbox.right == clipbox.left || clipbox.bottom == clipbox.top)
4931 { 5077 {
4932 /* Frame has become completely obscured so mark as 5078 /* Frame has become completely obscured so mark as such (we
4933 such (we do this by setting async_visible to 2 so 5079 do this by setting visible to 2 so that FRAME_VISIBLE_P
4934 that FRAME_VISIBLE_P is still true, but redisplay 5080 is still true, but redisplay will skip it). */
4935 will skip it). */ 5081 SET_FRAME_VISIBLE (f, 2);
4936 f->async_visible = 2;
4937 5082
4938 if (!FRAME_OBSCURED_P (f)) 5083 if (!obscured)
4939 { 5084 DebPrint (("frame %p (%s) obscured\n", f, SDATA (f->name)));
4940 DebPrint (("frame %p (%s) obscured\n", f,
4941 SDATA (f->name)));
4942 }
4943 } 5085 }
4944 else 5086 else
4945 { 5087 {
4946 /* Frame is not obscured, so mark it as such. */ 5088 /* Frame is not obscured, so mark it as such. */
4947 f->async_visible = 1; 5089 SET_FRAME_VISIBLE (f, 1);
4948 5090
4949 if (FRAME_OBSCURED_P (f)) 5091 if (obscured)
4950 { 5092 {
4951 SET_FRAME_GARBAGED (f); 5093 SET_FRAME_GARBAGED (f);
4952 DebPrint (("obscured frame %p (%s) found to be visible\n", f, 5094 DebPrint (("obscured frame %p (%s) found to be visible\n",
4953 SDATA (f->name))); 5095 f, SDATA (f->name)));
4954 5096
4955 /* Force a redisplay sooner or later. */ 5097 /* Force a redisplay sooner or later. */
4956 record_asynch_buffer_change (); 5098 record_asynch_buffer_change ();
@@ -5344,7 +5486,6 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset)
5344 FRAME_FONT (f) = font; 5486 FRAME_FONT (f) = font;
5345 FRAME_BASELINE_OFFSET (f) = font->baseline_offset; 5487 FRAME_BASELINE_OFFSET (f) = font->baseline_offset;
5346 FRAME_COLUMN_WIDTH (f) = font->average_width; 5488 FRAME_COLUMN_WIDTH (f) = font->average_width;
5347 FRAME_SPACE_WIDTH (f) = font->space_width;
5348 FRAME_LINE_HEIGHT (f) = font->height; 5489 FRAME_LINE_HEIGHT (f) = font->height;
5349 5490
5350 compute_fringe_widths (f, 1); 5491 compute_fringe_widths (f, 1);
@@ -5517,6 +5658,100 @@ x_check_fullscreen (struct frame *f)
5517 } 5658 }
5518} 5659}
5519 5660
5661static void
5662w32fullscreen_hook (FRAME_PTR f)
5663{
5664 if (FRAME_VISIBLE_P (f))
5665 {
5666 int width, height, top_pos, left_pos, pixel_height, pixel_width;
5667 int cur_w = FRAME_COLS (f), cur_h = FRAME_LINES (f);
5668 RECT workarea_rect;
5669
5670 block_input ();
5671 /* Record current "normal" dimensions for restoring later. */
5672 if (!( FRAME_PREV_FSMODE (f) == FULLSCREEN_BOTH
5673 || FRAME_PREV_FSMODE (f) == FULLSCREEN_MAXIMIZED))
5674 {
5675 if (FRAME_PREV_FSMODE (f) != FULLSCREEN_HEIGHT)
5676 {
5677 FRAME_NORMAL_HEIGHT (f) = cur_h;
5678 FRAME_NORMAL_TOP (f) = f->top_pos;
5679 }
5680 if (FRAME_PREV_FSMODE (f) != FULLSCREEN_WIDTH)
5681 {
5682 FRAME_NORMAL_WIDTH (f) = cur_w;
5683 FRAME_NORMAL_LEFT (f) = f->left_pos;
5684 }
5685 }
5686 eassert (FRAME_NORMAL_HEIGHT (f) > 0);
5687 eassert (FRAME_NORMAL_WIDTH (f) > 0);
5688 x_real_positions (f, &f->left_pos, &f->top_pos);
5689 x_fullscreen_adjust (f, &width, &height, &top_pos, &left_pos);
5690
5691 SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0);
5692 pixel_height = workarea_rect.bottom - workarea_rect.top;
5693 pixel_width = workarea_rect.right - workarea_rect.left;
5694 /* Need to send SC_RESTORE to the window, in case we are
5695 resizing from FULLSCREEN_MAXIMIZED. Otherwise, the mouse
5696 resize hints will not be shown by the window manager when the
5697 mouse pointer hovers over the window edges, becaise the WM
5698 will still think the window is maximized. */
5699 if (f->want_fullscreen != FULLSCREEN_BOTH)
5700 SendMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_RESTORE, 0);
5701
5702 FRAME_PREV_FSMODE (f) = f->want_fullscreen;
5703 switch (f->want_fullscreen)
5704 {
5705 case FULLSCREEN_BOTH:
5706 PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, SC_MAXIMIZE, 0);
5707 break;
5708 case FULLSCREEN_MAXIMIZED:
5709 height =
5710 FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height)
5711 - XINT (Ftool_bar_lines_needed (selected_frame))
5712 + (NILP (Vmenu_bar_mode) ? 1 : 0);
5713 width =
5714 FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width)
5715 - FRAME_SCROLL_BAR_COLS (f);
5716 left_pos = workarea_rect.left;
5717 top_pos = workarea_rect.top;
5718 break;
5719 case FULLSCREEN_WIDTH:
5720 width =
5721 FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pixel_width)
5722 - FRAME_SCROLL_BAR_COLS (f);
5723 height = FRAME_NORMAL_HEIGHT (f);
5724 left_pos = workarea_rect.left;
5725 break;
5726 case FULLSCREEN_HEIGHT:
5727 height =
5728 FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, pixel_height)
5729 - XINT (Ftool_bar_lines_needed (selected_frame))
5730 + (NILP (Vmenu_bar_mode) ? 1 : 0);
5731 width = FRAME_NORMAL_WIDTH (f);
5732 top_pos = workarea_rect.top;
5733 break;
5734 case FULLSCREEN_NONE:
5735 height = FRAME_NORMAL_HEIGHT (f);
5736 width = FRAME_NORMAL_WIDTH (f);
5737 left_pos = FRAME_NORMAL_LEFT (f);
5738 top_pos = FRAME_NORMAL_TOP (f);
5739 break;
5740 }
5741
5742 if (cur_w != width || cur_h != height)
5743 {
5744 x_set_offset (f, left_pos, top_pos, 1);
5745 x_set_window_size (f, 1, width, height);
5746 do_pending_window_change (0);
5747 }
5748 f->want_fullscreen = FULLSCREEN_NONE;
5749 unblock_input ();
5750 }
5751 else
5752 f->want_fullscreen |= FULLSCREEN_WAIT;
5753}
5754
5520/* Call this to change the size of frame F's x-window. 5755/* Call this to change the size of frame F's x-window.
5521 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity 5756 If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
5522 for this size change and subsequent size changes. 5757 for this size change and subsequent size changes.
@@ -5811,11 +6046,11 @@ x_make_frame_visible (struct frame *f)
5811 causes unexpected behavior when unminimizing frames that were 6046 causes unexpected behavior when unminimizing frames that were
5812 previously maximized. But only SW_SHOWNORMAL works properly for 6047 previously maximized. But only SW_SHOWNORMAL works properly for
5813 frames that were truely hidden (using make-frame-invisible), so 6048 frames that were truely hidden (using make-frame-invisible), so
5814 we need it to avoid Bug#5482. It seems that async_iconified 6049 we need it to avoid Bug#5482. It seems that iconified is only
5815 is only set for minimized windows that are still visible, so 6050 set for minimized windows that are still visible, so use that to
5816 use that to determine the appropriate flag to pass ShowWindow. */ 6051 determine the appropriate flag to pass ShowWindow. */
5817 my_show_window (f, FRAME_W32_WINDOW (f), 6052 my_show_window (f, FRAME_W32_WINDOW (f),
5818 f->async_iconified ? SW_RESTORE : SW_SHOWNORMAL); 6053 FRAME_ICONIFIED_P (f) ? SW_RESTORE : SW_SHOWNORMAL);
5819 } 6054 }
5820 6055
5821 /* Synchronize to ensure Emacs knows the frame is visible 6056 /* Synchronize to ensure Emacs knows the frame is visible
@@ -5854,7 +6089,6 @@ x_make_frame_visible (struct frame *f)
5854 poll_suppress_count = old_poll_suppress_count; 6089 poll_suppress_count = old_poll_suppress_count;
5855 } 6090 }
5856 } 6091 }
5857 FRAME_SAMPLE_VISIBILITY (f);
5858 } 6092 }
5859} 6093}
5860 6094
@@ -5878,10 +6112,8 @@ x_make_frame_invisible (struct frame *f)
5878 So we can't win using the usual strategy of letting 6112 So we can't win using the usual strategy of letting
5879 FRAME_SAMPLE_VISIBILITY set this. So do it by hand, 6113 FRAME_SAMPLE_VISIBILITY set this. So do it by hand,
5880 and synchronize with the server to make sure we agree. */ 6114 and synchronize with the server to make sure we agree. */
5881 f->visible = 0; 6115 SET_FRAME_VISIBLE (f, 0);
5882 FRAME_ICONIFIED_P (f) = 0; 6116 SET_FRAME_ICONIFIED (f, 0);
5883 f->async_visible = 0;
5884 f->async_iconified = 0;
5885 6117
5886 unblock_input (); 6118 unblock_input ();
5887} 6119}
@@ -5897,7 +6129,7 @@ x_iconify_frame (struct frame *f)
5897 if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f) 6129 if (FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame == f)
5898 FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0; 6130 FRAME_W32_DISPLAY_INFO (f)->x_highlight_frame = 0;
5899 6131
5900 if (f->async_iconified) 6132 if (FRAME_ICONIFIED_P (f))
5901 return; 6133 return;
5902 6134
5903 block_input (); 6135 block_input ();
@@ -6207,7 +6439,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo)
6207 terminal->mouse_position_hook = w32_mouse_position; 6439 terminal->mouse_position_hook = w32_mouse_position;
6208 terminal->frame_rehighlight_hook = w32_frame_rehighlight; 6440 terminal->frame_rehighlight_hook = w32_frame_rehighlight;
6209 terminal->frame_raise_lower_hook = w32_frame_raise_lower; 6441 terminal->frame_raise_lower_hook = w32_frame_raise_lower;
6210 /* terminal->fullscreen_hook = XTfullscreen_hook; */ 6442 terminal->fullscreen_hook = w32fullscreen_hook;
6211 terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar; 6443 terminal->set_vertical_scroll_bar_hook = w32_set_vertical_scroll_bar;
6212 terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars; 6444 terminal->condemn_scroll_bars_hook = w32_condemn_scroll_bars;
6213 terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar; 6445 terminal->redeem_scroll_bar_hook = w32_redeem_scroll_bar;
@@ -6431,7 +6663,7 @@ w32_initialize (void)
6431 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil); 6663 Fset_input_mode (Qnil, Qnil, make_number (2), Qnil);
6432 6664
6433 { 6665 {
6434 DWORD input_locale_id = (DWORD) GetKeyboardLayout (0); 6666 DWORD input_locale_id = ((DWORD_PTR) GetKeyboardLayout (0) & 0xffffffff);
6435 w32_keyboard_codepage = 6667 w32_keyboard_codepage =
6436 codepage_for_locale ((LCID) (input_locale_id & 0xffff)); 6668 codepage_for_locale ((LCID) (input_locale_id & 0xffff));
6437 } 6669 }
@@ -6500,6 +6732,12 @@ syms_of_w32term (void)
6500 6732
6501 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); 6733 DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
6502 6734
6735 DEFSYM (Qadded, "added");
6736 DEFSYM (Qremoved, "removed");
6737 DEFSYM (Qmodified, "modified");
6738 DEFSYM (Qrenamed_from, "renamed-from");
6739 DEFSYM (Qrenamed_to, "renamed-to");
6740
6503 DEFVAR_INT ("w32-num-mouse-buttons", 6741 DEFVAR_INT ("w32-num-mouse-buttons",
6504 w32_num_mouse_buttons, 6742 w32_num_mouse_buttons,
6505 doc: /* Number of physical mouse buttons. */); 6743 doc: /* Number of physical mouse buttons. */);