1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 1998-2002 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 * Update: a combination of TrackMouseEvent, GetCursorPos and
36 * GetWindowPos can and is actually used to get rid of those
37 * pesky tooltips. It should be possible to use this for the
38 * whole ENTER/LEAVE NOTIFY handling but some platforms may
39 * not have TrackMouseEvent at all (?) --hb
44 #include <glib/gprintf.h>
46 #if defined (__GNUC__) && defined (HAVE_DIMM_H)
47 /* The w32api imm.h clashes a bit with the IE5.5 dimm.h */
48 # define IMEMENUITEMINFOA hidden_IMEMENUITEMINFOA
49 # define IMEMENUITEMINFOW hidden_IMEMENUITEMINFOW
53 #include "gdkprivate-win32.h"
54 #include "gdkinput-win32.h"
55 #include "gdkkeysyms.h"
68 #if defined (__GNUC__) && defined (HAVE_DIMM_H)
69 # undef IMEMENUITEMINFOA
70 # undef IMEMENUITEMINFOW
88 #define MK_XBUTTON1 32
89 #define MK_XBUTTON2 64
93 * Private function declarations
96 static GdkFilterReturn
97 gdk_event_apply_filters(MSG *msg,
100 static gboolean gdk_event_translate (GdkDisplay *display,
103 static void handle_wm_paint (MSG *msg,
105 gboolean return_exposes,
108 static gboolean gdk_event_prepare (GSource *source,
110 static gboolean gdk_event_check (GSource *source);
111 static gboolean gdk_event_dispatch (GSource *source,
112 GSourceFunc callback,
115 /* Private variable declarations
118 static GdkWindow *p_grab_window = NULL; /* Window that currently holds
122 static GdkWindow *p_grab_confine_to = NULL;
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 GSourceFuncs event_funcs = {
142 GPollFD event_poll_fd;
144 static GdkWindow *current_window = NULL;
145 static gint current_x, current_y;
147 static UINT gdk_ping_msg;
149 static UINT msh_mousewheel;
150 static UINT client_message;
153 static IActiveIMMApp *active_imm_app = NULL;
154 static IActiveIMMMessagePumpOwner *active_imm_msgpump_owner = NULL;
158 static HKL latin_locale = NULL;
161 static gboolean in_ime_composition = FALSE;
162 static UINT resize_timer;
164 static int debug_indent = 0;
167 assign_object (gpointer lhsp,
170 if (*(gpointer *)lhsp != rhs)
172 if (*(gpointer *)lhsp != NULL)
173 g_object_unref (*(gpointer *)lhsp);
174 *(gpointer *)lhsp = rhs;
181 track_mouse_event (DWORD dwFlags,
184 typedef BOOL (WINAPI *PFN_TrackMouseEvent) (LPTRACKMOUSEEVENT);
185 static PFN_TrackMouseEvent p_TrackMouseEvent = NULL;
186 static gboolean once = FALSE;
191 HINSTANCE commctrl32;
193 user32 = GetModuleHandle ("user32.dll");
194 if ((p_TrackMouseEvent = (PFN_TrackMouseEvent)GetProcAddress (user32, "TrackMouseEvent")) == NULL)
196 if ((commctrl32 = LoadLibrary ("commctrl32.dll")) != NULL)
197 p_TrackMouseEvent = (PFN_TrackMouseEvent)
198 GetProcAddress (commctrl32, "_TrackMouseEvent");
203 if (p_TrackMouseEvent)
206 tme.cbSize = sizeof(TRACKMOUSEEVENT);
207 tme.dwFlags = dwFlags;
208 tme.hwndTrack = hwnd;
209 tme.dwHoverTime = HOVER_DEFAULT; /* not used */
211 if (!p_TrackMouseEvent (&tme))
212 WIN32_API_FAILED ("TrackMouseEvent");
213 else if (dwFlags == TME_LEAVE)
214 GDK_NOTE (EVENTS, g_print(" (TrackMouseEvent %p)", hwnd));
215 else if (dwFlags == TME_CANCEL)
216 GDK_NOTE (EVENTS, g_print(" (cancel TrackMouseEvent %p)", hwnd));
221 _gdk_win32_get_next_tick (gulong suggested_tick)
223 static gulong cur_tick = 0;
225 if (suggested_tick == 0)
226 suggested_tick = GetTickCount ();
227 if (suggested_tick <= cur_tick)
230 return cur_tick = suggested_tick;
234 inner_window_procedure (HWND hwnd,
239 GdkDisplay *display = gdk_display_get_default ();
248 msg.message = message;
251 msg.time = _gdk_win32_get_next_tick (0);
252 pos = GetMessagePos ();
253 msg.pt.x = GET_X_LPARAM (pos);
254 msg.pt.y = GET_Y_LPARAM (pos);
256 if (gdk_event_translate (display, &msg, &ret_val))
258 /* If gdk_event_translate() returns TRUE, we return ret_val from
259 * the window procedure.
265 /* Otherwise call DefWindowProc(). */
266 GDK_NOTE (EVENTS, g_print (" DefWindowProc"));
268 return DefWindowProc (hwnd, message, wparam, lparam);
270 if (active_imm_app == NULL ||
271 (*active_imm_app->lpVtbl->OnDefWindowProc) (active_imm_app, hwnd, message, wparam, lparam, &lres) == S_FALSE)
272 return DefWindowProc (hwnd, message, wparam, lparam);
280 _gdk_win32_window_procedure (HWND hwnd,
287 GDK_NOTE (EVENTS, g_print ("%s%*s%s %p",
288 (debug_indent > 0 ? "\n" : ""),
290 _gdk_win32_message_to_string (message), hwnd));
292 retval = inner_window_procedure (hwnd, message, wparam, lparam);
295 GDK_NOTE (EVENTS, g_print (" => %ld%s",
296 retval, (debug_indent == 0 ? "\n" : "")));
302 _gdk_events_init (void)
312 /* List of languages that use a latin keyboard. Somewhat sorted in
313 * "order of least surprise", in case we have to load one of them if
314 * the user only has arabic loaded, for instance.
316 static int latin_languages[] = {
322 /* Rest in numeric order */
352 gdk_ping_msg = RegisterWindowMessage ("gdk-ping");
353 GDK_NOTE (EVENTS, g_print ("gdk-ping = %#x\n", gdk_ping_msg));
356 /* This is the string MSH_MOUSEWHEEL from zmouse.h,
357 * http://www.microsoft.com/mouse/intellimouse/sdk/zmouse.h
358 * This message is used by mouse drivers than cannot generate WM_MOUSEWHEEL
361 msh_mousewheel = RegisterWindowMessage ("MSWHEEL_ROLLMSG");
363 client_message = RegisterWindowMessage ("GDK_WIN32_CLIENT_MESSAGE");
366 /* Check if we have some input locale identifier loaded that uses a
367 * latin keyboard, to be able to get the virtual-key code for the
368 * latin characters corresponding to ASCII control characters.
370 if ((n = GetKeyboardLayoutList (0, NULL)) == 0)
371 WIN32_API_FAILED ("GetKeyboardLayoutList");
374 HKL *hkl_list = g_new (HKL, n);
375 if (GetKeyboardLayoutList (n, hkl_list) == 0)
376 WIN32_API_FAILED ("GetKeyboardLayoutList");
379 for (i = 0; latin_locale == NULL && i < n; i++)
380 for (j = 0; j < G_N_ELEMENTS (latin_languages); j++)
381 if (PRIMARYLANGID (LOWORD (hkl_list[i])) == latin_languages[j])
383 latin_locale = hkl_list [i];
390 if (latin_locale == NULL)
392 /* Try to load a keyboard layout with latin characters then.
395 while (latin_locale == NULL && i < G_N_ELEMENTS (latin_languages))
398 g_sprintf (id, "%08x", MAKELANGID (latin_languages[i++], SUBLANG_DEFAULT));
399 latin_locale = LoadKeyboardLayout (id, KLF_NOTELLSHELL|KLF_SUBSTITUTE_OK);
403 GDK_NOTE (EVENTS, g_print ("latin_locale = %08x\n", (guint) latin_locale));
406 source = g_source_new (&event_funcs, sizeof (GSource));
407 g_source_set_priority (source, GDK_PRIORITY_EVENTS);
410 event_poll_fd.fd = open ("/dev/windows", O_RDONLY);
411 if (event_poll_fd.fd == -1)
412 g_error ("can't open \"/dev/windows\": %s", g_strerror (errno));
414 event_poll_fd.fd = G_WIN32_MSG_HANDLE;
416 event_poll_fd.events = G_IO_IN;
418 g_source_add_poll (source, &event_poll_fd);
419 g_source_set_can_recurse (source, TRUE);
420 g_source_attach (source, NULL);
423 hres = CoCreateInstance (&CLSID_CActiveIMM,
427 (LPVOID *) &active_imm_app);
431 GDK_NOTE (EVENTS, g_print ("IActiveIMMApp created %p\n",
433 (*active_imm_app->lpVtbl->Activate) (active_imm_app, TRUE);
435 hres = (*active_imm_app->lpVtbl->QueryInterface) (active_imm_app, &IID_IActiveIMMMessagePumpOwner, (void **) &active_imm_msgpump_owner);
436 GDK_NOTE (EVENTS, g_print ("IActiveIMMMessagePumpOwner created %p\n",
437 active_imm_msgpump_owner));
438 (active_imm_msgpump_owner->lpVtbl->Start) (active_imm_msgpump_owner);
444 gdk_events_pending (void)
447 GdkDisplay *display = gdk_display_get_default ();
449 return (_gdk_event_queue_find_first (display) ||
450 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE));
454 gdk_event_get_graphics_expose (GdkWindow *window)
457 GdkEvent *event = NULL;
459 g_return_val_if_fail (window != NULL, NULL);
461 GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose\n"));
463 if (PeekMessage (&msg, GDK_WINDOW_HWND (window), WM_PAINT, WM_PAINT, PM_REMOVE))
465 handle_wm_paint (&msg, window, TRUE, &event);
468 GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose: got it!\n"));
473 GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose: nope\n"));
478 event_mask_string (GdkEventMask mask)
480 static char bfr[500];
485 if (mask & GDK_##x##_MASK) \
486 p += g_sprintf (p, "%s" #x, (p > bfr ? " " : ""))
488 BIT (POINTER_MOTION);
489 BIT (POINTER_MOTION_HINT);
491 BIT (BUTTON1_MOTION);
492 BIT (BUTTON2_MOTION);
493 BIT (BUTTON3_MOTION);
495 BIT (BUTTON_RELEASE);
502 BIT (PROPERTY_CHANGE);
503 BIT (VISIBILITY_NOTIFY);
514 gdk_pointer_grab (GdkWindow *window,
515 gboolean owner_events,
516 GdkEventMask event_mask,
517 GdkWindow *confine_to,
522 GdkCursorPrivate *cursor_private;
523 gint return_val = GDK_GRAB_SUCCESS;
525 g_return_val_if_fail (window != NULL, 0);
526 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
527 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
529 cursor_private = (GdkCursorPrivate*) cursor;
533 else if ((hcursor = CopyCursor (cursor_private->hcursor)) == NULL)
534 WIN32_API_FAILED ("CopyCursor");
536 return_val = _gdk_input_grab_pointer (window,
542 if (return_val == GDK_GRAB_SUCCESS)
544 if (!GDK_WINDOW_DESTROYED (window))
546 GDK_NOTE (EVENTS, g_print ("%sgdk_pointer_grab: %p %s %p %s%s",
547 (debug_indent > 0 ? "\n" : ""),
548 GDK_WINDOW_HWND (window),
549 (owner_events ? "TRUE" : "FALSE"),
551 event_mask_string (event_mask),
552 (debug_indent == 0 ? "\n" : "")));
554 p_grab_mask = event_mask;
555 p_grab_owner_events = owner_events;
556 p_grab_automatic = FALSE;
558 SetCapture (GDK_WINDOW_HWND (window));
559 return_val = GDK_GRAB_SUCCESS;
562 return_val = GDK_GRAB_ALREADY_GRABBED;
565 if (return_val == GDK_GRAB_SUCCESS)
567 GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl);
568 p_grab_window = window;
570 if (p_grab_cursor != NULL)
572 if (GetCursor () == p_grab_cursor)
574 DestroyCursor (p_grab_cursor);
577 p_grab_cursor = hcursor;
579 if (p_grab_cursor != NULL)
580 SetCursor (p_grab_cursor);
581 else if (impl->hcursor != NULL)
582 SetCursor (impl->hcursor);
584 SetCursor (LoadCursor (NULL, IDC_ARROW));
586 if (confine_to != NULL)
588 gint x, y, width, height;
591 gdk_window_get_origin (confine_to, &x, &y);
592 gdk_drawable_get_size (confine_to, &width, &height);
596 rect.right = x + width;
597 rect.bottom = y + height;
598 API_CALL (ClipCursor, (&rect));
599 p_grab_confine_to = confine_to;
602 /* FIXME: Generate GDK_CROSSING_GRAB events */
609 gdk_display_pointer_ungrab (GdkDisplay *display,
612 g_return_if_fail (display == gdk_display_get_default ());
614 GDK_NOTE (EVENTS, g_print ("%sgdk_display_pointer_ungrab%s",
615 (debug_indent > 0 ? "\n" : ""),
616 (debug_indent == 0 ? "\n" : "")));
618 _gdk_input_ungrab_pointer (time);
620 if (GetCapture () != NULL)
623 /* FIXME: Generate GDK_CROSSING_UNGRAB events */
625 p_grab_window = NULL;
626 if (p_grab_cursor != NULL)
628 if (GetCursor () == p_grab_cursor)
630 DestroyCursor (p_grab_cursor);
631 p_grab_cursor = NULL;
634 if (p_grab_confine_to != NULL)
636 API_CALL (ClipCursor, (NULL));
637 p_grab_confine_to = NULL;
642 find_real_window_for_grabbed_mouse_event (GdkWindow* reported_window,
648 GdkWindow* other_window = NULL;
650 points = MAKEPOINTS (msg->lParam);
653 ClientToScreen (msg->hwnd, &pt);
655 hwnd = WindowFromPoint (pt);
661 GetClientRect (hwnd, &rect);
662 ScreenToClient (hwnd, &pt);
663 if (!PtInRect (&rect, pt))
664 return _gdk_parent_root;
666 other_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) hwnd);
669 if (other_window == NULL)
670 return _gdk_parent_root;
676 find_window_for_mouse_event (GdkWindow* reported_window,
679 if (p_grab_window == NULL || !p_grab_owner_events)
680 return reported_window;
682 return find_real_window_for_grabbed_mouse_event (reported_window, msg);
686 gdk_display_pointer_is_grabbed (GdkDisplay *display)
688 g_return_val_if_fail (display == gdk_display_get_default (), FALSE);
689 GDK_NOTE (EVENTS, g_print ("gdk_pointer_is_grabbed: %s\n",
690 p_grab_window != NULL ? "TRUE" : "FALSE"));
691 return p_grab_window != NULL;
695 gdk_pointer_grab_info_libgtk_only (GdkDisplay *display,
696 GdkWindow **grab_window,
697 gboolean *owner_events)
699 g_return_val_if_fail (display == gdk_display_get_default (), FALSE);
701 if (p_grab_window != NULL)
704 *grab_window = p_grab_window;
706 *owner_events = p_grab_owner_events;
715 gdk_keyboard_grab (GdkWindow *window,
716 gboolean owner_events,
721 g_return_val_if_fail (window != NULL, 0);
722 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
724 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_grab %p\n",
725 GDK_WINDOW_HWND (window)));
727 if (!GDK_WINDOW_DESTROYED (window))
729 k_grab_owner_events = owner_events != 0;
730 return_val = GDK_GRAB_SUCCESS;
733 return_val = GDK_GRAB_ALREADY_GRABBED;
735 if (return_val == GDK_GRAB_SUCCESS)
736 k_grab_window = window;
742 gdk_display_keyboard_ungrab (GdkDisplay *display,
745 g_return_if_fail (display == gdk_display_get_default ());
747 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_ungrab\n"));
749 k_grab_window = NULL;
753 gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display,
754 GdkWindow **grab_window,
755 gboolean *owner_events)
757 g_return_val_if_fail (display == gdk_display_get_default (), FALSE);
762 *grab_window = k_grab_window;
764 *owner_events = k_grab_owner_events;
772 static GdkFilterReturn
773 gdk_event_apply_filters (MSG *msg,
777 GdkEventFilter *filter;
779 GdkFilterReturn result;
785 filter = (GdkEventFilter *) tmp_list->data;
787 result = (*filter->function) (msg, event, filter->data);
788 if (result != GDK_FILTER_CONTINUE)
791 tmp_list = tmp_list->next;
794 return GDK_FILTER_CONTINUE;
798 gdk_display_add_client_message_filter (GdkDisplay *display,
799 GdkAtom message_type,
804 gdk_add_client_message_filter (message_type, func, data);
808 gdk_add_client_message_filter (GdkAtom message_type,
812 GdkClientFilter *filter = g_new (GdkClientFilter, 1);
814 filter->type = message_type;
815 filter->function = func;
818 client_filters = g_list_append (client_filters, filter);
822 build_key_event_state (GdkEvent *event,
825 event->key.state = 0;
827 if (key_state[VK_SHIFT] & 0x80)
828 event->key.state |= GDK_SHIFT_MASK;
830 if (key_state[VK_CAPITAL] & 0x01)
831 event->key.state |= GDK_LOCK_MASK;
833 if (key_state[VK_LBUTTON] & 0x80)
834 event->key.state |= GDK_BUTTON1_MASK;
835 if (key_state[VK_MBUTTON] & 0x80)
836 event->key.state |= GDK_BUTTON2_MASK;
837 if (key_state[VK_RBUTTON] & 0x80)
838 event->key.state |= GDK_BUTTON3_MASK;
839 if (key_state[VK_XBUTTON1] & 0x80)
840 event->key.state |= GDK_BUTTON4_MASK;
841 if (key_state[VK_XBUTTON2] & 0x80)
842 event->key.state |= GDK_BUTTON5_MASK;
844 /* Win9x doesn't distinguish between left and right Control and Alt
845 * in the keyboard state as returned by GetKeyboardState(), so we
846 * have to punt, and accept either Control + either Alt to be AltGr.
848 * Alternatively, we could have some state saved when the Control
849 * and Alt keys messages come in, as the KF_EXTENDED bit in lParam
850 * does indicate correctly whether it is the right Control or Alt
851 * key. But that would be a bit messy.
854 _gdk_keyboard_has_altgr &&
855 key_state[VK_CONTROL] & 0x80 &&
856 key_state[VK_MENU] & 0x80)
857 key_state[VK_LCONTROL] = key_state[VK_RMENU] = 0x80;
859 if (_gdk_keyboard_has_altgr &&
860 (key_state[VK_LCONTROL] & 0x80) &&
861 (key_state[VK_RMENU] & 0x80))
863 event->key.group = 1;
864 event->key.state |= GDK_MOD2_MASK;
865 if (key_state[VK_RCONTROL] & 0x80)
866 event->key.state |= GDK_CONTROL_MASK;
867 if (key_state[VK_LMENU] & 0x80)
868 event->key.state |= GDK_MOD1_MASK;
872 event->key.group = 0;
873 if (key_state[VK_CONTROL] & 0x80)
874 event->key.state |= GDK_CONTROL_MASK;
875 if (key_state[VK_MENU] & 0x80)
876 event->key.state |= GDK_MOD1_MASK;
881 build_pointer_event_state (MSG *msg)
886 if (msg->wParam & MK_CONTROL)
887 state |= GDK_CONTROL_MASK;
888 if (msg->wParam & MK_LBUTTON)
889 state |= GDK_BUTTON1_MASK;
890 if (msg->wParam & MK_MBUTTON)
891 state |= GDK_BUTTON2_MASK;
892 if (msg->wParam & MK_RBUTTON)
893 state |= GDK_BUTTON3_MASK;
894 if (msg->wParam & MK_XBUTTON1)
895 state |= GDK_BUTTON4_MASK;
896 if (msg->wParam & MK_XBUTTON2)
897 state |= GDK_BUTTON5_MASK;
898 if (msg->wParam & MK_SHIFT)
899 state |= GDK_SHIFT_MASK;
900 if (GetKeyState (VK_MENU) < 0)
901 state |= GDK_MOD1_MASK;
902 if (GetKeyState (VK_CAPITAL) & 0x1)
903 state |= GDK_LOCK_MASK;
909 build_wm_ime_composition_event (GdkEvent *event,
914 event->key.time = _gdk_win32_get_next_tick (msg->time);
916 build_key_event_state (event, key_state);
918 event->key.hardware_keycode = 0; /* FIXME: What should it be? */
919 event->key.string = NULL;
920 event->key.length = 0;
921 event->key.keyval = gdk_unicode_to_keyval (wc);
924 #ifdef G_ENABLE_DEBUG
927 print_event_state (guint state)
929 #define CASE(bit) if (state & GDK_ ## bit ## _MASK) g_print (#bit " ");
947 print_event (GdkEvent *event)
949 gchar *escaped, *kvname;
951 g_print ("%s%*s===> ", (debug_indent > 0 ? "\n" : ""), debug_indent, "");
952 switch (event->any.type)
954 #define CASE(x) case x: g_print (#x); break;
959 CASE (GDK_MOTION_NOTIFY);
960 CASE (GDK_BUTTON_PRESS);
961 CASE (GDK_2BUTTON_PRESS);
962 CASE (GDK_3BUTTON_PRESS);
963 CASE (GDK_BUTTON_RELEASE);
964 CASE (GDK_KEY_PRESS);
965 CASE (GDK_KEY_RELEASE);
966 CASE (GDK_ENTER_NOTIFY);
967 CASE (GDK_LEAVE_NOTIFY);
968 CASE (GDK_FOCUS_CHANGE);
969 CASE (GDK_CONFIGURE);
972 CASE (GDK_PROPERTY_NOTIFY);
973 CASE (GDK_SELECTION_CLEAR);
974 CASE (GDK_SELECTION_REQUEST);
975 CASE (GDK_SELECTION_NOTIFY);
976 CASE (GDK_PROXIMITY_IN);
977 CASE (GDK_PROXIMITY_OUT);
978 CASE (GDK_DRAG_ENTER);
979 CASE (GDK_DRAG_LEAVE);
980 CASE (GDK_DRAG_MOTION);
981 CASE (GDK_DRAG_STATUS);
982 CASE (GDK_DROP_START);
983 CASE (GDK_DROP_FINISHED);
984 CASE (GDK_CLIENT_EVENT);
985 CASE (GDK_VISIBILITY_NOTIFY);
986 CASE (GDK_NO_EXPOSE);
988 CASE (GDK_WINDOW_STATE);
991 default: g_assert_not_reached ();
994 g_print (" %p ", GDK_WINDOW_HWND (event->any.window));
996 switch (event->any.type)
1000 _gdk_win32_gdkrectangle_to_string (&event->expose.area),
1001 event->expose.count);
1003 case GDK_MOTION_NOTIFY:
1004 g_print ("(%.4g,%.4g) (%.4g,%.4g) %s",
1005 event->motion.x, event->motion.y,
1006 event->motion.x_root, event->motion.y_root,
1007 event->motion.is_hint ? "HINT " : "");
1008 print_event_state (event->motion.state);
1010 case GDK_BUTTON_PRESS:
1011 case GDK_2BUTTON_PRESS:
1012 case GDK_3BUTTON_PRESS:
1013 case GDK_BUTTON_RELEASE:
1014 g_print ("%d (%.4g,%.4g) (%.4g,%.4g) ",
1015 event->button.button,
1016 event->button.x, event->button.y,
1017 event->button.x_root, event->button.y_root);
1018 print_event_state (event->button.state);
1021 case GDK_KEY_RELEASE:
1022 if (event->key.length == 0)
1023 escaped = g_strdup ("");
1025 escaped = g_strescape (event->key.string, NULL);
1026 kvname = gdk_keyval_name (event->key.keyval);
1027 g_print ("%#.02x group:%d %s %d:\"%s\" ",
1028 event->key.hardware_keycode, event->key.group,
1029 (kvname ? kvname : "??"),
1033 print_event_state (event->key.state);
1035 case GDK_ENTER_NOTIFY:
1036 case GDK_LEAVE_NOTIFY:
1037 g_print ("%p (%.4g,%.4g) (%.4g,%.4g) %s %s%s",
1038 event->crossing.subwindow == NULL ? NULL : GDK_WINDOW_HWND (event->crossing.subwindow),
1039 event->crossing.x, event->crossing.y,
1040 event->crossing.x_root, event->crossing.y_root,
1041 (event->crossing.mode == GDK_CROSSING_NORMAL ? "NORMAL" :
1042 (event->crossing.mode == GDK_CROSSING_GRAB ? "GRAB" :
1043 (event->crossing.mode == GDK_CROSSING_UNGRAB ? "UNGRAB" :
1045 (event->crossing.detail == GDK_NOTIFY_ANCESTOR ? "ANCESTOR" :
1046 (event->crossing.detail == GDK_NOTIFY_VIRTUAL ? "VIRTUAL" :
1047 (event->crossing.detail == GDK_NOTIFY_INFERIOR ? "INFERIOR" :
1048 (event->crossing.detail == GDK_NOTIFY_NONLINEAR ? "NONLINEAR" :
1049 (event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL ? "NONLINEAR_VIRTUAL" :
1050 (event->crossing.detail == GDK_NOTIFY_UNKNOWN ? "UNKNOWN" :
1052 event->crossing.focus ? " FOCUS" : "");
1053 print_event_state (event->crossing.state);
1055 case GDK_FOCUS_CHANGE:
1056 g_print ("%s", (event->focus_change.in ? "IN" : "OUT"));
1059 g_print ("x:%d y:%d w:%d h:%d",
1060 event->configure.x, event->configure.y,
1061 event->configure.width, event->configure.height);
1064 g_print ("(%.4g,%.4g) (%.4g,%.4g)%s",
1065 event->scroll.x, event->scroll.y,
1066 event->scroll.x_root, event->scroll.y_root,
1067 (event->scroll.direction == GDK_SCROLL_UP ? "UP" :
1068 (event->scroll.direction == GDK_SCROLL_DOWN ? "DOWN" :
1069 (event->scroll.direction == GDK_SCROLL_LEFT ? "LEFT" :
1070 (event->scroll.direction == GDK_SCROLL_RIGHT ? "RIGHT" :
1072 print_event_state (event->scroll.state);
1074 case GDK_WINDOW_STATE:
1076 _gdk_win32_window_state_to_string (event->window_state.changed_mask),
1077 _gdk_win32_window_state_to_string (event->window_state.new_window_state));
1082 g_print ("%s", (debug_indent == 0 ? "\n" : ""));
1086 decode_key_lparam (LPARAM lParam)
1088 static char buf[100];
1091 if (HIWORD (lParam) & KF_UP)
1092 p += g_sprintf (p, "KF_UP ");
1093 if (HIWORD (lParam) & KF_REPEAT)
1094 p += g_sprintf (p, "KF_REPEAT ");
1095 if (HIWORD (lParam) & KF_ALTDOWN)
1096 p += g_sprintf (p, "KF_ALTDOWN ");
1097 if (HIWORD (lParam) & KF_EXTENDED)
1098 p += g_sprintf (p, "KF_EXTENDED ");
1099 p += g_sprintf (p, "sc:%d rep:%d", LOBYTE (HIWORD (lParam)), LOWORD (lParam));
1107 fixup_event (GdkEvent *event)
1109 if (event->any.window)
1110 g_object_ref (event->any.window);
1111 if (((event->any.type == GDK_ENTER_NOTIFY) ||
1112 (event->any.type == GDK_LEAVE_NOTIFY)) &&
1113 (event->crossing.subwindow != NULL))
1114 g_object_ref (event->crossing.subwindow);
1115 event->any.send_event = InSendMessage ();
1119 append_event (GdkDisplay *display,
1122 fixup_event (event);
1123 _gdk_event_queue_append (display, event);
1124 GDK_NOTE (EVENTS, print_event (event));
1128 fill_key_event_string (GdkEvent *event)
1133 /* Fill in event->string crudely, since various programs
1138 if (event->key.keyval != GDK_VoidSymbol)
1139 c = gdk_keyval_to_unicode (event->key.keyval);
1143 gsize bytes_written;
1146 /* Apply the control key - Taken from Xlib
1148 if (event->key.state & GDK_CONTROL_MASK)
1150 if ((c >= '@' && c < '\177') || c == ' ')
1154 event->key.string = g_memdup ("\0\0", 2);
1155 event->key.length = 1;
1158 else if (c >= '3' && c <= '7')
1159 c -= ('3' - '\033');
1166 len = g_unichar_to_utf8 (c, buf);
1169 event->key.string = g_locale_from_utf8 (buf, len,
1170 NULL, &bytes_written,
1172 if (event->key.string)
1173 event->key.length = bytes_written;
1175 else if (event->key.keyval == GDK_Escape)
1177 event->key.length = 1;
1178 event->key.string = g_strdup ("\033");
1180 else if (event->key.keyval == GDK_Return ||
1181 event->key.keyval == GDK_KP_Enter)
1183 event->key.length = 1;
1184 event->key.string = g_strdup ("\r");
1187 if (!event->key.string)
1189 event->key.length = 0;
1190 event->key.string = g_strdup ("");
1194 static GdkFilterReturn
1195 apply_filters (GdkDisplay *display,
1200 GdkFilterReturn result;
1201 GdkEvent *event = gdk_event_new (GDK_NOTHING);
1206 event->any.window = window;
1207 g_object_ref (window);
1209 ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
1211 /* I think GdkFilterFunc semantics require the passed-in event
1212 * to already be in the queue. The filter func can generate
1213 * more events and append them after it if it likes.
1215 node = _gdk_event_queue_append (display, event);
1217 result = gdk_event_apply_filters (msg, event, filters);
1219 if (result == GDK_FILTER_CONTINUE || result == GDK_FILTER_REMOVE)
1221 _gdk_event_queue_remove_link (display, node);
1222 g_list_free_1 (node);
1223 gdk_event_free (event);
1225 else /* GDK_FILTER_TRANSLATE */
1227 ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
1228 fixup_event (event);
1229 GDK_NOTE (EVENTS, print_event (event));
1235 gdk_window_is_ancestor (GdkWindow *ancestor,
1238 if (ancestor == NULL || window == NULL)
1241 return (gdk_window_get_parent (window) == ancestor ||
1242 gdk_window_is_ancestor (ancestor, gdk_window_get_parent (window)));
1246 synthesize_enter_or_leave_event (GdkWindow *window,
1249 GdkCrossingMode mode,
1250 GdkNotifyType detail,
1255 gint xoffset, yoffset;
1257 event = gdk_event_new (type);
1258 event->crossing.window = window;
1259 event->crossing.subwindow = NULL;
1260 event->crossing.time = _gdk_win32_get_next_tick (msg->time);
1261 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
1262 event->crossing.x = x + xoffset;
1263 event->crossing.y = y + yoffset;
1264 event->crossing.x_root = msg->pt.x + _gdk_offset_x;
1265 event->crossing.y_root = msg->pt.y + _gdk_offset_y;
1266 event->crossing.mode = mode;
1267 event->crossing.detail = detail;
1268 event->crossing.focus = TRUE; /* FIXME: Set correctly */
1269 event->crossing.state = 0; /* FIXME: Set correctly */
1271 append_event (gdk_drawable_get_display (window), event);
1273 if (type == GDK_ENTER_NOTIFY &&
1274 ((GdkWindowObject *) window)->extension_events != 0)
1275 _gdk_input_enter_event (window);
1279 synthesize_leave_event (GdkWindow *window,
1281 GdkCrossingMode mode,
1282 GdkNotifyType detail)
1286 if (p_grab_window != NULL && !p_grab_owner_events && !(p_grab_mask & GDK_LEAVE_NOTIFY_MASK))
1289 if (!(((GdkWindowObject *) window)->event_mask & GDK_LEAVE_NOTIFY_MASK))
1292 /* Leave events are at (current_x,current_y) in current_window */
1294 if (current_window != window)
1298 ClientToScreen (GDK_WINDOW_HWND (current_window), &pt);
1299 ScreenToClient (GDK_WINDOW_HWND (window), &pt);
1300 synthesize_enter_or_leave_event (window, msg, GDK_LEAVE_NOTIFY, mode, detail, pt.x, pt.y);
1303 synthesize_enter_or_leave_event (window, msg, GDK_LEAVE_NOTIFY, mode, detail, current_x, current_y);
1305 /* This would only make sense if the WM_MOUSEMOVE messages would come
1306 * before the respective WM_MOUSELEAVE message, which apparently they
1308 track_mouse_event (TME_CANCEL, msg->hwnd);
1313 synthesize_enter_event (GdkWindow *window,
1315 GdkCrossingMode mode,
1316 GdkNotifyType detail)
1320 if (p_grab_window != NULL && !p_grab_owner_events && !(p_grab_mask & GDK_ENTER_NOTIFY_MASK))
1323 if (!(((GdkWindowObject *) window)->event_mask & GDK_ENTER_NOTIFY_MASK))
1326 /* Enter events are at GET_X_LPARAM (msg->lParam), GET_Y_LPARAM
1327 * (msg->lParam) in msg->hwnd
1330 pt.x = GET_X_LPARAM (msg->lParam);
1331 pt.y = GET_Y_LPARAM (msg->lParam);
1332 if (msg->hwnd != GDK_WINDOW_HWND (window))
1334 ClientToScreen (msg->hwnd, &pt);
1335 ScreenToClient (GDK_WINDOW_HWND (window), &pt);
1337 synthesize_enter_or_leave_event (window, msg, GDK_ENTER_NOTIFY, mode, detail, pt.x, pt.y);
1339 track_mouse_event (TME_LEAVE, GDK_WINDOW_HWND (window));
1343 synthesize_enter_events (GdkWindow *from,
1346 GdkCrossingMode mode,
1347 GdkNotifyType detail)
1349 GdkWindow *prev = gdk_window_get_parent (to);
1352 synthesize_enter_events (from, prev, msg, mode, detail);
1353 synthesize_enter_event (to, msg, mode, detail);
1357 synthesize_leave_events (GdkWindow *from,
1360 GdkCrossingMode mode,
1361 GdkNotifyType detail)
1363 GdkWindow *next = gdk_window_get_parent (from);
1365 synthesize_leave_event (from, msg, mode, detail);
1367 synthesize_leave_events (next, to, msg, mode, detail);
1371 synthesize_crossing_events (GdkWindow *window,
1372 GdkCrossingMode mode,
1375 GdkWindow *intermediate, *tem, *common_ancestor;
1377 if (gdk_window_is_ancestor (current_window, window))
1379 /* Pointer has moved to an inferior window. */
1380 synthesize_leave_event (current_window, msg, mode, GDK_NOTIFY_INFERIOR);
1382 /* If there are intermediate windows, generate ENTER_NOTIFY
1385 intermediate = gdk_window_get_parent (window);
1386 if (intermediate != current_window)
1388 synthesize_enter_events (current_window, intermediate, msg, mode, GDK_NOTIFY_VIRTUAL);
1391 synthesize_enter_event (window, msg, mode, GDK_NOTIFY_ANCESTOR);
1393 else if (gdk_window_is_ancestor (window, current_window))
1395 /* Pointer has moved to an ancestor window. */
1396 synthesize_leave_event (current_window, msg, mode, GDK_NOTIFY_ANCESTOR);
1398 /* If there are intermediate windows, generate LEAVE_NOTIFY
1401 intermediate = gdk_window_get_parent (current_window);
1402 if (intermediate != window)
1404 synthesize_leave_events (intermediate, window, msg, mode, GDK_NOTIFY_VIRTUAL);
1407 synthesize_enter_event (window, msg, mode, GDK_NOTIFY_INFERIOR);
1409 else if (current_window)
1411 /* Find least common ancestor of current_window and window */
1412 tem = current_window;
1414 common_ancestor = gdk_window_get_parent (tem);
1415 tem = common_ancestor;
1416 } while (common_ancestor &&
1417 !gdk_window_is_ancestor (common_ancestor, window));
1418 if (common_ancestor)
1420 synthesize_leave_event (current_window, msg, mode, GDK_NOTIFY_NONLINEAR);
1421 intermediate = gdk_window_get_parent (current_window);
1422 if (intermediate != common_ancestor)
1424 synthesize_leave_events (intermediate, common_ancestor,
1425 msg, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
1427 intermediate = gdk_window_get_parent (window);
1428 if (intermediate != common_ancestor)
1430 synthesize_enter_events (common_ancestor, intermediate,
1431 msg, mode, GDK_NOTIFY_NONLINEAR_VIRTUAL);
1433 synthesize_enter_event (window, msg, mode, GDK_NOTIFY_NONLINEAR);
1438 /* Dunno where we are coming from */
1439 synthesize_enter_event (window, msg, mode, GDK_NOTIFY_UNKNOWN);
1442 assign_object (¤t_window, window);
1446 synthesize_expose_events (GdkWindow *window)
1450 GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (((GdkWindowObject *) window)->impl);
1451 GList *list = gdk_window_get_children (window);
1458 synthesize_expose_events ((GdkWindow *) list->data);
1464 if (((GdkWindowObject *) window)->input_only)
1466 else if (!(hdc = GetDC (impl->handle)))
1467 WIN32_GDI_FAILED ("GetDC");
1470 if ((k = GetClipBox (hdc, &r)) == ERROR)
1471 WIN32_GDI_FAILED ("GetClipBox");
1472 else if (k != NULLREGION)
1474 event = gdk_event_new (GDK_EXPOSE);
1475 event->expose.window = window;
1476 event->expose.area.x = r.left;
1477 event->expose.area.y = r.top;
1478 event->expose.area.width = r.right - r.left;
1479 event->expose.area.height = r.bottom - r.top;
1480 event->expose.region = gdk_region_rectangle (&(event->expose.area));
1481 event->expose.count = 0;
1483 append_event (gdk_drawable_get_display (window), event);
1485 if (!ReleaseDC (impl->handle, hdc))
1486 WIN32_GDI_FAILED ("ReleaseDC");
1491 update_colors (GdkWindow *window,
1495 GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (((GdkWindowObject *) window)->impl);
1496 GList *list = gdk_window_get_children (window);
1499 GDK_NOTE (COLORMAP, (top ? g_print ("update_colors:") : (void) 0));
1503 update_colors ((GdkWindow *) list->data, FALSE);
1508 if (((GdkWindowObject *) window)->input_only ||
1509 impl->colormap == NULL)
1512 if (!(hdc = GetDC (impl->handle)))
1513 WIN32_GDI_FAILED ("GetDC");
1516 GdkColormapPrivateWin32 *cmapp = GDK_WIN32_COLORMAP_DATA (impl->colormap);
1520 if ((holdpal = SelectPalette (hdc, cmapp->hpal, TRUE)) == NULL)
1521 WIN32_GDI_FAILED ("SelectPalette");
1522 else if ((k = RealizePalette (hdc)) == GDI_ERROR)
1523 WIN32_GDI_FAILED ("RealizePalette");
1528 g_print (" %p pal=%p: realized %d colors\n"
1530 impl->handle, cmapp->hpal, k) :
1532 g_print (" %p", impl->handle)));
1533 if (!UpdateColors (hdc))
1534 WIN32_GDI_FAILED ("UpdateColors");
1535 SelectPalette (hdc, holdpal, TRUE);
1536 RealizePalette (hdc);
1538 if (!ReleaseDC (impl->handle, hdc))
1539 WIN32_GDI_FAILED ("ReleaseDC");
1541 GDK_NOTE (COLORMAP, (top ? g_print ("\n") : (void) 0));
1545 translate_mouse_coords (GdkWindow *window1,
1551 pt.x = GET_X_LPARAM (msg->lParam);
1552 pt.y = GET_Y_LPARAM (msg->lParam);
1553 ClientToScreen (GDK_WINDOW_HWND (window1), &pt);
1554 ScreenToClient (GDK_WINDOW_HWND (window2), &pt);
1555 msg->lParam = MAKELPARAM (pt.x, pt.y);
1558 /* The check_extended flag controls whether to check if the windows want
1559 * events from extended input devices and if the message should be skipped
1560 * because an extended input device is active */
1562 propagate (GdkWindow **window,
1564 GdkWindow *grab_window,
1565 gboolean grab_owner_events,
1567 gboolean (*doesnt_want_it) (gint mask,
1569 gboolean check_extended)
1571 gboolean in_propagation = FALSE;
1573 if (grab_window != NULL && !grab_owner_events)
1575 /* Event source is grabbed with owner_events FALSE */
1577 /* See if the event should be ignored because an extended input device
1579 if (check_extended &&
1580 ((GdkWindowObject *) grab_window)->extension_events != 0 &&
1581 _gdk_input_ignore_core)
1583 GDK_NOTE (EVENTS, g_print (" (ignored for grabber)"));
1586 if ((*doesnt_want_it) (grab_mask, msg))
1588 GDK_NOTE (EVENTS, g_print (" (grabber doesn't want it)"));
1593 GDK_NOTE (EVENTS, g_print (" (to grabber)"));
1594 assign_object (window, grab_window);
1600 /* See if the event should be ignored because an extended input device
1602 if (check_extended &&
1603 ((GdkWindowObject *) *window)->extension_events != 0 &&
1604 _gdk_input_ignore_core)
1606 GDK_NOTE (EVENTS, g_print (" (ignored)"));
1609 if ((*doesnt_want_it) (((GdkWindowObject *) *window)->event_mask, msg))
1611 /* Owner doesn't want it, propagate to parent. */
1612 GdkWindow *parent = gdk_window_get_parent (*window);
1613 if (parent == _gdk_parent_root || parent == NULL)
1615 /* No parent; check if grabbed */
1616 if (grab_window != NULL)
1618 /* Event source is grabbed with owner_events TRUE */
1620 /* See if the event should be ignored because an extended
1621 * input device is used */
1622 if (check_extended &&
1623 ((GdkWindowObject *) grab_window)->extension_events != 0 &&
1624 _gdk_input_ignore_core)
1626 GDK_NOTE (EVENTS, g_print (" (ignored for grabber)"));
1629 if ((*doesnt_want_it) (grab_mask, msg))
1631 /* Grabber doesn't want it either */
1632 GDK_NOTE (EVENTS, g_print (" (grabber doesn't want it)"));
1638 GDK_NOTE (EVENTS, g_print (" (to grabber)"));
1639 assign_object (window, grab_window);
1645 GDK_NOTE (EVENTS, g_print (" (undelivered)"));
1651 assign_object (window, parent);
1652 in_propagation = TRUE;
1653 /* The only branch where we actually continue the loop */
1662 doesnt_want_key (gint mask,
1665 return (((msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP) &&
1666 !(mask & GDK_KEY_RELEASE_MASK)) ||
1667 ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) &&
1668 !(mask & GDK_KEY_PRESS_MASK)));
1672 doesnt_want_char (gint mask,
1675 return !(mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK));
1679 doesnt_want_button_press (gint mask,
1682 return !(mask & GDK_BUTTON_PRESS_MASK);
1686 doesnt_want_button_release (gint mask,
1689 return !(mask & GDK_BUTTON_RELEASE_MASK);
1693 doesnt_want_button_motion (gint mask,
1696 return !((mask & GDK_POINTER_MOTION_MASK) ||
1697 ((msg->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) && (mask & GDK_BUTTON_MOTION_MASK)) ||
1698 ((msg->wParam & MK_LBUTTON) && (mask & GDK_BUTTON1_MOTION_MASK)) ||
1699 ((msg->wParam & MK_MBUTTON) && (mask & GDK_BUTTON2_MOTION_MASK)) ||
1700 ((msg->wParam & MK_RBUTTON) && (mask & GDK_BUTTON3_MOTION_MASK)));
1704 doesnt_want_scroll (gint mask,
1708 return !(mask & GDK_SCROLL_MASK);
1710 return !(mask & GDK_BUTTON_PRESS_MASK);
1715 handle_configure_event (MSG *msg,
1721 GetClientRect (msg->hwnd, &client_rect);
1722 point.x = client_rect.left; /* always 0 */
1723 point.y = client_rect.top;
1724 /* top level windows need screen coords */
1725 if (gdk_window_get_parent (window) == _gdk_parent_root)
1727 ClientToScreen (msg->hwnd, &point);
1728 point.x += _gdk_offset_x;
1729 point.y += _gdk_offset_y;
1732 GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->width = client_rect.right - client_rect.left;
1733 GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->height = client_rect.bottom - client_rect.top;
1735 ((GdkWindowObject *) window)->x = point.x;
1736 ((GdkWindowObject *) window)->y = point.y;
1738 if (((GdkWindowObject *) window)->event_mask & GDK_STRUCTURE_MASK)
1740 GdkEvent *event = gdk_event_new (GDK_CONFIGURE);
1742 event->configure.window = window;
1744 event->configure.width = client_rect.right - client_rect.left;
1745 event->configure.height = client_rect.bottom - client_rect.top;
1747 event->configure.x = point.x;
1748 event->configure.y = point.y;
1750 append_event (gdk_drawable_get_display (window), event);
1755 erase_background (GdkWindow *window,
1760 HPALETTE holdpal = NULL;
1763 GdkColormap *colormap;
1764 GdkColormapPrivateWin32 *colormap_private;
1766 int x_offset, y_offset;
1768 if (((GdkWindowObject *) window)->input_only ||
1769 ((GdkWindowObject *) window)->bg_pixmap == GDK_NO_BG ||
1770 GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->position_info.no_bg)
1775 colormap = gdk_drawable_get_colormap (window);
1778 (colormap->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
1779 colormap->visual->type == GDK_VISUAL_STATIC_COLOR))
1783 colormap_private = GDK_WIN32_COLORMAP_DATA (colormap);
1785 if (!(holdpal = SelectPalette (hdc, colormap_private->hpal, FALSE)))
1786 WIN32_GDI_FAILED ("SelectPalette");
1787 else if ((k = RealizePalette (hdc)) == GDI_ERROR)
1788 WIN32_GDI_FAILED ("RealizePalette");
1790 GDK_NOTE (COLORMAP, g_print ("erase_background: realized %p: %d colors\n",
1791 colormap_private->hpal, k));
1794 x_offset = y_offset = 0;
1795 while (window && ((GdkWindowObject *) window)->bg_pixmap == GDK_PARENT_RELATIVE_BG)
1797 /* If this window should have the same background as the parent,
1798 * fetch the parent. (And if the same goes for the parent, fetch
1799 * the grandparent, etc.)
1801 x_offset += ((GdkWindowObject *) window)->x;
1802 y_offset += ((GdkWindowObject *) window)->y;
1803 window = GDK_WINDOW (((GdkWindowObject *) window)->parent);
1806 if (GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->position_info.no_bg)
1808 /* Improves scolling effect, e.g. main buttons of testgtk */
1812 GetClipBox (hdc, &rect);
1814 if (((GdkWindowObject *) window)->bg_pixmap == NULL)
1816 bg = _gdk_win32_colormap_color (GDK_DRAWABLE_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->colormap,
1817 ((GdkWindowObject *) window)->bg_color.pixel);
1819 if (!(hbr = CreateSolidBrush (bg)))
1820 WIN32_GDI_FAILED ("CreateSolidBrush");
1821 else if (!FillRect (hdc, &rect, hbr))
1822 WIN32_GDI_FAILED ("FillRect");
1826 else if (((GdkWindowObject *) window)->bg_pixmap != GDK_NO_BG)
1828 GdkPixmap *pixmap = ((GdkWindowObject *) window)->bg_pixmap;
1829 GdkPixmapImplWin32 *pixmap_impl = GDK_PIXMAP_IMPL_WIN32 (GDK_PIXMAP_OBJECT (pixmap)->impl);
1831 if (x_offset == 0 && y_offset == 0 &&
1832 pixmap_impl->width <= 8 && pixmap_impl->height <= 8)
1834 if (!(hbr = CreatePatternBrush (GDK_PIXMAP_HBITMAP (pixmap))))
1835 WIN32_GDI_FAILED ("CreatePatternBrush");
1836 else if (!FillRect (hdc, &rect, hbr))
1837 WIN32_GDI_FAILED ("FillRect");
1845 if (!(bgdc = CreateCompatibleDC (hdc)))
1847 WIN32_GDI_FAILED ("CreateCompatibleDC");
1850 if (!(oldbitmap = SelectObject (bgdc, GDK_PIXMAP_HBITMAP (pixmap))))
1852 WIN32_GDI_FAILED ("SelectObject");
1857 while (x < rect.right)
1859 if (x + pixmap_impl->width >= rect.left)
1862 while (y < rect.bottom)
1864 if (y + pixmap_impl->height >= rect.top)
1866 if (!BitBlt (hdc, x, y,
1867 pixmap_impl->width, pixmap_impl->height,
1868 bgdc, 0, 0, SRCCOPY))
1870 WIN32_GDI_FAILED ("BitBlt");
1871 SelectObject (bgdc, oldbitmap);
1876 y += pixmap_impl->height;
1879 x += pixmap_impl->width;
1881 SelectObject (bgdc, oldbitmap);
1888 _gdk_win32_hrgn_to_region (HRGN hrgn)
1896 if ((nbytes = GetRegionData (hrgn, 0, NULL)) == 0)
1898 WIN32_GDI_FAILED ("GetRegionData");
1902 rgndata = (RGNDATA *) g_malloc (nbytes);
1904 if (GetRegionData (hrgn, nbytes, rgndata) == 0)
1906 WIN32_GDI_FAILED ("GetRegionData");
1911 result = gdk_region_new ();
1912 rects = (RECT *) rgndata->Buffer;
1913 for (i = 0; i < rgndata->rdh.nCount; i++)
1917 r.x = rects[i].left;
1919 r.width = rects[i].right - r.x;
1920 r.height = rects[i].bottom - r.y;
1922 gdk_region_union_with_rect (result, &r);
1931 adjust_drag (LONG *drag,
1936 *drag = curr + ((*drag + inc/2 - curr) / inc) * inc;
1938 *drag = curr - ((curr - *drag + inc/2) / inc) * inc;
1942 handle_wm_paint (MSG *msg,
1944 gboolean return_exposes,
1947 HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
1949 PAINTSTRUCT paintstruct;
1950 GdkRegion *update_region;
1951 gint xoffset, yoffset;
1953 if (GetUpdateRgn (msg->hwnd, hrgn, FALSE) == ERROR)
1955 WIN32_GDI_FAILED ("GetUpdateRgn");
1959 hdc = BeginPaint (msg->hwnd, &paintstruct);
1961 GDK_NOTE (EVENTS, g_print (" %s %s dc %p%s",
1962 _gdk_win32_rect_to_string (&paintstruct.rcPaint),
1963 (paintstruct.fErase ? "erase" : ""),
1965 (return_exposes ? " return_exposes" : "")));
1967 EndPaint (msg->hwnd, &paintstruct);
1969 /* HB: don't generate GDK_EXPOSE events for InputOnly
1970 * windows -> backing store now works!
1972 if (((GdkWindowObject *) window)->input_only)
1974 DeleteObject (hrgn);
1978 if (!(((GdkWindowObject *) window)->event_mask & GDK_EXPOSURE_MASK))
1980 GDK_NOTE (EVENTS, g_print (" (ignored)"));
1981 DeleteObject (hrgn);
1985 #if 0 /* we need to process exposes even with GDK_NO_BG
1986 * Otherwise The GIMP canvas update is broken ....
1988 if (((GdkWindowObject *) window)->bg_pixmap == GDK_NO_BG)
1992 if ((paintstruct.rcPaint.right == paintstruct.rcPaint.left) ||
1993 (paintstruct.rcPaint.bottom == paintstruct.rcPaint.top))
1995 GDK_NOTE (EVENTS, g_print (" (empty paintstruct, ignored)"));
1996 DeleteObject (hrgn);
2002 if (!GDK_WINDOW_DESTROYED (window))
2004 GList *list = gdk_drawable_get_display (window)->queued_events;
2006 *event = gdk_event_new (GDK_EXPOSE);
2007 (*event)->expose.window = window;
2008 (*event)->expose.area.x = paintstruct.rcPaint.left;
2009 (*event)->expose.area.y = paintstruct.rcPaint.top;
2010 (*event)->expose.area.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left;
2011 (*event)->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
2012 (*event)->expose.region = _gdk_win32_hrgn_to_region (hrgn);
2013 (*event)->expose.count = 0;
2015 while (list != NULL)
2017 GdkEventPrivate *evp = list->data;
2019 if (evp->event.any.type == GDK_EXPOSE &&
2020 evp->event.any.window == window &&
2021 !(evp->flags & GDK_EVENT_PENDING))
2022 evp->event.expose.count++;
2031 update_region = _gdk_win32_hrgn_to_region (hrgn);
2033 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2034 gdk_region_offset (update_region, xoffset, yoffset);
2036 _gdk_window_process_expose (window, update_region);
2037 gdk_region_destroy (update_region);
2039 DeleteObject (hrgn);
2043 handle_stuff_while_moving_or_resizing (void)
2045 int arbitrary_limit = 1;
2046 while (g_main_pending () && arbitrary_limit--)
2047 g_main_iteration (FALSE);
2050 static VOID CALLBACK
2051 resize_timer_proc (HWND hwnd,
2056 if (_sizemove_in_progress)
2057 handle_stuff_while_moving_or_resizing ();
2061 handle_display_change (void)
2063 _gdk_monitor_init ();
2064 _gdk_root_window_size_init ();
2065 g_signal_emit_by_name (_gdk_screen, "size_changed");
2069 gdk_event_translate (GdkDisplay *display,
2075 RECT rect, *drag, orig_drag;
2080 CHARSETINFO charset_info;
2081 BYTE key_state[256];
2089 GdkWindow *window = NULL;
2090 GdkWindowImplWin32 *impl;
2092 GdkWindow *orig_window, *new_window;
2093 gint xoffset, yoffset;
2095 static gint update_colors_counter = 0;
2099 gboolean return_val = FALSE;
2103 if (_gdk_default_filters)
2105 /* Apply global filters */
2107 GdkFilterReturn result =
2108 apply_filters (display, NULL, msg, _gdk_default_filters);
2110 /* If result is GDK_FILTER_CONTINUE, we continue as if nothing
2111 * happened. If it is GDK_FILTER_REMOVE, we return FALSE from
2112 * gdk_event_translate(), meaning that the DefWindowProc() will
2113 * be called. If it is GDK_FILTER_TRANSLATE, we return TRUE, and
2114 * DefWindowProc() will not be called.
2116 if (result == GDK_FILTER_REMOVE)
2118 else if (result == GDK_FILTER_TRANSLATE)
2122 window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd);
2123 orig_window = window;
2127 /* XXX Handle WM_QUIT here ? */
2128 if (msg->message == WM_QUIT)
2130 GDK_NOTE (EVENTS, g_print (" %d", msg->wParam));
2133 else if (msg->message == WM_MOVE ||
2134 msg->message == WM_SIZE)
2136 /* It's quite normal to get these messages before we have
2137 * had time to register the window in our lookup table, or
2138 * when the window is being destroyed and we already have
2139 * removed it. Repost the same message to our queue so that
2140 * we will get it later when we are prepared.
2142 GDK_NOTE (MISC, g_print (" (posted)"));
2144 PostMessage (msg->hwnd, msg->message,
2145 msg->wParam, msg->lParam);
2147 else if (msg->message == WM_CREATE)
2149 window = (UNALIGNED GdkWindow*) (((LPCREATESTRUCT) msg->lParam)->lpCreateParams);
2150 GDK_WINDOW_HWND (window) = msg->hwnd;
2154 GDK_NOTE (EVENTS, g_print (" (no GdkWindow)"));
2159 g_object_ref (window);
2161 /* window's refcount has now been increased, so code below should
2162 * not just return from this function, but instead goto done (or
2163 * break out of the big switch). To protect against forgetting this,
2164 * #define return to a syntax error...
2166 #define return GOTO_DONE_INSTEAD
2168 if (!GDK_WINDOW_DESTROYED (window) && ((GdkWindowObject *) window)->filters)
2170 /* Apply per-window filters */
2172 GdkFilterReturn result =
2173 apply_filters (display, window, msg, ((GdkWindowObject *) window)->filters);
2175 if (result == GDK_FILTER_REMOVE)
2180 else if (result == GDK_FILTER_TRANSLATE)
2187 if (msg->message == msh_mousewheel)
2189 GDK_NOTE (EVENTS, g_print (" (MSH_MOUSEWHEEL)"));
2191 /* MSG_MOUSEWHEEL is delivered to the foreground window. Work
2192 * around that. Also, the position is in screen coordinates, not
2193 * client coordinates as with the button messages.
2195 point.x = GET_X_LPARAM (msg->lParam);
2196 point.y = GET_Y_LPARAM (msg->lParam);
2197 if ((hwnd = WindowFromPoint (point)) == NULL)
2201 if ((new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd)) == NULL)
2204 assign_object (&window, new_window);
2206 if (!propagate (&window, msg,
2207 p_grab_window, p_grab_owner_events, p_grab_mask,
2208 doesnt_want_scroll, TRUE))
2211 if (GDK_WINDOW_DESTROYED (window))
2214 ScreenToClient (msg->hwnd, &point);
2216 event = gdk_event_new (GDK_SCROLL);
2217 event->scroll.window = window;
2218 event->scroll.direction = ((int) msg->wParam > 0) ?
2219 GDK_SCROLL_UP : GDK_SCROLL_DOWN;
2220 event->scroll.time = _gdk_win32_get_next_tick (msg->time);
2221 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2222 event->scroll.x = (gint16) point.x + xoffset;
2223 event->scroll.y = (gint16) point.y + yoffset;
2224 event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam) + _gdk_offset_x;
2225 event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam) + _gdk_offset_y;
2226 event->scroll.state = 0; /* No state information with MSH_MOUSEWHEEL */
2227 event->scroll.device = display->core_pointer;
2229 append_event (display, event);
2234 else if (msg->message == client_message)
2238 tmp_list = client_filters;
2241 GdkClientFilter *filter = tmp_list->data;
2243 if (filter->type == GDK_POINTER_TO_ATOM (msg->wParam))
2245 GList *this_filter = g_list_append (NULL, filter);
2247 GdkFilterReturn result =
2248 apply_filters (display, window, msg, this_filter);
2250 GDK_NOTE (EVENTS, g_print (" (client filter match)"));
2252 g_list_free (this_filter);
2254 if (result == GDK_FILTER_REMOVE)
2259 else if (result == GDK_FILTER_TRANSLATE)
2264 else /* GDK_FILTER_CONTINUE */
2266 /* Send unknown client messages on to Gtk for it to use */
2268 event = gdk_event_new (GDK_CLIENT_EVENT);
2269 event->client.window = window;
2270 event->client.message_type = GDK_POINTER_TO_ATOM (msg->wParam);
2271 event->client.data_format = 32;
2272 event->client.data.l[0] = msg->lParam;
2273 for (i = 1; i < 5; i++)
2274 event->client.data.l[i] = 0;
2276 append_event (display, event);
2282 tmp_list = tmp_list->next;
2286 switch (msg->message)
2288 case WM_INPUTLANGCHANGE:
2289 _gdk_input_locale = (HKL) msg->lParam;
2290 _gdk_input_locale_is_ime = ImmIsIME (_gdk_input_locale);
2291 TranslateCharsetInfo ((DWORD FAR *) msg->wParam,
2294 _gdk_input_codepage = charset_info.ciACP;
2295 _gdk_keymap_serial++;
2297 g_print (" cs:%lu hkl:%lx%s cp:%d",
2298 (gulong) msg->wParam,
2299 msg->lParam, _gdk_input_locale_is_ime ? " (IME)" : "",
2300 _gdk_input_codepage));
2306 g_print (" %s ch:%.02x %s",
2307 (GetKeyNameText (msg->lParam, buf,
2311 decode_key_lparam (msg->lParam)));
2313 /* If posted without us having keyboard focus, ignore */
2314 if ((msg->wParam != VK_F10 && msg->wParam != VK_MENU) &&
2315 !(HIWORD (msg->lParam) & KF_ALTDOWN))
2318 /* Let the system handle Alt-Tab, Alt-Space, Alt-Enter and
2319 * Alt-F4 unless the keyboard is grabbed.
2321 if (k_grab_window == NULL &&
2322 (msg->wParam == VK_TAB ||
2323 msg->wParam == VK_SPACE ||
2324 msg->wParam == VK_RETURN ||
2325 msg->wParam == VK_F4))
2328 /* Jump to code in common with WM_KEYUP and WM_KEYDOWN */
2334 g_print (" %s ch:%.02x %s",
2335 (GetKeyNameText (msg->lParam, buf,
2339 decode_key_lparam (msg->lParam)));
2343 /* Ignore key messages intended for the IME */
2344 if (msg->wParam == VK_PROCESSKEY ||
2348 if (!propagate (&window, msg,
2349 k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
2350 doesnt_want_key, FALSE))
2353 if (GDK_WINDOW_DESTROYED (window))
2356 event = gdk_event_new ((msg->message == WM_KEYDOWN ||
2357 msg->message == WM_SYSKEYDOWN) ?
2358 GDK_KEY_PRESS : GDK_KEY_RELEASE);
2359 event->key.window = window;
2360 event->key.time = _gdk_win32_get_next_tick (msg->time);
2361 event->key.keyval = GDK_VoidSymbol;
2362 event->key.string = NULL;
2363 event->key.length = 0;
2364 event->key.hardware_keycode = msg->wParam;
2366 API_CALL (GetKeyboardState, (key_state));
2368 /* g_print ("ctrl:%02x lctrl:%02x rctrl:%02x alt:%02x lalt:%02x ralt:%02x\n", key_state[VK_CONTROL], key_state[VK_LCONTROL], key_state[VK_RCONTROL], key_state[VK_MENU], key_state[VK_LMENU], key_state[VK_RMENU]); */
2370 build_key_event_state (event, key_state);
2372 gdk_keymap_translate_keyboard_state (NULL,
2373 event->key.hardware_keycode,
2379 fill_key_event_string (event);
2381 /* Reset MOD1_MASK if it is the Alt key itself */
2382 if (msg->wParam == VK_MENU)
2383 event->key.state &= ~GDK_MOD1_MASK;
2385 append_event (display, event);
2391 if (msg->wParam != VK_SPACE)
2393 /* To prevent beeps, don't let DefWindowProc() be called */
2399 case WM_IME_STARTCOMPOSITION:
2400 in_ime_composition = TRUE;
2403 case WM_IME_ENDCOMPOSITION:
2404 in_ime_composition = FALSE;
2407 case WM_IME_COMPOSITION:
2408 /* On Win2k WM_IME_CHAR doesn't work correctly for non-Unicode
2409 * applications. Thus, handle WM_IME_COMPOSITION with
2410 * GCS_RESULTSTR instead, fetch the Unicode chars from the IME
2411 * with ImmGetCompositionStringW().
2414 * http://groups.google.com/groups?selm=natX5.57%24g77.19788%40nntp2.onemain.com
2416 * http://groups.google.com/groups?selm=u2XfrXw5BHA.1628%40tkmsftngp02
2417 * for comments by other people that seems to have the same
2418 * experience. WM_IME_CHAR just gives question marks, apparently
2419 * because of going through some conversion to the current code
2422 * WM_IME_CHAR might work on NT4 or Win9x with ActiveIMM, but
2423 * use WM_IME_COMPOSITION there, too, to simplify the code.
2425 GDK_NOTE (EVENTS, g_print (" %#lx", msg->lParam));
2427 if (!(msg->lParam & GCS_RESULTSTR))
2430 if (!propagate (&window, msg,
2431 k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
2432 doesnt_want_char, FALSE))
2435 if (GDK_WINDOW_DESTROYED (window))
2438 himc = ImmGetContext (msg->hwnd);
2439 ccount = ImmGetCompositionStringW (himc, GCS_RESULTSTR,
2440 wbuf, sizeof (wbuf));
2441 ImmReleaseContext (msg->hwnd, himc);
2445 API_CALL (GetKeyboardState, (key_state));
2447 for (i = 0; i < ccount; i++)
2449 if (((GdkWindowObject *) window)->event_mask & GDK_KEY_PRESS_MASK)
2451 /* Build a key press event */
2452 event = gdk_event_new (GDK_KEY_PRESS);
2453 event->key.window = window;
2454 build_wm_ime_composition_event (event, msg, wbuf[i], key_state);
2456 append_event (display, event);
2459 if (((GdkWindowObject *) window)->event_mask & GDK_KEY_RELEASE_MASK)
2461 /* Build a key release event. */
2462 event = gdk_event_new (GDK_KEY_RELEASE);
2463 event->key.window = window;
2464 build_wm_ime_composition_event (event, msg, wbuf[i], key_state);
2466 append_event (display, event);
2472 case WM_LBUTTONDOWN:
2476 case WM_MBUTTONDOWN:
2480 case WM_RBUTTONDOWN:
2484 case WM_XBUTTONDOWN:
2485 if (HIWORD (msg->wParam) == XBUTTON1)
2492 g_print (" (%d,%d)",
2493 GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
2495 assign_object (&window, find_window_for_mouse_event (window, msg));
2497 if (p_grab_window != NULL)
2499 GdkWindow *real_window = find_real_window_for_grabbed_mouse_event (window, msg);
2501 if (real_window != current_window)
2502 synthesize_crossing_events (real_window, GDK_CROSSING_NORMAL, msg);
2506 if (window != current_window)
2507 synthesize_crossing_events (window, GDK_CROSSING_NORMAL, msg);
2510 if (!propagate (&window, msg,
2511 p_grab_window, p_grab_owner_events, p_grab_mask,
2512 doesnt_want_button_press, TRUE))
2515 if (GDK_WINDOW_DESTROYED (window))
2518 /* Emulate X11's automatic active grab */
2521 /* No explicit active grab, let's start one automatically */
2522 GDK_NOTE (EVENTS, g_print (" (automatic grab)"));
2523 gdk_pointer_grab (window,
2525 ((GdkWindowObject *) window)->event_mask,
2527 p_grab_automatic = TRUE;
2530 event = gdk_event_new (GDK_BUTTON_PRESS);
2531 event->button.window = window;
2532 event->button.time = _gdk_win32_get_next_tick (msg->time);
2533 if (window != orig_window)
2534 translate_mouse_coords (orig_window, window, msg);
2535 event->button.x = current_x = (gint16) GET_X_LPARAM (msg->lParam);
2536 event->button.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam);
2537 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2538 event->button.x += xoffset;
2539 event->button.y += yoffset;
2540 event->button.x_root = msg->pt.x + _gdk_offset_x;
2541 event->button.y_root = msg->pt.y + _gdk_offset_y;
2542 event->button.axes = NULL;
2543 event->button.state = build_pointer_event_state (msg);
2544 event->button.button = button;
2545 event->button.device = display->core_pointer;
2547 append_event (display, event);
2549 _gdk_event_button_generate (display, event);
2567 if (HIWORD (msg->wParam) == XBUTTON1)
2574 g_print (" (%d,%d)",
2575 GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
2577 assign_object (&window, find_window_for_mouse_event (window, msg));
2579 if (p_grab_window != NULL)
2581 GdkWindow *real_window = find_real_window_for_grabbed_mouse_event (window, msg);
2583 if (real_window != current_window)
2584 synthesize_crossing_events (real_window, GDK_CROSSING_NORMAL, msg);
2588 if (window != current_window)
2589 synthesize_crossing_events (window, GDK_CROSSING_NORMAL, msg);
2593 if (((GdkWindowObject *) window)->extension_events != 0 &&
2594 _gdk_input_ignore_core)
2596 GDK_NOTE (EVENTS, g_print (" (ignored)"));
2601 if (!propagate (&window, msg,
2602 p_grab_window, p_grab_owner_events, p_grab_mask,
2603 doesnt_want_button_release, TRUE))
2606 else if (!GDK_WINDOW_DESTROYED (window))
2608 event = gdk_event_new (GDK_BUTTON_RELEASE);
2609 event->button.window = window;
2610 event->button.time = _gdk_win32_get_next_tick (msg->time);
2611 if (window != orig_window)
2612 translate_mouse_coords (orig_window, window, msg);
2613 event->button.x = current_x = (gint16) GET_X_LPARAM (msg->lParam);
2614 event->button.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam);
2615 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2616 event->button.x += xoffset;
2617 event->button.y += yoffset;
2618 event->button.x_root = msg->pt.x + _gdk_offset_x;
2619 event->button.y_root = msg->pt.y + _gdk_offset_y;
2620 event->button.axes = NULL;
2621 event->button.state = build_pointer_event_state (msg);
2622 event->button.button = button;
2623 event->button.device = display->core_pointer;
2625 append_event (display, event);
2628 if (p_grab_window != NULL &&
2630 (msg->wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) == 0)
2632 /* Terminate automatic grab */
2633 gdk_pointer_ungrab (0);
2641 g_print (" %#x (%d,%d)",
2643 GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
2645 /* HB: only process mouse move messages if we own the active window. */
2646 GetWindowThreadProcessId (GetActiveWindow (), &pidActWin);
2647 GetWindowThreadProcessId (msg->hwnd, &pidThis);
2648 if (pidActWin != pidThis)
2651 assign_object (&window, find_window_for_mouse_event (window, msg));
2653 if (p_grab_window != NULL)
2655 GdkWindow *real_window = find_real_window_for_grabbed_mouse_event (window, msg);
2657 if (real_window != current_window)
2658 synthesize_crossing_events (real_window, GDK_CROSSING_NORMAL, msg);
2662 if (window != current_window)
2663 synthesize_crossing_events (window, GDK_CROSSING_NORMAL, msg);
2666 if (!propagate (&window, msg,
2667 p_grab_window, p_grab_owner_events, p_grab_mask,
2668 doesnt_want_button_motion, TRUE))
2671 if (GDK_WINDOW_DESTROYED (window))
2674 if (window != orig_window)
2675 translate_mouse_coords (orig_window, window, msg);
2677 /* If we haven't moved, don't create any event.
2678 * Windows sends WM_MOUSEMOVE messages after button presses
2679 * even if the mouse doesn't move. This disturbs gtk.
2681 if (window == current_window &&
2682 GET_X_LPARAM (msg->lParam) == current_x &&
2683 GET_Y_LPARAM (msg->lParam) == current_y)
2686 event = gdk_event_new (GDK_MOTION_NOTIFY);
2687 event->motion.window = window;
2688 event->motion.time = _gdk_win32_get_next_tick (msg->time);
2689 event->motion.x = current_x = (gint16) GET_X_LPARAM (msg->lParam);
2690 event->motion.y = current_y = (gint16) GET_Y_LPARAM (msg->lParam);
2691 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2692 event->motion.x += xoffset;
2693 event->motion.y += yoffset;
2694 event->motion.x_root = msg->pt.x + _gdk_offset_x;
2695 event->motion.y_root = msg->pt.y + _gdk_offset_y;
2696 event->motion.axes = NULL;
2697 event->motion.state = build_pointer_event_state (msg);
2698 event->motion.is_hint = FALSE;
2699 event->motion.device = display->core_pointer;
2701 append_event (display, event);
2706 case WM_NCMOUSEMOVE:
2708 g_print (" (%d,%d)",
2709 GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
2710 if (current_window != NULL &&
2711 (((GdkWindowObject *) current_window)->event_mask & GDK_LEAVE_NOTIFY_MASK))
2713 synthesize_crossing_events (_gdk_parent_root, GDK_CROSSING_NORMAL, msg);
2719 GDK_NOTE (EVENTS, g_print (" %d (%ld,%ld)",
2720 HIWORD (msg->wParam), msg->pt.x, msg->pt.y));
2722 if (!gdk_win32_handle_table_lookup ((GdkNativeWindow) WindowFromPoint (msg->pt)))
2724 GdkNotifyType detail;
2726 if (GDK_WINDOW_TYPE (current_window) != GDK_WINDOW_CHILD)
2727 detail = GDK_NOTIFY_ANCESTOR;
2729 detail = GDK_NOTIFY_UNKNOWN;
2731 /* we are only interested if we don't know the new window */
2732 synthesize_enter_or_leave_event (current_window, msg,
2733 GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, detail,
2734 current_x, current_y);
2738 GDK_NOTE (EVENTS, g_print (" (ignored)"));
2744 GDK_NOTE (EVENTS, g_print (" %d", HIWORD (msg->wParam)));
2746 /* WM_MOUSEWHEEL is delivered to the focus window. Work around
2747 * that. Also, the position is in screen coordinates, not client
2748 * coordinates as with the button messages. I love the
2749 * consistency of Windows.
2751 point.x = GET_X_LPARAM (msg->lParam);
2752 point.y = GET_Y_LPARAM (msg->lParam);
2754 if ((hwnd = WindowFromPoint (point)) == NULL)
2758 if ((new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd)) == NULL)
2761 if (new_window != window)
2763 assign_object (&window, new_window);
2766 if (!propagate (&window, msg,
2767 p_grab_window, p_grab_owner_events, p_grab_mask,
2768 doesnt_want_scroll, TRUE))
2771 if (GDK_WINDOW_DESTROYED (window))
2774 ScreenToClient (msg->hwnd, &point);
2776 event = gdk_event_new (GDK_SCROLL);
2777 event->scroll.window = window;
2778 event->scroll.direction = (((short) HIWORD (msg->wParam)) > 0) ?
2779 GDK_SCROLL_UP : GDK_SCROLL_DOWN;
2780 event->scroll.window = window;
2781 event->scroll.time = _gdk_win32_get_next_tick (msg->time);
2782 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2783 event->scroll.x = (gint16) point.x + xoffset;
2784 event->scroll.y = (gint16) point.y + yoffset;
2785 event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam) + _gdk_offset_x;
2786 event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam) + _gdk_offset_y;
2787 event->scroll.state = build_pointer_event_state (msg);
2788 event->scroll.device = display->core_pointer;
2790 append_event (display, event);
2795 case WM_QUERYNEWPALETTE:
2796 if (gdk_visual_get_system ()->type == GDK_VISUAL_PSEUDO_COLOR)
2798 synthesize_expose_events (window);
2799 update_colors_counter = 0;
2804 case WM_PALETTECHANGED:
2805 GDK_NOTE (EVENTS_OR_COLORMAP, g_print (" %p", (HWND) msg->wParam));
2806 if (gdk_visual_get_system ()->type != GDK_VISUAL_PSEUDO_COLOR)
2811 if (msg->hwnd == (HWND) msg->wParam)
2814 if (++update_colors_counter == 5)
2816 synthesize_expose_events (window);
2817 update_colors_counter = 0;
2821 update_colors (window, TRUE);
2824 case WM_MOUSEACTIVATE:
2825 if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP)
2827 *ret_valp = MA_NOACTIVATE;
2834 if (p_grab_window != NULL && !p_grab_owner_events && !(p_grab_mask & GDK_FOCUS_CHANGE_MASK))
2837 if (!(((GdkWindowObject *) window)->event_mask & GDK_FOCUS_CHANGE_MASK))
2840 if (GDK_WINDOW_DESTROYED (window))
2843 event = gdk_event_new (GDK_FOCUS_CHANGE);
2844 event->focus_change.window = window;
2845 event->focus_change.in = (msg->message == WM_SETFOCUS);
2847 append_event (display, event);
2853 GDK_NOTE (EVENTS, g_print (" %p", (HANDLE) msg->wParam));
2855 if (GDK_WINDOW_DESTROYED (window))
2858 erase_background (window, (HDC) msg->wParam);
2864 handle_wm_paint (msg, window, FALSE, NULL);
2868 GDK_NOTE (EVENTS, g_print (" %#x %#x",
2869 LOWORD (msg->lParam), HIWORD (msg->lParam)));
2871 if (p_grab_window == NULL && LOWORD (msg->lParam) != HTCLIENT)
2874 if (p_grab_window != NULL && p_grab_cursor != NULL)
2875 hcursor = p_grab_cursor;
2876 else if (!GDK_WINDOW_DESTROYED (window))
2877 hcursor = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->hcursor;
2881 if (hcursor != NULL)
2883 GDK_NOTE (EVENTS, g_print (" (SetCursor(%p)", hcursor));
2884 SetCursor (hcursor);
2891 GDK_NOTE (EVENTS, g_print (" %d", msg->wParam));
2893 if (!(((GdkWindowObject *) window)->event_mask & GDK_STRUCTURE_MASK))
2896 if (msg->lParam == SW_OTHERUNZOOM ||
2897 msg->lParam == SW_OTHERZOOM)
2900 if (GDK_WINDOW_DESTROYED (window))
2903 event = gdk_event_new (msg->wParam ? GDK_MAP : GDK_UNMAP);
2904 event->any.window = window;
2906 append_event (display, event);
2908 if (event->any.type == GDK_UNMAP &&
2909 p_grab_window == window)
2910 gdk_pointer_ungrab (msg->time);
2912 if (event->any.type == GDK_UNMAP &&
2913 k_grab_window == window)
2914 gdk_keyboard_ungrab (msg->time);
2921 g_print (" %s %dx%d",
2922 (msg->wParam == SIZE_MAXHIDE ? "MAXHIDE" :
2923 (msg->wParam == SIZE_MAXIMIZED ? "MAXIMIZED" :
2924 (msg->wParam == SIZE_MAXSHOW ? "MAXSHOW" :
2925 (msg->wParam == SIZE_MINIMIZED ? "MINIMIZED" :
2926 (msg->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
2927 LOWORD (msg->lParam), HIWORD (msg->lParam)));
2929 if (msg->wParam == SIZE_MINIMIZED)
2931 /* Don't generate any GDK event. This is *not* an UNMAP. */
2933 if (p_grab_window == window)
2934 gdk_pointer_ungrab (msg->time);
2936 if (k_grab_window == window)
2937 gdk_keyboard_ungrab (msg->time);
2939 gdk_synthesize_window_state (window,
2940 GDK_WINDOW_STATE_WITHDRAWN,
2941 GDK_WINDOW_STATE_ICONIFIED);
2943 else if ((msg->wParam == SIZE_RESTORED ||
2944 msg->wParam == SIZE_MAXIMIZED) &&
2945 GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD)
2947 GdkWindowState withdrawn_bit =
2948 IsWindowVisible (msg->hwnd) ? GDK_WINDOW_STATE_WITHDRAWN : 0;
2950 if (!GDK_WINDOW_DESTROYED (window))
2951 handle_configure_event (msg, window);
2953 if (msg->wParam == SIZE_RESTORED)
2954 gdk_synthesize_window_state (window,
2955 GDK_WINDOW_STATE_ICONIFIED |
2956 GDK_WINDOW_STATE_MAXIMIZED |
2959 else if (msg->wParam == SIZE_MAXIMIZED)
2960 gdk_synthesize_window_state (window,
2961 GDK_WINDOW_STATE_ICONIFIED |
2963 GDK_WINDOW_STATE_MAXIMIZED);
2965 if (((GdkWindowObject *) window)->resize_count > 1)
2966 ((GdkWindowObject *) window)->resize_count -= 1;
2968 if (((GdkWindowObject *) window)->extension_events != 0)
2969 _gdk_input_configure_event (window);
2975 case WM_ENTERSIZEMOVE:
2976 _sizemove_in_progress = TRUE;
2977 resize_timer = SetTimer (NULL, 0, 20, resize_timer_proc);
2980 case WM_EXITSIZEMOVE:
2981 _sizemove_in_progress = FALSE;
2982 KillTimer (NULL, resize_timer);
2985 case WM_WINDOWPOSCHANGED :
2986 /* Once we've entered the moving or sizing modal loop, we won't
2987 * return to the main loop until we're done sizing or moving.
2989 if (_sizemove_in_progress &&
2990 GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
2991 !GDK_WINDOW_DESTROYED (window))
2996 GetClientRect (msg->hwnd, &client_rect);
2997 point.x = client_rect.left; /* always 0 */
2998 point.y = client_rect.top;
2999 /* top level windows need screen coords */
3000 if (gdk_window_get_parent (window) == _gdk_parent_root)
3002 ClientToScreen (msg->hwnd, &point);
3003 point.x += _gdk_offset_x;
3004 point.y += _gdk_offset_y;
3007 GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->width = client_rect.right - client_rect.left;
3008 GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->height = client_rect.bottom - client_rect.top;
3010 ((GdkWindowObject *) window)->x = point.x;
3011 ((GdkWindowObject *) window)->y = point.y;
3013 if (((GdkWindowObject *) window)->event_mask & GDK_STRUCTURE_MASK)
3015 GdkEvent *event = gdk_event_new (GDK_CONFIGURE);
3017 event->configure.window = window;
3019 event->configure.width = client_rect.right - client_rect.left;
3020 event->configure.height = client_rect.bottom - client_rect.top;
3022 event->configure.x = point.x;
3023 event->configure.y = point.y;
3025 if (((GdkWindowObject *) window)->resize_count > 1)
3026 ((GdkWindowObject *) window)->resize_count -= 1;
3028 #if 0 /* I don't like calling _gdk_event_func() from here, isn't there
3029 * a risk of getting events processed in the wrong order, like
3030 * Owen says in the discussion of bug #99540?
3032 fixup_event (event);
3033 if (_gdk_event_func)
3034 (*_gdk_event_func) (event, _gdk_event_data);
3035 gdk_event_free (event);
3036 #else /* Calling append_event() is slower, but guarantees that events won't
3037 * get reordered, I think.
3039 append_event (display, event);
3042 /* Dispatch main loop - to realize resizes... */
3043 handle_stuff_while_moving_or_resizing ();
3045 /* Claim as handled, so that WM_SIZE and WM_MOVE are avoided */
3053 GetWindowRect (GDK_WINDOW_HWND (window), &rect);
3054 GDK_NOTE (EVENTS, g_print (" %s curr:%s drag:%s",
3055 (msg->wParam == WMSZ_BOTTOM ? "BOTTOM" :
3056 (msg->wParam == WMSZ_BOTTOMLEFT ? "BOTTOMLEFT" :
3057 (msg->wParam == WMSZ_LEFT ? "LEFT" :
3058 (msg->wParam == WMSZ_TOPLEFT ? "TOPLEFT" :
3059 (msg->wParam == WMSZ_TOP ? "TOP" :
3060 (msg->wParam == WMSZ_TOPRIGHT ? "TOPRIGHT" :
3061 (msg->wParam == WMSZ_RIGHT ? "RIGHT" :
3063 (msg->wParam == WMSZ_BOTTOMRIGHT ? "BOTTOMRIGHT" :
3065 _gdk_win32_rect_to_string (&rect),
3066 _gdk_win32_rect_to_string ((RECT *) msg->lParam)));
3068 impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl);
3069 drag = (RECT *) msg->lParam;
3071 if (impl->hint_flags & GDK_HINT_RESIZE_INC)
3073 if (impl->hint_flags & GDK_HINT_BASE_SIZE)
3075 /* Resize in increments relative to the base size */
3076 rect.left = rect.top = 0;
3077 rect.right = impl->hints.base_width;
3078 rect.bottom = impl->hints.base_height;
3079 _gdk_win32_adjust_client_rect (window, &rect);
3080 point.x = rect.left;
3082 ClientToScreen (GDK_WINDOW_HWND (window), &point);
3083 rect.left = point.x;
3085 point.x = rect.right;
3086 point.y = rect.bottom;
3087 ClientToScreen (GDK_WINDOW_HWND (window), &point);
3088 rect.right = point.x;
3089 rect.bottom = point.y;
3091 GDK_NOTE (EVENTS, g_print (" (also BASE_SIZE, using %s)",
3092 _gdk_win32_rect_to_string (&rect)));
3095 switch (msg->wParam)
3098 if (drag->bottom == rect.bottom)
3100 adjust_drag (&drag->bottom, rect.bottom, impl->hints.height_inc);
3104 case WMSZ_BOTTOMLEFT:
3105 if (drag->bottom == rect.bottom && drag->left == rect.left)
3107 adjust_drag (&drag->bottom, rect.bottom, impl->hints.height_inc);
3108 adjust_drag (&drag->left, rect.left, impl->hints.width_inc);
3112 if (drag->left == rect.left)
3114 adjust_drag (&drag->left, rect.left, impl->hints.width_inc);
3118 if (drag->top == rect.top && drag->left == rect.left)
3120 adjust_drag (&drag->top, rect.top, impl->hints.height_inc);
3121 adjust_drag (&drag->left, rect.left, impl->hints.width_inc);
3125 if (drag->top == rect.top)
3127 adjust_drag (&drag->top, rect.top, impl->hints.height_inc);
3131 if (drag->top == rect.top && drag->right == rect.right)
3133 adjust_drag (&drag->top, rect.top, impl->hints.height_inc);
3134 adjust_drag (&drag->right, rect.right, impl->hints.width_inc);
3138 if (drag->right == rect.right)
3140 adjust_drag (&drag->right, rect.right, impl->hints.width_inc);
3143 case WMSZ_BOTTOMRIGHT:
3144 if (drag->bottom == rect.bottom && drag->right == rect.right)
3146 adjust_drag (&drag->bottom, rect.bottom, impl->hints.height_inc);
3147 adjust_drag (&drag->right, rect.right, impl->hints.width_inc);
3151 if (drag->bottom != orig_drag.bottom || drag->left != orig_drag.left ||
3152 drag->top != orig_drag.top || drag->right != orig_drag.right)
3156 GDK_NOTE (EVENTS, g_print (" (handled RESIZE_INC: drag:%s)",
3157 _gdk_win32_rect_to_string (drag)));
3161 /* WM_GETMINMAXINFO handles min_size and max_size hints? */
3163 if (impl->hint_flags & GDK_HINT_ASPECT)
3165 gdouble drag_aspect = (gdouble) (drag->right - drag->left) / (drag->bottom - drag->top);
3167 GDK_NOTE (EVENTS, g_print (" (aspect:%g)", drag_aspect));
3168 if (drag_aspect < impl->hints.min_aspect ||
3169 drag_aspect > impl->hints.max_aspect)
3174 GDK_NOTE (EVENTS, g_print (" (handled ASPECT: drag:%s)",
3175 _gdk_win32_rect_to_string (drag)));
3180 case WM_GETMINMAXINFO:
3181 if (GDK_WINDOW_DESTROYED (window))
3184 impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl);
3185 mmi = (MINMAXINFO*) msg->lParam;
3186 GDK_NOTE (EVENTS, g_print (" (mintrack:%ldx%ld maxtrack:%ldx%ld "
3187 "maxpos:+%ld+%ld maxsize:%ldx%ld)",
3188 mmi->ptMinTrackSize.x, mmi->ptMinTrackSize.y,
3189 mmi->ptMaxTrackSize.x, mmi->ptMaxTrackSize.y,
3190 mmi->ptMaxPosition.x, mmi->ptMaxPosition.y,
3191 mmi->ptMaxSize.x, mmi->ptMaxSize.y));
3193 if (impl->hint_flags & GDK_HINT_MIN_SIZE)
3195 rect.left = rect.top = 0;
3196 rect.right = impl->hints.min_width;
3197 rect.bottom = impl->hints.min_height;
3199 _gdk_win32_adjust_client_rect (window, &rect);
3201 mmi->ptMinTrackSize.x = rect.right - rect.left;
3202 mmi->ptMinTrackSize.y = rect.bottom - rect.top;
3205 if (impl->hint_flags & GDK_HINT_MAX_SIZE)
3209 rect.left = rect.top = 0;
3210 rect.right = impl->hints.max_width;
3211 rect.bottom = impl->hints.max_height;
3213 _gdk_win32_adjust_client_rect (window, &rect);
3215 /* at least on win9x we have the 16 bit trouble */
3216 maxw = rect.right - rect.left;
3217 maxh = rect.bottom - rect.top;
3218 mmi->ptMaxTrackSize.x = maxw > 0 && maxw < G_MAXSHORT ? maxw : G_MAXSHORT;
3219 mmi->ptMaxTrackSize.y = maxh > 0 && maxh < G_MAXSHORT ? maxw : G_MAXSHORT;
3222 if (impl->hint_flags & (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE))
3224 /* Don't call DefWindowProc() */
3225 GDK_NOTE (EVENTS, g_print (" (handled, mintrack:%ldx%ld maxtrack:%ldx%ld "
3226 "maxpos:+%ld+%ld maxsize:%ldx%ld)",
3227 mmi->ptMinTrackSize.x, mmi->ptMinTrackSize.y,
3228 mmi->ptMaxTrackSize.x, mmi->ptMaxTrackSize.y,
3229 mmi->ptMaxPosition.x, mmi->ptMaxPosition.y,
3230 mmi->ptMaxSize.x, mmi->ptMaxSize.y));
3236 GDK_NOTE (EVENTS, g_print (" (%d,%d)",
3237 GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
3239 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
3240 !IsIconic (msg->hwnd) &&
3241 IsWindowVisible (msg->hwnd))
3243 if (!GDK_WINDOW_DESTROYED (window))
3244 handle_configure_event (msg, window);
3251 if (GDK_WINDOW_DESTROYED (window))
3254 event = gdk_event_new (GDK_DELETE);
3255 event->any.window = window;
3257 append_event (display, event);
3263 if (window == current_window)
3264 assign_object (¤t_window, _gdk_parent_root);
3266 if (p_grab_window == window)
3267 gdk_pointer_ungrab (msg->time);
3269 if (k_grab_window == window)
3270 gdk_keyboard_ungrab (msg->time);
3272 if ((window != NULL) && (_gdk_root_window != msg->hwnd))
3273 gdk_window_destroy_notify (window);
3275 if (window == NULL || GDK_WINDOW_DESTROYED (window))
3278 event = gdk_event_new (GDK_DESTROY);
3279 event->any.window = window;
3281 append_event (display, event);
3286 case WM_DISPLAYCHANGE:
3287 handle_display_change ();
3292 /* Handle WINTAB events here, as we know that gdkinput.c will
3293 * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
3294 * constants as case labels.
3297 GDK_NOTE (EVENTS, g_print (" %d %#lx",
3298 msg->wParam, msg->lParam));
3302 GDK_NOTE (EVENTS, g_print (" %d %#lx",
3303 msg->wParam, msg->lParam));
3307 GDK_NOTE (EVENTS, g_print (" %#x %d %d",
3309 LOWORD (msg->lParam),
3310 HIWORD (msg->lParam)));
3314 event = gdk_event_new (GDK_NOTHING);
3315 event->any.window = window;
3316 g_object_ref (window);
3317 if (_gdk_input_other_event (event, msg, window))
3318 append_event (display, event);
3320 gdk_event_free (event);
3328 g_object_unref (window);
3335 _gdk_events_queue (GdkDisplay *display)
3339 while (!_gdk_event_queue_find_first (display) &&
3340 PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
3342 TranslateMessage (&msg);
3343 DispatchMessage (&msg);
3348 gdk_event_prepare (GSource *source,
3353 GdkDisplay *display = gdk_display_get_default ();
3355 GDK_THREADS_ENTER ();
3359 retval = (_gdk_event_queue_find_first (display) != NULL ||
3360 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE));
3362 GDK_THREADS_LEAVE ();
3368 gdk_event_check (GSource *source)
3372 GdkDisplay *display = gdk_display_get_default ();
3374 GDK_THREADS_ENTER ();
3376 if (event_poll_fd.revents & G_IO_IN)
3377 retval = (_gdk_event_queue_find_first (display) != NULL ||
3378 PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE));
3382 GDK_THREADS_LEAVE ();
3388 gdk_event_dispatch (GSource *source,
3389 GSourceFunc callback,
3393 GdkDisplay *display = gdk_display_get_default ();
3395 GDK_THREADS_ENTER ();
3397 _gdk_events_queue (display);
3398 event = _gdk_event_unqueue (display);
3402 if (_gdk_event_func)
3403 (*_gdk_event_func) (event, _gdk_event_data);
3405 gdk_event_free (event);
3408 GDK_THREADS_LEAVE ();
3414 check_for_too_much_data (GdkEvent *event)
3416 if (event->client.data.l[1] ||
3417 event->client.data.l[2] ||
3418 event->client.data.l[3] ||
3419 event->client.data.l[4])
3420 g_warning ("Only four bytes of data are passed in client messages on Win32\n");
3424 gdk_event_send_client_message_for_display (GdkDisplay *display,
3426 GdkNativeWindow winid)
3428 check_for_too_much_data (event);
3430 return PostMessage ((HWND) winid, client_message,
3431 (WPARAM) event->client.message_type,
3432 event->client.data.l[0]);
3436 gdk_screen_broadcast_client_message (GdkScreen *screen,
3439 check_for_too_much_data (event);
3441 PostMessage (HWND_BROADCAST, client_message,
3442 (WPARAM) event->client.message_type,
3443 event->client.data.l[0]);
3452 /* Process all messages currently available */
3453 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
3455 TranslateMessage (&msg);
3456 DispatchMessage (&msg);
3464 gdk_display_sync (GdkDisplay * display)
3468 g_return_if_fail (display == gdk_display_get_default ());
3470 /* Process all messages currently available */
3471 while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
3472 DispatchMessage (&msg);
3476 gdk_display_flush (GdkDisplay * display)
3478 g_return_if_fail (display == gdk_display_get_default ());
3484 gdk_net_wm_supports (GdkAtom property)