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)
528 g_return_val_if_fail (event != NULL, NULL);
530 new_event = gdk_event_new ();
533 gdk_window_ref (new_event->any.window);
535 switch (event->any.type)
538 case GDK_KEY_RELEASE:
539 if (event->key.length > 0)
541 s = event->key.string;
542 new_event->key.string = g_malloc (event->key.length + 1);
543 memcpy (new_event->key.string, s, event->key.length + 1);
547 case GDK_ENTER_NOTIFY:
548 case GDK_LEAVE_NOTIFY:
549 if (event->crossing.subwindow != NULL)
550 gdk_window_ref (event->crossing.subwindow);
555 case GDK_DRAG_MOTION:
556 case GDK_DRAG_STATUS:
558 case GDK_DROP_FINISHED:
559 gdk_drag_context_ref (event->dnd.context);
570 *--------------------------------------------------------------
573 * Free a event structure obtained from gdk_event_copy. Do not use
574 * with other event structures.
577 * "event" is the event struct to free.
582 * The reference count of the window in the event is decreased and
583 * might be freed, too.
585 *-------------------------------------------------------------- */
588 gdk_event_free (GdkEvent *event)
590 g_return_if_fail (event != NULL);
592 g_assert (event_chunk != NULL); /* paranoid */
594 if (event->any.window)
595 gdk_window_unref (event->any.window);
597 switch (event->any.type)
600 case GDK_KEY_RELEASE:
601 g_free (event->key.string);
604 case GDK_ENTER_NOTIFY:
605 case GDK_LEAVE_NOTIFY:
606 if (event->crossing.subwindow != NULL)
607 gdk_window_unref (event->crossing.subwindow);
612 case GDK_DRAG_MOTION:
613 case GDK_DRAG_STATUS:
615 case GDK_DROP_FINISHED:
616 gdk_drag_context_unref (event->dnd.context);
623 g_mem_chunk_free (event_chunk, event);
627 *--------------------------------------------------------------
628 * gdk_event_get_time:
629 * Get the timestamp from an event.
633 * The event's time stamp, if it has one, otherwise
635 *--------------------------------------------------------------
639 gdk_event_get_time (GdkEvent *event)
644 case GDK_MOTION_NOTIFY:
645 return event->motion.time;
646 case GDK_BUTTON_PRESS:
647 case GDK_2BUTTON_PRESS:
648 case GDK_3BUTTON_PRESS:
649 case GDK_BUTTON_RELEASE:
650 return event->button.time;
652 case GDK_KEY_RELEASE:
653 return event->key.time;
654 case GDK_ENTER_NOTIFY:
655 case GDK_LEAVE_NOTIFY:
656 return event->crossing.time;
657 case GDK_PROPERTY_NOTIFY:
658 return event->property.time;
659 case GDK_SELECTION_CLEAR:
660 case GDK_SELECTION_REQUEST:
661 case GDK_SELECTION_NOTIFY:
662 return event->selection.time;
663 case GDK_PROXIMITY_IN:
664 case GDK_PROXIMITY_OUT:
665 return event->proximity.time;
668 case GDK_DRAG_MOTION:
669 case GDK_DRAG_STATUS:
671 case GDK_DROP_FINISHED:
672 return event->dnd.time;
673 default: /* use current time */
677 return GDK_CURRENT_TIME;
681 *--------------------------------------------------------------
682 * gdk_set_show_events
684 * Turns on/off the showing of events.
687 * "show_events" is a boolean describing whether or
688 * not to show the events gdk receives.
693 * When "show_events" is TRUE, calls to "gdk_event_get"
694 * will output debugging informatin regarding the event
695 * received to stdout.
697 *--------------------------------------------------------------
701 gdk_set_show_events (gint show_events)
704 gdk_debug_flags |= GDK_DEBUG_EVENTS;
706 gdk_debug_flags &= ~GDK_DEBUG_EVENTS;
710 gdk_get_show_events (void)
712 return gdk_debug_flags & GDK_DEBUG_EVENTS;
716 *--------------------------------------------------------------
719 * Grabs the pointer to a specific window
722 * "window" is the window which will receive the grab
723 * "owner_events" specifies whether events will be reported as is,
724 * or relative to "window"
725 * "event_mask" masks only interesting events
726 * "confine_to" limits the cursor movement to the specified window
727 * "cursor" changes the cursor for the duration of the grab
728 * "time" specifies the time
733 * requires a corresponding call to gdk_pointer_ungrab
735 *--------------------------------------------------------------
739 gdk_pointer_grab (GdkWindow * window,
741 GdkEventMask event_mask,
742 GdkWindow * confine_to,
746 GdkWindowPrivate *window_private;
750 GdkWindowPrivate *confine_to_private;
751 GdkCursorPrivate *cursor_private;
754 g_return_val_if_fail (window != NULL, 0);
756 window_private = (GdkWindowPrivate*) window;
757 confine_to_private = (GdkWindowPrivate*) confine_to;
758 cursor_private = (GdkCursorPrivate*) cursor;
760 xwindow = window_private->xwindow;
762 if (!confine_to || confine_to_private->destroyed)
765 xconfine_to = confine_to_private->xwindow;
770 xcursor = cursor_private->xcursor;
772 if (gdk_input_vtable.grab_pointer)
773 return_val = gdk_input_vtable.grab_pointer (window,
779 return_val = Success;
781 if (return_val == Success)
783 if (!window_private->destroyed)
785 GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x\n",
787 (owner_events ? "TRUE" : "FALSE"),
789 p_grab_event_mask = event_mask;
790 p_grab_owner_events = owner_events != 0;
791 p_grab_automatic = FALSE;
793 #if 0 /* Menus don't work if we use mouse capture. Pity, because many other
794 * things work better with mouse capture.
796 SetCapture (xwindow);
798 return_val = GrabSuccess;
801 return_val = AlreadyGrabbed;
804 if (return_val == GrabSuccess)
806 p_grab_window = window_private;
807 p_grab_cursor = xcursor;
814 *--------------------------------------------------------------
817 * Releases any pointer grab
825 *--------------------------------------------------------------
829 gdk_pointer_ungrab (guint32 time)
831 if (gdk_input_vtable.ungrab_pointer)
832 gdk_input_vtable.ungrab_pointer (time);
834 if (GetCapture () != NULL)
837 GDK_NOTE (EVENTS, g_print ("gdk_pointer_ungrab\n"));
839 p_grab_window = NULL;
843 *--------------------------------------------------------------
844 * gdk_pointer_is_grabbed
846 * Tell wether there is an active x pointer grab in effect
854 *--------------------------------------------------------------
858 gdk_pointer_is_grabbed (void)
860 return p_grab_window != NULL;
864 *--------------------------------------------------------------
867 * Grabs the keyboard to a specific window
870 * "window" is the window which will receive the grab
871 * "owner_events" specifies whether events will be reported as is,
872 * or relative to "window"
873 * "time" specifies the time
878 * requires a corresponding call to gdk_keyboard_ungrab
880 *--------------------------------------------------------------
884 gdk_keyboard_grab (GdkWindow * window,
888 GdkWindowPrivate *window_private;
891 g_return_val_if_fail (window != NULL, 0);
893 window_private = (GdkWindowPrivate*) window;
895 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_grab %#x\n",
896 window_private->xwindow));
898 if (!window_private->destroyed)
900 k_grab_owner_events = owner_events != 0;
901 return_val = GrabSuccess;
904 return_val = AlreadyGrabbed;
906 if (return_val == GrabSuccess)
907 k_grab_window = window_private;
913 *--------------------------------------------------------------
914 * gdk_keyboard_ungrab
916 * Releases any keyboard grab
924 *--------------------------------------------------------------
928 gdk_keyboard_ungrab (guint32 time)
930 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_ungrab\n"));
932 k_grab_window = NULL;
936 gdk_io_destroy (gpointer data)
938 GdkIOClosure *closure = data;
941 closure->notify (closure->data);
947 gdk_io_invoke (GIOChannel *source,
948 GIOCondition condition,
951 GdkIOClosure *closure = data;
952 GdkInputCondition gdk_cond = 0;
954 if (condition & (G_IO_IN | G_IO_PRI))
955 gdk_cond |= GDK_INPUT_READ;
956 if (condition & G_IO_OUT)
957 gdk_cond |= GDK_INPUT_WRITE;
958 if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
959 gdk_cond |= GDK_INPUT_EXCEPTION;
961 if (closure->condition & gdk_cond)
962 closure->function (closure->data, g_io_channel_unix_get_fd (source), gdk_cond);
968 gdk_input_add_full (gint source,
969 GdkInputCondition condition,
970 GdkInputFunction function,
972 GdkDestroyNotify destroy)
975 GdkIOClosure *closure = g_new (GdkIOClosure, 1);
977 GIOCondition cond = 0;
979 closure->function = function;
980 closure->condition = condition;
981 closure->notify = destroy;
982 closure->data = data;
984 if (condition & GDK_INPUT_READ)
985 cond |= (G_IO_IN | G_IO_PRI);
986 if (condition & GDK_INPUT_WRITE)
988 if (condition & GDK_INPUT_EXCEPTION)
989 cond |= G_IO_ERR|G_IO_HUP|G_IO_NVAL;
991 channel = g_io_channel_unix_new (source);
992 result = g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, cond,
994 closure, gdk_io_destroy);
995 g_io_channel_unref (channel);
1001 gdk_input_add (gint source,
1002 GdkInputCondition condition,
1003 GdkInputFunction function,
1006 return gdk_input_add_full (source, condition, function, data, NULL);
1010 gdk_input_remove (gint tag)
1012 g_source_remove (tag);
1016 gdk_event_apply_filters (MSG *xevent,
1020 GdkEventFilter *filter;
1022 GdkFilterReturn result;
1028 filter = (GdkEventFilter *) tmp_list->data;
1030 result = (*filter->function) (xevent, event, filter->data);
1031 if (result != GDK_FILTER_CONTINUE)
1034 tmp_list = tmp_list->next;
1037 return GDK_FILTER_CONTINUE;
1041 gdk_add_client_message_filter (GdkAtom message_type,
1045 GdkClientFilter *filter = g_new (GdkClientFilter, 1);
1047 filter->type = message_type;
1048 filter->function = func;
1049 filter->data = data;
1051 client_filters = g_list_prepend (client_filters, filter);
1055 synthesize_crossing_events (GdkWindow *window,
1059 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
1060 GdkWindowPrivate *curWnd_private = (GdkWindowPrivate *) curWnd;
1062 if (curWnd && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
1064 GDK_NOTE (EVENTS, g_print ("synthesizing LEAVE_NOTIFY event\n"));
1066 event = gdk_event_new ();
1067 event->crossing.type = GDK_LEAVE_NOTIFY;
1068 event->crossing.window = curWnd;
1069 gdk_window_ref (event->crossing.window);
1070 event->crossing.subwindow = NULL;
1071 event->crossing.time = xevent->time;
1072 event->crossing.x = curX;
1073 event->crossing.y = curY;
1074 event->crossing.x_root = curXroot;
1075 event->crossing.y_root = curYroot;
1076 event->crossing.mode = GDK_CROSSING_NORMAL;
1077 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
1079 event->crossing.focus = TRUE; /* ??? */
1080 event->crossing.state = 0; /* ??? */
1082 gdk_event_queue_append (event);
1085 if (window_private && (window_private->event_mask & GDK_ENTER_NOTIFY_MASK))
1087 GDK_NOTE (EVENTS, g_print ("synthesizing ENTER_NOTIFY event\n"));
1089 event = gdk_event_new ();
1090 event->crossing.type = GDK_ENTER_NOTIFY;
1091 event->crossing.window = window;
1092 gdk_window_ref (event->crossing.window);
1093 event->crossing.subwindow = NULL;
1094 event->crossing.time = xevent->time;
1095 event->crossing.x = LOWORD (xevent->lParam);
1096 event->crossing.y = HIWORD (xevent->lParam);
1097 event->crossing.x_root = (gfloat) xevent->pt.x;
1098 event->crossing.y_root = (gfloat) xevent->pt.y;
1099 event->crossing.mode = GDK_CROSSING_NORMAL;
1100 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
1102 event->crossing.focus = TRUE; /* ??? */
1103 event->crossing.state = 0; /* ??? */
1105 gdk_event_queue_append (event);
1107 if (window_private->extension_events != 0
1108 && gdk_input_vtable.enter_event)
1109 gdk_input_vtable.enter_event (&event->crossing, window);
1113 gdk_window_unref (curWnd);
1115 gdk_window_ref (curWnd);
1119 gdk_event_translate (GdkEvent *event,
1121 gboolean *ret_val_flagp,
1125 GdkWindowPrivate *window_private;
1127 GdkColormapPrivate *colormap_private;
1130 PAINTSTRUCT paintstruct;
1135 GdkWindowPrivate *curWnd_private;
1147 *ret_val_flagp = FALSE;
1149 if (xevent->message == gdk_ping_msg)
1151 /* Messages we post ourselves just to wakeup WaitMessage. */
1155 window = gdk_window_lookup (xevent->hwnd);
1156 window_private = (GdkWindowPrivate *) window;
1158 if (xevent->message == g_pipe_readable_msg)
1160 GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n",
1161 xevent->wParam, xevent->lParam));
1163 g_io_channel_win32_pipe_readable (xevent->wParam, xevent->lParam);
1168 gdk_window_ref (window);
1171 /* Handle WM_QUIT here ? */
1172 if (xevent->message == WM_QUIT)
1174 GDK_NOTE (EVENTS, g_print ("WM_QUIT: %d\n", xevent->wParam));
1175 exit (xevent->wParam);
1177 else if (xevent->message == WM_MOVE
1178 || xevent->message == WM_SIZE)
1180 /* It's quite normal to get these messages before we have
1181 * had time to register the window in our lookup table, or
1182 * when the window is being destroyed and we already have
1183 * removed it. Repost the same message to our queue so that
1184 * we will get it later when we are prepared.
1186 PostMessage (xevent->hwnd, xevent->message,
1187 xevent->wParam, xevent->lParam);
1189 else if (xevent->message == WM_NCCREATE
1190 || xevent->message == WM_CREATE
1191 || xevent->message == WM_GETMINMAXINFO
1192 || xevent->message == WM_NCCALCSIZE
1193 || xevent->message == WM_NCDESTROY
1194 || xevent->message == WM_DESTROY)
1201 event->any.window = window;
1203 if (window_private && window_private->destroyed)
1208 /* Check for filters for this window */
1209 GdkFilterReturn result;
1210 result = gdk_event_apply_filters (xevent, event,
1212 ?window_private->filters
1213 :gdk_default_filters);
1215 if (result != GDK_FILTER_CONTINUE)
1217 return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
1221 if (xevent->message == gdk_selection_notify_msg)
1223 GDK_NOTE (SELECTION, g_print ("gdk_selection_notify_msg: %#x\n",
1226 event->selection.type = GDK_SELECTION_NOTIFY;
1227 event->selection.window = window;
1228 event->selection.selection = xevent->wParam;
1229 event->selection.target = xevent->lParam;
1230 event->selection.property = gdk_selection_property;
1231 event->selection.time = xevent->time;
1233 return_val = window_private && !window_private->destroyed;
1235 /* Will pass through switch below without match */
1237 else if (xevent->message == gdk_selection_request_msg)
1239 GDK_NOTE (SELECTION, g_print ("gdk_selection_request_msg: %#x\n",
1242 event->selection.type = GDK_SELECTION_REQUEST;
1243 event->selection.window = window;
1244 event->selection.selection = gdk_clipboard_atom;
1245 event->selection.target = GDK_TARGET_STRING;
1246 event->selection.property = gdk_selection_property;
1247 event->selection.requestor = (guint32) xevent->hwnd;
1248 event->selection.time = xevent->time;
1250 return_val = window_private && !window_private->destroyed;
1252 /* Again, will pass through switch below without match */
1254 else if (xevent->message == gdk_selection_clear_msg)
1256 GDK_NOTE (SELECTION, g_print ("gdk_selection_clear_msg: %#x\n",
1259 event->selection.type = GDK_SELECTION_CLEAR;
1260 event->selection.window = window;
1261 event->selection.selection = xevent->wParam;
1262 event->selection.time = xevent->time;
1264 return_val = window_private && !window_private->destroyed;
1266 /* Once again, we will pass through switch below without match */
1271 GdkFilterReturn result = GDK_FILTER_CONTINUE;
1273 tmp_list = client_filters;
1276 GdkClientFilter *filter = tmp_list->data;
1277 if (filter->type == xevent->message)
1279 GDK_NOTE (EVENTS, g_print ("client filter matched\n"));
1280 result = (*filter->function) (xevent, event, filter->data);
1283 case GDK_FILTER_REMOVE:
1287 case GDK_FILTER_TRANSLATE:
1291 case GDK_FILTER_CONTINUE:
1293 event->client.type = GDK_CLIENT_EVENT;
1294 event->client.window = window;
1295 event->client.message_type = xevent->message;
1296 event->client.data_format = 0;
1297 event->client.data.l[0] = xevent->wParam;
1298 event->client.data.l[1] = xevent->lParam;
1301 goto bypass_switch; /* Ouch */
1303 tmp_list = tmp_list->next;
1307 switch (xevent->message)
1312 g_print ("WM_SYSKEY%s: %#x key: %s %#x %#.08x\n",
1313 (xevent->message == WM_SYSKEYUP ? "UP" : "DOWN"),
1315 (GetKeyNameText (xevent->lParam, buf,
1321 /* Let the system handle Alt-Tab and Alt-Enter */
1322 if (xevent->wParam == VK_TAB
1323 || xevent->wParam == VK_RETURN
1324 || xevent->wParam == VK_F4)
1326 /* If posted without us having keyboard focus, ignore */
1327 if (!(xevent->lParam & 0x20000000))
1330 /* don't generate events for just the Alt key */
1331 if (xevent->wParam == VK_MENU)
1334 /* Jump to code in common with WM_KEYUP and WM_KEYDOWN */
1340 g_print ("WM_KEY%s: %#x key: %s %#x %#.08x\n",
1341 (xevent->message == WM_KEYUP ? "UP" : "DOWN"),
1343 (GetKeyNameText (xevent->lParam, buf,
1349 ignore_WM_CHAR = TRUE;
1351 if (k_grab_window != NULL
1352 && !k_grab_owner_events)
1354 /* Keyboard is grabbed with owner_events FALSE */
1356 g_print ("...grabbed, owner_events FALSE, "
1357 "sending to %#x\n", k_grab_window->xwindow));
1358 event->key.window = (GdkWindow *) k_grab_window;
1360 else if (window_private
1361 && (((xevent->message == WM_KEYUP
1362 || xevent->message == WM_SYSKEYUP)
1363 && !(window_private->event_mask & GDK_KEY_RELEASE_MASK))
1364 || ((xevent->message == WM_KEYDOWN
1365 || xevent->message == WM_SYSKEYDOWN)
1366 && !(window_private->event_mask & GDK_KEY_PRESS_MASK))))
1368 /* Owner window doesn't want it */
1369 if (k_grab_window != NULL
1370 && k_grab_owner_events)
1372 /* Keyboard is grabbed with owner_events TRUE */
1374 g_print ("...grabbed, owner_events TRUE, doesn't want it, "
1375 "sending to %#x\n", k_grab_window->xwindow));
1376 event->key.window = (GdkWindow *) k_grab_window;
1380 /* Owner doesn't want it, neither is it grabbed, so
1381 * propagate to parent.
1383 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1385 gdk_window_unref (window);
1386 window = window_private->parent;
1387 gdk_window_ref (window);
1388 window_private = (GdkWindowPrivate *) window;
1389 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1390 window_private->xwindow));
1395 switch (xevent->wParam)
1398 event->key.keyval = GDK_Pointer_Button1; break;
1400 event->key.keyval = GDK_Pointer_Button3; break;
1402 event->key.keyval = GDK_Pointer_Button2; break;
1404 event->key.keyval = GDK_Cancel; break;
1406 event->key.keyval = GDK_BackSpace; break;
1408 event->key.keyval = GDK_Tab; break;
1410 event->key.keyval = GDK_Clear; break;
1412 event->key.keyval = GDK_Return; break;
1414 event->key.keyval = GDK_Shift_L; break;
1416 if (xevent->lParam & 0x01000000)
1417 event->key.keyval = GDK_Control_R;
1419 event->key.keyval = GDK_Control_L;
1422 if (xevent->lParam & 0x01000000)
1424 /* AltGr key comes in as Control+Right Alt */
1425 if (GetKeyState (VK_CONTROL) < 0)
1427 ignore_WM_CHAR = FALSE;
1428 is_AltGr_key = TRUE;
1430 event->key.keyval = GDK_Alt_R;
1433 event->key.keyval = GDK_Alt_L;
1436 event->key.keyval = GDK_Pause; break;
1438 event->key.keyval = GDK_Caps_Lock; break;
1440 event->key.keyval = GDK_Escape; break;
1442 event->key.keyval = GDK_Prior; break;
1444 event->key.keyval = GDK_Next; break;
1446 event->key.keyval = GDK_End; break;
1448 event->key.keyval = GDK_Home; break;
1450 event->key.keyval = GDK_Left; break;
1452 event->key.keyval = GDK_Up; break;
1454 event->key.keyval = GDK_Right; break;
1456 event->key.keyval = GDK_Down; break;
1458 event->key.keyval = GDK_Select; break;
1460 event->key.keyval = GDK_Print; break;
1462 event->key.keyval = GDK_Execute; break;
1464 event->key.keyval = GDK_Insert; break;
1466 event->key.keyval = GDK_Delete; break;
1468 event->key.keyval = GDK_Help; break;
1479 /* Apparently applications work better if we just pass numpad digits
1480 * on as real digits? So wait for the WM_CHAR instead.
1482 ignore_WM_CHAR = FALSE;
1485 event->key.keyval = GDK_KP_Multiply; break;
1487 event->key.keyval = GDK_KP_Add; break;
1489 event->key.keyval = GDK_KP_Separator; break;
1491 event->key.keyval = GDK_KP_Subtract; break;
1494 event->key.keyval = GDK_KP_Decimal; break;
1496 /* The keypad decimal key should also be passed on as the decimal
1497 * sign ('.' or ',' depending on the Windows locale settings,
1498 * apparently). So wait for the WM_CHAR here, also.
1500 ignore_WM_CHAR = FALSE;
1504 event->key.keyval = GDK_KP_Divide; break;
1506 event->key.keyval = GDK_F1; break;
1508 event->key.keyval = GDK_F2; break;
1510 event->key.keyval = GDK_F3; break;
1512 event->key.keyval = GDK_F4; break;
1514 event->key.keyval = GDK_F5; break;
1516 event->key.keyval = GDK_F6; break;
1518 event->key.keyval = GDK_F7; break;
1520 event->key.keyval = GDK_F8; break;
1522 event->key.keyval = GDK_F9; break;
1524 event->key.keyval = GDK_F10; break;
1526 event->key.keyval = GDK_F11; break;
1528 event->key.keyval = GDK_F12; break;
1530 event->key.keyval = GDK_F13; break;
1532 event->key.keyval = GDK_F14; break;
1534 event->key.keyval = GDK_F15; break;
1536 event->key.keyval = GDK_F16; break;
1547 if (GetKeyState (VK_CONTROL) < 0)
1548 /* Control-digits won't come in as a WM_CHAR */
1549 event->key.keyval = GDK_0 + (xevent->wParam - '0');
1552 ignore_WM_CHAR = FALSE;
1553 event->key.keyval = GDK_VoidSymbol;
1557 if (xevent->message == WM_SYSKEYDOWN || xevent->message == WM_SYSKEYUP)
1559 event->key.keyval = xevent->wParam;
1563 ignore_WM_CHAR = FALSE;
1564 event->key.keyval = GDK_VoidSymbol;
1569 if (!ignore_WM_CHAR)
1572 is_AltGr_key = FALSE;
1573 event->key.type = ((xevent->message == WM_KEYDOWN
1574 || xevent->message == WM_SYSKEYDOWN) ?
1575 GDK_KEY_PRESS : GDK_KEY_RELEASE);
1576 event->key.window = window;
1577 event->key.time = xevent->time;
1578 event->key.state = 0;
1579 if (GetKeyState (VK_SHIFT) < 0)
1580 event->key.state |= GDK_SHIFT_MASK;
1581 if (GetKeyState (VK_CAPITAL) & 0x1)
1582 event->key.state |= GDK_LOCK_MASK;
1583 if (GetKeyState (VK_CONTROL) < 0)
1584 event->key.state |= GDK_CONTROL_MASK;
1585 if (xevent->wParam != VK_MENU && GetKeyState (VK_MENU) < 0)
1586 event->key.state |= GDK_MOD1_MASK;
1587 return_val = window_private && !window_private->destroyed;
1588 event->key.string = NULL;
1589 event->key.length = 0;
1594 g_print ("WM_CHAR: %#x char: %#x %#.08x %s\n",
1598 (ignore_WM_CHAR ? "ignored" : "")));
1602 ignore_WM_CHAR = FALSE;
1607 /* This doesn't handle the rather theorethical case that a window
1608 * wants key presses but still wants releases to be propagated,
1611 if (k_grab_window != NULL
1612 && !k_grab_owner_events)
1614 /* Keyboard is grabbed with owner_events FALSE */
1616 g_print ("...grabbed, owner_events FALSE, "
1617 "sending to %#x\n", k_grab_window->xwindow));
1618 event->key.window = (GdkWindow *) k_grab_window;
1620 else if (window_private
1621 && !(window_private->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)))
1623 /* Owner window doesn't want it */
1624 if (k_grab_window != NULL
1625 && k_grab_owner_events)
1627 /* Keyboard is grabbed with owner_events TRUE */
1629 g_print ("...grabbed, owner_events TRUE, doesn't want it, "
1630 "sending to %#x\n", k_grab_window->xwindow));
1631 event->key.window = (GdkWindow *) k_grab_window;
1635 /* Owner doesn't want it, neither is it grabbed, so
1636 * propagate to parent.
1638 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1639 g_assert_not_reached (); /* Should've been handled above */
1641 gdk_window_unref (window);
1642 window = window_private->parent;
1643 gdk_window_ref (window);
1644 window_private = (GdkWindowPrivate *) window;
1645 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1646 window_private->xwindow));
1651 return_val = window_private && !window_private->destroyed;
1652 if (return_val && (window_private->event_mask & GDK_KEY_RELEASE_MASK))
1654 /* Return the release event, and maybe append the press
1655 * event to the queued_events list (from which it will vbe
1656 * fetched before the release event).
1658 event->key.type = GDK_KEY_RELEASE;
1659 event->key.keyval = xevent->wParam;
1660 event->key.window = window;
1661 event->key.time = xevent->time;
1662 event->key.state = 0;
1663 if (GetKeyState (VK_SHIFT) < 0)
1664 event->key.state |= GDK_SHIFT_MASK;
1665 if (GetKeyState (VK_CAPITAL) & 0x1)
1666 event->key.state |= GDK_LOCK_MASK;
1669 else if (GetKeyState (VK_CONTROL) < 0)
1671 event->key.state |= GDK_CONTROL_MASK;
1672 if (event->key.keyval < ' ')
1673 event->key.keyval += '@';
1675 else if (event->key.keyval < ' ')
1677 event->key.state |= GDK_CONTROL_MASK;
1678 event->key.keyval += '@';
1680 if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
1681 event->key.state |= GDK_MOD1_MASK;
1682 event->key.string = g_malloc (2);
1683 event->key.length = 1;
1684 event->key.string[0] = xevent->wParam; /* ??? */
1685 event->key.string[1] = 0;
1687 if (window_private->event_mask & GDK_KEY_PRESS_MASK)
1689 /* Append also a GDK_KEY_PRESS event to the pushback list. */
1690 GdkEvent *event2 = gdk_event_copy (event);
1691 event2->key.type = GDK_KEY_PRESS;
1692 charcount = xevent->lParam & 0xFFFF;
1693 if (charcount > sizeof (buf)- 1)
1694 charcount = sizeof (buf) - 1;
1695 g_free (event2->key.string);
1696 event2->key.string = g_malloc (charcount + 1);
1697 for (i = 0; i < charcount; i++)
1698 event2->key.string[i] = event->key.keyval;
1699 event2->key.string[charcount] = 0;
1700 event2->key.length = charcount;
1702 gdk_event_queue_append (event2);
1705 else if (return_val && (window_private->event_mask & GDK_KEY_PRESS_MASK))
1707 /* Return just the GDK_KEY_PRESS event. */
1708 event->key.type = GDK_KEY_PRESS;
1709 charcount = xevent->lParam & 0xFFFF;
1710 if (charcount > sizeof (buf)- 1)
1711 charcount = sizeof (buf) - 1;
1712 event->key.keyval = xevent->wParam;
1713 event->key.window = window;
1714 event->key.time = xevent->time;
1715 event->key.state = 0;
1716 if (GetKeyState (VK_SHIFT) < 0)
1717 event->key.state |= GDK_SHIFT_MASK;
1718 if (GetKeyState (VK_CAPITAL) & 0x1)
1719 event->key.state |= GDK_LOCK_MASK;
1722 else if (GetKeyState (VK_CONTROL) < 0)
1724 event->key.state |= GDK_CONTROL_MASK;
1725 if (event->key.keyval < ' ')
1726 event->key.keyval += '@';
1728 else if (event->key.keyval < ' ')
1730 event->key.state |= GDK_CONTROL_MASK;
1731 event->key.keyval += '@';
1733 if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
1734 event->key.state |= GDK_MOD1_MASK;
1735 event->key.string = g_malloc (charcount + 1);
1736 for (i = 0; i < charcount; i++)
1737 event->key.string[i] = event->key.keyval;
1738 event->key.string[charcount] = 0;
1739 event->key.length = charcount;
1743 is_AltGr_key = FALSE;
1746 case WM_LBUTTONDOWN:
1749 case WM_MBUTTONDOWN:
1752 case WM_RBUTTONDOWN:
1757 g_print ("WM_%cBUTTONDOWN: %#x x,y: %d %d button: %d\n",
1760 LOWORD (xevent->lParam), HIWORD (xevent->lParam),
1764 && (window_private->extension_events != 0)
1765 && gdk_input_ignore_core)
1767 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1771 if (window != curWnd)
1772 synthesize_crossing_events (window, xevent);
1774 event->button.type = GDK_BUTTON_PRESS;
1776 event->button.window = window;
1778 mask = window_private->event_mask;
1782 if (p_grab_window != NULL
1783 && !p_grab_owner_events)
1785 /* Pointer is grabbed with owner_events FALSE */
1786 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
1787 mask = p_grab_event_mask;
1788 if (!(mask & GDK_BUTTON_PRESS_MASK))
1789 /* Grabber doesn't want it */
1792 event->button.window = (GdkWindow *) p_grab_window;
1793 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1794 p_grab_window->xwindow));
1796 else if (window_private
1797 && !(mask & GDK_BUTTON_PRESS_MASK))
1799 /* Owner window doesn't want it */
1800 if (p_grab_window != NULL
1801 && p_grab_owner_events)
1803 /* Pointer is grabbed wÃth owner_events TRUE */
1804 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
1805 mask = p_grab_event_mask;
1806 if (!(mask & GDK_BUTTON_PRESS_MASK))
1807 /* Grabber doesn't want it either */
1810 event->button.window = (GdkWindow *) p_grab_window;
1811 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1812 p_grab_window->xwindow));
1816 /* Owner doesn't want it, neither is it grabbed, so
1817 * propagate to parent.
1819 /* Yes, this code is duplicated twice below. So shoot me. */
1820 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1822 pt.x = LOWORD (xevent->lParam);
1823 pt.y = HIWORD (xevent->lParam);
1824 ClientToScreen (window_private->xwindow, &pt);
1825 gdk_window_unref (window);
1826 window = window_private->parent;
1827 gdk_window_ref (window);
1828 window_private = (GdkWindowPrivate *) window;
1829 ScreenToClient (window_private->xwindow, &pt);
1830 xevent->lParam = MAKELPARAM (pt.x, pt.y);
1831 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1832 window_private->xwindow));
1833 goto buttondown; /* What did Dijkstra say? */
1837 /* Emulate X11's automatic active grab */
1840 /* No explicit active grab, let's start one automatically */
1841 GDK_NOTE (EVENTS, g_print ("...automatic grab started\n"));
1842 gdk_pointer_grab (window, TRUE, window_private->event_mask,
1844 p_grab_automatic = TRUE;
1847 event->button.time = xevent->time;
1848 event->button.x = LOWORD (xevent->lParam);
1849 event->button.y = HIWORD (xevent->lParam);
1850 event->button.x_root = (gfloat)xevent->pt.x;
1851 event->button.y_root = (gfloat)xevent->pt.y;
1852 event->button.pressure = 0.5;
1853 event->button.xtilt = 0;
1854 event->button.ytilt = 0;
1855 event->button.state = 0;
1856 if (xevent->wParam & MK_CONTROL)
1857 event->button.state |= GDK_CONTROL_MASK;
1858 if (xevent->wParam & MK_LBUTTON)
1859 event->button.state |= GDK_BUTTON1_MASK;
1860 if (xevent->wParam & MK_MBUTTON)
1861 event->button.state |= GDK_BUTTON2_MASK;
1862 if (xevent->wParam & MK_RBUTTON)
1863 event->button.state |= GDK_BUTTON3_MASK;
1864 if (xevent->wParam & MK_SHIFT)
1865 event->button.state |= GDK_SHIFT_MASK;
1866 if (GetKeyState (VK_MENU) < 0)
1867 event->button.state |= GDK_MOD1_MASK;
1868 if (GetKeyState (VK_CAPITAL) & 0x1)
1869 event->button.state |= GDK_LOCK_MASK;
1870 event->button.button = button;
1871 event->button.source = GDK_SOURCE_MOUSE;
1872 event->button.deviceid = GDK_CORE_POINTER;
1874 if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) &&
1875 (event->button.window == button_window[1]) &&
1876 (event->button.button == button_number[1]))
1878 gdk_synthesize_click (event, 3);
1880 button_click_time[1] = 0;
1881 button_click_time[0] = 0;
1882 button_window[1] = NULL;
1883 button_window[0] = 0;
1884 button_number[1] = -1;
1885 button_number[0] = -1;
1887 else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) &&
1888 (event->button.window == button_window[0]) &&
1889 (event->button.button == button_number[0]))
1891 gdk_synthesize_click (event, 2);
1893 button_click_time[1] = button_click_time[0];
1894 button_click_time[0] = event->button.time;
1895 button_window[1] = button_window[0];
1896 button_window[0] = event->button.window;
1897 button_number[1] = button_number[0];
1898 button_number[0] = event->button.button;
1902 button_click_time[1] = 0;
1903 button_click_time[0] = event->button.time;
1904 button_window[1] = NULL;
1905 button_window[0] = event->button.window;
1906 button_number[1] = -1;
1907 button_number[0] = event->button.button;
1909 return_val = window_private && !window_private->destroyed;
1911 && p_grab_window != NULL
1912 && event->any.window == (GdkWindow *) p_grab_window
1913 && p_grab_window != window_private)
1915 /* Translate coordinates to grabber */
1916 pt.x = event->button.x;
1917 pt.y = event->button.y;
1918 ClientToScreen (window_private->xwindow, &pt);
1919 ScreenToClient (p_grab_window->xwindow, &pt);
1920 event->button.x = pt.x;
1921 event->button.y = pt.y;
1922 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
1937 g_print ("WM_%cBUTTONUP: %#x x,y: %d %d button: %d\n",
1940 LOWORD (xevent->lParam), HIWORD (xevent->lParam),
1944 && (window_private->extension_events != 0)
1945 && gdk_input_ignore_core)
1947 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1951 if (window != curWnd)
1952 synthesize_crossing_events (window, xevent);
1954 event->button.type = GDK_BUTTON_RELEASE;
1956 event->button.window = window;
1958 mask = window_private->event_mask;
1962 if (p_grab_window != NULL
1963 && !p_grab_owner_events)
1965 /* Pointer is grabbed with owner_events FALSE */
1966 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
1967 mask = p_grab_event_mask;
1968 if (!(mask & GDK_BUTTON_RELEASE_MASK))
1969 /* Grabber doesn't want it */
1972 event->button.window = (GdkWindow *) p_grab_window;
1973 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1974 p_grab_window->xwindow));
1976 else if (window_private
1977 && !(mask & GDK_BUTTON_RELEASE_MASK))
1979 /* Owner window doesn't want it */
1980 if (p_grab_window != NULL
1981 && p_grab_owner_events)
1983 /* Pointer is grabbed wÃth owner_events TRUE */
1984 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
1985 mask = p_grab_event_mask;
1986 if (!(mask & GDK_BUTTON_RELEASE_MASK))
1987 /* Grabber doesn't want it */
1990 event->button.window = (GdkWindow *) p_grab_window;
1991 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1992 p_grab_window->xwindow));
1996 /* Owner doesn't want it, neither is it grabbed, so
1997 * propagate to parent.
1999 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
2001 pt.x = LOWORD (xevent->lParam);
2002 pt.y = HIWORD (xevent->lParam);
2003 ClientToScreen (window_private->xwindow, &pt);
2004 gdk_window_unref (window);
2005 window = window_private->parent;
2006 gdk_window_ref (window);
2007 window_private = (GdkWindowPrivate *) window;
2008 ScreenToClient (window_private->xwindow, &pt);
2009 xevent->lParam = MAKELPARAM (pt.x, pt.y);
2010 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
2011 window_private->xwindow));
2016 event->button.time = xevent->time;
2017 event->button.x = LOWORD (xevent->lParam);
2018 event->button.y = HIWORD (xevent->lParam);
2019 event->button.x_root = (gfloat)xevent->pt.x;
2020 event->button.y_root = (gfloat)xevent->pt.y;
2021 event->button.pressure = 0.5;
2022 event->button.xtilt = 0;
2023 event->button.ytilt = 0;
2024 event->button.state = 0;
2025 if (xevent->wParam & MK_CONTROL)
2026 event->button.state |= GDK_CONTROL_MASK;
2027 if (xevent->wParam & MK_LBUTTON)
2028 event->button.state |= GDK_BUTTON1_MASK;
2029 if (xevent->wParam & MK_MBUTTON)
2030 event->button.state |= GDK_BUTTON2_MASK;
2031 if (xevent->wParam & MK_RBUTTON)
2032 event->button.state |= GDK_BUTTON3_MASK;
2033 if (xevent->wParam & MK_SHIFT)
2034 event->button.state |= GDK_SHIFT_MASK;
2035 event->button.button = button;
2036 event->button.source = GDK_SOURCE_MOUSE;
2037 event->button.deviceid = GDK_CORE_POINTER;
2038 return_val = window_private && !window_private->destroyed;
2040 && p_grab_window != NULL
2041 && event->any.window == (GdkWindow *) p_grab_window
2042 && p_grab_window != window_private)
2044 /* Translate coordinates to grabber */
2045 pt.x = event->button.x;
2046 pt.y = event->button.y;
2047 ClientToScreen (window_private->xwindow, &pt);
2048 ScreenToClient (p_grab_window->xwindow, &pt);
2049 event->button.x = pt.x;
2050 event->button.y = pt.y;
2051 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
2053 if (p_grab_window != NULL
2055 && (event->button.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0)
2056 gdk_pointer_ungrab (0);
2061 g_print ("WM_MOUSEMOVE: %#x %#x +%d+%d\n",
2062 xevent->hwnd, xevent->wParam,
2063 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2066 /* Try hard not to generate events for windows that shouldn't
2067 get any. This is hard because we don't want pushbuttons to
2068 highlight when the cursor moves over them if the window is
2069 inactive. We dont want tooltips windows to be active. OTOH,
2070 also menus are popup windows, but they definitely should
2071 get events. Aw shit. Skip this.
2073 dwStyle = GetWindowLong (xevent->hwnd, GWL_STYLE);
2074 if (active == NULL ||
2075 !(active == xevent->hwnd
2076 || (dwStyle & WS_POPUP)
2077 || IsChild (active, xevent->hwnd)))
2080 { /* HB: only process mouse move messages
2081 * if we own the active window.
2083 DWORD ProcessID_ActWin;
2084 DWORD ProcessID_this;
2086 GetWindowThreadProcessId(GetActiveWindow(), &ProcessID_ActWin);
2087 GetWindowThreadProcessId(xevent->hwnd, &ProcessID_this);
2088 if (ProcessID_ActWin != ProcessID_this)
2092 if (window != curWnd)
2093 synthesize_crossing_events (window, xevent);
2096 && (window_private->extension_events != 0)
2097 && gdk_input_ignore_core)
2099 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
2104 event->motion.type = GDK_MOTION_NOTIFY;
2105 event->motion.window = window;
2107 mask = window_private->event_mask;
2112 && !p_grab_owner_events)
2114 /* Pointer is grabbed with owner_events FALSE */
2116 g_print ("...grabbed, owner_events FALSE\n"));
2117 mask = p_grab_event_mask;
2118 if (!((mask & GDK_POINTER_MOTION_MASK)
2119 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2120 && (mask & GDK_BUTTON_MOTION_MASK))
2121 || ((xevent->wParam & MK_LBUTTON)
2122 && (mask & GDK_BUTTON1_MOTION_MASK))
2123 || ((xevent->wParam & MK_MBUTTON)
2124 && (mask & GDK_BUTTON2_MOTION_MASK))
2125 || ((xevent->wParam & MK_RBUTTON)
2126 && (mask & GDK_BUTTON3_MOTION_MASK))))
2129 event->motion.window = (GdkWindow *) p_grab_window;
2130 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
2131 p_grab_window->xwindow));
2133 else if (window_private
2134 && !((mask & GDK_POINTER_MOTION_MASK)
2135 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2136 && (mask & GDK_BUTTON_MOTION_MASK))
2137 || ((xevent->wParam & MK_LBUTTON)
2138 && (mask & GDK_BUTTON1_MOTION_MASK))
2139 || ((xevent->wParam & MK_MBUTTON)
2140 && (mask & GDK_BUTTON2_MOTION_MASK))
2141 || ((xevent->wParam & MK_RBUTTON)
2142 && (mask & GDK_BUTTON3_MOTION_MASK))))
2144 /* Owner window doesn't want it */
2145 if (p_grab_window != NULL
2146 && p_grab_owner_events)
2148 /* Pointer is grabbed wÃth owner_events TRUE */
2149 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
2150 mask = p_grab_event_mask;
2151 if (!((p_grab_event_mask & GDK_POINTER_MOTION_MASK)
2152 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2153 && (mask & GDK_BUTTON_MOTION_MASK))
2154 || ((xevent->wParam & MK_LBUTTON)
2155 && (mask & GDK_BUTTON1_MOTION_MASK))
2156 || ((xevent->wParam & MK_MBUTTON)
2157 && (mask & GDK_BUTTON2_MOTION_MASK))
2158 || ((xevent->wParam & MK_RBUTTON)
2159 && (mask & GDK_BUTTON3_MOTION_MASK))))
2160 /* Grabber doesn't want it either */
2163 event->motion.window = (GdkWindow *) p_grab_window;
2164 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
2165 p_grab_window->xwindow));
2169 /* Owner doesn't want it, neither is it grabbed, so
2170 * propagate to parent.
2172 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
2174 pt.x = LOWORD (xevent->lParam);
2175 pt.y = HIWORD (xevent->lParam);
2176 ClientToScreen (window_private->xwindow, &pt);
2177 gdk_window_unref (window);
2178 window = window_private->parent;
2179 gdk_window_ref (window);
2180 window_private = (GdkWindowPrivate *) window;
2181 ScreenToClient (window_private->xwindow, &pt);
2182 xevent->lParam = MAKELPARAM (pt.x, pt.y);
2183 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
2184 window_private->xwindow));
2189 event->motion.time = xevent->time;
2190 event->motion.x = curX = LOWORD (xevent->lParam);
2191 event->motion.y = curY = HIWORD (xevent->lParam);
2192 event->motion.x_root = xevent->pt.x;
2193 event->motion.y_root = xevent->pt.y;
2194 curXroot = event->motion.x_root;
2195 curYroot = event->motion.y_root;
2196 event->motion.pressure = 0.5;
2197 event->motion.xtilt = 0;
2198 event->motion.ytilt = 0;
2199 event->button.state = 0;
2200 if (xevent->wParam & MK_CONTROL)
2201 event->button.state |= GDK_CONTROL_MASK;
2202 if (xevent->wParam & MK_LBUTTON)
2203 event->button.state |= GDK_BUTTON1_MASK;
2204 if (xevent->wParam & MK_MBUTTON)
2205 event->button.state |= GDK_BUTTON2_MASK;
2206 if (xevent->wParam & MK_RBUTTON)
2207 event->button.state |= GDK_BUTTON3_MASK;
2208 if (xevent->wParam & MK_SHIFT)
2209 event->button.state |= GDK_SHIFT_MASK;
2210 if (mask & GDK_POINTER_MOTION_HINT_MASK)
2211 event->motion.is_hint = NotifyHint;
2213 event->motion.is_hint = NotifyNormal;
2214 event->motion.source = GDK_SOURCE_MOUSE;
2215 event->motion.deviceid = GDK_CORE_POINTER;
2217 return_val = window_private && !window_private->destroyed;
2219 && p_grab_window != NULL
2220 && event->any.window == (GdkWindow *) p_grab_window
2221 && p_grab_window != window_private)
2223 /* Translate coordinates to grabber */
2224 pt.x = event->motion.x;
2225 pt.y = event->motion.y;
2226 ClientToScreen (window_private->xwindow, &pt);
2227 ScreenToClient (p_grab_window->xwindow, &pt);
2228 event->motion.x = pt.x;
2229 event->motion.y = pt.y;
2230 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
2234 case WM_NCMOUSEMOVE:
2236 g_print ("WM_NCMOUSEMOVE: %#x x,y: %d %d\n",
2238 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2240 if (active == NULL || active != xevent->hwnd)
2243 curWnd_private = (GdkWindowPrivate *) curWnd;
2245 && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
2247 GDK_NOTE (EVENTS, g_print ("...synthesizing LEAVE_NOTIFY event\n"));
2249 event->crossing.type = GDK_LEAVE_NOTIFY;
2250 event->crossing.window = curWnd;
2251 event->crossing.subwindow = NULL;
2252 event->crossing.time = xevent->time;
2253 event->crossing.x = curX;
2254 event->crossing.y = curY;
2255 event->crossing.x_root = curXroot;
2256 event->crossing.y_root = curYroot;
2257 event->crossing.mode = GDK_CROSSING_NORMAL;
2258 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
2260 event->crossing.focus = TRUE; /* ??? */
2261 event->crossing.state = 0; /* ??? */
2262 gdk_window_unref (curWnd);
2272 && !(window_private->event_mask & GDK_FOCUS_CHANGE_MASK))
2275 GDK_NOTE (EVENTS, g_print ("WM_%sFOCUS: %#x\n",
2276 (xevent->message == WM_SETFOCUS ? "SET" : "KILL"),
2279 event->focus_change.type = GDK_FOCUS_CHANGE;
2280 event->focus_change.window = window;
2281 event->focus_change.in = (xevent->message == WM_SETFOCUS);
2282 return_val = window_private && !window_private->destroyed;
2286 GDK_NOTE (EVENTS, g_print ("WM_ACTIVATE: %#x %d\n",
2287 xevent->hwnd, LOWORD (xevent->wParam)));
2288 if (LOWORD (xevent->wParam) == WA_INACTIVE)
2289 active = (HWND) xevent->lParam;
2291 active = xevent->hwnd;
2295 GDK_NOTE (EVENTS, g_print ("WM_ERASEBKGND: %#x dc %#x\n",
2296 xevent->hwnd, xevent->wParam));
2298 if (!window_private || window_private->destroyed)
2300 colormap_private = (GdkColormapPrivate *) window_private->colormap;
2301 hdc = (HDC) xevent->wParam;
2302 if (colormap_private
2303 && colormap_private->xcolormap->rc_palette)
2307 if (SelectPalette (hdc, colormap_private->xcolormap->palette,
2309 g_warning ("WM_ERASEBKGND: SelectPalette failed");
2310 if ((k = RealizePalette (hdc)) == GDI_ERROR)
2311 g_warning ("WM_ERASEBKGND: RealizePalette failed");
2313 g_print ("WM_ERASEBKGND: selected %#x, realized %d colors\n",
2314 colormap_private->xcolormap->palette, k);
2317 *ret_val_flagp = TRUE;
2320 if (window_private->bg_type == GDK_WIN32_BG_TRANSPARENT)
2323 if (window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2325 /* If this window should have the same background as the
2326 * parent, fetch the parent. (And if the same goes for
2327 * the parent, fetch the grandparent, etc.)
2329 while (window_private
2330 && window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2331 window_private = (GdkWindowPrivate *) window_private->parent;
2334 if (window_private->bg_type == GDK_WIN32_BG_PIXEL)
2337 GetClipBox (hdc, &rect);
2338 GDK_NOTE (EVENTS, g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n",
2339 rect.right - rect.left,
2340 rect.bottom - rect.top,
2341 rect.left, rect.top,
2342 gdk_color_to_string (&window_private->bg_pixel)));
2343 #ifdef MULTIPLE_WINDOW_CLASSES
2344 bg = PALETTEINDEX (window_private->bg_pixel.pixel);
2346 bg = GetNearestColor (hdc, RGB (window_private->bg_pixel.red >> 8,
2347 window_private->bg_pixel.green >> 8,
2348 window_private->bg_pixel.blue >> 8));
2350 hbr = CreateSolidBrush (bg);
2352 g_print ("...CreateSolidBrush (%.08x) = %.08x\n", bg, hbr);
2354 if (!FillRect (hdc, &rect, hbr))
2355 g_warning ("WM_ERASEBKGND: FillRect failed");
2358 else if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
2360 GdkPixmapPrivate *pixmap_private;
2364 pixmap_private = (GdkPixmapPrivate *) window_private->bg_pixmap;
2365 GetClipBox (hdc, &rect);
2367 if (pixmap_private->width <= 8
2368 && pixmap_private->height <= 8)
2370 GDK_NOTE (EVENTS, g_print ("...small pixmap, using brush\n"));
2371 hbr = CreatePatternBrush (pixmap_private->xwindow);
2372 if (!FillRect (hdc, &rect, hbr))
2373 g_warning ("WM_ERASEBKGND: FillRect failed");
2379 g_print ("...blitting pixmap %#x (%dx%d) "
2380 "all over the place,\n"
2381 "...clip box = %dx%d@+%d+%d\n",
2382 pixmap_private->xwindow,
2383 pixmap_private->width, pixmap_private->height,
2384 rect.right - rect.left, rect.bottom - rect.top,
2385 rect.left, rect.top));
2387 if (!(bgdc = CreateCompatibleDC (hdc)))
2389 g_warning ("WM_ERASEBKGND: CreateCompatibleDC failed");
2392 if (!(oldbitmap = SelectObject (bgdc, pixmap_private->xwindow)))
2394 g_warning ("WM_ERASEBKGND: SelectObject failed");
2399 while (i < rect.right)
2402 while (j < rect.bottom)
2404 if (i + pixmap_private->width >= rect.left
2405 && j + pixmap_private->height >= rect.top)
2407 if (!BitBlt (hdc, i, j,
2408 pixmap_private->width, pixmap_private->height,
2409 bgdc, 0, 0, SRCCOPY))
2411 g_warning ("WM_ERASEBKGND: BitBlt failed");
2415 j += pixmap_private->height;
2417 i += pixmap_private->width;
2420 SelectObject (bgdc, oldbitmap);
2426 GDK_NOTE (EVENTS, g_print ("...BLACK_BRUSH (?)\n"));
2427 #ifdef MULTIPLE_WINDOW_CLASSES
2428 hbr = (HBRUSH) GetClassLong (window_private->xwindow,
2431 hbr = GetStockObject (BLACK_BRUSH);
2433 GetClipBox (hdc, &rect);
2434 if (!FillRect (hdc, &rect, hbr))
2435 g_warning ("WM_ERASEBKGND: FillRect failed");
2440 hdc = BeginPaint (xevent->hwnd, &paintstruct);
2443 g_print ("WM_PAINT: %#x %dx%d@+%d+%d %s dc %#x\n",
2445 paintstruct.rcPaint.right - paintstruct.rcPaint.left,
2446 paintstruct.rcPaint.bottom - paintstruct.rcPaint.top,
2447 paintstruct.rcPaint.left, paintstruct.rcPaint.top,
2448 (paintstruct.fErase ? "erase" : ""),
2451 EndPaint (xevent->hwnd, &paintstruct);
2454 && !(window_private->event_mask & GDK_EXPOSURE_MASK))
2457 event->expose.type = GDK_EXPOSE;
2458 event->expose.window = window;
2459 event->expose.area.x = paintstruct.rcPaint.left;
2460 event->expose.area.y = paintstruct.rcPaint.top;
2461 event->expose.area.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left;
2462 event->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
2463 event->expose.count = 1;
2465 return_val = window_private && !window_private->destroyed;
2468 #ifndef MULTIPLE_WINDOW_CLASSES
2470 GDK_NOTE (EVENTS, g_print ("WM_SETCURSOR: %#x %#x %#x\n",
2472 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2475 if (LOWORD (xevent->lParam) != HTCLIENT)
2477 if (p_grab_window != NULL && p_grab_cursor != NULL)
2478 SetCursor (p_grab_cursor);
2479 else if (window_private
2480 && !window_private->destroyed
2481 && window_private->xcursor)
2482 SetCursor (window_private->xcursor);
2483 *ret_val_flagp = TRUE;
2490 GDK_NOTE (EVENTS, g_print ("WM_QUERYOPEN: %#x\n",
2492 *ret_val_flagp = TRUE;
2496 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2499 event->any.type = GDK_MAP;
2500 event->any.window = window;
2502 return_val = window_private && !window_private->destroyed;
2508 GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#x %d\n",
2513 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2516 event->any.type = (xevent->wParam ? GDK_MAP : GDK_UNMAP);
2517 event->any.window = window;
2519 if (event->any.type == GDK_UNMAP
2520 && p_grab_window == window_private)
2521 gdk_pointer_ungrab (xevent->time);
2523 if (event->any.type == GDK_UNMAP
2524 && k_grab_window == window_private)
2525 gdk_keyboard_ungrab (xevent->time);
2527 return_val = window_private && !window_private->destroyed;
2532 g_print ("WM_SIZE: %#x %s %dx%d\n",
2534 (xevent->wParam == SIZE_MAXHIDE ? "MAXHIDE" :
2535 (xevent->wParam == SIZE_MAXIMIZED ? "MAXIMIZED" :
2536 (xevent->wParam == SIZE_MAXSHOW ? "MAXSHOW" :
2537 (xevent->wParam == SIZE_MINIMIZED ? "MINIMIZED" :
2538 (xevent->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
2539 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2542 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2544 if (window_private != NULL
2545 && xevent->wParam == SIZE_MINIMIZED)
2548 event->any.type = GDK_UNMAP;
2549 event->any.window = window;
2551 if (p_grab_window == window_private)
2552 gdk_pointer_ungrab (xevent->time);
2554 if (k_grab_window == window_private)
2555 gdk_keyboard_ungrab (xevent->time);
2557 return_val = !window_private->destroyed;
2560 else if (window_private != NULL
2561 && (xevent->wParam == SIZE_RESTORED
2562 || xevent->wParam == SIZE_MAXIMIZED)
2564 && window_private->window_type != GDK_WINDOW_CHILD
2568 if (LOWORD (xevent->lParam) == 0)
2571 event->configure.type = GDK_CONFIGURE;
2572 event->configure.window = window;
2575 ClientToScreen (xevent->hwnd, &pt);
2576 event->configure.x = pt.x;
2577 event->configure.y = pt.y;
2578 event->configure.width = LOWORD (xevent->lParam);
2579 event->configure.height = HIWORD (xevent->lParam);
2580 window_private->x = event->configure.x;
2581 window_private->y = event->configure.y;
2582 window_private->width = event->configure.width;
2583 window_private->height = event->configure.height;
2584 if (window_private->resize_count > 1)
2585 window_private->resize_count -= 1;
2587 return_val = !window_private->destroyed;
2589 && window_private->extension_events != 0
2590 && gdk_input_vtable.configure_event)
2591 gdk_input_vtable.configure_event (&event->configure, window);
2596 GDK_NOTE (EVENTS, g_print ("WM_SIZING: %#x\n", xevent->hwnd));
2597 if (ret_val_flagp == NULL)
2598 g_warning ("ret_val_flagp is NULL but we got a WM_SIZING?");
2599 else if (window_private != NULL
2600 && window_private->hint_flags &
2601 (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE))
2603 LPRECT lprc = (LPRECT) xevent->lParam;
2605 if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
2607 gint w = lprc->right - lprc->left;
2608 gint h = lprc->bottom - lprc->top;
2610 if (w < window_private->hint_min_width)
2612 if (xevent->wParam == WMSZ_BOTTOMLEFT
2613 || xevent->wParam == WMSZ_LEFT
2614 || xevent->wParam == WMSZ_TOPLEFT)
2615 lprc->left = lprc->right - window_private->hint_min_width;
2617 lprc->right = lprc->left + window_private->hint_min_width;
2618 *ret_val_flagp = TRUE;
2621 if (h < window_private->hint_min_height)
2623 if (xevent->wParam == WMSZ_BOTTOMLEFT
2624 || xevent->wParam == WMSZ_BOTTOM
2625 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2626 lprc->bottom = lprc->top + window_private->hint_min_height;
2628 lprc->top = lprc->bottom - window_private->hint_min_height;
2629 *ret_val_flagp = TRUE;
2633 if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
2635 gint w = lprc->right - lprc->left;
2636 gint h = lprc->bottom - lprc->top;
2638 if (w > window_private->hint_max_width)
2640 if (xevent->wParam == WMSZ_BOTTOMLEFT
2641 || xevent->wParam == WMSZ_LEFT
2642 || xevent->wParam == WMSZ_TOPLEFT)
2643 lprc->left = lprc->right - window_private->hint_max_width;
2645 lprc->right = lprc->left + window_private->hint_max_width;
2646 *ret_val_flagp = TRUE;
2649 if (h > window_private->hint_max_height)
2651 if (xevent->wParam == WMSZ_BOTTOMLEFT
2652 || xevent->wParam == WMSZ_BOTTOM
2653 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2654 lprc->bottom = lprc->top + window_private->hint_max_height;
2656 lprc->top = lprc->bottom - window_private->hint_max_height;
2657 *ret_val_flagp = TRUE;
2665 GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#x +%d+%d\n",
2667 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2670 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2672 if (window_private != NULL
2673 && window_private->window_type != GDK_WINDOW_CHILD)
2675 event->configure.type = GDK_CONFIGURE;
2676 event->configure.window = window;
2677 event->configure.x = LOWORD (xevent->lParam);
2678 event->configure.y = HIWORD (xevent->lParam);
2679 GetClientRect (xevent->hwnd, &rect);
2680 event->configure.width = rect.right;
2681 event->configure.height = rect.bottom;
2682 window_private->x = event->configure.x;
2683 window_private->y = event->configure.y;
2684 window_private->width = event->configure.width;
2685 window_private->height = event->configure.height;
2687 return_val = !window_private->destroyed;
2692 GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#x\n", xevent->hwnd));
2693 event->any.type = GDK_DELETE;
2694 event->any.window = window;
2696 return_val = window_private && !window_private->destroyed;
2700 /* No, don't use delayed rendering after all. It works only if the
2701 * delayed SetClipboardData is called from the WindowProc, it
2702 * seems. (The #else part below is test code for that. It succeeds
2703 * in setting the clipboard data. But if I call SetClipboardData
2704 * in gdk_property_change (as a consequence of the
2705 * GDK_SELECTION_REQUEST event), it fails. I deduce that this is
2706 * because delayed rendering requires that SetClipboardData is
2707 * called in the window procedure.)
2709 case WM_RENDERFORMAT:
2710 case WM_RENDERALLFORMATS:
2712 GDK_NOTE (EVENTS, flag = TRUE);
2713 GDK_NOTE (SELECTION, flag = TRUE);
2715 g_print ("WM_%s: %#x %#x (%s)\n",
2716 (xevent->message == WM_RENDERFORMAT ? "RENDERFORMAT" :
2717 "RENDERALLFORMATS"),
2720 (xevent->wParam == CF_TEXT ? "CF_TEXT" :
2721 (xevent->wParam == CF_DIB ? "CF_DIB" :
2722 (xevent->wParam == CF_UNICODETEXT ? "CF_UNICODETEXT" :
2723 (GetClipboardFormatName (xevent->wParam, buf, sizeof (buf)), buf)))));
2726 event->selection.type = GDK_SELECTION_REQUEST;
2727 event->selection.window = window;
2728 event->selection.selection = gdk_clipboard_atom;
2729 if (xevent->wParam == CF_TEXT)
2730 event->selection.target = GDK_TARGET_STRING;
2733 GetClipboardFormatName (xevent->wParam, buf, sizeof (buf));
2734 event->selection.target = gdk_atom_intern (buf, FALSE);
2736 event->selection.property = gdk_selection_property;
2737 event->selection.requestor = (guint32) xevent->hwnd;
2738 event->selection.time = xevent->time;
2739 return_val = window_private && !window_private->destroyed;
2741 /* Test code, to see if SetClipboardData works when called from
2742 * the window procedure.
2745 HGLOBAL hdata = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, 10);
2746 char *ptr = GlobalLock (hdata);
2747 strcpy (ptr, "Huhhaa");
2748 GlobalUnlock (hdata);
2749 if (!SetClipboardData (CF_TEXT, hdata))
2750 g_print ("SetClipboardData failed: %d\n", GetLastError ());
2753 *ret_val_flagp = TRUE;
2757 #endif /* No delayed rendering */
2760 GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#x\n", xevent->hwnd));
2761 event->any.type = GDK_DESTROY;
2762 event->any.window = window;
2763 if (window != NULL && window == curWnd)
2765 gdk_window_unref (curWnd);
2769 if (p_grab_window == window_private)
2770 gdk_pointer_ungrab (xevent->time);
2772 if (k_grab_window == window_private)
2773 gdk_keyboard_ungrab (xevent->time);
2775 return_val = window_private && !window_private->destroyed;
2778 /* Handle WINTAB events here, as we know that gdkinput.c will
2779 * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
2780 * constants as case labels.
2783 GDK_NOTE (EVENTS, g_print ("WT_PACKET: %d %#x\n",
2784 xevent->wParam, xevent->lParam));
2788 GDK_NOTE (EVENTS, g_print ("WT_CSRCHANGE: %d %#x\n",
2789 xevent->wParam, xevent->lParam));
2794 g_print ("WT_PROXIMITY: %#x %d %d\n",
2796 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2798 return_val = gdk_input_vtable.other_event(event, xevent);
2806 if (event->any.window)
2807 gdk_window_ref (event->any.window);
2808 if (((event->any.type == GDK_ENTER_NOTIFY) ||
2809 (event->any.type == GDK_LEAVE_NOTIFY)) &&
2810 (event->crossing.subwindow != NULL))
2811 gdk_window_ref (event->crossing.subwindow);
2815 /* Mark this event as having no resources to be freed */
2816 event->any.window = NULL;
2817 event->any.type = GDK_NOTHING;
2821 gdk_window_unref (window);
2827 gdk_events_queue (void)
2833 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: %s\n",
2834 (queued_events ? "yes" : "none")));
2836 while (!gdk_event_queue_find_first()
2837 && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
2839 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: got event\n"));
2840 TranslateMessage (&msg);
2842 event = gdk_event_new ();
2844 event->any.type = GDK_NOTHING;
2845 event->any.window = NULL;
2846 event->any.send_event = FALSE;
2848 ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
2850 gdk_event_queue_append (event);
2853 if (gdk_event_translate (event, &msg, NULL, NULL))
2854 ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
2857 DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
2858 gdk_event_queue_remove_link (node);
2859 g_list_free_1 (node);
2860 gdk_event_free (event);
2866 gdk_event_prepare (gpointer source_data,
2867 GTimeVal *current_time,
2873 GDK_THREADS_ENTER ();
2877 GDK_NOTE (EVENTS, g_print ("gdk_event_prepare\n"));
2879 retval = (gdk_event_queue_find_first () != NULL)
2880 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2882 GDK_THREADS_LEAVE ();
2888 gdk_event_check (gpointer source_data,
2889 GTimeVal *current_time)
2894 GDK_NOTE (EVENTS, g_print ("gdk_event_check\n"));
2896 GDK_THREADS_ENTER ();
2898 if (event_poll_fd.revents & G_IO_IN)
2899 retval = (gdk_event_queue_find_first () != NULL)
2900 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2904 GDK_THREADS_LEAVE ();
2910 gdk_event_unqueue (void)
2912 GdkEvent *event = NULL;
2915 tmp_list = gdk_event_queue_find_first ();
2919 event = tmp_list->data;
2920 gdk_event_queue_remove_link (tmp_list);
2921 g_list_free_1 (tmp_list);
2928 gdk_event_dispatch (gpointer source_data,
2929 GTimeVal *current_time,
2934 GDK_NOTE (EVENTS, g_print ("gdk_event_dispatch\n"));
2936 GDK_THREADS_ENTER ();
2939 event = gdk_event_unqueue();
2944 (*event_func) (event, event_data);
2946 gdk_event_free (event);
2949 GDK_THREADS_LEAVE ();
2955 gdk_synthesize_click (GdkEvent *event,
2958 GdkEvent temp_event;
2960 g_return_if_fail (event != NULL);
2962 temp_event = *event;
2963 temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
2965 gdk_event_put (&temp_event);
2968 /* Sends a ClientMessage to all toplevel client windows */
2970 gdk_event_send_client_message (GdkEvent *event, guint32 xid)
2977 gdk_event_send_clientmessage_toall (GdkEvent *event)