Fix creation of frames on MS-Windows: don't cons Lisp objects in input thread.

src/w32fns.c (w32_createwindow): Accept an additional argument, an
 array of 2 values specifying the coordinates of the frame's
 top-left corner.  Use these values instead of calling x_get_arg,
 which can cons Lisp objects, and therefore cannot be called except
 from the main thread.  Remove redundant tests for the default
 values.
 (my_create_window): Move the calculation of the coordinates of the
 frame's top-left edge here.  Pass them to the input thread via the
 second parameter of the WM_EMACS_CREATEWINDOW message.  See
 http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00892.html
 for the details.
This commit is contained in:
Eli Zaretskii 2014-09-30 16:53:24 +03:00
parent 42d4302f24
commit 572fe798cd
2 changed files with 44 additions and 17 deletions

View file

@ -1,3 +1,17 @@
2014-09-30 Eli Zaretskii <eliz@gnu.org>
* w32fns.c (w32_createwindow): Accept an additional argument, an
array of 2 values specifying the coordinates of the frame's
top-left corner. Use these values instead of calling x_get_arg,
which can cons Lisp objects, and therefore cannot be called except
from the main thread. Remove redundant tests for the default
values.
(my_create_window): Move the calculation of the coordinates of the
frame's top-left edge here. Pass them to the input thread via the
second parameter of the WM_EMACS_CREATEWINDOW message. See
http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00892.html
for the details.
2014-09-29 Eli Zaretskii <eliz@gnu.org>
* xdisp.c (cursor_row_fully_visible_p): Update commentary.

View file

@ -1911,13 +1911,12 @@ w32_createscrollbar (struct frame *f, struct scroll_bar * bar)
}
static void
w32_createwindow (struct frame *f)
w32_createwindow (struct frame *f, int *coords)
{
HWND hwnd;
RECT rect;
Lisp_Object top = Qunbound;
Lisp_Object left = Qunbound;
struct w32_display_info *dpyinfo = &one_w32_display_info;
int top;
int left;
rect.left = rect.top = 0;
rect.right = FRAME_PIXEL_WIDTH (f);
@ -1932,25 +1931,21 @@ w32_createwindow (struct frame *f)
if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
{
XSETINT (left, f->left_pos);
XSETINT (top, f->top_pos);
left = f->left_pos;
top = f->top_pos;
}
else if (EQ (left, Qunbound) && EQ (top, Qunbound))
else
{
/* When called with RES_TYPE_NUMBER, w32_get_arg will return zero
for anything that is not a number and is not Qunbound. */
left = x_get_arg (dpyinfo, Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
left = coords[0];
top = coords[1];
}
FRAME_W32_WINDOW (f) = hwnd
= CreateWindow (EMACS_CLASS,
f->namebuf,
f->output_data.w32->dwStyle | WS_CLIPCHILDREN,
EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left),
EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top),
rect.right - rect.left,
rect.bottom - rect.top,
left, top,
rect.right - rect.left, rect.bottom - rect.top,
NULL,
NULL,
hinst,
@ -2468,7 +2463,8 @@ w32_msg_pump (deferred_msg * msg_buf)
the patch for XP is not publicly available until XP SP3,
and older versions will never be patched. */
CoInitialize (NULL);
w32_createwindow ((struct frame *) msg.wParam);
w32_createwindow ((struct frame *) msg.wParam,
(int *) msg.lParam);
if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
emacs_abort ();
break;
@ -4069,8 +4065,25 @@ static void
my_create_window (struct frame * f)
{
MSG msg;
static int coords[2];
Lisp_Object left, top;
struct w32_display_info *dpyinfo = &one_w32_display_info;
if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0))
/* When called with RES_TYPE_NUMBER, x_get_arg will return zero for
anything that is not a number and is not Qunbound. */
left = x_get_arg (dpyinfo, Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
if (EQ (left, Qunbound))
coords[0] = CW_USEDEFAULT;
else
coords[0] = XINT (left);
if (EQ (top, Qunbound))
coords[1] = CW_USEDEFAULT;
else
coords[1] = XINT (top);
if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW,
(WPARAM)f, (LPARAM)coords))
emacs_abort ();
GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
}