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/.
33 #include "gdkprivate.h"
36 #include "gdkkeysyms.h"
41 #include "gdkinputprivate.h"
43 #define PING() printf("%s: %d\n",__FILE__,__LINE__),fflush(stdout)
45 typedef struct _GdkIOClosure GdkIOClosure;
46 typedef struct _GdkEventPrivate GdkEventPrivate;
48 #define DOUBLE_CLICK_TIME 250
49 #define TRIPLE_CLICK_TIME 500
50 #define DOUBLE_CLICK_DIST 5
51 #define TRIPLE_CLICK_DIST 5
53 gint gdk_event_func_from_window_proc = FALSE;
57 /* Following flag is set for events on the event queue during
58 * translation and cleared afterwards.
60 GDK_EVENT_PENDING = 1 << 0
65 GdkInputFunction function;
66 GdkInputCondition condition;
67 GdkDestroyNotify notify;
71 struct _GdkEventPrivate
78 * Private function declarations
81 static GdkEvent *gdk_event_new (void);
82 static GdkFilterReturn
83 gdk_event_apply_filters (MSG *xevent,
86 static gint gdk_event_translate (GdkEvent *event,
88 gboolean *ret_val_flagp,
90 static void gdk_events_queue (void);
91 static GdkEvent *gdk_event_unqueue (void);
92 static gboolean gdk_event_prepare (gpointer source_data,
93 GTimeVal *current_time,
95 static gboolean gdk_event_check (gpointer source_data,
96 GTimeVal *current_time);
97 static gboolean gdk_event_dispatch (gpointer source_data,
98 GTimeVal *current_time,
101 static void gdk_synthesize_click (GdkEvent *event,
104 /* Private variable declarations
107 static guint32 button_click_time[2]; /* The last 2 button click times. Used
108 * to determine if the latest button click
109 * is part of a double or triple click.
111 static GdkWindow *button_window[2]; /* The last 2 windows to receive button presses.
112 * Also used to determine if the latest button
113 * click is part of a double or triple click.
115 static guint button_number[2]; /* The last 2 buttons to be pressed.
117 static GdkWindow *p_grab_window = NULL; /* Window that currently
118 * holds the pointer grab
121 static GdkWindow *k_grab_window = NULL; /* Window the holds the
125 static GList *client_filters; /* Filters for client messages */
127 static gboolean p_grab_automatic;
128 static GdkEventMask p_grab_event_mask;
129 static gboolean p_grab_owner_events, k_grab_owner_events;
130 static HCURSOR p_grab_cursor;
132 static GdkEventFunc event_func = NULL; /* Callback for events */
133 static gpointer event_data = NULL;
134 static GDestroyNotify event_notify = NULL;
136 static GList *client_filters; /* Filters for client messages */
138 /* FIFO's for event queue, and for events put back using
141 static GList *queued_events = NULL;
142 static GList *queued_tail = NULL;
144 static GSourceFuncs event_funcs = {
148 (GDestroyNotify)g_free
151 GPollFD event_poll_fd;
153 static GdkWindow *curWnd = NULL;
154 static HWND active = NULL;
155 static gint curX, curY;
156 static gdouble curXroot, curYroot;
157 static UINT gdk_ping_msg;
158 static gboolean ignore_WM_CHAR = FALSE;
159 static gboolean is_AltGr_key = FALSE;
162 gdk_WindowProc(HWND hwnd,
172 gboolean ret_val_flag;
174 GDK_NOTE (EVENTS, g_print ("gdk_WindowProc: %#x\n", message));
177 msg.message = message;
180 msg.time = GetTickCount ();
181 pos = GetMessagePos ();
182 msg.pt.x = LOWORD (pos);
183 msg.pt.y = HIWORD (pos);
185 if (gdk_event_translate (&event, &msg, &ret_val_flag, &ret_val))
188 /* Compress configure events */
189 if (event.any.type == GDK_CONFIGURE)
191 GList *list = queued_events;
194 && (((GdkEvent *)list->data)->any.type != GDK_CONFIGURE
195 || ((GdkEvent *)list->data)->any.window != event.any.window))
199 *((GdkEvent *)list->data) = event;
200 gdk_window_unref (event.any.window);
201 /* Wake up WaitMessage */
202 PostMessage (NULL, gdk_ping_msg, 0, 0);
207 eventp = gdk_event_new ();
210 /* Philippe Colantoni <colanton@aris.ss.uci.edu> suggests this
211 * in order to handle events while opaque resizing neatly. I
212 * don't want it as default. Set the
213 * GDK_EVENT_FUNC_FROM_WINDOW_PROC env var to get this
216 if (gdk_event_func_from_window_proc && event_func)
218 GDK_THREADS_ENTER ();
220 (*event_func) (eventp, event_data);
221 gdk_event_free (eventp);
223 GDK_THREADS_LEAVE ();
227 gdk_event_queue_append (eventp);
229 /* Wake up WaitMessage */
230 PostMessage (NULL, gdk_ping_msg, 0, 0);
243 return DefWindowProc (hwnd, message, wParam, lParam);
246 /*********************************************
247 * Functions for maintaining the event queue *
248 *********************************************/
250 /*************************************************************
251 * gdk_event_queue_find_first:
252 * Find the first event on the queue that is not still
257 * Pointer to the list node for that event, or NULL
258 *************************************************************/
261 gdk_event_queue_find_first (void)
263 GList *tmp_list = queued_events;
267 GdkEventPrivate *event = tmp_list->data;
268 if (!(event->flags & GDK_EVENT_PENDING))
271 tmp_list = g_list_next (tmp_list);
277 /*************************************************************
278 * gdk_event_queue_remove_link:
279 * Remove a specified list node from the event queue.
281 * node: Node to remove.
283 *************************************************************/
286 gdk_event_queue_remove_link (GList *node)
289 node->prev->next = node->next;
291 queued_events = node->next;
294 node->next->prev = node->prev;
296 queued_tail = node->prev;
300 /*************************************************************
301 * gdk_event_queue_append:
302 * Append an event onto the tail of the event queue.
304 * event: Event to append.
306 *************************************************************/
309 gdk_event_queue_append (GdkEvent *event)
311 queued_tail = g_list_append (queued_tail, event);
314 queued_events = queued_tail;
316 queued_tail = queued_tail->next;
320 gdk_events_init (void)
322 if (g_pipe_readable_msg == 0)
323 g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable");
325 g_source_add (GDK_PRIORITY_EVENTS, TRUE, &event_funcs, NULL, NULL, NULL);
327 event_poll_fd.fd = G_WIN32_MSG_HANDLE;
328 event_poll_fd.events = G_IO_IN;
330 g_main_add_poll (&event_poll_fd, GDK_PRIORITY_EVENTS);
332 button_click_time[0] = 0;
333 button_click_time[1] = 0;
334 button_window[0] = NULL;
335 button_window[1] = NULL;
336 button_number[0] = -1;
337 button_number[1] = -1;
339 gdk_ping_msg = RegisterWindowMessage ("gdk-ping");
343 *--------------------------------------------------------------
346 * Returns if events are pending on the queue.
351 * Returns TRUE if events are pending
355 *--------------------------------------------------------------
359 gdk_events_pending (void)
363 return (gdk_event_queue_find_first() || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE));
367 *--------------------------------------------------------------
368 * gdk_event_get_graphics_expose
370 * Waits for a GraphicsExpose or NoExpose event
375 * For GraphicsExpose events, returns a pointer to the event
376 * converted into a GdkEvent Otherwise, returns NULL.
380 *-------------------------------------------------------------- */
383 gdk_event_get_graphics_expose (GdkWindow *window)
387 GdkWindowPrivate *private = (GdkWindowPrivate *) window;
389 g_return_val_if_fail (window != NULL, NULL);
391 GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose\n"));
394 /* Some nasty bugs here, just return NULL for now. */
397 if (GetMessage (&xevent, private->xwindow, WM_PAINT, WM_PAINT))
399 event = gdk_event_new ();
401 if (gdk_event_translate (event, &xevent, NULL, NULL))
404 gdk_event_free (event);
411 /************************
412 * Exposure compression *
413 ************************/
415 /* I don't bother with exposure compression on Win32. Windows compresses
416 * WM_PAINT events by itself.
419 /*************************************************************
420 * gdk_event_handler_set:
423 * func: Callback function to be called for each event.
424 * data: Data supplied to the function
425 * notify: function called when function is no longer needed
428 *************************************************************/
431 gdk_event_handler_set (GdkEventFunc func,
433 GDestroyNotify notify)
436 (*event_notify) (event_data);
440 event_notify = notify;
444 *--------------------------------------------------------------
447 * Gets the next event.
452 * If an event is waiting that we care about, returns
453 * a pointer to that event, to be freed with gdk_event_free.
454 * Otherwise, returns NULL.
458 *--------------------------------------------------------------
466 return gdk_event_unqueue();
470 *--------------------------------------------------------------
473 * Gets the next event.
478 * If an event is waiting that we care about, returns
479 * a copy of that event, but does not remove it from
480 * the queue. The pointer is to be freed with gdk_event_free.
481 * Otherwise, returns NULL.
485 *--------------------------------------------------------------
489 gdk_event_peek (void)
493 tmp_list = gdk_event_queue_find_first ();
496 return gdk_event_copy (tmp_list->data);
502 gdk_event_put (GdkEvent *event)
507 g_return_if_fail (event != NULL);
509 new_event = gdk_event_copy (event);
511 gdk_event_queue_append (new_event);
515 *--------------------------------------------------------------
518 * Copy a event structure into new storage.
521 * "event" is the event struct to copy.
524 * A new event structure. Free it with gdk_event_free.
527 * The reference count of the window in the event is increased.
529 *--------------------------------------------------------------
532 static GMemChunk *event_chunk = NULL;
537 GdkEventPrivate *new_event;
539 if (event_chunk == NULL)
540 event_chunk = g_mem_chunk_new ("events",
541 sizeof (GdkEventPrivate),
545 new_event = g_chunk_new (GdkEventPrivate, event_chunk);
546 new_event->flags = 0;
548 return (GdkEvent *) new_event;
552 gdk_event_copy (GdkEvent *event)
557 g_return_val_if_fail (event != NULL, NULL);
559 new_event = gdk_event_new ();
562 gdk_window_ref (new_event->any.window);
564 switch (event->any.type)
567 case GDK_KEY_RELEASE:
568 if (event->key.length > 0)
570 s = event->key.string;
571 new_event->key.string = g_malloc (event->key.length + 1);
572 memcpy (new_event->key.string, s, event->key.length + 1);
576 case GDK_ENTER_NOTIFY:
577 case GDK_LEAVE_NOTIFY:
578 if (event->crossing.subwindow != NULL)
579 gdk_window_ref (event->crossing.subwindow);
584 case GDK_DRAG_MOTION:
585 case GDK_DRAG_STATUS:
587 case GDK_DROP_FINISHED:
588 gdk_drag_context_ref (event->dnd.context);
599 *--------------------------------------------------------------
602 * Free a event structure obtained from gdk_event_copy. Do not use
603 * with other event structures.
606 * "event" is the event struct to free.
611 * The reference count of the window in the event is decreased and
612 * might be freed, too.
614 *-------------------------------------------------------------- */
617 gdk_event_free (GdkEvent *event)
619 g_return_if_fail (event != NULL);
621 g_assert (event_chunk != NULL); /* paranoid */
623 if (event->any.window)
624 gdk_window_unref (event->any.window);
626 switch (event->any.type)
629 case GDK_KEY_RELEASE:
630 g_free (event->key.string);
633 case GDK_ENTER_NOTIFY:
634 case GDK_LEAVE_NOTIFY:
635 if (event->crossing.subwindow != NULL)
636 gdk_window_unref (event->crossing.subwindow);
641 case GDK_DRAG_MOTION:
642 case GDK_DRAG_STATUS:
644 case GDK_DROP_FINISHED:
645 gdk_drag_context_unref (event->dnd.context);
652 g_mem_chunk_free (event_chunk, event);
656 *--------------------------------------------------------------
657 * gdk_event_get_time:
658 * Get the timestamp from an event.
662 * The event's time stamp, if it has one, otherwise
664 *--------------------------------------------------------------
668 gdk_event_get_time (GdkEvent *event)
673 case GDK_MOTION_NOTIFY:
674 return event->motion.time;
675 case GDK_BUTTON_PRESS:
676 case GDK_2BUTTON_PRESS:
677 case GDK_3BUTTON_PRESS:
678 case GDK_BUTTON_RELEASE:
679 return event->button.time;
681 case GDK_KEY_RELEASE:
682 return event->key.time;
683 case GDK_ENTER_NOTIFY:
684 case GDK_LEAVE_NOTIFY:
685 return event->crossing.time;
686 case GDK_PROPERTY_NOTIFY:
687 return event->property.time;
688 case GDK_SELECTION_CLEAR:
689 case GDK_SELECTION_REQUEST:
690 case GDK_SELECTION_NOTIFY:
691 return event->selection.time;
692 case GDK_PROXIMITY_IN:
693 case GDK_PROXIMITY_OUT:
694 return event->proximity.time;
697 case GDK_DRAG_MOTION:
698 case GDK_DRAG_STATUS:
700 case GDK_DROP_FINISHED:
701 return event->dnd.time;
702 default: /* use current time */
706 return GDK_CURRENT_TIME;
710 *--------------------------------------------------------------
711 * gdk_set_show_events
713 * Turns on/off the showing of events.
716 * "show_events" is a boolean describing whether or
717 * not to show the events gdk receives.
722 * When "show_events" is TRUE, calls to "gdk_event_get"
723 * will output debugging informatin regarding the event
724 * received to stdout.
726 *--------------------------------------------------------------
730 gdk_set_show_events (gint show_events)
733 gdk_debug_flags |= GDK_DEBUG_EVENTS;
735 gdk_debug_flags &= ~GDK_DEBUG_EVENTS;
739 gdk_get_show_events (void)
741 return gdk_debug_flags & GDK_DEBUG_EVENTS;
745 *--------------------------------------------------------------
748 * Grabs the pointer to a specific window
751 * "window" is the window which will receive the grab
752 * "owner_events" specifies whether events will be reported as is,
753 * or relative to "window"
754 * "event_mask" masks only interesting events
755 * "confine_to" limits the cursor movement to the specified window
756 * "cursor" changes the cursor for the duration of the grab
757 * "time" specifies the time
762 * requires a corresponding call to gdk_pointer_ungrab
764 *--------------------------------------------------------------
768 gdk_pointer_grab (GdkWindow * window,
770 GdkEventMask event_mask,
771 GdkWindow * confine_to,
778 GdkCursorPrivate *cursor_private;
781 g_return_val_if_fail (window != NULL, 0);
782 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
783 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
785 cursor_private = (GdkCursorPrivate*) cursor;
787 xwindow = GDK_DRAWABLE_XID (window);
789 if (!confine_to || GDK_DRAWABLE_DESTROYED (confine_to))
792 xconfine_to = GDK_DRAWABLE_XID (confine_to);
797 xcursor = cursor_private->xcursor;
799 if (gdk_input_vtable.grab_pointer)
800 return_val = gdk_input_vtable.grab_pointer (window,
806 return_val = Success;
808 if (return_val == Success)
810 if (!GDK_DRAWABLE_DESTROYED (window))
812 GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x\n",
814 (owner_events ? "TRUE" : "FALSE"),
816 p_grab_event_mask = event_mask;
817 p_grab_owner_events = owner_events != 0;
818 p_grab_automatic = FALSE;
820 #if 0 /* Menus don't work if we use mouse capture. Pity, because many other
821 * things work better with mouse capture.
823 SetCapture (xwindow);
825 return_val = GrabSuccess;
828 return_val = AlreadyGrabbed;
831 if (return_val == GrabSuccess)
833 p_grab_window = window;
834 p_grab_cursor = xcursor;
841 *--------------------------------------------------------------
844 * Releases any pointer grab
852 *--------------------------------------------------------------
856 gdk_pointer_ungrab (guint32 time)
858 if (gdk_input_vtable.ungrab_pointer)
859 gdk_input_vtable.ungrab_pointer (time);
861 if (GetCapture () != NULL)
864 GDK_NOTE (EVENTS, g_print ("gdk_pointer_ungrab\n"));
866 p_grab_window = NULL;
870 *--------------------------------------------------------------
871 * gdk_pointer_is_grabbed
873 * Tell wether there is an active x pointer grab in effect
881 *--------------------------------------------------------------
885 gdk_pointer_is_grabbed (void)
887 return p_grab_window != NULL;
891 *--------------------------------------------------------------
894 * Grabs the keyboard to a specific window
897 * "window" is the window which will receive the grab
898 * "owner_events" specifies whether events will be reported as is,
899 * or relative to "window"
900 * "time" specifies the time
905 * requires a corresponding call to gdk_keyboard_ungrab
907 *--------------------------------------------------------------
911 gdk_keyboard_grab (GdkWindow * window,
917 g_return_val_if_fail (window != NULL, 0);
918 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
920 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_grab %#x\n",
921 GDK_DRAWABLE_XID (window)));
923 if (!GDK_DRAWABLE_DESTROYED (window))
925 k_grab_owner_events = owner_events != 0;
926 return_val = GrabSuccess;
929 return_val = AlreadyGrabbed;
931 if (return_val == GrabSuccess)
932 k_grab_window = window;
938 *--------------------------------------------------------------
939 * gdk_keyboard_ungrab
941 * Releases any keyboard grab
949 *--------------------------------------------------------------
953 gdk_keyboard_ungrab (guint32 time)
955 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_ungrab\n"));
957 k_grab_window = NULL;
961 gdk_io_destroy (gpointer data)
963 GdkIOClosure *closure = data;
966 closure->notify (closure->data);
972 gdk_io_invoke (GIOChannel *source,
973 GIOCondition condition,
976 GdkIOClosure *closure = data;
977 GdkInputCondition gdk_cond = 0;
979 if (condition & (G_IO_IN | G_IO_PRI))
980 gdk_cond |= GDK_INPUT_READ;
981 if (condition & G_IO_OUT)
982 gdk_cond |= GDK_INPUT_WRITE;
983 if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
984 gdk_cond |= GDK_INPUT_EXCEPTION;
986 if (closure->condition & gdk_cond)
987 closure->function (closure->data, g_io_channel_unix_get_fd (source), gdk_cond);
993 gdk_input_add_full (gint source,
994 GdkInputCondition condition,
995 GdkInputFunction function,
997 GdkDestroyNotify destroy)
1000 GdkIOClosure *closure = g_new (GdkIOClosure, 1);
1001 GIOChannel *channel;
1002 GIOCondition cond = 0;
1004 closure->function = function;
1005 closure->condition = condition;
1006 closure->notify = destroy;
1007 closure->data = data;
1009 if (condition & GDK_INPUT_READ)
1010 cond |= (G_IO_IN | G_IO_PRI);
1011 if (condition & GDK_INPUT_WRITE)
1013 if (condition & GDK_INPUT_EXCEPTION)
1014 cond |= G_IO_ERR|G_IO_HUP|G_IO_NVAL;
1016 channel = g_io_channel_unix_new (source);
1017 result = g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, cond,
1019 closure, gdk_io_destroy);
1020 g_io_channel_unref (channel);
1026 gdk_input_add (gint source,
1027 GdkInputCondition condition,
1028 GdkInputFunction function,
1031 return gdk_input_add_full (source, condition, function, data, NULL);
1035 gdk_input_remove (gint tag)
1037 g_source_remove (tag);
1040 static GdkFilterReturn
1041 gdk_event_apply_filters (MSG *xevent,
1045 GdkEventFilter *filter;
1047 GdkFilterReturn result;
1053 filter = (GdkEventFilter *) tmp_list->data;
1055 result = (*filter->function) (xevent, event, filter->data);
1056 if (result != GDK_FILTER_CONTINUE)
1059 tmp_list = tmp_list->next;
1062 return GDK_FILTER_CONTINUE;
1066 gdk_add_client_message_filter (GdkAtom message_type,
1070 GdkClientFilter *filter = g_new (GdkClientFilter, 1);
1072 filter->type = message_type;
1073 filter->function = func;
1074 filter->data = data;
1076 client_filters = g_list_prepend (client_filters, filter);
1080 synthesize_crossing_events (GdkWindow *window,
1084 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
1085 GdkWindowPrivate *curWnd_private = (GdkWindowPrivate *) curWnd;
1087 if (curWnd && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
1089 GDK_NOTE (EVENTS, g_print ("synthesizing LEAVE_NOTIFY event\n"));
1091 event = gdk_event_new ();
1092 event->crossing.type = GDK_LEAVE_NOTIFY;
1093 event->crossing.window = curWnd;
1094 gdk_window_ref (event->crossing.window);
1095 event->crossing.subwindow = NULL;
1096 event->crossing.time = xevent->time;
1097 event->crossing.x = curX;
1098 event->crossing.y = curY;
1099 event->crossing.x_root = curXroot;
1100 event->crossing.y_root = curYroot;
1101 event->crossing.mode = GDK_CROSSING_NORMAL;
1102 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
1104 event->crossing.focus = TRUE; /* ??? */
1105 event->crossing.state = 0; /* ??? */
1107 gdk_event_queue_append (event);
1110 if (window_private && (window_private->event_mask & GDK_ENTER_NOTIFY_MASK))
1112 GDK_NOTE (EVENTS, g_print ("synthesizing ENTER_NOTIFY event\n"));
1114 event = gdk_event_new ();
1115 event->crossing.type = GDK_ENTER_NOTIFY;
1116 event->crossing.window = window;
1117 gdk_window_ref (event->crossing.window);
1118 event->crossing.subwindow = NULL;
1119 event->crossing.time = xevent->time;
1120 event->crossing.x = LOWORD (xevent->lParam);
1121 event->crossing.y = HIWORD (xevent->lParam);
1122 event->crossing.x_root = (gfloat) xevent->pt.x;
1123 event->crossing.y_root = (gfloat) xevent->pt.y;
1124 event->crossing.mode = GDK_CROSSING_NORMAL;
1125 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
1127 event->crossing.focus = TRUE; /* ??? */
1128 event->crossing.state = 0; /* ??? */
1130 gdk_event_queue_append (event);
1132 if (window_private->extension_events != 0
1133 && gdk_input_vtable.enter_event)
1134 gdk_input_vtable.enter_event (&event->crossing, window);
1138 gdk_window_unref (curWnd);
1140 gdk_window_ref (curWnd);
1144 gdk_event_translate (GdkEvent *event,
1146 gboolean *ret_val_flagp,
1150 GdkWindowPrivate *window_private;
1152 GdkColormapPrivate *colormap_private;
1155 PAINTSTRUCT paintstruct;
1161 GdkWindowPrivate *curWnd_private;
1163 GdkDrawablePrivate *pixmap_private;
1176 *ret_val_flagp = FALSE;
1178 if (xevent->message == gdk_ping_msg)
1180 /* Messages we post ourselves just to wakeup WaitMessage. */
1184 window = gdk_window_lookup (xevent->hwnd);
1185 window_private = (GdkWindowPrivate *) window;
1187 if (xevent->message == g_pipe_readable_msg)
1189 GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n",
1190 xevent->wParam, xevent->lParam));
1192 g_io_channel_win32_pipe_readable (xevent->wParam, xevent->lParam);
1197 gdk_window_ref (window);
1200 /* Handle WM_QUIT here ? */
1201 if (xevent->message == WM_QUIT)
1203 GDK_NOTE (EVENTS, g_print ("WM_QUIT: %d\n", xevent->wParam));
1204 exit (xevent->wParam);
1206 else if (xevent->message == WM_MOVE
1207 || xevent->message == WM_SIZE)
1209 /* It's quite normal to get these messages before we have
1210 * had time to register the window in our lookup table, or
1211 * when the window is being destroyed and we already have
1212 * removed it. Repost the same message to our queue so that
1213 * we will get it later when we are prepared.
1215 PostMessage (xevent->hwnd, xevent->message,
1216 xevent->wParam, xevent->lParam);
1221 event->any.window = window;
1223 if (window_private && GDK_DRAWABLE_DESTROYED (window))
1228 /* Check for filters for this window */
1229 GdkFilterReturn result;
1230 result = gdk_event_apply_filters
1232 window_private ? window_private->filters : gdk_default_filters);
1234 if (result != GDK_FILTER_CONTINUE)
1236 return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
1240 if (xevent->message == gdk_selection_notify_msg)
1242 GDK_NOTE (SELECTION, g_print ("gdk_selection_notify_msg: %#x\n",
1245 event->selection.type = GDK_SELECTION_NOTIFY;
1246 event->selection.window = window;
1247 event->selection.selection = xevent->wParam;
1248 event->selection.target = xevent->lParam;
1249 event->selection.property = gdk_selection_property;
1250 event->selection.time = xevent->time;
1252 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
1254 /* Will pass through switch below without match */
1256 else if (xevent->message == gdk_selection_request_msg)
1258 GDK_NOTE (SELECTION, g_print ("gdk_selection_request_msg: %#x\n",
1261 event->selection.type = GDK_SELECTION_REQUEST;
1262 event->selection.window = window;
1263 event->selection.selection = gdk_clipboard_atom;
1264 event->selection.target = GDK_TARGET_STRING;
1265 event->selection.property = gdk_selection_property;
1266 event->selection.requestor = (guint32) xevent->hwnd;
1267 event->selection.time = xevent->time;
1269 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
1271 /* Again, will pass through switch below without match */
1273 else if (xevent->message == gdk_selection_clear_msg)
1275 GDK_NOTE (SELECTION, g_print ("gdk_selection_clear_msg: %#x\n",
1278 event->selection.type = GDK_SELECTION_CLEAR;
1279 event->selection.window = window;
1280 event->selection.selection = xevent->wParam;
1281 event->selection.time = xevent->time;
1283 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
1285 /* Once again, we will pass through switch below without match */
1290 GdkFilterReturn result = GDK_FILTER_CONTINUE;
1292 tmp_list = client_filters;
1295 GdkClientFilter *filter = tmp_list->data;
1296 if (filter->type == xevent->message)
1298 GDK_NOTE (EVENTS, g_print ("client filter matched\n"));
1299 result = (*filter->function) (xevent, event, filter->data);
1302 case GDK_FILTER_REMOVE:
1306 case GDK_FILTER_TRANSLATE:
1310 case GDK_FILTER_CONTINUE:
1312 event->client.type = GDK_CLIENT_EVENT;
1313 event->client.window = window;
1314 event->client.message_type = xevent->message;
1315 event->client.data_format = 0;
1316 event->client.data.l[0] = xevent->wParam;
1317 event->client.data.l[1] = xevent->lParam;
1320 goto bypass_switch; /* Ouch */
1322 tmp_list = tmp_list->next;
1326 switch (xevent->message)
1331 g_print ("WM_SYSKEY%s: %#x key: %s %#x %#.08x\n",
1332 (xevent->message == WM_SYSKEYUP ? "UP" : "DOWN"),
1334 (GetKeyNameText (xevent->lParam, buf,
1340 /* Let the system handle Alt-Tab and Alt-Enter */
1341 if (xevent->wParam == VK_TAB
1342 || xevent->wParam == VK_RETURN
1343 || xevent->wParam == VK_F4)
1345 /* If posted without us having keyboard focus, ignore */
1346 if (!(xevent->lParam & 0x20000000))
1349 /* don't generate events for just the Alt key */
1350 if (xevent->wParam == VK_MENU)
1353 /* Jump to code in common with WM_KEYUP and WM_KEYDOWN */
1359 g_print ("WM_KEY%s: %#x key: %s %#x %#.08x\n",
1360 (xevent->message == WM_KEYUP ? "UP" : "DOWN"),
1362 (GetKeyNameText (xevent->lParam, buf,
1368 ignore_WM_CHAR = TRUE;
1370 if (k_grab_window != NULL && !k_grab_owner_events)
1372 /* Keyboard is grabbed with owner_events FALSE */
1374 g_print ("...grabbed, owner_events FALSE, "
1376 GDK_DRAWABLE_XID (k_grab_window)));
1377 event->key.window = k_grab_window;
1379 else if (window_private
1380 && (((xevent->message == WM_KEYUP
1381 || xevent->message == WM_SYSKEYUP)
1382 && !(window_private->event_mask & GDK_KEY_RELEASE_MASK))
1383 || ((xevent->message == WM_KEYDOWN
1384 || xevent->message == WM_SYSKEYDOWN)
1385 && !(window_private->event_mask & GDK_KEY_PRESS_MASK))))
1387 /* Owner window doesn't want it */
1388 if (k_grab_window != NULL && k_grab_owner_events)
1390 /* Keyboard is grabbed with owner_events TRUE */
1392 g_print ("...grabbed, owner_events TRUE, doesn't want it, "
1394 GDK_DRAWABLE_XID (k_grab_window)));
1395 event->key.window = k_grab_window;
1399 /* Owner doesn't want it, neither is it grabbed, so
1400 * propagate to parent.
1402 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1404 gdk_window_unref (window);
1405 window = window_private->parent;
1406 gdk_window_ref (window);
1407 window_private = (GdkWindowPrivate *) window;
1408 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1409 GDK_DRAWABLE_XID (window)));
1414 switch (xevent->wParam)
1417 event->key.keyval = GDK_Pointer_Button1; break;
1419 event->key.keyval = GDK_Pointer_Button3; break;
1421 event->key.keyval = GDK_Pointer_Button2; break;
1423 event->key.keyval = GDK_Cancel; break;
1425 event->key.keyval = GDK_BackSpace; break;
1427 event->key.keyval = (GetKeyState(VK_SHIFT) < 0 ?
1428 GDK_ISO_Left_Tab : GDK_Tab);
1431 event->key.keyval = GDK_Clear; break;
1433 event->key.keyval = GDK_Return; break;
1435 event->key.keyval = GDK_Shift_L; break;
1437 if (xevent->lParam & 0x01000000)
1438 event->key.keyval = GDK_Control_R;
1440 event->key.keyval = GDK_Control_L;
1443 if (xevent->lParam & 0x01000000)
1445 /* AltGr key comes in as Control+Right Alt */
1446 if (GetKeyState (VK_CONTROL) < 0)
1448 ignore_WM_CHAR = FALSE;
1449 is_AltGr_key = TRUE;
1451 event->key.keyval = GDK_Alt_R;
1454 event->key.keyval = GDK_Alt_L;
1457 event->key.keyval = GDK_Pause; break;
1459 event->key.keyval = GDK_Caps_Lock; break;
1461 event->key.keyval = GDK_Escape; break;
1463 event->key.keyval = GDK_Prior; break;
1465 event->key.keyval = GDK_Next; break;
1467 event->key.keyval = GDK_End; break;
1469 event->key.keyval = GDK_Home; break;
1471 event->key.keyval = GDK_Left; break;
1473 event->key.keyval = GDK_Up; break;
1475 event->key.keyval = GDK_Right; break;
1477 event->key.keyval = GDK_Down; break;
1479 event->key.keyval = GDK_Select; break;
1481 event->key.keyval = GDK_Print; break;
1483 event->key.keyval = GDK_Execute; break;
1485 event->key.keyval = GDK_Insert; break;
1487 event->key.keyval = GDK_Delete; break;
1489 event->key.keyval = GDK_Help; break;
1500 /* Apparently applications work better if we just pass numpad digits
1501 * on as real digits? So wait for the WM_CHAR instead.
1503 ignore_WM_CHAR = FALSE;
1506 event->key.keyval = GDK_KP_Multiply; break;
1509 event->key.keyval = GDK_KP_Add; break;
1511 /* Pass it on as an ASCII plus in WM_CHAR. */
1512 ignore_WM_CHAR = FALSE;
1516 event->key.keyval = GDK_KP_Separator; break;
1519 event->key.keyval = GDK_KP_Subtract; break;
1521 /* Pass it on as an ASCII minus in WM_CHAR. */
1522 ignore_WM_CHAR = FALSE;
1527 event->key.keyval = GDK_KP_Decimal; break;
1529 /* The keypad decimal key should also be passed on as the decimal
1530 * sign ('.' or ',' depending on the Windows locale settings,
1531 * apparently). So wait for the WM_CHAR here, also.
1533 ignore_WM_CHAR = FALSE;
1537 event->key.keyval = GDK_KP_Divide; break;
1539 event->key.keyval = GDK_F1; break;
1541 event->key.keyval = GDK_F2; break;
1543 event->key.keyval = GDK_F3; break;
1545 event->key.keyval = GDK_F4; break;
1547 event->key.keyval = GDK_F5; break;
1549 event->key.keyval = GDK_F6; break;
1551 event->key.keyval = GDK_F7; break;
1553 event->key.keyval = GDK_F8; break;
1555 event->key.keyval = GDK_F9; break;
1557 event->key.keyval = GDK_F10; break;
1559 event->key.keyval = GDK_F11; break;
1561 event->key.keyval = GDK_F12; break;
1563 event->key.keyval = GDK_F13; break;
1565 event->key.keyval = GDK_F14; break;
1567 event->key.keyval = GDK_F15; break;
1569 event->key.keyval = GDK_F16; break;
1580 if (!is_AltGr_key && (GetKeyState (VK_CONTROL) < 0
1581 || GetKeyState (VK_MENU) < 0))
1582 /* Control- or Alt-digits won't come in as a WM_CHAR */
1583 event->key.keyval = GDK_0 + (xevent->wParam - '0');
1586 ignore_WM_CHAR = FALSE;
1587 event->key.keyval = GDK_VoidSymbol;
1591 if (xevent->message == WM_SYSKEYDOWN || xevent->message == WM_SYSKEYUP)
1593 event->key.keyval = xevent->wParam;
1597 ignore_WM_CHAR = FALSE;
1598 event->key.keyval = GDK_VoidSymbol;
1603 if (!ignore_WM_CHAR)
1606 is_AltGr_key = FALSE;
1607 event->key.type = ((xevent->message == WM_KEYDOWN
1608 || xevent->message == WM_SYSKEYDOWN) ?
1609 GDK_KEY_PRESS : GDK_KEY_RELEASE);
1610 event->key.window = window;
1611 event->key.time = xevent->time;
1612 event->key.state = 0;
1613 if (GetKeyState (VK_SHIFT) < 0)
1614 event->key.state |= GDK_SHIFT_MASK;
1615 if (GetKeyState (VK_CAPITAL) & 0x1)
1616 event->key.state |= GDK_LOCK_MASK;
1617 if (GetKeyState (VK_CONTROL) < 0)
1618 event->key.state |= GDK_CONTROL_MASK;
1619 if (xevent->wParam != VK_MENU && GetKeyState (VK_MENU) < 0)
1620 event->key.state |= GDK_MOD1_MASK;
1621 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
1622 event->key.string = NULL;
1623 event->key.length = 0;
1628 g_print ("WM_CHAR: %#x char: %#x %#.08x %s\n",
1632 (ignore_WM_CHAR ? "ignored" : "")));
1636 ignore_WM_CHAR = FALSE;
1641 /* This doesn't handle the rather theorethical case that a window
1642 * wants key presses but still wants releases to be propagated,
1645 if (k_grab_window != NULL && !k_grab_owner_events)
1647 /* Keyboard is grabbed with owner_events FALSE */
1649 g_print ("...grabbed, owner_events FALSE, "
1651 GDK_DRAWABLE_XID (k_grab_window)));
1652 event->key.window = k_grab_window;
1654 else if (window_private
1655 && !(window_private->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)))
1657 /* Owner window doesn't want it */
1658 if (k_grab_window != NULL && k_grab_owner_events)
1660 /* Keyboard is grabbed with owner_events TRUE */
1662 g_print ("...grabbed, owner_events TRUE, doesn't want it, "
1664 GDK_DRAWABLE_XID (k_grab_window)));
1665 event->key.window = k_grab_window;
1669 /* Owner doesn't want it, neither is it grabbed, so
1670 * propagate to parent.
1672 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1673 g_assert_not_reached (); /* Should've been handled above */
1675 gdk_window_unref (window);
1676 window = window_private->parent;
1677 gdk_window_ref (window);
1678 window_private = (GdkWindowPrivate *) window;
1679 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1680 GDK_DRAWABLE_XID (window)));
1685 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
1686 if (return_val && (window_private->event_mask & GDK_KEY_RELEASE_MASK))
1688 /* Return the release event, and maybe append the press
1689 * event to the queued_events list (from which it will vbe
1690 * fetched before the release event).
1692 event->key.type = GDK_KEY_RELEASE;
1693 event->key.keyval = xevent->wParam;
1694 event->key.window = window;
1695 event->key.time = xevent->time;
1696 event->key.state = 0;
1697 if (GetKeyState (VK_SHIFT) < 0)
1698 event->key.state |= GDK_SHIFT_MASK;
1699 if (GetKeyState (VK_CAPITAL) & 0x1)
1700 event->key.state |= GDK_LOCK_MASK;
1703 else if (GetKeyState (VK_CONTROL) < 0)
1705 event->key.state |= GDK_CONTROL_MASK;
1706 if (event->key.keyval < ' ')
1707 event->key.keyval += '@';
1709 else if (event->key.keyval < ' ')
1711 event->key.state |= GDK_CONTROL_MASK;
1712 event->key.keyval += '@';
1714 if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
1715 event->key.state |= GDK_MOD1_MASK;
1716 event->key.string = g_malloc (2);
1717 event->key.length = 1;
1718 event->key.string[0] = xevent->wParam; /* ??? */
1719 event->key.string[1] = 0;
1721 if (window_private->event_mask & GDK_KEY_PRESS_MASK)
1723 /* Append also a GDK_KEY_PRESS event to the pushback list. */
1724 GdkEvent *event2 = gdk_event_copy (event);
1725 event2->key.type = GDK_KEY_PRESS;
1726 charcount = xevent->lParam & 0xFFFF;
1727 if (charcount > sizeof (buf)- 1)
1728 charcount = sizeof (buf) - 1;
1729 g_free (event2->key.string);
1730 event2->key.string = g_malloc (charcount + 1);
1731 for (i = 0; i < charcount; i++)
1732 event2->key.string[i] = event->key.keyval;
1733 event2->key.string[charcount] = 0;
1734 event2->key.length = charcount;
1736 gdk_event_queue_append (event2);
1739 else if (return_val && (window_private->event_mask & GDK_KEY_PRESS_MASK))
1741 /* Return just the GDK_KEY_PRESS event. */
1742 event->key.type = GDK_KEY_PRESS;
1743 charcount = xevent->lParam & 0xFFFF;
1744 if (charcount > sizeof (buf)- 1)
1745 charcount = sizeof (buf) - 1;
1746 event->key.keyval = xevent->wParam;
1747 event->key.window = window;
1748 event->key.time = xevent->time;
1749 event->key.state = 0;
1750 if (GetKeyState (VK_SHIFT) < 0)
1751 event->key.state |= GDK_SHIFT_MASK;
1752 if (GetKeyState (VK_CAPITAL) & 0x1)
1753 event->key.state |= GDK_LOCK_MASK;
1756 else if (GetKeyState (VK_CONTROL) < 0)
1758 event->key.state |= GDK_CONTROL_MASK;
1759 if (event->key.keyval < ' ')
1760 event->key.keyval += '@';
1762 else if (event->key.keyval < ' ')
1764 event->key.state |= GDK_CONTROL_MASK;
1765 event->key.keyval += '@';
1767 if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
1768 event->key.state |= GDK_MOD1_MASK;
1769 event->key.string = g_malloc (charcount + 1);
1770 for (i = 0; i < charcount; i++)
1771 event->key.string[i] = event->key.keyval;
1772 event->key.string[charcount] = 0;
1773 event->key.length = charcount;
1777 #if 0 /* Don't reset is_AltGr_key here. Othewise we can't type several
1778 * AltGr-accessed chars while keeping the AltGr pressed down
1781 is_AltGr_key = FALSE;
1785 case WM_LBUTTONDOWN:
1788 case WM_MBUTTONDOWN:
1791 case WM_RBUTTONDOWN:
1796 g_print ("WM_%cBUTTONDOWN: %#x x,y: %d %d button: %d\n",
1799 LOWORD (xevent->lParam), HIWORD (xevent->lParam),
1803 && (window_private->extension_events != 0)
1804 && gdk_input_ignore_core)
1806 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1810 if (window != curWnd)
1811 synthesize_crossing_events (window, xevent);
1813 event->button.type = GDK_BUTTON_PRESS;
1815 event->button.window = window;
1817 mask = window_private->event_mask;
1821 if (p_grab_window != NULL && !p_grab_owner_events)
1823 /* Pointer is grabbed with owner_events FALSE */
1824 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
1825 mask = p_grab_event_mask;
1826 if (!(mask & GDK_BUTTON_PRESS_MASK))
1827 /* Grabber doesn't want it */
1830 event->button.window = p_grab_window;
1831 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1832 GDK_DRAWABLE_XID (p_grab_window)));
1834 else if (window_private
1835 && !(mask & GDK_BUTTON_PRESS_MASK))
1837 /* Owner window doesn't want it */
1838 if (p_grab_window != NULL && p_grab_owner_events)
1840 /* Pointer is grabbed wÃth owner_events TRUE */
1841 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
1842 mask = p_grab_event_mask;
1843 if (!(mask & GDK_BUTTON_PRESS_MASK))
1844 /* Grabber doesn't want it either */
1847 event->button.window = p_grab_window;
1848 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1849 GDK_DRAWABLE_XID (p_grab_window)));
1853 /* Owner doesn't want it, neither is it grabbed, so
1854 * propagate to parent.
1856 /* Yes, this code is duplicated twice below. So shoot me. */
1857 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1859 pt.x = LOWORD (xevent->lParam);
1860 pt.y = HIWORD (xevent->lParam);
1861 ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
1862 gdk_window_unref (window);
1863 window = window_private->parent;
1864 gdk_window_ref (window);
1865 window_private = (GdkWindowPrivate *) window;
1866 ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
1867 xevent->lParam = MAKELPARAM (pt.x, pt.y);
1868 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1869 GDK_DRAWABLE_XID (window)));
1870 goto buttondown; /* What did Dijkstra say? */
1874 /* Emulate X11's automatic active grab */
1877 /* No explicit active grab, let's start one automatically */
1878 GDK_NOTE (EVENTS, g_print ("...automatic grab started\n"));
1879 gdk_pointer_grab (window, TRUE, window_private->event_mask,
1881 p_grab_automatic = TRUE;
1884 event->button.time = xevent->time;
1885 event->button.x = LOWORD (xevent->lParam);
1886 event->button.y = HIWORD (xevent->lParam);
1887 event->button.x_root = (gfloat)xevent->pt.x;
1888 event->button.y_root = (gfloat)xevent->pt.y;
1889 event->button.pressure = 0.5;
1890 event->button.xtilt = 0;
1891 event->button.ytilt = 0;
1892 event->button.state = 0;
1893 if (xevent->wParam & MK_CONTROL)
1894 event->button.state |= GDK_CONTROL_MASK;
1895 if (xevent->wParam & MK_LBUTTON)
1896 event->button.state |= GDK_BUTTON1_MASK;
1897 if (xevent->wParam & MK_MBUTTON)
1898 event->button.state |= GDK_BUTTON2_MASK;
1899 if (xevent->wParam & MK_RBUTTON)
1900 event->button.state |= GDK_BUTTON3_MASK;
1901 if (xevent->wParam & MK_SHIFT)
1902 event->button.state |= GDK_SHIFT_MASK;
1903 if (GetKeyState (VK_MENU) < 0)
1904 event->button.state |= GDK_MOD1_MASK;
1905 if (GetKeyState (VK_CAPITAL) & 0x1)
1906 event->button.state |= GDK_LOCK_MASK;
1907 event->button.button = button;
1908 event->button.source = GDK_SOURCE_MOUSE;
1909 event->button.deviceid = GDK_CORE_POINTER;
1911 if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) &&
1912 (event->button.window == button_window[1]) &&
1913 (event->button.button == button_number[1]))
1915 gdk_synthesize_click (event, 3);
1917 button_click_time[1] = 0;
1918 button_click_time[0] = 0;
1919 button_window[1] = NULL;
1920 button_window[0] = 0;
1921 button_number[1] = -1;
1922 button_number[0] = -1;
1924 else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) &&
1925 (event->button.window == button_window[0]) &&
1926 (event->button.button == button_number[0]))
1928 gdk_synthesize_click (event, 2);
1930 button_click_time[1] = button_click_time[0];
1931 button_click_time[0] = event->button.time;
1932 button_window[1] = button_window[0];
1933 button_window[0] = event->button.window;
1934 button_number[1] = button_number[0];
1935 button_number[0] = event->button.button;
1939 button_click_time[1] = 0;
1940 button_click_time[0] = event->button.time;
1941 button_window[1] = NULL;
1942 button_window[0] = event->button.window;
1943 button_number[1] = -1;
1944 button_number[0] = event->button.button;
1946 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
1948 && p_grab_window != NULL
1949 && event->any.window == p_grab_window
1950 && p_grab_window != window)
1952 /* Translate coordinates to grabber */
1953 pt.x = event->button.x;
1954 pt.y = event->button.y;
1955 ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
1956 ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
1957 event->button.x = pt.x;
1958 event->button.y = pt.y;
1959 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
1974 g_print ("WM_%cBUTTONUP: %#x x,y: %d %d button: %d\n",
1977 LOWORD (xevent->lParam), HIWORD (xevent->lParam),
1981 && (window_private->extension_events != 0)
1982 && gdk_input_ignore_core)
1984 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1988 if (window != curWnd)
1989 synthesize_crossing_events (window, xevent);
1991 event->button.type = GDK_BUTTON_RELEASE;
1993 event->button.window = window;
1995 mask = window_private->event_mask;
1999 if (p_grab_window != NULL && !p_grab_owner_events)
2001 /* Pointer is grabbed with owner_events FALSE */
2002 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
2003 mask = p_grab_event_mask;
2004 if (!(mask & GDK_BUTTON_RELEASE_MASK))
2005 /* Grabber doesn't want it */
2008 event->button.window = p_grab_window;
2009 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
2010 GDK_DRAWABLE_XID (p_grab_window)));
2012 else if (window_private
2013 && !(mask & GDK_BUTTON_RELEASE_MASK))
2015 /* Owner window doesn't want it */
2016 if (p_grab_window != NULL && p_grab_owner_events)
2018 /* Pointer is grabbed wÃth owner_events TRUE */
2019 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
2020 mask = p_grab_event_mask;
2021 if (!(mask & GDK_BUTTON_RELEASE_MASK))
2022 /* Grabber doesn't want it */
2025 event->button.window = p_grab_window;
2026 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
2027 GDK_DRAWABLE_XID (p_grab_window)));
2031 /* Owner doesn't want it, neither is it grabbed, so
2032 * propagate to parent.
2034 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
2036 pt.x = LOWORD (xevent->lParam);
2037 pt.y = HIWORD (xevent->lParam);
2038 ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
2039 gdk_window_unref (window);
2040 window = window_private->parent;
2041 gdk_window_ref (window);
2042 window_private = (GdkWindowPrivate *) window;
2043 ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
2044 xevent->lParam = MAKELPARAM (pt.x, pt.y);
2045 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
2046 GDK_DRAWABLE_XID (window)));
2051 event->button.time = xevent->time;
2052 event->button.x = LOWORD (xevent->lParam);
2053 event->button.y = HIWORD (xevent->lParam);
2054 event->button.x_root = (gfloat)xevent->pt.x;
2055 event->button.y_root = (gfloat)xevent->pt.y;
2056 event->button.pressure = 0.5;
2057 event->button.xtilt = 0;
2058 event->button.ytilt = 0;
2059 event->button.state = 0;
2060 if (xevent->wParam & MK_CONTROL)
2061 event->button.state |= GDK_CONTROL_MASK;
2062 if (xevent->wParam & MK_LBUTTON)
2063 event->button.state |= GDK_BUTTON1_MASK;
2064 if (xevent->wParam & MK_MBUTTON)
2065 event->button.state |= GDK_BUTTON2_MASK;
2066 if (xevent->wParam & MK_RBUTTON)
2067 event->button.state |= GDK_BUTTON3_MASK;
2068 if (xevent->wParam & MK_SHIFT)
2069 event->button.state |= GDK_SHIFT_MASK;
2070 event->button.button = button;
2071 event->button.source = GDK_SOURCE_MOUSE;
2072 event->button.deviceid = GDK_CORE_POINTER;
2073 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
2075 && p_grab_window != NULL
2076 && event->any.window == p_grab_window
2077 && p_grab_window != window)
2079 /* Translate coordinates to grabber */
2080 pt.x = event->button.x;
2081 pt.y = event->button.y;
2082 ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
2083 ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
2084 event->button.x = pt.x;
2085 event->button.y = pt.y;
2086 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
2088 if (p_grab_window != NULL
2090 && (event->button.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0)
2091 gdk_pointer_ungrab (0);
2096 g_print ("WM_MOUSEMOVE: %#x %#x +%d+%d\n",
2097 xevent->hwnd, xevent->wParam,
2098 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2101 /* Try hard not to generate events for windows that shouldn't
2102 get any. This is hard because we don't want pushbuttons to
2103 highlight when the cursor moves over them if the window is
2104 inactive. We dont want tooltips windows to be active. OTOH,
2105 also menus are popup windows, but they definitely should
2106 get events. Aw shit. Skip this.
2108 dwStyle = GetWindowLong (xevent->hwnd, GWL_STYLE);
2109 if (active == NULL ||
2110 !(active == xevent->hwnd
2111 || (dwStyle & WS_POPUP)
2112 || IsChild (active, xevent->hwnd)))
2115 { /* HB: only process mouse move messages
2116 * if we own the active window.
2118 DWORD ProcessID_ActWin;
2119 DWORD ProcessID_this;
2121 GetWindowThreadProcessId(GetActiveWindow(), &ProcessID_ActWin);
2122 GetWindowThreadProcessId(xevent->hwnd, &ProcessID_this);
2123 if (ProcessID_ActWin != ProcessID_this)
2127 if (window != curWnd)
2128 synthesize_crossing_events (window, xevent);
2131 && (window_private->extension_events != 0)
2132 && gdk_input_ignore_core)
2134 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
2139 event->motion.type = GDK_MOTION_NOTIFY;
2140 event->motion.window = window;
2142 mask = window_private->event_mask;
2146 if (p_grab_window && !p_grab_owner_events)
2148 /* Pointer is grabbed with owner_events FALSE */
2150 g_print ("...grabbed, owner_events FALSE\n"));
2151 mask = p_grab_event_mask;
2152 if (!((mask & GDK_POINTER_MOTION_MASK)
2153 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2154 && (mask & GDK_BUTTON_MOTION_MASK))
2155 || ((xevent->wParam & MK_LBUTTON)
2156 && (mask & GDK_BUTTON1_MOTION_MASK))
2157 || ((xevent->wParam & MK_MBUTTON)
2158 && (mask & GDK_BUTTON2_MOTION_MASK))
2159 || ((xevent->wParam & MK_RBUTTON)
2160 && (mask & GDK_BUTTON3_MOTION_MASK))))
2163 event->motion.window = p_grab_window;
2164 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
2165 GDK_DRAWABLE_XID (p_grab_window)));
2167 else if (window_private
2168 && !((mask & GDK_POINTER_MOTION_MASK)
2169 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2170 && (mask & GDK_BUTTON_MOTION_MASK))
2171 || ((xevent->wParam & MK_LBUTTON)
2172 && (mask & GDK_BUTTON1_MOTION_MASK))
2173 || ((xevent->wParam & MK_MBUTTON)
2174 && (mask & GDK_BUTTON2_MOTION_MASK))
2175 || ((xevent->wParam & MK_RBUTTON)
2176 && (mask & GDK_BUTTON3_MOTION_MASK))))
2178 /* Owner window doesn't want it */
2179 if (p_grab_window != NULL && p_grab_owner_events)
2181 /* Pointer is grabbed wÃth owner_events TRUE */
2182 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
2183 mask = p_grab_event_mask;
2184 if (!((p_grab_event_mask & GDK_POINTER_MOTION_MASK)
2185 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2186 && (mask & GDK_BUTTON_MOTION_MASK))
2187 || ((xevent->wParam & MK_LBUTTON)
2188 && (mask & GDK_BUTTON1_MOTION_MASK))
2189 || ((xevent->wParam & MK_MBUTTON)
2190 && (mask & GDK_BUTTON2_MOTION_MASK))
2191 || ((xevent->wParam & MK_RBUTTON)
2192 && (mask & GDK_BUTTON3_MOTION_MASK))))
2193 /* Grabber doesn't want it either */
2196 event->motion.window = p_grab_window;
2197 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
2198 GDK_DRAWABLE_XID (p_grab_window)));
2202 /* Owner doesn't want it, neither is it grabbed, so
2203 * propagate to parent.
2205 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
2207 pt.x = LOWORD (xevent->lParam);
2208 pt.y = HIWORD (xevent->lParam);
2209 ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
2210 gdk_window_unref (window);
2211 window = window_private->parent;
2212 gdk_window_ref (window);
2213 window_private = (GdkWindowPrivate *) window;
2214 ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
2215 xevent->lParam = MAKELPARAM (pt.x, pt.y);
2216 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
2217 GDK_DRAWABLE_XID (window)));
2222 event->motion.time = xevent->time;
2223 event->motion.x = curX = LOWORD (xevent->lParam);
2224 event->motion.y = curY = HIWORD (xevent->lParam);
2225 event->motion.x_root = xevent->pt.x;
2226 event->motion.y_root = xevent->pt.y;
2227 curXroot = event->motion.x_root;
2228 curYroot = event->motion.y_root;
2229 event->motion.pressure = 0.5;
2230 event->motion.xtilt = 0;
2231 event->motion.ytilt = 0;
2232 event->button.state = 0;
2233 if (xevent->wParam & MK_CONTROL)
2234 event->button.state |= GDK_CONTROL_MASK;
2235 if (xevent->wParam & MK_LBUTTON)
2236 event->button.state |= GDK_BUTTON1_MASK;
2237 if (xevent->wParam & MK_MBUTTON)
2238 event->button.state |= GDK_BUTTON2_MASK;
2239 if (xevent->wParam & MK_RBUTTON)
2240 event->button.state |= GDK_BUTTON3_MASK;
2241 if (xevent->wParam & MK_SHIFT)
2242 event->button.state |= GDK_SHIFT_MASK;
2243 if (mask & GDK_POINTER_MOTION_HINT_MASK)
2244 event->motion.is_hint = NotifyHint;
2246 event->motion.is_hint = NotifyNormal;
2247 event->motion.source = GDK_SOURCE_MOUSE;
2248 event->motion.deviceid = GDK_CORE_POINTER;
2250 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
2252 && p_grab_window != NULL
2253 && event->any.window == p_grab_window
2254 && p_grab_window != window)
2256 /* Translate coordinates to grabber */
2257 pt.x = event->motion.x;
2258 pt.y = event->motion.y;
2259 ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
2260 ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
2261 event->motion.x = pt.x;
2262 event->motion.y = pt.y;
2263 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
2267 case WM_NCMOUSEMOVE:
2269 g_print ("WM_NCMOUSEMOVE: %#x x,y: %d %d\n",
2271 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2273 if (active == NULL || active != xevent->hwnd)
2276 curWnd_private = (GdkWindowPrivate *) curWnd;
2278 && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
2280 GDK_NOTE (EVENTS, g_print ("...synthesizing LEAVE_NOTIFY event\n"));
2282 event->crossing.type = GDK_LEAVE_NOTIFY;
2283 event->crossing.window = curWnd;
2284 event->crossing.subwindow = NULL;
2285 event->crossing.time = xevent->time;
2286 event->crossing.x = curX;
2287 event->crossing.y = curY;
2288 event->crossing.x_root = curXroot;
2289 event->crossing.y_root = curYroot;
2290 event->crossing.mode = GDK_CROSSING_NORMAL;
2291 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
2293 event->crossing.focus = TRUE; /* ??? */
2294 event->crossing.state = 0; /* ??? */
2295 gdk_window_unref (curWnd);
2305 && !(window_private->event_mask & GDK_FOCUS_CHANGE_MASK))
2308 GDK_NOTE (EVENTS, g_print ("WM_%sFOCUS: %#x\n",
2309 (xevent->message == WM_SETFOCUS ? "SET" : "KILL"),
2312 event->focus_change.type = GDK_FOCUS_CHANGE;
2313 event->focus_change.window = window;
2314 event->focus_change.in = (xevent->message == WM_SETFOCUS);
2315 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
2319 GDK_NOTE (EVENTS, g_print ("WM_ACTIVATE: %#x %d\n",
2320 xevent->hwnd, LOWORD (xevent->wParam)));
2321 if (LOWORD (xevent->wParam) == WA_INACTIVE)
2322 active = (HWND) xevent->lParam;
2324 active = xevent->hwnd;
2328 GDK_NOTE (EVENTS, g_print ("WM_ERASEBKGND: %#x dc %#x\n",
2329 xevent->hwnd, xevent->wParam));
2331 if (!window_private || GDK_DRAWABLE_DESTROYED (window))
2333 colormap_private = (GdkColormapPrivate *) window_private->drawable.colormap;
2334 hdc = (HDC) xevent->wParam;
2335 if (colormap_private
2336 && colormap_private->xcolormap->rc_palette)
2340 if (SelectPalette (hdc, colormap_private->xcolormap->palette,
2342 g_warning ("WM_ERASEBKGND: SelectPalette failed");
2343 if ((k = RealizePalette (hdc)) == GDI_ERROR)
2344 g_warning ("WM_ERASEBKGND: RealizePalette failed");
2346 g_print ("WM_ERASEBKGND: selected %#x, realized %d colors\n",
2347 colormap_private->xcolormap->palette, k);
2350 *ret_val_flagp = TRUE;
2353 if (window_private->bg_type == GDK_WIN32_BG_TRANSPARENT)
2356 if (window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2358 /* If this window should have the same background as the
2359 * parent, fetch the parent. (And if the same goes for
2360 * the parent, fetch the grandparent, etc.)
2362 while (window_private
2363 && window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2364 window_private = (GdkWindowPrivate *) window_private->parent;
2367 if (window_private->bg_type == GDK_WIN32_BG_PIXEL)
2370 GetClipBox (hdc, &rect);
2371 GDK_NOTE (EVENTS, g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n",
2372 rect.right - rect.left,
2373 rect.bottom - rect.top,
2374 rect.left, rect.top,
2375 gdk_color_to_string (&window_private->bg_pixel)));
2376 bg = GetNearestColor (hdc, RGB (window_private->bg_pixel.red >> 8,
2377 window_private->bg_pixel.green >> 8,
2378 window_private->bg_pixel.blue >> 8));
2379 hbr = CreateSolidBrush (bg);
2381 g_print ("...CreateSolidBrush (%.08x) = %.08x\n", bg, hbr);
2383 if (!FillRect (hdc, &rect, hbr))
2384 g_warning ("WM_ERASEBKGND: FillRect failed");
2387 else if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
2389 pixmap_private = (GdkDrawablePrivate*) window_private->bg_pixmap;
2390 GetClipBox (hdc, &rect);
2392 if (pixmap_private->width <= 8
2393 && pixmap_private->height <= 8)
2395 GDK_NOTE (EVENTS, g_print ("...small pixmap, using brush\n"));
2396 hbr = CreatePatternBrush (pixmap_private->xwindow);
2397 if (!FillRect (hdc, &rect, hbr))
2398 g_warning ("WM_ERASEBKGND: FillRect failed");
2404 g_print ("...blitting pixmap %#x (%dx%d) "
2405 "all over the place,\n"
2406 "...clip box = %dx%d@+%d+%d\n",
2407 pixmap_private->xwindow,
2408 pixmap_private->width, pixmap_private->height,
2409 rect.right - rect.left, rect.bottom - rect.top,
2410 rect.left, rect.top));
2412 if (!(bgdc = CreateCompatibleDC (hdc)))
2414 g_warning ("WM_ERASEBKGND: CreateCompatibleDC failed");
2417 if (!(oldbitmap = SelectObject (bgdc, pixmap_private->xwindow)))
2419 g_warning ("WM_ERASEBKGND: SelectObject failed");
2424 while (i < rect.right)
2427 while (j < rect.bottom)
2429 if (i + pixmap_private->width >= rect.left
2430 && j + pixmap_private->height >= rect.top)
2432 if (!BitBlt (hdc, i, j,
2433 pixmap_private->width, pixmap_private->height,
2434 bgdc, 0, 0, SRCCOPY))
2436 g_warning ("WM_ERASEBKGND: BitBlt failed");
2440 j += pixmap_private->height;
2442 i += pixmap_private->width;
2445 SelectObject (bgdc, oldbitmap);
2451 GDK_NOTE (EVENTS, g_print ("...BLACK_BRUSH (?)\n"));
2452 hbr = GetStockObject (BLACK_BRUSH);
2453 GetClipBox (hdc, &rect);
2454 if (!FillRect (hdc, &rect, hbr))
2455 g_warning ("WM_ERASEBKGND: FillRect failed");
2460 hdc = BeginPaint (xevent->hwnd, &paintstruct);
2463 g_print ("WM_PAINT: %#x %dx%d@+%d+%d %s dc %#x\n",
2465 paintstruct.rcPaint.right - paintstruct.rcPaint.left,
2466 paintstruct.rcPaint.bottom - paintstruct.rcPaint.top,
2467 paintstruct.rcPaint.left, paintstruct.rcPaint.top,
2468 (paintstruct.fErase ? "erase" : ""),
2471 EndPaint (xevent->hwnd, &paintstruct);
2474 && !(window_private->event_mask & GDK_EXPOSURE_MASK))
2477 event->expose.type = GDK_EXPOSE;
2478 event->expose.window = window;
2479 event->expose.area.x = paintstruct.rcPaint.left;
2480 event->expose.area.y = paintstruct.rcPaint.top;
2481 event->expose.area.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left;
2482 event->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
2483 event->expose.count = 0;
2485 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
2488 GList *list = queued_events;
2489 while (list != NULL )
2491 if ((((GdkEvent *)list->data)->any.type == GDK_EXPOSE) &&
2492 (((GdkEvent *)list->data)->any.window == window) &&
2493 !(((GdkEventPrivate *)list->data)->flags & GDK_EVENT_PENDING))
2494 ((GdkEvent *)list->data)->expose.count++;
2502 GDK_NOTE (EVENTS, g_print ("WM_SETCURSOR: %#x %#x %#x\n",
2504 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2507 if (LOWORD (xevent->lParam) != HTCLIENT)
2509 if (p_grab_window != NULL && p_grab_cursor != NULL)
2511 GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", p_grab_cursor));
2512 SetCursor (p_grab_cursor);
2514 else if (window_private
2515 && !GDK_DRAWABLE_DESTROYED (window)
2516 && window_private->xcursor)
2518 GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n",
2519 window_private->xcursor));
2520 SetCursor (window_private->xcursor);
2522 *ret_val_flagp = TRUE;
2528 GDK_NOTE (EVENTS, g_print ("WM_QUERYOPEN: %#x\n",
2530 *ret_val_flagp = TRUE;
2534 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2537 event->any.type = GDK_MAP;
2538 event->any.window = window;
2540 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
2546 GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#x %d\n",
2551 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2554 event->any.type = (xevent->wParam ? GDK_MAP : GDK_UNMAP);
2555 event->any.window = window;
2557 if (event->any.type == GDK_UNMAP
2558 && p_grab_window == window)
2559 gdk_pointer_ungrab (xevent->time);
2561 if (event->any.type == GDK_UNMAP
2562 && k_grab_window == window)
2563 gdk_keyboard_ungrab (xevent->time);
2565 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
2570 g_print ("WM_SIZE: %#x %s %dx%d\n",
2572 (xevent->wParam == SIZE_MAXHIDE ? "MAXHIDE" :
2573 (xevent->wParam == SIZE_MAXIMIZED ? "MAXIMIZED" :
2574 (xevent->wParam == SIZE_MAXSHOW ? "MAXSHOW" :
2575 (xevent->wParam == SIZE_MINIMIZED ? "MINIMIZED" :
2576 (xevent->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
2577 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2580 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2582 if (window_private != NULL
2583 && xevent->wParam == SIZE_MINIMIZED)
2586 event->any.type = GDK_UNMAP;
2587 event->any.window = window;
2589 if (p_grab_window == window)
2590 gdk_pointer_ungrab (xevent->time);
2592 if (k_grab_window == window)
2593 gdk_keyboard_ungrab (xevent->time);
2595 return_val = !GDK_DRAWABLE_DESTROYED (window);
2598 else if (window_private != NULL
2599 && (xevent->wParam == SIZE_RESTORED
2600 || xevent->wParam == SIZE_MAXIMIZED)
2602 && GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD
2606 if (LOWORD (xevent->lParam) == 0)
2609 event->configure.type = GDK_CONFIGURE;
2610 event->configure.window = window;
2613 ClientToScreen (xevent->hwnd, &pt);
2614 event->configure.x = pt.x;
2615 event->configure.y = pt.y;
2616 event->configure.width = LOWORD (xevent->lParam);
2617 event->configure.height = HIWORD (xevent->lParam);
2618 window_private->x = event->configure.x;
2619 window_private->y = event->configure.y;
2620 window_private->drawable.width = event->configure.width;
2621 window_private->drawable.height = event->configure.height;
2622 if (window_private->resize_count > 1)
2623 window_private->resize_count -= 1;
2625 return_val = !GDK_DRAWABLE_DESTROYED (window);
2627 && window_private->extension_events != 0
2628 && gdk_input_vtable.configure_event)
2629 gdk_input_vtable.configure_event (&event->configure, window);
2632 #if 0 /* Bernd Herd suggests responding to WM_GETMINMAXINFO instead,
2633 * which indeed is much easier.
2636 GDK_NOTE (EVENTS, g_print ("WM_SIZING: %#x\n", xevent->hwnd));
2637 if (ret_val_flagp == NULL)
2638 g_warning ("ret_val_flagp is NULL but we got a WM_SIZING?");
2639 else if (window_private != NULL
2640 && window_private->hint_flags &
2641 (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE))
2643 LPRECT lprc = (LPRECT) xevent->lParam;
2645 if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
2647 gint w = lprc->right - lprc->left;
2648 gint h = lprc->bottom - lprc->top;
2650 if (w < window_private->hint_min_width)
2652 if (xevent->wParam == WMSZ_BOTTOMLEFT
2653 || xevent->wParam == WMSZ_LEFT
2654 || xevent->wParam == WMSZ_TOPLEFT)
2655 lprc->left = lprc->right - window_private->hint_min_width;
2657 lprc->right = lprc->left + window_private->hint_min_width;
2658 *ret_val_flagp = TRUE;
2661 if (h < window_private->hint_min_height)
2663 if (xevent->wParam == WMSZ_BOTTOMLEFT
2664 || xevent->wParam == WMSZ_BOTTOM
2665 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2666 lprc->bottom = lprc->top + window_private->hint_min_height;
2668 lprc->top = lprc->bottom - window_private->hint_min_height;
2669 *ret_val_flagp = TRUE;
2673 if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
2675 gint w = lprc->right - lprc->left;
2676 gint h = lprc->bottom - lprc->top;
2678 if (w > window_private->hint_max_width)
2680 if (xevent->wParam == WMSZ_BOTTOMLEFT
2681 || xevent->wParam == WMSZ_LEFT
2682 || xevent->wParam == WMSZ_TOPLEFT)
2683 lprc->left = lprc->right - window_private->hint_max_width;
2685 lprc->right = lprc->left + window_private->hint_max_width;
2686 *ret_val_flagp = TRUE;
2689 if (h > window_private->hint_max_height)
2691 if (xevent->wParam == WMSZ_BOTTOMLEFT
2692 || xevent->wParam == WMSZ_BOTTOM
2693 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2694 lprc->bottom = lprc->top + window_private->hint_max_height;
2696 lprc->top = lprc->bottom - window_private->hint_max_height;
2697 *ret_val_flagp = TRUE;
2704 case WM_GETMINMAXINFO:
2705 GDK_NOTE (EVENTS, g_print ("WM_GETMINMAXINFO: %#x\n", xevent->hwnd));
2706 lpmmi = (MINMAXINFO*) xevent->lParam;
2707 if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
2709 lpmmi->ptMinTrackSize.x = window_private->hint_min_width;
2710 lpmmi->ptMinTrackSize.y = window_private->hint_min_height;
2712 if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
2714 lpmmi->ptMaxTrackSize.x = window_private->hint_max_width;
2715 lpmmi->ptMaxTrackSize.y = window_private->hint_max_height;
2717 lpmmi->ptMaxSize.x = window_private->hint_max_width;
2718 lpmmi->ptMaxSize.y = window_private->hint_max_height;
2724 GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#x +%d+%d\n",
2726 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2729 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2731 if (window_private != NULL
2732 && GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD)
2734 event->configure.type = GDK_CONFIGURE;
2735 event->configure.window = window;
2736 event->configure.x = LOWORD (xevent->lParam);
2737 event->configure.y = HIWORD (xevent->lParam);
2738 GetClientRect (xevent->hwnd, &rect);
2739 event->configure.width = rect.right;
2740 event->configure.height = rect.bottom;
2741 window_private->x = event->configure.x;
2742 window_private->y = event->configure.y;
2743 window_private->drawable.width = event->configure.width;
2744 window_private->drawable.height = event->configure.height;
2746 return_val = !GDK_DRAWABLE_DESTROYED (window);
2751 GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#x\n", xevent->hwnd));
2752 event->any.type = GDK_DELETE;
2753 event->any.window = window;
2755 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
2759 /* No, don't use delayed rendering after all. It works only if the
2760 * delayed SetClipboardData is called from the WindowProc, it
2761 * seems. (The #else part below is test code for that. It succeeds
2762 * in setting the clipboard data. But if I call SetClipboardData
2763 * in gdk_property_change (as a consequence of the
2764 * GDK_SELECTION_REQUEST event), it fails. I deduce that this is
2765 * because delayed rendering requires that SetClipboardData is
2766 * called in the window procedure.)
2768 case WM_RENDERFORMAT:
2769 case WM_RENDERALLFORMATS:
2771 GDK_NOTE (EVENTS, flag = TRUE);
2772 GDK_NOTE (SELECTION, flag = TRUE);
2774 g_print ("WM_%s: %#x %#x (%s)\n",
2775 (xevent->message == WM_RENDERFORMAT ? "RENDERFORMAT" :
2776 "RENDERALLFORMATS"),
2779 (xevent->wParam == CF_TEXT ? "CF_TEXT" :
2780 (xevent->wParam == CF_DIB ? "CF_DIB" :
2781 (xevent->wParam == CF_UNICODETEXT ? "CF_UNICODETEXT" :
2782 (GetClipboardFormatName (xevent->wParam, buf, sizeof (buf)), buf)))));
2785 event->selection.type = GDK_SELECTION_REQUEST;
2786 event->selection.window = window;
2787 event->selection.selection = gdk_clipboard_atom;
2788 if (xevent->wParam == CF_TEXT)
2789 event->selection.target = GDK_TARGET_STRING;
2792 GetClipboardFormatName (xevent->wParam, buf, sizeof (buf));
2793 event->selection.target = gdk_atom_intern (buf, FALSE);
2795 event->selection.property = gdk_selection_property;
2796 event->selection.requestor = (guint32) xevent->hwnd;
2797 event->selection.time = xevent->time;
2798 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
2800 /* Test code, to see if SetClipboardData works when called from
2801 * the window procedure.
2804 HGLOBAL hdata = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, 10);
2805 char *ptr = GlobalLock (hdata);
2806 strcpy (ptr, "Huhhaa");
2807 GlobalUnlock (hdata);
2808 if (!SetClipboardData (CF_TEXT, hdata))
2809 g_print ("SetClipboardData failed: %d\n", GetLastError ());
2812 *ret_val_flagp = TRUE;
2816 #endif /* No delayed rendering */
2819 GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#x\n", xevent->hwnd));
2820 event->any.type = GDK_DESTROY;
2821 event->any.window = window;
2822 if (window != NULL && window == curWnd)
2824 gdk_window_unref (curWnd);
2828 if (p_grab_window == window)
2829 gdk_pointer_ungrab (xevent->time);
2831 if (k_grab_window == window)
2832 gdk_keyboard_ungrab (xevent->time);
2834 return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
2838 /* Handle WINTAB events here, as we know that gdkinput.c will
2839 * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
2840 * constants as case labels.
2843 GDK_NOTE (EVENTS, g_print ("WT_PACKET: %d %#x\n",
2844 xevent->wParam, xevent->lParam));
2848 GDK_NOTE (EVENTS, g_print ("WT_CSRCHANGE: %d %#x\n",
2849 xevent->wParam, xevent->lParam));
2854 g_print ("WT_PROXIMITY: %#x %d %d\n",
2856 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2859 return_val = gdk_input_vtable.other_event(event, xevent);
2868 if (event->any.window)
2869 gdk_window_ref (event->any.window);
2870 if (((event->any.type == GDK_ENTER_NOTIFY) ||
2871 (event->any.type == GDK_LEAVE_NOTIFY)) &&
2872 (event->crossing.subwindow != NULL))
2873 gdk_window_ref (event->crossing.subwindow);
2877 /* Mark this event as having no resources to be freed */
2878 event->any.window = NULL;
2879 event->any.type = GDK_NOTHING;
2883 gdk_window_unref (window);
2889 gdk_events_queue (void)
2895 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: %s\n",
2896 (queued_events ? "yes" : "none")));
2898 while (!gdk_event_queue_find_first()
2899 && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
2901 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: PeekMessage: %#x\n",
2903 TranslateMessage (&msg);
2905 event = gdk_event_new ();
2907 event->any.type = GDK_NOTHING;
2908 event->any.window = NULL;
2909 event->any.send_event = FALSE;
2911 ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
2913 gdk_event_queue_append (event);
2916 if (gdk_event_translate (event, &msg, NULL, NULL))
2917 ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
2920 DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
2921 gdk_event_queue_remove_link (node);
2922 g_list_free_1 (node);
2923 gdk_event_free (event);
2929 gdk_event_prepare (gpointer source_data,
2930 GTimeVal *current_time,
2936 GDK_THREADS_ENTER ();
2940 GDK_NOTE (EVENTS, g_print ("gdk_event_prepare\n"));
2942 retval = (gdk_event_queue_find_first () != NULL)
2943 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2945 GDK_THREADS_LEAVE ();
2951 gdk_event_check (gpointer source_data,
2952 GTimeVal *current_time)
2957 GDK_NOTE (EVENTS, g_print ("gdk_event_check\n"));
2959 GDK_THREADS_ENTER ();
2961 if (event_poll_fd.revents & G_IO_IN)
2962 retval = (gdk_event_queue_find_first () != NULL)
2963 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2967 GDK_THREADS_LEAVE ();
2973 gdk_event_unqueue (void)
2975 GdkEvent *event = NULL;
2978 tmp_list = gdk_event_queue_find_first ();
2982 event = tmp_list->data;
2983 gdk_event_queue_remove_link (tmp_list);
2984 g_list_free_1 (tmp_list);
2991 gdk_event_dispatch (gpointer source_data,
2992 GTimeVal *current_time,
2997 GDK_NOTE (EVENTS, g_print ("gdk_event_dispatch\n"));
2999 GDK_THREADS_ENTER ();
3002 event = gdk_event_unqueue();
3007 (*event_func) (event, event_data);
3009 gdk_event_free (event);
3012 GDK_THREADS_LEAVE ();
3018 gdk_synthesize_click (GdkEvent *event,
3021 GdkEvent temp_event;
3023 g_return_if_fail (event != NULL);
3025 temp_event = *event;
3026 temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
3028 gdk_event_put (&temp_event);
3031 /* Sends a ClientMessage to all toplevel client windows */
3033 gdk_event_send_client_message (GdkEvent *event, guint32 xid)
3040 gdk_event_send_clientmessage_toall (GdkEvent *event)