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 Library 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 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library 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-1999. 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/.
30 /* Cannot use TrackMouseEvent, as the stupid WM_MOUSELEAVE message
31 * doesn't tell us where the mouse has gone. Thus we cannot use it to
32 * generate a correct GdkNotifyType. Pity, as using TrackMouseEvent
33 * otherwise would make it possible to reliably generate
34 * GDK_LEAVE_NOTIFY events, which would help get rid of those pesky
35 * tooltips sometimes popping up in the wrong place.
37 /* define USE_TRACKMOUSEEVENT */
42 #include "gdkinternals.h"
43 #include "gdkprivate-win32.h"
45 #include "gdkkeysyms.h"
47 #include "gdkinputprivate.h"
55 #include "surrogate-dimm.h"
62 #define PING() printf("%s: %d\n",__FILE__,__LINE__),fflush(stdout)
64 #define WINDOW_PRIVATE(wp) GDK_WINDOW_WIN32DATA (wp)
66 typedef struct _GdkIOClosure GdkIOClosure;
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
79 GdkInputFunction function;
80 GdkInputCondition condition;
81 GdkDestroyNotify notify;
85 struct _GdkEventPrivate
92 * Private function declarations
95 static GdkFilterReturn
96 gdk_event_apply_filters(MSG *xevent,
99 static gboolean gdk_event_translate (GdkEvent *event,
101 gboolean *ret_val_flagp,
103 static gboolean gdk_event_prepare (gpointer source_data,
104 GTimeVal *current_time,
107 static gboolean gdk_event_check (gpointer source_data,
108 GTimeVal *current_time,
110 static gboolean gdk_event_dispatch (gpointer source_data,
111 GTimeVal *current_time,
114 static void gdk_synthesize_click (GdkEvent *event,
117 /* Private variable declarations
120 static GdkWindow *p_grab_window = NULL; /* Window that currently
121 * holds the pointer grab
124 static GdkWindow *k_grab_window = NULL; /* Window the holds the
128 static GList *client_filters; /* Filters for client messages */
130 static gboolean p_grab_automatic;
131 static GdkEventMask p_grab_mask;
132 static gboolean p_grab_owner_events, k_grab_owner_events;
133 static HCURSOR p_grab_cursor;
135 static GList *client_filters; /* Filters for client messages */
137 static GSourceFuncs event_funcs = {
141 (GDestroyNotify)g_free
144 GPollFD event_poll_fd;
146 static GdkWindow *curWnd = NULL;
147 static HWND active = NULL;
148 static gint curX, curY;
149 static gdouble curXroot, curYroot;
150 static UINT gdk_ping_msg;
151 static gboolean ignore_WM_CHAR = FALSE;
152 static gboolean is_AltGr_key = FALSE;
154 static IActiveIMMApp *paimmapp = NULL;
155 static IActiveIMMMessagePumpOwner *paimmmpo = NULL;
157 typedef BOOL (WINAPI *PFN_TrackMouseEvent) (LPTRACKMOUSEEVENT);
158 static PFN_TrackMouseEvent p_TrackMouseEvent = NULL;
160 static gboolean use_IME_COMPOSITION = FALSE;
163 gdk_WindowProc (HWND hWnd,
168 GdkEventPrivate event;
174 gboolean ret_val_flag;
176 GDK_NOTE (EVENTS, g_print ("gdk_WindowProc: %#x %s\n",
177 hWnd, gdk_win32_message_name (message)));
180 msg.message = message;
183 msg.time = GetTickCount ();
184 pos = GetMessagePos ();
185 msg.pt.x = LOWORD (pos);
186 msg.pt.y = HIWORD (pos);
188 event.flags = GDK_EVENT_PENDING;
189 if (gdk_event_translate (&event.event, &msg, &ret_val_flag, &ret_val))
191 event.flags &= ~GDK_EVENT_PENDING;
193 if (event.event.any.type == GDK_CONFIGURE)
195 /* Compress configure events */
196 GList *list = gdk_queued_events;
199 && (((GdkEvent *)list->data)->any.type != GDK_CONFIGURE
200 || ((GdkEvent *)list->data)->any.window != event.event.any.window))
204 GDK_NOTE (EVENTS, g_print ("... compressing an CONFIGURE event\n"));
206 *((GdkEvent *)list->data) = event.event;
207 gdk_drawable_unref (event.event.any.window);
208 /* Wake up WaitMessage */
209 PostMessage (NULL, gdk_ping_msg, 0, 0);
213 else if (event.event.any.type == GDK_EXPOSE)
215 /* Compress expose events */
216 GList *list = gdk_queued_events;
219 && (((GdkEvent *)list->data)->any.type != GDK_EXPOSE
220 || ((GdkEvent *)list->data)->any.window != event.event.any.window))
226 GDK_NOTE (EVENTS, g_print ("... compressing an EXPOSE event\n"));
227 gdk_rectangle_union (&event.event.expose.area,
228 &((GdkEvent *)list->data)->expose.area,
230 ((GdkEvent *)list->data)->expose.area = u;
231 gdk_drawable_unref (event.event.any.window);
233 /* Wake up WaitMessage */
234 PostMessage (NULL, gdk_ping_msg, 0, 0);
240 eventp = gdk_event_new ();
241 *((GdkEventPrivate *) eventp) = event;
243 /* Philippe Colantoni <colanton@aris.ss.uci.edu> suggests this
244 * in order to handle events while opaque resizing neatly. I
245 * don't want it as default. Set the
246 * GDK_EVENT_FUNC_FROM_WINDOW_PROC env var to get this
249 if (gdk_event_func_from_window_proc && gdk_event_func)
251 GDK_THREADS_ENTER ();
253 (*gdk_event_func) (eventp, gdk_event_data);
254 gdk_event_free (eventp);
256 GDK_THREADS_LEAVE ();
260 gdk_event_queue_append (eventp);
262 /* Wake up WaitMessage */
263 PostMessage (NULL, gdk_ping_msg, 0, 0);
278 || (*paimmapp->lpVtbl->OnDefWindowProc) (paimmapp, hWnd, message, wParam, lParam, &lres) == S_FALSE)
279 return DefWindowProc (hWnd, message, wParam, lParam);
286 gdk_events_init (void)
289 HMODULE user32, imm32;
290 HINSTANCE commctrl32;
292 if (g_pipe_readable_msg == 0)
293 g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable");
294 GDK_NOTE (EVENTS, g_print ("g-pipe-readable = %#.03x\n",
295 g_pipe_readable_msg));
297 gdk_ping_msg = RegisterWindowMessage ("gdk-ping");
298 GDK_NOTE (EVENTS, g_print ("gdk-ping = %#.03x\n",
301 g_source_add (GDK_PRIORITY_EVENTS, TRUE, &event_funcs, NULL, NULL, NULL);
303 event_poll_fd.fd = G_WIN32_MSG_HANDLE;
304 event_poll_fd.events = G_IO_IN;
306 g_main_add_poll (&event_poll_fd, GDK_PRIORITY_EVENTS);
308 hres = CoCreateInstance (&CLSID_CActiveIMM,
312 (LPVOID *) &paimmapp);
316 GDK_NOTE (EVENTS, g_print ("IActiveIMMApp created %#x\n",
318 (*paimmapp->lpVtbl->Activate) (paimmapp, TRUE);
320 hres = (*paimmapp->lpVtbl->QueryInterface) (paimmapp, &IID_IActiveIMMMessagePumpOwner, &paimmmpo);
321 GDK_NOTE (EVENTS, g_print ("IActiveIMMMessagePumpOwner created %#x\n",
323 (paimmmpo->lpVtbl->Start) (paimmmpo);
326 #ifdef USE_TRACKMOUSEEVENT
327 user32 = GetModuleHandle ("user32.dll");
328 if ((p_TrackMouseEvent = GetProcAddress (user32, "TrackMouseEvent")) == NULL)
330 if ((commctrl32 = LoadLibrary ("commctrl32.dll")) != NULL)
331 p_TrackMouseEvent = (PFN_TrackMouseEvent)
332 GetProcAddress (commctrl32, "_TrackMouseEvent");
334 if (p_TrackMouseEvent != NULL)
335 GDK_NOTE (EVENTS, g_print ("Using TrackMouseEvent to detect leave events\n"));
337 if (IS_WIN_NT (windows_version) && (windows_version & 0xFF) == 5)
339 /* On Win2k (Beta 3, at least) WM_IME_CHAR doesn't seem to work
340 * correctly for non-Unicode applications. Handle
341 * WM_IME_COMPOSITION with GCS_RESULTSTR instead, fetch the
342 * Unicode char from the IME with ImmGetCompositionStringW().
344 use_IME_COMPOSITION = TRUE;
349 *--------------------------------------------------------------
352 * Returns if events are pending on the queue.
357 * Returns TRUE if events are pending
361 *--------------------------------------------------------------
365 gdk_events_pending (void)
369 return (gdk_event_queue_find_first() || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE));
373 *--------------------------------------------------------------
374 * gdk_event_get_graphics_expose
376 * Waits for a GraphicsExpose or NoExpose event
381 * For GraphicsExpose events, returns a pointer to the event
382 * converted into a GdkEvent Otherwise, returns NULL.
386 *-------------------------------------------------------------- */
389 gdk_event_get_graphics_expose (GdkWindow *window)
394 g_return_val_if_fail (window != NULL, NULL);
396 GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose\n"));
399 /* Some nasty bugs here, just return NULL for now. */
402 if (PeekMessage (&xevent, GDK_DRAWABLE_XID (window), WM_PAINT, WM_PAINT, PM_REMOVE))
404 event = gdk_event_new ();
406 if (gdk_event_translate (event, &xevent, NULL, NULL))
409 gdk_event_free (event);
417 event_mask_string (GdkEventMask mask)
419 static char bfr[500];
424 if (mask & GDK_##x##_MASK) \
425 p += sprintf (p, "%s" #x, (p > bfr ? " " : ""))
428 BIT(POINTER_MOTION_HINT);
441 BIT(PROPERTY_CHANGE);
442 BIT(VISIBILITY_NOTIFY);
453 *--------------------------------------------------------------
456 * Grabs the pointer to a specific window
459 * "window" is the window which will receive the grab
460 * "owner_events" specifies whether events will be reported as is,
461 * or relative to "window"
462 * "event_mask" masks only interesting events
463 * "confine_to" limits the cursor movement to the specified window
464 * "cursor" changes the cursor for the duration of the grab
465 * "time" specifies the time
470 * requires a corresponding call to gdk_pointer_ungrab
472 *--------------------------------------------------------------
476 gdk_pointer_grab (GdkWindow * window,
477 gboolean owner_events,
478 GdkEventMask event_mask,
479 GdkWindow * confine_to,
486 GdkCursorPrivate *cursor_private;
489 g_return_val_if_fail (window != NULL, 0);
490 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
491 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
493 cursor_private = (GdkCursorPrivate*) cursor;
495 xwindow = GDK_DRAWABLE_XID (window);
497 if (!confine_to || GDK_DRAWABLE_DESTROYED (confine_to))
500 xconfine_to = GDK_DRAWABLE_XID (confine_to);
505 xcursor = cursor_private->xcursor;
507 if (gdk_input_vtable.grab_pointer)
508 return_val = gdk_input_vtable.grab_pointer (window,
514 return_val = GDK_GRAB_SUCCESS;
516 if (return_val == GDK_GRAB_SUCCESS)
518 if (!GDK_DRAWABLE_DESTROYED (window))
520 GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x %s\n",
522 (owner_events ? "TRUE" : "FALSE"),
524 event_mask_string (event_mask)));
525 p_grab_mask = event_mask;
526 p_grab_owner_events = (owner_events != 0);
527 p_grab_automatic = FALSE;
529 #if 1 /* Menus don't work if we use mouse capture. Pity, because many other
530 * things work better with mouse capture.
532 SetCapture (xwindow);
534 return_val = GDK_GRAB_SUCCESS;
537 return_val = GDK_GRAB_ALREADY_GRABBED;
540 if (return_val == GDK_GRAB_SUCCESS)
542 p_grab_window = window;
543 p_grab_cursor = xcursor;
550 *--------------------------------------------------------------
553 * Releases any pointer grab
561 *--------------------------------------------------------------
565 gdk_pointer_ungrab (guint32 time)
567 if (gdk_input_vtable.ungrab_pointer)
568 gdk_input_vtable.ungrab_pointer (time);
570 if (GetCapture () != NULL)
573 GDK_NOTE (EVENTS, g_print ("gdk_pointer_ungrab\n"));
575 p_grab_window = NULL;
579 *--------------------------------------------------------------
580 * gdk_pointer_is_grabbed
582 * Tell wether there is an active x pointer grab in effect
590 *--------------------------------------------------------------
594 gdk_pointer_is_grabbed (void)
596 return p_grab_window != NULL;
600 *--------------------------------------------------------------
603 * Grabs the keyboard to a specific window
606 * "window" is the window which will receive the grab
607 * "owner_events" specifies whether events will be reported as is,
608 * or relative to "window"
609 * "time" specifies the time
614 * requires a corresponding call to gdk_keyboard_ungrab
616 *--------------------------------------------------------------
620 gdk_keyboard_grab (GdkWindow * window,
621 gboolean owner_events,
626 g_return_val_if_fail (window != NULL, 0);
627 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
629 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_grab %#x\n",
630 GDK_DRAWABLE_XID (window)));
632 if (!GDK_DRAWABLE_DESTROYED (window))
634 k_grab_owner_events = owner_events != 0;
635 return_val = GDK_GRAB_SUCCESS;
638 return_val = GDK_GRAB_ALREADY_GRABBED;
640 if (return_val == GDK_GRAB_SUCCESS)
641 k_grab_window = window;
647 *--------------------------------------------------------------
648 * gdk_keyboard_ungrab
650 * Releases any keyboard grab
658 *--------------------------------------------------------------
662 gdk_keyboard_ungrab (guint32 time)
664 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_ungrab\n"));
666 k_grab_window = NULL;
670 gdk_io_destroy (gpointer data)
672 GdkIOClosure *closure = data;
675 closure->notify (closure->data);
681 gdk_io_invoke (GIOChannel *source,
682 GIOCondition condition,
685 GdkIOClosure *closure = data;
686 GdkInputCondition gdk_cond = 0;
688 if (condition & (G_IO_IN | G_IO_PRI))
689 gdk_cond |= GDK_INPUT_READ;
690 if (condition & G_IO_OUT)
691 gdk_cond |= GDK_INPUT_WRITE;
692 if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
693 gdk_cond |= GDK_INPUT_EXCEPTION;
695 if (closure->condition & gdk_cond)
696 closure->function (closure->data, g_io_channel_unix_get_fd (source), gdk_cond);
701 static GdkFilterReturn
702 gdk_event_apply_filters (MSG *xevent,
706 GdkEventFilter *filter;
708 GdkFilterReturn result;
714 filter = (GdkEventFilter *) tmp_list->data;
716 result = (*filter->function) (xevent, event, filter->data);
717 if (result != GDK_FILTER_CONTINUE)
720 tmp_list = tmp_list->next;
723 return GDK_FILTER_CONTINUE;
727 gdk_add_client_message_filter (GdkAtom message_type,
731 GdkClientFilter *filter = g_new (GdkClientFilter, 1);
733 filter->type = message_type;
734 filter->function = func;
737 client_filters = g_list_prepend (client_filters, filter);
740 /* Thanks to Markus G. Kuhn <mkuhn@acm.org> for the ksysym<->Unicode
741 * mapping functions, from the xterm sources.
745 build_key_event_state (GdkEvent *event)
747 if (GetKeyState (VK_SHIFT) < 0)
748 event->key.state |= GDK_SHIFT_MASK;
749 if (GetKeyState (VK_CAPITAL) & 0x1)
750 event->key.state |= GDK_LOCK_MASK;
753 if (GetKeyState (VK_CONTROL) < 0)
755 event->key.state |= GDK_CONTROL_MASK;
757 if (event->key.keyval < ' ')
758 event->key.keyval += '@';
762 else if (event->key.keyval < ' ')
764 event->key.state |= GDK_CONTROL_MASK;
765 event->key.keyval += '@';
768 if (GetKeyState (VK_MENU) < 0)
769 event->key.state |= GDK_MOD1_MASK;
774 build_pointer_event_state (MSG *xevent)
779 if (xevent->wParam & MK_CONTROL)
780 state |= GDK_CONTROL_MASK;
781 if (xevent->wParam & MK_LBUTTON)
782 state |= GDK_BUTTON1_MASK;
783 if (xevent->wParam & MK_MBUTTON)
784 state |= GDK_BUTTON2_MASK;
785 if (xevent->wParam & MK_RBUTTON)
786 state |= GDK_BUTTON3_MASK;
787 if (xevent->wParam & MK_SHIFT)
788 state |= GDK_SHIFT_MASK;
789 if (GetKeyState (VK_MENU) < 0)
790 state |= GDK_MOD1_MASK;
791 if (GetKeyState (VK_CAPITAL) & 0x1)
792 state |= GDK_LOCK_MASK;
798 build_keypress_event (GdkWindowWin32Data *windata,
803 gint i, bytecount, ucount, ucleft, len;
804 guchar buf[100], *bp;
805 wchar_t wbuf[100], *wcp;
807 event->key.type = GDK_KEY_PRESS;
808 event->key.time = xevent->time;
809 event->key.state = 0;
811 if (xevent->message == WM_IME_COMPOSITION)
813 hIMC = ImmGetContext (xevent->hwnd);
815 bytecount = ImmGetCompositionStringW (hIMC, GCS_RESULTSTR,
816 wbuf, sizeof (wbuf));
817 ucount = bytecount / 2;
821 if (xevent->message == WM_CHAR || xevent->message == WM_SYSCHAR)
823 bytecount = MIN ((xevent->lParam & 0xFFFF), sizeof (buf));
824 for (i = 0; i < bytecount; i++)
825 buf[i] = xevent->wParam;
827 else /* WM_IME_CHAR */
829 event->key.keyval = GDK_VoidSymbol;
830 if (xevent->wParam & 0xFF00)
832 /* Contrary to some versions of the documentation,
833 * the lead byte is the most significant byte.
835 buf[0] = ((xevent->wParam >> 8) & 0xFF);
836 buf[1] = (xevent->wParam & 0xFF);
841 buf[0] = (xevent->wParam & 0xFF);
846 /* Convert from the window's current code page
847 * to Unicode. Then convert to UTF-8.
848 * We don't handle the surrogate stuff. Should we?
850 ucount = MultiByteToWideChar (windata->charset_info.ciACP,
852 wbuf, sizeof (wbuf) / sizeof (wbuf[0]));
856 event->key.keyval = GDK_VoidSymbol;
857 else if (xevent->message == WM_CHAR || xevent->message == WM_SYSCHAR)
858 if (xevent->wParam < ' ')
860 event->key.keyval = xevent->wParam + '@';
861 /* This is needed in case of Alt+nnn or Alt+0nnn (on the numpad)
864 event->key.state |= GDK_CONTROL_MASK;
867 event->key.keyval = gdk_unicode_to_keyval (wbuf[0]);
869 build_key_event_state (event);
871 /* Build UTF-8 string */
887 event->key.string = g_malloc (len + 1);
888 event->key.length = len;
892 bp = event->key.string;
919 case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
920 case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
921 case 1: bp[0] = c | first;
924 for (i = len - 1; i > 0; --i)
926 bp[i] = (c & 0x3f) | 0x80;
938 build_keyrelease_event (GdkWindowWin32Data *windata,
945 event->key.type = GDK_KEY_RELEASE;
946 event->key.time = xevent->time;
947 event->key.state = 0;
949 if (xevent->message == WM_CHAR || xevent->message == WM_SYSCHAR)
950 if (xevent->wParam < ' ')
951 event->key.keyval = xevent->wParam + '@';
954 buf = xevent->wParam;
955 MultiByteToWideChar (windata->charset_info.ciACP,
956 0, &buf, 1, &wbuf, 1);
958 event->key.keyval = gdk_unicode_to_keyval (wbuf);
961 event->key.keyval = GDK_VoidSymbol;
962 build_key_event_state (event);
963 event->key.string = NULL;
964 event->key.length = 0;
968 print_event_state (gint state)
970 if (state & GDK_SHIFT_MASK)
972 if (state & GDK_LOCK_MASK)
974 if (state & GDK_CONTROL_MASK)
975 g_print ("CONTROL ");
976 if (state & GDK_MOD1_MASK)
978 if (state & GDK_BUTTON1_MASK)
979 g_print ("BUTTON1 ");
980 if (state & GDK_BUTTON2_MASK)
981 g_print ("BUTTON2 ");
982 if (state & GDK_BUTTON3_MASK)
983 g_print ("BUTTON3 ");
987 print_event (GdkEvent *event)
989 gchar *escaped, *kvname;
991 switch (event->any.type)
993 case GDK_NOTHING: g_print ("GDK_NOTHING "); break;
994 case GDK_DELETE: g_print ("GDK_DELETE "); break;
995 case GDK_DESTROY: g_print ("GDK_DESTROY "); break;
996 case GDK_EXPOSE: g_print ("GDK_EXPOSE "); break;
997 case GDK_MOTION_NOTIFY: g_print ("GDK_MOTION_NOTIFY "); break;
998 case GDK_BUTTON_PRESS: g_print ("GDK_BUTTON_PRESS "); break;
999 case GDK_2BUTTON_PRESS: g_print ("GDK_2BUTTON_PRESS "); break;
1000 case GDK_3BUTTON_PRESS: g_print ("GDK_3BUTTON_PRESS "); break;
1001 case GDK_BUTTON_RELEASE: g_print ("GDK_BUTTON_RELEASE "); break;
1002 case GDK_KEY_PRESS: g_print ("GDK_KEY_PRESS "); break;
1003 case GDK_KEY_RELEASE: g_print ("GDK_KEY_RELEASE "); break;
1004 case GDK_ENTER_NOTIFY: g_print ("GDK_ENTER_NOTIFY "); break;
1005 case GDK_LEAVE_NOTIFY: g_print ("GDK_LEAVE_NOTIFY "); break;
1006 case GDK_FOCUS_CHANGE: g_print ("GDK_FOCUS_CHANGE "); break;
1007 case GDK_CONFIGURE: g_print ("GDK_CONFIGURE "); break;
1008 case GDK_MAP: g_print ("GDK_MAP "); break;
1009 case GDK_UNMAP: g_print ("GDK_UNMAP "); break;
1010 case GDK_PROPERTY_NOTIFY: g_print ("GDK_PROPERTY_NOTIFY "); break;
1011 case GDK_SELECTION_CLEAR: g_print ("GDK_SELECTION_CLEAR "); break;
1012 case GDK_SELECTION_REQUEST: g_print ("GDK_SELECTION_REQUEST "); break;
1013 case GDK_SELECTION_NOTIFY: g_print ("GDK_SELECTION_NOTIFY "); break;
1014 case GDK_PROXIMITY_IN: g_print ("GDK_PROXIMITY_IN "); break;
1015 case GDK_PROXIMITY_OUT: g_print ("GDK_PROXIMITY_OUT "); break;
1016 case GDK_DRAG_ENTER: g_print ("GDK_DRAG_ENTER "); break;
1017 case GDK_DRAG_LEAVE: g_print ("GDK_DRAG_LEAVE "); break;
1018 case GDK_DRAG_MOTION: g_print ("GDK_DRAG_MOTION "); break;
1019 case GDK_DRAG_STATUS: g_print ("GDK_DRAG_STATUS "); break;
1020 case GDK_DROP_START: g_print ("GDK_DROP_START "); break;
1021 case GDK_DROP_FINISHED: g_print ("GDK_DROP_FINISHED "); break;
1022 case GDK_CLIENT_EVENT: g_print ("GDK_CLIENT_EVENT "); break;
1023 case GDK_VISIBILITY_NOTIFY: g_print ("GDK_VISIBILITY_NOTIFY "); break;
1024 case GDK_NO_EXPOSE: g_print ("GDK_NO_EXPOSE "); break;
1025 case GDK_SCROLL: g_print ("GDK_SCROLL "); break;
1027 g_print ("%#x ", GDK_DRAWABLE_XID (event->any.window));
1029 switch (event->any.type)
1032 g_print ("%dx%d@+%d+%d %d",
1033 event->expose.area.width,
1034 event->expose.area.height,
1035 event->expose.area.x,
1036 event->expose.area.y,
1037 event->expose.count);
1039 case GDK_MOTION_NOTIFY:
1040 g_print ("(%.4g,%.4g) %s",
1041 event->motion.x, event->motion.y,
1042 event->motion.is_hint ? "HINT " : "");
1043 print_event_state (event->motion.state);
1045 case GDK_BUTTON_PRESS:
1046 case GDK_2BUTTON_PRESS:
1047 case GDK_3BUTTON_PRESS:
1048 case GDK_BUTTON_RELEASE:
1049 g_print ("%d (%.4g,%.4g) ",
1050 event->button.button,
1051 event->button.x, event->button.y);
1052 print_event_state (event->button.state);
1055 case GDK_KEY_RELEASE:
1056 if (event->key.length == 0)
1057 escaped = g_strdup ("");
1059 escaped = g_strescape (event->key.string, NULL);
1060 kvname = gdk_keyval_name (event->key.keyval);
1061 g_print ("%s %d:\"%s\" ",
1062 (kvname ? kvname : "??"),
1066 print_event_state (event->key.state);
1068 case GDK_ENTER_NOTIFY:
1069 case GDK_LEAVE_NOTIFY:
1071 (event->crossing.detail == GDK_NOTIFY_INFERIOR ? "INFERIOR" :
1072 (event->crossing.detail == GDK_NOTIFY_ANCESTOR ? "ANCESTOR" :
1073 (event->crossing.detail == GDK_NOTIFY_NONLINEAR ? "NONLINEAR" :
1078 (event->scroll.direction == GDK_SCROLL_UP ? "UP" :
1079 (event->scroll.direction == GDK_SCROLL_DOWN ? "DOWN" :
1080 (event->scroll.direction == GDK_SCROLL_LEFT ? "LEFT" :
1081 (event->scroll.direction == GDK_SCROLL_RIGHT ? "RIGHT" :
1083 print_event_state (event->scroll.state);
1090 synthesize_crossing_events (GdkWindow *window,
1095 /* If we are not using TrackMouseEvent, generate a leave notify
1096 * event if necessary
1098 if (p_TrackMouseEvent == NULL
1100 && (GDK_WINDOW_WIN32DATA (curWnd)->event_mask & GDK_LEAVE_NOTIFY_MASK))
1102 GDK_NOTE (EVENTS, g_print ("synthesizing LEAVE_NOTIFY event\n"));
1104 event = gdk_event_new ();
1105 event->crossing.type = GDK_LEAVE_NOTIFY;
1106 event->crossing.window = curWnd;
1107 gdk_drawable_ref (event->crossing.window);
1108 event->crossing.subwindow = NULL;
1109 event->crossing.time = xevent->time;
1110 event->crossing.x = curX;
1111 event->crossing.y = curY;
1112 event->crossing.x_root = curXroot;
1113 event->crossing.y_root = curYroot;
1114 event->crossing.mode = GDK_CROSSING_NORMAL;
1115 if (IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window)))
1116 event->crossing.detail = GDK_NOTIFY_INFERIOR;
1117 else if (IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd)))
1118 event->crossing.detail = GDK_NOTIFY_ANCESTOR;
1120 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
1122 event->crossing.focus = TRUE; /* ??? */
1123 event->crossing.state = 0; /* ??? */
1125 gdk_event_queue_append (event);
1126 GDK_NOTE (EVENTS, print_event (event));
1129 if (GDK_WINDOW_WIN32DATA (window)->event_mask & GDK_ENTER_NOTIFY_MASK)
1131 GDK_NOTE (EVENTS, g_print ("synthesizing ENTER_NOTIFY event\n"));
1133 event = gdk_event_new ();
1134 event->crossing.type = GDK_ENTER_NOTIFY;
1135 event->crossing.window = window;
1136 gdk_drawable_ref (event->crossing.window);
1137 event->crossing.subwindow = NULL;
1138 event->crossing.time = xevent->time;
1139 event->crossing.x = LOWORD (xevent->lParam);
1140 event->crossing.y = HIWORD (xevent->lParam);
1141 event->crossing.x_root = (gfloat) xevent->pt.x;
1142 event->crossing.y_root = (gfloat) xevent->pt.y;
1143 event->crossing.mode = GDK_CROSSING_NORMAL;
1145 && IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window)))
1146 event->crossing.detail = GDK_NOTIFY_ANCESTOR;
1148 && IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd)))
1149 event->crossing.detail = GDK_NOTIFY_INFERIOR;
1151 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
1153 event->crossing.focus = TRUE; /* ??? */
1154 event->crossing.state = 0; /* ??? */
1156 gdk_event_queue_append (event);
1158 GDK_NOTE (EVENTS, print_event (event));
1160 if (((GdkWindowPrivate *) window)->extension_events != 0
1161 && gdk_input_vtable.enter_event)
1162 gdk_input_vtable.enter_event (&event->crossing, window);
1167 gdk_drawable_unref (curWnd);
1169 gdk_drawable_ref (curWnd);
1170 #ifdef USE_TRACKMOUSEEVENT
1171 if (p_TrackMouseEvent != NULL)
1173 TRACKMOUSEEVENT tme;
1175 tme.cbSize = sizeof (TRACKMOUSEEVENT);
1176 tme.dwFlags = TME_LEAVE;
1177 tme.hwndTrack = GDK_DRAWABLE_XID (curWnd);
1178 tme.dwHoverTime = HOVER_DEFAULT;
1180 (*p_TrackMouseEvent) (&tme);
1186 translate_mouse_coords (GdkWindow *window1,
1192 pt.x = LOWORD (xevent->lParam);
1193 pt.y = HIWORD (xevent->lParam);
1194 ClientToScreen (GDK_DRAWABLE_XID (window1), &pt);
1195 ScreenToClient (GDK_DRAWABLE_XID (window2), &pt);
1196 xevent->lParam = MAKELPARAM (pt.x, pt.y);
1197 GDK_NOTE (EVENTS, g_print ("...new coords are (%d,%d)\n", pt.x, pt.y));
1201 propagate (GdkWindow **window,
1203 GdkWindow *grab_window,
1204 gboolean grab_owner_events,
1206 gboolean (*doesnt_want_it) (gint mask,
1209 if (grab_window != NULL && !grab_owner_events)
1211 /* Event source is grabbed with owner_events FALSE */
1212 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE, "));
1213 if ((*doesnt_want_it) (grab_mask, xevent))
1215 GDK_NOTE (EVENTS, g_print ("...grabber doesn't want it\n"));
1220 GDK_NOTE (EVENTS, g_print ("...sending to grabber %#x\n",
1221 GDK_DRAWABLE_XID (grab_window)));
1222 gdk_drawable_unref (*window);
1223 *window = grab_window;
1224 gdk_drawable_ref (*window);
1230 if ((*doesnt_want_it) (GDK_WINDOW_WIN32DATA (*window)->event_mask, xevent))
1232 /* Owner doesn't want it, propagate to parent. */
1233 if (((GdkWindowPrivate *) *window)->parent == gdk_parent_root)
1235 /* No parent; check if grabbed */
1236 if (grab_window != NULL)
1238 /* Event source is grabbed with owner_events TRUE */
1239 GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
1240 if ((*doesnt_want_it) (grab_mask, xevent))
1242 /* Grabber doesn't want it either */
1243 GDK_NOTE (EVENTS, g_print ("...grabber doesn't want it\n"));
1249 GDK_NOTE (EVENTS, g_print ("...sending to grabber %#x\n",
1250 GDK_DRAWABLE_XID (grab_window)));
1251 gdk_drawable_unref (*window);
1252 *window = grab_window;
1253 gdk_drawable_ref (*window);
1259 GDK_NOTE (EVENTS, g_print ("...undelivered\n"));
1265 gdk_drawable_unref (*window);
1266 *window = ((GdkWindowPrivate *) *window)->parent;
1267 gdk_drawable_ref (*window);
1268 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1269 GDK_DRAWABLE_XID (*window)));
1270 /* The only branch where we actually continue the loop */
1279 doesnt_want_key (gint mask,
1282 return (((xevent->message == WM_KEYUP || xevent->message == WM_SYSKEYUP)
1283 && !(mask & GDK_KEY_RELEASE_MASK))
1285 ((xevent->message == WM_KEYDOWN || xevent->message == WM_SYSKEYDOWN)
1286 && !(mask & GDK_KEY_PRESS_MASK)));
1290 doesnt_want_char (gint mask,
1293 return !(mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK));
1297 doesnt_want_button_press (gint mask,
1300 return !(mask & GDK_BUTTON_PRESS_MASK);
1304 doesnt_want_button_release (gint mask,
1307 return !(mask & GDK_BUTTON_RELEASE_MASK);
1311 doesnt_want_button_motion (gint mask,
1314 return !((mask & GDK_POINTER_MOTION_MASK)
1315 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
1316 && (mask & GDK_BUTTON_MOTION_MASK))
1317 || ((xevent->wParam & MK_LBUTTON)
1318 && (mask & GDK_BUTTON1_MOTION_MASK))
1319 || ((xevent->wParam & MK_MBUTTON)
1320 && (mask & GDK_BUTTON2_MOTION_MASK))
1321 || ((xevent->wParam & MK_RBUTTON)
1322 && (mask & GDK_BUTTON3_MOTION_MASK)));
1326 doesnt_want_scroll (gint mask,
1330 return !(mask & GDK_SCROLL_MASK);
1332 return !(mask & GDK_BUTTON_PRESS_MASK);
1337 decode_key_lparam (LPARAM lParam)
1339 static char buf[100];
1342 if (HIWORD (lParam) & KF_UP)
1343 p += sprintf (p, "KF_UP ");
1344 if (HIWORD (lParam) & KF_REPEAT)
1345 p += sprintf (p, "KF_REPEAT ");
1346 if (HIWORD (lParam) & KF_ALTDOWN)
1347 p += sprintf (p, "KF_ALTDOWN ");
1348 if (HIWORD (lParam) & KF_EXTENDED)
1349 p += sprintf (p, "KF_EXTENDED ");
1350 p += sprintf (p, "sc%d rep%d", LOBYTE (HIWORD (lParam)), LOWORD (lParam));
1356 gdk_event_translate (GdkEvent *event,
1358 gboolean *ret_val_flagp,
1364 PAINTSTRUCT paintstruct;
1375 GdkWindow *window, *orig_window, *newwindow;
1376 GdkColormapPrivateWin32 *colormap_private;
1379 GdkDrawablePrivate *pixmap_private;
1384 gboolean return_val;
1390 *ret_val_flagp = FALSE;
1392 window = gdk_window_lookup (xevent->hwnd);
1393 orig_window = window;
1395 event->any.window = window;
1396 event->any.send_event = FALSE;
1399 gdk_drawable_ref (window);
1402 /* Handle WM_QUIT here ? */
1403 if (xevent->message == WM_QUIT)
1405 GDK_NOTE (EVENTS, g_print ("WM_QUIT: %d\n", xevent->wParam));
1406 exit (xevent->wParam);
1408 else if (xevent->message == WM_MOVE
1409 || xevent->message == WM_SIZE)
1411 /* It's quite normal to get these messages before we have
1412 * had time to register the window in our lookup table, or
1413 * when the window is being destroyed and we already have
1414 * removed it. Repost the same message to our queue so that
1415 * we will get it later when we are prepared.
1417 GDK_NOTE(MISC, g_print("gdk_event_translate: %#x %s posted.\n",
1419 xevent->message == WM_MOVE ?
1420 "WM_MOVE" : "WM_SIZE"));
1422 PostMessage (xevent->hwnd, xevent->message,
1423 xevent->wParam, xevent->lParam);
1428 if (!GDK_DRAWABLE_DESTROYED (window))
1430 /* Check for filters for this window */
1431 GdkFilterReturn result;
1433 result = gdk_event_apply_filters
1434 (xevent, event, ((GdkWindowPrivate *) window)->filters);
1436 if (result != GDK_FILTER_CONTINUE)
1438 return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
1443 if (xevent->message == gdk_selection_notify_msg)
1445 GDK_NOTE (EVENTS, g_print ("gdk_selection_notify_msg: %#x\n",
1448 event->selection.type = GDK_SELECTION_NOTIFY;
1449 event->selection.window = window;
1450 event->selection.selection = xevent->wParam;
1451 event->selection.target = xevent->lParam;
1452 event->selection.property = gdk_selection_property;
1453 event->selection.time = xevent->time;
1455 return_val = !GDK_DRAWABLE_DESTROYED (window);
1457 /* Will pass through switch below without match */
1459 else if (xevent->message == gdk_selection_request_msg)
1461 GDK_NOTE (EVENTS, g_print ("gdk_selection_request_msg: %#x\n",
1464 event->selection.type = GDK_SELECTION_REQUEST;
1465 event->selection.window = window;
1466 event->selection.selection = gdk_clipboard_atom;
1467 event->selection.target = GDK_TARGET_STRING;
1468 event->selection.property = gdk_selection_property;
1469 event->selection.requestor = (guint32) xevent->hwnd;
1470 event->selection.time = xevent->time;
1472 return_val = !GDK_DRAWABLE_DESTROYED (window);
1474 /* Again, will pass through switch below without match */
1476 else if (xevent->message == gdk_selection_clear_msg)
1478 GDK_NOTE (EVENTS, g_print ("gdk_selection_clear_msg: %#x\n",
1481 event->selection.type = GDK_SELECTION_CLEAR;
1482 event->selection.window = window;
1483 event->selection.selection = xevent->wParam;
1484 event->selection.time = xevent->time;
1486 return_val = !GDK_DRAWABLE_DESTROYED (window);
1488 /* Once again, we will pass through switch below without match */
1493 GdkFilterReturn result = GDK_FILTER_CONTINUE;
1495 tmp_list = client_filters;
1498 GdkClientFilter *filter = tmp_list->data;
1499 if (filter->type == xevent->message)
1501 GDK_NOTE (EVENTS, g_print ("client filter matched\n"));
1502 event->any.window = window;
1503 result = (*filter->function) (xevent, event, filter->data);
1506 case GDK_FILTER_REMOVE:
1510 case GDK_FILTER_TRANSLATE:
1514 case GDK_FILTER_CONTINUE:
1516 event->client.type = GDK_CLIENT_EVENT;
1517 event->client.window = window;
1518 event->client.message_type = xevent->message;
1519 event->client.data_format = 0;
1520 event->client.data.l[0] = xevent->wParam;
1521 event->client.data.l[1] = xevent->lParam;
1526 tmp_list = tmp_list->next;
1530 switch (xevent->message)
1532 case WM_INPUTLANGCHANGE:
1534 g_print ("WM_INPUTLANGCHANGE: %#x charset %d locale %x\n",
1535 xevent->hwnd, xevent->wParam, xevent->lParam));
1536 GDK_WINDOW_WIN32DATA (window)->input_locale = (HKL) xevent->lParam;
1537 TranslateCharsetInfo ((DWORD FAR *) xevent->wParam,
1538 &GDK_WINDOW_WIN32DATA (window)->charset_info,
1545 g_print ("WM_SYSKEY%s: %#x %s %#x %s\n",
1546 (xevent->message == WM_SYSKEYUP ? "UP" : "DOWN"),
1548 (GetKeyNameText (xevent->lParam, buf,
1552 decode_key_lparam (xevent->lParam)));
1554 /* Let the system handle Alt-Tab and Alt-Enter */
1555 if (xevent->wParam == VK_TAB
1556 || xevent->wParam == VK_RETURN
1557 || xevent->wParam == VK_F4)
1559 /* If posted without us having keyboard focus, ignore */
1560 if (!(xevent->lParam & 0x20000000))
1563 /* don't generate events for just the Alt key */
1564 if (xevent->wParam == VK_MENU)
1567 /* Jump to code in common with WM_KEYUP and WM_KEYDOWN */
1573 g_print ("WM_KEY%s: %#x %s %#x %s\n",
1574 (xevent->message == WM_KEYUP ? "UP" : "DOWN"),
1576 (GetKeyNameText (xevent->lParam, buf,
1580 decode_key_lparam (xevent->lParam)));
1582 ignore_WM_CHAR = TRUE;
1586 event->key.window = window;
1587 switch (xevent->wParam)
1590 event->key.keyval = GDK_Pointer_Button1; break;
1592 event->key.keyval = GDK_Pointer_Button3; break;
1594 event->key.keyval = GDK_Pointer_Button2; break;
1596 event->key.keyval = GDK_Cancel; break;
1598 event->key.keyval = GDK_BackSpace; break;
1600 event->key.keyval = (GetKeyState(VK_SHIFT) < 0 ?
1601 GDK_ISO_Left_Tab : GDK_Tab);
1604 event->key.keyval = GDK_Clear; break;
1606 event->key.keyval = GDK_Return; break;
1608 /* Don't let Shift auto-repeat */
1609 if (xevent->message == WM_KEYDOWN
1610 && (HIWORD (xevent->lParam) & KF_REPEAT))
1611 ignore_WM_CHAR = FALSE;
1613 event->key.keyval = GDK_Shift_L;
1616 /* And not Control either */
1617 if (xevent->message == WM_KEYDOWN
1618 && (HIWORD (xevent->lParam) & KF_REPEAT))
1619 ignore_WM_CHAR = FALSE;
1620 else if (HIWORD (xevent->lParam) & KF_EXTENDED)
1621 event->key.keyval = GDK_Control_R;
1623 event->key.keyval = GDK_Control_L;
1627 if (xevent->message == WM_KEYDOWN
1628 && (HIWORD (xevent->lParam) & KF_REPEAT))
1629 ignore_WM_CHAR = FALSE;
1630 else if (HIWORD (xevent->lParam) & KF_EXTENDED)
1632 /* AltGr key comes in as Control+Right Alt */
1633 if (GetKeyState (VK_CONTROL) < 0)
1635 ignore_WM_CHAR = FALSE;
1636 is_AltGr_key = TRUE;
1638 event->key.keyval = GDK_Alt_R;
1642 event->key.keyval = GDK_Alt_L;
1643 /* This needed in case she types Alt+nnn (on the numpad) */
1644 ignore_WM_CHAR = FALSE;
1648 event->key.keyval = GDK_Pause; break;
1650 event->key.keyval = GDK_Caps_Lock; break;
1652 event->key.keyval = GDK_Escape; break;
1654 event->key.keyval = GDK_Prior; break;
1656 event->key.keyval = GDK_Next; break;
1658 event->key.keyval = GDK_End; break;
1660 event->key.keyval = GDK_Home; break;
1662 event->key.keyval = GDK_Left; break;
1664 event->key.keyval = GDK_Up; break;
1666 event->key.keyval = GDK_Right; break;
1668 event->key.keyval = GDK_Down; break;
1670 event->key.keyval = GDK_Select; break;
1672 event->key.keyval = GDK_Print; break;
1674 event->key.keyval = GDK_Execute; break;
1676 event->key.keyval = GDK_Insert; break;
1678 event->key.keyval = GDK_Delete; break;
1680 event->key.keyval = GDK_Help; break;
1691 /* Apparently applications work better if we just pass numpad digits
1692 * on as real digits? So wait for the WM_CHAR instead.
1694 ignore_WM_CHAR = FALSE;
1697 event->key.keyval = GDK_KP_Multiply; break;
1699 /* Pass it on as an ASCII plus in WM_CHAR. */
1700 ignore_WM_CHAR = FALSE;
1703 event->key.keyval = GDK_KP_Separator; break;
1705 /* Pass it on as an ASCII minus in WM_CHAR. */
1706 ignore_WM_CHAR = FALSE;
1709 /* The keypad decimal key should also be passed on as the decimal
1710 * sign ('.' or ',' depending on the Windows locale settings,
1711 * apparently). So wait for the WM_CHAR here, also.
1713 ignore_WM_CHAR = FALSE;
1716 event->key.keyval = GDK_KP_Divide; break;
1718 event->key.keyval = GDK_F1; break;
1720 event->key.keyval = GDK_F2; break;
1722 event->key.keyval = GDK_F3; break;
1724 event->key.keyval = GDK_F4; break;
1726 event->key.keyval = GDK_F5; break;
1728 event->key.keyval = GDK_F6; break;
1730 event->key.keyval = GDK_F7; break;
1732 event->key.keyval = GDK_F8; break;
1734 event->key.keyval = GDK_F9; break;
1736 event->key.keyval = GDK_F10; break;
1738 event->key.keyval = GDK_F11; break;
1740 event->key.keyval = GDK_F12; break;
1742 event->key.keyval = GDK_F13; break;
1744 event->key.keyval = GDK_F14; break;
1746 event->key.keyval = GDK_F15; break;
1748 event->key.keyval = GDK_F16; break;
1759 if (!is_AltGr_key && (GetKeyState (VK_CONTROL) < 0
1760 || GetKeyState (VK_MENU) < 0))
1761 /* Control- or Alt-digits won't come in as a WM_CHAR,
1762 * but beware of AltGr-digits, which are used for instance
1763 * on Finnish keyboards.
1765 event->key.keyval = GDK_0 + (xevent->wParam - '0');
1767 ignore_WM_CHAR = FALSE;
1769 case VK_OEM_PLUS: /* On my Win98, the '+' key comes in
1772 if (!is_AltGr_key && (GetKeyState (VK_CONTROL) < 0
1773 || GetKeyState (VK_MENU) < 0))
1774 /* Control- or Alt-plus won't come in as WM_CHAR,
1775 * but beware of AltGr-plus which is backslash on
1778 event->key.keyval = '+';
1780 ignore_WM_CHAR = FALSE;
1783 if (xevent->message == WM_SYSKEYDOWN || xevent->message == WM_SYSKEYUP)
1784 event->key.keyval = xevent->wParam;
1786 ignore_WM_CHAR = FALSE;
1790 if (!ignore_WM_CHAR)
1793 if (!propagate (&window, xevent,
1794 k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
1798 is_AltGr_key = FALSE;
1799 event->key.type = ((xevent->message == WM_KEYDOWN
1800 || xevent->message == WM_SYSKEYDOWN) ?
1801 GDK_KEY_PRESS : GDK_KEY_RELEASE);
1802 event->key.time = xevent->time;
1803 event->key.state = 0;
1804 if (GetKeyState (VK_SHIFT) < 0)
1805 event->key.state |= GDK_SHIFT_MASK;
1806 if (GetKeyState (VK_CAPITAL) & 0x1)
1807 event->key.state |= GDK_LOCK_MASK;
1808 if (GetKeyState (VK_CONTROL) < 0)
1809 event->key.state |= GDK_CONTROL_MASK;
1810 if (xevent->wParam != VK_MENU && GetKeyState (VK_MENU) < 0)
1811 event->key.state |= GDK_MOD1_MASK;
1812 event->key.string = NULL;
1813 event->key.length = 0;
1814 return_val = !GDK_DRAWABLE_DESTROYED (window);
1817 case WM_IME_COMPOSITION:
1818 if (!use_IME_COMPOSITION)
1820 GDK_NOTE (EVENTS, g_print ("WM_IME_COMPOSITION: %#x %#x\n",
1821 xevent->hwnd, xevent->lParam));
1822 if (xevent->lParam & GCS_RESULTSTR)
1828 g_print ("WM_IME_CHAR: %#x bytes: %#.04x\n",
1829 xevent->hwnd, xevent->wParam));
1835 g_print ("WM_%sCHAR: %#x %#x %#s %s\n",
1836 (xevent->message == WM_CHAR ? "" : "SYS"),
1837 xevent->hwnd, xevent->wParam,
1838 decode_key_lparam (xevent->lParam),
1839 (ignore_WM_CHAR ? "ignored" : "")));
1843 ignore_WM_CHAR = FALSE;
1848 if (!propagate (&window, xevent,
1849 k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
1852 event->key.window = window;
1853 return_val = !GDK_DRAWABLE_DESTROYED (window);
1854 if (return_val && (event->key.window == k_grab_window
1855 || (GDK_WINDOW_WIN32DATA (window)->event_mask & GDK_KEY_RELEASE_MASK)))
1857 if (window == k_grab_window
1858 || (GDK_WINDOW_WIN32DATA (window)->event_mask & GDK_KEY_PRESS_MASK))
1860 /* Append a GDK_KEY_PRESS event to the pushback list
1861 * (from which it will be fetched before the release
1864 GdkEvent *event2 = gdk_event_new ();
1865 build_keypress_event (GDK_WINDOW_WIN32DATA (window), event2, xevent);
1866 event2->key.window = window;
1867 gdk_drawable_ref (window);
1868 gdk_event_queue_append (event2);
1869 GDK_NOTE (EVENTS, print_event (event2));
1871 /* Return the key release event. */
1872 build_keyrelease_event (GDK_WINDOW_WIN32DATA (window), event, xevent);
1875 && (GDK_WINDOW_WIN32DATA (window)->event_mask & GDK_KEY_PRESS_MASK))
1877 /* Return just the key press event. */
1878 build_keypress_event (GDK_WINDOW_WIN32DATA (window), event, xevent);
1883 #if 0 /* Don't reset is_AltGr_key here. Othewise we can't type several
1884 * AltGr-accessed chars while keeping the AltGr pressed down
1887 is_AltGr_key = FALSE;
1891 case WM_LBUTTONDOWN:
1894 case WM_MBUTTONDOWN:
1897 case WM_RBUTTONDOWN:
1902 g_print ("WM_%cBUTTONDOWN: %#x (%d,%d)\n",
1905 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
1907 if (((GdkWindowPrivate *) window)->extension_events != 0
1908 && gdk_input_ignore_core)
1910 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1914 if (window != curWnd)
1915 synthesize_crossing_events (window, xevent);
1917 event->button.type = GDK_BUTTON_PRESS;
1918 if (!propagate (&window, xevent,
1919 p_grab_window, p_grab_owner_events, p_grab_mask,
1920 doesnt_want_button_press))
1922 event->button.window = window;
1923 /* Emulate X11's automatic active grab */
1926 /* No explicit active grab, let's start one automatically */
1928 GDK_WINDOW_WIN32DATA (window)->event_mask
1929 & (GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK);
1931 GDK_NOTE (EVENTS, g_print ("...automatic grab started\n"));
1932 gdk_pointer_grab (window,
1934 GDK_WINDOW_WIN32DATA (window)->event_mask,
1936 p_grab_automatic = TRUE;
1939 event->button.time = xevent->time;
1940 if (window != orig_window)
1941 translate_mouse_coords (orig_window, window, xevent);
1942 event->button.x = curX = (gint16) LOWORD (xevent->lParam);
1943 event->button.y = curY = (gint16) HIWORD (xevent->lParam);
1944 event->button.x_root = xevent->pt.x;
1945 event->button.y_root = xevent->pt.y;
1946 event->button.pressure = 0.5;
1947 event->button.xtilt = 0;
1948 event->button.ytilt = 0;
1949 event->button.state = build_pointer_event_state (xevent);
1950 event->button.button = button;
1951 event->button.source = GDK_SOURCE_MOUSE;
1952 event->button.deviceid = GDK_CORE_POINTER;
1954 gdk_event_button_generate (event);
1956 return_val = !GDK_DRAWABLE_DESTROYED (window);
1970 g_print ("WM_%cBUTTONUP: %#x (%d,%d)\n",
1973 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
1975 if (((GdkWindowPrivate *) window)->extension_events != 0
1976 && gdk_input_ignore_core)
1978 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1982 if (window != curWnd)
1983 synthesize_crossing_events (window, xevent);
1985 event->button.type = GDK_BUTTON_RELEASE;
1986 if (!propagate (&window, xevent,
1987 p_grab_window, p_grab_owner_events, p_grab_mask,
1988 doesnt_want_button_release))
1990 event->button.window = window;
1991 event->button.time = xevent->time;
1992 if (window != orig_window)
1993 translate_mouse_coords (orig_window, window, xevent);
1994 event->button.x = (gint16) LOWORD (xevent->lParam);
1995 event->button.y = (gint16) HIWORD (xevent->lParam);
1996 event->button.x_root = xevent->pt.x;
1997 event->button.y_root = xevent->pt.y;
1998 event->button.pressure = 0.5;
1999 event->button.xtilt = 0;
2000 event->button.ytilt = 0;
2001 event->button.state = build_pointer_event_state (xevent);
2002 event->button.button = button;
2003 event->button.source = GDK_SOURCE_MOUSE;
2004 event->button.deviceid = GDK_CORE_POINTER;
2006 return_val = !GDK_DRAWABLE_DESTROYED (window);
2009 if (p_grab_window != NULL
2011 && (event->button.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0)
2012 gdk_pointer_ungrab (0);
2017 g_print ("WM_MOUSEMOVE: %#x %#x (%d,%d)\n",
2018 xevent->hwnd, xevent->wParam,
2019 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2021 /* If we haven't moved, don't create any event.
2022 * Windows sends WM_MOUSEMOVE messages after button presses
2023 * even if the mouse doesn't move. This disturbs gtk.
2025 if (window == curWnd
2026 && LOWORD (xevent->lParam) == curX
2027 && HIWORD (xevent->lParam) == curY)
2030 /* HB: only process mouse move messages if we own the active window. */
2031 GetWindowThreadProcessId(GetActiveWindow(), &pidActWin);
2032 GetWindowThreadProcessId(xevent->hwnd, &pidThis);
2033 if (pidActWin != pidThis)
2036 if (window != curWnd)
2037 synthesize_crossing_events (window, xevent);
2039 if (((GdkWindowPrivate *) window)->extension_events != 0
2040 && gdk_input_ignore_core)
2042 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
2046 event->motion.type = GDK_MOTION_NOTIFY;
2047 if (!propagate (&window, xevent,
2048 p_grab_window, p_grab_owner_events, p_grab_mask,
2049 doesnt_want_button_motion))
2051 event->motion.window = window;
2052 event->motion.time = xevent->time;
2053 if (window != orig_window)
2054 translate_mouse_coords (orig_window, window, xevent);
2055 event->motion.x = curX = (gint16) LOWORD (xevent->lParam);
2056 event->motion.y = curY = (gint16) HIWORD (xevent->lParam);
2057 event->motion.x_root = xevent->pt.x;
2058 event->motion.y_root = xevent->pt.y;
2059 curXroot = event->motion.x_root;
2060 curYroot = event->motion.y_root;
2061 event->motion.pressure = 0.5;
2062 event->motion.xtilt = 0;
2063 event->motion.ytilt = 0;
2064 event->motion.state = build_pointer_event_state (xevent);
2065 event->motion.is_hint = FALSE;
2066 event->motion.source = GDK_SOURCE_MOUSE;
2067 event->motion.deviceid = GDK_CORE_POINTER;
2069 return_val = !GDK_DRAWABLE_DESTROYED (window);
2072 case WM_NCMOUSEMOVE:
2074 g_print ("WM_NCMOUSEMOVE: %#x x,y: %d %d\n",
2076 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2077 if (p_TrackMouseEvent == NULL
2079 && (GDK_WINDOW_WIN32DATA (curWnd)->event_mask & GDK_LEAVE_NOTIFY_MASK))
2081 GDK_NOTE (EVENTS, g_print ("...synthesizing LEAVE_NOTIFY event\n"));
2083 event->crossing.type = GDK_LEAVE_NOTIFY;
2084 event->crossing.window = curWnd;
2085 event->crossing.subwindow = NULL;
2086 event->crossing.time = xevent->time;
2087 event->crossing.x = curX;
2088 event->crossing.y = curY;
2089 event->crossing.x_root = curXroot;
2090 event->crossing.y_root = curYroot;
2091 event->crossing.mode = GDK_CROSSING_NORMAL;
2092 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
2094 event->crossing.focus = TRUE; /* ??? */
2095 event->crossing.state = 0; /* ??? */
2101 gdk_drawable_unref (curWnd);
2108 GDK_NOTE (EVENTS, g_print ("WM_MOUSEWHEEL: %#x\n", xevent->hwnd));
2110 if (((GdkWindowPrivate *) window)->extension_events != 0
2111 && gdk_input_ignore_core)
2113 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
2117 event->scroll.type = GDK_SCROLL;
2119 /* WM_MOUSEWHEEL seems to be delivered to top-level windows
2120 * only, for some reason. Work around that. Also, the position
2121 * is in screen coordinates, not client coordinates as with the
2122 * button messages. I love the consistency of Windows.
2124 pt.x = LOWORD (xevent->lParam);
2125 pt.y = HIWORD (xevent->lParam);
2126 if ((hwnd = WindowFromPoint (pt)) == NULL)
2128 xevent->hwnd = hwnd;
2129 if ((newwindow = gdk_window_lookup (xevent->hwnd)) == NULL)
2131 if (newwindow != window)
2133 gdk_drawable_unref (window);
2135 gdk_drawable_ref (window);
2137 ScreenToClient (xevent->hwnd, &pt);
2138 if (!propagate (&window, xevent,
2139 p_grab_window, p_grab_owner_events, p_grab_mask,
2140 doesnt_want_scroll))
2142 event->button.window = window;
2143 event->scroll.direction = (((short) HIWORD (xevent->wParam)) > 0) ?
2144 GDK_SCROLL_UP : GDK_SCROLL_DOWN;
2145 event->scroll.window = window;
2146 event->scroll.time = xevent->time;
2147 event->scroll.x = (gint16) pt.x;
2148 event->scroll.y = (gint16) pt.y;
2149 event->scroll.x_root = (gint16) LOWORD (xevent->lParam);
2150 event->scroll.y_root = (gint16) LOWORD (xevent->lParam);
2151 event->scroll.pressure = 0.5;
2152 event->scroll.xtilt = 0;
2153 event->scroll.ytilt = 0;
2154 event->scroll.state = build_pointer_event_state (xevent);
2155 event->scroll.source = GDK_SOURCE_MOUSE;
2156 event->scroll.deviceid = GDK_CORE_POINTER;
2157 return_val = !GDK_DRAWABLE_DESTROYED (window);
2161 #ifdef USE_TRACKMOUSEEVENT
2163 GDK_NOTE (EVENTS, g_print ("WM_MOUSELEAVE: %#x\n", xevent->hwnd));
2165 if (!(GDK_WINDOW_WIN32DATA (window)->event_mask & GDK_LEAVE_NOTIFY_MASK))
2168 event->crossing.type = GDK_LEAVE_NOTIFY;
2169 event->crossing.window = window;
2170 event->crossing.subwindow = NULL;
2171 event->crossing.time = xevent->time;
2172 event->crossing.x = curX;
2173 event->crossing.y = curY;
2174 event->crossing.x_root = curXroot;
2175 event->crossing.y_root = curYroot;
2176 event->crossing.mode = GDK_CROSSING_NORMAL;
2178 && IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window)))
2179 event->crossing.detail = GDK_NOTIFY_INFERIOR;
2181 && IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd)))
2182 event->crossing.detail = GDK_NOTIFY_ANCESTOR;
2184 event->crossing.detail = GDK_NOTIFY_NONLINEAR;
2186 event->crossing.focus = TRUE; /* ??? */
2187 event->crossing.state = 0; /* ??? */
2191 gdk_drawable_unref (curWnd);
2195 return_val = !GDK_DRAWABLE_DESTROYED (window);
2201 GDK_NOTE (EVENTS, g_print ("WM_%sFOCUS: %#x\n",
2202 (xevent->message == WM_SETFOCUS ?
2206 if (!(GDK_WINDOW_WIN32DATA (window)->event_mask & GDK_FOCUS_CHANGE_MASK))
2209 event->focus_change.type = GDK_FOCUS_CHANGE;
2210 event->focus_change.window = window;
2211 event->focus_change.in = (xevent->message == WM_SETFOCUS);
2212 return_val = !GDK_DRAWABLE_DESTROYED (window);
2216 GDK_NOTE (EVENTS, g_print ("WM_ERASEBKGND: %#x dc %#x\n",
2217 xevent->hwnd, xevent->wParam));
2219 if (GDK_DRAWABLE_DESTROYED (window))
2222 colormap_private = (GdkColormapPrivateWin32 *) ((GdkWindowPrivate *) window)->drawable.colormap;
2223 hdc = (HDC) xevent->wParam;
2224 if (colormap_private
2225 && colormap_private->xcolormap->rc_palette)
2229 if (SelectPalette (hdc, colormap_private->xcolormap->palette,
2231 WIN32_GDI_FAILED ("SelectPalette");
2232 if ((k = RealizePalette (hdc)) == GDI_ERROR)
2233 WIN32_GDI_FAILED ("RealizePalette");
2235 g_print ("WM_ERASEBKGND: selected %#x, realized %d colors\n",
2236 colormap_private->xcolormap->palette, k);
2239 *ret_val_flagp = TRUE;
2242 if (GDK_WINDOW_WIN32DATA (window)->bg_type == GDK_WIN32_BG_TRANSPARENT)
2245 if (GDK_WINDOW_WIN32DATA (window)->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2247 /* If this window should have the same background as the
2248 * parent, fetch the parent. (And if the same goes for
2249 * the parent, fetch the grandparent, etc.)
2252 && GDK_WINDOW_WIN32DATA (window)->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2254 gdk_drawable_unref (window);
2255 window = ((GdkWindowPrivate *) window)->parent;
2256 gdk_drawable_ref (window);
2260 if (GDK_WINDOW_WIN32DATA (window)->bg_type == GDK_WIN32_BG_PIXEL)
2262 bg = gdk_colormap_color (colormap_private,
2263 GDK_WINDOW_WIN32DATA (window)->bg_pixel);
2265 GetClipBox (hdc, &rect);
2267 g_print ("...%dx%d@+%d+%d BG_PIXEL %.06x\n",
2268 rect.right - rect.left,
2269 rect.bottom - rect.top,
2270 rect.left, rect.top,
2272 hbr = CreateSolidBrush (bg);
2274 g_print ("...CreateSolidBrush (%.08x) = %.08x\n", bg, hbr);
2276 if (!FillRect (hdc, &rect, hbr))
2277 WIN32_GDI_FAILED ("FillRect");
2280 else if (GDK_WINDOW_WIN32DATA (window)->bg_type == GDK_WIN32_BG_PIXMAP)
2282 pixmap = GDK_WINDOW_WIN32DATA (window)->bg_pixmap;
2283 pixmap_private = (GdkDrawablePrivate*) pixmap;
2284 GetClipBox (hdc, &rect);
2286 if (pixmap_private->width <= 8
2287 && pixmap_private->height <= 8)
2289 GDK_NOTE (EVENTS, g_print ("...small pixmap, using brush\n"));
2290 hbr = CreatePatternBrush (GDK_DRAWABLE_XID (pixmap));
2291 if (!FillRect (hdc, &rect, hbr))
2292 WIN32_GDI_FAILED ("FillRect");
2298 g_print ("...blitting pixmap %#x (%dx%d) "
2299 "all over the place,\n"
2300 "...clip box = %dx%d@+%d+%d\n",
2301 GDK_DRAWABLE_XID (pixmap),
2302 pixmap_private->width, pixmap_private->height,
2303 rect.right - rect.left, rect.bottom - rect.top,
2304 rect.left, rect.top));
2306 if (!(bgdc = CreateCompatibleDC (hdc)))
2308 WIN32_GDI_FAILED ("CreateCompatibleDC");
2311 if (!(oldbitmap = SelectObject (bgdc, GDK_DRAWABLE_XID (pixmap))))
2313 WIN32_GDI_FAILED ("SelectObject");
2318 while (i < rect.right)
2321 while (j < rect.bottom)
2323 if (i + pixmap_private->width >= rect.left
2324 && j + pixmap_private->height >= rect.top)
2326 if (!BitBlt (hdc, i, j,
2327 pixmap_private->width, pixmap_private->height,
2328 bgdc, 0, 0, SRCCOPY))
2330 WIN32_GDI_FAILED ("BitBlt");
2334 j += pixmap_private->height;
2336 i += pixmap_private->width;
2339 SelectObject (bgdc, oldbitmap);
2345 GDK_NOTE (EVENTS, g_print ("...BLACK_BRUSH (?)\n"));
2346 hbr = GetStockObject (BLACK_BRUSH);
2347 GetClipBox (hdc, &rect);
2348 if (!FillRect (hdc, &rect, hbr))
2349 WIN32_GDI_FAILED ("FillRect");
2354 if (!GetUpdateRect(xevent->hwnd, NULL, FALSE))
2356 GDK_NOTE (EVENTS, g_print ("WM_PAINT: %#x no update rect\n",
2361 hdc = BeginPaint (xevent->hwnd, &paintstruct);
2364 g_print ("WM_PAINT: %#x %dx%d@+%d+%d %s dc %#x\n",
2366 paintstruct.rcPaint.right - paintstruct.rcPaint.left,
2367 paintstruct.rcPaint.bottom - paintstruct.rcPaint.top,
2368 paintstruct.rcPaint.left, paintstruct.rcPaint.top,
2369 (paintstruct.fErase ? "erase" : ""),
2372 EndPaint (xevent->hwnd, &paintstruct);
2374 if (!(GDK_WINDOW_WIN32DATA (window)->event_mask & GDK_EXPOSURE_MASK))
2377 if ((paintstruct.rcPaint.right == paintstruct.rcPaint.left)
2378 || (paintstruct.rcPaint.bottom == paintstruct.rcPaint.top))
2381 event->expose.type = GDK_EXPOSE;
2382 event->expose.window = window;
2383 event->expose.area.x = paintstruct.rcPaint.left;
2384 event->expose.area.y = paintstruct.rcPaint.top;
2385 event->expose.area.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left;
2386 event->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
2387 event->expose.count = 0;
2389 return_val = !GDK_DRAWABLE_DESTROYED (window);
2392 GList *list = gdk_queued_events;
2393 while (list != NULL )
2395 if ((((GdkEvent *)list->data)->any.type == GDK_EXPOSE) &&
2396 (((GdkEvent *)list->data)->any.window == window) &&
2397 !(((GdkEventPrivate *)list->data)->flags & GDK_EVENT_PENDING))
2398 ((GdkEvent *)list->data)->expose.count++;
2406 GDK_NOTE (EVENTS, g_print ("WM_SETCURSOR: %#x %#x %#x\n",
2408 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2410 if (LOWORD (xevent->lParam) != HTCLIENT)
2413 if (p_grab_window != NULL && p_grab_cursor != NULL)
2414 xcursor = p_grab_cursor;
2415 else if (!GDK_DRAWABLE_DESTROYED (window))
2416 xcursor = GDK_WINDOW_WIN32DATA (window)->xcursor;
2420 if (xcursor != NULL)
2422 GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", xcursor));
2423 SetCursor (xcursor);
2424 *ret_val_flagp = TRUE;
2430 GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#x %d\n",
2434 if (!(GDK_WINDOW_WIN32DATA (window)->event_mask & GDK_STRUCTURE_MASK))
2437 event->any.type = (xevent->wParam ? GDK_MAP : GDK_UNMAP);
2438 event->any.window = window;
2440 if (event->any.type == GDK_UNMAP
2441 && p_grab_window == window)
2442 gdk_pointer_ungrab (xevent->time);
2444 if (event->any.type == GDK_UNMAP
2445 && k_grab_window == window)
2446 gdk_keyboard_ungrab (xevent->time);
2448 return_val = !GDK_DRAWABLE_DESTROYED (window);
2453 g_print ("WM_SIZE: %#x %s %dx%d\n",
2455 (xevent->wParam == SIZE_MAXHIDE ? "MAXHIDE" :
2456 (xevent->wParam == SIZE_MAXIMIZED ? "MAXIMIZED" :
2457 (xevent->wParam == SIZE_MAXSHOW ? "MAXSHOW" :
2458 (xevent->wParam == SIZE_MINIMIZED ? "MINIMIZED" :
2459 (xevent->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
2460 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2462 if (!(GDK_WINDOW_WIN32DATA (window)->event_mask & GDK_STRUCTURE_MASK))
2465 if (xevent->wParam == SIZE_MINIMIZED)
2467 event->any.type = GDK_UNMAP;
2468 event->any.window = window;
2470 if (p_grab_window == window)
2471 gdk_pointer_ungrab (xevent->time);
2473 if (k_grab_window == window)
2474 gdk_keyboard_ungrab (xevent->time);
2476 return_val = !GDK_DRAWABLE_DESTROYED (window);
2478 else if ((xevent->wParam == SIZE_RESTORED
2479 || xevent->wParam == SIZE_MAXIMIZED)
2481 && GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD
2485 if (LOWORD (xevent->lParam) == 0)
2488 event->configure.type = GDK_CONFIGURE;
2489 event->configure.window = window;
2492 ClientToScreen (xevent->hwnd, &pt);
2493 event->configure.x = pt.x;
2494 event->configure.y = pt.y;
2495 event->configure.width = LOWORD (xevent->lParam);
2496 event->configure.height = HIWORD (xevent->lParam);
2497 ((GdkWindowPrivate *) window)->x = event->configure.x;
2498 ((GdkWindowPrivate *) window)->y = event->configure.y;
2499 ((GdkWindowPrivate *) window)->drawable.width = event->configure.width;
2500 ((GdkWindowPrivate *) window)->drawable.height = event->configure.height;
2501 if (((GdkWindowPrivate *) window)->resize_count > 1)
2502 ((GdkWindowPrivate *) window)->resize_count -= 1;
2504 return_val = !GDK_DRAWABLE_DESTROYED (window);
2506 && ((GdkWindowPrivate *) window)->extension_events != 0
2507 && gdk_input_vtable.configure_event)
2508 gdk_input_vtable.configure_event (&event->configure, window);
2512 case WM_GETMINMAXINFO:
2513 GDK_NOTE (EVENTS, g_print ("WM_GETMINMAXINFO: %#x\n", xevent->hwnd));
2515 lpmmi = (MINMAXINFO*) xevent->lParam;
2516 if (GDK_WINDOW_WIN32DATA (window)->hint_flags & GDK_HINT_MIN_SIZE)
2518 lpmmi->ptMinTrackSize.x = GDK_WINDOW_WIN32DATA (window)->hint_min_width;
2519 lpmmi->ptMinTrackSize.y = GDK_WINDOW_WIN32DATA (window)->hint_min_height;
2521 if (GDK_WINDOW_WIN32DATA (window)->hint_flags & GDK_HINT_MAX_SIZE)
2523 lpmmi->ptMaxTrackSize.x = GDK_WINDOW_WIN32DATA (window)->hint_max_width;
2524 lpmmi->ptMaxTrackSize.y = GDK_WINDOW_WIN32DATA (window)->hint_max_height;
2526 lpmmi->ptMaxSize.x = GDK_WINDOW_WIN32DATA (window)->hint_max_width;
2527 lpmmi->ptMaxSize.y = GDK_WINDOW_WIN32DATA (window)->hint_max_height;
2532 GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#x (%d,%d)\n",
2534 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2536 if (!(GDK_WINDOW_WIN32DATA (window)->event_mask & GDK_STRUCTURE_MASK))
2539 if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD
2540 && !IsIconic(xevent->hwnd)
2541 && IsWindowVisible(xevent->hwnd))
2543 event->configure.type = GDK_CONFIGURE;
2544 event->configure.window = window;
2545 event->configure.x = LOWORD (xevent->lParam);
2546 event->configure.y = HIWORD (xevent->lParam);
2547 GetClientRect (xevent->hwnd, &rect);
2548 event->configure.width = rect.right;
2549 event->configure.height = rect.bottom;
2550 ((GdkWindowPrivate *) window)->x = event->configure.x;
2551 ((GdkWindowPrivate *) window)->y = event->configure.y;
2552 ((GdkWindowPrivate *) window)->drawable.width = event->configure.width;
2553 ((GdkWindowPrivate *) window)->drawable.height = event->configure.height;
2555 return_val = !GDK_DRAWABLE_DESTROYED (window);
2560 GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#x\n", xevent->hwnd));
2562 event->any.type = GDK_DELETE;
2563 event->any.window = window;
2565 return_val = !GDK_DRAWABLE_DESTROYED (window);
2569 /* No, don't use delayed rendering after all. It works only if the
2570 * delayed SetClipboardData is called from the WindowProc, it
2571 * seems. (The #else part below is test code for that. It succeeds
2572 * in setting the clipboard data. But if I call SetClipboardData
2573 * in gdk_property_change (as a consequence of the
2574 * GDK_SELECTION_REQUEST event), it fails. I deduce that this is
2575 * because delayed rendering requires that SetClipboardData is
2576 * called in the window procedure.)
2578 case WM_RENDERFORMAT:
2579 case WM_RENDERALLFORMATS:
2581 GDK_NOTE (EVENTS, flag = TRUE);
2583 g_print ("WM_%s: %#x %#x (%s)\n",
2584 (xevent->message == WM_RENDERFORMAT ? "RENDERFORMAT" :
2585 "RENDERALLFORMATS"),
2588 (xevent->wParam == CF_TEXT ? "CF_TEXT" :
2589 (xevent->wParam == CF_DIB ? "CF_DIB" :
2590 (xevent->wParam == CF_UNICODETEXT ? "CF_UNICODETEXT" :
2591 (GetClipboardFormatName (xevent->wParam, buf, sizeof (buf)), buf)))));
2594 event->selection.type = GDK_SELECTION_REQUEST;
2595 event->selection.window = window;
2596 event->selection.selection = gdk_clipboard_atom;
2597 if (xevent->wParam == CF_TEXT)
2598 event->selection.target = GDK_TARGET_STRING;
2601 GetClipboardFormatName (xevent->wParam, buf, sizeof (buf));
2602 event->selection.target = gdk_atom_intern (buf, FALSE);
2604 event->selection.property = gdk_selection_property;
2605 event->selection.requestor = (guint32) xevent->hwnd;
2606 event->selection.time = xevent->time;
2607 return_val = !GDK_DRAWABLE_DESTROYED (window);
2609 /* Test code, to see if SetClipboardData works when called from
2610 * the window procedure.
2613 HGLOBAL hdata = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, 10);
2614 char *ptr = GlobalLock (hdata);
2615 strcpy (ptr, "Huhhaa");
2616 GlobalUnlock (hdata);
2617 if (!SetClipboardData (CF_TEXT, hdata))
2618 WIN32_API_FAILED ("SetClipboardData");
2621 *ret_val_flagp = TRUE;
2625 #endif /* No delayed rendering */
2628 GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#x\n", xevent->hwnd));
2630 event->any.type = GDK_DESTROY;
2631 event->any.window = window;
2632 if (window != NULL && window == curWnd)
2634 gdk_drawable_unref (curWnd);
2638 if (p_grab_window == window)
2639 gdk_pointer_ungrab (xevent->time);
2641 if (k_grab_window == window)
2642 gdk_keyboard_ungrab (xevent->time);
2644 return_val = window != NULL && !GDK_DRAWABLE_DESTROYED (window);
2647 gdk_window_destroy_notify (window);
2652 /* Handle WINTAB events here, as we know that gdkinput.c will
2653 * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
2654 * constants as case labels.
2657 GDK_NOTE (EVENTS, g_print ("WT_PACKET: %#x %d %#x\n",
2659 xevent->wParam, xevent->lParam));
2663 GDK_NOTE (EVENTS, g_print ("WT_CSRCHANGE: %#x %d %#x\n",
2665 xevent->wParam, xevent->lParam));
2669 GDK_NOTE (EVENTS, g_print ("WT_PROXIMITY: %#x %#x %d %d\n",
2670 xevent->hwnd, xevent->wParam,
2671 LOWORD (xevent->lParam),
2672 HIWORD (xevent->lParam)));
2675 event->any.window = window;
2676 return_val = gdk_input_vtable.other_event(event, xevent);
2681 GDK_NOTE (EVENTS, g_print ("%s: %#x %#x %#x\n",
2682 gdk_win32_message_name (xevent->message),
2684 xevent->wParam, xevent->lParam));
2691 if (event->any.window)
2692 gdk_drawable_ref (event->any.window);
2693 if (((event->any.type == GDK_ENTER_NOTIFY) ||
2694 (event->any.type == GDK_LEAVE_NOTIFY)) &&
2695 (event->crossing.subwindow != NULL))
2696 gdk_drawable_ref (event->crossing.subwindow);
2698 GDK_NOTE (EVENTS, print_event (event));
2702 /* Mark this event as having no resources to be freed */
2703 event->any.window = NULL;
2704 event->any.type = GDK_NOTHING;
2708 gdk_drawable_unref (window);
2714 gdk_events_queue (void)
2721 while (!gdk_event_queue_find_first ()
2722 && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
2724 GDK_NOTE (EVENTS, g_print ("PeekMessage: %#x %s\n",
2725 msg.hwnd, gdk_win32_message_name (msg.message)));
2727 if (paimmmpo == NULL
2728 || (paimmmpo->lpVtbl->OnTranslateMessage) (paimmmpo, &msg) != S_OK)
2729 TranslateMessage (&msg);
2731 if (msg.message == g_pipe_readable_msg)
2733 GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n",
2734 msg.wParam, msg.lParam));
2736 g_io_channel_win32_pipe_readable (msg.wParam, msg.lParam);
2741 DispatchMessage (&msg);
2746 gdk_event_prepare (gpointer source_data,
2747 GTimeVal *current_time,
2754 GDK_THREADS_ENTER ();
2758 retval = (gdk_event_queue_find_first () != NULL)
2759 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2761 GDK_THREADS_LEAVE ();
2767 gdk_event_check (gpointer source_data,
2768 GTimeVal *current_time,
2774 GDK_THREADS_ENTER ();
2776 if (event_poll_fd.revents & G_IO_IN)
2777 retval = (gdk_event_queue_find_first () != NULL)
2778 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2782 GDK_THREADS_LEAVE ();
2788 gdk_event_dispatch (gpointer source_data,
2789 GTimeVal *current_time,
2794 GDK_THREADS_ENTER ();
2797 event = gdk_event_unqueue();
2802 (*gdk_event_func) (event, gdk_event_data);
2804 gdk_event_free (event);
2807 GDK_THREADS_LEAVE ();
2812 /* Sends a ClientMessage to all toplevel client windows */
2814 gdk_event_send_client_message (GdkEvent *event, guint32 xid)
2821 gdk_event_send_clientmessage_toall (GdkEvent *event)
2832 #ifdef G_ENABLE_DEBUG
2835 gdk_win32_message_name (UINT msg)
2837 static gchar bfr[100];
2841 #define CASE(x) case x: return #x
2849 CASE (WM_KILLFOCUS);
2851 CASE (WM_SETREDRAW);
2854 CASE (WM_GETTEXTLENGTH);
2857 CASE (WM_QUERYENDSESSION);
2858 CASE (WM_QUERYOPEN);
2859 CASE (WM_ENDSESSION);
2861 CASE (WM_ERASEBKGND);
2862 CASE (WM_SYSCOLORCHANGE);
2863 CASE (WM_SHOWWINDOW);
2864 CASE (WM_WININICHANGE);
2865 CASE (WM_DEVMODECHANGE);
2866 CASE (WM_ACTIVATEAPP);
2867 CASE (WM_FONTCHANGE);
2868 CASE (WM_TIMECHANGE);
2869 CASE (WM_CANCELMODE);
2870 CASE (WM_SETCURSOR);
2871 CASE (WM_MOUSEACTIVATE);
2872 CASE (WM_CHILDACTIVATE);
2873 CASE (WM_QUEUESYNC);
2874 CASE (WM_GETMINMAXINFO);
2875 CASE (WM_PAINTICON);
2876 CASE (WM_ICONERASEBKGND);
2877 CASE (WM_NEXTDLGCTL);
2878 CASE (WM_SPOOLERSTATUS);
2880 CASE (WM_MEASUREITEM);
2881 CASE (WM_DELETEITEM);
2882 CASE (WM_VKEYTOITEM);
2883 CASE (WM_CHARTOITEM);
2886 CASE (WM_SETHOTKEY);
2887 CASE (WM_GETHOTKEY);
2888 CASE (WM_QUERYDRAGICON);
2889 CASE (WM_COMPAREITEM);
2890 CASE (WM_GETOBJECT);
2891 CASE (WM_COMPACTING);
2892 CASE (WM_WINDOWPOSCHANGING);
2893 CASE (WM_WINDOWPOSCHANGED);
2896 CASE (WM_CANCELJOURNAL);
2898 CASE (WM_INPUTLANGCHANGEREQUEST);
2899 CASE (WM_INPUTLANGCHANGE);
2902 CASE (WM_USERCHANGED);
2903 CASE (WM_NOTIFYFORMAT);
2904 CASE (WM_CONTEXTMENU);
2905 CASE (WM_STYLECHANGING);
2906 CASE (WM_STYLECHANGED);
2907 CASE (WM_DISPLAYCHANGE);
2911 CASE (WM_NCDESTROY);
2912 CASE (WM_NCCALCSIZE);
2913 CASE (WM_NCHITTEST);
2915 CASE (WM_NCACTIVATE);
2916 CASE (WM_GETDLGCODE);
2917 CASE (WM_SYNCPAINT);
2918 CASE (WM_NCMOUSEMOVE);
2919 CASE (WM_NCLBUTTONDOWN);
2920 CASE (WM_NCLBUTTONUP);
2921 CASE (WM_NCLBUTTONDBLCLK);
2922 CASE (WM_NCRBUTTONDOWN);
2923 CASE (WM_NCRBUTTONUP);
2924 CASE (WM_NCRBUTTONDBLCLK);
2925 CASE (WM_NCMBUTTONDOWN);
2926 CASE (WM_NCMBUTTONUP);
2927 CASE (WM_NCMBUTTONDBLCLK);
2928 CASE (WM_NCXBUTTONDOWN);
2929 CASE (WM_NCXBUTTONUP);
2930 CASE (WM_NCXBUTTONDBLCLK);
2935 CASE (WM_SYSKEYDOWN);
2938 CASE (WM_SYSDEADCHAR);
2940 CASE (WM_IME_STARTCOMPOSITION);
2941 CASE (WM_IME_ENDCOMPOSITION);
2942 CASE (WM_IME_COMPOSITION);
2943 CASE (WM_INITDIALOG);
2945 CASE (WM_SYSCOMMAND);
2950 CASE (WM_INITMENUPOPUP);
2951 CASE (WM_MENUSELECT);
2953 CASE (WM_ENTERIDLE);
2954 CASE (WM_MENURBUTTONUP);
2956 CASE (WM_MENUGETOBJECT);
2957 CASE (WM_UNINITMENUPOPUP);
2958 CASE (WM_MENUCOMMAND);
2959 CASE (WM_CHANGEUISTATE);
2960 CASE (WM_UPDATEUISTATE);
2961 CASE (WM_QUERYUISTATE);
2962 CASE (WM_CTLCOLORMSGBOX);
2963 CASE (WM_CTLCOLOREDIT);
2964 CASE (WM_CTLCOLORLISTBOX);
2965 CASE (WM_CTLCOLORBTN);
2966 CASE (WM_CTLCOLORDLG);
2967 CASE (WM_CTLCOLORSCROLLBAR);
2968 CASE (WM_CTLCOLORSTATIC);
2969 CASE (WM_MOUSEMOVE);
2970 CASE (WM_LBUTTONDOWN);
2971 CASE (WM_LBUTTONUP);
2972 CASE (WM_LBUTTONDBLCLK);
2973 CASE (WM_RBUTTONDOWN);
2974 CASE (WM_RBUTTONUP);
2975 CASE (WM_RBUTTONDBLCLK);
2976 CASE (WM_MBUTTONDOWN);
2977 CASE (WM_MBUTTONUP);
2978 CASE (WM_MBUTTONDBLCLK);
2979 CASE (WM_MOUSEWHEEL);
2980 CASE (WM_XBUTTONDOWN);
2981 CASE (WM_XBUTTONUP);
2982 CASE (WM_XBUTTONDBLCLK);
2983 CASE (WM_PARENTNOTIFY);
2984 CASE (WM_ENTERMENULOOP);
2985 CASE (WM_EXITMENULOOP);
2988 CASE (WM_CAPTURECHANGED);
2990 CASE (WM_POWERBROADCAST);
2991 CASE (WM_DEVICECHANGE);
2992 CASE (WM_MDICREATE);
2993 CASE (WM_MDIDESTROY);
2994 CASE (WM_MDIACTIVATE);
2995 CASE (WM_MDIRESTORE);
2997 CASE (WM_MDIMAXIMIZE);
2999 CASE (WM_MDICASCADE);
3000 CASE (WM_MDIICONARRANGE);
3001 CASE (WM_MDIGETACTIVE);
3002 CASE (WM_MDISETMENU);
3003 CASE (WM_ENTERSIZEMOVE);
3004 CASE (WM_EXITSIZEMOVE);
3005 CASE (WM_DROPFILES);
3006 CASE (WM_MDIREFRESHMENU);
3007 CASE (WM_IME_SETCONTEXT);
3008 CASE (WM_IME_NOTIFY);
3009 CASE (WM_IME_CONTROL);
3010 CASE (WM_IME_COMPOSITIONFULL);
3011 CASE (WM_IME_SELECT);
3013 CASE (WM_IME_REQUEST);
3014 CASE (WM_IME_KEYDOWN);
3015 CASE (WM_IME_KEYUP);
3016 CASE (WM_MOUSEHOVER);
3017 CASE (WM_MOUSELEAVE);
3018 CASE (WM_NCMOUSEHOVER);
3019 CASE (WM_NCMOUSELEAVE);
3025 CASE (WM_RENDERFORMAT);
3026 CASE (WM_RENDERALLFORMATS);
3027 CASE (WM_DESTROYCLIPBOARD);
3028 CASE (WM_DRAWCLIPBOARD);
3029 CASE (WM_PAINTCLIPBOARD);
3030 CASE (WM_VSCROLLCLIPBOARD);
3031 CASE (WM_SIZECLIPBOARD);
3032 CASE (WM_ASKCBFORMATNAME);
3033 CASE (WM_CHANGECBCHAIN);
3034 CASE (WM_HSCROLLCLIPBOARD);
3035 CASE (WM_QUERYNEWPALETTE);
3036 CASE (WM_PALETTEISCHANGING);
3037 CASE (WM_PALETTECHANGED);
3040 CASE (WM_PRINTCLIENT);
3041 CASE (WM_APPCOMMAND);
3042 CASE (WM_HANDHELDFIRST);
3043 CASE (WM_HANDHELDLAST);
3046 CASE (WM_PENWINFIRST);
3047 CASE (WM_PENWINLAST);
3051 if (msg >= WM_HANDHELDFIRST && msg <= WM_HANDHELDLAST)
3052 sprintf (bfr, "WM_HANDHELDFIRST+%d", msg - WM_HANDHELDFIRST);
3053 else if (msg >= WM_AFXFIRST && msg <= WM_AFXLAST)
3054 sprintf (bfr, "WM_AFXFIRST+%d", msg - WM_AFXFIRST);
3055 else if (msg >= WM_PENWINFIRST && msg <= WM_PENWINLAST)
3056 sprintf (bfr, "WM_PENWINFIRST+%d", msg - WM_PENWINFIRST);
3057 else if (msg >= WM_USER && msg <= 0x7FFF)
3058 sprintf (bfr, "WM_USER+%d", msg - WM_USER);
3059 else if (msg >= 0xC000 && msg <= 0xFFFF)
3060 sprintf (bfr, "reg-%#x", msg);
3062 sprintf (bfr, "unk-%#x", msg);
3065 g_assert_not_reached ();
3068 #endif /* G_ENABLE_DEBUG */