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)
2479 GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", p_grab_cursor));
2480 SetCursor (p_grab_cursor);
2482 else if (window_private
2483 && !window_private->destroyed
2484 && window_private->xcursor)
2486 GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n",
2487 window_private->xcursor));
2488 SetCursor (window_private->xcursor);
2490 *ret_val_flagp = TRUE;
2497 GDK_NOTE (EVENTS, g_print ("WM_QUERYOPEN: %#x\n",
2499 *ret_val_flagp = TRUE;
2503 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2506 event->any.type = GDK_MAP;
2507 event->any.window = window;
2509 return_val = window_private && !window_private->destroyed;
2515 GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#x %d\n",
2520 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2523 event->any.type = (xevent->wParam ? GDK_MAP : GDK_UNMAP);
2524 event->any.window = window;
2526 if (event->any.type == GDK_UNMAP
2527 && p_grab_window == window_private)
2528 gdk_pointer_ungrab (xevent->time);
2530 if (event->any.type == GDK_UNMAP
2531 && k_grab_window == window_private)
2532 gdk_keyboard_ungrab (xevent->time);
2534 return_val = window_private && !window_private->destroyed;
2539 g_print ("WM_SIZE: %#x %s %dx%d\n",
2541 (xevent->wParam == SIZE_MAXHIDE ? "MAXHIDE" :
2542 (xevent->wParam == SIZE_MAXIMIZED ? "MAXIMIZED" :
2543 (xevent->wParam == SIZE_MAXSHOW ? "MAXSHOW" :
2544 (xevent->wParam == SIZE_MINIMIZED ? "MINIMIZED" :
2545 (xevent->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
2546 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2549 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2551 if (window_private != NULL
2552 && xevent->wParam == SIZE_MINIMIZED)
2555 event->any.type = GDK_UNMAP;
2556 event->any.window = window;
2558 if (p_grab_window == window_private)
2559 gdk_pointer_ungrab (xevent->time);
2561 if (k_grab_window == window_private)
2562 gdk_keyboard_ungrab (xevent->time);
2564 return_val = !window_private->destroyed;
2567 else if (window_private != NULL
2568 && (xevent->wParam == SIZE_RESTORED
2569 || xevent->wParam == SIZE_MAXIMIZED)
2571 && window_private->window_type != GDK_WINDOW_CHILD
2575 if (LOWORD (xevent->lParam) == 0)
2578 event->configure.type = GDK_CONFIGURE;
2579 event->configure.window = window;
2582 ClientToScreen (xevent->hwnd, &pt);
2583 event->configure.x = pt.x;
2584 event->configure.y = pt.y;
2585 event->configure.width = LOWORD (xevent->lParam);
2586 event->configure.height = HIWORD (xevent->lParam);
2587 window_private->x = event->configure.x;
2588 window_private->y = event->configure.y;
2589 window_private->width = event->configure.width;
2590 window_private->height = event->configure.height;
2591 if (window_private->resize_count > 1)
2592 window_private->resize_count -= 1;
2594 return_val = !window_private->destroyed;
2596 && window_private->extension_events != 0
2597 && gdk_input_vtable.configure_event)
2598 gdk_input_vtable.configure_event (&event->configure, window);
2603 GDK_NOTE (EVENTS, g_print ("WM_SIZING: %#x\n", xevent->hwnd));
2604 if (ret_val_flagp == NULL)
2605 g_warning ("ret_val_flagp is NULL but we got a WM_SIZING?");
2606 else if (window_private != NULL
2607 && window_private->hint_flags &
2608 (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE))
2610 LPRECT lprc = (LPRECT) xevent->lParam;
2612 if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
2614 gint w = lprc->right - lprc->left;
2615 gint h = lprc->bottom - lprc->top;
2617 if (w < window_private->hint_min_width)
2619 if (xevent->wParam == WMSZ_BOTTOMLEFT
2620 || xevent->wParam == WMSZ_LEFT
2621 || xevent->wParam == WMSZ_TOPLEFT)
2622 lprc->left = lprc->right - window_private->hint_min_width;
2624 lprc->right = lprc->left + window_private->hint_min_width;
2625 *ret_val_flagp = TRUE;
2628 if (h < window_private->hint_min_height)
2630 if (xevent->wParam == WMSZ_BOTTOMLEFT
2631 || xevent->wParam == WMSZ_BOTTOM
2632 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2633 lprc->bottom = lprc->top + window_private->hint_min_height;
2635 lprc->top = lprc->bottom - window_private->hint_min_height;
2636 *ret_val_flagp = TRUE;
2640 if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
2642 gint w = lprc->right - lprc->left;
2643 gint h = lprc->bottom - lprc->top;
2645 if (w > window_private->hint_max_width)
2647 if (xevent->wParam == WMSZ_BOTTOMLEFT
2648 || xevent->wParam == WMSZ_LEFT
2649 || xevent->wParam == WMSZ_TOPLEFT)
2650 lprc->left = lprc->right - window_private->hint_max_width;
2652 lprc->right = lprc->left + window_private->hint_max_width;
2653 *ret_val_flagp = TRUE;
2656 if (h > window_private->hint_max_height)
2658 if (xevent->wParam == WMSZ_BOTTOMLEFT
2659 || xevent->wParam == WMSZ_BOTTOM
2660 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2661 lprc->bottom = lprc->top + window_private->hint_max_height;
2663 lprc->top = lprc->bottom - window_private->hint_max_height;
2664 *ret_val_flagp = TRUE;
2672 GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#x +%d+%d\n",
2674 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2677 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2679 if (window_private != NULL
2680 && window_private->window_type != GDK_WINDOW_CHILD)
2682 event->configure.type = GDK_CONFIGURE;
2683 event->configure.window = window;
2684 event->configure.x = LOWORD (xevent->lParam);
2685 event->configure.y = HIWORD (xevent->lParam);
2686 GetClientRect (xevent->hwnd, &rect);
2687 event->configure.width = rect.right;
2688 event->configure.height = rect.bottom;
2689 window_private->x = event->configure.x;
2690 window_private->y = event->configure.y;
2691 window_private->width = event->configure.width;
2692 window_private->height = event->configure.height;
2694 return_val = !window_private->destroyed;
2699 GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#x\n", xevent->hwnd));
2700 event->any.type = GDK_DELETE;
2701 event->any.window = window;
2703 return_val = window_private && !window_private->destroyed;
2707 /* No, don't use delayed rendering after all. It works only if the
2708 * delayed SetClipboardData is called from the WindowProc, it
2709 * seems. (The #else part below is test code for that. It succeeds
2710 * in setting the clipboard data. But if I call SetClipboardData
2711 * in gdk_property_change (as a consequence of the
2712 * GDK_SELECTION_REQUEST event), it fails. I deduce that this is
2713 * because delayed rendering requires that SetClipboardData is
2714 * called in the window procedure.)
2716 case WM_RENDERFORMAT:
2717 case WM_RENDERALLFORMATS:
2719 GDK_NOTE (EVENTS, flag = TRUE);
2720 GDK_NOTE (SELECTION, flag = TRUE);
2722 g_print ("WM_%s: %#x %#x (%s)\n",
2723 (xevent->message == WM_RENDERFORMAT ? "RENDERFORMAT" :
2724 "RENDERALLFORMATS"),
2727 (xevent->wParam == CF_TEXT ? "CF_TEXT" :
2728 (xevent->wParam == CF_DIB ? "CF_DIB" :
2729 (xevent->wParam == CF_UNICODETEXT ? "CF_UNICODETEXT" :
2730 (GetClipboardFormatName (xevent->wParam, buf, sizeof (buf)), buf)))));
2733 event->selection.type = GDK_SELECTION_REQUEST;
2734 event->selection.window = window;
2735 event->selection.selection = gdk_clipboard_atom;
2736 if (xevent->wParam == CF_TEXT)
2737 event->selection.target = GDK_TARGET_STRING;
2740 GetClipboardFormatName (xevent->wParam, buf, sizeof (buf));
2741 event->selection.target = gdk_atom_intern (buf, FALSE);
2743 event->selection.property = gdk_selection_property;
2744 event->selection.requestor = (guint32) xevent->hwnd;
2745 event->selection.time = xevent->time;
2746 return_val = window_private && !window_private->destroyed;
2748 /* Test code, to see if SetClipboardData works when called from
2749 * the window procedure.
2752 HGLOBAL hdata = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, 10);
2753 char *ptr = GlobalLock (hdata);
2754 strcpy (ptr, "Huhhaa");
2755 GlobalUnlock (hdata);
2756 if (!SetClipboardData (CF_TEXT, hdata))
2757 g_print ("SetClipboardData failed: %d\n", GetLastError ());
2760 *ret_val_flagp = TRUE;
2764 #endif /* No delayed rendering */
2767 GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#x\n", xevent->hwnd));
2768 event->any.type = GDK_DESTROY;
2769 event->any.window = window;
2770 if (window != NULL && window == curWnd)
2772 gdk_window_unref (curWnd);
2776 if (p_grab_window == window_private)
2777 gdk_pointer_ungrab (xevent->time);
2779 if (k_grab_window == window_private)
2780 gdk_keyboard_ungrab (xevent->time);
2782 return_val = window_private && !window_private->destroyed;
2785 /* Handle WINTAB events here, as we know that gdkinput.c will
2786 * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
2787 * constants as case labels.
2790 GDK_NOTE (EVENTS, g_print ("WT_PACKET: %d %#x\n",
2791 xevent->wParam, xevent->lParam));
2795 GDK_NOTE (EVENTS, g_print ("WT_CSRCHANGE: %d %#x\n",
2796 xevent->wParam, xevent->lParam));
2801 g_print ("WT_PROXIMITY: %#x %d %d\n",
2803 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2805 return_val = gdk_input_vtable.other_event(event, xevent);
2813 if (event->any.window)
2814 gdk_window_ref (event->any.window);
2815 if (((event->any.type == GDK_ENTER_NOTIFY) ||
2816 (event->any.type == GDK_LEAVE_NOTIFY)) &&
2817 (event->crossing.subwindow != NULL))
2818 gdk_window_ref (event->crossing.subwindow);
2822 /* Mark this event as having no resources to be freed */
2823 event->any.window = NULL;
2824 event->any.type = GDK_NOTHING;
2828 gdk_window_unref (window);
2834 gdk_events_queue (void)
2840 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: %s\n",
2841 (queued_events ? "yes" : "none")));
2843 while (!gdk_event_queue_find_first()
2844 && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
2846 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: got event\n"));
2847 TranslateMessage (&msg);
2849 event = gdk_event_new ();
2851 event->any.type = GDK_NOTHING;
2852 event->any.window = NULL;
2853 event->any.send_event = FALSE;
2855 ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
2857 gdk_event_queue_append (event);
2860 if (gdk_event_translate (event, &msg, NULL, NULL))
2861 ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
2864 DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
2865 gdk_event_queue_remove_link (node);
2866 g_list_free_1 (node);
2867 gdk_event_free (event);
2873 gdk_event_prepare (gpointer source_data,
2874 GTimeVal *current_time,
2880 GDK_THREADS_ENTER ();
2884 GDK_NOTE (EVENTS, g_print ("gdk_event_prepare\n"));
2886 retval = (gdk_event_queue_find_first () != NULL)
2887 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2889 GDK_THREADS_LEAVE ();
2895 gdk_event_check (gpointer source_data,
2896 GTimeVal *current_time)
2901 GDK_NOTE (EVENTS, g_print ("gdk_event_check\n"));
2903 GDK_THREADS_ENTER ();
2905 if (event_poll_fd.revents & G_IO_IN)
2906 retval = (gdk_event_queue_find_first () != NULL)
2907 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2911 GDK_THREADS_LEAVE ();
2917 gdk_event_unqueue (void)
2919 GdkEvent *event = NULL;
2922 tmp_list = gdk_event_queue_find_first ();
2926 event = tmp_list->data;
2927 gdk_event_queue_remove_link (tmp_list);
2928 g_list_free_1 (tmp_list);
2935 gdk_event_dispatch (gpointer source_data,
2936 GTimeVal *current_time,
2941 GDK_NOTE (EVENTS, g_print ("gdk_event_dispatch\n"));
2943 GDK_THREADS_ENTER ();
2946 event = gdk_event_unqueue();
2951 (*event_func) (event, event_data);
2953 gdk_event_free (event);
2956 GDK_THREADS_LEAVE ();
2962 gdk_synthesize_click (GdkEvent *event,
2965 GdkEvent temp_event;
2967 g_return_if_fail (event != NULL);
2969 temp_event = *event;
2970 temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
2972 gdk_event_put (&temp_event);
2975 /* Sends a ClientMessage to all toplevel client windows */
2977 gdk_event_send_client_message (GdkEvent *event, guint32 xid)
2984 gdk_event_send_clientmessage_toall (GdkEvent *event)