X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/0b2014f9cb13efdd6ebc30627d88b9a7f3a42149..829733104db073f8abd67765eae162e7360281fa:/src/w32term.c diff --git a/src/w32term.c b/src/w32term.c index 251c46c73c..51743f8f94 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -1,13 +1,13 @@ /* Implementation of GUI terminal on the Microsoft Windows API. -Copyright (C) 1989, 1993-2015 Free Software Foundation, Inc. +Copyright (C) 1989, 1993-2016 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -23,38 +23,29 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" #include "blockinput.h" #include "w32term.h" - -#include "systty.h" -#include "systime.h" +#include "w32common.h" /* for OS version info */ #include #include #include +#ifdef CYGWIN +#include /* for O_RDWR */ +#endif #include -#include "charset.h" -#include "character.h" #include "coding.h" -#include "ccl.h" #include "frame.h" -#include "dispextern.h" #include "fontset.h" #include "termhooks.h" #include "termopts.h" #include "termchar.h" -#include "disptab.h" #include "buffer.h" #include "window.h" #include "keyboard.h" -#include "intervals.h" -#include "process.h" -#include "atimer.h" -#include "keymap.h" -#include "menu.h" +#include "menu.h" /* for w32_menu_show */ #ifdef WINDOWSNT #include "w32.h" /* for filename_from_utf16, filename_from_ansi */ -#include "w32heap.h" #endif #ifndef WINDOWSNT @@ -65,6 +56,10 @@ along with GNU Emacs. If not, see . */ #include "font.h" #include "w32font.h" + +#if 0 /* TODO: stipple */ +#include "bitmaps/gray.xbm" +#endif /* Fringe bitmaps. */ @@ -401,7 +396,13 @@ w32_draw_rectangle (HDC hdc, XGCValues *gc, int x, int y, oldhb = SelectObject (hdc, hb); oldhp = SelectObject (hdc, hp); - Rectangle (hdc, x, y, x + width, y + height); + /* We enlarge WIDTH and HEIGHT by 1 to be bug-compatible to the + brain-dead design of XDrawRectangle, which draws a rectangle that + is 1 pixel wider and higher than its arguments WIDTH and HEIGHT. + This allows us to keep the code that calls this function similar + to the corresponding code in xterm.c. For the details, see + http://lists.gnu.org/archives/html/emacs-devel/2014-10/msg00546.html. */ + Rectangle (hdc, x, y, x + width + 1, y + height + 1); SelectObject (hdc, oldhb); SelectObject (hdc, oldhp); @@ -1212,7 +1213,12 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p) } else #endif - if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width + if (FONT_HEIGHT (s->font) < s->height - 2 * box_line_width + /* When xdisp.c ignores FONT_HEIGHT, we cannot trust + font dimensions, since the actual glyphs might be + much smaller. So in that case we always clear the + rectangle with background color. */ + || FONT_TOO_HIGH (s->font) || s->font_not_found_p || s->extends_to_end_of_line_p || force_p) @@ -1410,7 +1416,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s) if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM) { - if (len > 1 + if (len > 0 && CHAR_TABLE_P (Vglyphless_char_display) && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)) @@ -1585,7 +1591,9 @@ w32_setup_relief_color (struct frame *f, struct relief *relief, double factor, unsigned long mask = GCForeground; COLORREF pixel; COLORREF background = di->relief_background; +#if 0 struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); +#endif /* TODO: Free colors (if using palette)? */ @@ -3223,7 +3231,7 @@ queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f, if (notification_buffer_in_use) { DWORD info_size = notifications_size; - Lisp_Object cs = intern ("utf-16le"); + Lisp_Object cs = Qutf_16le; Lisp_Object obj = w32_get_watch_object (notifications_desc); /* notifications_size could be zero when the buffer of @@ -3344,8 +3352,6 @@ static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object enum scroll_bar_part *, Lisp_Object *, Lisp_Object *, Time *); -static void x_check_fullscreen (struct frame *); - static void w32_define_cursor (Window window, Cursor cursor) { @@ -3610,8 +3616,8 @@ w32_set_horizontal_scroll_bar_thumb (struct scroll_bar *bar, si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; si.nMin = 0; si.nMax = whole; - /* Allow nPage to be one larger than nPos so we don't allow to scroll - an already fully visible buffer. */ + /* Allow nPage to be one larger than nPos so we don't allow the scrolling + of an already fully visible buffer. */ si.nPage = min (portion, si.nMax) + 1; si.nPos = min (position, si.nMax); SetScrollInfo (w, SB_CTL, &si, TRUE); @@ -4341,8 +4347,6 @@ w32_horizontal_scroll_bar_handle_click (struct scroll_bar *bar, W32Msg *msg, if (dragging) { SCROLLINFO si; - int start = bar->start; - int end = bar->end; si.cbSize = sizeof (si); si.fMask = SIF_POS; @@ -4500,18 +4504,6 @@ x_scroll_bar_clear (struct frame *f) } } -static void -set_frame_param (struct frame *f, Lisp_Object prop, Lisp_Object val) -{ - register Lisp_Object old_alist_elt; - - old_alist_elt = Fassq (prop, f->param_alist); - if (EQ (old_alist_elt, Qnil)) - fset_param_alist (f, Fcons (Fcons (prop, val), f->param_alist)); - else - Fsetcdr (old_alist_elt, val); -} - /* The main W32 event-reading loop - w32_read_socket. */ /* Record the last 100 characters stored @@ -4989,8 +4981,12 @@ w32_read_socket (struct terminal *terminal, 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); + { + /* Must set visibility right here since otherwise + w32fullscreen_hook returns immediately. */ + SET_FRAME_VISIBLE (f, 1); + w32fullscreen_hook (f); + } } check_visibility = 1; break; @@ -5050,6 +5046,7 @@ w32_read_socket (struct terminal *terminal, case SIZE_MAXIMIZED: { bool iconified = FRAME_ICONIFIED_P (f); + Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); SET_FRAME_VISIBLE (f, 1); SET_FRAME_ICONIFIED (f, false); @@ -5080,12 +5077,22 @@ w32_read_socket (struct terminal *terminal, to update the frame titles in case this is the second frame. */ record_asynch_buffer_change (); - } - if (EQ (get_frame_param (f, Qfullscreen), Qnil)) - set_frame_param (f, Qfullscreen, Qmaximized); - else if (! EQ (get_frame_param (f, Qfullscreen), Qmaximized)) - set_frame_param (f, Qmaximized, Qmaximized); + /* Windows can send us a SIZE_MAXIMIZED message even + when fullscreen is fullboth. The following is a + simple hack to check that based on the fact that + only a maximized fullscreen frame should have both + top/left outside the screen. */ + if (EQ (fullscreen, Qfullwidth) || EQ (fullscreen, Qfullheight) + || NILP (fullscreen)) + { + int x, y; + + x_real_positions (f, &x, &y); + if (x < 0 && y < 0) + store_frame_param (f, Qfullscreen, Qmaximized); + } + } break; @@ -5126,9 +5133,7 @@ w32_read_socket (struct terminal *terminal, } if (EQ (get_frame_param (f, Qfullscreen), Qmaximized)) - set_frame_param (f, Qfullscreen, Qnil); - else if (! EQ (get_frame_param (f, Qmaximized), Qnil)) - set_frame_param (f, Qmaximized, Qnil); + store_frame_param (f, Qfullscreen, Qnil); break; } @@ -5137,7 +5142,7 @@ w32_read_socket (struct terminal *terminal, if (f && !FRAME_ICONIFIED_P (f) && msg.msg.wParam != SIZE_MINIMIZED) { RECT rect; - int rows, columns, width, height, text_width, text_height; + int /* rows, columns, */ width, height, text_width, text_height; if (GetClientRect (msg.msg.hwnd, &rect) /* GetClientRect evidently returns (0, 0, 0, 0) if @@ -5269,11 +5274,18 @@ w32_read_socket (struct terminal *terminal, if (f) { + Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); + dpyinfo->n_cbits = msg.msg.wParam; /* The new display could have a different resolution, in - which case we must reconsider what fullscreen - means. */ - x_check_fullscreen (f); + which case we must reconsider what fullscreen means. + The following code is untested yet. */ + if (!NILP (fullscreen)) + { + x_set_fullscreen (f, fullscreen, fullscreen); + w32fullscreen_hook (f); + } + DebPrint (("display change: %d %d\n", (short) LOWORD (msg.msg.lParam), (short) HIWORD (msg.msg.lParam))); @@ -5803,7 +5815,7 @@ Lisp_Object x_new_font (struct frame *f, Lisp_Object font_object, int fontset) { struct font *font = XFONT_OBJECT (font_object); - int unit; + int unit, font_ascent, font_descent; if (fontset < 0) fontset = fontset_from_font (font_object); @@ -5816,7 +5828,8 @@ x_new_font (struct frame *f, Lisp_Object font_object, int fontset) FRAME_FONT (f) = font; FRAME_BASELINE_OFFSET (f) = font->baseline_offset; FRAME_COLUMN_WIDTH (f) = unit = font->average_width; - FRAME_LINE_HEIGHT (f) = font->height; + get_font_ascent_descent (font, &font_ascent, &font_descent); + FRAME_LINE_HEIGHT (f) = font_ascent + font_descent; /* Compute number of scrollbar columns. */ unit = FRAME_COLUMN_WIDTH (f); @@ -5901,16 +5914,49 @@ x_calc_absolute_position (struct frame *f) top_bottom_borders_height = 32; } + /* With multiple monitors, we can legitimately get negative + coordinates (for monitors above or to the left of the primary + monitor). Find the display origin to ensure negative positions + are computed correctly (Bug#21173). */ + int display_left = 0; + int display_top = 0; + if (flags & (XNegative | YNegative)) + { + Lisp_Object list; + + list = Fw32_display_monitor_attributes_list (Qnil); + while (CONSP (list)) + { + Lisp_Object attributes = CAR(list); + Lisp_Object geometry; + Lisp_Object monitor_left, monitor_top; + + list = CDR(list); + + geometry = Fassoc (Qgeometry, attributes); + if (!NILP (geometry)) + { + monitor_left = Fnth (make_number (1), geometry); + monitor_top = Fnth (make_number (2), geometry); + + display_left = min (display_left, XINT (monitor_left)); + display_top = min (display_top, XINT (monitor_top)); + } + } + } + /* Treat negative positions as relative to the rightmost bottommost position that fits on the screen. */ if (flags & XNegative) f->left_pos = (x_display_pixel_width (FRAME_DISPLAY_INFO (f)) + + display_left - FRAME_PIXEL_WIDTH (f) + f->left_pos - (left_right_borders_width - 1)); if (flags & YNegative) f->top_pos = (x_display_pixel_height (FRAME_DISPLAY_INFO (f)) + + display_top - FRAME_PIXEL_HEIGHT (f) + f->top_pos - (top_bottom_borders_height - 1)); @@ -5959,75 +6005,6 @@ x_set_offset (struct frame *f, register int xoff, register int yoff, unblock_input (); } -/* Calculate fullscreen size. Return in *TOP_POS and *LEFT_POS the - wanted positions of the WM window (not Emacs window). - Return in *WIDTH and *HEIGHT the wanted width and height of Emacs - window (FRAME_X_WINDOW). - */ - -static void -x_fullscreen_adjust (struct frame *f, int *width, int *height, int *top_pos, int *left_pos) -{ - int newwidth = FRAME_COLS (f); - int newheight = FRAME_LINES (f); - Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); - - *top_pos = f->top_pos; - *left_pos = f->left_pos; - - if (f->want_fullscreen & FULLSCREEN_HEIGHT) - { - int ph; - - ph = x_display_pixel_height (dpyinfo); - newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph); - ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, newheight) - f->y_pixels_diff; - newheight = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, ph); - *top_pos = 0; - } - - if (f->want_fullscreen & FULLSCREEN_WIDTH) - { - int pw; - - pw = x_display_pixel_width (dpyinfo); - newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw); - pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, newwidth) - f->x_pixels_diff; - newwidth = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, pw); - *left_pos = 0; - } - - *width = newwidth; - *height = newheight; -} - -/* Check if we need to resize the frame due to a fullscreen request. - If so needed, resize the frame. */ -static void -x_check_fullscreen (struct frame *f) -{ - if (f->want_fullscreen & FULLSCREEN_BOTH) - { - int width, height, ign; - - x_real_positions (f, &f->left_pos, &f->top_pos); - - x_fullscreen_adjust (f, &width, &height, &ign, &ign); - - /* We do not need to move the window, it shall be taken care of - when setting WM manager hints. */ - if (FRAME_COLS (f) != width || FRAME_LINES (f) != height) - { - change_frame_size (f, width, height, 0, 1, 0, 0); - SET_FRAME_GARBAGED (f); - cancel_mouse_face (f); - - /* Wait for the change of frame size to occur. */ - f->want_fullscreen |= FULLSCREEN_WAIT; - } - } -} - static void w32fullscreen_hook (struct frame *f) { @@ -6068,12 +6045,19 @@ w32fullscreen_hook (struct frame *f) } else if (f->want_fullscreen == FULLSCREEN_BOTH) { + int menu_bar_height = GetSystemMetrics (SM_CYMENU); + w32_fullscreen_rect (hwnd, f->want_fullscreen, FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); 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); + change_frame_size + (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, rect.right - rect.left), + FRAME_PIXEL_TO_TEXT_HEIGHT (f, (rect.bottom - rect.top + - menu_bar_height)), + 0, 1, 0, 1); } else { @@ -6082,10 +6066,39 @@ w32fullscreen_hook (struct frame *f) FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0); + + if (f->want_fullscreen == FULLSCREEN_WIDTH) + { + int border_width = GetSystemMetrics (SM_CXFRAME); + + change_frame_size + (f, (FRAME_PIXEL_TO_TEXT_WIDTH + (f, rect.right - rect.left - 2 * border_width)), + 0, 0, 1, 0, 1); + } + else + { + int border_height = GetSystemMetrics (SM_CYFRAME); + /* Won't work for wrapped menu bar. */ + int menu_bar_height = GetSystemMetrics (SM_CYMENU); + int title_height = GetSystemMetrics (SM_CYCAPTION); + + change_frame_size + (f, 0, (FRAME_PIXEL_TO_TEXT_HEIGHT + (f, rect.bottom - rect.top - 2 * border_height + - title_height - menu_bar_height)), + 0, 1, 0, 1); + } } f->want_fullscreen = FULLSCREEN_NONE; unblock_input (); + + if (f->want_fullscreen == FULLSCREEN_BOTH + || f->want_fullscreen == FULLSCREEN_WIDTH + || f->want_fullscreen == FULLSCREEN_HEIGHT) + do_pending_window_change (0); + } else f->want_fullscreen |= FULLSCREEN_WAIT; @@ -6101,10 +6114,24 @@ x_set_window_size (struct frame *f, bool change_gravity, int width, int height, bool pixelwise) { int pixelwidth, pixelheight; + Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); RECT rect; + MENUBARINFO info; + int menu_bar_height; block_input (); + /* Get the height of the menu bar here. It's used below to detect + whether the menu bar is wrapped. It's also used to specify the + third argument for AdjustWindowRect. FRAME_EXTERNAL_MENU_BAR which + has been used before for that reason is unreliable because it only + specifies whether we _want_ a menu bar for this frame and not + whether this frame _has_ a menu bar. See bug#22105. */ + info.cbSize = sizeof (info); + info.rcBar.top = info.rcBar.bottom = 0; + GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info); + menu_bar_height = info.rcBar.bottom - info.rcBar.top; + if (pixelwise) { pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); @@ -6119,20 +6146,14 @@ x_set_window_size (struct frame *f, bool change_gravity, if (w32_add_wrapped_menu_bar_lines) { /* When the menu bar wraps sending a SetWindowPos shrinks the - height of the frame when the wrapped menu bar lines are not + height of the frame then the wrapped menu bar lines are not accounted for (Bug#15174 and Bug#18720). Here we add these extra lines to the frame height. */ - MENUBARINFO info; int default_menu_bar_height; - int menu_bar_height; /* Why is (apparently) SM_CYMENUSIZE needed here instead of SM_CYMENU ?? */ default_menu_bar_height = GetSystemMetrics (SM_CYMENUSIZE); - info.cbSize = sizeof (info); - info.rcBar.top = info.rcBar.bottom = 0; - GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &info); - menu_bar_height = info.rcBar.bottom - info.rcBar.top; if ((default_menu_bar_height > 0) && (menu_bar_height > default_menu_bar_height) @@ -6143,55 +6164,58 @@ x_set_window_size (struct frame *f, bool change_gravity, f->win_gravity = NorthWestGravity; x_wm_set_size_hint (f, (long) 0, false); - f->want_fullscreen = FULLSCREEN_NONE; - w32fullscreen_hook (f); - rect.left = rect.top = 0; rect.right = pixelwidth; rect.bottom = pixelheight; - AdjustWindowRect (&rect, f->output_data.w32->dwStyle, - FRAME_EXTERNAL_MENU_BAR (f)); + AdjustWindowRect (&rect, f->output_data.w32->dwStyle, menu_bar_height > 0); - my_set_window_pos (FRAME_W32_WINDOW (f), - NULL, - 0, 0, - rect.right - rect.left, - rect.bottom - rect.top, - SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); - - /* If w32_enable_frame_resize_hack is non-nil, immediately apply the - new pixel sizes to the frame and its subwindows. - - Jason Rumney earlier refused to call change_frame_size right here - with the following argument: - - The following mirrors what is done in xterm.c. It appears to be for - informing lisp of the new size immediately, while the actual resize - will happen asynchronously. But on Windows, the menu bar - automatically wraps when the frame is too narrow to contain it, and - that causes any calculations made here to come out wrong. The end - is some nasty buggy behavior, including the potential loss of the - minibuffer. - - Disabling this code is either not sufficient to fix the problems - completely, or it causes fresh problems, but at least it removes - the most problematic symptom of the minibuffer becoming unusable. - - However, as the discussion about how to handle frame size - parameters on Windows (Bug#1348, Bug#16028) shows, that cure seems - worse than the disease. In particular, menu bar wrapping looks - like a non-issue - maybe so because Windows eventually gets back to - us with the correct client rectangle anyway. But we have to avoid - calling change_frame_size with a delta of less than one canoncial - character size when frame_resize_pixelwise is nil, as explained in - the comment above. */ - - if (w32_enable_frame_resize_hack) + if (!(f->after_make_frame) + && !(f->want_fullscreen & FULLSCREEN_WAIT) + && FRAME_VISIBLE_P (f)) + { + RECT window_rect; + GetWindowRect (FRAME_W32_WINDOW (f), &window_rect); + + if (EQ (fullscreen, Qmaximized) + || EQ (fullscreen, Qfullboth) + || EQ (fullscreen, Qfullwidth)) + { + rect.left = window_rect.left; + rect.right = window_rect.right; + pixelwidth = 0; + } + if (EQ (fullscreen, Qmaximized) + || EQ (fullscreen, Qfullboth) + || EQ (fullscreen, Qfullheight)) + { + rect.top = window_rect.top; + rect.bottom = window_rect.bottom; + pixelheight = 0; + } + } + + if (pixelwidth > 0 || pixelheight > 0) { - change_frame_size (f, FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth), - FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight), + frame_size_history_add + (f, Qx_set_window_size_1, width, height, + list2 (Fcons (make_number (pixelwidth), + make_number (pixelheight)), + Fcons (make_number (rect.right - rect.left), + make_number (rect.bottom - rect.top)))); + + my_set_window_pos (FRAME_W32_WINDOW (f), NULL, + 0, 0, + rect.right - rect.left, + rect.bottom - rect.top, + SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); + + change_frame_size (f, + ((pixelwidth == 0) + ? 0 : FRAME_PIXEL_TO_TEXT_WIDTH (f, pixelwidth)), + ((pixelheight == 0) + ? 0 : FRAME_PIXEL_TO_TEXT_HEIGHT (f, pixelheight)), 0, 1, 0, 1); SET_FRAME_GARBAGED (f); @@ -6208,7 +6232,7 @@ x_set_window_size (struct frame *f, bool change_gravity, unblock_input (); - do_pending_window_change (0); + do_pending_window_change (false); } /* Mouse warping. */ @@ -6216,6 +6240,8 @@ x_set_window_size (struct frame *f, bool change_gravity, void frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y) { + UINT trail_num = 0; + BOOL ret = false; RECT rect; POINT pt; @@ -6226,7 +6252,15 @@ frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y) pt.y = rect.top + pix_y; ClientToScreen (FRAME_W32_WINDOW (f), &pt); + /* When "mouse trails" are in effect, moving the mouse cursor + sometimes leaves behind an annoying "ghost" of the pointer. + Avoid that by momentarily switching off mouse trails. */ + if (os_subtype == OS_NT + && w32_major_version + w32_minor_version >= 6) + ret = SystemParametersInfo (SPI_GETMOUSETRAILS, 0, &trail_num, 0); SetCursorPos (pt.x, pt.y); + if (ret) + SystemParametersInfo (SPI_SETMOUSETRAILS, trail_num, NULL, 0); unblock_input (); } @@ -6595,7 +6629,10 @@ w32_hide_hourglass (struct frame *f) struct w32_output *w32 = FRAME_X_OUTPUT (f); w32->hourglass_p = 0; - SetCursor (w32->current_cursor); + if (f->pointer_invisible) + SetCursor (NULL); + else + SetCursor (w32->current_cursor); } /* FIXME: old code did that, but I don't know why. Anyway, @@ -6607,6 +6644,21 @@ w32_arrow_cursor (void) SetCursor (w32_load_cursor (IDC_ARROW)); } +static void +w32_toggle_invisible_pointer (struct frame *f, bool invisible) +{ + block_input (); + + if (f->pointer_invisible != invisible) + { + f->pointer_invisible = invisible; + w32_define_cursor (FRAME_W32_WINDOW (f), + f->output_data.w32->current_cursor); + } + + unblock_input (); +} + /*********************************************************************** Initialization ***********************************************************************/ @@ -6746,6 +6798,7 @@ w32_create_terminal (struct w32_display_info *dpyinfo) terminal->ins_del_lines_hook = x_ins_del_lines; terminal->delete_glyphs_hook = x_delete_glyphs; terminal->ring_bell_hook = w32_ring_bell; + terminal->toggle_invisible_pointer_hook = w32_toggle_invisible_pointer; terminal->update_begin_hook = x_update_begin; terminal->update_end_hook = x_update_end; terminal->read_socket_hook = w32_read_socket; @@ -6891,6 +6944,15 @@ x_delete_display (struct w32_display_info *dpyinfo) /* Set up use of W32. */ +void +w32_init_main_thread (void) +{ + dwMainThreadId = GetCurrentThreadId (); + DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), + GetCurrentProcess (), &hMainThread, 0, TRUE, + DUPLICATE_SAME_ACCESS); +} + DWORD WINAPI w32_msg_worker (void * arg); static void @@ -6951,10 +7013,6 @@ w32_initialize (void) terminates */ init_crit (); - dwMainThreadId = GetCurrentThreadId (); - DuplicateHandle (GetCurrentProcess (), GetCurrentThread (), - GetCurrentProcess (), &hMainThread, 0, TRUE, DUPLICATE_SAME_ACCESS); - /* Wait for thread to start */ { MSG msg; @@ -7102,7 +7160,7 @@ Windows 8. It is set to nil on Windows 9X. */); w32_unicode_filenames = 0; - /* FIXME: The following two variables will be (hopefully) removed + /* FIXME: The following variable will be (hopefully) removed before Emacs 25.1 gets released. */ DEFVAR_BOOL ("w32-add-wrapped-menu-bar-lines", @@ -7116,16 +7174,6 @@ wrapped menu bar lines when sending frame resize requests to the Windows API. */); w32_add_wrapped_menu_bar_lines = 1; - DEFVAR_BOOL ("w32-enable-frame-resize-hack", - w32_enable_frame_resize_hack, - doc: /* Non-nil means enable hack for frame resizing on Windows. -A value of nil means to resize frames by sending a corresponding request -to the Windows API and changing the pixel sizes of the frame and its -windows after the latter calls back. If this is non-nil, Emacs changes -the pixel sizes of the frame and its windows at the time it sends the -resize request to the API. */); - w32_enable_frame_resize_hack = 1; - /* Tell Emacs about this window system. */ Fprovide (Qw32, Qnil); }