1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-1999 Tor Lillqvist
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 /* Cannot use TrackMouseEvent, as the stupid WM_MOUSELEAVE message
29 * doesn't tell us where the mouse has gone. Thus we cannot use it to
30 * generate a correct GdkNotifyType. Pity, as using TrackMouseEvent
31 * otherwise would make it possible to reliably generate
32 * GDK_LEAVE_NOTIFY events, which would help get rid of those pesky
33 * tooltips sometimes popping up in the wrong place.
35 /* define USE_TRACKMOUSEEVENT */
37 /* Do use SetCapture, it works now. Thanks to jpe@archaeopteryx.com */
38 #define USE_SETCAPTURE 1
43 #include "gdkprivate-win32.h"
44 #include "gdkinput-win32.h"
45 #include "gdkkeysyms.h"
49 #if defined (__GNUC__) && defined (HAVE_DIMM_H)
50 /* The w32api imm.h clashes a bit with the IE5.5 dimm.h */
51 # define IMEMENUITEMINFOA hidden_IMEMENUITEMINFOA
52 # define IMEMENUITEMINFOW hidden_IMEMENUITEMINFOW
57 #if defined (__GNUC__) && defined (HAVE_DIMM_H)
58 # undef IMEMENUITEMINFOA
59 # undef IMEMENUITEMINFOW
67 typedef struct _GdkEventPrivate GdkEventPrivate;
71 /* Following flag is set for events on the event queue during
72 * translation and cleared afterwards.
74 GDK_EVENT_PENDING = 1 << 0
77 struct _GdkEventPrivate
84 * Private function declarations
87 static GdkFilterReturn
88 gdk_event_apply_filters(MSG *msg,
91 static gboolean gdk_event_translate (GdkEvent *event,
93 gboolean *ret_val_flagp,
95 gboolean return_exposes);
97 static gboolean gdk_event_prepare (GSource *source,
99 static gboolean gdk_event_check (GSource *source);
100 static gboolean gdk_event_dispatch (GSource *source,
101 GSourceFunc callback,
104 /* Private variable declarations
107 static GdkWindow *p_grab_window = NULL; /* Window that currently
108 * holds the pointer grab
111 static GdkWindow *k_grab_window = NULL; /* Window the holds the
115 static GList *client_filters; /* Filters for client messages */
117 static gboolean p_grab_automatic;
118 static GdkEventMask p_grab_mask;
119 static gboolean p_grab_owner_events, k_grab_owner_events;
120 static HCURSOR p_grab_cursor;
122 static GSourceFuncs event_funcs = {
129 GPollFD event_poll_fd;
131 static GdkWindow *current_window = NULL;
132 static gint current_x, current_y;
133 static gdouble current_x_root, current_y_root;
134 static UINT gdk_ping_msg;
135 static UINT msh_mousewheel_msg;
136 static gboolean ignore_wm_char = FALSE;
137 static gboolean is_altgr_key = FALSE;
140 static IActiveIMMApp *active_imm_app = NULL;
141 static IActiveIMMMessagePumpOwner *active_imm_msgpump_owner = NULL;
144 typedef BOOL (WINAPI *PFN_TrackMouseEvent) (LPTRACKMOUSEEVENT);
145 static PFN_TrackMouseEvent track_mouse_event = NULL;
147 static gboolean use_ime_composition = FALSE;
150 real_window_procedure (HWND hwnd,
155 GdkEventPrivate event;
161 gboolean ret_val_flag;
164 msg.message = message;
167 msg.time = GetTickCount ();
168 pos = GetMessagePos ();
169 msg.pt.x = LOWORD (pos);
170 msg.pt.y = HIWORD (pos);
172 event.flags = GDK_EVENT_PENDING;
173 if (gdk_event_translate (&event.event, &msg, &ret_val_flag, &ret_val, FALSE))
175 event.flags &= ~GDK_EVENT_PENDING;
177 if (event.event.any.type == GDK_CONFIGURE)
179 /* Compress configure events */
180 GList *list = _gdk_queued_events;
183 && (((GdkEvent *)list->data)->any.type != GDK_CONFIGURE
184 || ((GdkEvent *)list->data)->any.window != event.event.any.window))
188 GDK_NOTE (EVENTS, g_print ("... compressing an CONFIGURE event\n"));
190 *((GdkEvent *)list->data) = event.event;
191 gdk_drawable_unref (event.event.any.window);
192 /* Wake up WaitMessage */
193 PostMessage (NULL, gdk_ping_msg, 0, 0);
197 else if (event.event.any.type == GDK_EXPOSE)
199 /* Compress expose events */
200 GList *list = _gdk_queued_events;
203 && (((GdkEvent *)list->data)->any.type != GDK_EXPOSE
204 || ((GdkEvent *)list->data)->any.window != event.event.any.window))
210 GDK_NOTE (EVENTS, g_print ("... compressing an EXPOSE event\n"));
211 gdk_rectangle_union (&event.event.expose.area,
212 &((GdkEvent *)list->data)->expose.area,
214 ((GdkEvent *)list->data)->expose.area = u;
215 gdk_drawable_unref (event.event.any.window);
217 /* Wake up WaitMessage */
218 PostMessage (NULL, gdk_ping_msg, 0, 0);
224 eventp = _gdk_event_new ();
225 *((GdkEventPrivate *) eventp) = event;
227 /* Philippe Colantoni <colanton@aris.ss.uci.edu> suggests this
228 * in order to handle events while opaque resizing neatly. I
229 * don't want it as default. Set the
230 * GDK_EVENT_FUNC_FROM_WINDOW_PROC env var to get this
233 if (gdk_event_func_from_window_proc && _gdk_event_func)
235 GDK_THREADS_ENTER ();
237 (*_gdk_event_func) (eventp, _gdk_event_data);
238 gdk_event_free (eventp);
240 GDK_THREADS_LEAVE ();
244 _gdk_event_queue_append (eventp);
246 /* Wake up WaitMessage */
247 PostMessage (NULL, gdk_ping_msg, 0, 0);
262 return DefWindowProc (hwnd, message, wparam, lparam);
264 if (active_imm_app == NULL
265 || (*active_imm_app->lpVtbl->OnDefWindowProc) (active_imm_app, hwnd, message, wparam, lparam, &lres) == S_FALSE)
266 return DefWindowProc (hwnd, message, wparam, lparam);
274 _gdk_win32_window_procedure (HWND hwnd,
281 GDK_NOTE (MISC, g_print ("_gdk_win32_window_procedure: %#lx %s\n",
282 (gulong) hwnd, gdk_win32_message_name (message)));
284 retval = real_window_procedure (hwnd, message, wparam, lparam);
286 GDK_NOTE (MISC, g_print ("_gdk_win32_window_procedure: %#lx returns %ld\n",
287 (gulong) hwnd, retval));
293 _gdk_events_init (void)
297 #ifdef USE_TRACKMOUSEEVENT
298 HMODULE user32, imm32;
299 HINSTANCE commctrl32;
302 gdk_ping_msg = RegisterWindowMessage ("gdk-ping");
303 GDK_NOTE (EVENTS, g_print ("gdk-ping = %#x\n", gdk_ping_msg));
305 /* This is the string MSH_MOUSEWHEEL from zmouse.h,
306 * http://www.microsoft.com/mouse/intellimouse/sdk/zmouse.h
307 * This message is used by mouse drivers than cannot generate WM_MOUSEWHEEL
310 msh_mousewheel_msg = RegisterWindowMessage ("MSWHEEL_ROLLMSG");
311 GDK_NOTE (EVENTS, g_print ("MSH_MOUSEWHEEL = %#x\n", msh_mousewheel_msg));
313 source = g_source_new (&event_funcs, sizeof (GSource));
314 g_source_set_priority (source, GDK_PRIORITY_EVENTS);
316 event_poll_fd.fd = G_WIN32_MSG_HANDLE;
317 event_poll_fd.events = G_IO_IN;
319 g_source_add_poll (source, &event_poll_fd);
320 g_source_set_can_recurse (source, TRUE);
321 g_source_attach (source, NULL);
324 hres = CoCreateInstance (&CLSID_CActiveIMM,
328 (LPVOID *) &active_imm_app);
332 GDK_NOTE (EVENTS, g_print ("IActiveIMMApp created %p\n",
334 (*active_imm_app->lpVtbl->Activate) (active_imm_app, TRUE);
336 hres = (*active_imm_app->lpVtbl->QueryInterface) (active_imm_app, &IID_IActiveIMMMessagePumpOwner, &active_imm_msgpump_owner);
337 GDK_NOTE (EVENTS, g_print ("IActiveIMMMessagePumpOwner created %p\n",
338 active_imm_msgpump_owner));
339 (active_imm_msgpump_owner->lpVtbl->Start) (active_imm_msgpump_owner);
343 #ifdef USE_TRACKMOUSEEVENT
344 user32 = GetModuleHandle ("user32.dll");
345 if ((track_mouse_event = GetProcAddress (user32, "TrackMouseEvent")) == NULL)
347 if ((commctrl32 = LoadLibrary ("commctrl32.dll")) != NULL)
348 track_mouse_event = (PFN_TrackMouseEvent)
349 GetProcAddress (commctrl32, "_TrackMouseEvent");
351 if (track_mouse_event != NULL)
352 GDK_NOTE (EVENTS, g_print ("Using TrackMouseEvent to detect leave events\n"));
354 if (IS_WIN_NT () && (windows_version & 0xFF) == 5)
356 /* On Win2k (Beta 3, at least) WM_IME_CHAR doesn't seem to work
357 * correctly for non-Unicode applications. Handle
358 * WM_IME_COMPOSITION with GCS_RESULTSTR instead, fetch the
359 * Unicode char from the IME with ImmGetCompositionStringW().
361 use_ime_composition = TRUE;
366 *--------------------------------------------------------------
369 * Returns if events are pending on the queue.
374 * Returns TRUE if events are pending
378 *--------------------------------------------------------------
382 gdk_events_pending (void)
386 return (_gdk_event_queue_find_first() ||
387 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE));
391 *--------------------------------------------------------------
392 * gdk_event_get_graphics_expose
394 * Waits for a GraphicsExpose or NoExpose event
399 * For GraphicsExpose events, returns a pointer to the event
400 * converted into a GdkEvent Otherwise, returns NULL.
404 *-------------------------------------------------------------- */
407 gdk_event_get_graphics_expose (GdkWindow *window)
412 g_return_val_if_fail (window != NULL, NULL);
414 GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose\n"));
417 /* Some nasty bugs here, just return NULL for now. */
420 if (PeekMessage (&msg, GDK_WINDOW_HWND (window), WM_PAINT, WM_PAINT, PM_REMOVE))
422 event = _gdk_event_new ();
424 if (gdk_event_translate (event, &msg, NULL, NULL, TRUE))
427 gdk_event_free (event);
435 event_mask_string (GdkEventMask mask)
437 static char bfr[500];
442 if (mask & GDK_##x##_MASK) \
443 p += sprintf (p, "%s" #x, (p > bfr ? " " : ""))
446 BIT(POINTER_MOTION_HINT);
459 BIT(PROPERTY_CHANGE);
460 BIT(VISIBILITY_NOTIFY);
471 *--------------------------------------------------------------
474 * Grabs the pointer to a specific window
477 * "window" is the window which will receive the grab
478 * "owner_events" specifies whether events will be reported as is,
479 * or relative to "window"
480 * "event_mask" masks only interesting events
481 * "confine_to" limits the cursor movement to the specified window
482 * "cursor" changes the cursor for the duration of the grab
483 * "time" specifies the time
488 * requires a corresponding call to gdk_pointer_ungrab
490 *--------------------------------------------------------------
494 gdk_pointer_grab (GdkWindow *window,
495 gboolean owner_events,
496 GdkEventMask event_mask,
497 GdkWindow *confine_to,
501 HWND hwnd_confined_to;
503 GdkCursorPrivate *cursor_private;
506 g_return_val_if_fail (window != NULL, 0);
507 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
508 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
510 cursor_private = (GdkCursorPrivate*) cursor;
512 if (!confine_to || GDK_WINDOW_DESTROYED (confine_to))
513 hwnd_confined_to = NULL;
515 hwnd_confined_to = GDK_WINDOW_HWND (confine_to);
520 hcursor = cursor_private->hcursor;
522 return_val = _gdk_input_grab_pointer (window,
528 if (return_val == GDK_GRAB_SUCCESS)
530 if (!GDK_WINDOW_DESTROYED (window))
532 GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#lx %s %#lx %s\n",
533 (gulong) GDK_WINDOW_HWND (window),
534 (owner_events ? "TRUE" : "FALSE"),
536 event_mask_string (event_mask)));
537 p_grab_mask = event_mask;
538 p_grab_owner_events = (owner_events != 0);
539 p_grab_automatic = FALSE;
542 SetCapture (GDK_WINDOW_HWND (window));
544 return_val = GDK_GRAB_SUCCESS;
547 return_val = GDK_GRAB_ALREADY_GRABBED;
550 if (return_val == GDK_GRAB_SUCCESS)
552 p_grab_window = window;
553 p_grab_cursor = hcursor;
560 *--------------------------------------------------------------
563 * Releases any pointer grab
571 *--------------------------------------------------------------
575 gdk_pointer_ungrab (guint32 time)
577 GDK_NOTE (EVENTS, g_print ("gdk_pointer_ungrab\n"));
579 _gdk_input_ungrab_pointer (time);
582 if (GetCapture () != NULL)
586 p_grab_window = NULL;
590 *--------------------------------------------------------------
591 * find_window_for_pointer_event
593 * Find the window a pointer event (mouse up, down, move) should
594 * be reported to. If the return value != reported_window then
595 * the ref count of reported_window will be decremented and the
596 * ref count of the return value will be incremented.
600 * "reported_window" is the gdk window the xevent was reported relative to
601 * "xevent" is the win32 message
607 *--------------------------------------------------------------
611 find_window_for_pointer_event (GdkWindow* reported_window,
617 GdkWindow* other_window;
619 if (p_grab_window == NULL || !p_grab_owner_events)
620 return reported_window;
622 points = MAKEPOINTS (msg->lParam);
625 ClientToScreen (msg->hwnd, &pt);
627 GDK_NOTE (EVENTS, g_print ("Finding window for grabbed pointer event at (%ld, %ld)\n",
630 hwnd = WindowFromPoint (pt);
632 return reported_window;
633 other_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
634 if (other_window == NULL)
635 return reported_window;
637 GDK_NOTE (EVENTS, g_print ("Found window %#x for point (%ld, %ld)\n",
638 (guint) hwnd, pt.x, pt.y));
640 gdk_window_unref (reported_window);
641 gdk_window_ref (other_window);
647 *--------------------------------------------------------------
648 * gdk_pointer_is_grabbed
650 * Tell wether there is an active x pointer grab in effect
658 *--------------------------------------------------------------
662 gdk_pointer_is_grabbed (void)
664 return p_grab_window != NULL;
668 *--------------------------------------------------------------
671 * Grabs the keyboard to a specific window
674 * "window" is the window which will receive the grab
675 * "owner_events" specifies whether events will be reported as is,
676 * or relative to "window"
677 * "time" specifies the time
682 * requires a corresponding call to gdk_keyboard_ungrab
684 *--------------------------------------------------------------
688 gdk_keyboard_grab (GdkWindow *window,
689 gboolean owner_events,
694 g_return_val_if_fail (window != NULL, 0);
695 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
697 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_grab %#lx\n",
698 (gulong) GDK_WINDOW_HWND (window)));
700 if (!GDK_WINDOW_DESTROYED (window))
702 k_grab_owner_events = owner_events != 0;
703 return_val = GDK_GRAB_SUCCESS;
706 return_val = GDK_GRAB_ALREADY_GRABBED;
708 if (return_val == GDK_GRAB_SUCCESS)
709 k_grab_window = window;
715 *--------------------------------------------------------------
716 * gdk_keyboard_ungrab
718 * Releases any keyboard grab
726 *--------------------------------------------------------------
730 gdk_keyboard_ungrab (guint32 time)
732 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_ungrab\n"));
734 k_grab_window = NULL;
737 static GdkFilterReturn
738 gdk_event_apply_filters (MSG *msg,
742 GdkEventFilter *filter;
744 GdkFilterReturn result;
750 filter = (GdkEventFilter *) tmp_list->data;
752 result = (*filter->function) (msg, event, filter->data);
753 if (result != GDK_FILTER_CONTINUE)
756 tmp_list = tmp_list->next;
759 return GDK_FILTER_CONTINUE;
763 gdk_add_client_message_filter (GdkAtom message_type,
767 GdkClientFilter *filter = g_new (GdkClientFilter, 1);
769 filter->type = message_type;
770 filter->function = func;
773 client_filters = g_list_prepend (client_filters, filter);
776 /* Thanks to Markus G. Kuhn <mkuhn@acm.org> for the ksysym<->Unicode
777 * mapping functions, from the xterm sources.
781 build_key_event_state (GdkEvent *event)
783 if (GetKeyState (VK_SHIFT) < 0)
784 event->key.state |= GDK_SHIFT_MASK;
785 if (GetKeyState (VK_CAPITAL) & 0x1)
786 event->key.state |= GDK_LOCK_MASK;
789 if (GetKeyState (VK_CONTROL) < 0)
791 event->key.state |= GDK_CONTROL_MASK;
793 if (event->key.keyval < ' ')
794 event->key.keyval += '@';
798 else if (event->key.keyval < ' ')
800 event->key.state |= GDK_CONTROL_MASK;
801 event->key.keyval += '@';
804 if (GetKeyState (VK_MENU) < 0)
805 event->key.state |= GDK_MOD1_MASK;
810 build_pointer_event_state (MSG *msg)
815 if (msg->wParam & MK_CONTROL)
816 state |= GDK_CONTROL_MASK;
817 if (msg->wParam & MK_LBUTTON)
818 state |= GDK_BUTTON1_MASK;
819 if (msg->wParam & MK_MBUTTON)
820 state |= GDK_BUTTON2_MASK;
821 if (msg->wParam & MK_RBUTTON)
822 state |= GDK_BUTTON3_MASK;
823 if (msg->wParam & MK_SHIFT)
824 state |= GDK_SHIFT_MASK;
825 if (GetKeyState (VK_MENU) < 0)
826 state |= GDK_MOD1_MASK;
827 if (GetKeyState (VK_CAPITAL) & 0x1)
828 state |= GDK_LOCK_MASK;
834 build_keypress_event (GdkWindowImplWin32 *impl,
839 gint i, bytecount, ucount, ucleft, len;
840 guchar buf[100], *bp;
841 wchar_t wbuf[100], *wcp;
843 event->key.type = GDK_KEY_PRESS;
844 event->key.time = msg->time;
845 event->key.state = 0;
847 if (msg->message == WM_IME_COMPOSITION)
849 himc = ImmGetContext (msg->hwnd);
851 bytecount = ImmGetCompositionStringW (himc, GCS_RESULTSTR,
852 wbuf, sizeof (wbuf));
853 ucount = bytecount / 2;
857 if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
859 bytecount = MIN ((msg->lParam & 0xFFFF), sizeof (buf));
860 for (i = 0; i < bytecount; i++)
861 buf[i] = msg->wParam;
863 else /* WM_IME_CHAR */
865 event->key.keyval = GDK_VoidSymbol;
866 if (msg->wParam & 0xFF00)
868 /* Contrary to some versions of the documentation,
869 * the lead byte is the most significant byte.
871 buf[0] = ((msg->wParam >> 8) & 0xFF);
872 buf[1] = (msg->wParam & 0xFF);
877 buf[0] = (msg->wParam & 0xFF);
882 /* Convert from the window's current code page
883 * to Unicode. Then convert to UTF-8.
884 * We don't handle the surrogate stuff. Should we?
886 ucount = MultiByteToWideChar (impl->charset_info.ciACP,
888 wbuf, sizeof (wbuf) / sizeof (wbuf[0]));
892 event->key.keyval = GDK_VoidSymbol;
893 else if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
895 if (msg->wParam < ' ')
897 event->key.keyval = msg->wParam + '@';
898 /* This is needed in case of Alt+nnn or Alt+0nnn (on the numpad)
901 event->key.state |= GDK_CONTROL_MASK;
904 event->key.keyval = gdk_unicode_to_keyval (wbuf[0]);
907 build_key_event_state (event);
909 /* Build UTF-8 string */
925 event->key.string = g_malloc (len + 1);
926 event->key.length = len;
930 bp = event->key.string;
956 case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
957 case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
958 case 1: bp[0] = c | first;
961 for (i = len - 1; i > 0; --i)
963 bp[i] = (c & 0x3f) | 0x80;
975 build_keyrelease_event (GdkWindowImplWin32 *impl,
982 event->key.type = GDK_KEY_RELEASE;
983 event->key.time = msg->time;
984 event->key.state = 0;
986 if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
987 if (msg->wParam < ' ')
988 event->key.keyval = msg->wParam + '@';
992 MultiByteToWideChar (impl->charset_info.ciACP,
993 0, &buf, 1, &wbuf, 1);
995 event->key.keyval = gdk_unicode_to_keyval (wbuf);
998 event->key.keyval = GDK_VoidSymbol;
999 build_key_event_state (event);
1000 event->key.string = NULL;
1001 event->key.length = 0;
1005 print_event_state (gint state)
1007 #define CASE(bit) if (state & GDK_ ## bit ## _MASK) g_print (#bit " ");
1019 print_window_state (GdkWindowState state)
1021 #define CASE(bit) if (state & GDK_WINDOW_STATE_ ## bit ) g_print (#bit " ");
1030 print_event (GdkEvent *event)
1032 gchar *escaped, *kvname;
1034 switch (event->any.type)
1036 #define CASE(x) case x: g_print ( #x " "); break;
1041 CASE (GDK_MOTION_NOTIFY);
1042 CASE (GDK_BUTTON_PRESS);
1043 CASE (GDK_2BUTTON_PRESS);
1044 CASE (GDK_3BUTTON_PRESS);
1045 CASE (GDK_BUTTON_RELEASE);
1046 CASE (GDK_KEY_PRESS);
1047 CASE (GDK_KEY_RELEASE);
1048 CASE (GDK_ENTER_NOTIFY);
1049 CASE (GDK_LEAVE_NOTIFY);
1050 CASE (GDK_FOCUS_CHANGE);
1051 CASE (GDK_CONFIGURE);
1054 CASE (GDK_PROPERTY_NOTIFY);
1055 CASE (GDK_SELECTION_CLEAR);
1056 CASE (GDK_SELECTION_REQUEST);
1057 CASE (GDK_SELECTION_NOTIFY);
1058 CASE (GDK_PROXIMITY_IN);
1059 CASE (GDK_PROXIMITY_OUT);
1060 CASE (GDK_DRAG_ENTER);
1061 CASE (GDK_DRAG_LEAVE);
1062 CASE (GDK_DRAG_MOTION);
1063 CASE (GDK_DRAG_STATUS);
1064 CASE (GDK_DROP_START);
1065 CASE (GDK_DROP_FINISHED);
1066 CASE (GDK_CLIENT_EVENT);
1067 CASE (GDK_VISIBILITY_NOTIFY);
1068 CASE (GDK_NO_EXPOSE);
1070 CASE (GDK_WINDOW_STATE);
1074 g_print ("%#lx ", (gulong) GDK_WINDOW_HWND (event->any.window));
1076 switch (event->any.type)
1079 g_print ("%dx%d@+%d+%d %d",
1080 event->expose.area.width,
1081 event->expose.area.height,
1082 event->expose.area.x,
1083 event->expose.area.y,
1084 event->expose.count);
1086 case GDK_MOTION_NOTIFY:
1087 g_print ("(%.4g,%.4g) %s",
1088 event->motion.x, event->motion.y,
1089 event->motion.is_hint ? "HINT " : "");
1090 print_event_state (event->motion.state);
1092 case GDK_BUTTON_PRESS:
1093 case GDK_2BUTTON_PRESS:
1094 case GDK_3BUTTON_PRESS:
1095 case GDK_BUTTON_RELEASE:
1096 g_print ("%d (%.4g,%.4g) ",
1097 event->button.button,
1098 event->button.x, event->button.y);
1099 print_event_state (event->button.state);
1102 case GDK_KEY_RELEASE:
1103 if (event->key.length == 0)
1104 escaped = g_strdup ("");
1106 escaped = g_strescape (event->key.string, NULL);
1107 kvname = gdk_keyval_name (event->key.keyval);
1108 g_print ("%s %d:\"%s\" ",
1109 (kvname ? kvname : "??"),
1113 print_event_state (event->key.state);
1115 case GDK_ENTER_NOTIFY:
1116 case GDK_LEAVE_NOTIFY:
1118 (event->crossing.detail == GDK_NOTIFY_INFERIOR ? "INFERIOR" :
1119 (event->crossing.detail == GDK_NOTIFY_ANCESTOR ? "ANCESTOR" :
1120 (event->crossing.detail == GDK_NOTIFY_NONLINEAR ? "NONLINEAR" :
1125 (event->scroll.direction == GDK_SCROLL_UP ? "UP" :
1126 (event->scroll.direction == GDK_SCROLL_DOWN ? "DOWN" :
1127 (event->scroll.direction == GDK_SCROLL_LEFT ? "LEFT" :
1128 (event->scroll.direction == GDK_SCROLL_RIGHT ? "RIGHT" :
1130 print_event_state (event->scroll.state);
1132 case GDK_WINDOW_STATE:
1133 print_window_state (event->window_state.changed_mask);
1134 print_window_state (event->window_state.new_window_state);
1143 gdk_window_is_child (GdkWindow *parent,
1146 if (parent == NULL || window == NULL)
1149 return (gdk_window_get_parent (window) == parent ||
1150 gdk_window_is_child (parent, gdk_window_get_parent (window)));
1154 synthesize_enter_or_leave_event (GdkWindow *window,
1157 GdkNotifyType detail,
1163 event = _gdk_event_new ();
1164 event->crossing.type = type;
1165 event->crossing.window = window;
1166 event->crossing.send_event = FALSE;
1167 gdk_window_ref (event->crossing.window);
1168 event->crossing.subwindow = NULL;
1169 event->crossing.time = msg->time;
1170 event->crossing.x = x;
1171 event->crossing.y = y;
1172 event->crossing.x_root = msg->pt.x;
1173 event->crossing.y_root = msg->pt.y;
1174 event->crossing.mode = GDK_CROSSING_NORMAL;
1175 event->crossing.detail = detail;
1176 event->crossing.focus = TRUE; /* ??? */
1177 event->crossing.state = 0; /* ??? */
1179 _gdk_event_queue_append (event);
1181 if (type == GDK_ENTER_NOTIFY
1182 && GDK_WINDOW_OBJECT (window)->extension_events != 0)
1183 _gdk_input_enter_event (&event->crossing, window);
1185 GDK_NOTE (EVENTS, print_event (event));
1189 synthesize_leave_event (GdkWindow *window,
1191 GdkNotifyType detail)
1195 if (!(GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->event_mask & GDK_LEAVE_NOTIFY_MASK))
1198 /* Leave events are at (current_x,current_y) in current_window */
1200 if (current_window != window)
1204 ClientToScreen (GDK_WINDOW_HWND (current_window), &pt);
1205 ScreenToClient (GDK_WINDOW_HWND (window), &pt);
1206 synthesize_enter_or_leave_event (window, msg, GDK_LEAVE_NOTIFY, detail, pt.x, pt.y);
1209 synthesize_enter_or_leave_event (window, msg, GDK_LEAVE_NOTIFY, detail, current_x, current_y);
1214 synthesize_enter_event (GdkWindow *window,
1216 GdkNotifyType detail)
1220 if (!(GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->event_mask & GDK_ENTER_NOTIFY_MASK))
1223 /* Enter events are at LOWORD (msg->lParam), HIWORD
1224 * (msg->lParam) in msg->hwnd */
1226 pt.x = LOWORD (msg->lParam);
1227 pt.y = HIWORD (msg->lParam);
1228 if (msg->hwnd != GDK_WINDOW_HWND (window))
1230 ClientToScreen (msg->hwnd, &pt);
1231 ScreenToClient (GDK_WINDOW_HWND (window), &pt);
1233 synthesize_enter_or_leave_event (window, msg, GDK_ENTER_NOTIFY, detail, pt.x, pt.y);
1237 synthesize_enter_events (GdkWindow *from,
1240 GdkNotifyType detail)
1242 GdkWindow *prev = gdk_window_get_parent (to);
1245 synthesize_enter_events (from, prev, msg, detail);
1246 synthesize_enter_event (to, msg, detail);
1250 synthesize_leave_events (GdkWindow *from,
1253 GdkNotifyType detail)
1255 GdkWindow *next = gdk_window_get_parent (from);
1257 synthesize_leave_event (from, msg, detail);
1259 synthesize_leave_events (next, to, msg, detail);
1263 synthesize_crossing_events (GdkWindow *window,
1266 GdkWindow *intermediate, *tem, *common_ancestor;
1268 if (gdk_window_is_child (current_window, window))
1270 /* Pointer has moved to an inferior window. */
1271 synthesize_leave_event (current_window, msg, GDK_NOTIFY_INFERIOR);
1273 /* If there are intermediate windows, generate ENTER_NOTIFY
1276 intermediate = gdk_window_get_parent (window);
1277 if (intermediate != current_window)
1279 synthesize_enter_events (current_window, intermediate, msg, GDK_NOTIFY_VIRTUAL);
1282 synthesize_enter_event (window, msg, GDK_NOTIFY_ANCESTOR);
1284 else if (gdk_window_is_child (window, current_window))
1286 /* Pointer has moved to an ancestor window. */
1287 synthesize_leave_event (current_window, msg, GDK_NOTIFY_ANCESTOR);
1289 /* If there are intermediate windows, generate LEAVE_NOTIFY
1292 intermediate = gdk_window_get_parent (current_window);
1293 if (intermediate != window)
1295 synthesize_leave_events (intermediate, window, msg, GDK_NOTIFY_VIRTUAL);
1298 else if (current_window)
1300 /* Find least common ancestor of current_window and window */
1301 tem = current_window;
1303 common_ancestor = gdk_window_get_parent (tem);
1304 tem = common_ancestor;
1305 } while (common_ancestor &&
1306 !gdk_window_is_child (common_ancestor, window));
1307 if (common_ancestor)
1309 synthesize_leave_event (current_window, msg, GDK_NOTIFY_NONLINEAR);
1310 intermediate = gdk_window_get_parent (current_window);
1311 if (intermediate != common_ancestor)
1313 synthesize_leave_events (intermediate, common_ancestor,
1314 msg, GDK_NOTIFY_NONLINEAR_VIRTUAL);
1316 intermediate = gdk_window_get_parent (window);
1317 if (intermediate != common_ancestor)
1319 synthesize_enter_events (common_ancestor, intermediate,
1320 msg, GDK_NOTIFY_NONLINEAR_VIRTUAL);
1322 synthesize_enter_event (window, msg, GDK_NOTIFY_NONLINEAR);
1327 /* Dunno where we are coming from */
1328 synthesize_enter_event (window, msg, GDK_NOTIFY_UNKNOWN);
1332 gdk_window_unref (current_window);
1333 current_window = window;
1334 gdk_window_ref (current_window);
1338 translate_mouse_coords (GdkWindow *window1,
1344 pt.x = LOWORD (msg->lParam);
1345 pt.y = HIWORD (msg->lParam);
1346 ClientToScreen (GDK_WINDOW_HWND (window1), &pt);
1347 ScreenToClient (GDK_WINDOW_HWND (window2), &pt);
1348 msg->lParam = MAKELPARAM (pt.x, pt.y);
1349 GDK_NOTE (EVENTS, g_print ("...new coords are (%ld,%ld)\n", pt.x, pt.y));
1353 propagate (GdkWindow **window,
1355 GdkWindow *grab_window,
1356 gboolean grab_owner_events,
1358 gboolean (*doesnt_want_it) (gint mask,
1361 gboolean in_propagation = FALSE;
1363 if (grab_window != NULL && !grab_owner_events)
1365 /* Event source is grabbed with owner_events FALSE */
1366 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE, "));
1367 if ((*doesnt_want_it) (grab_mask, msg))
1369 GDK_NOTE (EVENTS, g_print ("...grabber doesn't want it\n"));
1374 GDK_NOTE (EVENTS, g_print ("...sending to grabber %#lx\n",
1375 (gulong) GDK_WINDOW_HWND (grab_window)));
1376 gdk_drawable_unref (*window);
1377 *window = grab_window;
1378 gdk_drawable_ref (*window);
1384 if ((*doesnt_want_it) (GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (*window)->impl)->event_mask, msg))
1386 /* Owner doesn't want it, propagate to parent. */
1387 if (GDK_WINDOW (GDK_WINDOW_OBJECT (*window)->parent) == _gdk_parent_root)
1389 /* No parent; check if grabbed */
1390 if (grab_window != NULL)
1392 /* Event source is grabbed with owner_events TRUE */
1393 GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
1394 if ((*doesnt_want_it) (grab_mask, msg))
1396 /* Grabber doesn't want it either */
1397 GDK_NOTE (EVENTS, g_print ("...grabber doesn't want it\n"));
1404 g_print ("...sending to grabber %#lx\n",
1405 (gulong) GDK_WINDOW_HWND (grab_window)));
1406 gdk_drawable_unref (*window);
1407 *window = grab_window;
1408 gdk_drawable_ref (*window);
1414 GDK_NOTE (EVENTS, g_print ("...undelivered\n"));
1420 gdk_drawable_unref (*window);
1421 *window = GDK_WINDOW (GDK_WINDOW_OBJECT (*window)->parent);
1422 gdk_drawable_ref (*window);
1423 GDK_NOTE (EVENTS, g_print ("%s %#lx",
1424 (in_propagation ? "," : " ...propagating to"),
1425 (gulong) GDK_WINDOW_HWND (*window)));
1426 /* The only branch where we actually continue the loop */
1427 in_propagation = TRUE;
1436 doesnt_want_key (gint mask,
1439 return (((msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
1440 && !(mask & GDK_KEY_RELEASE_MASK))
1442 ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN)
1443 && !(mask & GDK_KEY_PRESS_MASK)));
1447 doesnt_want_char (gint mask,
1450 return !(mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK));
1454 doesnt_want_button_press (gint mask,
1457 return !(mask & GDK_BUTTON_PRESS_MASK);
1461 doesnt_want_button_release (gint mask,
1464 return !(mask & GDK_BUTTON_RELEASE_MASK);
1468 doesnt_want_button_motion (gint mask,
1471 return !((mask & GDK_POINTER_MOTION_MASK)
1472 || ((msg->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
1473 && (mask & GDK_BUTTON_MOTION_MASK))
1474 || ((msg->wParam & MK_LBUTTON)
1475 && (mask & GDK_BUTTON1_MOTION_MASK))
1476 || ((msg->wParam & MK_MBUTTON)
1477 && (mask & GDK_BUTTON2_MOTION_MASK))
1478 || ((msg->wParam & MK_RBUTTON)
1479 && (mask & GDK_BUTTON3_MOTION_MASK)));
1483 doesnt_want_scroll (gint mask,
1487 return !(mask & GDK_SCROLL_MASK);
1489 return !(mask & GDK_BUTTON_PRESS_MASK);
1494 decode_key_lparam (LPARAM lParam)
1496 static char buf[100];
1499 if (HIWORD (lParam) & KF_UP)
1500 p += sprintf (p, "KF_UP ");
1501 if (HIWORD (lParam) & KF_REPEAT)
1502 p += sprintf (p, "KF_REPEAT ");
1503 if (HIWORD (lParam) & KF_ALTDOWN)
1504 p += sprintf (p, "KF_ALTDOWN ");
1505 if (HIWORD (lParam) & KF_EXTENDED)
1506 p += sprintf (p, "KF_EXTENDED ");
1507 p += sprintf (p, "sc%d rep%d", LOBYTE (HIWORD (lParam)), LOWORD (lParam));
1513 gdk_event_translate (GdkEvent *event,
1515 gboolean *ret_val_flagp,
1517 gboolean return_exposes)
1521 PAINTSTRUCT paintstruct;
1534 * window_impl == GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)
1537 GdkWindowImplWin32 *window_impl;
1538 #define ASSIGN_WINDOW(rhs) \
1540 window_impl = (window ? GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl) : NULL))
1542 GdkWindow *orig_window, *new_window;
1543 GdkColormap *colormap;
1544 GdkColormapPrivateWin32 *colormap_private;
1546 GdkPixmapImplWin32 *pixmap_impl;
1547 gint xoffset, yoffset;
1553 gboolean return_val;
1558 *ret_val_flagp = FALSE;
1560 ASSIGN_WINDOW (gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd));
1561 orig_window = window;
1563 event->any.window = window;
1565 /* InSendMessage() does not really mean the same as X11's send_event flag,
1566 * but it is close enough, says jpe@archaeopteryx.com.
1568 event->any.send_event = InSendMessage ();
1572 /* Handle WM_QUIT here ? */
1573 if (msg->message == WM_QUIT)
1575 GDK_NOTE (EVENTS, g_print ("WM_QUIT: %d\n", msg->wParam));
1578 else if (msg->message == WM_MOVE
1579 || msg->message == WM_SIZE)
1581 /* It's quite normal to get these messages before we have
1582 * had time to register the window in our lookup table, or
1583 * when the window is being destroyed and we already have
1584 * removed it. Repost the same message to our queue so that
1585 * we will get it later when we are prepared.
1587 GDK_NOTE(MISC, g_print("gdk_event_translate: %#lx %s posted.\n",
1589 msg->message == WM_MOVE ?
1590 "WM_MOVE" : "WM_SIZE"));
1592 PostMessage (msg->hwnd, msg->message,
1593 msg->wParam, msg->lParam);
1595 #ifndef WITHOUT_WM_CREATE
1596 else if (WM_CREATE == msg->message)
1598 window = (UNALIGNED GdkWindow*) (((LPCREATESTRUCT) msg->lParam)->lpCreateParams);
1599 GDK_WINDOW_HWND (window) = msg->hwnd;
1600 GDK_NOTE (EVENTS, g_print ("gdk_event_translate: created %#x\n",
1601 (guint) msg->hwnd));
1603 /* This should handle allmost all the other window==NULL cases.
1604 * This code is executed while gdk_window_new is in it's
1605 * CreateWindowEx call.
1606 * Don't insert xid there a second time, if it's done here.
1608 gdk_drawable_ref (window);
1609 gdk_win32_handle_table_insert (&GDK_WINDOW_HWND(window), window);
1614 GDK_NOTE (EVENTS, g_print ("gdk_event_translate: %s for %#x (NULL)\n",
1615 gdk_win32_message_name(msg->message),
1616 (guint) msg->hwnd));
1622 gdk_drawable_ref (window);
1624 if (!GDK_WINDOW_DESTROYED (window))
1626 /* Check for filters for this window */
1627 GdkFilterReturn result;
1629 result = gdk_event_apply_filters
1630 (msg, event, GDK_WINDOW_OBJECT (window)->filters);
1632 if (result != GDK_FILTER_CONTINUE)
1634 return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
1636 *ret_val_flagp = TRUE;
1638 *ret_valp = return_val;
1643 /* to translate coordinates to the internal > 16 bit system */
1644 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1646 if (msg->message == gdk_selection_notify_msg)
1648 GDK_NOTE (EVENTS, g_print ("gdk_selection_notify_msg: %#lx\n",
1649 (gulong) msg->hwnd));
1651 event->selection.type = GDK_SELECTION_NOTIFY;
1652 event->selection.window = window;
1653 event->selection.selection = GDK_POINTER_TO_ATOM (msg->wParam);
1654 event->selection.target = GDK_POINTER_TO_ATOM (msg->lParam);
1655 event->selection.property = _gdk_selection_property;
1656 event->selection.time = msg->time;
1658 return_val = !GDK_WINDOW_DESTROYED (window);
1662 else if (msg->message == gdk_selection_request_msg)
1664 GDK_NOTE (EVENTS, g_print ("gdk_selection_request_msg: %#lx\n",
1665 (gulong) msg->hwnd));
1667 event->selection.type = GDK_SELECTION_REQUEST;
1668 event->selection.window = window;
1669 event->selection.selection = gdk_clipboard_atom;
1670 event->selection.target = GDK_TARGET_STRING;
1671 event->selection.property = _gdk_selection_property;
1672 event->selection.requestor = (guint32) msg->hwnd;
1673 event->selection.time = msg->time;
1675 return_val = !GDK_WINDOW_DESTROYED (window);
1679 else if (msg->message == gdk_selection_clear_msg)
1681 GDK_NOTE (EVENTS, g_print ("gdk_selection_clear_msg: %#lx\n",
1682 (gulong) msg->hwnd));
1684 event->selection.type = GDK_SELECTION_CLEAR;
1685 event->selection.window = window;
1686 event->selection.selection = GDK_POINTER_TO_ATOM (msg->wParam);
1687 event->selection.target = GDK_POINTER_TO_ATOM (msg->lParam);
1688 event->selection.time = msg->time;
1690 return_val = !GDK_WINDOW_DESTROYED (window);
1694 else if (msg->message == msh_mousewheel_msg)
1696 GDK_NOTE (EVENTS, g_print ("MSH_MOUSEWHEEL: %#lx %d\n",
1697 (gulong) msg->hwnd, msg->wParam));
1699 event->scroll.type = GDK_SCROLL;
1701 /* MSG_MOUSEWHEEL is delivered to the foreground window. Work
1702 * around that. Also, the position is in screen coordinates, not
1703 * client coordinates as with the button messages.
1705 pt.x = LOWORD (msg->lParam);
1706 pt.y = HIWORD (msg->lParam);
1707 if ((hwnd = WindowFromPoint (pt)) == NULL)
1711 if ((new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd)) == NULL)
1714 if (new_window != window)
1716 gdk_drawable_unref (window);
1717 ASSIGN_WINDOW (new_window);
1718 gdk_drawable_ref (window);
1721 if (GDK_WINDOW_OBJECT (window)->extension_events != 0
1722 && _gdk_input_ignore_core)
1724 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1728 if (!propagate (&window, msg,
1729 p_grab_window, p_grab_owner_events, p_grab_mask,
1730 doesnt_want_scroll))
1733 ASSIGN_WINDOW (window);
1735 ScreenToClient (msg->hwnd, &pt);
1736 event->button.window = window;
1737 event->scroll.direction = ((int) msg->wParam > 0) ?
1738 GDK_SCROLL_UP : GDK_SCROLL_DOWN;
1739 event->scroll.window = window;
1740 event->scroll.time = msg->time;
1741 event->scroll.x = (gint16) pt.x + xoffset;
1742 event->scroll.y = (gint16) pt.y + yoffset;
1743 event->scroll.x_root = (gint16) LOWORD (msg->lParam);
1744 event->scroll.y_root = (gint16) HIWORD (msg->lParam);
1745 event->scroll.state = 0; /* No state information with MSH_MOUSEWHEEL */
1746 event->scroll.device = _gdk_core_pointer;
1747 return_val = !GDK_WINDOW_DESTROYED (window);
1754 GdkFilterReturn result = GDK_FILTER_CONTINUE;
1756 tmp_list = client_filters;
1759 GdkClientFilter *filter = tmp_list->data;
1760 /* FIXME: under win32 messages are not really atoms
1761 * as the following cast suggest, but the appears to be right
1762 * Haven't found a use case though ...
1764 if (filter->type == GDK_POINTER_TO_ATOM (msg->message))
1766 GDK_NOTE (EVENTS, g_print ("client filter matched\n"));
1767 event->any.window = window;
1768 result = (*filter->function) (msg, event, filter->data);
1771 case GDK_FILTER_REMOVE:
1772 *ret_val_flagp = TRUE;
1777 case GDK_FILTER_TRANSLATE:
1781 case GDK_FILTER_CONTINUE:
1782 *ret_val_flagp = TRUE;
1785 event->client.type = GDK_CLIENT_EVENT;
1786 event->client.window = window;
1787 /* FIXME: check if the cast is correct, see above */
1788 event->client.message_type = GDK_POINTER_TO_ATOM (msg->message);
1789 event->client.data_format = 0;
1790 event->client.data.l[0] = msg->wParam;
1791 event->client.data.l[1] = msg->lParam;
1796 tmp_list = tmp_list->next;
1800 switch (msg->message)
1802 case WM_INPUTLANGCHANGE:
1804 g_print ("WM_INPUTLANGCHANGE: %#lx charset %lu locale %lx\n",
1805 (gulong) msg->hwnd, (gulong) msg->wParam, msg->lParam));
1806 window_impl->input_locale = (HKL) msg->lParam;
1807 TranslateCharsetInfo ((DWORD FAR *) msg->wParam,
1808 &window_impl->charset_info,
1815 g_print ("WM_SYSKEY%s: %#lx %s %#x %s\n",
1816 (msg->message == WM_SYSKEYUP ? "UP" : "DOWN"),
1818 (GetKeyNameText (msg->lParam, buf,
1822 decode_key_lparam (msg->lParam)));
1824 /* Let the system handle Alt-Tab and Alt-Enter */
1825 if (msg->wParam == VK_TAB
1826 || msg->wParam == VK_RETURN
1827 || msg->wParam == VK_F4)
1829 /* If posted without us having keyboard focus, ignore */
1830 if (!(msg->lParam & 0x20000000))
1833 /* don't generate events for just the Alt key */
1834 if (msg->wParam == VK_MENU)
1837 /* Jump to code in common with WM_KEYUP and WM_KEYDOWN */
1843 g_print ("WM_KEY%s: %#lx %s %#x %s\n",
1844 (msg->message == WM_KEYUP ? "UP" : "DOWN"),
1846 (GetKeyNameText (msg->lParam, buf,
1850 decode_key_lparam (msg->lParam)));
1852 ignore_wm_char = TRUE;
1856 event->key.window = window;
1857 event->key.hardware_keycode = msg->wParam;
1859 switch (msg->wParam)
1862 event->key.keyval = GDK_Pointer_Button1; break;
1864 event->key.keyval = GDK_Pointer_Button3; break;
1866 event->key.keyval = GDK_Pointer_Button2; break;
1868 event->key.keyval = GDK_Cancel; break;
1870 event->key.keyval = GDK_BackSpace; break;
1872 event->key.keyval = (GetKeyState(VK_SHIFT) < 0 ?
1873 GDK_ISO_Left_Tab : GDK_Tab);
1876 event->key.keyval = GDK_Clear; break;
1878 event->key.keyval = GDK_Return; break;
1880 /* Don't let Shift auto-repeat */
1881 if (msg->message == WM_KEYDOWN
1882 && (HIWORD (msg->lParam) & KF_REPEAT))
1883 ignore_wm_char = FALSE;
1885 event->key.keyval = GDK_Shift_L;
1888 /* And not Control either */
1889 if (msg->message == WM_KEYDOWN
1890 && (HIWORD (msg->lParam) & KF_REPEAT))
1891 ignore_wm_char = FALSE;
1892 else if (HIWORD (msg->lParam) & KF_EXTENDED)
1893 event->key.keyval = GDK_Control_R;
1895 event->key.keyval = GDK_Control_L;
1899 if (msg->message == WM_KEYDOWN
1900 && (HIWORD (msg->lParam) & KF_REPEAT))
1901 ignore_wm_char = FALSE;
1902 else if (HIWORD (msg->lParam) & KF_EXTENDED)
1904 /* AltGr key comes in as Control+Right Alt */
1905 if (GetKeyState (VK_CONTROL) < 0)
1907 ignore_wm_char = FALSE;
1908 is_altgr_key = TRUE;
1910 event->key.keyval = GDK_Alt_R;
1914 event->key.keyval = GDK_Alt_L;
1915 /* This needed in case she types Alt+nnn (on the numpad) */
1916 ignore_wm_char = FALSE;
1920 event->key.keyval = GDK_Pause; break;
1922 event->key.keyval = GDK_Caps_Lock; break;
1924 event->key.keyval = GDK_Escape; break;
1926 event->key.keyval = GDK_Prior; break;
1928 event->key.keyval = GDK_Next; break;
1930 event->key.keyval = GDK_End; break;
1932 event->key.keyval = GDK_Home; break;
1934 event->key.keyval = GDK_Left; break;
1936 event->key.keyval = GDK_Up; break;
1938 event->key.keyval = GDK_Right; break;
1940 event->key.keyval = GDK_Down; break;
1942 event->key.keyval = GDK_Select; break;
1944 event->key.keyval = GDK_Print; break;
1946 event->key.keyval = GDK_Execute; break;
1948 event->key.keyval = GDK_Insert; break;
1950 event->key.keyval = GDK_Delete; break;
1952 event->key.keyval = GDK_Help; break;
1963 /* Apparently applications work better if we just pass numpad digits
1964 * on as real digits? So wait for the WM_CHAR instead.
1966 ignore_wm_char = FALSE;
1969 event->key.keyval = GDK_KP_Multiply; break;
1971 /* Pass it on as an ASCII plus in WM_CHAR. */
1972 ignore_wm_char = FALSE;
1975 event->key.keyval = GDK_KP_Separator; break;
1977 /* Pass it on as an ASCII minus in WM_CHAR. */
1978 ignore_wm_char = FALSE;
1981 /* The keypad decimal key should also be passed on as the decimal
1982 * sign ('.' or ',' depending on the Windows locale settings,
1983 * apparently). So wait for the WM_CHAR here, also.
1985 ignore_wm_char = FALSE;
1988 event->key.keyval = GDK_KP_Divide; break;
1990 event->key.keyval = GDK_F1; break;
1992 event->key.keyval = GDK_F2; break;
1994 event->key.keyval = GDK_F3; break;
1996 event->key.keyval = GDK_F4; break;
1998 event->key.keyval = GDK_F5; break;
2000 event->key.keyval = GDK_F6; break;
2002 event->key.keyval = GDK_F7; break;
2004 event->key.keyval = GDK_F8; break;
2006 event->key.keyval = GDK_F9; break;
2008 event->key.keyval = GDK_F10; break;
2010 event->key.keyval = GDK_F11; break;
2012 event->key.keyval = GDK_F12; break;
2014 event->key.keyval = GDK_F13; break;
2016 event->key.keyval = GDK_F14; break;
2018 event->key.keyval = GDK_F15; break;
2020 event->key.keyval = GDK_F16; break;
2031 if (!is_altgr_key && (GetKeyState (VK_CONTROL) < 0
2032 || GetKeyState (VK_MENU) < 0))
2033 /* Control- or Alt-digits won't come in as a WM_CHAR,
2034 * but beware of AltGr-digits, which are used for instance
2035 * on Finnish keyboards.
2037 event->key.keyval = GDK_0 + (msg->wParam - '0');
2039 ignore_wm_char = FALSE;
2041 case VK_OEM_PLUS: /* On my Win98, the '+' key comes in
2042 * as VK_OEM_PLUS, etc.
2051 if (!is_altgr_key && (GetKeyState (VK_CONTROL) < 0
2052 || GetKeyState (VK_MENU) < 0))
2053 /* Control- or Alt-plus won't come in as WM_CHAR,
2054 * but beware of AltGr-plus which is backslash on
2057 /* All these VK_OEM keycodes happen to be the corresponding ASCII
2060 event->key.keyval = msg->wParam - 0x90;
2062 ignore_wm_char = FALSE;
2065 if (!is_altgr_key && (GetKeyState (VK_CONTROL) < 0
2066 || GetKeyState (VK_MENU) < 0))
2067 /* ;: on US keyboard */
2068 event->key.keyval = ';';
2070 ignore_wm_char = FALSE;
2073 if (!is_altgr_key && (GetKeyState (VK_CONTROL) < 0
2074 || GetKeyState (VK_MENU) < 0))
2075 /* `~ on US keyboard */
2076 event->key.keyval = '`';
2078 ignore_wm_char = FALSE;
2081 if (!is_altgr_key && (GetKeyState (VK_CONTROL) < 0
2082 || GetKeyState (VK_MENU) < 0))
2083 /* '" on US keyboard */
2084 event->key.keyval = '\'';
2086 ignore_wm_char = FALSE;
2089 if (msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSKEYUP)
2090 event->key.keyval = msg->wParam;
2092 ignore_wm_char = FALSE;
2096 if (!ignore_wm_char)
2099 if (!propagate (&window, msg,
2100 k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
2103 ASSIGN_WINDOW (window);
2105 is_altgr_key = FALSE;
2106 event->key.type = ((msg->message == WM_KEYDOWN
2107 || msg->message == WM_SYSKEYDOWN) ?
2108 GDK_KEY_PRESS : GDK_KEY_RELEASE);
2109 event->key.time = msg->time;
2110 event->key.state = 0;
2111 if (GetKeyState (VK_SHIFT) < 0)
2112 event->key.state |= GDK_SHIFT_MASK;
2113 if (GetKeyState (VK_CAPITAL) & 0x1)
2114 event->key.state |= GDK_LOCK_MASK;
2115 if (GetKeyState (VK_CONTROL) < 0)
2116 event->key.state |= GDK_CONTROL_MASK;
2117 if (msg->wParam != VK_MENU && GetKeyState (VK_MENU) < 0)
2118 event->key.state |= GDK_MOD1_MASK;
2119 event->key.string = NULL;
2120 event->key.length = 0;
2121 return_val = !GDK_WINDOW_DESTROYED (window);
2124 case WM_IME_COMPOSITION:
2125 if (!use_ime_composition)
2128 GDK_NOTE (EVENTS, g_print ("WM_IME_COMPOSITION: %#lx %#lx\n",
2129 (gulong) msg->hwnd, msg->lParam));
2130 if (msg->lParam & GCS_RESULTSTR)
2136 g_print ("WM_IME_CHAR: %#lx bytes: %#.04x\n",
2137 (gulong) msg->hwnd, msg->wParam));
2143 g_print ("WM_%sCHAR: %#lx %#x %s %s\n",
2144 (msg->message == WM_CHAR ? "" : "SYS"),
2145 (gulong) msg->hwnd, msg->wParam,
2146 decode_key_lparam (msg->lParam),
2147 (ignore_wm_char ? "ignored" : "")));
2151 ignore_wm_char = FALSE;
2156 if (!propagate (&window, msg,
2157 k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
2160 ASSIGN_WINDOW (window);
2162 event->key.window = window;
2163 return_val = !GDK_WINDOW_DESTROYED (window);
2165 if (return_val && (event->key.window == k_grab_window
2166 || (window_impl->event_mask & GDK_KEY_RELEASE_MASK)))
2168 if (window == k_grab_window
2169 || (window_impl->event_mask & GDK_KEY_PRESS_MASK))
2171 /* Append a GDK_KEY_PRESS event to the pushback list
2172 * (from which it will be fetched before the release
2175 GdkEvent *event2 = _gdk_event_new ();
2176 build_keypress_event (window_impl, event2, msg);
2177 event2->key.window = window;
2178 gdk_drawable_ref (window);
2179 _gdk_event_queue_append (event2);
2180 GDK_NOTE (EVENTS, print_event (event2));
2182 /* Return the key release event. */
2183 build_keyrelease_event (window_impl, event, msg);
2186 && (window_impl->event_mask & GDK_KEY_PRESS_MASK))
2188 /* Return just the key press event. */
2189 build_keypress_event (window_impl, event, msg);
2194 #if 0 /* Don't reset is_AltGr_key here. Othewise we can't type several
2195 * AltGr-accessed chars while keeping the AltGr pressed down
2198 is_AltGr_key = FALSE;
2202 case WM_LBUTTONDOWN:
2205 case WM_MBUTTONDOWN:
2208 case WM_RBUTTONDOWN:
2213 g_print ("WM_%cBUTTONDOWN: %#lx (%d,%d)\n",
2216 LOWORD (msg->lParam), HIWORD (msg->lParam)));
2218 if (GDK_WINDOW_OBJECT (window)->extension_events != 0
2219 && _gdk_input_ignore_core)
2221 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
2225 ASSIGN_WINDOW (find_window_for_pointer_event (window, msg));
2227 if (window != current_window)
2228 synthesize_crossing_events (window, msg);
2230 event->button.type = GDK_BUTTON_PRESS;
2231 if (!propagate (&window, msg,
2232 p_grab_window, p_grab_owner_events, p_grab_mask,
2233 doesnt_want_button_press))
2235 ASSIGN_WINDOW (window);
2237 event->button.window = window;
2239 /* Emulate X11's automatic active grab */
2242 /* No explicit active grab, let's start one automatically */
2243 gint owner_events = window_impl->event_mask
2244 & (GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK);
2246 GDK_NOTE (EVENTS, g_print ("...automatic grab started\n"));
2247 gdk_pointer_grab (window,
2249 window_impl->event_mask,
2251 p_grab_automatic = TRUE;
2254 event->button.time = msg->time;
2255 if (window != orig_window)
2256 translate_mouse_coords (orig_window, window, msg);
2257 event->button.x = current_x = (gint16) LOWORD (msg->lParam);
2258 event->button.y = current_y = (gint16) HIWORD (msg->lParam);
2259 event->button.x += xoffset; /* XXX translate current_x, y too? */
2260 event->button.y += yoffset;
2261 event->button.x_root = msg->pt.x;
2262 event->button.y_root = msg->pt.y;
2263 event->button.axes = NULL;
2264 event->button.state = build_pointer_event_state (msg);
2265 event->button.button = button;
2266 event->button.device = _gdk_core_pointer;
2268 _gdk_event_button_generate (event);
2270 return_val = !GDK_WINDOW_DESTROYED (window);
2284 g_print ("WM_%cBUTTONUP: %#lx (%d,%d)\n",
2287 LOWORD (msg->lParam), HIWORD (msg->lParam)));
2289 ASSIGN_WINDOW (find_window_for_pointer_event (window, msg));
2291 if (GDK_WINDOW_OBJECT (window)->extension_events != 0
2292 && _gdk_input_ignore_core)
2294 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
2298 if (window != current_window)
2299 synthesize_crossing_events (window, msg);
2301 event->button.type = GDK_BUTTON_RELEASE;
2302 if (!propagate (&window, msg,
2303 p_grab_window, p_grab_owner_events, p_grab_mask,
2304 doesnt_want_button_release))
2309 ASSIGN_WINDOW (window);
2311 event->button.window = window;
2312 event->button.time = msg->time;
2313 if (window != orig_window)
2314 translate_mouse_coords (orig_window, window, msg);
2315 event->button.x = (gint16) LOWORD (msg->lParam) + xoffset;
2316 event->button.y = (gint16) HIWORD (msg->lParam) + yoffset;
2317 event->button.x_root = msg->pt.x;
2318 event->button.y_root = msg->pt.y;
2319 event->button.axes = NULL;
2320 event->button.state = build_pointer_event_state (msg);
2321 event->button.button = button;
2322 event->button.device = _gdk_core_pointer;
2324 return_val = !GDK_WINDOW_DESTROYED (window);
2327 if (p_grab_window != NULL
2329 && (msg->wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) == 0)
2330 gdk_pointer_ungrab (0);
2335 g_print ("WM_MOUSEMOVE: %#lx %#x (%d,%d)\n",
2336 (gulong) msg->hwnd, msg->wParam,
2337 LOWORD (msg->lParam), HIWORD (msg->lParam)));
2339 ASSIGN_WINDOW (find_window_for_pointer_event (window, msg));
2341 /* If we haven't moved, don't create any event.
2342 * Windows sends WM_MOUSEMOVE messages after button presses
2343 * even if the mouse doesn't move. This disturbs gtk.
2345 if (window == current_window
2346 && LOWORD (msg->lParam) == current_x
2347 && HIWORD (msg->lParam) == current_y)
2350 /* HB: only process mouse move messages if we own the active window. */
2351 GetWindowThreadProcessId(GetActiveWindow(), &pidActWin);
2352 GetWindowThreadProcessId(msg->hwnd, &pidThis);
2353 if (pidActWin != pidThis)
2356 if (window != current_window)
2357 synthesize_crossing_events (window, msg);
2359 if (GDK_WINDOW_OBJECT (window)->extension_events != 0
2360 && _gdk_input_ignore_core)
2362 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
2366 event->motion.type = GDK_MOTION_NOTIFY;
2367 if (!propagate (&window, msg,
2368 p_grab_window, p_grab_owner_events, p_grab_mask,
2369 doesnt_want_button_motion))
2371 ASSIGN_WINDOW (window);
2373 event->motion.window = window;
2374 event->motion.time = msg->time;
2375 if (window != orig_window)
2376 translate_mouse_coords (orig_window, window, msg);
2377 event->motion.x = current_x = (gint16) LOWORD (msg->lParam);
2378 event->motion.y = current_y = (gint16) HIWORD (msg->lParam);
2379 event->motion.x += xoffset;
2380 event->motion.y += yoffset;
2381 event->motion.x_root = current_x_root = msg->pt.x;
2382 event->motion.y_root = current_y_root = msg->pt.y;
2383 event->motion.axes = NULL;
2384 event->motion.state = build_pointer_event_state (msg);
2385 event->motion.is_hint = FALSE;
2386 event->motion.device = _gdk_core_pointer;
2388 return_val = !GDK_WINDOW_DESTROYED (window);
2391 case WM_NCMOUSEMOVE:
2393 g_print ("WM_NCMOUSEMOVE: %#lx x,y: %d %d\n",
2395 LOWORD (msg->lParam), HIWORD (msg->lParam)));
2396 if (track_mouse_event == NULL
2397 && current_window != NULL
2398 && (GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (current_window)->impl)->event_mask & GDK_LEAVE_NOTIFY_MASK))
2400 GDK_NOTE (EVENTS, g_print ("...synthesizing LEAVE_NOTIFY event\n"));
2402 event->crossing.type = GDK_LEAVE_NOTIFY;
2403 event->crossing.window = current_window;
2404 event->crossing.subwindow = NULL;
2405 event->crossing.time = msg->time;
2406 event->crossing.x = current_x + xoffset; /* XXX translated current_x */
2407 event->crossing.y = current_y + yoffset;
2408 event->crossing.x_root = current_x_root;
2409 event->crossing.y_root = current_y_root;
2410 event->crossing.mode = GDK_CROSSING_NORMAL;
2411 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
2413 event->crossing.focus = TRUE; /* ??? */
2414 event->crossing.state = 0; /* ??? */
2420 gdk_drawable_unref (current_window);
2421 current_window = NULL;
2427 GDK_NOTE (EVENTS, g_print ("WM_MOUSEWHEEL: %#lx %d\n",
2428 (gulong) msg->hwnd, HIWORD (msg->wParam)));
2430 event->scroll.type = GDK_SCROLL;
2432 /* WM_MOUSEWHEEL is delivered to the focus window Work around
2433 * that. Also, the position is in screen coordinates, not client
2434 * coordinates as with the button messages. I love the
2435 * consistency of Windows.
2437 pt.x = LOWORD (msg->lParam);
2438 pt.y = HIWORD (msg->lParam);
2439 if ((hwnd = WindowFromPoint (pt)) == NULL)
2443 if ((new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd)) == NULL)
2446 if (new_window != window)
2448 gdk_drawable_unref (window);
2449 ASSIGN_WINDOW (new_window);
2450 gdk_drawable_ref (window);
2453 if (GDK_WINDOW_OBJECT (window)->extension_events != 0
2454 && _gdk_input_ignore_core)
2456 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
2460 if (!propagate (&window, msg,
2461 p_grab_window, p_grab_owner_events, p_grab_mask,
2462 doesnt_want_scroll))
2465 ASSIGN_WINDOW (window);
2467 ScreenToClient (msg->hwnd, &pt);
2468 event->button.window = window;
2469 event->scroll.direction = (((short) HIWORD (msg->wParam)) > 0) ?
2470 GDK_SCROLL_UP : GDK_SCROLL_DOWN;
2471 event->scroll.window = window;
2472 event->scroll.time = msg->time;
2473 event->scroll.x = (gint16) pt.x + xoffset;
2474 event->scroll.y = (gint16) pt.y + yoffset;
2475 event->scroll.x_root = (gint16) LOWORD (msg->lParam);
2476 event->scroll.y_root = (gint16) HIWORD (msg->lParam);
2477 event->scroll.state = build_pointer_event_state (msg);
2478 event->scroll.device = _gdk_core_pointer;
2479 return_val = !GDK_WINDOW_DESTROYED (window);
2483 #ifdef USE_TRACKMOUSEEVENT
2485 GDK_NOTE (EVENTS, g_print ("WM_MOUSELEAVE: %#lx\n", (gulong) msg->hwnd));
2487 if (!(window_impl->event_mask & GDK_LEAVE_NOTIFY_MASK))
2490 event->crossing.type = GDK_LEAVE_NOTIFY;
2491 event->crossing.window = window;
2492 event->crossing.subwindow = NULL;
2493 event->crossing.time = msg->time;
2494 event->crossing.x = current_x + xoffset; /* XXX translated current_x */
2495 event->crossing.y = current_y + yoffset;
2496 event->crossing.x_root = current_xroot;
2497 event->crossing.y_root = current_yroot;
2498 event->crossing.mode = GDK_CROSSING_NORMAL;
2500 && IsChild (GDK_WINDOW_HWND (current_window), GDK_WINDOW_HWND (window)))
2501 event->crossing.detail = GDK_NOTIFY_INFERIOR;
2502 else if (current_window
2503 && IsChild (GDK_WINDOW_HWND (window), GDK_WINDOW_HWND (current_window)))
2504 event->crossing.detail = GDK_NOTIFY_ANCESTOR;
2506 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
2508 event->crossing.focus = TRUE; /* ??? */
2509 event->crossing.state = 0; /* ??? */
2513 gdk_drawable_unref (current_window);
2514 current_window = NULL;
2517 return_val = !GDK_WINDOW_DESTROYED (window);
2523 GDK_NOTE (EVENTS, g_print ("WM_%sFOCUS: %#lx\n",
2524 (msg->message == WM_SETFOCUS ?
2526 (gulong) msg->hwnd));
2528 if (!(window_impl->event_mask & GDK_FOCUS_CHANGE_MASK))
2531 event->focus_change.type = GDK_FOCUS_CHANGE;
2532 event->focus_change.window = window;
2533 event->focus_change.in = (msg->message == WM_SETFOCUS);
2534 return_val = !GDK_WINDOW_DESTROYED (window);
2538 GDK_NOTE (EVENTS, g_print ("WM_ERASEBKGND: %#lx dc %#x\n",
2539 (gulong) msg->hwnd, msg->wParam));
2541 if (GDK_WINDOW_DESTROYED (window))
2544 *ret_val_flagp = TRUE; /* always claim as handled */
2547 if (GDK_WINDOW_OBJECT (window)->input_only)
2550 if (GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->position_info.no_bg)
2552 /* improves scolling effect, e.g. main buttons of testgtk */
2553 *ret_val_flagp = TRUE;
2558 colormap = GDK_DRAWABLE_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->colormap;
2560 colormap_private = GDK_COLORMAP_PRIVATE_DATA (colormap);
2561 hdc = (HDC) msg->wParam;
2562 if (colormap && colormap_private->xcolormap->rc_palette)
2566 if (SelectPalette (hdc, colormap_private->xcolormap->palette,
2568 WIN32_GDI_FAILED ("SelectPalette");
2569 if ((k = RealizePalette (hdc)) == GDI_ERROR)
2570 WIN32_GDI_FAILED ("RealizePalette");
2572 g_print ("WM_ERASEBKGND: selected %#x, realized %d colors\n",
2573 colormap_private->xcolormap->palette, k);
2577 if (GDK_WINDOW_OBJECT (window)->bg_pixmap == GDK_PARENT_RELATIVE_BG)
2579 /* If this window should have the same background as the
2580 * parent, fetch the parent. (And if the same goes for
2581 * the parent, fetch the grandparent, etc.)
2583 while (window && GDK_WINDOW_OBJECT (window)->bg_pixmap == GDK_PARENT_RELATIVE_BG)
2585 gdk_drawable_unref (window);
2586 ASSIGN_WINDOW (GDK_WINDOW (GDK_WINDOW_OBJECT (window)->parent));
2587 gdk_drawable_ref (window);
2591 if (GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->position_info.no_bg)
2593 /* improves scolling effect, e.g. main buttons of testgtk */
2594 *ret_val_flagp = TRUE;
2599 if (GDK_WINDOW_OBJECT (window)->bg_pixmap == NULL)
2601 bg = _gdk_win32_colormap_color (GDK_DRAWABLE_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl)->colormap,
2602 GDK_WINDOW_OBJECT (window)->bg_color.pixel);
2604 GetClipBox (hdc, &rect);
2606 g_print ("...%ldx%ld@+%ld+%ld BG_PIXEL %.06lx\n",
2607 rect.right - rect.left,
2608 rect.bottom - rect.top,
2609 rect.left, rect.top,
2611 hbr = CreateSolidBrush (bg);
2613 g_print ("...CreateSolidBrush (%.08x) = %.08x\n", bg, hbr);
2615 if (!FillRect (hdc, &rect, hbr))
2616 WIN32_GDI_FAILED ("FillRect");
2619 else if (GDK_WINDOW_OBJECT (window)->bg_pixmap != NULL &&
2620 GDK_WINDOW_OBJECT (window)->bg_pixmap != GDK_NO_BG)
2622 pixmap = GDK_WINDOW_OBJECT (window)->bg_pixmap;
2623 pixmap_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
2624 GetClipBox (hdc, &rect);
2626 if (pixmap_impl->width <= 8 && pixmap_impl->height <= 8)
2628 GDK_NOTE (EVENTS, g_print ("...small pixmap, using brush\n"));
2629 hbr = CreatePatternBrush (GDK_PIXMAP_HBITMAP (pixmap));
2630 if (!FillRect (hdc, &rect, hbr))
2631 WIN32_GDI_FAILED ("FillRect");
2637 g_print ("...blitting pixmap %#lx (%dx%d) "
2638 "all over the place,\n"
2639 "...clip box = %ldx%ld@+%ld+%ld\n",
2640 (gulong) GDK_PIXMAP_HBITMAP (pixmap),
2641 pixmap_impl->width, pixmap_impl->height,
2642 rect.right - rect.left, rect.bottom - rect.top,
2643 rect.left, rect.top));
2645 if (!(bgdc = CreateCompatibleDC (hdc)))
2647 WIN32_GDI_FAILED ("CreateCompatibleDC");
2650 if (!(oldbitmap = SelectObject (bgdc, GDK_PIXMAP_HBITMAP (pixmap))))
2652 WIN32_GDI_FAILED ("SelectObject");
2657 while (i < rect.right)
2660 while (j < rect.bottom)
2662 if (i + pixmap_impl->width >= rect.left
2663 && j + pixmap_impl->height >= rect.top)
2665 if (!BitBlt (hdc, i, j,
2666 pixmap_impl->width, pixmap_impl->height,
2667 bgdc, 0, 0, SRCCOPY))
2669 WIN32_GDI_FAILED ("BitBlt");
2673 j += pixmap_impl->height;
2675 i += pixmap_impl->width;
2678 SelectObject (bgdc, oldbitmap);
2684 GDK_NOTE (EVENTS, g_print ("...BLACK_BRUSH (?)\n"));
2685 hbr = GetStockObject (BLACK_BRUSH);
2686 GetClipBox (hdc, &rect);
2687 if (!FillRect (hdc, &rect, hbr))
2688 WIN32_GDI_FAILED ("FillRect");
2693 if (!GetUpdateRect(msg->hwnd, NULL, FALSE))
2695 GDK_NOTE (EVENTS, g_print ("WM_PAINT: %#lx no update rect\n",
2696 (gulong) msg->hwnd));
2700 hdc = BeginPaint (msg->hwnd, &paintstruct);
2703 g_print ("WM_PAINT: %#lx %ldx%ld@+%ld+%ld %s dc %#lx\n",
2705 paintstruct.rcPaint.right - paintstruct.rcPaint.left,
2706 paintstruct.rcPaint.bottom - paintstruct.rcPaint.top,
2707 paintstruct.rcPaint.left, paintstruct.rcPaint.top,
2708 (paintstruct.fErase ? "erase" : ""),
2711 EndPaint (msg->hwnd, &paintstruct);
2713 /* HB: don't generate GDK_EXPOSE events for InputOnly
2714 * windows -> backing store now works!
2716 if (GDK_WINDOW_OBJECT (window)->input_only)
2719 if (!(window_impl->event_mask & GDK_EXPOSURE_MASK))
2722 if (GDK_WINDOW_OBJECT (window)->bg_pixmap == GDK_NO_BG)
2725 if ((paintstruct.rcPaint.right == paintstruct.rcPaint.left)
2726 || (paintstruct.rcPaint.bottom == paintstruct.rcPaint.top))
2731 event->expose.type = GDK_EXPOSE;
2732 event->expose.window = window;
2733 event->expose.area.x = paintstruct.rcPaint.left;
2734 event->expose.area.y = paintstruct.rcPaint.top;
2735 event->expose.area.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left;
2736 event->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
2737 event->expose.region = gdk_region_rectangle (&(event->expose.area));
2738 event->expose.count = 0;
2740 return_val = !GDK_WINDOW_DESTROYED (window);
2743 GList *list = _gdk_queued_events;
2744 while (list != NULL )
2746 if ((((GdkEvent *)list->data)->any.type == GDK_EXPOSE) &&
2747 (((GdkEvent *)list->data)->any.window == window) &&
2748 !(((GdkEventPrivate *)list->data)->flags & GDK_EVENT_PENDING))
2749 ((GdkEvent *)list->data)->expose.count++;
2757 GdkRectangle expose_rect;
2759 expose_rect.x = paintstruct.rcPaint.left + xoffset;
2760 expose_rect.y = paintstruct.rcPaint.top + yoffset;
2761 expose_rect.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left;
2762 expose_rect.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
2764 _gdk_window_process_expose (window, msg->time, &expose_rect);
2771 GDK_NOTE (EVENTS, g_print ("WM_GETICON: %#lx %s\n",
2773 (ICON_BIG == msg->wParam ? "big" : "small")));
2777 GDK_NOTE (EVENTS, g_print ("WM_SETCURSOR: %#lx %#x %#x\n",
2779 LOWORD (msg->lParam), HIWORD (msg->lParam)));
2781 if (LOWORD (msg->lParam) != HTCLIENT)
2784 if (p_grab_window != NULL && p_grab_cursor != NULL)
2785 hcursor = p_grab_cursor;
2786 else if (!GDK_WINDOW_DESTROYED (window))
2787 hcursor = window_impl->hcursor;
2791 if (hcursor != NULL)
2793 GDK_NOTE (EVENTS, g_print ("...SetCursor(%#lx)\n", (gulong) hcursor));
2794 SetCursor (hcursor);
2795 *ret_val_flagp = TRUE;
2801 GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#lx %d\n",
2805 if (!(window_impl->event_mask & GDK_STRUCTURE_MASK))
2808 event->any.type = (msg->wParam ? GDK_MAP : GDK_UNMAP);
2809 event->any.window = window;
2811 if (event->any.type == GDK_UNMAP
2812 && p_grab_window == window)
2813 gdk_pointer_ungrab (msg->time);
2815 if (event->any.type == GDK_UNMAP
2816 && k_grab_window == window)
2817 gdk_keyboard_ungrab (msg->time);
2819 return_val = !GDK_WINDOW_DESTROYED (window);
2824 g_print ("WM_SIZE: %#lx %s %dx%d\n",
2826 (msg->wParam == SIZE_MAXHIDE ? "MAXHIDE" :
2827 (msg->wParam == SIZE_MAXIMIZED ? "MAXIMIZED" :
2828 (msg->wParam == SIZE_MAXSHOW ? "MAXSHOW" :
2829 (msg->wParam == SIZE_MINIMIZED ? "MINIMIZED" :
2830 (msg->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
2831 LOWORD (msg->lParam), HIWORD (msg->lParam)));
2833 if (!(window_impl->event_mask & GDK_STRUCTURE_MASK))
2836 if (msg->wParam == SIZE_MINIMIZED)
2838 event->any.type = GDK_UNMAP;
2839 event->any.window = window;
2841 if (p_grab_window == window)
2842 gdk_pointer_ungrab (msg->time);
2844 if (k_grab_window == window)
2845 gdk_keyboard_ungrab (msg->time);
2847 return_val = !GDK_WINDOW_DESTROYED (window);
2849 else if ((msg->wParam == SIZE_RESTORED
2850 || msg->wParam == SIZE_MAXIMIZED)
2852 && GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD
2856 if (LOWORD (msg->lParam) == 0)
2859 event->configure.type = GDK_CONFIGURE;
2860 event->configure.window = window;
2863 ClientToScreen (msg->hwnd, &pt);
2864 event->configure.x = pt.x;
2865 event->configure.y = pt.y;
2866 event->configure.width = LOWORD (msg->lParam);
2867 event->configure.height = HIWORD (msg->lParam);
2868 GDK_WINDOW_OBJECT (window)->x = event->configure.x;
2869 GDK_WINDOW_OBJECT (window)->y = event->configure.y;
2870 window_impl->width = event->configure.width;
2871 window_impl->height = event->configure.height;
2873 if (GDK_WINDOW_OBJECT (window)->resize_count > 1)
2874 GDK_WINDOW_OBJECT (window)->resize_count -= 1;
2876 return_val = !GDK_WINDOW_DESTROYED (window);
2878 && GDK_WINDOW_OBJECT (window)->extension_events != 0)
2879 _gdk_input_configure_event (&event->configure, window);
2885 LPRECT lpr = (LPRECT) msg->lParam;
2886 NONCLIENTMETRICS ncm;
2887 ncm.cbSize = sizeof (NONCLIENTMETRICS);
2889 SystemParametersInfo (SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
2891 g_print ("WM_SIZING borderWidth %d captionHeight %d\n",
2892 ncm.iBorderWidth, ncm.iCaptionHeight);
2893 event->configure.type = GDK_CONFIGURE;
2894 event->configure.window = window;
2896 event->configure.x = lpr->left + ncm.iBorderWidth;
2897 event->configure.y = lpr->top + ncm.iCaptionHeight;
2898 event->configure.width = lpr->right - lpr->left - 2 * ncm.iBorderWidth;
2899 event->configure.height = lpr->bottom - lpr->top - ncm.iCaptionHeight;
2900 GDK_WINDOW_OBJECT (window)->x = event->configure.x;
2901 GDK_WINDOW_OBJECT (window)->y = event->configure.y;
2902 window_impl->width = event->configure.width;
2903 window_impl->height = event->configure.height;
2905 if (GDK_WINDOW_OBJECT (window)->resize_count > 1)
2906 GDK_WINDOW_OBJECT (window)->resize_count -= 1;
2908 return_val = !GDK_WINDOW_DESTROYED (window);
2910 && GDK_WINDOW_OBJECT (window)->extension_events != 0)
2911 _gdk_input_configure_event (&event->configure, window);
2915 case WM_GETMINMAXINFO:
2916 GDK_NOTE (EVENTS, g_print ("WM_GETMINMAXINFO: %#lx\n", (gulong) msg->hwnd));
2918 mmi = (MINMAXINFO*) msg->lParam;
2919 if (window_impl->hint_flags & GDK_HINT_MIN_SIZE)
2921 mmi->ptMinTrackSize.x = window_impl->hint_min_width;
2922 mmi->ptMinTrackSize.y = window_impl->hint_min_height;
2924 if (window_impl->hint_flags & GDK_HINT_MAX_SIZE)
2926 mmi->ptMaxTrackSize.x = window_impl->hint_max_width;
2927 mmi->ptMaxTrackSize.y = window_impl->hint_max_height;
2929 /* kind of WM functionality, limit maximized size to screen */
2930 mmi->ptMaxPosition.x = 0; mmi->ptMaxPosition.y = 0;
2931 mmi->ptMaxSize.x = MIN(window_impl->hint_max_width, gdk_screen_width ());
2932 mmi->ptMaxSize.y = MIN(window_impl->hint_max_height, gdk_screen_height ());
2937 GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#lx (%d,%d)\n",
2939 LOWORD (msg->lParam), HIWORD (msg->lParam)));
2941 if (!(window_impl->event_mask & GDK_STRUCTURE_MASK))
2944 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD
2945 && !IsIconic(msg->hwnd)
2946 && IsWindowVisible(msg->hwnd))
2948 event->configure.type = GDK_CONFIGURE;
2949 event->configure.window = window;
2950 event->configure.x = LOWORD (msg->lParam);
2951 event->configure.y = HIWORD (msg->lParam);
2952 GetClientRect (msg->hwnd, &rect);
2953 event->configure.width = rect.right;
2954 event->configure.height = rect.bottom;
2955 GDK_WINDOW_OBJECT (window)->x = event->configure.x;
2956 GDK_WINDOW_OBJECT (window)->y = event->configure.y;
2957 window_impl->width = event->configure.width;
2958 window_impl->height = event->configure.height;
2960 return_val = !GDK_WINDOW_DESTROYED (window);
2963 #if 0 /* not quite right, otherwise it may be faster/better than WM_(MOVE|SIZE)
2964 * remove decoration (frame) sizes ?
2966 case WM_WINDOWPOSCHANGED :
2968 if (!(window_impl->event_mask & GDK_STRUCTURE_MASK))
2971 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD
2972 && !IsIconic(msg->hwnd)
2973 && IsWindowVisible(msg->hwnd))
2975 LPWINDOWPOS lpwp = (LPWINDOWPOS) (msg->lParam);
2977 event->configure.type = GDK_CONFIGURE;
2978 event->configure.window = window;
2979 event->configure.x = lpwp->x;
2980 event->configure.y = lpwp->y;
2981 event->configure.width = lpwp->cx;
2982 event->configure.height = lpwp->cy;
2983 GDK_WINDOW_OBJECT (window)->x = event->configure.x;
2984 GDK_WINDOW_OBJECT (window)->y = event->configure.y;
2985 window_impl->width = event->configure.width;
2986 window_impl->height = event->configure.height;
2988 return_val = !GDK_WINDOW_DESTROYED (window);
2990 GDK_NOTE (EVENTS, g_print ("WM_WINDOWPOSCHANGED: %#lx %ldx%ld@+%ld+%ld\n",
2992 lpwp->cx, lpwp->cy, lpwp->x, lpwp->y));
2995 *ret_val_flagp = TRUE;
3002 GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#lx\n", (gulong) msg->hwnd));
3004 event->any.type = GDK_DELETE;
3005 event->any.window = window;
3007 return_val = !GDK_WINDOW_DESTROYED (window);
3011 /* No, don't use delayed rendering after all. It works only if the
3012 * delayed SetClipboardData is called from the WindowProc, it
3013 * seems. (The #else part below is test code for that. It succeeds
3014 * in setting the clipboard data. But if I call SetClipboardData
3015 * in gdk_property_change (as a consequence of the
3016 * GDK_SELECTION_REQUEST event), it fails. I deduce that this is
3017 * because delayed rendering requires that SetClipboardData is
3018 * called in the window procedure.)
3020 case WM_RENDERFORMAT:
3021 case WM_RENDERALLFORMATS:
3023 GDK_NOTE (EVENTS, flag = TRUE);
3025 g_print ("WM_%s: %#lx %#x (%s)\n",
3026 (msg->message == WM_RENDERFORMAT ? "RENDERFORMAT" :
3027 "RENDERALLFORMATS"),
3030 (msg->wParam == CF_TEXT ? "CF_TEXT" :
3031 (msg->wParam == CF_DIB ? "CF_DIB" :
3032 (msg->wParam == CF_UNICODETEXT ? "CF_UNICODETEXT" :
3033 (GetClipboardFormatName (msg->wParam, buf, sizeof (buf)), buf)))));
3036 event->selection.type = GDK_SELECTION_REQUEST;
3037 event->selection.window = window;
3038 event->selection.selection = gdk_clipboard_atom;
3039 if (msg->wParam == CF_TEXT)
3040 event->selection.target = GDK_TARGET_STRING;
3043 GetClipboardFormatName (msg->wParam, buf, sizeof (buf));
3044 event->selection.target = gdk_atom_intern (buf, FALSE);
3046 event->selection.property = _gdk_selection_property;
3047 event->selection.requestor = (guint32) msg->hwnd;
3048 event->selection.time = msg->time;
3049 return_val = !GDK_WINDOW_DESTROYED (window);
3051 /* Test code, to see if SetClipboardData works when called from
3052 * the window procedure.
3055 HGLOBAL hdata = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, 10);
3056 char *ptr = GlobalLock (hdata);
3057 strcpy (ptr, "Huhhaa");
3058 GlobalUnlock (hdata);
3059 if (!SetClipboardData (CF_TEXT, hdata))
3060 WIN32_API_FAILED ("SetClipboardData");
3063 *ret_val_flagp = TRUE;
3067 #endif /* No delayed rendering */
3070 GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#lx\n", (gulong) msg->hwnd));
3072 event->any.type = GDK_DESTROY;
3073 event->any.window = window;
3074 if (window != NULL && window == current_window)
3076 gdk_drawable_unref (current_window);
3077 current_window = NULL;
3080 if (p_grab_window == window)
3081 gdk_pointer_ungrab (msg->time);
3083 if (k_grab_window == window)
3084 gdk_keyboard_ungrab (msg->time);
3086 return_val = window != NULL && !GDK_WINDOW_DESTROYED (window);
3088 if ((window != NULL) && (gdk_root_window != msg->hwnd))
3089 gdk_window_destroy_notify (window);
3094 /* Handle WINTAB events here, as we know that gdkinput.c will
3095 * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
3096 * constants as case labels.
3099 GDK_NOTE (EVENTS, g_print ("WT_PACKET: %#lx %d %#lx\n",
3101 msg->wParam, msg->lParam));
3105 GDK_NOTE (EVENTS, g_print ("WT_CSRCHANGE: %#lx %d %#lx\n",
3107 msg->wParam, msg->lParam));
3111 GDK_NOTE (EVENTS, g_print ("WT_PROXIMITY: %#lx %#x %d %d\n",
3112 (gulong) msg->hwnd, msg->wParam,
3113 LOWORD (msg->lParam),
3114 HIWORD (msg->lParam)));
3117 event->any.window = window;
3118 return_val = _gdk_input_other_event(event, msg, window);
3123 GDK_NOTE (EVENTS, g_print ("%s: %#lx %#x %#lx\n",
3124 gdk_win32_message_name (msg->message),
3126 msg->wParam, msg->lParam));
3133 if (event->any.window)
3134 gdk_drawable_ref (event->any.window);
3135 if (((event->any.type == GDK_ENTER_NOTIFY) ||
3136 (event->any.type == GDK_LEAVE_NOTIFY)) &&
3137 (event->crossing.subwindow != NULL))
3138 gdk_drawable_ref (event->crossing.subwindow);
3140 GDK_NOTE (EVENTS, print_event (event));
3144 /* Mark this event as having no resources to be freed */
3145 event->any.window = NULL;
3146 event->any.type = GDK_NOTHING;
3150 gdk_drawable_unref (window);
3156 _gdk_events_queue (void)
3162 while (!_gdk_event_queue_find_first ()
3163 && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
3165 GDK_NOTE (EVENTS, g_print ("PeekMessage: %#lx %s\n",
3166 (gulong) msg.hwnd, gdk_win32_message_name (msg.message)));
3168 TranslateMessage (&msg);
3170 if (active_imm_msgpump_owner == NULL
3171 || (active_imm_msgpump_owner->lpVtbl->OnTranslateMessage) (active_imm_msgpump_owner, &msg) != S_OK)
3172 TranslateMessage (&msg);
3175 #if 1 /* It was like this all the time */
3176 DispatchMessage (&msg);
3177 #else /* but this one is more similar to the X implementation. Any effect ? */
3178 event = _gdk_event_new ();
3180 event->any.type = GDK_NOTHING;
3181 event->any.window = NULL;
3182 event->any.send_event = InSendMessage ();
3184 ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
3186 _gdk_event_queue_append (event);
3187 node = _gdk_queued_tail;
3189 if (gdk_event_translate (event, &msg, NULL, NULL, FALSE))
3191 ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
3195 _gdk_event_queue_remove_link (node);
3196 g_list_free_1 (node);
3197 gdk_event_free (event);
3198 DispatchMessage (&msg);
3206 gdk_event_prepare (GSource *source,
3212 GDK_THREADS_ENTER ();
3216 retval = (_gdk_event_queue_find_first () != NULL)
3217 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
3219 GDK_THREADS_LEAVE ();
3225 gdk_event_check (GSource *source)
3230 GDK_THREADS_ENTER ();
3232 if (event_poll_fd.revents & G_IO_IN)
3233 retval = (_gdk_event_queue_find_first () != NULL)
3234 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
3238 GDK_THREADS_LEAVE ();
3244 gdk_event_dispatch (GSource *source,
3245 GSourceFunc callback,
3250 GDK_THREADS_ENTER ();
3252 _gdk_events_queue();
3253 event = _gdk_event_unqueue();
3257 if (_gdk_event_func)
3258 (*_gdk_event_func) (event, _gdk_event_data);
3260 gdk_event_free (event);
3263 GDK_THREADS_LEAVE ();
3268 /* Sends a ClientMessage to all toplevel client windows */
3270 gdk_event_send_client_message (GdkEvent *event, guint32 xid)
3277 gdk_event_send_clientmessage_toall (GdkEvent *event)
3288 /* Process all messages currently available */
3289 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
3291 TranslateMessage (&msg); /* Translate virt. key codes */
3292 DispatchMessage (&msg); /* Dispatch msg. to window */
3299 #ifdef G_ENABLE_DEBUG
3302 gdk_win32_message_name (UINT msg)
3304 static gchar bfr[100];
3308 #define CASE(x) case x: return #x
3316 CASE (WM_KILLFOCUS);
3318 CASE (WM_SETREDRAW);
3321 CASE (WM_GETTEXTLENGTH);
3324 CASE (WM_QUERYENDSESSION);
3325 CASE (WM_QUERYOPEN);
3326 CASE (WM_ENDSESSION);
3328 CASE (WM_ERASEBKGND);
3329 CASE (WM_SYSCOLORCHANGE);
3330 CASE (WM_SHOWWINDOW);
3331 CASE (WM_WININICHANGE);
3332 CASE (WM_DEVMODECHANGE);
3333 CASE (WM_ACTIVATEAPP);
3334 CASE (WM_FONTCHANGE);
3335 CASE (WM_TIMECHANGE);
3336 CASE (WM_CANCELMODE);
3337 CASE (WM_SETCURSOR);
3338 CASE (WM_MOUSEACTIVATE);
3339 CASE (WM_CHILDACTIVATE);
3340 CASE (WM_QUEUESYNC);
3341 CASE (WM_GETMINMAXINFO);
3342 CASE (WM_PAINTICON);
3343 CASE (WM_ICONERASEBKGND);
3344 CASE (WM_NEXTDLGCTL);
3345 CASE (WM_SPOOLERSTATUS);
3347 CASE (WM_MEASUREITEM);
3348 CASE (WM_DELETEITEM);
3349 CASE (WM_VKEYTOITEM);
3350 CASE (WM_CHARTOITEM);
3353 CASE (WM_SETHOTKEY);
3354 CASE (WM_GETHOTKEY);
3355 CASE (WM_QUERYDRAGICON);
3356 CASE (WM_COMPAREITEM);
3357 CASE (WM_GETOBJECT);
3358 CASE (WM_COMPACTING);
3359 CASE (WM_WINDOWPOSCHANGING);
3360 CASE (WM_WINDOWPOSCHANGED);
3363 CASE (WM_CANCELJOURNAL);
3365 CASE (WM_INPUTLANGCHANGEREQUEST);
3366 CASE (WM_INPUTLANGCHANGE);
3369 CASE (WM_USERCHANGED);
3370 CASE (WM_NOTIFYFORMAT);
3371 CASE (WM_CONTEXTMENU);
3372 CASE (WM_STYLECHANGING);
3373 CASE (WM_STYLECHANGED);
3374 CASE (WM_DISPLAYCHANGE);
3378 CASE (WM_NCDESTROY);
3379 CASE (WM_NCCALCSIZE);
3380 CASE (WM_NCHITTEST);
3382 CASE (WM_NCACTIVATE);
3383 CASE (WM_GETDLGCODE);
3384 CASE (WM_SYNCPAINT);
3385 CASE (WM_NCMOUSEMOVE);
3386 CASE (WM_NCLBUTTONDOWN);
3387 CASE (WM_NCLBUTTONUP);
3388 CASE (WM_NCLBUTTONDBLCLK);
3389 CASE (WM_NCRBUTTONDOWN);
3390 CASE (WM_NCRBUTTONUP);
3391 CASE (WM_NCRBUTTONDBLCLK);
3392 CASE (WM_NCMBUTTONDOWN);
3393 CASE (WM_NCMBUTTONUP);
3394 CASE (WM_NCMBUTTONDBLCLK);
3395 CASE (WM_NCXBUTTONDOWN);
3396 CASE (WM_NCXBUTTONUP);
3397 CASE (WM_NCXBUTTONDBLCLK);
3402 CASE (WM_SYSKEYDOWN);
3405 CASE (WM_SYSDEADCHAR);
3407 CASE (WM_IME_STARTCOMPOSITION);
3408 CASE (WM_IME_ENDCOMPOSITION);
3409 CASE (WM_IME_COMPOSITION);
3410 CASE (WM_INITDIALOG);
3412 CASE (WM_SYSCOMMAND);
3417 CASE (WM_INITMENUPOPUP);
3418 CASE (WM_MENUSELECT);
3420 CASE (WM_ENTERIDLE);
3421 CASE (WM_MENURBUTTONUP);
3423 CASE (WM_MENUGETOBJECT);
3424 CASE (WM_UNINITMENUPOPUP);
3425 CASE (WM_MENUCOMMAND);
3426 CASE (WM_CHANGEUISTATE);
3427 CASE (WM_UPDATEUISTATE);
3428 CASE (WM_QUERYUISTATE);
3429 CASE (WM_CTLCOLORMSGBOX);
3430 CASE (WM_CTLCOLOREDIT);
3431 CASE (WM_CTLCOLORLISTBOX);
3432 CASE (WM_CTLCOLORBTN);
3433 CASE (WM_CTLCOLORDLG);
3434 CASE (WM_CTLCOLORSCROLLBAR);
3435 CASE (WM_CTLCOLORSTATIC);
3436 CASE (WM_MOUSEMOVE);
3437 CASE (WM_LBUTTONDOWN);
3438 CASE (WM_LBUTTONUP);
3439 CASE (WM_LBUTTONDBLCLK);
3440 CASE (WM_RBUTTONDOWN);
3441 CASE (WM_RBUTTONUP);
3442 CASE (WM_RBUTTONDBLCLK);
3443 CASE (WM_MBUTTONDOWN);
3444 CASE (WM_MBUTTONUP);
3445 CASE (WM_MBUTTONDBLCLK);
3446 CASE (WM_MOUSEWHEEL);
3447 CASE (WM_XBUTTONDOWN);
3448 CASE (WM_XBUTTONUP);
3449 CASE (WM_XBUTTONDBLCLK);
3450 CASE (WM_PARENTNOTIFY);
3451 CASE (WM_ENTERMENULOOP);
3452 CASE (WM_EXITMENULOOP);
3455 CASE (WM_CAPTURECHANGED);
3457 CASE (WM_POWERBROADCAST);
3458 CASE (WM_DEVICECHANGE);
3459 CASE (WM_MDICREATE);
3460 CASE (WM_MDIDESTROY);
3461 CASE (WM_MDIACTIVATE);
3462 CASE (WM_MDIRESTORE);
3464 CASE (WM_MDIMAXIMIZE);
3466 CASE (WM_MDICASCADE);
3467 CASE (WM_MDIICONARRANGE);
3468 CASE (WM_MDIGETACTIVE);
3469 CASE (WM_MDISETMENU);
3470 CASE (WM_ENTERSIZEMOVE);
3471 CASE (WM_EXITSIZEMOVE);
3472 CASE (WM_DROPFILES);
3473 CASE (WM_MDIREFRESHMENU);
3474 CASE (WM_IME_SETCONTEXT);
3475 CASE (WM_IME_NOTIFY);
3476 CASE (WM_IME_CONTROL);
3477 CASE (WM_IME_COMPOSITIONFULL);
3478 CASE (WM_IME_SELECT);
3480 CASE (WM_IME_REQUEST);
3481 CASE (WM_IME_KEYDOWN);
3482 CASE (WM_IME_KEYUP);
3483 CASE (WM_MOUSEHOVER);
3484 CASE (WM_MOUSELEAVE);
3485 CASE (WM_NCMOUSEHOVER);
3486 CASE (WM_NCMOUSELEAVE);
3492 CASE (WM_RENDERFORMAT);
3493 CASE (WM_RENDERALLFORMATS);
3494 CASE (WM_DESTROYCLIPBOARD);
3495 CASE (WM_DRAWCLIPBOARD);
3496 CASE (WM_PAINTCLIPBOARD);
3497 CASE (WM_VSCROLLCLIPBOARD);
3498 CASE (WM_SIZECLIPBOARD);
3499 CASE (WM_ASKCBFORMATNAME);
3500 CASE (WM_CHANGECBCHAIN);
3501 CASE (WM_HSCROLLCLIPBOARD);
3502 CASE (WM_QUERYNEWPALETTE);
3503 CASE (WM_PALETTEISCHANGING);
3504 CASE (WM_PALETTECHANGED);
3507 CASE (WM_PRINTCLIENT);
3508 CASE (WM_APPCOMMAND);
3509 CASE (WM_HANDHELDFIRST);
3510 CASE (WM_HANDHELDLAST);
3513 CASE (WM_PENWINFIRST);
3514 CASE (WM_PENWINLAST);
3518 if (msg >= WM_HANDHELDFIRST && msg <= WM_HANDHELDLAST)
3519 sprintf (bfr, "WM_HANDHELDFIRST+%d", msg - WM_HANDHELDFIRST);
3520 else if (msg >= WM_AFXFIRST && msg <= WM_AFXLAST)
3521 sprintf (bfr, "WM_AFXFIRST+%d", msg - WM_AFXFIRST);
3522 else if (msg >= WM_PENWINFIRST && msg <= WM_PENWINLAST)
3523 sprintf (bfr, "WM_PENWINFIRST+%d", msg - WM_PENWINFIRST);
3524 else if (msg >= WM_USER && msg <= 0x7FFF)
3525 sprintf (bfr, "WM_USER+%d", msg - WM_USER);
3526 else if (msg >= 0xC000 && msg <= 0xFFFF)
3527 sprintf (bfr, "reg-%#x", msg);
3529 sprintf (bfr, "unk-%#x", msg);
3532 g_assert_not_reached ();
3535 #endif /* G_ENABLE_DEBUG */