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/.
32 #include <gdk/gdkkeysyms.h>
36 #define PING() printf("%s: %d\n",__FILE__,__LINE__),fflush(stdout)
38 typedef struct _GdkIOClosure GdkIOClosure;
39 typedef struct _GdkEventPrivate GdkEventPrivate;
41 #define DOUBLE_CLICK_TIME 250
42 #define TRIPLE_CLICK_TIME 500
43 #define DOUBLE_CLICK_DIST 5
44 #define TRIPLE_CLICK_DIST 5
48 /* Following flag is set for events on the event queue during
49 * translation and cleared afterwards.
51 GDK_EVENT_PENDING = 1 << 0
56 GdkInputFunction function;
57 GdkInputCondition condition;
58 GdkDestroyNotify notify;
62 struct _GdkEventPrivate
69 * Private function declarations
72 static GdkEvent *gdk_event_new (void);
73 static gint gdk_event_apply_filters(MSG *xevent,
76 static gint gdk_event_translate (GdkEvent *event,
78 gboolean *ret_val_flagp,
80 static void gdk_events_queue (void);
81 static GdkEvent *gdk_event_unqueue (void);
82 static gboolean gdk_event_prepare (gpointer source_data,
83 GTimeVal *current_time,
85 static gboolean gdk_event_check (gpointer source_data,
86 GTimeVal *current_time);
87 static gboolean gdk_event_dispatch (gpointer source_data,
88 GTimeVal *current_time,
91 static void gdk_synthesize_click (GdkEvent *event,
94 /* Private variable declarations
97 static guint32 button_click_time[2]; /* The last 2 button click times. Used
98 * to determine if the latest button click
99 * is part of a double or triple click.
101 static GdkWindow *button_window[2]; /* The last 2 windows to receive button presses.
102 * Also used to determine if the latest button
103 * click is part of a double or triple click.
105 static guint button_number[2]; /* The last 2 buttons to be pressed.
107 static GdkWindowPrivate *p_grab_window = NULL; /* Window that currently
108 * holds the pointer grab
111 static GdkWindowPrivate *k_grab_window = NULL; /* Window the holds the
115 static GList *client_filters; /* Filters for client messages */
117 static gboolean p_grab_automatic;
118 static GdkEventMask p_grab_event_mask;
119 static gboolean p_grab_owner_events, k_grab_owner_events;
120 static HCURSOR p_grab_cursor;
122 static GdkEventFunc event_func = NULL; /* Callback for events */
123 static gpointer event_data = NULL;
124 static GDestroyNotify event_notify = NULL;
126 static GList *client_filters; /* Filters for client messages */
128 /* FIFO's for event queue, and for events put back using
131 static GList *queued_events = NULL;
132 static GList *queued_tail = NULL;
134 static GSourceFuncs event_funcs = {
138 (GDestroyNotify)g_free
141 GPollFD event_poll_fd;
143 static GdkWindow *curWnd = NULL;
144 static HWND active = NULL;
145 static gint curX, curY;
146 static gdouble curXroot, curYroot;
147 static UINT gdk_ping_msg;
148 static gboolean ignore_WM_CHAR = FALSE;
149 static gboolean is_AltGr_key = FALSE;
152 gdk_WindowProc(HWND hwnd,
162 gboolean ret_val_flag;
164 GDK_NOTE (EVENTS, g_print ("gdk_WindowProc: %#x\n", message));
167 msg.message = message;
170 msg.time = GetTickCount ();
171 pos = GetMessagePos ();
172 msg.pt.x = LOWORD (pos);
173 msg.pt.y = HIWORD (pos);
175 if (gdk_event_translate (&event, &msg, &ret_val_flag, &ret_val))
178 /* Compress configure events */
179 if (event.any.type == GDK_CONFIGURE)
181 GList *list = queued_events;
184 && (((GdkEvent *)list->data)->any.type != GDK_CONFIGURE
185 || ((GdkEvent *)list->data)->any.window != event.any.window))
189 *((GdkEvent *)list->data) = event;
190 gdk_window_unref (event.any.window);
191 /* Wake up WaitMessage */
192 PostMessage (NULL, gdk_ping_msg, 0, 0);
197 eventp = gdk_event_new ();
200 gdk_event_queue_append (eventp);
202 /* Wake up WaitMessage */
203 PostMessage (NULL, gdk_ping_msg, 0, 0);
214 return DefWindowProc (hwnd, message, wParam, lParam);
217 /*********************************************
218 * Functions for maintaining the event queue *
219 *********************************************/
221 /*************************************************************
222 * gdk_event_queue_find_first:
223 * Find the first event on the queue that is not still
228 * Pointer to the list node for that event, or NULL
229 *************************************************************/
232 gdk_event_queue_find_first (void)
234 GList *tmp_list = queued_events;
238 GdkEventPrivate *event = tmp_list->data;
239 if (!(event->flags & GDK_EVENT_PENDING))
242 tmp_list = g_list_next (tmp_list);
248 /*************************************************************
249 * gdk_event_queue_remove_link:
250 * Remove a specified list node from the event queue.
252 * node: Node to remove.
254 *************************************************************/
257 gdk_event_queue_remove_link (GList *node)
260 node->prev->next = node->next;
262 queued_events = node->next;
265 node->next->prev = node->prev;
267 queued_tail = node->prev;
271 /*************************************************************
272 * gdk_event_queue_append:
273 * Append an event onto the tail of the event queue.
275 * event: Event to append.
277 *************************************************************/
280 gdk_event_queue_append (GdkEvent *event)
282 queued_tail = g_list_append (queued_tail, event);
285 queued_events = queued_tail;
287 queued_tail = queued_tail->next;
291 gdk_events_init (void)
293 if (g_pipe_readable_msg == 0)
294 g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable");
296 g_source_add (GDK_PRIORITY_EVENTS, TRUE, &event_funcs, NULL, NULL, NULL);
298 event_poll_fd.fd = G_WIN32_MSG_HANDLE;
299 event_poll_fd.events = G_IO_IN;
301 g_main_add_poll (&event_poll_fd, GDK_PRIORITY_EVENTS);
303 button_click_time[0] = 0;
304 button_click_time[1] = 0;
305 button_window[0] = NULL;
306 button_window[1] = NULL;
307 button_number[0] = -1;
308 button_number[1] = -1;
310 gdk_ping_msg = RegisterWindowMessage ("gdk-ping");
314 *--------------------------------------------------------------
317 * Returns if events are pending on the queue.
322 * Returns TRUE if events are pending
326 *--------------------------------------------------------------
330 gdk_events_pending (void)
334 return (gdk_event_queue_find_first() || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE));
338 *--------------------------------------------------------------
339 * gdk_event_get_graphics_expose
341 * Waits for a GraphicsExpose or NoExpose event
346 * For GraphicsExpose events, returns a pointer to the event
347 * converted into a GdkEvent Otherwise, returns NULL.
351 *-------------------------------------------------------------- */
354 gdk_event_get_graphics_expose (GdkWindow *window)
358 GdkWindowPrivate *private = (GdkWindowPrivate *) window;
360 g_return_val_if_fail (window != NULL, NULL);
362 GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose\n"));
365 /* Some nasty bugs here, just return NULL for now. */
368 if (GetMessage (&xevent, private->xwindow, WM_PAINT, WM_PAINT))
370 event = gdk_event_new ();
372 if (gdk_event_translate (event, &xevent, NULL, NULL))
375 gdk_event_free (event);
382 /************************
383 * Exposure compression *
384 ************************/
386 /* I don't bother with exposure compression on Win32. Windows compresses
387 * WM_PAINT events by itself.
390 /*************************************************************
391 * gdk_event_handler_set:
394 * func: Callback function to be called for each event.
395 * data: Data supplied to the function
396 * notify: function called when function is no longer needed
399 *************************************************************/
402 gdk_event_handler_set (GdkEventFunc func,
404 GDestroyNotify notify)
407 (*event_notify) (event_data);
411 event_notify = notify;
415 *--------------------------------------------------------------
418 * Gets the next event.
423 * If an event is waiting that we care about, returns
424 * a pointer to that event, to be freed with gdk_event_free.
425 * Otherwise, returns NULL.
429 *--------------------------------------------------------------
437 return gdk_event_unqueue();
441 *--------------------------------------------------------------
444 * Gets the next event.
449 * If an event is waiting that we care about, returns
450 * a copy of that event, but does not remove it from
451 * the queue. The pointer is to be freed with gdk_event_free.
452 * Otherwise, returns NULL.
456 *--------------------------------------------------------------
460 gdk_event_peek (void)
464 tmp_list = gdk_event_queue_find_first ();
467 return gdk_event_copy (tmp_list->data);
473 gdk_event_put (GdkEvent *event)
478 g_return_if_fail (event != NULL);
480 new_event = gdk_event_copy (event);
482 gdk_event_queue_append (new_event);
486 *--------------------------------------------------------------
489 * Copy a event structure into new storage.
492 * "event" is the event struct to copy.
495 * A new event structure. Free it with gdk_event_free.
498 * The reference count of the window in the event is increased.
500 *--------------------------------------------------------------
503 static GMemChunk *event_chunk = NULL;
508 GdkEventPrivate *new_event;
510 if (event_chunk == NULL)
511 event_chunk = g_mem_chunk_new ("events",
512 sizeof (GdkEventPrivate),
516 new_event = g_chunk_new (GdkEventPrivate, event_chunk);
517 new_event->flags = 0;
519 return (GdkEvent *) new_event;
523 gdk_event_copy (GdkEvent *event)
527 g_return_val_if_fail (event != NULL, NULL);
529 new_event = gdk_event_new ();
532 gdk_window_ref (new_event->any.window);
534 switch (event->any.type)
537 case GDK_KEY_RELEASE:
538 new_event->key.string = g_strdup (event->key.string);
541 case GDK_ENTER_NOTIFY:
542 case GDK_LEAVE_NOTIFY:
543 if (event->crossing.subwindow != NULL)
544 gdk_window_ref (event->crossing.subwindow);
549 case GDK_DRAG_MOTION:
550 case GDK_DRAG_STATUS:
552 case GDK_DROP_FINISHED:
553 gdk_drag_context_ref (event->dnd.context);
564 *--------------------------------------------------------------
567 * Free a event structure obtained from gdk_event_copy. Do not use
568 * with other event structures.
571 * "event" is the event struct to free.
576 * The reference count of the window in the event is decreased and
577 * might be freed, too.
579 *-------------------------------------------------------------- */
582 gdk_event_free (GdkEvent *event)
584 g_return_if_fail (event != NULL);
586 g_assert (event_chunk != NULL); /* paranoid */
588 if (event->any.window)
589 gdk_window_unref (event->any.window);
591 switch (event->any.type)
594 case GDK_KEY_RELEASE:
595 g_free (event->key.string);
598 case GDK_ENTER_NOTIFY:
599 case GDK_LEAVE_NOTIFY:
600 if (event->crossing.subwindow != NULL)
601 gdk_window_unref (event->crossing.subwindow);
606 case GDK_DRAG_MOTION:
607 case GDK_DRAG_STATUS:
609 case GDK_DROP_FINISHED:
610 gdk_drag_context_unref (event->dnd.context);
617 g_mem_chunk_free (event_chunk, event);
621 *--------------------------------------------------------------
622 * gdk_event_get_time:
623 * Get the timestamp from an event.
627 * The event's time stamp, if it has one, otherwise
629 *--------------------------------------------------------------
633 gdk_event_get_time (GdkEvent *event)
638 case GDK_MOTION_NOTIFY:
639 return event->motion.time;
640 case GDK_BUTTON_PRESS:
641 case GDK_2BUTTON_PRESS:
642 case GDK_3BUTTON_PRESS:
643 case GDK_BUTTON_RELEASE:
644 return event->button.time;
646 case GDK_KEY_RELEASE:
647 return event->key.time;
648 case GDK_ENTER_NOTIFY:
649 case GDK_LEAVE_NOTIFY:
650 return event->crossing.time;
651 case GDK_PROPERTY_NOTIFY:
652 return event->property.time;
653 case GDK_SELECTION_CLEAR:
654 case GDK_SELECTION_REQUEST:
655 case GDK_SELECTION_NOTIFY:
656 return event->selection.time;
657 case GDK_PROXIMITY_IN:
658 case GDK_PROXIMITY_OUT:
659 return event->proximity.time;
662 case GDK_DRAG_MOTION:
663 case GDK_DRAG_STATUS:
665 case GDK_DROP_FINISHED:
666 return event->dnd.time;
667 default: /* use current time */
671 return GDK_CURRENT_TIME;
675 *--------------------------------------------------------------
676 * gdk_set_show_events
678 * Turns on/off the showing of events.
681 * "show_events" is a boolean describing whether or
682 * not to show the events gdk receives.
687 * When "show_events" is TRUE, calls to "gdk_event_get"
688 * will output debugging informatin regarding the event
689 * received to stdout.
691 *--------------------------------------------------------------
695 gdk_set_show_events (gint show_events)
698 gdk_debug_flags |= GDK_DEBUG_EVENTS;
700 gdk_debug_flags &= ~GDK_DEBUG_EVENTS;
704 gdk_get_show_events (void)
706 return gdk_debug_flags & GDK_DEBUG_EVENTS;
710 *--------------------------------------------------------------
713 * Grabs the pointer to a specific window
716 * "window" is the window which will receive the grab
717 * "owner_events" specifies whether events will be reported as is,
718 * or relative to "window"
719 * "event_mask" masks only interesting events
720 * "confine_to" limits the cursor movement to the specified window
721 * "cursor" changes the cursor for the duration of the grab
722 * "time" specifies the time
727 * requires a corresponding call to gdk_pointer_ungrab
729 *--------------------------------------------------------------
733 gdk_pointer_grab (GdkWindow * window,
735 GdkEventMask event_mask,
736 GdkWindow * confine_to,
740 GdkWindowPrivate *window_private;
744 GdkWindowPrivate *confine_to_private;
745 GdkCursorPrivate *cursor_private;
748 g_return_val_if_fail (window != NULL, 0);
750 window_private = (GdkWindowPrivate*) window;
751 confine_to_private = (GdkWindowPrivate*) confine_to;
752 cursor_private = (GdkCursorPrivate*) cursor;
754 xwindow = window_private->xwindow;
756 if (!confine_to || confine_to_private->destroyed)
759 xconfine_to = confine_to_private->xwindow;
764 xcursor = cursor_private->xcursor;
766 if (gdk_input_vtable.grab_pointer)
767 return_val = gdk_input_vtable.grab_pointer (window,
773 return_val = Success;
775 if (return_val == Success)
777 if (!window_private->destroyed)
779 GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x\n",
781 (owner_events ? "TRUE" : "FALSE"),
783 p_grab_event_mask = event_mask;
784 p_grab_owner_events = owner_events != 0;
785 p_grab_automatic = FALSE;
787 #if 0 /* Menus don't work if we use mouse capture. Pity, because many other
788 * things work better with mouse capture.
790 SetCapture (xwindow);
792 return_val = GrabSuccess;
795 return_val = AlreadyGrabbed;
798 if (return_val == GrabSuccess)
800 p_grab_window = window_private;
801 p_grab_cursor = xcursor;
808 *--------------------------------------------------------------
811 * Releases any pointer grab
819 *--------------------------------------------------------------
823 gdk_pointer_ungrab (guint32 time)
825 if (gdk_input_vtable.ungrab_pointer)
826 gdk_input_vtable.ungrab_pointer (time);
828 if (GetCapture () != NULL)
831 GDK_NOTE (EVENTS, g_print ("gdk_pointer_ungrab\n"));
833 p_grab_window = NULL;
837 *--------------------------------------------------------------
838 * gdk_pointer_is_grabbed
840 * Tell wether there is an active x pointer grab in effect
848 *--------------------------------------------------------------
852 gdk_pointer_is_grabbed (void)
854 return p_grab_window != NULL;
858 *--------------------------------------------------------------
861 * Grabs the keyboard to a specific window
864 * "window" is the window which will receive the grab
865 * "owner_events" specifies whether events will be reported as is,
866 * or relative to "window"
867 * "time" specifies the time
872 * requires a corresponding call to gdk_keyboard_ungrab
874 *--------------------------------------------------------------
878 gdk_keyboard_grab (GdkWindow * window,
882 GdkWindowPrivate *window_private;
885 g_return_val_if_fail (window != NULL, 0);
887 window_private = (GdkWindowPrivate*) window;
889 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_grab %#x\n",
890 window_private->xwindow));
892 if (!window_private->destroyed)
894 k_grab_owner_events = owner_events != 0;
895 return_val = GrabSuccess;
898 return_val = AlreadyGrabbed;
900 if (return_val == GrabSuccess)
901 k_grab_window = window_private;
907 *--------------------------------------------------------------
908 * gdk_keyboard_ungrab
910 * Releases any keyboard grab
918 *--------------------------------------------------------------
922 gdk_keyboard_ungrab (guint32 time)
924 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_ungrab\n"));
926 k_grab_window = NULL;
930 gdk_io_destroy (gpointer data)
932 GdkIOClosure *closure = data;
935 closure->notify (closure->data);
941 gdk_io_invoke (GIOChannel *source,
942 GIOCondition condition,
945 GdkIOClosure *closure = data;
946 GdkInputCondition gdk_cond = 0;
948 if (condition & (G_IO_IN | G_IO_PRI))
949 gdk_cond |= GDK_INPUT_READ;
950 if (condition & G_IO_OUT)
951 gdk_cond |= GDK_INPUT_WRITE;
952 if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
953 gdk_cond |= GDK_INPUT_EXCEPTION;
955 if (closure->condition & gdk_cond)
956 closure->function (closure->data, g_io_channel_unix_get_fd (source), gdk_cond);
962 gdk_input_add_full (gint source,
963 GdkInputCondition condition,
964 GdkInputFunction function,
966 GdkDestroyNotify destroy)
969 GdkIOClosure *closure = g_new (GdkIOClosure, 1);
971 GIOCondition cond = 0;
973 closure->function = function;
974 closure->condition = condition;
975 closure->notify = destroy;
976 closure->data = data;
978 if (condition & GDK_INPUT_READ)
979 cond |= (G_IO_IN | G_IO_PRI);
980 if (condition & GDK_INPUT_WRITE)
982 if (condition & GDK_INPUT_EXCEPTION)
983 cond |= G_IO_ERR|G_IO_HUP|G_IO_NVAL;
985 channel = g_io_channel_unix_new (source);
986 result = g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, cond,
988 closure, gdk_io_destroy);
989 g_io_channel_unref (channel);
995 gdk_input_add (gint source,
996 GdkInputCondition condition,
997 GdkInputFunction function,
1000 return gdk_input_add_full (source, condition, function, data, NULL);
1004 gdk_input_remove (gint tag)
1006 g_source_remove (tag);
1010 gdk_event_apply_filters (MSG *xevent,
1014 GdkEventFilter *filter;
1016 GdkFilterReturn result;
1022 filter = (GdkEventFilter *) tmp_list->data;
1024 result = (*filter->function) (xevent, event, filter->data);
1025 if (result != GDK_FILTER_CONTINUE)
1028 tmp_list = tmp_list->next;
1031 return GDK_FILTER_CONTINUE;
1035 gdk_add_client_message_filter (GdkAtom message_type,
1039 GdkClientFilter *filter = g_new (GdkClientFilter, 1);
1041 filter->type = message_type;
1042 filter->function = func;
1043 filter->data = data;
1045 client_filters = g_list_prepend (client_filters, filter);
1049 synthesize_crossing_events (GdkWindow *window,
1053 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
1054 GdkWindowPrivate *curWnd_private = (GdkWindowPrivate *) curWnd;
1056 if (curWnd && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
1058 GDK_NOTE (EVENTS, g_print ("synthesizing LEAVE_NOTIFY event\n"));
1060 event = gdk_event_new ();
1061 event->crossing.type = GDK_LEAVE_NOTIFY;
1062 event->crossing.window = curWnd;
1063 gdk_window_ref (event->crossing.window);
1064 event->crossing.subwindow = NULL;
1065 event->crossing.time = xevent->time;
1066 event->crossing.x = curX;
1067 event->crossing.y = curY;
1068 event->crossing.x_root = curXroot;
1069 event->crossing.y_root = curYroot;
1070 event->crossing.mode = GDK_CROSSING_NORMAL;
1071 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
1073 event->crossing.focus = TRUE; /* ??? */
1074 event->crossing.state = 0; /* ??? */
1076 gdk_event_queue_append (event);
1079 if (window_private && (window_private->event_mask & GDK_ENTER_NOTIFY_MASK))
1081 GDK_NOTE (EVENTS, g_print ("synthesizing ENTER_NOTIFY event\n"));
1083 event = gdk_event_new ();
1084 event->crossing.type = GDK_ENTER_NOTIFY;
1085 event->crossing.window = window;
1086 gdk_window_ref (event->crossing.window);
1087 event->crossing.subwindow = NULL;
1088 event->crossing.time = xevent->time;
1089 event->crossing.x = LOWORD (xevent->lParam);
1090 event->crossing.y = HIWORD (xevent->lParam);
1091 event->crossing.x_root = (gfloat) xevent->pt.x;
1092 event->crossing.y_root = (gfloat) xevent->pt.y;
1093 event->crossing.mode = GDK_CROSSING_NORMAL;
1094 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
1096 event->crossing.focus = TRUE; /* ??? */
1097 event->crossing.state = 0; /* ??? */
1099 gdk_event_queue_append (event);
1101 if (window_private->extension_events != 0
1102 && gdk_input_vtable.enter_event)
1103 gdk_input_vtable.enter_event (&event->crossing, window);
1107 gdk_window_unref (curWnd);
1109 gdk_window_ref (curWnd);
1113 gdk_event_translate (GdkEvent *event,
1115 gboolean *ret_val_flagp,
1119 GdkWindowPrivate *window_private;
1121 GdkColormapPrivate *colormap_private;
1124 PAINTSTRUCT paintstruct;
1129 GdkWindowPrivate *curWnd_private;
1141 *ret_val_flagp = FALSE;
1143 if (xevent->message == gdk_ping_msg)
1145 /* Messages we post ourselves just to wakeup WaitMessage. */
1149 window = gdk_window_lookup (xevent->hwnd);
1150 window_private = (GdkWindowPrivate *) window;
1152 if (xevent->message == g_pipe_readable_msg)
1154 GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n",
1155 xevent->wParam, xevent->lParam));
1157 g_io_channel_win32_pipe_readable (xevent->wParam, xevent->lParam);
1162 gdk_window_ref (window);
1165 /* Handle WM_QUIT here ? */
1166 if (xevent->message == WM_QUIT)
1168 GDK_NOTE (EVENTS, g_print ("WM_QUIT: %d\n", xevent->wParam));
1169 exit (xevent->wParam);
1171 else if (xevent->message == WM_MOVE
1172 || xevent->message == WM_SIZE)
1174 /* It's quite normal to get these messages before we have
1175 * had time to register the window in our lookup table, or
1176 * when the window is being destroyed and we already have
1177 * removed it. Repost the same message to our queue so that
1178 * we will get it later when we are prepared.
1180 PostMessage (xevent->hwnd, xevent->message,
1181 xevent->wParam, xevent->lParam);
1183 else if (xevent->message == WM_NCCREATE
1184 || xevent->message == WM_CREATE
1185 || xevent->message == WM_GETMINMAXINFO
1186 || xevent->message == WM_NCCALCSIZE
1187 || xevent->message == WM_NCDESTROY
1188 || xevent->message == WM_DESTROY)
1195 event->any.window = window;
1197 if (window_private && window_private->destroyed)
1202 /* Check for filters for this window */
1203 GdkFilterReturn result;
1204 result = gdk_event_apply_filters (xevent, event,
1206 ?window_private->filters
1207 :gdk_default_filters);
1209 if (result != GDK_FILTER_CONTINUE)
1211 return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
1215 if (xevent->message == gdk_selection_notify_msg)
1217 GDK_NOTE (SELECTION, g_print ("gdk_selection_notify_msg: %#x\n",
1220 event->selection.type = GDK_SELECTION_NOTIFY;
1221 event->selection.window = window;
1222 event->selection.selection = xevent->wParam;
1223 event->selection.target = xevent->lParam;
1224 event->selection.property = gdk_selection_property;
1225 event->selection.time = xevent->time;
1227 return_val = window_private && !window_private->destroyed;
1229 /* Will pass through switch below without match */
1231 else if (xevent->message == gdk_selection_request_msg)
1233 GDK_NOTE (SELECTION, g_print ("gdk_selection_request_msg: %#x\n",
1236 event->selection.type = GDK_SELECTION_REQUEST;
1237 event->selection.window = window;
1238 event->selection.selection = gdk_clipboard_atom;
1239 event->selection.target = GDK_TARGET_STRING;
1240 event->selection.property = gdk_selection_property;
1241 event->selection.requestor = (guint32) xevent->hwnd;
1242 event->selection.time = xevent->time;
1244 return_val = window_private && !window_private->destroyed;
1246 /* Again, will pass through switch below without match */
1248 else if (xevent->message == gdk_selection_clear_msg)
1250 GDK_NOTE (SELECTION, g_print ("gdk_selection_clear_msg: %#x\n",
1253 event->selection.type = GDK_SELECTION_CLEAR;
1254 event->selection.window = window;
1255 event->selection.selection = xevent->wParam;
1256 event->selection.time = xevent->time;
1258 return_val = window_private && !window_private->destroyed;
1260 /* Once again, we will pass through switch below without match */
1265 GdkFilterReturn result = GDK_FILTER_CONTINUE;
1267 tmp_list = client_filters;
1270 GdkClientFilter *filter = tmp_list->data;
1271 if (filter->type == xevent->message)
1273 GDK_NOTE (EVENTS, g_print ("client filter matched\n"));
1274 result = (*filter->function) (xevent, event, filter->data);
1277 case GDK_FILTER_REMOVE:
1281 case GDK_FILTER_TRANSLATE:
1285 case GDK_FILTER_CONTINUE:
1287 event->client.type = GDK_CLIENT_EVENT;
1288 event->client.window = window;
1289 event->client.message_type = xevent->message;
1290 event->client.data_format = 0;
1291 event->client.data.l[0] = xevent->wParam;
1292 event->client.data.l[1] = xevent->lParam;
1295 goto bypass_switch; /* Ouch */
1297 tmp_list = tmp_list->next;
1301 switch (xevent->message)
1306 g_print ("WM_SYSKEY%s: %#x key: %s %#x %#.08x\n",
1307 (xevent->message == WM_SYSKEYUP ? "UP" : "DOWN"),
1309 (GetKeyNameText (xevent->lParam, buf,
1315 /* Let the system handle Alt-Tab and Alt-Enter */
1316 if (xevent->wParam == VK_TAB
1317 || xevent->wParam == VK_RETURN
1318 || xevent->wParam == VK_F4)
1320 /* If posted without us having keyboard focus, ignore */
1321 if (!(xevent->lParam & 0x20000000))
1324 /* don't generate events for just the Alt key */
1325 if (xevent->wParam == VK_MENU)
1328 /* Jump to code in common with WM_KEYUP and WM_KEYDOWN */
1334 g_print ("WM_KEY%s: %#x key: %s %#x %#.08x\n",
1335 (xevent->message == WM_KEYUP ? "UP" : "DOWN"),
1337 (GetKeyNameText (xevent->lParam, buf,
1343 ignore_WM_CHAR = TRUE;
1345 if (k_grab_window != NULL
1346 && !k_grab_owner_events)
1348 /* Keyboard is grabbed with owner_events FALSE */
1350 g_print ("...grabbed, owner_events FALSE, "
1351 "sending to %#x\n", k_grab_window->xwindow));
1352 event->key.window = (GdkWindow *) k_grab_window;
1354 else if (window_private
1355 && (((xevent->message == WM_KEYUP
1356 || xevent->message == WM_SYSKEYUP)
1357 && !(window_private->event_mask & GDK_KEY_RELEASE_MASK))
1358 || ((xevent->message == WM_KEYDOWN
1359 || xevent->message == WM_SYSKEYDOWN)
1360 && !(window_private->event_mask & GDK_KEY_PRESS_MASK))))
1362 /* Owner window doesn't want it */
1363 if (k_grab_window != NULL
1364 && k_grab_owner_events)
1366 /* Keyboard is grabbed with owner_events TRUE */
1368 g_print ("...grabbed, owner_events TRUE, doesn't want it, "
1369 "sending to %#x\n", k_grab_window->xwindow));
1370 event->key.window = (GdkWindow *) k_grab_window;
1374 /* Owner doesn't want it, neither is it grabbed, so
1375 * propagate to parent.
1377 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1379 gdk_window_unref (window);
1380 window = window_private->parent;
1381 gdk_window_ref (window);
1382 window_private = (GdkWindowPrivate *) window;
1383 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1384 window_private->xwindow));
1389 switch (xevent->wParam)
1392 event->key.keyval = GDK_Pointer_Button1; break;
1394 event->key.keyval = GDK_Pointer_Button3; break;
1396 event->key.keyval = GDK_Pointer_Button2; break;
1398 event->key.keyval = GDK_Cancel; break;
1400 event->key.keyval = GDK_BackSpace; break;
1402 event->key.keyval = GDK_Tab; break;
1404 event->key.keyval = GDK_Clear; break;
1406 event->key.keyval = GDK_Return; break;
1408 event->key.keyval = GDK_Shift_L; break;
1410 if (xevent->lParam & 0x01000000)
1411 event->key.keyval = GDK_Control_R;
1413 event->key.keyval = GDK_Control_L;
1416 if (xevent->lParam & 0x01000000)
1418 /* AltGr key comes in as Control+Right Alt */
1419 if (GetKeyState (VK_CONTROL) < 0)
1421 ignore_WM_CHAR = FALSE;
1422 is_AltGr_key = TRUE;
1424 event->key.keyval = GDK_Alt_R;
1427 event->key.keyval = GDK_Alt_L;
1430 event->key.keyval = GDK_Pause; break;
1432 event->key.keyval = GDK_Caps_Lock; break;
1434 event->key.keyval = GDK_Escape; break;
1436 event->key.keyval = GDK_Prior; break;
1438 event->key.keyval = GDK_Next; break;
1440 event->key.keyval = GDK_End; break;
1442 event->key.keyval = GDK_Home; break;
1444 event->key.keyval = GDK_Left; break;
1446 event->key.keyval = GDK_Up; break;
1448 event->key.keyval = GDK_Right; break;
1450 event->key.keyval = GDK_Down; break;
1452 event->key.keyval = GDK_Select; break;
1454 event->key.keyval = GDK_Print; break;
1456 event->key.keyval = GDK_Execute; break;
1458 event->key.keyval = GDK_Insert; break;
1460 event->key.keyval = GDK_Delete; break;
1462 event->key.keyval = GDK_Help; break;
1473 /* Apparently applications work better if we just pass numpad digits
1474 * on as real digits? So wait for the WM_CHAR instead.
1476 ignore_WM_CHAR = FALSE;
1479 event->key.keyval = GDK_KP_Multiply; break;
1481 event->key.keyval = GDK_KP_Add; break;
1483 event->key.keyval = GDK_KP_Separator; break;
1485 event->key.keyval = GDK_KP_Subtract; break;
1488 event->key.keyval = GDK_KP_Decimal; break;
1490 /* The keypad decimal key should also be passed on as the decimal
1491 * sign ('.' or ',' depending on the Windows locale settings,
1492 * apparently). So wait for the WM_CHAR here, also.
1494 ignore_WM_CHAR = FALSE;
1498 event->key.keyval = GDK_KP_Divide; break;
1500 event->key.keyval = GDK_F1; break;
1502 event->key.keyval = GDK_F2; break;
1504 event->key.keyval = GDK_F3; break;
1506 event->key.keyval = GDK_F4; break;
1508 event->key.keyval = GDK_F5; break;
1510 event->key.keyval = GDK_F6; break;
1512 event->key.keyval = GDK_F7; break;
1514 event->key.keyval = GDK_F8; break;
1516 event->key.keyval = GDK_F9; break;
1518 event->key.keyval = GDK_F10; break;
1520 event->key.keyval = GDK_F11; break;
1522 event->key.keyval = GDK_F12; break;
1524 event->key.keyval = GDK_F13; break;
1526 event->key.keyval = GDK_F14; break;
1528 event->key.keyval = GDK_F15; break;
1530 event->key.keyval = GDK_F16; break;
1541 if (GetKeyState (VK_CONTROL) < 0)
1542 /* Control-digits won't come in as a WM_CHAR */
1543 event->key.keyval = GDK_0 + (xevent->wParam - '0');
1546 ignore_WM_CHAR = FALSE;
1547 event->key.keyval = GDK_VoidSymbol;
1551 if (xevent->message == WM_SYSKEYDOWN || xevent->message == WM_SYSKEYUP)
1553 event->key.keyval = xevent->wParam;
1557 ignore_WM_CHAR = FALSE;
1558 event->key.keyval = GDK_VoidSymbol;
1563 if (!ignore_WM_CHAR)
1566 is_AltGr_key = FALSE;
1567 event->key.type = ((xevent->message == WM_KEYDOWN
1568 || xevent->message == WM_SYSKEYDOWN) ?
1569 GDK_KEY_PRESS : GDK_KEY_RELEASE);
1570 event->key.window = window;
1571 event->key.time = xevent->time;
1572 event->key.state = 0;
1573 if (GetKeyState (VK_SHIFT) < 0)
1574 event->key.state |= GDK_SHIFT_MASK;
1575 if (GetKeyState (VK_CAPITAL) & 0x1)
1576 event->key.state |= GDK_LOCK_MASK;
1577 if (GetKeyState (VK_CONTROL) < 0)
1578 event->key.state |= GDK_CONTROL_MASK;
1579 if (xevent->wParam != VK_MENU && GetKeyState (VK_MENU) < 0)
1580 event->key.state |= GDK_MOD1_MASK;
1581 event->key.length = 0;
1582 return_val = window_private && !window_private->destroyed;
1583 event->key.string = NULL;
1588 g_print ("WM_CHAR: %#x char: %#x %#.08x %s\n",
1592 (ignore_WM_CHAR ? "ignored" : "")));
1596 ignore_WM_CHAR = FALSE;
1601 /* This doesn't handle the rather theorethical case that a window
1602 * wants key presses but still wants releases to be propagated,
1605 if (k_grab_window != NULL
1606 && !k_grab_owner_events)
1608 /* Keyboard is grabbed with owner_events FALSE */
1610 g_print ("...grabbed, owner_events FALSE, "
1611 "sending to %#x\n", k_grab_window->xwindow));
1612 event->key.window = (GdkWindow *) k_grab_window;
1614 else if (window_private
1615 && !(window_private->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)))
1617 /* Owner window doesn't want it */
1618 if (k_grab_window != NULL
1619 && k_grab_owner_events)
1621 /* Keyboard is grabbed with owner_events TRUE */
1623 g_print ("...grabbed, owner_events TRUE, doesn't want it, "
1624 "sending to %#x\n", k_grab_window->xwindow));
1625 event->key.window = (GdkWindow *) k_grab_window;
1629 /* Owner doesn't want it, neither is it grabbed, so
1630 * propagate to parent.
1632 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1633 g_assert_not_reached (); /* Should've been handled above */
1635 gdk_window_unref (window);
1636 window = window_private->parent;
1637 gdk_window_ref (window);
1638 window_private = (GdkWindowPrivate *) window;
1639 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1640 window_private->xwindow));
1645 return_val = window_private && !window_private->destroyed;
1646 if (return_val && (window_private->event_mask & GDK_KEY_RELEASE_MASK))
1648 /* Return the release event, and maybe append the press
1649 * event to the queued_events list (from which it will vbe
1650 * fetched before the release event).
1652 event->key.type = GDK_KEY_RELEASE;
1653 event->key.keyval = xevent->wParam;
1654 event->key.window = window;
1655 event->key.time = xevent->time;
1656 event->key.state = 0;
1657 if (GetKeyState (VK_SHIFT) < 0)
1658 event->key.state |= GDK_SHIFT_MASK;
1659 if (GetKeyState (VK_CAPITAL) & 0x1)
1660 event->key.state |= GDK_LOCK_MASK;
1663 else if (GetKeyState (VK_CONTROL) < 0)
1665 event->key.state |= GDK_CONTROL_MASK;
1666 if (event->key.keyval < ' ')
1667 event->key.keyval += '@';
1669 else if (event->key.keyval < ' ')
1671 event->key.state |= GDK_CONTROL_MASK;
1672 event->key.keyval += '@';
1674 if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
1675 event->key.state |= GDK_MOD1_MASK;
1676 event->key.string = g_strdup (" ");
1677 event->key.length = 1;
1678 event->key.string[0] = xevent->wParam; /* ??? */
1680 if (window_private->event_mask & GDK_KEY_PRESS_MASK)
1682 /* Append also a GDK_KEY_PRESS event to the pushback list. */
1683 GdkEvent *event2 = gdk_event_copy (event);
1684 event2->key.type = GDK_KEY_PRESS;
1685 charcount = xevent->lParam & 0xFFFF;
1686 if (charcount > sizeof (buf)- 1)
1687 charcount = sizeof (buf) - 1;
1688 g_free (event2->key.string);
1689 event2->key.string = g_malloc (charcount);
1690 for (i = 0; i < charcount; i++)
1691 event2->key.string[i] = event->key.keyval;
1692 event2->key.length = charcount;
1694 gdk_event_queue_append (event2);
1697 else if (return_val && (window_private->event_mask & GDK_KEY_PRESS_MASK))
1699 /* Return just the GDK_KEY_PRESS event. */
1700 event->key.type = GDK_KEY_PRESS;
1701 charcount = xevent->lParam & 0xFFFF;
1702 if (charcount > sizeof (buf)- 1)
1703 charcount = sizeof (buf) - 1;
1704 event->key.keyval = xevent->wParam;
1705 event->key.window = window;
1706 event->key.time = xevent->time;
1707 event->key.state = 0;
1708 if (GetKeyState (VK_SHIFT) < 0)
1709 event->key.state |= GDK_SHIFT_MASK;
1710 if (GetKeyState (VK_CAPITAL) & 0x1)
1711 event->key.state |= GDK_LOCK_MASK;
1714 else if (GetKeyState (VK_CONTROL) < 0)
1716 event->key.state |= GDK_CONTROL_MASK;
1717 if (event->key.keyval < ' ')
1718 event->key.keyval += '@';
1720 else if (event->key.keyval < ' ')
1722 event->key.state |= GDK_CONTROL_MASK;
1723 event->key.keyval += '@';
1725 if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
1726 event->key.state |= GDK_MOD1_MASK;
1727 event->key.string = g_malloc (charcount);
1728 for (i = 0; i < charcount; i++)
1729 event->key.string[i] = event->key.keyval;
1730 event->key.length = charcount;
1734 is_AltGr_key = FALSE;
1737 case WM_LBUTTONDOWN:
1740 case WM_MBUTTONDOWN:
1743 case WM_RBUTTONDOWN:
1748 g_print ("WM_%cBUTTONDOWN: %#x x,y: %d %d button: %d\n",
1751 LOWORD (xevent->lParam), HIWORD (xevent->lParam),
1755 && (window_private->extension_events != 0)
1756 && gdk_input_ignore_core)
1758 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1762 event->button.type = GDK_BUTTON_PRESS;
1764 event->button.window = window;
1766 mask = window_private->event_mask;
1770 if (p_grab_window != NULL
1771 && !p_grab_owner_events)
1773 /* Pointer is grabbed with owner_events FALSE */
1774 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
1775 mask = p_grab_event_mask;
1776 if (!(mask & GDK_BUTTON_PRESS_MASK))
1777 /* Grabber doesn't want it */
1780 event->button.window = (GdkWindow *) p_grab_window;
1781 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1782 p_grab_window->xwindow));
1784 else if (window_private
1785 && !(mask & GDK_BUTTON_PRESS_MASK))
1787 /* Owner window doesn't want it */
1788 if (p_grab_window != NULL
1789 && p_grab_owner_events)
1791 /* Pointer is grabbed wÃth owner_events TRUE */
1792 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
1793 mask = p_grab_event_mask;
1794 if (!(mask & GDK_BUTTON_PRESS_MASK))
1795 /* Grabber doesn't want it either */
1798 event->button.window = (GdkWindow *) p_grab_window;
1799 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1800 p_grab_window->xwindow));
1804 /* Owner doesn't want it, neither is it grabbed, so
1805 * propagate to parent.
1807 /* Yes, this code is duplicated twice below. So shoot me. */
1808 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1810 pt.x = LOWORD (xevent->lParam);
1811 pt.y = HIWORD (xevent->lParam);
1812 ClientToScreen (window_private->xwindow, &pt);
1813 gdk_window_unref (window);
1814 window = window_private->parent;
1815 gdk_window_ref (window);
1816 window_private = (GdkWindowPrivate *) window;
1817 ScreenToClient (window_private->xwindow, &pt);
1818 xevent->lParam = MAKELPARAM (pt.x, pt.y);
1819 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1820 window_private->xwindow));
1821 goto buttondown; /* What did Dijkstra say? */
1825 /* Emulate X11's automatic active grab */
1828 /* No explicit active grab, let's start one automatically */
1829 GDK_NOTE (EVENTS, g_print ("...automatic grab started\n"));
1830 gdk_pointer_grab (window, TRUE, window_private->event_mask,
1832 p_grab_automatic = TRUE;
1835 if (window != curWnd)
1836 synthesize_crossing_events (window, xevent);
1838 event->button.time = xevent->time;
1839 event->button.x = LOWORD (xevent->lParam);
1840 event->button.y = HIWORD (xevent->lParam);
1841 event->button.x_root = (gfloat)xevent->pt.x;
1842 event->button.y_root = (gfloat)xevent->pt.y;
1843 event->button.pressure = 0.5;
1844 event->button.xtilt = 0;
1845 event->button.ytilt = 0;
1846 event->button.state = 0;
1847 if (xevent->wParam & MK_CONTROL)
1848 event->button.state |= GDK_CONTROL_MASK;
1849 if (xevent->wParam & MK_LBUTTON)
1850 event->button.state |= GDK_BUTTON1_MASK;
1851 if (xevent->wParam & MK_MBUTTON)
1852 event->button.state |= GDK_BUTTON2_MASK;
1853 if (xevent->wParam & MK_RBUTTON)
1854 event->button.state |= GDK_BUTTON3_MASK;
1855 if (xevent->wParam & MK_SHIFT)
1856 event->button.state |= GDK_SHIFT_MASK;
1857 if (GetKeyState (VK_MENU) < 0)
1858 event->button.state |= GDK_MOD1_MASK;
1859 if (GetKeyState (VK_CAPITAL) & 0x1)
1860 event->button.state |= GDK_LOCK_MASK;
1861 event->button.button = button;
1862 event->button.source = GDK_SOURCE_MOUSE;
1863 event->button.deviceid = GDK_CORE_POINTER;
1865 if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) &&
1866 (event->button.window == button_window[1]) &&
1867 (event->button.button == button_number[1]))
1869 gdk_synthesize_click (event, 3);
1871 button_click_time[1] = 0;
1872 button_click_time[0] = 0;
1873 button_window[1] = NULL;
1874 button_window[0] = 0;
1875 button_number[1] = -1;
1876 button_number[0] = -1;
1878 else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) &&
1879 (event->button.window == button_window[0]) &&
1880 (event->button.button == button_number[0]))
1882 gdk_synthesize_click (event, 2);
1884 button_click_time[1] = button_click_time[0];
1885 button_click_time[0] = event->button.time;
1886 button_window[1] = button_window[0];
1887 button_window[0] = event->button.window;
1888 button_number[1] = button_number[0];
1889 button_number[0] = event->button.button;
1893 button_click_time[1] = 0;
1894 button_click_time[0] = event->button.time;
1895 button_window[1] = NULL;
1896 button_window[0] = event->button.window;
1897 button_number[1] = -1;
1898 button_number[0] = event->button.button;
1900 return_val = window_private && !window_private->destroyed;
1902 && p_grab_window != NULL
1903 && event->any.window == (GdkWindow *) p_grab_window
1904 && p_grab_window != window_private)
1906 /* Translate coordinates to grabber */
1907 pt.x = event->button.x;
1908 pt.y = event->button.y;
1909 ClientToScreen (window_private->xwindow, &pt);
1910 ScreenToClient (p_grab_window->xwindow, &pt);
1911 event->button.x = pt.x;
1912 event->button.y = pt.y;
1913 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
1928 g_print ("WM_%cBUTTONUP: %#x x,y: %d %d button: %d\n",
1931 LOWORD (xevent->lParam), HIWORD (xevent->lParam),
1935 && (window_private->extension_events != 0)
1936 && gdk_input_ignore_core)
1938 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1942 event->button.type = GDK_BUTTON_RELEASE;
1944 event->button.window = window;
1946 mask = window_private->event_mask;
1950 if (p_grab_window != NULL
1951 && !p_grab_owner_events)
1953 /* Pointer is grabbed with owner_events FALSE */
1954 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
1955 mask = p_grab_event_mask;
1956 if (!(mask & GDK_BUTTON_RELEASE_MASK))
1957 /* Grabber doesn't want it */
1960 event->button.window = (GdkWindow *) p_grab_window;
1961 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1962 p_grab_window->xwindow));
1964 else if (window_private
1965 && !(mask & GDK_BUTTON_RELEASE_MASK))
1967 /* Owner window doesn't want it */
1968 if (p_grab_window != NULL
1969 && p_grab_owner_events)
1971 /* Pointer is grabbed wÃth owner_events TRUE */
1972 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
1973 mask = p_grab_event_mask;
1974 if (!(mask & GDK_BUTTON_RELEASE_MASK))
1975 /* Grabber doesn't want it */
1978 event->button.window = (GdkWindow *) p_grab_window;
1979 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1980 p_grab_window->xwindow));
1984 /* Owner doesn't want it, neither is it grabbed, so
1985 * propagate to parent.
1987 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1989 pt.x = LOWORD (xevent->lParam);
1990 pt.y = HIWORD (xevent->lParam);
1991 ClientToScreen (window_private->xwindow, &pt);
1992 gdk_window_unref (window);
1993 window = window_private->parent;
1994 gdk_window_ref (window);
1995 window_private = (GdkWindowPrivate *) window;
1996 ScreenToClient (window_private->xwindow, &pt);
1997 xevent->lParam = MAKELPARAM (pt.x, pt.y);
1998 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1999 window_private->xwindow));
2004 if (window != curWnd)
2005 synthesize_crossing_events (window, xevent);
2007 event->button.time = xevent->time;
2008 event->button.x = LOWORD (xevent->lParam);
2009 event->button.y = HIWORD (xevent->lParam);
2010 event->button.x_root = (gfloat)xevent->pt.x;
2011 event->button.y_root = (gfloat)xevent->pt.y;
2012 event->button.pressure = 0.5;
2013 event->button.xtilt = 0;
2014 event->button.ytilt = 0;
2015 event->button.state = 0;
2016 if (xevent->wParam & MK_CONTROL)
2017 event->button.state |= GDK_CONTROL_MASK;
2018 if (xevent->wParam & MK_LBUTTON)
2019 event->button.state |= GDK_BUTTON1_MASK;
2020 if (xevent->wParam & MK_MBUTTON)
2021 event->button.state |= GDK_BUTTON2_MASK;
2022 if (xevent->wParam & MK_RBUTTON)
2023 event->button.state |= GDK_BUTTON3_MASK;
2024 if (xevent->wParam & MK_SHIFT)
2025 event->button.state |= GDK_SHIFT_MASK;
2026 event->button.button = button;
2027 event->button.source = GDK_SOURCE_MOUSE;
2028 event->button.deviceid = GDK_CORE_POINTER;
2029 return_val = window_private && !window_private->destroyed;
2031 && p_grab_window != NULL
2032 && event->any.window == (GdkWindow *) p_grab_window
2033 && p_grab_window != window_private)
2035 /* Translate coordinates to grabber */
2036 pt.x = event->button.x;
2037 pt.y = event->button.y;
2038 ClientToScreen (window_private->xwindow, &pt);
2039 ScreenToClient (p_grab_window->xwindow, &pt);
2040 event->button.x = pt.x;
2041 event->button.y = pt.y;
2042 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
2044 if (p_grab_window != NULL
2046 && (event->button.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0)
2047 gdk_pointer_ungrab (0);
2052 g_print ("WM_MOUSEMOVE: %#x %#x +%d+%d\n",
2053 xevent->hwnd, xevent->wParam,
2054 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2057 /* Try hard not to generate events for windows that shouldn't
2058 get any. This is hard because we don't want pushbuttons to
2059 highlight when the cursor moves over them if the window is
2060 inactive. We dont want tooltips windows to be active. OTOH,
2061 also menus are popup windows, but they definitely should
2062 get events. Aw shit. Skip this.
2064 dwStyle = GetWindowLong (xevent->hwnd, GWL_STYLE);
2065 if (active == NULL ||
2066 !(active == xevent->hwnd
2067 || (dwStyle & WS_POPUP)
2068 || IsChild (active, xevent->hwnd)))
2071 { /* HB: only process mouse move messages
2072 * if we own the active window.
2074 DWORD ProcessID_ActWin;
2075 DWORD ProcessID_this;
2077 GetWindowThreadProcessId(GetActiveWindow(), &ProcessID_ActWin);
2078 GetWindowThreadProcessId(xevent->hwnd, &ProcessID_this);
2079 if (ProcessID_ActWin != ProcessID_this)
2083 if (window != curWnd)
2084 synthesize_crossing_events (window, xevent);
2087 && (window_private->extension_events != 0)
2088 && gdk_input_ignore_core)
2090 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
2095 event->motion.type = GDK_MOTION_NOTIFY;
2096 event->motion.window = window;
2098 mask = window_private->event_mask;
2103 && !p_grab_owner_events)
2105 /* Pointer is grabbed with owner_events FALSE */
2107 g_print ("...grabbed, owner_events FALSE\n"));
2108 mask = p_grab_event_mask;
2109 if (!((mask & GDK_POINTER_MOTION_MASK)
2110 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2111 && (mask & GDK_BUTTON_MOTION_MASK))
2112 || ((xevent->wParam & MK_LBUTTON)
2113 && (mask & GDK_BUTTON1_MOTION_MASK))
2114 || ((xevent->wParam & MK_MBUTTON)
2115 && (mask & GDK_BUTTON2_MOTION_MASK))
2116 || ((xevent->wParam & MK_RBUTTON)
2117 && (mask & GDK_BUTTON3_MOTION_MASK))))
2120 event->motion.window = (GdkWindow *) p_grab_window;
2121 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
2122 p_grab_window->xwindow));
2124 else if (window_private
2125 && !((mask & GDK_POINTER_MOTION_MASK)
2126 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2127 && (mask & GDK_BUTTON_MOTION_MASK))
2128 || ((xevent->wParam & MK_LBUTTON)
2129 && (mask & GDK_BUTTON1_MOTION_MASK))
2130 || ((xevent->wParam & MK_MBUTTON)
2131 && (mask & GDK_BUTTON2_MOTION_MASK))
2132 || ((xevent->wParam & MK_RBUTTON)
2133 && (mask & GDK_BUTTON3_MOTION_MASK))))
2135 /* Owner window doesn't want it */
2136 if (p_grab_window != NULL
2137 && p_grab_owner_events)
2139 /* Pointer is grabbed wÃth owner_events TRUE */
2140 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
2141 mask = p_grab_event_mask;
2142 if (!((p_grab_event_mask & GDK_POINTER_MOTION_MASK)
2143 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2144 && (mask & GDK_BUTTON_MOTION_MASK))
2145 || ((xevent->wParam & MK_LBUTTON)
2146 && (mask & GDK_BUTTON1_MOTION_MASK))
2147 || ((xevent->wParam & MK_MBUTTON)
2148 && (mask & GDK_BUTTON2_MOTION_MASK))
2149 || ((xevent->wParam & MK_RBUTTON)
2150 && (mask & GDK_BUTTON3_MOTION_MASK))))
2151 /* Grabber doesn't want it either */
2154 event->motion.window = (GdkWindow *) p_grab_window;
2155 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
2156 p_grab_window->xwindow));
2160 /* Owner doesn't want it, neither is it grabbed, so
2161 * propagate to parent.
2163 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
2165 pt.x = LOWORD (xevent->lParam);
2166 pt.y = HIWORD (xevent->lParam);
2167 ClientToScreen (window_private->xwindow, &pt);
2168 gdk_window_unref (window);
2169 window = window_private->parent;
2170 gdk_window_ref (window);
2171 window_private = (GdkWindowPrivate *) window;
2172 ScreenToClient (window_private->xwindow, &pt);
2173 xevent->lParam = MAKELPARAM (pt.x, pt.y);
2174 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
2175 window_private->xwindow));
2180 event->motion.time = xevent->time;
2181 event->motion.x = curX = LOWORD (xevent->lParam);
2182 event->motion.y = curY = HIWORD (xevent->lParam);
2183 event->motion.x_root = xevent->pt.x;
2184 event->motion.y_root = xevent->pt.y;
2185 curXroot = event->motion.x_root;
2186 curYroot = event->motion.y_root;
2187 event->motion.pressure = 0.5;
2188 event->motion.xtilt = 0;
2189 event->motion.ytilt = 0;
2190 event->button.state = 0;
2191 if (xevent->wParam & MK_CONTROL)
2192 event->button.state |= GDK_CONTROL_MASK;
2193 if (xevent->wParam & MK_LBUTTON)
2194 event->button.state |= GDK_BUTTON1_MASK;
2195 if (xevent->wParam & MK_MBUTTON)
2196 event->button.state |= GDK_BUTTON2_MASK;
2197 if (xevent->wParam & MK_RBUTTON)
2198 event->button.state |= GDK_BUTTON3_MASK;
2199 if (xevent->wParam & MK_SHIFT)
2200 event->button.state |= GDK_SHIFT_MASK;
2201 if (mask & GDK_POINTER_MOTION_HINT_MASK)
2202 event->motion.is_hint = NotifyHint;
2204 event->motion.is_hint = NotifyNormal;
2205 event->motion.source = GDK_SOURCE_MOUSE;
2206 event->motion.deviceid = GDK_CORE_POINTER;
2208 return_val = window_private && !window_private->destroyed;
2210 && p_grab_window != NULL
2211 && event->any.window == (GdkWindow *) p_grab_window
2212 && p_grab_window != window_private)
2214 /* Translate coordinates to grabber */
2215 pt.x = event->motion.x;
2216 pt.y = event->motion.y;
2217 ClientToScreen (window_private->xwindow, &pt);
2218 ScreenToClient (p_grab_window->xwindow, &pt);
2219 event->motion.x = pt.x;
2220 event->motion.y = pt.y;
2221 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
2225 case WM_NCMOUSEMOVE:
2227 g_print ("WM_NCMOUSEMOVE: %#x x,y: %d %d\n",
2229 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2231 if (active == NULL || active != xevent->hwnd)
2234 curWnd_private = (GdkWindowPrivate *) curWnd;
2236 && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
2238 GDK_NOTE (EVENTS, g_print ("...synthesizing LEAVE_NOTIFY event\n"));
2240 event->crossing.type = GDK_LEAVE_NOTIFY;
2241 event->crossing.window = curWnd;
2242 event->crossing.subwindow = NULL;
2243 event->crossing.time = xevent->time;
2244 event->crossing.x = curX;
2245 event->crossing.y = curY;
2246 event->crossing.x_root = curXroot;
2247 event->crossing.y_root = curYroot;
2248 event->crossing.mode = GDK_CROSSING_NORMAL;
2249 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
2251 event->crossing.focus = TRUE; /* ??? */
2252 event->crossing.state = 0; /* ??? */
2253 gdk_window_unref (curWnd);
2263 && !(window_private->event_mask & GDK_FOCUS_CHANGE_MASK))
2266 GDK_NOTE (EVENTS, g_print ("WM_%sFOCUS: %#x\n",
2267 (xevent->message == WM_SETFOCUS ? "SET" : "KILL"),
2270 event->focus_change.type = GDK_FOCUS_CHANGE;
2271 event->focus_change.window = window;
2272 event->focus_change.in = (xevent->message == WM_SETFOCUS);
2273 return_val = window_private && !window_private->destroyed;
2277 GDK_NOTE (EVENTS, g_print ("WM_ACTIVATE: %#x %d\n",
2278 xevent->hwnd, LOWORD (xevent->wParam)));
2279 if (LOWORD (xevent->wParam) == WA_INACTIVE)
2280 active = (HWND) xevent->lParam;
2282 active = xevent->hwnd;
2286 GDK_NOTE (EVENTS, g_print ("WM_ERASEBKGND: %#x dc %#x\n",
2287 xevent->hwnd, xevent->wParam));
2289 if (!window_private || window_private->destroyed)
2291 colormap_private = (GdkColormapPrivate *) window_private->colormap;
2292 hdc = (HDC) xevent->wParam;
2293 if (colormap_private
2294 && colormap_private->xcolormap->rc_palette)
2298 if (SelectPalette (hdc, colormap_private->xcolormap->palette,
2300 g_warning ("WM_ERASEBKGND: SelectPalette failed");
2301 if ((k = RealizePalette (hdc)) == GDI_ERROR)
2302 g_warning ("WM_ERASEBKGND: RealizePalette failed");
2304 g_print ("WM_ERASEBKGND: selected %#x, realized %d colors\n",
2305 colormap_private->xcolormap->palette, k);
2308 *ret_val_flagp = TRUE;
2311 if (window_private->bg_type == GDK_WIN32_BG_TRANSPARENT)
2314 if (window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2316 /* If this window should have the same background as the
2317 * parent, fetch the parent. (And if the same goes for
2318 * the parent, fetch the grandparent, etc.)
2320 while (window_private
2321 && window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2322 window_private = (GdkWindowPrivate *) window_private->parent;
2325 if (window_private->bg_type == GDK_WIN32_BG_PIXEL)
2328 GDK_NOTE (EVENTS, g_print ("...BG_PIXEL %s\n",
2329 gdk_color_to_string (&window_private->bg_pixel)));
2330 GetClipBox (hdc, &rect);
2331 #ifdef MULTIPLE_WINDOW_CLASSES
2332 bg = PALETTEINDEX (window_private->bg_pixel.pixel);
2334 bg = GetNearestColor (hdc, RGB (window_private->bg_pixel.red >> 8,
2335 window_private->bg_pixel.green >> 8,
2336 window_private->bg_pixel.blue >> 8));
2338 hbr = CreateSolidBrush (bg);
2340 g_print ("...CreateSolidBrush (%.08x) = %.08x\n", bg, hbr);
2342 if (!FillRect (hdc, &rect, hbr))
2343 g_warning ("WM_ERASEBKGND: FillRect failed");
2346 else if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
2348 GdkPixmapPrivate *pixmap_private;
2352 pixmap_private = (GdkPixmapPrivate *) window_private->bg_pixmap;
2353 GetClipBox (hdc, &rect);
2355 if (pixmap_private->width <= 8
2356 && pixmap_private->height <= 8)
2358 GDK_NOTE (EVENTS, g_print ("...small pixmap, using brush\n"));
2359 hbr = CreatePatternBrush (pixmap_private->xwindow);
2360 if (!FillRect (hdc, &rect, hbr))
2361 g_warning ("WM_ERASEBKGND: FillRect failed");
2367 g_print ("...blitting pixmap %#x (%dx%d) "
2368 "all over the place,\n"
2369 "...clip box = %dx%d@+%d+%d\n",
2370 pixmap_private->xwindow,
2371 pixmap_private->width, pixmap_private->height,
2372 rect.right - rect.left, rect.bottom - rect.top,
2373 rect.left, rect.top));
2375 if (!(bgdc = CreateCompatibleDC (hdc)))
2377 g_warning ("WM_ERASEBKGND: CreateCompatibleDC failed");
2380 if (!(oldbitmap = SelectObject (bgdc, pixmap_private->xwindow)))
2382 g_warning ("WM_ERASEBKGND: SelectObject failed");
2387 while (i < rect.right)
2390 while (j < rect.bottom)
2392 if (i + pixmap_private->width >= rect.left
2393 && j + pixmap_private->height >= rect.top)
2395 if (!BitBlt (hdc, i, j,
2396 pixmap_private->width, pixmap_private->height,
2397 bgdc, 0, 0, SRCCOPY))
2399 g_warning ("WM_ERASEBKGND: BitBlt failed");
2403 j += pixmap_private->height;
2405 i += pixmap_private->width;
2408 SelectObject (bgdc, oldbitmap);
2414 GDK_NOTE (EVENTS, g_print ("...BLACK_BRUSH (?)\n"));
2415 #ifdef MULTIPLE_WINDOW_CLASSES
2416 hbr = (HBRUSH) GetClassLong (window_private->xwindow,
2419 hbr = GetStockObject (BLACK_BRUSH);
2421 GetClipBox (hdc, &rect);
2422 if (!FillRect (hdc, &rect, hbr))
2423 g_warning ("WM_ERASEBKGND: FillRect failed");
2428 hdc = BeginPaint (xevent->hwnd, &paintstruct);
2431 g_print ("WM_PAINT: %#x %dx%d@+%d+%d %s dc %#x\n",
2433 paintstruct.rcPaint.right - paintstruct.rcPaint.left,
2434 paintstruct.rcPaint.bottom - paintstruct.rcPaint.top,
2435 paintstruct.rcPaint.left, paintstruct.rcPaint.top,
2436 (paintstruct.fErase ? "erase" : ""),
2439 EndPaint (xevent->hwnd, &paintstruct);
2442 && !(window_private->event_mask & GDK_EXPOSURE_MASK))
2445 event->expose.type = GDK_EXPOSE;
2446 event->expose.window = window;
2447 event->expose.area.x = paintstruct.rcPaint.left;
2448 event->expose.area.y = paintstruct.rcPaint.top;
2449 event->expose.area.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left;
2450 event->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
2451 event->expose.count = 1;
2453 return_val = window_private && !window_private->destroyed;
2456 #ifndef MULTIPLE_WINDOW_CLASSES
2458 GDK_NOTE (EVENTS, g_print ("WM_SETCURSOR: %#x %#x %#x\n",
2460 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2463 if (LOWORD (xevent->lParam) != HTCLIENT)
2465 if (p_grab_window != NULL && p_grab_cursor != NULL)
2466 SetCursor (p_grab_cursor);
2467 else if (window_private
2468 && !window_private->destroyed
2469 && window_private->xcursor)
2470 SetCursor (window_private->xcursor);
2471 *ret_val_flagp = TRUE;
2478 GDK_NOTE (EVENTS, g_print ("WM_QUERYOPEN: %#x\n",
2480 *ret_val_flagp = TRUE;
2484 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2487 event->any.type = GDK_MAP;
2488 event->any.window = window;
2490 return_val = window_private && !window_private->destroyed;
2496 GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#x %d\n",
2501 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2504 event->any.type = (xevent->wParam ? GDK_MAP : GDK_UNMAP);
2505 event->any.window = window;
2507 if (event->any.type == GDK_UNMAP
2508 && p_grab_window == window_private)
2509 gdk_pointer_ungrab (xevent->time);
2511 if (event->any.type == GDK_UNMAP
2512 && k_grab_window == window_private)
2513 gdk_keyboard_ungrab (xevent->time);
2515 return_val = window_private && !window_private->destroyed;
2520 g_print ("WM_SIZE: %#x %s %dx%d\n",
2522 (xevent->wParam == SIZE_MAXHIDE ? "MAXHIDE" :
2523 (xevent->wParam == SIZE_MAXIMIZED ? "MAXIMIZED" :
2524 (xevent->wParam == SIZE_MAXSHOW ? "MAXSHOW" :
2525 (xevent->wParam == SIZE_MINIMIZED ? "MINIMIZED" :
2526 (xevent->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
2527 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2530 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2532 if (window_private != NULL
2533 && xevent->wParam == SIZE_MINIMIZED)
2536 event->any.type = GDK_UNMAP;
2537 event->any.window = window;
2539 if (p_grab_window == window_private)
2540 gdk_pointer_ungrab (xevent->time);
2542 if (k_grab_window == window_private)
2543 gdk_keyboard_ungrab (xevent->time);
2545 return_val = !window_private->destroyed;
2548 else if (window_private != NULL
2549 && (xevent->wParam == SIZE_RESTORED
2550 || xevent->wParam == SIZE_MAXIMIZED)
2552 && window_private->window_type != GDK_WINDOW_CHILD
2556 if (LOWORD (xevent->lParam) == 0)
2559 event->configure.type = GDK_CONFIGURE;
2560 event->configure.window = window;
2563 ClientToScreen (xevent->hwnd, &pt);
2564 event->configure.x = pt.x;
2565 event->configure.y = pt.y;
2566 event->configure.width = LOWORD (xevent->lParam);
2567 event->configure.height = HIWORD (xevent->lParam);
2568 window_private->x = event->configure.x;
2569 window_private->y = event->configure.y;
2570 window_private->width = event->configure.width;
2571 window_private->height = event->configure.height;
2572 if (window_private->resize_count > 1)
2573 window_private->resize_count -= 1;
2575 return_val = !window_private->destroyed;
2577 && window_private->extension_events != 0
2578 && gdk_input_vtable.configure_event)
2579 gdk_input_vtable.configure_event (&event->configure, window);
2584 GDK_NOTE (EVENTS, g_print ("WM_SIZING: %#x\n", xevent->hwnd));
2585 if (ret_val_flagp == NULL)
2586 g_warning ("ret_val_flagp is NULL but we got a WM_SIZING?");
2587 else if (window_private != NULL
2588 && window_private->hint_flags &
2589 (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE))
2591 LPRECT lprc = (LPRECT) xevent->lParam;
2593 if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
2595 gint w = lprc->right - lprc->left;
2596 gint h = lprc->bottom - lprc->top;
2598 if (w < window_private->hint_min_width)
2600 if (xevent->wParam == WMSZ_BOTTOMLEFT
2601 || xevent->wParam == WMSZ_LEFT
2602 || xevent->wParam == WMSZ_TOPLEFT)
2603 lprc->left = lprc->right - window_private->hint_min_width;
2605 lprc->right = lprc->left + window_private->hint_min_width;
2606 *ret_val_flagp = TRUE;
2609 if (h < window_private->hint_min_height)
2611 if (xevent->wParam == WMSZ_BOTTOMLEFT
2612 || xevent->wParam == WMSZ_BOTTOM
2613 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2614 lprc->bottom = lprc->top + window_private->hint_min_height;
2616 lprc->top = lprc->bottom - window_private->hint_min_height;
2617 *ret_val_flagp = TRUE;
2621 if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
2623 gint w = lprc->right - lprc->left;
2624 gint h = lprc->bottom - lprc->top;
2626 if (w > window_private->hint_max_width)
2628 if (xevent->wParam == WMSZ_BOTTOMLEFT
2629 || xevent->wParam == WMSZ_LEFT
2630 || xevent->wParam == WMSZ_TOPLEFT)
2631 lprc->left = lprc->right - window_private->hint_max_width;
2633 lprc->right = lprc->left + window_private->hint_max_width;
2634 *ret_val_flagp = TRUE;
2637 if (h > window_private->hint_max_height)
2639 if (xevent->wParam == WMSZ_BOTTOMLEFT
2640 || xevent->wParam == WMSZ_BOTTOM
2641 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2642 lprc->bottom = lprc->top + window_private->hint_max_height;
2644 lprc->top = lprc->bottom - window_private->hint_max_height;
2645 *ret_val_flagp = TRUE;
2653 GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#x +%d+%d\n",
2655 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2658 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2660 if (window_private != NULL
2661 && window_private->window_type != GDK_WINDOW_CHILD)
2663 event->configure.type = GDK_CONFIGURE;
2664 event->configure.window = window;
2665 event->configure.x = LOWORD (xevent->lParam);
2666 event->configure.y = HIWORD (xevent->lParam);
2667 GetClientRect (xevent->hwnd, &rect);
2668 event->configure.width = rect.right;
2669 event->configure.height = rect.bottom;
2670 window_private->x = event->configure.x;
2671 window_private->y = event->configure.y;
2672 window_private->width = event->configure.width;
2673 window_private->height = event->configure.height;
2675 return_val = !window_private->destroyed;
2680 GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#x\n", xevent->hwnd));
2681 event->any.type = GDK_DELETE;
2682 event->any.window = window;
2684 return_val = window_private && !window_private->destroyed;
2688 /* No, don't use delayed rendering after all. It works only if the
2689 * delayed SetClipboardData is called from the WindowProc, it
2690 * seems. (The #else part below is test code for that. It succeeds
2691 * in setting the clipboard data. But if I call SetClipboardData
2692 * in gdk_property_change (as a consequence of the
2693 * GDK_SELECTION_REQUEST event), it fails. I deduce that this is
2694 * because delayed rendering requires that SetClipboardData is
2695 * called in the window procedure.)
2697 case WM_RENDERFORMAT:
2698 case WM_RENDERALLFORMATS:
2700 GDK_NOTE (EVENTS, flag = TRUE);
2701 GDK_NOTE (SELECTION, flag = TRUE);
2703 g_print ("WM_%s: %#x %#x (%s)\n",
2704 (xevent->message == WM_RENDERFORMAT ? "RENDERFORMAT" :
2705 "RENDERALLFORMATS"),
2708 (xevent->wParam == CF_TEXT ? "CF_TEXT" :
2709 (xevent->wParam == CF_DIB ? "CF_DIB" :
2710 (xevent->wParam == CF_UNICODETEXT ? "CF_UNICODETEXT" :
2711 (GetClipboardFormatName (xevent->wParam, buf, sizeof (buf)), buf)))));
2714 event->selection.type = GDK_SELECTION_REQUEST;
2715 event->selection.window = window;
2716 event->selection.selection = gdk_clipboard_atom;
2717 if (xevent->wParam == CF_TEXT)
2718 event->selection.target = GDK_TARGET_STRING;
2721 GetClipboardFormatName (xevent->wParam, buf, sizeof (buf));
2722 event->selection.target = gdk_atom_intern (buf, FALSE);
2724 event->selection.property = gdk_selection_property;
2725 event->selection.requestor = (guint32) xevent->hwnd;
2726 event->selection.time = xevent->time;
2727 return_val = window_private && !window_private->destroyed;
2729 /* Test code, to see if SetClipboardData works when called from
2730 * the window procedure.
2733 HGLOBAL hdata = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, 10);
2734 char *ptr = GlobalLock (hdata);
2735 strcpy (ptr, "Huhhaa");
2736 GlobalUnlock (hdata);
2737 if (!SetClipboardData (CF_TEXT, hdata))
2738 g_print ("SetClipboardData failed: %d\n", GetLastError ());
2741 *ret_val_flagp = TRUE;
2745 #endif /* No delayed rendering */
2748 GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#x\n", xevent->hwnd));
2749 event->any.type = GDK_DESTROY;
2750 event->any.window = window;
2751 if (window != NULL && window == curWnd)
2753 gdk_window_unref (curWnd);
2757 if (p_grab_window == window_private)
2758 gdk_pointer_ungrab (xevent->time);
2760 if (k_grab_window == window_private)
2761 gdk_keyboard_ungrab (xevent->time);
2763 return_val = window_private && !window_private->destroyed;
2766 /* Handle WINTAB events here, as we know that gdkinput.c will
2767 * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
2768 * constants as case labels.
2771 GDK_NOTE (EVENTS, g_print ("WT_PACKET: %d %#x\n",
2772 xevent->wParam, xevent->lParam));
2776 GDK_NOTE (EVENTS, g_print ("WT_CSRCHANGE: %d %#x\n",
2777 xevent->wParam, xevent->lParam));
2782 g_print ("WT_PROXIMITY: %#x %d %d\n",
2784 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2786 return_val = gdk_input_vtable.other_event(event, xevent);
2794 if (event->any.window)
2795 gdk_window_ref (event->any.window);
2796 if (((event->any.type == GDK_ENTER_NOTIFY) ||
2797 (event->any.type == GDK_LEAVE_NOTIFY)) &&
2798 (event->crossing.subwindow != NULL))
2799 gdk_window_ref (event->crossing.subwindow);
2803 /* Mark this event as having no resources to be freed */
2804 event->any.window = NULL;
2805 event->any.type = GDK_NOTHING;
2809 gdk_window_unref (window);
2815 gdk_events_queue (void)
2821 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: %s\n",
2822 (queued_events ? "yes" : "none")));
2824 while (!gdk_event_queue_find_first()
2825 && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
2827 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: got event\n"));
2828 TranslateMessage (&msg);
2830 event = gdk_event_new ();
2832 event->any.type = GDK_NOTHING;
2833 event->any.window = NULL;
2834 event->any.send_event = FALSE;
2836 ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
2838 gdk_event_queue_append (event);
2841 if (gdk_event_translate (event, &msg, NULL, NULL))
2842 ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
2845 DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
2846 gdk_event_queue_remove_link (node);
2847 g_list_free_1 (node);
2848 gdk_event_free (event);
2854 gdk_event_prepare (gpointer source_data,
2855 GTimeVal *current_time,
2861 GDK_THREADS_ENTER ();
2865 GDK_NOTE (EVENTS, g_print ("gdk_event_prepare\n"));
2867 retval = (gdk_event_queue_find_first () != NULL)
2868 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2870 GDK_THREADS_LEAVE ();
2876 gdk_event_check (gpointer source_data,
2877 GTimeVal *current_time)
2882 GDK_NOTE (EVENTS, g_print ("gdk_event_check\n"));
2884 GDK_THREADS_ENTER ();
2886 if (event_poll_fd.revents & G_IO_IN)
2887 retval = (gdk_event_queue_find_first () != NULL)
2888 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2892 GDK_THREADS_LEAVE ();
2898 gdk_event_unqueue (void)
2900 GdkEvent *event = NULL;
2903 tmp_list = gdk_event_queue_find_first ();
2907 event = tmp_list->data;
2908 gdk_event_queue_remove_link (tmp_list);
2909 g_list_free_1 (tmp_list);
2916 gdk_event_dispatch (gpointer source_data,
2917 GTimeVal *current_time,
2922 GDK_NOTE (EVENTS, g_print ("gdk_event_dispatch\n"));
2924 GDK_THREADS_ENTER ();
2927 event = gdk_event_unqueue();
2932 (*event_func) (event, event_data);
2934 gdk_event_free (event);
2937 GDK_THREADS_LEAVE ();
2943 gdk_synthesize_click (GdkEvent *event,
2946 GdkEvent temp_event;
2948 g_return_if_fail (event != NULL);
2950 temp_event = *event;
2951 temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
2953 gdk_event_put (&temp_event);
2956 /* Sends a ClientMessage to all toplevel client windows */
2958 gdk_event_send_client_message (GdkEvent *event, guint32 xid)
2965 gdk_event_send_clientmessage_toall (GdkEvent *event)