Mercurial > hg > xemacs-beta
diff src/msw-proc.c @ 223:2c611d1463a6 r20-4b10
Import from CVS: tag r20-4b10
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:10:54 +0200 |
parents | 6c0ae1f9357f |
children | 12579d965149 |
line wrap: on
line diff
--- a/src/msw-proc.c Mon Aug 13 10:10:03 2007 +0200 +++ b/src/msw-proc.c Mon Aug 13 10:10:54 2007 +0200 @@ -25,46 +25,6 @@ Jonathan Harris, November 1997 for 20.4. */ -/* - * Comment: - * - * X on UNIX may be bad, but the win32 API really really really sucks. - * - * Windows user-input type events are stored in a per-thread message queue - * and retrieved using GetMessage(). It is not possible to wait on this - * queue and on other events (eg process input) simultaneously. Also, the - * main event-handling code in windows (the "windows procedure") is called - * asynchronously when windows has certain other types of events ("nonqueued - * messages") to deliver. The documentation doesn't appear to specify the - * context in which the windows procedure is called, but I assume that the - * thread that created the window is temporarily highjacked for this purpose - * when it calls GetMessage (a bit like X callbacks?). - * - * We spawn off a single thread to deal with both queued and non-queued - * events. The thread turns both kinds of events into emacs_events and stuffs - * them in a queue which XEmacs reads at its leisure. This file contains the - * code for that thread. - * - * Unfortunately, under win32 a seemingly-random selection of resources are - * owned by the thread that created/asked for them and not by the process. In - * particular, only the thread that created a window can retrieve messages - * destined for that window ("GetMessage does not retrieve messages for - * windows that belong to other threads..."). This means that our message- - * processing thread also has to do all window creation, deletion and various - * other random stuff. We handle this bogosity by getting the main XEmacs - * thread to send special user-defined messages to the message-processing - * thread to instruct it to create windows etc. - * - * More bogosity: Windows95 doesn't offer any one-shot timers, only a - * periodic timer. Worse, if you don't want a periodic timer to be associated - * with a particular mswindows window (we don't) your periodic timers don't - * have unique ids associated with them. We get round this lameness by - * setting off a single periodic timer and we use this to schedule timeouts - * manually. Implementing basic stuff like one-shot timers at the application - * level is not particularly efficient, but Windows95 leaves us no choice. - */ - - #include <config.h> #include "lisp.h" @@ -80,11 +40,15 @@ # undef DEBUG_TIMEOUTS #endif -#define MSWINDOWS_FRAME_STYLE WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_TILEDWINDOW -#define MSWINDOWS_POPUP_STYLE WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_CAPTION|WS_POPUP +#ifdef HAVE_MENUBARS +#define ADJR_MENUFLAG TRUE +#else +#define ADJR_MENUFLAG FALSE +#endif -static LRESULT WINAPI mswindows_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); -static Lisp_Object mswindows_find_console (HWND hwnd); +/* Timer ID used for button2 emulation */ +#define BUTTON_2_TIMER_ID 1 + static Lisp_Object mswindows_find_frame (HWND hwnd); static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods); static int mswindows_modifier_state (void); @@ -92,7 +56,7 @@ static void mswindows_dequeue_timeout (int interval_id); /* Virtual keycode of the '@' key */ -static int virtual_at_key; +static int virtual_at_key = -1; /* Timeout queue */ struct mswindows_timeout @@ -106,37 +70,12 @@ static mswindows_timeout *timeout_head = NULL; static int timeout_mswindows_id; +#if 0 /* * Entry point for the "windows" message-processing thread */ DWORD mswindows_win_thread() { - WNDCLASS wc; - MSG msg; - mswindows_waitable_info_type info; - - /* Register the main window class */ - wc.style = CS_OWNDC; /* One DC per window */ - wc.lpfnWndProc = (WNDPROC) mswindows_wnd_proc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; /* ? */ - wc.hInstance = NULL; /* ? */ - wc.hIcon = LoadIcon (NULL, XEMACS_CLASS); - wc.hCursor = LoadCursor (NULL, IDC_ARROW); - wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH); */ - wc.lpszMenuName = NULL; /* XXX FIXME? Add a menu? */ - wc.lpszClassName = XEMACS_CLASS; - RegisterClass(&wc); /* XXX FIXME: Should use RegisterClassEx */ - - info.type = mswindows_waitable_type_dispatch; - mswindows_add_waitable(&info); - - /* Ensure our message queue is created XXX FIXME: Is this necessary? */ - PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE); - - /* Notify the main thread that we're ready */ - assert(PostThreadMessage (mswindows_main_thread_id, WM_XEMACS_ACK, 0, 0)); - /* Hack! Windows doesn't report Ctrl-@ characters so we have to find out * which virtual key generates '@' at runtime */ virtual_at_key = VkKeyScan ('@'); @@ -193,62 +132,151 @@ DispatchMessage (&msg); } } +#endif /* 0 */ + +static void +mswindows_enqueue_magic_event (HWND hwnd, UINT message) +{ + Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); + struct Lisp_Event* event = XEVENT (emacs_event); + + event->channel = mswindows_find_frame (hwnd); + event->timestamp = GetMessageTime(); + event->event_type = magic_event; + EVENT_MSWINDOWS_MAGIC_TYPE (event) = message; + + mswindows_enqueue_dispatch_event (emacs_event); +} + +static void +mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWORD when) +{ + + /* We always use last message time, because mouse button + events may get delayed, and XEmacs double click + recognition will fail */ + + Lisp_Object emacs_event = Fmake_event (Qnil, Qnil); + struct Lisp_Event* event = XEVENT(emacs_event); + + event->channel = mswindows_find_frame(hwnd); + event->timestamp = when; + event->event.button.button = + (message==WM_LBUTTONDOWN || message==WM_LBUTTONUP) ? 1 : + ((message==WM_RBUTTONDOWN || message==WM_RBUTTONUP) ? 3 : 2); + event->event.button.x = where.x; + event->event.button.y = where.y; + event->event.button.modifiers = mswindows_modifier_state(); + + if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN || + message==WM_RBUTTONDOWN) + { + event->event_type = button_press_event; + SetCapture (hwnd); + } + else + { + event->event_type = button_release_event; + ReleaseCapture (); + } + + mswindows_enqueue_dispatch_event (emacs_event); +} + +static void +mswindows_set_chord_timer (HWND hwnd) +{ + int interval; + + /* We get half system threshold as it seems to + long before drag-selection is shown */ + if (mswindows_button2_chord_time <= 0) + interval = GetDoubleClickTime () / 2; + else + interval = mswindows_button2_chord_time; + + SetTimer (hwnd, BUTTON_2_TIMER_ID, interval, 0); +} + +static int +mswindows_button2_near_enough (POINTS p1, POINTS p2) +{ + int dx, dy; + if (mswindows_button2_max_skew_x <= 0) + dx = GetSystemMetrics (SM_CXDOUBLECLK) / 2; + else + dx = mswindows_button2_max_skew_x; + + if (mswindows_button2_max_skew_y <= 0) + dy = GetSystemMetrics (SM_CYDOUBLECLK) / 2; + else + dy = mswindows_button2_max_skew_y; + + return abs (p1.x - p2.x) < dx && abs (p1.y- p2.y)< dy; +} /* * The windows procedure for the window class XEMACS_CLASS * Stuffs messages in the mswindows event queue */ -static LRESULT WINAPI mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, - LPARAM lParam) +LRESULT WINAPI +mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { /* Note: Remember to initialise these before use */ Lisp_Object emacs_event; struct Lisp_Event *event; - - static sizing = 0; - MSG msg = { hwnd, message, wParam, lParam, 0, {0,0} }; - msg.time = GetMessageTime(); - -#ifdef DEBUG_MESSAGES - stderr_out("Message %04x, wParam=%04x, lParam=%08lx\n", message, wParam, lParam); -#endif + Lisp_Object fobj; + struct frame *frame; + struct mswindows_frame* msframe; + switch (message) { + case WM_ERASEBKGND: + /* Erase background only during non-dynamic sizing */ + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + if (msframe->sizing && !mswindows_dynamic_frame_resize) + goto defproc; + return 1; + + case WM_CLOSE: + fobj = mswindows_find_frame (hwnd); + enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt)); + mswindows_enqueue_magic_event (hwnd, XM_BUMPQUEUE); + break; + case WM_KEYDOWN: case WM_SYSKEYDOWN: { + MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), GetMessagePos() }; /* Handle those keys that TranslateMessage won't generate a WM_CHAR for */ Lisp_Object keysym; int mods = mswindows_modifier_state(); if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods))) { - EnterCriticalSection (&mswindows_dispatch_crit); emacs_event = Fmake_event (Qnil, Qnil); event = XEVENT(emacs_event); event->channel = mswindows_find_console(hwnd); - event->timestamp = msg.time; + event->timestamp = GetMessageTime(); event->event_type = key_press_event; event->event.key.keysym = keysym; event->event.key.modifiers = mods; mswindows_enqueue_dispatch_event (emacs_event); - LeaveCriticalSection (&mswindows_dispatch_crit); return (0); } + TranslateMessage (&msg); } - TranslateMessage (&msg); /* Maybe generates WM_[SYS]CHAR in message queue */ goto defproc; case WM_CHAR: case WM_SYSCHAR: { - EnterCriticalSection (&mswindows_dispatch_crit); emacs_event = Fmake_event (Qnil, Qnil); event = XEVENT(emacs_event); event->channel = mswindows_find_console(hwnd); - event->timestamp = msg.time; + event->timestamp = GetMessageTime(); event->event_type = key_press_event; /* XEmacs doesn't seem to like Shift on non-alpha keys */ @@ -256,6 +284,16 @@ mswindows_modifier_state() : mswindows_modifier_state() & ~MOD_SHIFT; + /* If a quit char with no modifiers other than control and + shift, then mark it with a fake modifier, which is removed + upon dequeueing the event */ + if (wParam == CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd))) + && ((event->event.key.modifiers & ~(MOD_CONTROL | MOD_SHIFT)) == 0)) + { + event->event.key.modifiers |= FAKE_MOD_QUIT; + ++mswindows_quit_chars_count; + } + if (wParam<' ') /* Control char not already handled under WM_KEYDOWN */ { /* Don't capitalise alpha control keys */ @@ -270,95 +308,200 @@ } mswindows_enqueue_dispatch_event (emacs_event); - LeaveCriticalSection (&mswindows_dispatch_crit); } break; + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + /* Real middle mouse button has nothing to do with emulated one: + if one wants to exercise fingers playing chords on the mouse, + he is allowed to do that! */ + mswindows_enqueue_mouse_button_event (hwnd, message, + MAKEPOINTS (lParam), GetMessageTime()); + break; + + case WM_LBUTTONUP: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + msframe->last_click_time = GetMessageTime(); + + KillTimer (hwnd, BUTTON_2_TIMER_ID); + msframe->button2_need_lbutton = 0; + if (msframe->ignore_next_lbutton_up) + { + msframe->ignore_next_lbutton_up = 0; + } + else if (msframe->button2_is_down) + { + msframe->button2_is_down = 0; + msframe->ignore_next_rbutton_up = 1; + mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP, + MAKEPOINTS (lParam), GetMessageTime()); + } + else + { + if (msframe->button2_need_rbutton) + { + msframe->button2_need_rbutton = 0; + mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + } + mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONUP, + MAKEPOINTS (lParam), GetMessageTime()); + } + break; + + case WM_RBUTTONUP: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + msframe->last_click_time = GetMessageTime(); + + KillTimer (hwnd, BUTTON_2_TIMER_ID); + msframe->button2_need_rbutton = 0; + if (msframe->ignore_next_rbutton_up) + { + msframe->ignore_next_rbutton_up = 0; + } + else if (msframe->button2_is_down) + { + msframe->button2_is_down = 0; + msframe->ignore_next_lbutton_up = 1; + mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP, + MAKEPOINTS (lParam), GetMessageTime()); + } + else + { + if (msframe->button2_need_lbutton) + { + msframe->button2_need_lbutton = 0; + mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + } + mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONUP, + MAKEPOINTS (lParam), GetMessageTime()); + } + break; + case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + + if (msframe->button2_need_lbutton) + { + KillTimer (hwnd, BUTTON_2_TIMER_ID); + msframe->button2_need_lbutton = 0; + msframe->button2_need_rbutton = 0; + msframe->button2_is_down = 1; + if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam))) + mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + else + { + mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, + msframe->last_click_point, msframe->last_click_time); + mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + } + } + else + { + mswindows_set_chord_timer (hwnd); + msframe->button2_need_rbutton = 1; + msframe->last_click_point = MAKEPOINTS (lParam); + } + msframe->last_click_time = GetMessageTime(); + break; + case WM_RBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + + if (msframe->button2_need_rbutton) + { + KillTimer (hwnd, BUTTON_2_TIMER_ID); + msframe->button2_need_lbutton = 0; + msframe->button2_need_rbutton = 0; + msframe->button2_is_down = 1; + if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam))) + mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + else + { + mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, + msframe->last_click_point, msframe->last_click_time); + mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, + MAKEPOINTS (lParam), GetMessageTime()); + } + } + else + { + mswindows_set_chord_timer (hwnd); + msframe->button2_need_lbutton = 1; + msframe->last_click_point = MAKEPOINTS (lParam); + } + msframe->last_click_time = GetMessageTime(); + break; + + case WM_TIMER: + if (wParam == BUTTON_2_TIMER_ID) + { + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + KillTimer (hwnd, BUTTON_2_TIMER_ID); + + if (msframe->button2_need_lbutton) + { + msframe->button2_need_lbutton = 0; + mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN, + msframe->last_click_point, msframe->last_click_time); + } + else if (msframe->button2_need_rbutton) + { + msframe->button2_need_rbutton = 0; + mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN, + msframe->last_click_point, msframe->last_click_time); + } + } + else + assert ("Spurious timer fired" == 0); + break; + + case WM_MOUSEMOVE: + /* Optimization: don't report mouse movement while size is changind */ + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + if (!msframe->sizing) { - /* XXX FIXME: Do middle button emulation */ - short x, y; + /* When waiting for the second mouse button to finish + button2 emulation, and have moved too far, just pretend + as if timer has expired. This impoves drag-select feedback */ + if ((msframe->button2_need_lbutton || msframe->button2_need_rbutton) + && !mswindows_button2_near_enough (msframe->last_click_point, + MAKEPOINTS (lParam))) + { + KillTimer (hwnd, BUTTON_2_TIMER_ID); + SendMessage (hwnd, WM_TIMER, BUTTON_2_TIMER_ID, 0); + } - EnterCriticalSection (&mswindows_dispatch_crit); emacs_event = Fmake_event (Qnil, Qnil); event = XEVENT(emacs_event); event->channel = mswindows_find_frame(hwnd); - event->timestamp = msg.time; - event->event.button.button = - (message==WM_LBUTTONDOWN || message==WM_LBUTTONUP) ? 1 : - ((message==WM_RBUTTONDOWN || message==WM_RBUTTONUP) ? 3 : 2); - x = LOWORD (lParam); - y = HIWORD (lParam); - event->event.button.x = x; - event->event.button.y = y; - event->event.button.modifiers = mswindows_modifier_state(); - - if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN || - message==WM_RBUTTONDOWN) - { - event->event_type = button_press_event; - SetCapture (hwnd); - } - else - { - event->event_type = button_release_event; - ReleaseCapture (); - } - - mswindows_enqueue_dispatch_event (emacs_event); - LeaveCriticalSection (&mswindows_dispatch_crit); - } - break; - - case WM_MOUSEMOVE: - /* Optimization: don't report mouse movement while size is changind */ - if (!sizing) - { - short x, y; - - EnterCriticalSection (&mswindows_dispatch_crit); - emacs_event = Fmake_event (Qnil, Qnil); - event = XEVENT(emacs_event); - - event->channel = mswindows_find_frame(hwnd); - event->timestamp = msg.time; + event->timestamp = GetMessageTime(); event->event_type = pointer_motion_event; - x = LOWORD (lParam); - y = HIWORD (lParam); - event->event.motion.x = x; - event->event.motion.y = y; + event->event.motion.x = MAKEPOINTS(lParam).x; + event->event.motion.y = MAKEPOINTS(lParam).y; event->event.motion.modifiers = mswindows_modifier_state(); mswindows_enqueue_dispatch_event (emacs_event); - LeaveCriticalSection (&mswindows_dispatch_crit); } break; case WM_PAINT: - if (GetUpdateRect(hwnd, NULL, FALSE)) { PAINTSTRUCT paintStruct; - - EnterCriticalSection (&mswindows_dispatch_crit); - emacs_event = Fmake_event (Qnil, Qnil); - event = XEVENT(emacs_event); + + frame = XFRAME (mswindows_find_frame (hwnd)); - event->channel = mswindows_find_frame(hwnd); - event->timestamp = msg.time; - event->event_type = magic_event; BeginPaint (hwnd, &paintStruct); - EVENT_MSWINDOWS_MAGIC_TYPE(event) = message; - EVENT_MSWINDOWS_MAGIC_DATA(event) = paintStruct.rcPaint; + mswindows_redraw_exposed_area (frame, + paintStruct.rcPaint.left, paintStruct.rcPaint.top, + paintStruct.rcPaint.right, paintStruct.rcPaint.bottom); EndPaint (hwnd, &paintStruct); - - mswindows_enqueue_dispatch_event (emacs_event); - LeaveCriticalSection (&mswindows_dispatch_crit); } break; @@ -367,42 +510,46 @@ if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED || wParam==SIZE_MINIMIZED) { RECT rect; - EnterCriticalSection (&mswindows_dispatch_crit); - emacs_event = Fmake_event (Qnil, Qnil); - event = XEVENT(emacs_event); + int columns, rows; - event->channel = mswindows_find_frame(hwnd); - event->timestamp = msg.time; - event->event_type = magic_event; + fobj = mswindows_find_frame (hwnd); + frame = XFRAME (fobj); + msframe = FRAME_MSWINDOWS_DATA (frame); + + /* We cannot handle frame map and unmap hooks right in + this routine, because these may throw. We queue + magic events to run these hooks instead - kkm */ + if (wParam==SIZE_MINIMIZED) - rect.left = rect.top = rect.right = rect.bottom = -1; + { + /* Iconified */ + FRAME_VISIBLE_P (frame) = 0; + mswindows_enqueue_magic_event (hwnd, XM_UNMAPFRAME); + Fframe_iconified_p (fobj); + } else - GetClientRect(hwnd, &rect); - EVENT_MSWINDOWS_MAGIC_TYPE(event) = message; - EVENT_MSWINDOWS_MAGIC_DATA(event) = rect; + { + int was_visible = FRAME_VISIBLE_P (frame); + if (!msframe->sizing && !was_visible) + mswindows_enqueue_magic_event (hwnd, XM_MAPFRAME); + + GetClientRect(hwnd, &rect); + FRAME_VISIBLE_P(frame) = 1; + FRAME_PIXWIDTH(frame) = rect.right; + FRAME_PIXHEIGHT(frame) = rect.bottom; + pixel_to_char_size (frame, rect.right, rect.bottom, &columns, &rows); + change_frame_size (frame, rows, columns, 1); - mswindows_enqueue_dispatch_event (emacs_event); - LeaveCriticalSection (&mswindows_dispatch_crit); + if (mswindows_dynamic_frame_resize) + redisplay (); + } } break; /* Misc magic events which only require that the frame be identified */ case WM_SETFOCUS: case WM_KILLFOCUS: - case WM_CLOSE: - { - EnterCriticalSection (&mswindows_dispatch_crit); - emacs_event = Fmake_event (Qnil, Qnil); - event = XEVENT (emacs_event); - - event->channel = mswindows_find_frame (hwnd); - event->timestamp = msg.time; - event->event_type = magic_event; - EVENT_MSWINDOWS_MAGIC_TYPE (event) = message; - - mswindows_enqueue_dispatch_event (emacs_event); - LeaveCriticalSection (&mswindows_dispatch_crit); - } + mswindows_enqueue_magic_event (hwnd, message); break; case WM_WINDOWPOSCHANGING: @@ -416,7 +563,9 @@ { RECT ncsize = { 0, 0, 0, 0 }; int pixwidth, pixheight; - AdjustWindowRect (&ncsize, GetWindowLong (hwnd, GWL_STYLE), FALSE); + AdjustWindowRectEx (&ncsize, GetWindowLong (hwnd, GWL_STYLE), + GetMenu(hwnd) != NULL, + GetWindowLong (hwnd, GWL_EXSTYLE)); round_size_to_char (XFRAME (mswindows_find_frame (hwnd)), wp->cx - (ncsize.right - ncsize.left), @@ -447,9 +596,16 @@ break; case WM_ENTERSIZEMOVE: + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + msframe->sizing = 1; + return 0; + case WM_EXITSIZEMOVE: - sizing = (message == WM_ENTERSIZEMOVE); - goto defproc; + msframe = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd))); + msframe->sizing = 0; + /* Queue noop event */ + mswindows_enqueue_magic_event (hwnd, XM_BUMPQUEUE); + return 0; defproc: default: @@ -459,6 +615,7 @@ } +#if 0 /* * Make a request to the message-processing thread to do things that * can't be done in the main thread. @@ -466,94 +623,17 @@ LPARAM mswindows_make_request(UINT message, WPARAM wParam, mswindows_request_type *request) { - MSG msg; - assert(PostThreadMessage (mswindows_win_thread_id, message, wParam, - (LPARAM) request)); - GetMessage (&msg, NULL, WM_XEMACS_ACK, WM_XEMACS_ACK); - return (msg.lParam); -} - - -/* - * Handle a request from the main thread to do things that have to be - * done in the message-processing thread. - */ -static void -mswindows_handle_request (MSG *msg) -{ - mswindows_request_type *request = (mswindows_request_type *) msg->lParam; - - switch (msg->message) - { - case WM_XEMACS_CREATEWINDOW: - { - struct frame *f = request->thing1; - Lisp_Object *props = request->thing2; - Lisp_Object name, height, width, popup, top, left; - int pixel_width, pixel_height; - RECT rect; - DWORD style; - HWND hwnd; - - name = Fplist_get (*props, Qname, Qnil); - height = Fplist_get (*props, Qheight, Qnil); - width = Fplist_get (*props, Qwidth, Qnil); - popup = Fplist_get (*props, Qpopup, Qnil); - top = Fplist_get (*props, Qtop, Qnil); - left = Fplist_get (*props, Qleft, Qnil); - - style = (NILP(popup)) ? MSWINDOWS_FRAME_STYLE : MSWINDOWS_POPUP_STYLE; - - FRAME_WIDTH (f) = INTP(width) ? XINT(width) : 80; - FRAME_HEIGHT (f) = INTP(height) ? XINT(height) : 30; - char_to_pixel_size (f, FRAME_WIDTH(f), FRAME_HEIGHT (f), - &FRAME_PIXWIDTH (f), &FRAME_PIXHEIGHT (f)); - - rect.left = rect.top = 0; - rect.right = FRAME_PIXWIDTH (f); - rect.bottom = FRAME_PIXHEIGHT (f); -#ifdef HAVE_MENUBARS - AdjustWindowRect(&rect, style, TRUE); -#else - AdjustWindowRect(&rect, style, FALSE); -#endif - - hwnd = CreateWindow (XEMACS_CLASS, - STRINGP(f->name) ? XSTRING_DATA(f->name) : - (STRINGP(name) ? XSTRING_DATA(name) : XEMACS_CLASS), - style, - INTP(left) ? XINT(left) : CW_USEDEFAULT, - INTP(top) ? XINT(top) : CW_USEDEFAULT, - rect.right-rect.left, rect.bottom-rect.top, - NULL, NULL, NULL, NULL); - assert(PostThreadMessage (mswindows_main_thread_id, WM_XEMACS_ACK, 0, (LPARAM) hwnd)); - } - return; - - case WM_XEMACS_DESTROYWINDOW: - { - struct frame *f = request->thing1; - ReleaseDC(FRAME_MSWINDOWS_HANDLE(f), FRAME_MSWINDOWS_DC(f)); - DestroyWindow(FRAME_MSWINDOWS_HANDLE(f)); - assert (PostThreadMessage (mswindows_main_thread_id, WM_XEMACS_ACK, 0, 0)); - } - break; - case WM_XEMACS_SETTIMER: { int id; - EnterCriticalSection (&mswindows_dispatch_crit); id = mswindows_enqueue_timeout((int) request->thing1); - LeaveCriticalSection (&mswindows_dispatch_crit); assert(PostThreadMessage (mswindows_main_thread_id, WM_XEMACS_ACK, 0, id)); } break; case WM_XEMACS_KILLTIMER: { - EnterCriticalSection (&mswindows_dispatch_crit); mswindows_dequeue_timeout((int) request->thing1); - LeaveCriticalSection (&mswindows_dispatch_crit); assert(PostThreadMessage (mswindows_main_thread_id, WM_XEMACS_ACK, 0, 0)); } break; @@ -562,7 +642,7 @@ assert(0); } } - +#endif /* Returns the state of the modifier keys in the format expected by the * Lisp_Event key_data, button_data and motion_data modifiers member */ @@ -650,7 +730,7 @@ return Qnil; } - +#if 0 /* * Add a timeout to the queue. Returns the id or 0 on failure */ @@ -791,12 +871,12 @@ Fdeallocate_event(match_event); } } - +#endif /* * Find the console that matches the supplied mswindows window handle */ -static Lisp_Object +Lisp_Object mswindows_find_console (HWND hwnd) { Lisp_Object concons; @@ -817,19 +897,7 @@ static Lisp_Object mswindows_find_frame (HWND hwnd) { - Lisp_Object frmcons, devcons, concons; - - FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) - { - struct frame *f; - Lisp_Object frame = XCAR (frmcons); - f = XFRAME (frame); - if (FRAME_TYPE_P(f, mswindows)) /* Might be a stream-type frame */ - if (FRAME_MSWINDOWS_HANDLE(f)==hwnd) - return frame; - } - assert(0); /* XXX Can't happen! we only get messages for our windows */ - return Qnil; + return (Lisp_Object) GetWindowLong (hwnd, XWL_FRAMEOBJ); }