X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/5491fd1098d27b3ba3db054076b9ab60fb3558dc..93ae9f46e7947aeb2180e3b8a98b551fa143ba51:/src/w32fns.c diff --git a/src/w32fns.c b/src/w32fns.c index 777819edd5..5f40729011 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -29,6 +29,8 @@ along with GNU Emacs. If not, see . */ #include #include +#include + #include "lisp.h" #include "w32term.h" #include "frame.h" @@ -157,8 +159,8 @@ typedef BOOL (WINAPI * TrackMouseEvent_Proc) typedef LONG (WINAPI * ImmGetCompositionString_Proc) (IN HIMC context, IN DWORD index, OUT LPVOID buffer, IN DWORD bufLen); typedef HIMC (WINAPI * ImmGetContext_Proc) (IN HWND window); -typedef HWND (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context); -typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, +typedef BOOL (WINAPI * ImmReleaseContext_Proc) (IN HWND wnd, IN HIMC context); +typedef BOOL (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, IN COMPOSITIONFORM *form); typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); typedef BOOL (WINAPI * GetMonitorInfo_Proc) @@ -202,7 +204,8 @@ unsigned int msh_mousewheel = 0; static unsigned menu_free_timer = 0; #ifdef GLYPH_DEBUG -static int image_cache_refcount, dpyinfo_refcount; +static ptrdiff_t image_cache_refcount; +static int dpyinfo_refcount; #endif static HWND w32_visible_system_caret_hwnd; @@ -346,10 +349,6 @@ x_real_positions (struct frame *f, int *xptr, int *yptr) /* Convert (0, 0) in the client area to screen co-ordinates. */ ClientToScreen (FRAME_W32_WINDOW (f), &pt); - /* Remember x_pixels_diff and y_pixels_diff. */ - f->x_pixels_diff = pt.x - rect.left; - f->y_pixels_diff = pt.y - rect.top; - *xptr = rect.left; *yptr = rect.top; } @@ -1722,6 +1721,7 @@ x_change_tool_bar_height (struct frame *f, int height) int old_height = FRAME_TOOL_BAR_HEIGHT (f); int lines = (height + unit - 1) / unit; int old_text_height = FRAME_TEXT_HEIGHT (f); + Lisp_Object fullscreen; /* Make sure we redisplay all windows in this frame. */ windows_or_buffers_changed = 23; @@ -1746,7 +1746,10 @@ x_change_tool_bar_height (struct frame *f, int height) f->n_tool_bar_rows = 0; adjust_frame_size (f, -1, -1, - (!f->tool_bar_redisplayed_once ? 1 + ((!f->tool_bar_redisplayed_once + && (NILP (fullscreen = + get_frame_param (f, Qfullscreen)) + || EQ (fullscreen, Qfullwidth))) ? 1 : (old_height == 0 || height == 0) ? 2 : 4), false, Qtool_bar_lines); @@ -3291,12 +3294,12 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) field being reset to nil. */ f = x_window_to_frame (dpyinfo, hwnd); if (!(f && FRAME_LIVE_P (f))) - break; + goto dflt; w = XWINDOW (FRAME_SELECTED_WINDOW (f)); /* Punt if someone changed the frame's selected window behind our back. */ if (w != w32_system_caret_window) - break; + goto dflt; form.dwStyle = CFS_RECT; form.ptCurrentPos.x = w32_system_caret_x; @@ -3314,16 +3317,22 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Punt if the window was deleted behind our back. */ if (!BUFFERP (w->contents)) - break; + goto dflt; context = get_ime_context_fn (hwnd); if (!context) - break; + goto dflt; set_ime_composition_window_fn (context, &form); release_ime_context_fn (hwnd, context); } + /* We should "goto dflt" here to pass WM_IME_STARTCOMPOSITION to + DefWindowProc, so that the composition window will actually + be displayed. But doing so causes trouble with displaying + dialog boxes, such as the file selection dialog or font + selection dialog. So something else is needed to fix the + former without breaking the latter. See bug#11732. */ break; case WM_IME_ENDCOMPOSITION: @@ -4668,8 +4677,6 @@ This function is an internal primitive--use `make-frame' instead. */) "bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL); x_default_parameter (f, parameters, Qtitle, Qnil, "title", "Title", RES_TYPE_STRING); - x_default_parameter (f, parameters, Qfullscreen, Qnil, - "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window; @@ -4728,6 +4735,12 @@ This function is an internal primitive--use `make-frame' instead. */) x_wm_set_size_hint (f, window_prompting, false); unblock_input (); + /* Process fullscreen parameter here in the hope that normalizing a + fullheight/fullwidth frame will produce the size set by the last + adjust_frame_size call. */ + x_default_parameter (f, parameters, Qfullscreen, Qnil, + "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); + /* Make the window appear on the frame and enable display, unless the caller says not to. However, with explicit parent, Emacs cannot control visibility, so don't try. */ @@ -5668,7 +5681,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, ptrdiff_t count = SPECPDL_INDEX (); struct gcpro gcpro1, gcpro2, gcpro3; struct kboard *kb; - int face_change_count_before = face_change_count; + bool face_change_before = face_change; Lisp_Object buffer; struct buffer *old_buffer; @@ -5832,7 +5845,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, SET_FRAME_COLS (f, 0); SET_FRAME_LINES (f, 0); adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f), - height * FRAME_LINE_HEIGHT (f), 0, true, Qnil); + height * FRAME_LINE_HEIGHT (f), 0, true, Qtip_frame); /* Add `tooltip' frame parameter's default value. */ if (NILP (Fframe_parameter (frame, Qtooltip))) @@ -5880,11 +5893,11 @@ x_create_tip_frame (struct w32_display_info *dpyinfo, f->can_x_set_window_size = true; /* Setting attributes of faces of the tooltip frame from resources - and similar will increment face_change_count, which leads to the + and similar will set face_change, which leads to the clearing of all current matrices. Since this isn't necessary - here, avoid it by resetting face_change_count to the value it + here, avoid it by resetting face_change to the value it had before we created the tip frame. */ - face_change_count = face_change_count_before; + face_change = face_change_before; /* Discard the unwind_protect. */ return unbind_to (count, frame); @@ -7028,7 +7041,28 @@ a ShowWindow flag: #else /* !CYGWIN */ - current_dir = ENCODE_FILE (current_dir); + const char file_url_str[] = "file:///"; + const int file_url_len = sizeof (file_url_str) - 1; + if (strncmp (SSDATA (document), file_url_str, file_url_len) == 0) + { + /* Passing "file:///" URLs to ShellExecute causes shlwapi.dll to + start a thread in some rare system configurations, for + unknown reasons. That thread is started in the context of + the Emacs process, but out of control of our code, and seems + to never exit afterwards. Each such thread reserves 8MB of + stack space (because that's the value recorded in the Emacs + executable at link time: Emacs needs a large stack). So a + large enough number of invocations of w32-shell-execute can + potentially cause the Emacs process to run out of available + address space, which is nasty. To work around this, we + convert such URLs to local file names, which seems to prevent + those threads from starting. See bug #20220. */ + char *p = SSDATA (document) + file_url_len; + + if (c_isalpha (*p) && p[1] == ':' && IS_DIRECTORY_SEP (p[2])) + document = Fsubstring_no_properties (document, + make_number (file_url_len), Qnil); + } /* We have a situation here. If DOCUMENT is a relative file name, but its name includes leading directories, i.e. it lives not in CURRENT_DIR, but in its subdirectory, then ShellExecute below @@ -7061,6 +7095,8 @@ a ShowWindow flag: else document = ENCODE_FILE (document); UNGCPRO; + + current_dir = ENCODE_FILE (current_dir); if (use_unicode) { wchar_t document_w[MAX_PATH], current_dir_w[MAX_PATH]; @@ -7500,13 +7536,13 @@ elements (all size values are in pixels). - `title-bar-height' is the height of the title bar of FRAME. -- `menu-bar-external' if `t' means the menu bar is by default external +- `menu-bar-external' if t means the menu bar is by default external (not included in the inner size of FRAME). - `menu-bar-size' is a cons of the width and height of the menu bar of FRAME. -- `tool-bar-external' if `t' means the tool bar is by default external +- `tool-bar-external' if t means the tool bar is by default external (not included in the inner size of FRAME). - `tool-bar-side' tells tells on which side the tool bar on FRAME is by @@ -7558,7 +7594,7 @@ elements (all size values are in pixels). menu_bar_height = single_bar_height; return - listn (CONSTYPE_PURE, 10, + listn (CONSTYPE_HEAP, 10, Fcons (Qframe_position, Fcons (make_number (frame_outer_edges.left), make_number (frame_outer_edges.top))), @@ -8232,6 +8268,15 @@ w32_sys_ring_bell (struct frame *f) MessageBeep (sound_type); } +DEFUN ("w32--menu-bar-in-use", Fw32__menu_bar_in_use, Sw32__menu_bar_in_use, + 0, 0, 0, + doc: /* Return non-nil when a menu-bar menu is being used. +Internal use only. */) + (void) +{ + return menubar_in_use ? Qt : Qnil; +} + /*********************************************************************** Initialization @@ -8303,6 +8348,14 @@ syms_of_w32fns (void) DEFSYM (Qworkarea, "workarea"); DEFSYM (Qmm_size, "mm-size"); DEFSYM (Qframes, "frames"); + DEFSYM (Qtip_frame, "tip-frame"); + DEFSYM (Qunicode_sip, "unicode-sip"); + + /* Symbols used elsewhere, but only in MS-Windows-specific code. */ + DEFSYM (Qgnutls_dll, "gnutls"); + DEFSYM (Qlibxml2_dll, "libxml2"); + DEFSYM (Qserif, "serif"); + DEFSYM (Qzlib_dll, "zlib"); Fput (Qundefined_color, Qerror_conditions, listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror)); @@ -8609,6 +8662,7 @@ only be necessary if the default setting causes problems. */); defsubr (&Sw32_frame_rect); defsubr (&Sw32_frame_menu_bar_size); defsubr (&Sw32_battery_status); + defsubr (&Sw32__menu_bar_in_use); #ifdef WINDOWSNT defsubr (&Sfile_system_info);