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 <gdk/gdkkeysyms.h>
40 #define PING() printf("%s: %d\n",__FILE__,__LINE__),fflush(stdout)
42 typedef struct _GdkIOClosure GdkIOClosure;
43 typedef struct _GdkEventPrivate GdkEventPrivate;
45 #define DOUBLE_CLICK_TIME 250
46 #define TRIPLE_CLICK_TIME 500
47 #define DOUBLE_CLICK_DIST 5
48 #define TRIPLE_CLICK_DIST 5
52 /* Following flag is set for events on the event queue during
53 * translation and cleared afterwards.
55 GDK_EVENT_PENDING = 1 << 0
60 GdkInputFunction function;
61 GdkInputCondition condition;
62 GdkDestroyNotify notify;
66 struct _GdkEventPrivate
73 * Private function declarations
76 static GdkEvent *gdk_event_new (void);
77 static gint gdk_event_apply_filters(MSG *xevent,
80 static gint gdk_event_translate (GdkEvent *event,
82 gboolean *ret_val_flagp,
84 static void gdk_events_queue (void);
85 static GdkEvent *gdk_event_unqueue (void);
86 static gboolean gdk_event_prepare (gpointer source_data,
87 GTimeVal *current_time,
89 static gboolean gdk_event_check (gpointer source_data,
90 GTimeVal *current_time);
91 static gboolean gdk_event_dispatch (gpointer source_data,
92 GTimeVal *current_time,
95 static void gdk_synthesize_click (GdkEvent *event,
98 /* Private variable declarations
101 static guint32 button_click_time[2]; /* The last 2 button click times. Used
102 * to determine if the latest button click
103 * is part of a double or triple click.
105 static GdkWindow *button_window[2]; /* The last 2 windows to receive button presses.
106 * Also used to determine if the latest button
107 * click is part of a double or triple click.
109 static guint button_number[2]; /* The last 2 buttons to be pressed.
111 static GdkWindowPrivate *p_grab_window = NULL; /* Window that currently
112 * holds the pointer grab
115 static GdkWindowPrivate *k_grab_window = NULL; /* Window the holds the
119 static GList *client_filters; /* Filters for client messages */
121 static gboolean p_grab_automatic;
122 static GdkEventMask p_grab_event_mask;
123 static gboolean p_grab_owner_events, k_grab_owner_events;
124 static HCURSOR p_grab_cursor;
126 static GdkEventFunc event_func = NULL; /* Callback for events */
127 static gpointer event_data = NULL;
128 static GDestroyNotify event_notify = NULL;
130 static GList *client_filters; /* Filters for client messages */
132 /* FIFO's for event queue, and for events put back using
135 static GList *queued_events = NULL;
136 static GList *queued_tail = NULL;
138 static GSourceFuncs event_funcs = {
142 (GDestroyNotify)g_free
145 GPollFD event_poll_fd;
147 static GdkWindow *curWnd = NULL;
148 static HWND active = NULL;
149 static gint curX, curY;
150 static gdouble curXroot, curYroot;
151 static UINT gdk_ping_msg;
152 static gboolean ignore_WM_CHAR = FALSE;
153 static gboolean is_AltGr_key = FALSE;
156 gdk_WindowProc(HWND hwnd,
166 gboolean ret_val_flag;
168 GDK_NOTE (EVENTS, g_print ("gdk_WindowProc: %#x\n", message));
171 msg.message = message;
174 msg.time = GetTickCount ();
175 pos = GetMessagePos ();
176 msg.pt.x = LOWORD (pos);
177 msg.pt.y = HIWORD (pos);
179 if (gdk_event_translate (&event, &msg, &ret_val_flag, &ret_val))
182 /* Compress configure events */
183 if (event.any.type == GDK_CONFIGURE)
185 GList *list = queued_events;
188 && (((GdkEvent *)list->data)->any.type != GDK_CONFIGURE
189 || ((GdkEvent *)list->data)->any.window != event.any.window))
193 *((GdkEvent *)list->data) = event;
194 gdk_window_unref (event.any.window);
195 /* Wake up WaitMessage */
196 PostMessage (NULL, gdk_ping_msg, 0, 0);
201 eventp = gdk_event_new ();
204 gdk_event_queue_append (eventp);
206 /* Wake up WaitMessage */
207 PostMessage (NULL, gdk_ping_msg, 0, 0);
218 return DefWindowProc (hwnd, message, wParam, lParam);
221 /*********************************************
222 * Functions for maintaining the event queue *
223 *********************************************/
225 /*************************************************************
226 * gdk_event_queue_find_first:
227 * Find the first event on the queue that is not still
232 * Pointer to the list node for that event, or NULL
233 *************************************************************/
236 gdk_event_queue_find_first (void)
238 GList *tmp_list = queued_events;
242 GdkEventPrivate *event = tmp_list->data;
243 if (!(event->flags & GDK_EVENT_PENDING))
246 tmp_list = g_list_next (tmp_list);
252 /*************************************************************
253 * gdk_event_queue_remove_link:
254 * Remove a specified list node from the event queue.
256 * node: Node to remove.
258 *************************************************************/
261 gdk_event_queue_remove_link (GList *node)
264 node->prev->next = node->next;
266 queued_events = node->next;
269 node->next->prev = node->prev;
271 queued_tail = node->prev;
275 /*************************************************************
276 * gdk_event_queue_append:
277 * Append an event onto the tail of the event queue.
279 * event: Event to append.
281 *************************************************************/
284 gdk_event_queue_append (GdkEvent *event)
286 queued_tail = g_list_append (queued_tail, event);
289 queued_events = queued_tail;
291 queued_tail = queued_tail->next;
295 gdk_events_init (void)
297 if (g_pipe_readable_msg == 0)
298 g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable");
300 g_source_add (GDK_PRIORITY_EVENTS, TRUE, &event_funcs, NULL, NULL, NULL);
302 event_poll_fd.fd = G_WIN32_MSG_HANDLE;
303 event_poll_fd.events = G_IO_IN;
305 g_main_add_poll (&event_poll_fd, GDK_PRIORITY_EVENTS);
307 button_click_time[0] = 0;
308 button_click_time[1] = 0;
309 button_window[0] = NULL;
310 button_window[1] = NULL;
311 button_number[0] = -1;
312 button_number[1] = -1;
314 gdk_ping_msg = RegisterWindowMessage ("gdk-ping");
318 *--------------------------------------------------------------
321 * Returns if events are pending on the queue.
326 * Returns TRUE if events are pending
330 *--------------------------------------------------------------
334 gdk_events_pending (void)
338 return (gdk_event_queue_find_first() || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE));
342 *--------------------------------------------------------------
343 * gdk_event_get_graphics_expose
345 * Waits for a GraphicsExpose or NoExpose event
350 * For GraphicsExpose events, returns a pointer to the event
351 * converted into a GdkEvent Otherwise, returns NULL.
355 *-------------------------------------------------------------- */
358 gdk_event_get_graphics_expose (GdkWindow *window)
362 GdkWindowPrivate *private = (GdkWindowPrivate *) window;
364 g_return_val_if_fail (window != NULL, NULL);
366 GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose\n"));
369 /* Some nasty bugs here, just return NULL for now. */
372 if (GetMessage (&xevent, private->xwindow, WM_PAINT, WM_PAINT))
374 event = gdk_event_new ();
376 if (gdk_event_translate (event, &xevent, NULL, NULL))
379 gdk_event_free (event);
386 /************************
387 * Exposure compression *
388 ************************/
390 /* I don't bother with exposure compression on Win32. Windows compresses
391 * WM_PAINT events by itself.
394 /*************************************************************
395 * gdk_event_handler_set:
398 * func: Callback function to be called for each event.
399 * data: Data supplied to the function
400 * notify: function called when function is no longer needed
403 *************************************************************/
406 gdk_event_handler_set (GdkEventFunc func,
408 GDestroyNotify notify)
411 (*event_notify) (event_data);
415 event_notify = notify;
419 *--------------------------------------------------------------
422 * Gets the next event.
427 * If an event is waiting that we care about, returns
428 * a pointer to that event, to be freed with gdk_event_free.
429 * Otherwise, returns NULL.
433 *--------------------------------------------------------------
441 return gdk_event_unqueue();
445 *--------------------------------------------------------------
448 * Gets the next event.
453 * If an event is waiting that we care about, returns
454 * a copy of that event, but does not remove it from
455 * the queue. The pointer is to be freed with gdk_event_free.
456 * Otherwise, returns NULL.
460 *--------------------------------------------------------------
464 gdk_event_peek (void)
468 tmp_list = gdk_event_queue_find_first ();
471 return gdk_event_copy (tmp_list->data);
477 gdk_event_put (GdkEvent *event)
482 g_return_if_fail (event != NULL);
484 new_event = gdk_event_copy (event);
486 gdk_event_queue_append (new_event);
490 *--------------------------------------------------------------
493 * Copy a event structure into new storage.
496 * "event" is the event struct to copy.
499 * A new event structure. Free it with gdk_event_free.
502 * The reference count of the window in the event is increased.
504 *--------------------------------------------------------------
507 static GMemChunk *event_chunk = NULL;
512 GdkEventPrivate *new_event;
514 if (event_chunk == NULL)
515 event_chunk = g_mem_chunk_new ("events",
516 sizeof (GdkEventPrivate),
520 new_event = g_chunk_new (GdkEventPrivate, event_chunk);
521 new_event->flags = 0;
523 return (GdkEvent *) new_event;
527 gdk_event_copy (GdkEvent *event)
532 g_return_val_if_fail (event != NULL, NULL);
534 new_event = gdk_event_new ();
537 gdk_window_ref (new_event->any.window);
539 switch (event->any.type)
542 case GDK_KEY_RELEASE:
543 if (event->key.length > 0)
545 s = event->key.string;
546 new_event->key.string = g_malloc (event->key.length + 1);
547 memcpy (new_event->key.string, s, event->key.length + 1);
551 case GDK_ENTER_NOTIFY:
552 case GDK_LEAVE_NOTIFY:
553 if (event->crossing.subwindow != NULL)
554 gdk_window_ref (event->crossing.subwindow);
559 case GDK_DRAG_MOTION:
560 case GDK_DRAG_STATUS:
562 case GDK_DROP_FINISHED:
563 gdk_drag_context_ref (event->dnd.context);
574 *--------------------------------------------------------------
577 * Free a event structure obtained from gdk_event_copy. Do not use
578 * with other event structures.
581 * "event" is the event struct to free.
586 * The reference count of the window in the event is decreased and
587 * might be freed, too.
589 *-------------------------------------------------------------- */
592 gdk_event_free (GdkEvent *event)
594 g_return_if_fail (event != NULL);
596 g_assert (event_chunk != NULL); /* paranoid */
598 if (event->any.window)
599 gdk_window_unref (event->any.window);
601 switch (event->any.type)
604 case GDK_KEY_RELEASE:
605 g_free (event->key.string);
608 case GDK_ENTER_NOTIFY:
609 case GDK_LEAVE_NOTIFY:
610 if (event->crossing.subwindow != NULL)
611 gdk_window_unref (event->crossing.subwindow);
616 case GDK_DRAG_MOTION:
617 case GDK_DRAG_STATUS:
619 case GDK_DROP_FINISHED:
620 gdk_drag_context_unref (event->dnd.context);
627 g_mem_chunk_free (event_chunk, event);
631 *--------------------------------------------------------------
632 * gdk_event_get_time:
633 * Get the timestamp from an event.
637 * The event's time stamp, if it has one, otherwise
639 *--------------------------------------------------------------
643 gdk_event_get_time (GdkEvent *event)
648 case GDK_MOTION_NOTIFY:
649 return event->motion.time;
650 case GDK_BUTTON_PRESS:
651 case GDK_2BUTTON_PRESS:
652 case GDK_3BUTTON_PRESS:
653 case GDK_BUTTON_RELEASE:
654 return event->button.time;
656 case GDK_KEY_RELEASE:
657 return event->key.time;
658 case GDK_ENTER_NOTIFY:
659 case GDK_LEAVE_NOTIFY:
660 return event->crossing.time;
661 case GDK_PROPERTY_NOTIFY:
662 return event->property.time;
663 case GDK_SELECTION_CLEAR:
664 case GDK_SELECTION_REQUEST:
665 case GDK_SELECTION_NOTIFY:
666 return event->selection.time;
667 case GDK_PROXIMITY_IN:
668 case GDK_PROXIMITY_OUT:
669 return event->proximity.time;
672 case GDK_DRAG_MOTION:
673 case GDK_DRAG_STATUS:
675 case GDK_DROP_FINISHED:
676 return event->dnd.time;
677 default: /* use current time */
681 return GDK_CURRENT_TIME;
685 *--------------------------------------------------------------
686 * gdk_set_show_events
688 * Turns on/off the showing of events.
691 * "show_events" is a boolean describing whether or
692 * not to show the events gdk receives.
697 * When "show_events" is TRUE, calls to "gdk_event_get"
698 * will output debugging informatin regarding the event
699 * received to stdout.
701 *--------------------------------------------------------------
705 gdk_set_show_events (gint show_events)
708 gdk_debug_flags |= GDK_DEBUG_EVENTS;
710 gdk_debug_flags &= ~GDK_DEBUG_EVENTS;
714 gdk_get_show_events (void)
716 return gdk_debug_flags & GDK_DEBUG_EVENTS;
720 *--------------------------------------------------------------
723 * Grabs the pointer to a specific window
726 * "window" is the window which will receive the grab
727 * "owner_events" specifies whether events will be reported as is,
728 * or relative to "window"
729 * "event_mask" masks only interesting events
730 * "confine_to" limits the cursor movement to the specified window
731 * "cursor" changes the cursor for the duration of the grab
732 * "time" specifies the time
737 * requires a corresponding call to gdk_pointer_ungrab
739 *--------------------------------------------------------------
743 gdk_pointer_grab (GdkWindow * window,
745 GdkEventMask event_mask,
746 GdkWindow * confine_to,
750 GdkWindowPrivate *window_private;
754 GdkWindowPrivate *confine_to_private;
755 GdkCursorPrivate *cursor_private;
758 g_return_val_if_fail (window != NULL, 0);
760 window_private = (GdkWindowPrivate*) window;
761 confine_to_private = (GdkWindowPrivate*) confine_to;
762 cursor_private = (GdkCursorPrivate*) cursor;
764 xwindow = window_private->xwindow;
766 if (!confine_to || confine_to_private->destroyed)
769 xconfine_to = confine_to_private->xwindow;
774 xcursor = cursor_private->xcursor;
776 if (gdk_input_vtable.grab_pointer)
777 return_val = gdk_input_vtable.grab_pointer (window,
783 return_val = Success;
785 if (return_val == Success)
787 if (!window_private->destroyed)
789 GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x\n",
791 (owner_events ? "TRUE" : "FALSE"),
793 p_grab_event_mask = event_mask;
794 p_grab_owner_events = owner_events != 0;
795 p_grab_automatic = FALSE;
797 #if 0 /* Menus don't work if we use mouse capture. Pity, because many other
798 * things work better with mouse capture.
800 SetCapture (xwindow);
802 return_val = GrabSuccess;
805 return_val = AlreadyGrabbed;
808 if (return_val == GrabSuccess)
810 p_grab_window = window_private;
811 p_grab_cursor = xcursor;
818 *--------------------------------------------------------------
821 * Releases any pointer grab
829 *--------------------------------------------------------------
833 gdk_pointer_ungrab (guint32 time)
835 if (gdk_input_vtable.ungrab_pointer)
836 gdk_input_vtable.ungrab_pointer (time);
838 if (GetCapture () != NULL)
841 GDK_NOTE (EVENTS, g_print ("gdk_pointer_ungrab\n"));
843 p_grab_window = NULL;
847 *--------------------------------------------------------------
848 * gdk_pointer_is_grabbed
850 * Tell wether there is an active x pointer grab in effect
858 *--------------------------------------------------------------
862 gdk_pointer_is_grabbed (void)
864 return p_grab_window != NULL;
868 *--------------------------------------------------------------
871 * Grabs the keyboard to a specific window
874 * "window" is the window which will receive the grab
875 * "owner_events" specifies whether events will be reported as is,
876 * or relative to "window"
877 * "time" specifies the time
882 * requires a corresponding call to gdk_keyboard_ungrab
884 *--------------------------------------------------------------
888 gdk_keyboard_grab (GdkWindow * window,
892 GdkWindowPrivate *window_private;
895 g_return_val_if_fail (window != NULL, 0);
897 window_private = (GdkWindowPrivate*) window;
899 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_grab %#x\n",
900 window_private->xwindow));
902 if (!window_private->destroyed)
904 k_grab_owner_events = owner_events != 0;
905 return_val = GrabSuccess;
908 return_val = AlreadyGrabbed;
910 if (return_val == GrabSuccess)
911 k_grab_window = window_private;
917 *--------------------------------------------------------------
918 * gdk_keyboard_ungrab
920 * Releases any keyboard grab
928 *--------------------------------------------------------------
932 gdk_keyboard_ungrab (guint32 time)
934 GDK_NOTE (EVENTS, g_print ("gdk_keyboard_ungrab\n"));
936 k_grab_window = NULL;
940 gdk_io_destroy (gpointer data)
942 GdkIOClosure *closure = data;
945 closure->notify (closure->data);
951 gdk_io_invoke (GIOChannel *source,
952 GIOCondition condition,
955 GdkIOClosure *closure = data;
956 GdkInputCondition gdk_cond = 0;
958 if (condition & (G_IO_IN | G_IO_PRI))
959 gdk_cond |= GDK_INPUT_READ;
960 if (condition & G_IO_OUT)
961 gdk_cond |= GDK_INPUT_WRITE;
962 if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
963 gdk_cond |= GDK_INPUT_EXCEPTION;
965 if (closure->condition & gdk_cond)
966 closure->function (closure->data, g_io_channel_unix_get_fd (source), gdk_cond);
972 gdk_input_add_full (gint source,
973 GdkInputCondition condition,
974 GdkInputFunction function,
976 GdkDestroyNotify destroy)
979 GdkIOClosure *closure = g_new (GdkIOClosure, 1);
981 GIOCondition cond = 0;
983 closure->function = function;
984 closure->condition = condition;
985 closure->notify = destroy;
986 closure->data = data;
988 if (condition & GDK_INPUT_READ)
989 cond |= (G_IO_IN | G_IO_PRI);
990 if (condition & GDK_INPUT_WRITE)
992 if (condition & GDK_INPUT_EXCEPTION)
993 cond |= G_IO_ERR|G_IO_HUP|G_IO_NVAL;
995 channel = g_io_channel_unix_new (source);
996 result = g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, cond,
998 closure, gdk_io_destroy);
999 g_io_channel_unref (channel);
1005 gdk_input_add (gint source,
1006 GdkInputCondition condition,
1007 GdkInputFunction function,
1010 return gdk_input_add_full (source, condition, function, data, NULL);
1014 gdk_input_remove (gint tag)
1016 g_source_remove (tag);
1020 gdk_event_apply_filters (MSG *xevent,
1024 GdkEventFilter *filter;
1026 GdkFilterReturn result;
1032 filter = (GdkEventFilter *) tmp_list->data;
1034 result = (*filter->function) (xevent, event, filter->data);
1035 if (result != GDK_FILTER_CONTINUE)
1038 tmp_list = tmp_list->next;
1041 return GDK_FILTER_CONTINUE;
1045 gdk_add_client_message_filter (GdkAtom message_type,
1049 GdkClientFilter *filter = g_new (GdkClientFilter, 1);
1051 filter->type = message_type;
1052 filter->function = func;
1053 filter->data = data;
1055 client_filters = g_list_prepend (client_filters, filter);
1059 synthesize_crossing_events (GdkWindow *window,
1063 GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
1064 GdkWindowPrivate *curWnd_private = (GdkWindowPrivate *) curWnd;
1066 if (curWnd && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
1068 GDK_NOTE (EVENTS, g_print ("synthesizing LEAVE_NOTIFY event\n"));
1070 event = gdk_event_new ();
1071 event->crossing.type = GDK_LEAVE_NOTIFY;
1072 event->crossing.window = curWnd;
1073 gdk_window_ref (event->crossing.window);
1074 event->crossing.subwindow = NULL;
1075 event->crossing.time = xevent->time;
1076 event->crossing.x = curX;
1077 event->crossing.y = curY;
1078 event->crossing.x_root = curXroot;
1079 event->crossing.y_root = curYroot;
1080 event->crossing.mode = GDK_CROSSING_NORMAL;
1081 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
1083 event->crossing.focus = TRUE; /* ??? */
1084 event->crossing.state = 0; /* ??? */
1086 gdk_event_queue_append (event);
1089 if (window_private && (window_private->event_mask & GDK_ENTER_NOTIFY_MASK))
1091 GDK_NOTE (EVENTS, g_print ("synthesizing ENTER_NOTIFY event\n"));
1093 event = gdk_event_new ();
1094 event->crossing.type = GDK_ENTER_NOTIFY;
1095 event->crossing.window = window;
1096 gdk_window_ref (event->crossing.window);
1097 event->crossing.subwindow = NULL;
1098 event->crossing.time = xevent->time;
1099 event->crossing.x = LOWORD (xevent->lParam);
1100 event->crossing.y = HIWORD (xevent->lParam);
1101 event->crossing.x_root = (gfloat) xevent->pt.x;
1102 event->crossing.y_root = (gfloat) xevent->pt.y;
1103 event->crossing.mode = GDK_CROSSING_NORMAL;
1104 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
1106 event->crossing.focus = TRUE; /* ??? */
1107 event->crossing.state = 0; /* ??? */
1109 gdk_event_queue_append (event);
1111 if (window_private->extension_events != 0
1112 && gdk_input_vtable.enter_event)
1113 gdk_input_vtable.enter_event (&event->crossing, window);
1117 gdk_window_unref (curWnd);
1119 gdk_window_ref (curWnd);
1123 gdk_event_translate (GdkEvent *event,
1125 gboolean *ret_val_flagp,
1129 GdkWindowPrivate *window_private;
1131 GdkColormapPrivate *colormap_private;
1134 PAINTSTRUCT paintstruct;
1139 GdkWindowPrivate *curWnd_private;
1151 *ret_val_flagp = FALSE;
1153 if (xevent->message == gdk_ping_msg)
1155 /* Messages we post ourselves just to wakeup WaitMessage. */
1159 window = gdk_window_lookup (xevent->hwnd);
1160 window_private = (GdkWindowPrivate *) window;
1162 if (xevent->message == g_pipe_readable_msg)
1164 GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n",
1165 xevent->wParam, xevent->lParam));
1167 g_io_channel_win32_pipe_readable (xevent->wParam, xevent->lParam);
1172 gdk_window_ref (window);
1175 /* Handle WM_QUIT here ? */
1176 if (xevent->message == WM_QUIT)
1178 GDK_NOTE (EVENTS, g_print ("WM_QUIT: %d\n", xevent->wParam));
1179 exit (xevent->wParam);
1181 else if (xevent->message == WM_MOVE
1182 || xevent->message == WM_SIZE)
1184 /* It's quite normal to get these messages before we have
1185 * had time to register the window in our lookup table, or
1186 * when the window is being destroyed and we already have
1187 * removed it. Repost the same message to our queue so that
1188 * we will get it later when we are prepared.
1190 PostMessage (xevent->hwnd, xevent->message,
1191 xevent->wParam, xevent->lParam);
1193 else if (xevent->message == WM_NCCREATE
1194 || xevent->message == WM_CREATE
1195 || xevent->message == WM_GETMINMAXINFO
1196 || xevent->message == WM_NCCALCSIZE
1197 || xevent->message == WM_NCDESTROY
1198 || xevent->message == WM_DESTROY)
1205 event->any.window = window;
1207 if (window_private && window_private->destroyed)
1212 /* Check for filters for this window */
1213 GdkFilterReturn result;
1214 result = gdk_event_apply_filters (xevent, event,
1216 ?window_private->filters
1217 :gdk_default_filters);
1219 if (result != GDK_FILTER_CONTINUE)
1221 return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
1225 if (xevent->message == gdk_selection_notify_msg)
1227 GDK_NOTE (SELECTION, g_print ("gdk_selection_notify_msg: %#x\n",
1230 event->selection.type = GDK_SELECTION_NOTIFY;
1231 event->selection.window = window;
1232 event->selection.selection = xevent->wParam;
1233 event->selection.target = xevent->lParam;
1234 event->selection.property = gdk_selection_property;
1235 event->selection.time = xevent->time;
1237 return_val = window_private && !window_private->destroyed;
1239 /* Will pass through switch below without match */
1241 else if (xevent->message == gdk_selection_request_msg)
1243 GDK_NOTE (SELECTION, g_print ("gdk_selection_request_msg: %#x\n",
1246 event->selection.type = GDK_SELECTION_REQUEST;
1247 event->selection.window = window;
1248 event->selection.selection = gdk_clipboard_atom;
1249 event->selection.target = GDK_TARGET_STRING;
1250 event->selection.property = gdk_selection_property;
1251 event->selection.requestor = (guint32) xevent->hwnd;
1252 event->selection.time = xevent->time;
1254 return_val = window_private && !window_private->destroyed;
1256 /* Again, will pass through switch below without match */
1258 else if (xevent->message == gdk_selection_clear_msg)
1260 GDK_NOTE (SELECTION, g_print ("gdk_selection_clear_msg: %#x\n",
1263 event->selection.type = GDK_SELECTION_CLEAR;
1264 event->selection.window = window;
1265 event->selection.selection = xevent->wParam;
1266 event->selection.time = xevent->time;
1268 return_val = window_private && !window_private->destroyed;
1270 /* Once again, we will pass through switch below without match */
1275 GdkFilterReturn result = GDK_FILTER_CONTINUE;
1277 tmp_list = client_filters;
1280 GdkClientFilter *filter = tmp_list->data;
1281 if (filter->type == xevent->message)
1283 GDK_NOTE (EVENTS, g_print ("client filter matched\n"));
1284 result = (*filter->function) (xevent, event, filter->data);
1287 case GDK_FILTER_REMOVE:
1291 case GDK_FILTER_TRANSLATE:
1295 case GDK_FILTER_CONTINUE:
1297 event->client.type = GDK_CLIENT_EVENT;
1298 event->client.window = window;
1299 event->client.message_type = xevent->message;
1300 event->client.data_format = 0;
1301 event->client.data.l[0] = xevent->wParam;
1302 event->client.data.l[1] = xevent->lParam;
1305 goto bypass_switch; /* Ouch */
1307 tmp_list = tmp_list->next;
1311 switch (xevent->message)
1316 g_print ("WM_SYSKEY%s: %#x key: %s %#x %#.08x\n",
1317 (xevent->message == WM_SYSKEYUP ? "UP" : "DOWN"),
1319 (GetKeyNameText (xevent->lParam, buf,
1325 /* Let the system handle Alt-Tab and Alt-Enter */
1326 if (xevent->wParam == VK_TAB
1327 || xevent->wParam == VK_RETURN
1328 || xevent->wParam == VK_F4)
1330 /* If posted without us having keyboard focus, ignore */
1331 if (!(xevent->lParam & 0x20000000))
1334 /* don't generate events for just the Alt key */
1335 if (xevent->wParam == VK_MENU)
1338 /* Jump to code in common with WM_KEYUP and WM_KEYDOWN */
1344 g_print ("WM_KEY%s: %#x key: %s %#x %#.08x\n",
1345 (xevent->message == WM_KEYUP ? "UP" : "DOWN"),
1347 (GetKeyNameText (xevent->lParam, buf,
1353 ignore_WM_CHAR = TRUE;
1355 if (k_grab_window != NULL
1356 && !k_grab_owner_events)
1358 /* Keyboard is grabbed with owner_events FALSE */
1360 g_print ("...grabbed, owner_events FALSE, "
1361 "sending to %#x\n", k_grab_window->xwindow));
1362 event->key.window = (GdkWindow *) k_grab_window;
1364 else if (window_private
1365 && (((xevent->message == WM_KEYUP
1366 || xevent->message == WM_SYSKEYUP)
1367 && !(window_private->event_mask & GDK_KEY_RELEASE_MASK))
1368 || ((xevent->message == WM_KEYDOWN
1369 || xevent->message == WM_SYSKEYDOWN)
1370 && !(window_private->event_mask & GDK_KEY_PRESS_MASK))))
1372 /* Owner window doesn't want it */
1373 if (k_grab_window != NULL
1374 && k_grab_owner_events)
1376 /* Keyboard is grabbed with owner_events TRUE */
1378 g_print ("...grabbed, owner_events TRUE, doesn't want it, "
1379 "sending to %#x\n", k_grab_window->xwindow));
1380 event->key.window = (GdkWindow *) k_grab_window;
1384 /* Owner doesn't want it, neither is it grabbed, so
1385 * propagate to parent.
1387 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1389 gdk_window_unref (window);
1390 window = window_private->parent;
1391 gdk_window_ref (window);
1392 window_private = (GdkWindowPrivate *) window;
1393 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1394 window_private->xwindow));
1399 switch (xevent->wParam)
1402 event->key.keyval = GDK_Pointer_Button1; break;
1404 event->key.keyval = GDK_Pointer_Button3; break;
1406 event->key.keyval = GDK_Pointer_Button2; break;
1408 event->key.keyval = GDK_Cancel; break;
1410 event->key.keyval = GDK_BackSpace; break;
1412 event->key.keyval = GDK_Tab; break;
1414 event->key.keyval = GDK_Clear; break;
1416 event->key.keyval = GDK_Return; break;
1418 event->key.keyval = GDK_Shift_L; break;
1420 if (xevent->lParam & 0x01000000)
1421 event->key.keyval = GDK_Control_R;
1423 event->key.keyval = GDK_Control_L;
1426 if (xevent->lParam & 0x01000000)
1428 /* AltGr key comes in as Control+Right Alt */
1429 if (GetKeyState (VK_CONTROL) < 0)
1431 ignore_WM_CHAR = FALSE;
1432 is_AltGr_key = TRUE;
1434 event->key.keyval = GDK_Alt_R;
1437 event->key.keyval = GDK_Alt_L;
1440 event->key.keyval = GDK_Pause; break;
1442 event->key.keyval = GDK_Caps_Lock; break;
1444 event->key.keyval = GDK_Escape; break;
1446 event->key.keyval = GDK_Prior; break;
1448 event->key.keyval = GDK_Next; break;
1450 event->key.keyval = GDK_End; break;
1452 event->key.keyval = GDK_Home; break;
1454 event->key.keyval = GDK_Left; break;
1456 event->key.keyval = GDK_Up; break;
1458 event->key.keyval = GDK_Right; break;
1460 event->key.keyval = GDK_Down; break;
1462 event->key.keyval = GDK_Select; break;
1464 event->key.keyval = GDK_Print; break;
1466 event->key.keyval = GDK_Execute; break;
1468 event->key.keyval = GDK_Insert; break;
1470 event->key.keyval = GDK_Delete; break;
1472 event->key.keyval = GDK_Help; break;
1483 /* Apparently applications work better if we just pass numpad digits
1484 * on as real digits? So wait for the WM_CHAR instead.
1486 ignore_WM_CHAR = FALSE;
1489 event->key.keyval = GDK_KP_Multiply; break;
1491 event->key.keyval = GDK_KP_Add; break;
1493 event->key.keyval = GDK_KP_Separator; break;
1495 event->key.keyval = GDK_KP_Subtract; break;
1498 event->key.keyval = GDK_KP_Decimal; break;
1500 /* The keypad decimal key should also be passed on as the decimal
1501 * sign ('.' or ',' depending on the Windows locale settings,
1502 * apparently). So wait for the WM_CHAR here, also.
1504 ignore_WM_CHAR = FALSE;
1508 event->key.keyval = GDK_KP_Divide; break;
1510 event->key.keyval = GDK_F1; break;
1512 event->key.keyval = GDK_F2; break;
1514 event->key.keyval = GDK_F3; break;
1516 event->key.keyval = GDK_F4; break;
1518 event->key.keyval = GDK_F5; break;
1520 event->key.keyval = GDK_F6; break;
1522 event->key.keyval = GDK_F7; break;
1524 event->key.keyval = GDK_F8; break;
1526 event->key.keyval = GDK_F9; break;
1528 event->key.keyval = GDK_F10; break;
1530 event->key.keyval = GDK_F11; break;
1532 event->key.keyval = GDK_F12; break;
1534 event->key.keyval = GDK_F13; break;
1536 event->key.keyval = GDK_F14; break;
1538 event->key.keyval = GDK_F15; break;
1540 event->key.keyval = GDK_F16; break;
1551 if (GetKeyState (VK_CONTROL) < 0)
1552 /* Control-digits won't come in as a WM_CHAR */
1553 event->key.keyval = GDK_0 + (xevent->wParam - '0');
1556 ignore_WM_CHAR = FALSE;
1557 event->key.keyval = GDK_VoidSymbol;
1561 if (xevent->message == WM_SYSKEYDOWN || xevent->message == WM_SYSKEYUP)
1563 event->key.keyval = xevent->wParam;
1567 ignore_WM_CHAR = FALSE;
1568 event->key.keyval = GDK_VoidSymbol;
1573 if (!ignore_WM_CHAR)
1576 is_AltGr_key = FALSE;
1577 event->key.type = ((xevent->message == WM_KEYDOWN
1578 || xevent->message == WM_SYSKEYDOWN) ?
1579 GDK_KEY_PRESS : GDK_KEY_RELEASE);
1580 event->key.window = window;
1581 event->key.time = xevent->time;
1582 event->key.state = 0;
1583 if (GetKeyState (VK_SHIFT) < 0)
1584 event->key.state |= GDK_SHIFT_MASK;
1585 if (GetKeyState (VK_CAPITAL) & 0x1)
1586 event->key.state |= GDK_LOCK_MASK;
1587 if (GetKeyState (VK_CONTROL) < 0)
1588 event->key.state |= GDK_CONTROL_MASK;
1589 if (xevent->wParam != VK_MENU && GetKeyState (VK_MENU) < 0)
1590 event->key.state |= GDK_MOD1_MASK;
1591 return_val = window_private && !window_private->destroyed;
1592 event->key.string = NULL;
1593 event->key.length = 0;
1598 g_print ("WM_CHAR: %#x char: %#x %#.08x %s\n",
1602 (ignore_WM_CHAR ? "ignored" : "")));
1606 ignore_WM_CHAR = FALSE;
1611 /* This doesn't handle the rather theorethical case that a window
1612 * wants key presses but still wants releases to be propagated,
1615 if (k_grab_window != NULL
1616 && !k_grab_owner_events)
1618 /* Keyboard is grabbed with owner_events FALSE */
1620 g_print ("...grabbed, owner_events FALSE, "
1621 "sending to %#x\n", k_grab_window->xwindow));
1622 event->key.window = (GdkWindow *) k_grab_window;
1624 else if (window_private
1625 && !(window_private->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)))
1627 /* Owner window doesn't want it */
1628 if (k_grab_window != NULL
1629 && k_grab_owner_events)
1631 /* Keyboard is grabbed with owner_events TRUE */
1633 g_print ("...grabbed, owner_events TRUE, doesn't want it, "
1634 "sending to %#x\n", k_grab_window->xwindow));
1635 event->key.window = (GdkWindow *) k_grab_window;
1639 /* Owner doesn't want it, neither is it grabbed, so
1640 * propagate to parent.
1642 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1643 g_assert_not_reached (); /* Should've been handled above */
1645 gdk_window_unref (window);
1646 window = window_private->parent;
1647 gdk_window_ref (window);
1648 window_private = (GdkWindowPrivate *) window;
1649 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1650 window_private->xwindow));
1655 return_val = window_private && !window_private->destroyed;
1656 if (return_val && (window_private->event_mask & GDK_KEY_RELEASE_MASK))
1658 /* Return the release event, and maybe append the press
1659 * event to the queued_events list (from which it will vbe
1660 * fetched before the release event).
1662 event->key.type = GDK_KEY_RELEASE;
1663 event->key.keyval = xevent->wParam;
1664 event->key.window = window;
1665 event->key.time = xevent->time;
1666 event->key.state = 0;
1667 if (GetKeyState (VK_SHIFT) < 0)
1668 event->key.state |= GDK_SHIFT_MASK;
1669 if (GetKeyState (VK_CAPITAL) & 0x1)
1670 event->key.state |= GDK_LOCK_MASK;
1673 else if (GetKeyState (VK_CONTROL) < 0)
1675 event->key.state |= GDK_CONTROL_MASK;
1676 if (event->key.keyval < ' ')
1677 event->key.keyval += '@';
1679 else if (event->key.keyval < ' ')
1681 event->key.state |= GDK_CONTROL_MASK;
1682 event->key.keyval += '@';
1684 if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
1685 event->key.state |= GDK_MOD1_MASK;
1686 event->key.string = g_malloc (2);
1687 event->key.length = 1;
1688 event->key.string[0] = xevent->wParam; /* ??? */
1689 event->key.string[1] = 0;
1691 if (window_private->event_mask & GDK_KEY_PRESS_MASK)
1693 /* Append also a GDK_KEY_PRESS event to the pushback list. */
1694 GdkEvent *event2 = gdk_event_copy (event);
1695 event2->key.type = GDK_KEY_PRESS;
1696 charcount = xevent->lParam & 0xFFFF;
1697 if (charcount > sizeof (buf)- 1)
1698 charcount = sizeof (buf) - 1;
1699 g_free (event2->key.string);
1700 event2->key.string = g_malloc (charcount + 1);
1701 for (i = 0; i < charcount; i++)
1702 event2->key.string[i] = event->key.keyval;
1703 event2->key.string[charcount] = 0;
1704 event2->key.length = charcount;
1706 gdk_event_queue_append (event2);
1709 else if (return_val && (window_private->event_mask & GDK_KEY_PRESS_MASK))
1711 /* Return just the GDK_KEY_PRESS event. */
1712 event->key.type = GDK_KEY_PRESS;
1713 charcount = xevent->lParam & 0xFFFF;
1714 if (charcount > sizeof (buf)- 1)
1715 charcount = sizeof (buf) - 1;
1716 event->key.keyval = xevent->wParam;
1717 event->key.window = window;
1718 event->key.time = xevent->time;
1719 event->key.state = 0;
1720 if (GetKeyState (VK_SHIFT) < 0)
1721 event->key.state |= GDK_SHIFT_MASK;
1722 if (GetKeyState (VK_CAPITAL) & 0x1)
1723 event->key.state |= GDK_LOCK_MASK;
1726 else if (GetKeyState (VK_CONTROL) < 0)
1728 event->key.state |= GDK_CONTROL_MASK;
1729 if (event->key.keyval < ' ')
1730 event->key.keyval += '@';
1732 else if (event->key.keyval < ' ')
1734 event->key.state |= GDK_CONTROL_MASK;
1735 event->key.keyval += '@';
1737 if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
1738 event->key.state |= GDK_MOD1_MASK;
1739 event->key.string = g_malloc (charcount + 1);
1740 for (i = 0; i < charcount; i++)
1741 event->key.string[i] = event->key.keyval;
1742 event->key.string[charcount] = 0;
1743 event->key.length = charcount;
1747 is_AltGr_key = FALSE;
1750 case WM_LBUTTONDOWN:
1753 case WM_MBUTTONDOWN:
1756 case WM_RBUTTONDOWN:
1761 g_print ("WM_%cBUTTONDOWN: %#x x,y: %d %d button: %d\n",
1764 LOWORD (xevent->lParam), HIWORD (xevent->lParam),
1768 && (window_private->extension_events != 0)
1769 && gdk_input_ignore_core)
1771 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1775 if (window != curWnd)
1776 synthesize_crossing_events (window, xevent);
1778 event->button.type = GDK_BUTTON_PRESS;
1780 event->button.window = window;
1782 mask = window_private->event_mask;
1786 if (p_grab_window != NULL
1787 && !p_grab_owner_events)
1789 /* Pointer is grabbed with owner_events FALSE */
1790 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
1791 mask = p_grab_event_mask;
1792 if (!(mask & GDK_BUTTON_PRESS_MASK))
1793 /* Grabber doesn't want it */
1796 event->button.window = (GdkWindow *) p_grab_window;
1797 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1798 p_grab_window->xwindow));
1800 else if (window_private
1801 && !(mask & GDK_BUTTON_PRESS_MASK))
1803 /* Owner window doesn't want it */
1804 if (p_grab_window != NULL
1805 && p_grab_owner_events)
1807 /* Pointer is grabbed wÃth owner_events TRUE */
1808 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
1809 mask = p_grab_event_mask;
1810 if (!(mask & GDK_BUTTON_PRESS_MASK))
1811 /* Grabber doesn't want it either */
1814 event->button.window = (GdkWindow *) p_grab_window;
1815 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1816 p_grab_window->xwindow));
1820 /* Owner doesn't want it, neither is it grabbed, so
1821 * propagate to parent.
1823 /* Yes, this code is duplicated twice below. So shoot me. */
1824 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
1826 pt.x = LOWORD (xevent->lParam);
1827 pt.y = HIWORD (xevent->lParam);
1828 ClientToScreen (window_private->xwindow, &pt);
1829 gdk_window_unref (window);
1830 window = window_private->parent;
1831 gdk_window_ref (window);
1832 window_private = (GdkWindowPrivate *) window;
1833 ScreenToClient (window_private->xwindow, &pt);
1834 xevent->lParam = MAKELPARAM (pt.x, pt.y);
1835 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
1836 window_private->xwindow));
1837 goto buttondown; /* What did Dijkstra say? */
1841 /* Emulate X11's automatic active grab */
1844 /* No explicit active grab, let's start one automatically */
1845 GDK_NOTE (EVENTS, g_print ("...automatic grab started\n"));
1846 gdk_pointer_grab (window, TRUE, window_private->event_mask,
1848 p_grab_automatic = TRUE;
1851 event->button.time = xevent->time;
1852 event->button.x = LOWORD (xevent->lParam);
1853 event->button.y = HIWORD (xevent->lParam);
1854 event->button.x_root = (gfloat)xevent->pt.x;
1855 event->button.y_root = (gfloat)xevent->pt.y;
1856 event->button.pressure = 0.5;
1857 event->button.xtilt = 0;
1858 event->button.ytilt = 0;
1859 event->button.state = 0;
1860 if (xevent->wParam & MK_CONTROL)
1861 event->button.state |= GDK_CONTROL_MASK;
1862 if (xevent->wParam & MK_LBUTTON)
1863 event->button.state |= GDK_BUTTON1_MASK;
1864 if (xevent->wParam & MK_MBUTTON)
1865 event->button.state |= GDK_BUTTON2_MASK;
1866 if (xevent->wParam & MK_RBUTTON)
1867 event->button.state |= GDK_BUTTON3_MASK;
1868 if (xevent->wParam & MK_SHIFT)
1869 event->button.state |= GDK_SHIFT_MASK;
1870 if (GetKeyState (VK_MENU) < 0)
1871 event->button.state |= GDK_MOD1_MASK;
1872 if (GetKeyState (VK_CAPITAL) & 0x1)
1873 event->button.state |= GDK_LOCK_MASK;
1874 event->button.button = button;
1875 event->button.source = GDK_SOURCE_MOUSE;
1876 event->button.deviceid = GDK_CORE_POINTER;
1878 if ((event->button.time < (button_click_time[1] + TRIPLE_CLICK_TIME)) &&
1879 (event->button.window == button_window[1]) &&
1880 (event->button.button == button_number[1]))
1882 gdk_synthesize_click (event, 3);
1884 button_click_time[1] = 0;
1885 button_click_time[0] = 0;
1886 button_window[1] = NULL;
1887 button_window[0] = 0;
1888 button_number[1] = -1;
1889 button_number[0] = -1;
1891 else if ((event->button.time < (button_click_time[0] + DOUBLE_CLICK_TIME)) &&
1892 (event->button.window == button_window[0]) &&
1893 (event->button.button == button_number[0]))
1895 gdk_synthesize_click (event, 2);
1897 button_click_time[1] = button_click_time[0];
1898 button_click_time[0] = event->button.time;
1899 button_window[1] = button_window[0];
1900 button_window[0] = event->button.window;
1901 button_number[1] = button_number[0];
1902 button_number[0] = event->button.button;
1906 button_click_time[1] = 0;
1907 button_click_time[0] = event->button.time;
1908 button_window[1] = NULL;
1909 button_window[0] = event->button.window;
1910 button_number[1] = -1;
1911 button_number[0] = event->button.button;
1913 return_val = window_private && !window_private->destroyed;
1915 && p_grab_window != NULL
1916 && event->any.window == (GdkWindow *) p_grab_window
1917 && p_grab_window != window_private)
1919 /* Translate coordinates to grabber */
1920 pt.x = event->button.x;
1921 pt.y = event->button.y;
1922 ClientToScreen (window_private->xwindow, &pt);
1923 ScreenToClient (p_grab_window->xwindow, &pt);
1924 event->button.x = pt.x;
1925 event->button.y = pt.y;
1926 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
1941 g_print ("WM_%cBUTTONUP: %#x x,y: %d %d button: %d\n",
1944 LOWORD (xevent->lParam), HIWORD (xevent->lParam),
1948 && (window_private->extension_events != 0)
1949 && gdk_input_ignore_core)
1951 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
1955 if (window != curWnd)
1956 synthesize_crossing_events (window, xevent);
1958 event->button.type = GDK_BUTTON_RELEASE;
1960 event->button.window = window;
1962 mask = window_private->event_mask;
1966 if (p_grab_window != NULL
1967 && !p_grab_owner_events)
1969 /* Pointer is grabbed with owner_events FALSE */
1970 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
1971 mask = p_grab_event_mask;
1972 if (!(mask & GDK_BUTTON_RELEASE_MASK))
1973 /* Grabber doesn't want it */
1976 event->button.window = (GdkWindow *) p_grab_window;
1977 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1978 p_grab_window->xwindow));
1980 else if (window_private
1981 && !(mask & GDK_BUTTON_RELEASE_MASK))
1983 /* Owner window doesn't want it */
1984 if (p_grab_window != NULL
1985 && p_grab_owner_events)
1987 /* Pointer is grabbed wÃth owner_events TRUE */
1988 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
1989 mask = p_grab_event_mask;
1990 if (!(mask & GDK_BUTTON_RELEASE_MASK))
1991 /* Grabber doesn't want it */
1994 event->button.window = (GdkWindow *) p_grab_window;
1995 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
1996 p_grab_window->xwindow));
2000 /* Owner doesn't want it, neither is it grabbed, so
2001 * propagate to parent.
2003 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
2005 pt.x = LOWORD (xevent->lParam);
2006 pt.y = HIWORD (xevent->lParam);
2007 ClientToScreen (window_private->xwindow, &pt);
2008 gdk_window_unref (window);
2009 window = window_private->parent;
2010 gdk_window_ref (window);
2011 window_private = (GdkWindowPrivate *) window;
2012 ScreenToClient (window_private->xwindow, &pt);
2013 xevent->lParam = MAKELPARAM (pt.x, pt.y);
2014 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
2015 window_private->xwindow));
2020 event->button.time = xevent->time;
2021 event->button.x = LOWORD (xevent->lParam);
2022 event->button.y = HIWORD (xevent->lParam);
2023 event->button.x_root = (gfloat)xevent->pt.x;
2024 event->button.y_root = (gfloat)xevent->pt.y;
2025 event->button.pressure = 0.5;
2026 event->button.xtilt = 0;
2027 event->button.ytilt = 0;
2028 event->button.state = 0;
2029 if (xevent->wParam & MK_CONTROL)
2030 event->button.state |= GDK_CONTROL_MASK;
2031 if (xevent->wParam & MK_LBUTTON)
2032 event->button.state |= GDK_BUTTON1_MASK;
2033 if (xevent->wParam & MK_MBUTTON)
2034 event->button.state |= GDK_BUTTON2_MASK;
2035 if (xevent->wParam & MK_RBUTTON)
2036 event->button.state |= GDK_BUTTON3_MASK;
2037 if (xevent->wParam & MK_SHIFT)
2038 event->button.state |= GDK_SHIFT_MASK;
2039 event->button.button = button;
2040 event->button.source = GDK_SOURCE_MOUSE;
2041 event->button.deviceid = GDK_CORE_POINTER;
2042 return_val = window_private && !window_private->destroyed;
2044 && p_grab_window != NULL
2045 && event->any.window == (GdkWindow *) p_grab_window
2046 && p_grab_window != window_private)
2048 /* Translate coordinates to grabber */
2049 pt.x = event->button.x;
2050 pt.y = event->button.y;
2051 ClientToScreen (window_private->xwindow, &pt);
2052 ScreenToClient (p_grab_window->xwindow, &pt);
2053 event->button.x = pt.x;
2054 event->button.y = pt.y;
2055 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
2057 if (p_grab_window != NULL
2059 && (event->button.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0)
2060 gdk_pointer_ungrab (0);
2065 g_print ("WM_MOUSEMOVE: %#x %#x +%d+%d\n",
2066 xevent->hwnd, xevent->wParam,
2067 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2070 /* Try hard not to generate events for windows that shouldn't
2071 get any. This is hard because we don't want pushbuttons to
2072 highlight when the cursor moves over them if the window is
2073 inactive. We dont want tooltips windows to be active. OTOH,
2074 also menus are popup windows, but they definitely should
2075 get events. Aw shit. Skip this.
2077 dwStyle = GetWindowLong (xevent->hwnd, GWL_STYLE);
2078 if (active == NULL ||
2079 !(active == xevent->hwnd
2080 || (dwStyle & WS_POPUP)
2081 || IsChild (active, xevent->hwnd)))
2084 { /* HB: only process mouse move messages
2085 * if we own the active window.
2087 DWORD ProcessID_ActWin;
2088 DWORD ProcessID_this;
2090 GetWindowThreadProcessId(GetActiveWindow(), &ProcessID_ActWin);
2091 GetWindowThreadProcessId(xevent->hwnd, &ProcessID_this);
2092 if (ProcessID_ActWin != ProcessID_this)
2096 if (window != curWnd)
2097 synthesize_crossing_events (window, xevent);
2100 && (window_private->extension_events != 0)
2101 && gdk_input_ignore_core)
2103 GDK_NOTE (EVENTS, g_print ("...ignored\n"));
2108 event->motion.type = GDK_MOTION_NOTIFY;
2109 event->motion.window = window;
2111 mask = window_private->event_mask;
2116 && !p_grab_owner_events)
2118 /* Pointer is grabbed with owner_events FALSE */
2120 g_print ("...grabbed, owner_events FALSE\n"));
2121 mask = p_grab_event_mask;
2122 if (!((mask & GDK_POINTER_MOTION_MASK)
2123 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2124 && (mask & GDK_BUTTON_MOTION_MASK))
2125 || ((xevent->wParam & MK_LBUTTON)
2126 && (mask & GDK_BUTTON1_MOTION_MASK))
2127 || ((xevent->wParam & MK_MBUTTON)
2128 && (mask & GDK_BUTTON2_MOTION_MASK))
2129 || ((xevent->wParam & MK_RBUTTON)
2130 && (mask & GDK_BUTTON3_MOTION_MASK))))
2133 event->motion.window = (GdkWindow *) p_grab_window;
2134 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
2135 p_grab_window->xwindow));
2137 else if (window_private
2138 && !((mask & GDK_POINTER_MOTION_MASK)
2139 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2140 && (mask & GDK_BUTTON_MOTION_MASK))
2141 || ((xevent->wParam & MK_LBUTTON)
2142 && (mask & GDK_BUTTON1_MOTION_MASK))
2143 || ((xevent->wParam & MK_MBUTTON)
2144 && (mask & GDK_BUTTON2_MOTION_MASK))
2145 || ((xevent->wParam & MK_RBUTTON)
2146 && (mask & GDK_BUTTON3_MOTION_MASK))))
2148 /* Owner window doesn't want it */
2149 if (p_grab_window != NULL
2150 && p_grab_owner_events)
2152 /* Pointer is grabbed wÃth owner_events TRUE */
2153 GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
2154 mask = p_grab_event_mask;
2155 if (!((p_grab_event_mask & GDK_POINTER_MOTION_MASK)
2156 || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
2157 && (mask & GDK_BUTTON_MOTION_MASK))
2158 || ((xevent->wParam & MK_LBUTTON)
2159 && (mask & GDK_BUTTON1_MOTION_MASK))
2160 || ((xevent->wParam & MK_MBUTTON)
2161 && (mask & GDK_BUTTON2_MOTION_MASK))
2162 || ((xevent->wParam & MK_RBUTTON)
2163 && (mask & GDK_BUTTON3_MOTION_MASK))))
2164 /* Grabber doesn't want it either */
2167 event->motion.window = (GdkWindow *) p_grab_window;
2168 GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
2169 p_grab_window->xwindow));
2173 /* Owner doesn't want it, neither is it grabbed, so
2174 * propagate to parent.
2176 if (window_private->parent == (GdkWindow *) &gdk_root_parent)
2178 pt.x = LOWORD (xevent->lParam);
2179 pt.y = HIWORD (xevent->lParam);
2180 ClientToScreen (window_private->xwindow, &pt);
2181 gdk_window_unref (window);
2182 window = window_private->parent;
2183 gdk_window_ref (window);
2184 window_private = (GdkWindowPrivate *) window;
2185 ScreenToClient (window_private->xwindow, &pt);
2186 xevent->lParam = MAKELPARAM (pt.x, pt.y);
2187 GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
2188 window_private->xwindow));
2193 event->motion.time = xevent->time;
2194 event->motion.x = curX = LOWORD (xevent->lParam);
2195 event->motion.y = curY = HIWORD (xevent->lParam);
2196 event->motion.x_root = xevent->pt.x;
2197 event->motion.y_root = xevent->pt.y;
2198 curXroot = event->motion.x_root;
2199 curYroot = event->motion.y_root;
2200 event->motion.pressure = 0.5;
2201 event->motion.xtilt = 0;
2202 event->motion.ytilt = 0;
2203 event->button.state = 0;
2204 if (xevent->wParam & MK_CONTROL)
2205 event->button.state |= GDK_CONTROL_MASK;
2206 if (xevent->wParam & MK_LBUTTON)
2207 event->button.state |= GDK_BUTTON1_MASK;
2208 if (xevent->wParam & MK_MBUTTON)
2209 event->button.state |= GDK_BUTTON2_MASK;
2210 if (xevent->wParam & MK_RBUTTON)
2211 event->button.state |= GDK_BUTTON3_MASK;
2212 if (xevent->wParam & MK_SHIFT)
2213 event->button.state |= GDK_SHIFT_MASK;
2214 if (mask & GDK_POINTER_MOTION_HINT_MASK)
2215 event->motion.is_hint = NotifyHint;
2217 event->motion.is_hint = NotifyNormal;
2218 event->motion.source = GDK_SOURCE_MOUSE;
2219 event->motion.deviceid = GDK_CORE_POINTER;
2221 return_val = window_private && !window_private->destroyed;
2223 && p_grab_window != NULL
2224 && event->any.window == (GdkWindow *) p_grab_window
2225 && p_grab_window != window_private)
2227 /* Translate coordinates to grabber */
2228 pt.x = event->motion.x;
2229 pt.y = event->motion.y;
2230 ClientToScreen (window_private->xwindow, &pt);
2231 ScreenToClient (p_grab_window->xwindow, &pt);
2232 event->motion.x = pt.x;
2233 event->motion.y = pt.y;
2234 GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
2238 case WM_NCMOUSEMOVE:
2240 g_print ("WM_NCMOUSEMOVE: %#x x,y: %d %d\n",
2242 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2244 if (active == NULL || active != xevent->hwnd)
2247 curWnd_private = (GdkWindowPrivate *) curWnd;
2249 && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
2251 GDK_NOTE (EVENTS, g_print ("...synthesizing LEAVE_NOTIFY event\n"));
2253 event->crossing.type = GDK_LEAVE_NOTIFY;
2254 event->crossing.window = curWnd;
2255 event->crossing.subwindow = NULL;
2256 event->crossing.time = xevent->time;
2257 event->crossing.x = curX;
2258 event->crossing.y = curY;
2259 event->crossing.x_root = curXroot;
2260 event->crossing.y_root = curYroot;
2261 event->crossing.mode = GDK_CROSSING_NORMAL;
2262 event->crossing.detail = GDK_NOTIFY_UNKNOWN;
2264 event->crossing.focus = TRUE; /* ??? */
2265 event->crossing.state = 0; /* ??? */
2266 gdk_window_unref (curWnd);
2276 && !(window_private->event_mask & GDK_FOCUS_CHANGE_MASK))
2279 GDK_NOTE (EVENTS, g_print ("WM_%sFOCUS: %#x\n",
2280 (xevent->message == WM_SETFOCUS ? "SET" : "KILL"),
2283 event->focus_change.type = GDK_FOCUS_CHANGE;
2284 event->focus_change.window = window;
2285 event->focus_change.in = (xevent->message == WM_SETFOCUS);
2286 return_val = window_private && !window_private->destroyed;
2290 GDK_NOTE (EVENTS, g_print ("WM_ACTIVATE: %#x %d\n",
2291 xevent->hwnd, LOWORD (xevent->wParam)));
2292 if (LOWORD (xevent->wParam) == WA_INACTIVE)
2293 active = (HWND) xevent->lParam;
2295 active = xevent->hwnd;
2299 GDK_NOTE (EVENTS, g_print ("WM_ERASEBKGND: %#x dc %#x\n",
2300 xevent->hwnd, xevent->wParam));
2302 if (!window_private || window_private->destroyed)
2304 colormap_private = (GdkColormapPrivate *) window_private->colormap;
2305 hdc = (HDC) xevent->wParam;
2306 if (colormap_private
2307 && colormap_private->xcolormap->rc_palette)
2311 if (SelectPalette (hdc, colormap_private->xcolormap->palette,
2313 g_warning ("WM_ERASEBKGND: SelectPalette failed");
2314 if ((k = RealizePalette (hdc)) == GDI_ERROR)
2315 g_warning ("WM_ERASEBKGND: RealizePalette failed");
2317 g_print ("WM_ERASEBKGND: selected %#x, realized %d colors\n",
2318 colormap_private->xcolormap->palette, k);
2321 *ret_val_flagp = TRUE;
2324 if (window_private->bg_type == GDK_WIN32_BG_TRANSPARENT)
2327 if (window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2329 /* If this window should have the same background as the
2330 * parent, fetch the parent. (And if the same goes for
2331 * the parent, fetch the grandparent, etc.)
2333 while (window_private
2334 && window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
2335 window_private = (GdkWindowPrivate *) window_private->parent;
2338 if (window_private->bg_type == GDK_WIN32_BG_PIXEL)
2341 GetClipBox (hdc, &rect);
2342 GDK_NOTE (EVENTS, g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n",
2343 rect.right - rect.left,
2344 rect.bottom - rect.top,
2345 rect.left, rect.top,
2346 gdk_color_to_string (&window_private->bg_pixel)));
2347 #ifdef MULTIPLE_WINDOW_CLASSES
2348 bg = PALETTEINDEX (window_private->bg_pixel.pixel);
2350 bg = GetNearestColor (hdc, RGB (window_private->bg_pixel.red >> 8,
2351 window_private->bg_pixel.green >> 8,
2352 window_private->bg_pixel.blue >> 8));
2354 hbr = CreateSolidBrush (bg);
2356 g_print ("...CreateSolidBrush (%.08x) = %.08x\n", bg, hbr);
2358 if (!FillRect (hdc, &rect, hbr))
2359 g_warning ("WM_ERASEBKGND: FillRect failed");
2362 else if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
2364 GdkPixmapPrivate *pixmap_private;
2368 pixmap_private = (GdkPixmapPrivate *) window_private->bg_pixmap;
2369 GetClipBox (hdc, &rect);
2371 if (pixmap_private->width <= 8
2372 && pixmap_private->height <= 8)
2374 GDK_NOTE (EVENTS, g_print ("...small pixmap, using brush\n"));
2375 hbr = CreatePatternBrush (pixmap_private->xwindow);
2376 if (!FillRect (hdc, &rect, hbr))
2377 g_warning ("WM_ERASEBKGND: FillRect failed");
2383 g_print ("...blitting pixmap %#x (%dx%d) "
2384 "all over the place,\n"
2385 "...clip box = %dx%d@+%d+%d\n",
2386 pixmap_private->xwindow,
2387 pixmap_private->width, pixmap_private->height,
2388 rect.right - rect.left, rect.bottom - rect.top,
2389 rect.left, rect.top));
2391 if (!(bgdc = CreateCompatibleDC (hdc)))
2393 g_warning ("WM_ERASEBKGND: CreateCompatibleDC failed");
2396 if (!(oldbitmap = SelectObject (bgdc, pixmap_private->xwindow)))
2398 g_warning ("WM_ERASEBKGND: SelectObject failed");
2403 while (i < rect.right)
2406 while (j < rect.bottom)
2408 if (i + pixmap_private->width >= rect.left
2409 && j + pixmap_private->height >= rect.top)
2411 if (!BitBlt (hdc, i, j,
2412 pixmap_private->width, pixmap_private->height,
2413 bgdc, 0, 0, SRCCOPY))
2415 g_warning ("WM_ERASEBKGND: BitBlt failed");
2419 j += pixmap_private->height;
2421 i += pixmap_private->width;
2424 SelectObject (bgdc, oldbitmap);
2430 GDK_NOTE (EVENTS, g_print ("...BLACK_BRUSH (?)\n"));
2431 #ifdef MULTIPLE_WINDOW_CLASSES
2432 hbr = (HBRUSH) GetClassLong (window_private->xwindow,
2435 hbr = GetStockObject (BLACK_BRUSH);
2437 GetClipBox (hdc, &rect);
2438 if (!FillRect (hdc, &rect, hbr))
2439 g_warning ("WM_ERASEBKGND: FillRect failed");
2444 hdc = BeginPaint (xevent->hwnd, &paintstruct);
2447 g_print ("WM_PAINT: %#x %dx%d@+%d+%d %s dc %#x\n",
2449 paintstruct.rcPaint.right - paintstruct.rcPaint.left,
2450 paintstruct.rcPaint.bottom - paintstruct.rcPaint.top,
2451 paintstruct.rcPaint.left, paintstruct.rcPaint.top,
2452 (paintstruct.fErase ? "erase" : ""),
2455 EndPaint (xevent->hwnd, &paintstruct);
2458 && !(window_private->event_mask & GDK_EXPOSURE_MASK))
2461 event->expose.type = GDK_EXPOSE;
2462 event->expose.window = window;
2463 event->expose.area.x = paintstruct.rcPaint.left;
2464 event->expose.area.y = paintstruct.rcPaint.top;
2465 event->expose.area.width = paintstruct.rcPaint.right - paintstruct.rcPaint.left;
2466 event->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
2467 event->expose.count = 1;
2469 return_val = window_private && !window_private->destroyed;
2472 #ifndef MULTIPLE_WINDOW_CLASSES
2474 GDK_NOTE (EVENTS, g_print ("WM_SETCURSOR: %#x %#x %#x\n",
2476 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2479 if (LOWORD (xevent->lParam) != HTCLIENT)
2481 if (p_grab_window != NULL && p_grab_cursor != NULL)
2483 GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", p_grab_cursor));
2484 SetCursor (p_grab_cursor);
2486 else if (window_private
2487 && !window_private->destroyed
2488 && window_private->xcursor)
2490 GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n",
2491 window_private->xcursor));
2492 SetCursor (window_private->xcursor);
2494 *ret_val_flagp = TRUE;
2501 GDK_NOTE (EVENTS, g_print ("WM_QUERYOPEN: %#x\n",
2503 *ret_val_flagp = TRUE;
2507 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2510 event->any.type = GDK_MAP;
2511 event->any.window = window;
2513 return_val = window_private && !window_private->destroyed;
2519 GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#x %d\n",
2524 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2527 event->any.type = (xevent->wParam ? GDK_MAP : GDK_UNMAP);
2528 event->any.window = window;
2530 if (event->any.type == GDK_UNMAP
2531 && p_grab_window == window_private)
2532 gdk_pointer_ungrab (xevent->time);
2534 if (event->any.type == GDK_UNMAP
2535 && k_grab_window == window_private)
2536 gdk_keyboard_ungrab (xevent->time);
2538 return_val = window_private && !window_private->destroyed;
2543 g_print ("WM_SIZE: %#x %s %dx%d\n",
2545 (xevent->wParam == SIZE_MAXHIDE ? "MAXHIDE" :
2546 (xevent->wParam == SIZE_MAXIMIZED ? "MAXIMIZED" :
2547 (xevent->wParam == SIZE_MAXSHOW ? "MAXSHOW" :
2548 (xevent->wParam == SIZE_MINIMIZED ? "MINIMIZED" :
2549 (xevent->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
2550 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2553 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2555 if (window_private != NULL
2556 && xevent->wParam == SIZE_MINIMIZED)
2559 event->any.type = GDK_UNMAP;
2560 event->any.window = window;
2562 if (p_grab_window == window_private)
2563 gdk_pointer_ungrab (xevent->time);
2565 if (k_grab_window == window_private)
2566 gdk_keyboard_ungrab (xevent->time);
2568 return_val = !window_private->destroyed;
2571 else if (window_private != NULL
2572 && (xevent->wParam == SIZE_RESTORED
2573 || xevent->wParam == SIZE_MAXIMIZED)
2575 && window_private->window_type != GDK_WINDOW_CHILD
2579 if (LOWORD (xevent->lParam) == 0)
2582 event->configure.type = GDK_CONFIGURE;
2583 event->configure.window = window;
2586 ClientToScreen (xevent->hwnd, &pt);
2587 event->configure.x = pt.x;
2588 event->configure.y = pt.y;
2589 event->configure.width = LOWORD (xevent->lParam);
2590 event->configure.height = HIWORD (xevent->lParam);
2591 window_private->x = event->configure.x;
2592 window_private->y = event->configure.y;
2593 window_private->width = event->configure.width;
2594 window_private->height = event->configure.height;
2595 if (window_private->resize_count > 1)
2596 window_private->resize_count -= 1;
2598 return_val = !window_private->destroyed;
2600 && window_private->extension_events != 0
2601 && gdk_input_vtable.configure_event)
2602 gdk_input_vtable.configure_event (&event->configure, window);
2607 GDK_NOTE (EVENTS, g_print ("WM_SIZING: %#x\n", xevent->hwnd));
2608 if (ret_val_flagp == NULL)
2609 g_warning ("ret_val_flagp is NULL but we got a WM_SIZING?");
2610 else if (window_private != NULL
2611 && window_private->hint_flags &
2612 (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE))
2614 LPRECT lprc = (LPRECT) xevent->lParam;
2616 if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
2618 gint w = lprc->right - lprc->left;
2619 gint h = lprc->bottom - lprc->top;
2621 if (w < window_private->hint_min_width)
2623 if (xevent->wParam == WMSZ_BOTTOMLEFT
2624 || xevent->wParam == WMSZ_LEFT
2625 || xevent->wParam == WMSZ_TOPLEFT)
2626 lprc->left = lprc->right - window_private->hint_min_width;
2628 lprc->right = lprc->left + window_private->hint_min_width;
2629 *ret_val_flagp = TRUE;
2632 if (h < window_private->hint_min_height)
2634 if (xevent->wParam == WMSZ_BOTTOMLEFT
2635 || xevent->wParam == WMSZ_BOTTOM
2636 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2637 lprc->bottom = lprc->top + window_private->hint_min_height;
2639 lprc->top = lprc->bottom - window_private->hint_min_height;
2640 *ret_val_flagp = TRUE;
2644 if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
2646 gint w = lprc->right - lprc->left;
2647 gint h = lprc->bottom - lprc->top;
2649 if (w > window_private->hint_max_width)
2651 if (xevent->wParam == WMSZ_BOTTOMLEFT
2652 || xevent->wParam == WMSZ_LEFT
2653 || xevent->wParam == WMSZ_TOPLEFT)
2654 lprc->left = lprc->right - window_private->hint_max_width;
2656 lprc->right = lprc->left + window_private->hint_max_width;
2657 *ret_val_flagp = TRUE;
2660 if (h > window_private->hint_max_height)
2662 if (xevent->wParam == WMSZ_BOTTOMLEFT
2663 || xevent->wParam == WMSZ_BOTTOM
2664 || xevent->wParam == WMSZ_BOTTOMRIGHT)
2665 lprc->bottom = lprc->top + window_private->hint_max_height;
2667 lprc->top = lprc->bottom - window_private->hint_max_height;
2668 *ret_val_flagp = TRUE;
2676 GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#x +%d+%d\n",
2678 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2681 && !(window_private->event_mask & GDK_STRUCTURE_MASK))
2683 if (window_private != NULL
2684 && window_private->window_type != GDK_WINDOW_CHILD)
2686 event->configure.type = GDK_CONFIGURE;
2687 event->configure.window = window;
2688 event->configure.x = LOWORD (xevent->lParam);
2689 event->configure.y = HIWORD (xevent->lParam);
2690 GetClientRect (xevent->hwnd, &rect);
2691 event->configure.width = rect.right;
2692 event->configure.height = rect.bottom;
2693 window_private->x = event->configure.x;
2694 window_private->y = event->configure.y;
2695 window_private->width = event->configure.width;
2696 window_private->height = event->configure.height;
2698 return_val = !window_private->destroyed;
2703 GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#x\n", xevent->hwnd));
2704 event->any.type = GDK_DELETE;
2705 event->any.window = window;
2707 return_val = window_private && !window_private->destroyed;
2711 /* No, don't use delayed rendering after all. It works only if the
2712 * delayed SetClipboardData is called from the WindowProc, it
2713 * seems. (The #else part below is test code for that. It succeeds
2714 * in setting the clipboard data. But if I call SetClipboardData
2715 * in gdk_property_change (as a consequence of the
2716 * GDK_SELECTION_REQUEST event), it fails. I deduce that this is
2717 * because delayed rendering requires that SetClipboardData is
2718 * called in the window procedure.)
2720 case WM_RENDERFORMAT:
2721 case WM_RENDERALLFORMATS:
2723 GDK_NOTE (EVENTS, flag = TRUE);
2724 GDK_NOTE (SELECTION, flag = TRUE);
2726 g_print ("WM_%s: %#x %#x (%s)\n",
2727 (xevent->message == WM_RENDERFORMAT ? "RENDERFORMAT" :
2728 "RENDERALLFORMATS"),
2731 (xevent->wParam == CF_TEXT ? "CF_TEXT" :
2732 (xevent->wParam == CF_DIB ? "CF_DIB" :
2733 (xevent->wParam == CF_UNICODETEXT ? "CF_UNICODETEXT" :
2734 (GetClipboardFormatName (xevent->wParam, buf, sizeof (buf)), buf)))));
2737 event->selection.type = GDK_SELECTION_REQUEST;
2738 event->selection.window = window;
2739 event->selection.selection = gdk_clipboard_atom;
2740 if (xevent->wParam == CF_TEXT)
2741 event->selection.target = GDK_TARGET_STRING;
2744 GetClipboardFormatName (xevent->wParam, buf, sizeof (buf));
2745 event->selection.target = gdk_atom_intern (buf, FALSE);
2747 event->selection.property = gdk_selection_property;
2748 event->selection.requestor = (guint32) xevent->hwnd;
2749 event->selection.time = xevent->time;
2750 return_val = window_private && !window_private->destroyed;
2752 /* Test code, to see if SetClipboardData works when called from
2753 * the window procedure.
2756 HGLOBAL hdata = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, 10);
2757 char *ptr = GlobalLock (hdata);
2758 strcpy (ptr, "Huhhaa");
2759 GlobalUnlock (hdata);
2760 if (!SetClipboardData (CF_TEXT, hdata))
2761 g_print ("SetClipboardData failed: %d\n", GetLastError ());
2764 *ret_val_flagp = TRUE;
2768 #endif /* No delayed rendering */
2771 GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#x\n", xevent->hwnd));
2772 event->any.type = GDK_DESTROY;
2773 event->any.window = window;
2774 if (window != NULL && window == curWnd)
2776 gdk_window_unref (curWnd);
2780 if (p_grab_window == window_private)
2781 gdk_pointer_ungrab (xevent->time);
2783 if (k_grab_window == window_private)
2784 gdk_keyboard_ungrab (xevent->time);
2786 return_val = window_private && !window_private->destroyed;
2790 /* Handle WINTAB events here, as we know that gdkinput.c will
2791 * use the fixed WT_DEFBASE as lcMsgBase, and we thus can use the
2792 * constants as case labels.
2795 GDK_NOTE (EVENTS, g_print ("WT_PACKET: %d %#x\n",
2796 xevent->wParam, xevent->lParam));
2800 GDK_NOTE (EVENTS, g_print ("WT_CSRCHANGE: %d %#x\n",
2801 xevent->wParam, xevent->lParam));
2806 g_print ("WT_PROXIMITY: %#x %d %d\n",
2808 LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
2811 return_val = gdk_input_vtable.other_event(event, xevent);
2820 if (event->any.window)
2821 gdk_window_ref (event->any.window);
2822 if (((event->any.type == GDK_ENTER_NOTIFY) ||
2823 (event->any.type == GDK_LEAVE_NOTIFY)) &&
2824 (event->crossing.subwindow != NULL))
2825 gdk_window_ref (event->crossing.subwindow);
2829 /* Mark this event as having no resources to be freed */
2830 event->any.window = NULL;
2831 event->any.type = GDK_NOTHING;
2835 gdk_window_unref (window);
2841 gdk_events_queue (void)
2847 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: %s\n",
2848 (queued_events ? "yes" : "none")));
2850 while (!gdk_event_queue_find_first()
2851 && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
2853 GDK_NOTE (EVENTS, g_print ("gdk_events_queue: got event\n"));
2854 TranslateMessage (&msg);
2856 event = gdk_event_new ();
2858 event->any.type = GDK_NOTHING;
2859 event->any.window = NULL;
2860 event->any.send_event = FALSE;
2862 ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
2864 gdk_event_queue_append (event);
2867 if (gdk_event_translate (event, &msg, NULL, NULL))
2868 ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
2871 DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
2872 gdk_event_queue_remove_link (node);
2873 g_list_free_1 (node);
2874 gdk_event_free (event);
2880 gdk_event_prepare (gpointer source_data,
2881 GTimeVal *current_time,
2887 GDK_THREADS_ENTER ();
2891 GDK_NOTE (EVENTS, g_print ("gdk_event_prepare\n"));
2893 retval = (gdk_event_queue_find_first () != NULL)
2894 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2896 GDK_THREADS_LEAVE ();
2902 gdk_event_check (gpointer source_data,
2903 GTimeVal *current_time)
2908 GDK_NOTE (EVENTS, g_print ("gdk_event_check\n"));
2910 GDK_THREADS_ENTER ();
2912 if (event_poll_fd.revents & G_IO_IN)
2913 retval = (gdk_event_queue_find_first () != NULL)
2914 || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
2918 GDK_THREADS_LEAVE ();
2924 gdk_event_unqueue (void)
2926 GdkEvent *event = NULL;
2929 tmp_list = gdk_event_queue_find_first ();
2933 event = tmp_list->data;
2934 gdk_event_queue_remove_link (tmp_list);
2935 g_list_free_1 (tmp_list);
2942 gdk_event_dispatch (gpointer source_data,
2943 GTimeVal *current_time,
2948 GDK_NOTE (EVENTS, g_print ("gdk_event_dispatch\n"));
2950 GDK_THREADS_ENTER ();
2953 event = gdk_event_unqueue();
2958 (*event_func) (event, event_data);
2960 gdk_event_free (event);
2963 GDK_THREADS_LEAVE ();
2969 gdk_synthesize_click (GdkEvent *event,
2972 GdkEvent temp_event;
2974 g_return_if_fail (event != NULL);
2976 temp_event = *event;
2977 temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS;
2979 gdk_event_put (&temp_event);
2982 /* Sends a ClientMessage to all toplevel client windows */
2984 gdk_event_send_client_message (GdkEvent *event, guint32 xid)
2991 gdk_event_send_clientmessage_toall (GdkEvent *event)