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;
1384 g_print ("not wanted, not grabbed, "
1385 "sending to %#x\n", window_private->xwindow));
1390 switch (xevent->wParam)
1393 event->key.keyval = GDK_Pointer_Button1; break;
1395 event->key.keyval = GDK_Pointer_Button3; break;
1397 event->key.keyval = GDK_Pointer_Button2; break;
1399 event->key.keyval = GDK_Cancel; break;
1401 event->key.keyval = GDK_BackSpace; break;
1403 event->key.keyval = GDK_Tab; break;
1405 event->key.keyval = GDK_Clear; break;
1407 event->key.keyval = GDK_Return; break;
1409 event->key.keyval = GDK_Shift_L; break;
1411 if (xevent->lParam & 0x01000000)
1412 event->key.keyval = GDK_Control_R;
1414 event->key.keyval = GDK_Control_L;
1417 if (xevent->lParam & 0x01000000)
1419 /* AltGr key comes in as Control+Right Alt */
1420 if (GetKeyState (VK_CONTROL) < 0)
1422 ignore_WM_CHAR = FALSE;
1423 is_AltGr_key = TRUE;
1425 event->key.keyval = GDK_Alt_R;
1428 event->key.keyval = GDK_Alt_L;
1431 event->key.keyval = GDK_Pause; break;
1433 event->key.keyval = GDK_Caps_Lock; break;
1435 event->key.keyval = GDK_Escape; break;
1437 event->key.keyval = GDK_Prior; break;
1439 event->key.keyval = GDK_Next; break;
1441 event->key.keyval = GDK_End; break;
1443 event->key.keyval = GDK_Home; break;
1445 event->key.keyval = GDK_Left; break;
1447 event->key.keyval = GDK_Up; break;
1449 event->key.keyval = GDK_Right; break;
1451 event->key.keyval = GDK_Down; break;
1453 event->key.keyval = GDK_Select; break;
1455 event->key.keyval = GDK_Print; break;
1457 event->key.keyval = GDK_Execute; break;
1459 event->key.keyval = GDK_Insert; break;
1461 event->key.keyval = GDK_Delete; break;
1463 event->key.keyval = GDK_Help; break;
1474 /* Apparently applications work better if we just pass numpad digits
1475 * on as real digits? So wait for the WM_CHAR instead.
1477 ignore_WM_CHAR = FALSE;
1480 event->key.keyval = GDK_KP_Multiply; break;
1482 event->key.keyval = GDK_KP_Add; break;
1484 event->key.keyval = GDK_KP_Separator; break;
1486 event->key.keyval = GDK_KP_Subtract; break;
1489 event->key.keyval = GDK_KP_Decimal; break;
1491 /* The keypad decimal key should also be passed on as the decimal
1492 * sign ('.' or ',' depending on the Windows locale settings,
1493 * apparently). So wait for the WM_CHAR here, also.
1495 ignore_WM_CHAR = FALSE;
1499 event->key.keyval = GDK_KP_Divide; break;
1501 event->key.keyval = GDK_F1; break;
1503 event->key.keyval = GDK_F2; break;
1505 event->key.keyval = GDK_F3; break;
1507 event->key.keyval = GDK_F4; break;
1509 event->key.keyval = GDK_F5; break;
1511 event->key.keyval = GDK_F6; break;
1513 event->key.keyval = GDK_F7; break;
1515 event->key.keyval = GDK_F8; break;
1517 event->key.keyval = GDK_F9; break;
1519 event->key.keyval = GDK_F10; break;
1521 event->key.keyval = GDK_F11; break;
1523 event->key.keyval = GDK_F12; break;
1525 event->key.keyval = GDK_F13; break;
1527 event->key.keyval = GDK_F14; break;
1529 event->key.keyval = GDK_F15; break;
1531 event->key.keyval = GDK_F16; break;
1533 if (xevent->message == WM_SYSKEYDOWN || xevent->message == WM_SYSKEYUP)
1535 event->key.keyval = xevent->wParam;
1539 ignore_WM_CHAR = FALSE;
1540 event->key.keyval = GDK_VoidSymbol;
1545 if (!ignore_WM_CHAR)
1548 is_AltGr_key = FALSE;
1549 event->key.type = ((xevent->message == WM_KEYDOWN
1550 | xevent->message == WM_SYSKEYDOWN) ?
1551 GDK_KEY_PRESS : GDK_KEY_RELEASE);
1552 event->key.window = window;
1553 event->key.time = xevent->time;
1554 event->key.state = 0;
1555 if (GetKeyState (VK_SHIFT) < 0)
1556 event->key.state |= GDK_SHIFT_MASK;
1557 if (GetKeyState (VK_CAPITAL) & 0x1)
1558 event->key.state |= GDK_LOCK_MASK;
1559 if (GetKeyState (VK_CONTROL) < 0)
1560 event->key.state |= GDK_CONTROL_MASK;
1561 if (xevent->wParam != VK_MENU && GetKeyState (VK_MENU) < 0)
1562 event->key.state |= GDK_MOD1_MASK;
1563 event->key.length = 0;
1564 return_val = window_private && !window_private->destroyed;
1565 event->key.string = NULL;
1570 g_print ("WM_CHAR: %#x char: %#x %#.08x %s\n",
1574 (ignore_WM_CHAR ? "ignored" : "")));
1578 ignore_WM_CHAR = FALSE;
1583 /* This doesn't handle the rather theorethical case that a window
1584 * wants key presses but still wants releases to be propagated,
1587 if (k_grab_window != NULL
1588 && !k_grab_owner_events)
1590 /* Keyboard is grabbed with owner_events FALSE */
1592 g_print ("grabbed, owner_events FALSE, "
1593 "sending to %#x\n", k_grab_window->xwindow));
1594 event->key.window = (GdkWindow *) k_grab_window;
1596 else if (window_private
1597 && !(window_private->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)))
1599 /* Owner window doesn't want it */
1600 if (k_grab_window != NULL
1601 && k_grab_owner_events)
1603 /* Keyboard is grabbed with owner_events TRUE */
1605 g_print ("grabbed, owner_events TRUE, doesn't want it, "
1606 "sending to %#x\n", k_grab_window->xwindow));
1607 event->key.window = (GdkWindow *) k_grab_window;
1611 /* Owner doesn't want it, neither is it grabbed, so
1612 * propagate to parent.
1614 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1615 g_assert_not_reached (); /* Should've been handled above */
1617 gdk_window_unref (window);
1618 window = window_private->parent;
1619 gdk_window_ref (window);
1620 window_private = (GdkWindowPrivate *) window;
1622 g_print ("not wanted, not grabbed, sending to %#x\n",
1623 window_private->xwindow));
1628 return_val = window_private && !window_private->destroyed;
1629 if (return_val && (window_private->event_mask & GDK_KEY_RELEASE_MASK))
1631 /* Return the release event, and maybe append the press
1632 * event to the queued_events list (from which it will vbe
1633 * fetched before the release event).
1635 event->key.type = GDK_KEY_RELEASE;
1636 event->key.keyval = xevent->wParam;
1637 event->key.window = window;
1638 event->key.time = xevent->time;
1639 event->key.state = 0;
1640 if (GetKeyState (VK_SHIFT) < 0)
1641 event->key.state |= GDK_SHIFT_MASK;
1642 if (GetKeyState (VK_CAPITAL) & 0x1)
1643 event->key.state |= GDK_LOCK_MASK;
1646 else if (GetKeyState (VK_CONTROL) < 0)
1648 event->key.state |= GDK_CONTROL_MASK;
1649 if (event->key.keyval < ' ')
1650 event->key.keyval += '@';
1652 else if (event->key.keyval < ' ')
1654 event->key.state |= GDK_CONTROL_MASK;
1655 event->key.keyval += '@';
1657 if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
1658 event->key.state |= GDK_MOD1_MASK;
1659 event->key.string = g_strdup (" ");
1660 event->key.length = 1;
1661 event->key.string[0] = xevent->wParam; /* ??? */
1663 if (window_private->event_mask & GDK_KEY_PRESS_MASK)
1665 /* Append also a GDK_KEY_PRESS event to the pushback list. */
1666 GdkEvent *event2 = gdk_event_copy (event);
1667 event2->key.type = GDK_KEY_PRESS;
1668 charcount = xevent->lParam & 0xFFFF;
1669 if (charcount > sizeof (buf)- 1)
1670 charcount = sizeof (buf) - 1;
1671 g_free (event2->key.string);
1672 event2->key.string = g_malloc (charcount);
1673 for (i = 0; i < charcount; i++)
1674 event2->key.string[i] = event->key.keyval;
1675 event2->key.length = charcount;
1677 gdk_event_queue_append (event2);
1680 else if (return_val && (window_private->event_mask & GDK_KEY_PRESS_MASK))
1682 /* Return just the GDK_KEY_PRESS event. */
1683 event->key.type = GDK_KEY_PRESS;
1684 charcount = xevent->lParam & 0xFFFF;
1685 if (charcount > sizeof (buf)- 1)
1686 charcount = sizeof (buf) - 1;
1687 event->key.keyval = xevent->wParam;
1688 event->key.window = window;
1689 event->key.time = xevent->time;
1690 event->key.state = 0;
1691 if (GetKeyState (VK_SHIFT) < 0)
1692 event->key.state |= GDK_SHIFT_MASK;
1693 if (GetKeyState (VK_CAPITAL) & 0x1)
1694 event->key.state |= GDK_LOCK_MASK;
1697 else if (GetKeyState (VK_CONTROL) < 0)
1699 event->key.state |= GDK_CONTROL_MASK;
1700 if (event->key.keyval < ' ')
1701 event->key.keyval += '@';
1703 else if (event->key.keyval < ' ')
1705 event->key.state |= GDK_CONTROL_MASK;
1706 event->key.keyval += '@';
1708 if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
1709 event->key.state |= GDK_MOD1_MASK;
1710 event->key.string = g_malloc (charcount);
1711 for (i = 0; i < charcount; i++)
1712 event->key.string[i] = event->key.keyval;
1713 event->key.length = charcount;
1717 is_AltGr_key = FALSE;
1720 case WM_LBUTTONDOWN:
1723 case WM_MBUTTONDOWN:
1726 case WM_RBUTTONDOWN:
1729 /* Print debugging info.
1733 g_print ("WM_%cBUTTONDOWN: %#x x,y: %d %d button: %d\n",
1736 LOWORD (xevent->lParam), HIWORD (xevent->lParam),
1740 && (window_private->extension_events != 0)
1741 && gdk_input_ignore_core)
1743 GDK_NOTE (EVENTS, g_print ("... ignored\n"));
1748 event->button.type = GDK_BUTTON_PRESS;
1749 event->button.window = window;
1751 mask = window_private->event_mask;
1755 if (p_grab_window != NULL
1756 && !p_grab_owner_events)
1758 /* Pointer is grabbed with owner_events FALSE */
1759 GDK_NOTE (EVENTS, g_print ("grabbed, owner_events FALSE\n"));
1760 mask = p_grab_event_mask;
1761 if (!(mask & GDK_BUTTON_PRESS_MASK))
1762 /* Grabber doesn't want it */
1765 event->button.window = (GdkWindow *) p_grab_window;
1766 GDK_NOTE (EVENTS, g_print ("sending to %#x\n",
1767 p_grab_window->xwindow));
1769 else if (window_private
1770 && !(mask & GDK_BUTTON_PRESS_MASK))
1772 /* Owner window doesn't want it */
1773 if (p_grab_window != NULL
1774 && p_grab_owner_events)
1776 /* Pointer is grabbed wÃth owner_events TRUE */
1777 GDK_NOTE (EVENTS, g_print ("grabbed, owner_events TRUE, doesn't want it\n"));
1778 mask = p_grab_event_mask;
1779 if (!(mask & GDK_BUTTON_PRESS_MASK))
1780 /* Grabber doesn't want it either */
1783 event->button.window = (GdkWindow *) p_grab_window;
1784 GDK_NOTE (EVENTS, g_print ("sending to %#x\n",
1785 p_grab_window->xwindow));
1789 /* Owner doesn't want it, neither is it grabbed, so
1790 * propagate to parent.
1792 /* Yes, this code is duplicated twice below. So shoot me. */
1793 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1795 pt.x = LOWORD (xevent->lParam);
1796 pt.y = HIWORD (xevent->lParam);
1797 ClientToScreen (window_private->xwindow, &pt);
1798 gdk_window_unref (window);
1799 window = window_private->parent;
1800 gdk_window_ref (window);
1801 window_private = (GdkWindowPrivate *) window;
1802 ScreenToClient (window_private->xwindow, &pt);
1803 xevent->lParam = MAKELPARAM (pt.x, pt.y);
1804 goto buttondown; /* What did Dijkstra say? */
1808 /* Emulate X11's automatic active grab */
1811 /* No explicit active grab, let's start one automatically */
1812 GDK_NOTE (EVENTS, g_print ("automatic grab started\n"));
1813 gdk_pointer_grab (window, TRUE, window_private->event_mask,
1815 p_grab_automatic = TRUE;
1818 if (window != curWnd)
1819 synthesize_crossing_events (window, xevent);
1821 event->button.time = xevent->time;
1822 event->button.x = LOWORD (xevent->lParam);
1823 event->button.y = HIWORD (xevent->lParam);
1824 event->button.x_root = (gfloat)xevent->pt.x;
1825 event->button.y_root = (gfloat)xevent->pt.y;
1826 event->button.pressure = 0.5;
1827 event->button.xtilt = 0;
1828 event->button.ytilt = 0;
1829 event->button.state = 0;
1830 if (xevent->wParam & MK_CONTROL)
1831 event->button.state |= GDK_CONTROL_MASK;
1832 if (xevent->wParam & MK_LBUTTON)
1833 event->button.state |= GDK_BUTTON1_MASK;
1834 if (xevent->wParam & MK_MBUTTON)
1835 event->button.state |= GDK_BUTTON2_MASK;
1836 if (xevent->wParam & MK_RBUTTON)
1837 event->button.state |= GDK_BUTTON3_MASK;
1838 if (xevent->wParam & MK_SHIFT)
1839 event->button.state |= GDK_SHIFT_MASK;
1840 if (GetKeyState (VK_MENU) < 0)
1841 event->button.state |= GDK_MOD1_MASK;
1842 if (GetKeyState (VK_CAPITAL) & 0x1)
1843 event->button.state |= GDK_LOCK_MASK;
1844 event->button.button = button;
1845 event->button.source = GDK_SOURCE_MOUSE;
1846 event->button.deviceid = GDK_CORE_POINTER;
1848 if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) &&
1849 (event->button.window == button_window[1]) &&
1850 (event->button.button == button_number[1]))
1852 gdk_synthesize_click (event, 3);
1854 button_click_time[1] = 0;
1855 button_click_time[0] = 0;
1856 button_window[1] = NULL;
1857 button_window[0] = 0;
1858 button_number[1] = -1;
1859 button_number[0] = -1;
1861 else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) &&
1862 (event->button.window == button_window[0]) &&
1863 (event->button.button == button_number[0]))
1865 gdk_synthesize_click (event, 2);
1867 button_click_time[1] = button_click_time[0];
1868 button_click_time[0] = event->button.time;
1869 button_window[1] = button_window[0];
1870 button_window[0] = event->button.window;
1871 button_number[1] = button_number[0];
1872 button_number[0] = event->button.button;
1876 button_click_time[1] = 0;
1877 button_click_time[0] = event->button.time;
1878 button_window[1] = NULL;
1879 button_window[0] = event->button.window;
1880 button_number[1] = -1;
1881 button_number[0] = event->button.button;
1883 return_val = window_private && !window_private->destroyed;
1885 && p_grab_window != NULL
1886 && event->any.window == (GdkWindow *) p_grab_window
1887 && p_grab_window != window_private)
1889 /* Translate coordinates to grabber */
1890 pt.x = event->button.x;
1891 pt.y = event->button.y;
1892 ClientToScreen (window_private->xwindow, &pt);
1893 ScreenToClient (p_grab_window->xwindow, &pt);
1894 event->button.x = pt.x;
1895 event->button.y = pt.y;
1896 GDK_NOTE (EVENTS, g_print ("New coords are +%d+%d\n", pt.x, pt.y));
1909 /* Print debugging info.
1913 g_print ("WM_%cBUTTONUP: %#x x,y: %d %d button: %d\n",
1916 LOWORD (xevent->lParam), HIWORD (xevent->lParam),
1920 && (window_private->extension_events != 0)
1921 && gdk_input_ignore_core)
1923 GDK_NOTE (EVENTS, g_print ("... ignored\n"));
1928 event->button.type = GDK_BUTTON_RELEASE;
1929 event->button.window = window;
1931 mask = window_private->event_mask;
1935 if (p_grab_window != NULL
1936 && !p_grab_owner_events)
1938 /* Pointer is grabbed with owner_events FALSE */
1939 GDK_NOTE (EVENTS, g_print ("grabbed, owner_events FALSE\n"));
1940 mask = p_grab_event_mask;
1941 if (!(mask & GDK_BUTTON_RELEASE_MASK))
1942 /* Grabber doesn't want it */
1945 event->button.window = (GdkWindow *) p_grab_window;
1946 GDK_NOTE (EVENTS, g_print ("sending to %#x\n",
1947 p_grab_window->xwindow));
1949 else if (window_private
1950 && !(mask & GDK_BUTTON_RELEASE_MASK))
1952 /* Owner window doesn't want it */
1953 if (p_grab_window != NULL
1954 && p_grab_owner_events)
1956 /* Pointer is grabbed wÃth owner_events TRUE */
1957 GDK_NOTE (EVENTS, g_print ("grabbed, owner_events TRUE, doesn't want it\n"));
1958 mask = p_grab_event_mask;
1959 if (!(mask & GDK_BUTTON_RELEASE_MASK))
1960 /* Grabber doesn't want it */
1963 event->button.window = (GdkWindow *) p_grab_window;
1964 GDK_NOTE (EVENTS, g_print ("sending to %#x\n",
1965 p_grab_window->xwindow));
1969 /* Owner doesn't want it, neither is it grabbed, so
1970 * propagate to parent.
1972 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1974 pt.x = LOWORD (xevent->lParam);
1975 pt.y = HIWORD (xevent->lParam);
1976 ClientToScreen (window_private->xwindow, &pt);
1977 gdk_window_unref (window);
1978 window = window_private->parent;
1979 gdk_window_ref (window);
1980 window_private = (GdkWindowPrivate *) window;
1981 ScreenToClient (window_private->xwindow, &pt);
1982 xevent->lParam = MAKELPARAM (pt.x, pt.y);
1987 if (window != curWnd)
1988 synthesize_crossing_events (window, xevent);
1990 event->button.time = xevent->time;
1991 event->button.x = LOWORD (xevent->lParam);
1992 event->button.y = HIWORD (xevent->lParam);
1993 event->button.x_root = (gfloat)xevent->pt.x;
1994 event->button.y_root = (gfloat)xevent->pt.y;
1995 event->button.pressure = 0.5;
1996 event->button.xtilt = 0;
1997 event->button.ytilt = 0;
1998 event->button.state = 0;
1999 if (xevent->wParam & MK_CONTROL)
2000 event->button.state |= GDK_CONTROL_MASK;
2001 if (xevent->wParam & MK_LBUTTON)
2002 event->button.state |= GDK_BUTTON1_MASK;
2003 if (xevent->wParam & MK_MBUTTON)
2004 event->button.state |= GDK_BUTTON2_MASK;
2005 if (xevent->wParam & MK_RBUTTON)
2006 event->button.state |= GDK_BUTTON3_MASK;
2007 if (xevent->wParam & MK_SHIFT)
2008 event->button.state |= GDK_SHIFT_MASK;
2009 event->button.button = button;
2010 event->button.source = GDK_SOURCE_MOUSE;
2011 event->button.deviceid = GDK_CORE_POINTER;
2012 return_val = window_private && !window_private->destroyed;
2014 && p_grab_window != NULL
2015 && event->any.window == (GdkWindow *) p_grab_window
2016 && p_grab_window != window_private)
2018 /* Translate coordinates to grabber */
2019 pt.x = event->button.x;
2020 pt.y = event->button.y;
2021 ClientToScreen (window_private->xwindow, &pt);
2022 ScreenToClient (p_grab_window->xwindow, &pt);
2023 event->button.x = pt.x;
2024 event->button.y = pt.y;
2025 GDK_NOTE (EVENTS, g_print ("New coords are +%d+%d\n", pt.x, pt.y));
2027 if (p_grab_window != NULL
2029 && (event->button.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0)
2030 gdk_pointer_ungrab (0);
2034 /* Print debugging info.
2037 g_print ("WM_MOUSEMOVE: %#x %#x +%d+%d\n",
2038 xevent->hwnd, xevent->wParam,
2039 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2042 /* Try hard not to generate events for windows that shouldn't
2043 get any. This is hard because we don't want pushbuttons to
2044 highlight when the cursor moves over them if the window is
2045 inactive. We dont want tooltips windows to be active. OTOH,
2046 also menus are popup windows, but they definitely should
2047 get events. Aw shit. Skip this.
2049 dwStyle = GetWindowLong (xevent->hwnd, GWL_STYLE);
2050 if (active == NULL ||
2051 !(active == xevent->hwnd
2052 || (dwStyle & WS_POPUP)
2053 || IsChild (active, xevent->hwnd)))
2056 { /* HB: only process mouse move messages
2057 * if we own the active window.
2059 DWORD ProcessID_ActWin;
2060 DWORD ProcessID_this;
2062 GetWindowThreadProcessId(GetActiveWindow(), &ProcessID_ActWin);
2063 GetWindowThreadProcessId(xevent->hwnd, &ProcessID_this);
2064 if (ProcessID_ActWin != ProcessID_this)
2068 if (window != curWnd)
2069 synthesize_crossing_events (window, xevent);
2072 && (window_private->extension_events != 0)
2073 && gdk_input_ignore_core)
2075 GDK_NOTE (EVENTS, g_print ("... ignored\n"));
2080 event->motion.type = GDK_MOTION_NOTIFY;
2081 event->motion.window = window;
2083 mask = window_private->event_mask;
2088 && !p_grab_owner_events)
2090 /* Pointer is grabbed with owner_events FALSE */
2092 g_print ("grabbed, owner_events FALSE\n"));
2093 mask = p_grab_event_mask;
2094 if (!((mask & GDK_POINTER_MOTION_MASK)
2095 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2096 && (mask & GDK_BUTTON_MOTION_MASK))
2097 || ((xevent->wParam & MK_LBUTTON)
2098 && (mask & GDK_BUTTON1_MOTION_MASK))
2099 || ((xevent->wParam & MK_MBUTTON)
2100 && (mask & GDK_BUTTON2_MOTION_MASK))
2101 || ((xevent->wParam & MK_RBUTTON)
2102 && (mask & GDK_BUTTON3_MOTION_MASK))))
2105 event->motion.window = (GdkWindow *) p_grab_window;
2106 GDK_NOTE (EVENTS, g_print ("sending to %#x\n",
2107 p_grab_window->xwindow));
2109 else if (window_private
2110 && !((mask & GDK_POINTER_MOTION_MASK)
2111 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2112 && (mask & GDK_BUTTON_MOTION_MASK))
2113 || ((xevent->wParam & MK_LBUTTON)
2114 && (mask & GDK_BUTTON1_MOTION_MASK))
2115 || ((xevent->wParam & MK_MBUTTON)
2116 && (mask & GDK_BUTTON2_MOTION_MASK))
2117 || ((xevent->wParam & MK_RBUTTON)
2118 && (mask & GDK_BUTTON3_MOTION_MASK))))
2120 /* Owner window doesn't want it */
2121 if (p_grab_window != NULL
2122 && p_grab_owner_events)
2124 /* Pointer is grabbed wÃth owner_events TRUE */
2125 GDK_NOTE (EVENTS, g_print ("grabbed, owner_events TRUE, doesn't want it\n"));
2126 mask = p_grab_event_mask;
2127 if (!((p_grab_event_mask & GDK_POINTER_MOTION_MASK)
2128 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2129 && (mask & GDK_BUTTON_MOTION_MASK))
2130 || ((xevent->wParam & MK_LBUTTON)
2131 && (mask & GDK_BUTTON1_MOTION_MASK))
2132 || ((xevent->wParam & MK_MBUTTON)
2133 && (mask & GDK_BUTTON2_MOTION_MASK))
2134 || ((xevent->wParam & MK_RBUTTON)
2135 && (mask & GDK_BUTTON3_MOTION_MASK))))
2136 /* Grabber doesn't want it either */
2139 event->motion.window = (GdkWindow *) p_grab_window;
2140 GDK_NOTE (EVENTS, g_print ("sending to %#x\n",
2141 p_grab_window->xwindow));
2145 /* Owner doesn't want it, neither is it grabbed, so
2146 * propagate to parent.
2148 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
2150 pt.x = LOWORD (xevent->lParam);
2151 pt.y = HIWORD (xevent->lParam);
2152 ClientToScreen (window_private->xwindow, &pt);
2153 gdk_window_unref (window);
2154 window = window_private->parent;
2155 gdk_window_ref (window);
2156 window_private = (GdkWindowPrivate *) window;
2157 ScreenToClient (window_private->xwindow, &pt);
2158 xevent->lParam = MAKELPARAM (pt.x, pt.y);
2159 GDK_NOTE (EVENTS, g_print ("propagating to %#x\n",
2160 window_private->xwindow));
2165 event->motion.time = xevent->time;
2166 event->motion.x = curX = LOWORD (xevent->lParam);
2167 event->motion.y = curY = HIWORD (xevent->lParam);
2168 event->motion.x_root = xevent->pt.x;
2169 event->motion.y_root = xevent->pt.y;
2170 curXroot = event->motion.x_root;
2171 curYroot = event->motion.y_root;
2172 event->motion.pressure = 0.5;
2173 event->motion.xtilt = 0;
2174 event->motion.ytilt = 0;
2175 event->button.state = 0;
2176 if (xevent->wParam & MK_CONTROL)
2177 event->button.state |= GDK_CONTROL_MASK;
2178 if (xevent->wParam & MK_LBUTTON)
2179 event->button.state |= GDK_BUTTON1_MASK;
2180 if (xevent->wParam & MK_MBUTTON)
2181 event->button.state |= GDK_BUTTON2_MASK;
2182 if (xevent->wParam & MK_RBUTTON)
2183 event->button.state |= GDK_BUTTON3_MASK;
2184 if (xevent->wParam & MK_SHIFT)
2185 event->button.state |= GDK_SHIFT_MASK;
2186 if (mask & GDK_POINTER_MOTION_HINT_MASK)
2187 event->motion.is_hint = NotifyHint;
2189 event->motion.is_hint = NotifyNormal;
2190 event->motion.source = GDK_SOURCE_MOUSE;
2191 event->motion.deviceid = GDK_CORE_POINTER;
2193 return_val = window_private && !window_private->destroyed;
2195 && p_grab_window != NULL
2196 && event->any.window == (GdkWindow *) p_grab_window
2197 && p_grab_window != window_private)
2199 /* Translate coordinates to grabber */
2200 pt.x = event->motion.x;
2201 pt.y = event->motion.y;
2202 ClientToScreen (window_private->xwindow, &pt);
2203 ScreenToClient (p_grab_window->xwindow, &pt);
2204 event->motion.x = pt.x;
2205 event->motion.y = pt.y;
2206 GDK_NOTE (EVENTS, g_print ("New coords are +%d+%d\n", pt.x, pt.y));
2210 case WM_NCMOUSEMOVE:
2211 /* Print debugging info. */
2213 g_print ("WM_NCMOUSEMOVE: %#x x,y: %d %d\n",
2215 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2217 if (active == NULL || active != xevent->hwnd)
2220 curWnd_private = (GdkWindowPrivate *) curWnd;
2222 && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
2224 GDK_NOTE (EVENTS, g_print ("synthesizing LEAVE_NOTIFY event\n"));
2226 event->crossing.type = GDK_LEAVE_NOTIFY;
2227 event->crossing.window = curWnd;
2228 event->crossing.subwindow = NULL;
2229 event->crossing.time = xevent->time;
2230 event->crossing.x = curX;
2231 event->crossing.y = curY;
2232 event->crossing.x_root = curXroot;
2233 event->crossing.y_root = curYroot;
2234 event->crossing.mode = GDK_CROSSING_NORMAL;
2235 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
2237 event->crossing.focus = TRUE; /* ??? */
2238 event->crossing.state = 0; /* ??? */
2239 gdk_window_unref (curWnd);
2249 && !(window_private->event_mask & GDK_FOCUS_CHANGE_MASK))
2252 GDK_NOTE (EVENTS, g_print ("WM_%sFOCUS: %#x\n",
2253 (xevent->message == WM_SETFOCUS ? "SET" : "KILL"),
2256 event->focus_change.type = GDK_FOCUS_CHANGE;
2257 event->focus_change.window = window;
2258 event->focus_change.in = (xevent->message == WM_SETFOCUS);
2259 return_val = window_private && !window_private->destroyed;
2263 GDK_NOTE (EVENTS, g_print ("WM_ACTIVATE: %#x %d\n",
2264 xevent->hwnd, LOWORD (xevent->wParam)));
2265 if (LOWORD (xevent->wParam) == WA_INACTIVE)
2266 active = (HWND) xevent->lParam;
2268 active = xevent->hwnd;
2272 GDK_NOTE (EVENTS, g_print ("WM_ERASEBKGND: %#x dc %#x\n",
2273 xevent->hwnd, xevent->wParam));
2275 if (!window_private || window_private->destroyed)
2277 colormap_private = (GdkColormapPrivate *) window_private->colormap;
2278 hdc = (HDC) xevent->wParam;
2279 if (colormap_private
2280 && colormap_private->xcolormap->rc_palette)
2284 if (SelectPalette (hdc, colormap_private->xcolormap->palette,
2286 g_warning ("WM_ERASEBKGND: SelectPalette failed");
2287 if ((k = RealizePalette (hdc)) == GDI_ERROR)
2288 g_warning ("WM_ERASEBKGND: RealizePalette failed");
2290 g_print ("WM_ERASEBKGND: selected %#x, realized %d colors\n",
2291 colormap_private->xcolormap->palette, k);
2294 *ret_val_flagp = TRUE;
2297 if (window_private->bg_type == GDK_WIN32_BG_TRANSPARENT)
2300 if (window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2302 /* If this window should have the same background as the
2303 * parent, fetch the parent. (And if the same goes for
2304 * the parent, fetch the grandparent, etc.)
2306 while (window_private
2307 && window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2308 window_private = (GdkWindowPrivate *) window_private->parent;
2311 if (window_private->bg_type == GDK_WIN32_BG_PIXEL)
2314 GDK_NOTE (EVENTS, g_print ("... BG_PIXEL %s\n",
2315 gdk_color_to_string (&window_private->bg_pixel)));
2316 GetClipBox (hdc, &rect);
2317 #ifdef MULTIPLE_WINDOW_CLASSES
2318 bg = PALETTEINDEX (window_private->bg_pixel.pixel);
2320 bg = GetNearestColor (hdc, RGB (window_private->bg_pixel.red >> 8,
2321 window_private->bg_pixel.green >> 8,
2322 window_private->bg_pixel.blue >> 8));
2324 hbr = CreateSolidBrush (bg);
2326 g_print ("... CreateSolidBrush (%.08x) = %.08x\n", bg, hbr);
2328 if (!FillRect (hdc, &rect, hbr))
2329 g_warning ("WM_ERASEBKGND: FillRect failed");
2332 else if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
2334 GdkPixmapPrivate *pixmap_private;
2338 pixmap_private = (GdkPixmapPrivate *) window_private->bg_pixmap;
2339 GetClipBox (hdc, &rect);
2341 if (pixmap_private->width <= 8
2342 && pixmap_private->height <= 8)
2344 GDK_NOTE (EVENTS, g_print ("...small pixmap, using brush\n"));
2345 hbr = CreatePatternBrush (pixmap_private->xwindow);
2346 if (!FillRect (hdc, &rect, hbr))
2347 g_warning ("WM_ERASEBKGND: FillRect failed");
2353 g_print ("...blitting pixmap %#x (%dx%d) "
2354 "all over the place,\n"
2355 "...clip box = %dx%d@+%d+%d\n",
2356 pixmap_private->xwindow,
2357 pixmap_private->width, pixmap_private->height,
2358 rect.right - rect.left, rect.bottom - rect.top,
2359 rect.left, rect.top));
2361 if (!(bgdc = CreateCompatibleDC (hdc)))
2363 g_warning ("WM_ERASEBKGND: CreateCompatibleDC failed");
2366 if (!(oldbitmap = SelectObject (bgdc, pixmap_private->xwindow)))
2368 g_warning ("WM_ERASEBKGND: SelectObject failed");
2373 while (i < rect.right)
2376 while (j < rect.bottom)
2378 if (i + pixmap_private->width >= rect.left
2379 && j + pixmap_private->height >= rect.top)
2381 if (!BitBlt (hdc, i, j,
2382 pixmap_private->width, pixmap_private->height,
2383 bgdc, 0, 0, SRCCOPY))
2385 g_warning ("WM_ERASEBKGND: BitBlt failed");
2389 j += pixmap_private->height;
2391 i += pixmap_private->width;
2394 SelectObject (bgdc, oldbitmap);
2400 GDK_NOTE (EVENTS, g_print ("... BLACK_BRUSH (?)\n"));
2401 #ifdef MULTIPLE_WINDOW_CLASSES
2402 hbr = (HBRUSH) GetClassLong (window_private->xwindow,
2405 hbr = GetStockObject (BLACK_BRUSH);
2407 GetClipBox (hdc, &rect);
2408 if (!FillRect (hdc, &rect, hbr))
2409 g_warning ("WM_ERASEBKGND: FillRect failed");
2414 GDK_NOTE (EVENTS, g_print ("WM_PAINT: %#x\n", xevent->hwnd));
2415 hdc = BeginPaint (xevent->hwnd, &paintstruct);
2417 /* Print debugging info.
2420 g_print ("...WM_PAINT: %#x %dx%d@+%d+%d %s dc %#x\n",
2422 paintstruct.rcPaint.right - paintstruct.rcPaint.left,
2423 paintstruct.rcPaint.bottom - paintstruct.rcPaint.top,
2424 paintstruct.rcPaint.left, paintstruct.rcPaint.top,
2425 (paintstruct.fErase ? "erase" : ""),
2428 EndPaint (xevent->hwnd, &paintstruct);
2431 && !(window_private->event_mask & GDK_EXPOSURE_MASK))
2434 event->expose.type = GDK_EXPOSE;
2435 event->expose.window = window;
2436 event->expose.area.x = paintstruct.rcPaint.left;
2437 event->expose.area.y = paintstruct.rcPaint.top;
2438 event->expose.area.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left;
2439 event->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
2440 event->expose.count = 1;
2442 return_val = window_private && !window_private->destroyed;
2445 #ifndef MULTIPLE_WINDOW_CLASSES
2447 GDK_NOTE (EVENTS, g_print ("WM_SETCURSOR: %#x %#x %#x\n",
2449 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2452 if (LOWORD (xevent->lParam) != HTCLIENT)
2454 if (p_grab_window != NULL && p_grab_cursor != NULL)
2455 SetCursor (p_grab_cursor);
2456 else if (window_private
2457 && !window_private->destroyed
2458 && window_private->xcursor)
2459 SetCursor (window_private->xcursor);
2460 *ret_val_flagp = TRUE;
2467 GDK_NOTE (EVENTS, g_print ("WM_QUERYOPEN: %#x\n",
2469 *ret_val_flagp = TRUE;
2473 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2476 event->any.type = GDK_MAP;
2477 event->any.window = window;
2479 return_val = window_private && !window_private->destroyed;
2485 /* Print debugging info.
2487 GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#x %d\n",
2492 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2495 event->any.type = (xevent->wParam ? GDK_MAP : GDK_UNMAP);
2496 event->any.window = window;
2498 if (event->any.type == GDK_UNMAP
2499 && p_grab_window == window_private)
2500 gdk_pointer_ungrab (xevent->time);
2502 if (event->any.type == GDK_UNMAP
2503 && k_grab_window == window_private)
2504 gdk_keyboard_ungrab (xevent->time);
2506 return_val = window_private && !window_private->destroyed;
2510 /* Print debugging info.
2513 g_print ("WM_SIZE: %#x %s %dx%d\n",
2515 (xevent->wParam == SIZE_MAXHIDE ? "MAXHIDE" :
2516 (xevent->wParam == SIZE_MAXIMIZED ? "MAXIMIZED" :
2517 (xevent->wParam == SIZE_MAXSHOW ? "MAXSHOW" :
2518 (xevent->wParam == SIZE_MINIMIZED ? "MINIMIZED" :
2519 (xevent->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
2520 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2523 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2525 if (window_private != NULL
2526 && xevent->wParam == SIZE_MINIMIZED)
2529 event->any.type = GDK_UNMAP;
2530 event->any.window = window;
2532 if (p_grab_window == window_private)
2533 gdk_pointer_ungrab (xevent->time);
2535 if (k_grab_window == window_private)
2536 gdk_keyboard_ungrab (xevent->time);
2538 return_val = !window_private->destroyed;
2541 else if (window_private != NULL
2542 && (xevent->wParam == SIZE_RESTORED
2543 || xevent->wParam == SIZE_MAXIMIZED)
2545 && window_private->window_type != GDK_WINDOW_CHILD
2549 if (LOWORD (xevent->lParam) == 0)
2552 event->configure.type = GDK_CONFIGURE;
2553 event->configure.window = window;
2556 ClientToScreen (xevent->hwnd, &pt);
2557 event->configure.x = pt.x;
2558 event->configure.y = pt.y;
2559 event->configure.width = LOWORD (xevent->lParam);
2560 event->configure.height = HIWORD (xevent->lParam);
2561 window_private->x = event->configure.x;
2562 window_private->y = event->configure.y;
2563 window_private->width = event->configure.width;
2564 window_private->height = event->configure.height;
2565 if (window_private->resize_count > 1)
2566 window_private->resize_count -= 1;
2568 return_val = !window_private->destroyed;
2570 && window_private->extension_events != 0
2571 && gdk_input_vtable.configure_event)
2572 gdk_input_vtable.configure_event (&event->configure, window);
2577 GDK_NOTE (EVENTS, g_print ("WM_SIZING: %#x\n", xevent->hwnd));
2578 if (ret_val_flagp == NULL)
2579 g_warning ("ret_val_flagp is NULL but we got a WM_SIZING?");
2580 else if (window_private != NULL
2581 && window_private->hint_flags &
2582 (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE))
2584 LPRECT lprc = (LPRECT) xevent->lParam;
2586 if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
2588 gint w = lprc->right - lprc->left;
2589 gint h = lprc->bottom - lprc->top;
2591 if (w < window_private->hint_min_width)
2593 if (xevent->wParam == WMSZ_BOTTOMLEFT
2594 || xevent->wParam == WMSZ_LEFT
2595 || xevent->wParam == WMSZ_TOPLEFT)
2596 lprc->left = lprc->right - window_private->hint_min_width;
2598 lprc->right = lprc->left + window_private->hint_min_width;
2599 *ret_val_flagp = TRUE;
2602 if (h < window_private->hint_min_height)
2604 if (xevent->wParam == WMSZ_BOTTOMLEFT
2605 || xevent->wParam == WMSZ_BOTTOM
2606 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2607 lprc->bottom = lprc->top + window_private->hint_min_height;
2609 lprc->top = lprc->bottom - window_private->hint_min_height;
2610 *ret_val_flagp = TRUE;
2614 if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
2616 gint w = lprc->right - lprc->left;
2617 gint h = lprc->bottom - lprc->top;
2619 if (w > window_private->hint_max_width)
2621 if (xevent->wParam == WMSZ_BOTTOMLEFT
2622 || xevent->wParam == WMSZ_LEFT
2623 || xevent->wParam == WMSZ_TOPLEFT)
2624 lprc->left = lprc->right - window_private->hint_max_width;
2626 lprc->right = lprc->left + window_private->hint_max_width;
2627 *ret_val_flagp = TRUE;
2630 if (h > window_private->hint_max_height)
2632 if (xevent->wParam == WMSZ_BOTTOMLEFT
2633 || xevent->wParam == WMSZ_BOTTOM
2634 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2635 lprc->bottom = lprc->top + window_private->hint_max_height;
2637 lprc->top = lprc->bottom - window_private->hint_max_height;
2638 *ret_val_flagp = TRUE;
2646 GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#x +%d+%d\n",
2648 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2651 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2653 if (window_private != NULL
2654 && window_private->window_type != GDK_WINDOW_CHILD)
2656 event->configure.type = GDK_CONFIGURE;
2657 event->configure.window = window;
2658 event->configure.x = LOWORD (xevent->lParam);
2659 event->configure.y = HIWORD (xevent->lParam);
2660 GetClientRect (xevent->hwnd, &rect);
2661 event->configure.width = rect.right;
2662 event->configure.height = rect.bottom;
2663 window_private->x = event->configure.x;
2664 window_private->y = event->configure.y;
2665 window_private->width = event->configure.width;
2666 window_private->height = event->configure.height;
2668 return_val = !window_private->destroyed;
2673 GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#x\n", xevent->hwnd));
2674 event->any.type = GDK_DELETE;
2675 event->any.window = window;
2677 return_val = window_private && !window_private->destroyed;
2681 /* No, don't use delayed rendering after all. It works only if the
2682 * delayed SetClipboardData is called from the WindowProc, it
2683 * seems. (The #else part below is test code for that. It succeeds
2684 * in setting the clipboard data. But if I call SetClipboardData
2685 * in gdk_property_change (as a consequence of the
2686 * GDK_SELECTION_REQUEST event), it fails. I deduce that this is
2687 * because delayed rendering requires that SetClipboardData is
2688 * called in the window procedure.)
2690 case WM_RENDERFORMAT:
2691 case WM_RENDERALLFORMATS:
2693 GDK_NOTE (EVENTS, flag = TRUE);
2694 GDK_NOTE (SELECTION, flag = TRUE);
2696 g_print ("WM_%s: %#x %#x (%s)\n",
2697 (xevent->message == WM_RENDERFORMAT ? "RENDERFORMAT" :
2698 "RENDERALLFORMATS"),
2701 (xevent->wParam == CF_TEXT ? "CF_TEXT" :
2702 (xevent->wParam == CF_DIB ? "CF_DIB" :
2703 (xevent->wParam == CF_UNICODETEXT ? "CF_UNICODETEXT" :
2704 (GetClipboardFormatName (xevent->wParam, buf, sizeof (buf)), buf)))));
2707 event->selection.type = GDK_SELECTION_REQUEST;
2708 event->selection.window = window;
2709 event->selection.selection = gdk_clipboard_atom;
2710 if (xevent->wParam == CF_TEXT)
2711 event->selection.target = GDK_TARGET_STRING;
2714 GetClipboardFormatName (xevent->wParam, buf, sizeof (buf));
2715 event->selection.target = gdk_atom_intern (buf, FALSE);
2717 event->selection.property = gdk_selection_property;
2718 event->selection.requestor = (guint32) xevent->hwnd;
2719 event->selection.time = xevent->time;
2720 return_val = window_private && !window_private->destroyed;
2722 /* Test code, to see if SetClipboardData works when called from
2723 * the window procedure.
2726 HGLOBAL hdata = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, 10);
2727 char *ptr = GlobalLock (hdata);
2728 strcpy (ptr, "Huhhaa");
2729 GlobalUnlock (hdata);
2730 if (!SetClipboardData (CF_TEXT, hdata))
2731 g_print ("SetClipboardData failed: %d\n", GetLastError ());
2734 *ret_val_flagp = TRUE;
2738 #endif /* No delayed rendering */
2741 GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#x\n", xevent->hwnd));
2742 event->any.type = GDK_DESTROY;
2743 event->any.window = window;
2744 if (window != NULL && window == curWnd)
2746 gdk_window_unref (curWnd);
2750 if (p_grab_window == window_private)
2751 gdk_pointer_ungrab (xevent->time);
2753 if (k_grab_window == window_private)
2754 gdk_keyboard_ungrab (xevent->time);
2756 return_val = window_private && !window_private->destroyed;
2759 /* Handle WINTAB events here, as we know that gdkinput.c will
2760 * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
2761 * constants as case labels.
2764 GDK_NOTE (EVENTS, g_print ("WT_PACKET: %d %#x\n",
2765 xevent->wParam, xevent->lParam));
2769 GDK_NOTE (EVENTS, g_print ("WT_CSRCHANGE: %d %#x\n",
2770 xevent->wParam, xevent->lParam));
2775 g_print ("WT_PROXIMITY: %#x %d %d\n",
2777 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2779 return_val = gdk_input_vtable.other_event(event, xevent);
2787 if (event->any.window)
2788 gdk_window_ref (event->any.window);
2789 if (((event->any.type == GDK_ENTER_NOTIFY) ||
2790 (event->any.type == GDK_LEAVE_NOTIFY)) &&
2791 (event->crossing.subwindow != NULL))
2792 gdk_window_ref (event->crossing.subwindow);
2796 /* Mark this event as having no resources to be freed */
2797 event->any.window = NULL;
2798 event->any.type = GDK_NOTHING;
2802 gdk_window_unref (window);
2808 gdk_events_queue (void)
2814 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: %s\n",
2815 (queued_events ? "yes" : "none")));
2817 while (!gdk_event_queue_find_first()
2818 && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
2820 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: got event\n"));
2821 TranslateMessage (&msg);
2823 event = gdk_event_new ();
2825 event->any.type = GDK_NOTHING;
2826 event->any.window = NULL;
2827 event->any.send_event = FALSE;
2829 ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
2831 gdk_event_queue_append (event);
2834 if (gdk_event_translate (event, &msg, NULL, NULL))
2835 ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
2838 DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
2839 gdk_event_queue_remove_link (node);
2840 g_list_free_1 (node);
2841 gdk_event_free (event);
2847 gdk_event_prepare (gpointer source_data,
2848 GTimeVal *current_time,
2854 GDK_THREADS_ENTER ();
2858 GDK_NOTE (EVENTS, g_print ("gdk_event_prepare\n"));
2860 retval = (gdk_event_queue_find_first () != NULL)
2861 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2863 GDK_THREADS_LEAVE ();
2869 gdk_event_check (gpointer source_data,
2870 GTimeVal *current_time)
2875 GDK_NOTE (EVENTS, g_print ("gdk_event_check\n"));
2877 GDK_THREADS_ENTER ();
2879 if (event_poll_fd.revents & G_IO_IN)
2880 retval = (gdk_event_queue_find_first () != NULL)
2881 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2885 GDK_THREADS_LEAVE ();
2891 gdk_event_unqueue (void)
2893 GdkEvent *event = NULL;
2896 tmp_list = gdk_event_queue_find_first ();
2900 event = tmp_list->data;
2901 gdk_event_queue_remove_link (tmp_list);
2902 g_list_free_1 (tmp_list);
2909 gdk_event_dispatch (gpointer source_data,
2910 GTimeVal *current_time,
2915 GDK_NOTE (EVENTS, g_print ("gdk_event_dispatch\n"));
2917 GDK_THREADS_ENTER ();
2920 event = gdk_event_unqueue();
2925 (*event_func) (event, event_data);
2927 gdk_event_free (event);
2930 GDK_THREADS_LEAVE ();
2936 gdk_synthesize_click (GdkEvent *event,
2939 GdkEvent temp_event;
2941 g_return_if_fail (event != NULL);
2943 temp_event = *event;
2944 temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
2946 gdk_event_put (&temp_event);
2949 /* Sends a ClientMessage to all toplevel client windows */
2951 gdk_event_send_client_message (GdkEvent *event, guint32 xid)
2958 gdk_event_send_clientmessage_toall (GdkEvent *event)