]> Pileus Git - ~andy/gtk/blobdiff - gdk/win32/gdkevents-win32.c
Minor documentation improvements
[~andy/gtk] / gdk / win32 / gdkevents-win32.c
index 38ad79c9fb1d7e5018b3f810924387ba0b4cfa2d..cc7343c7f62b60ec46d3b8d5a54fcb8b1e389cf5 100644 (file)
@@ -1,6 +1,7 @@
 /* GDK - The GIMP Drawing Kit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
  * Copyright (C) 1998-2002 Tor Lillqvist
+ * Copyright (C) 2001,2009 Hans Breuer
  * Copyright (C) 2007-2009 Cody Russell
  *
  * This library is free software; you can redistribute it and/or
 #include <glib/gprintf.h>
 
 #include "gdk.h"
+#include "gdkdisplayprivate.h"
 #include "gdkprivate-win32.h"
-#include "gdkinput-win32.h"
+#include "gdkwin32.h"
 #include "gdkkeysyms.h"
+#include "gdkdevicemanager-win32.h"
+#include "gdkdeviceprivate.h"
+#include "gdkdevice-wintab.h"
+#include "gdkwin32dnd.h"
+#include "gdkdndprivate.h"
 
 #include <windowsx.h>
 
@@ -99,23 +106,9 @@ static gboolean is_modally_blocked (GdkWindow   *window);
 /* Private variable declarations
  */
 
-#if 0
-static GdkWindow *p_grab_window = NULL; /* Window that currently holds
-                                        * the pointer grab
-                                        */
-
-static GdkWindow *p_grab_confine_to = NULL;
-
-static GdkWindow *k_grab_window = NULL; /* Window the holds the
-                                        * keyboard grab
-                                        */
-#endif
-
 static GList *client_filters;  /* Filters for client messages */
+extern gint       _gdk_input_ignore_core;
 
-static gboolean p_grab_automatic;
-static GdkEventMask p_grab_mask;
-static gboolean p_grab_owner_events, k_grab_owner_events;
 static HCURSOR p_grab_cursor;
 
 static GSourceFuncs event_funcs = {
@@ -163,40 +156,19 @@ static void
 track_mouse_event (DWORD dwFlags,
                   HWND  hwnd)
 {
-  typedef BOOL (WINAPI *PFN_TrackMouseEvent) (LPTRACKMOUSEEVENT);
-  static PFN_TrackMouseEvent p_TrackMouseEvent = NULL;
-  static gboolean once = FALSE;
+  TRACKMOUSEEVENT tme;
 
-  if (!once)
-    {
-      HMODULE user32;
-      HINSTANCE commctrl32;
-
-      user32 = GetModuleHandle ("user32.dll");
-      if ((p_TrackMouseEvent = (PFN_TrackMouseEvent)GetProcAddress (user32, "TrackMouseEvent")) == NULL)
-        {
-          if ((commctrl32 = LoadLibrary ("commctrl32.dll")) != NULL)
-           p_TrackMouseEvent = (PFN_TrackMouseEvent)
-             GetProcAddress (commctrl32, "_TrackMouseEvent");
-        }
-      once = TRUE;
-    }
+  tme.cbSize = sizeof(TRACKMOUSEEVENT);
+  tme.dwFlags = dwFlags;
+  tme.hwndTrack = hwnd;
+  tme.dwHoverTime = HOVER_DEFAULT; /* not used */
 
-  if (p_TrackMouseEvent)
-    {
-      TRACKMOUSEEVENT tme;
-      tme.cbSize = sizeof(TRACKMOUSEEVENT);
-      tme.dwFlags = dwFlags;
-      tme.hwndTrack = hwnd;
-      tme.dwHoverTime = HOVER_DEFAULT; /* not used */
-
-      if (!p_TrackMouseEvent (&tme))
-        WIN32_API_FAILED ("TrackMouseEvent");
-      else if (dwFlags == TME_LEAVE)
-        GDK_NOTE (EVENTS, g_print(" (TrackMouseEvent %p)", hwnd));
-      else if (dwFlags == TME_CANCEL)
-       GDK_NOTE (EVENTS, g_print(" (cancel TrackMouseEvent %p)", hwnd));
-    }
+  if (!TrackMouseEvent (&tme))
+    WIN32_API_FAILED ("TrackMouseEvent");
+  else if (dwFlags == TME_LEAVE)
+    GDK_NOTE (EVENTS, g_print(" (TrackMouseEvent %p)", hwnd));
+  else if (dwFlags == TME_CANCEL)
+    GDK_NOTE (EVENTS, g_print(" (cancel TrackMouseEvent %p)", hwnd));
 }
 
 gulong
@@ -213,31 +185,44 @@ _gdk_win32_get_next_tick (gulong suggested_tick)
 }
 
 static void
-generate_focus_event (GdkWindow *window,
-                     gboolean   in)
+generate_focus_event (GdkDeviceManager *device_manager,
+                      GdkWindow        *window,
+                      gboolean          in)
 {
+  GdkDevice *device;
   GdkEvent *event;
 
+  device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard;
+
   event = gdk_event_new (GDK_FOCUS_CHANGE);
   event->focus_change.window = window;
   event->focus_change.in = in;
+  gdk_event_set_device (event, device);
 
   append_event (event);
 }
 
 static void
-generate_grab_broken_event (GdkWindow *window,
-                           gboolean   keyboard,
-                           GdkWindow *grab_window)
+generate_grab_broken_event (GdkDeviceManager *device_manager,
+                            GdkWindow        *window,
+                            gboolean          keyboard,
+                            GdkWindow        *grab_window)
 {
   GdkEvent *event = gdk_event_new (GDK_GRAB_BROKEN);
+  GdkDevice *device;
+
+  if (keyboard)
+    device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard;
+  else
+    device = GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_pointer;
 
   event->grab_broken.window = window;
   event->grab_broken.send_event = 0;
   event->grab_broken.keyboard = keyboard;
   event->grab_broken.implicit = FALSE;
   event->grab_broken.grab_window = grab_window;
-         
+  gdk_event_set_device (event, device);
+
   append_event (event);
 }
 
@@ -391,6 +376,7 @@ _gdk_events_init (void)
 #endif
 
   source = g_source_new (&event_funcs, sizeof (GSource));
+  g_source_set_name (source, "GDK Win32 event source"); 
   g_source_set_priority (source, GDK_PRIORITY_EVENTS);
 
 #ifdef G_WITH_CYGWIN
@@ -408,37 +394,15 @@ _gdk_events_init (void)
 }
 
 gboolean
-gdk_events_pending (void)
+_gdk_win32_display_has_pending (GdkDisplay *display)
 {
   MSG msg;
-  return (_gdk_event_queue_find_first (_gdk_display) ||
+  return (_gdk_event_queue_find_first (display) ||
          (modal_win32_dialog == NULL &&
           PeekMessageW (&msg, NULL, 0, 0, PM_NOREMOVE)));
 }
 
-GdkEvent*
-gdk_event_get_graphics_expose (GdkWindow *window)
-{
-  MSG msg;
-  GdkEvent *event = NULL;
-
-  g_return_val_if_fail (window != NULL, NULL);
-  
-  GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose\n"));
-
-  if (PeekMessageW (&msg, GDK_WINDOW_HWND (window), WM_PAINT, WM_PAINT, PM_REMOVE))
-    {
-      handle_wm_paint (&msg, window, TRUE, &event);
-      if (event != NULL)
-       {
-         GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose: got it!\n"));
-         return event;
-       }
-    }
-  
-  GDK_NOTE (EVENTS, g_print ("gdk_event_get_graphics_expose: nope\n"));
-  return NULL; 
-}
+#if 0 /* Unused, but might be useful to re-introduce in some debugging output? */
 
 static char *
 event_mask_string (GdkEventMask mask)
@@ -476,94 +440,108 @@ event_mask_string (GdkEventMask mask)
   return bfr;
 }
 
-GdkGrabStatus
-_gdk_windowing_pointer_grab (GdkWindow    *window,
-                            GdkWindow    *native_window,
-                            gboolean   owner_events,
-                            GdkEventMask       event_mask,
-                            GdkWindow    *confine_to,
-                            GdkCursor    *cursor,
-                            guint32    time)
-{
-  SetCapture (GDK_WINDOW_HWND (native_window));
-  /* TODO_CSW: grab brokens, confine window, cursor, input_grab */
-  return GDK_GRAB_SUCCESS;
-}
+#endif
 
-void
-gdk_display_pointer_ungrab (GdkDisplay *display,
-                            guint32     time)
+GdkGrabStatus
+_gdk_windowing_device_grab (GdkDevice    *device,
+                            GdkWindow    *window,
+                            GdkWindow    *native_window,
+                            gboolean      owner_events,
+                            GdkEventMask       event_mask,
+                            GdkWindow    *confine_to,
+                            GdkCursor    *cursor,
+                            guint32          time)
 {
-  GdkPointerGrabInfo *info;
+  HCURSOR hcursor;
+  GdkWin32Cursor *cursor_private;
+  gint return_val;
+  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (native_window->impl);
 
-  info = _gdk_display_get_last_pointer_grab (display);
-  if (info)
+  g_return_val_if_fail (window != NULL, 0);
+  g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
+  g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
+  
+  cursor_private = (GdkWin32Cursor*) cursor;
+  
+  if (!cursor)
+    hcursor = NULL;
+  else if ((hcursor = CopyCursor (cursor_private->hcursor)) == NULL)
+    WIN32_API_FAILED ("CopyCursor");
+
+  return_val = GDK_DEVICE_GET_CLASS (device)->grab (device,
+                                                    native_window,
+                                                    owner_events,
+                                                    event_mask,
+                                                    confine_to,
+                                                    cursor,
+                                                    time);
+
+  /* TODO_CSW: grab brokens, confine window, input_grab */
+  if (p_grab_cursor != NULL)
     {
-      info->serial_end = 0;
-      ReleaseCapture ();
+      if (GetCursor () == p_grab_cursor)
+        SetCursor (NULL);
+      DestroyCursor (p_grab_cursor);
     }
-  /* TODO_CSW: cursor, confines, etc */
 
-  _gdk_display_pointer_grab_update (display, 0);
+  p_grab_cursor = hcursor;
+
+  if (p_grab_cursor != NULL)
+    SetCursor (p_grab_cursor);
+  else if (impl->hcursor != NULL)
+    SetCursor (impl->hcursor);
+  else
+    SetCursor (LoadCursor (NULL, IDC_ARROW));
+
+  return return_val;
 }
 
-GdkGrabStatus
-gdk_keyboard_grab (GdkWindow *window,
-                  gboolean   owner_events,
-                  guint32    time)
+static GdkWindow *
+find_window_for_mouse_event (GdkWindow* reported_window,
+                            MSG*       msg)
 {
-  GdkDisplay *display;
-  GdkWindow  *toplevel;
+  HWND hwnd;
+  POINTS points;
+  POINT pt;
+  GdkWindow* other_window = NULL;
+  GdkDeviceManagerWin32 *device_manager;
 
-  g_return_val_if_fail (window != NULL, 0);
-  g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
-  
-  GDK_NOTE (EVENTS, g_print ("gdk_keyboard_grab %p%s\n",
-                            GDK_WINDOW_HWND (window), owner_events ? " OWNER_EVENTS" : ""));
+  device_manager = GDK_DEVICE_MANAGER_WIN32 (gdk_display_get_device_manager (_gdk_display));
 
-  display = gdk_drawable_get_display (window);
-  toplevel = gdk_window_get_toplevel (window);
+  if (!_gdk_display_get_last_device_grab (_gdk_display, device_manager->core_pointer))
+    return reported_window;
 
-  _gdk_display_set_has_keyboard_grab (display,
-                                     window,
-                                     toplevel,
-                                     owner_events,
-                                     0,
-                                     time);
+  points = MAKEPOINTS (msg->lParam);
+  pt.x = points.x;
+  pt.y = points.y;
+  ClientToScreen (msg->hwnd, &pt);
 
-  return GDK_GRAB_SUCCESS;
-}
+  hwnd = WindowFromPoint (pt);
 
-void
-gdk_display_keyboard_ungrab (GdkDisplay *display,
-                             guint32 time)
-{
-  GDK_NOTE (EVENTS, g_print ("gdk_display_keyboard_ungrab\n"));
-  _gdk_display_unset_has_keyboard_grab (display, FALSE);
-}
+  if (hwnd != NULL)
+    {
+      RECT rect;
 
-void 
-gdk_display_add_client_message_filter (GdkDisplay   *display,
-                                      GdkAtom       message_type,
-                                      GdkFilterFunc func,
-                                      gpointer      data)
-{
-  /* XXX */
-  gdk_add_client_message_filter (message_type, func, data);
-}
+      GetClientRect (hwnd, &rect);
+      ScreenToClient (hwnd, &pt);
+      if (!PtInRect (&rect, pt))
+       return _gdk_root;
 
-void
-gdk_add_client_message_filter (GdkAtom       message_type,
-                              GdkFilterFunc func,
-                              gpointer      data)
-{
-  GdkClientFilter *filter = g_new (GdkClientFilter, 1);
+      other_window = gdk_win32_handle_table_lookup (hwnd);
+    }
 
-  filter->type = message_type;
-  filter->function = func;
-  filter->data = data;
-  
-  client_filters = g_list_append (client_filters, filter);
+  if (other_window == NULL)
+    return _gdk_root;
+
+  /* need to also adjust the coordinates to the new window */
+  pt.x = points.x;
+  pt.y = points.y;
+  ClientToScreen (msg->hwnd, &pt);
+  ScreenToClient (GDK_WINDOW_HWND (other_window), &pt);
+  /* ATTENTION: need to update client coords */
+  msg->lParam = MAKELPARAM (pt.x, pt.y);
+
+  return other_window;
 }
 
 static void
@@ -695,8 +673,8 @@ print_event_state (guint state)
 #undef CASE
 }
 
-static void
-print_event (GdkEvent *event)
+void
+_gdk_win32_print_event (const GdkEvent *event)
 {
   gchar *escaped, *kvname;
   gchar *selection_name, *target_name, *property_name;
@@ -736,7 +714,6 @@ print_event (GdkEvent *event)
     CASE (GDK_DROP_FINISHED);
     CASE (GDK_CLIENT_EVENT);
     CASE (GDK_VISIBILITY_NOTIFY);
-    CASE (GDK_NO_EXPOSE);
     CASE (GDK_SCROLL);
     CASE (GDK_WINDOW_STATE);
     CASE (GDK_SETTING);
@@ -746,7 +723,7 @@ print_event (GdkEvent *event)
     default: g_assert_not_reached ();
     }
 
-  g_print (" %p ", GDK_WINDOW_HWND (event->any.window));
+  g_print (" %p ", event->any.window ? GDK_WINDOW_HWND (event->any.window) : NULL);
 
   switch (event->any.type)
     {
@@ -810,9 +787,14 @@ print_event (GdkEvent *event)
     case GDK_FOCUS_CHANGE:
       g_print ("%s", (event->focus_change.in ? "IN" : "OUT"));
       break;
+    case GDK_CONFIGURE:
+      g_print ("x:%d y:%d w:%d h:%d",
+              event->configure.x, event->configure.y,
+              event->configure.width, event->configure.height);
+      break;
+    case GDK_SELECTION_CLEAR:
     case GDK_SELECTION_REQUEST:
     case GDK_SELECTION_NOTIFY:
-    case GDK_SELECTION_CLEAR:
       selection_name = gdk_atom_name (event->selection.selection);
       target_name = gdk_atom_name (event->selection.target);
       property_name = gdk_atom_name (event->selection.property);
@@ -822,20 +804,22 @@ print_event (GdkEvent *event)
       g_free (target_name);
       g_free (property_name);
       break;
-    case GDK_CONFIGURE:
-      g_print ("x:%d y:%d w:%d h:%d",
-              event->configure.x, event->configure.y,
-              event->configure.width, event->configure.height);
+    case GDK_DRAG_ENTER:
+    case GDK_DRAG_LEAVE:
+    case GDK_DRAG_MOTION:
+    case GDK_DRAG_STATUS:
+    case GDK_DROP_START:
+    case GDK_DROP_FINISHED:
+      if (event->dnd.context != NULL)
+       g_print ("ctx:%p: %s %s src:%p dest:%p",
+                event->dnd.context,
+                _gdk_win32_drag_protocol_to_string (event->dnd.context->protocol),
+                event->dnd.context->is_source ? "SOURCE" : "DEST",
+                event->dnd.context->source_window == NULL ? NULL : GDK_WINDOW_HWND (event->dnd.context->source_window),
+                event->dnd.context->dest_window == NULL ? NULL : GDK_WINDOW_HWND (event->dnd.context->dest_window));
       break;
     case GDK_CLIENT_EVENT:
-      g_print ("%s %d %ld %ld %ld %ld %ld",
-              gdk_atom_name (event->client.message_type),
-              event->client.data_format,
-              event->client.data.l[0],
-              event->client.data.l[1],
-              event->client.data.l[2],
-              event->client.data.l[3],
-              event->client.data.l[4]);
+      /* no more GdkEventClient */
       break;
     case GDK_SCROLL:
       g_print ("(%.4g,%.4g) (%.4g,%.4g) %s ",
@@ -910,9 +894,15 @@ append_event (GdkEvent *event)
   GList *link;
   
   fixup_event (event);
+#if 1
   link = _gdk_event_queue_append (_gdk_display, event);
+  GDK_NOTE (EVENTS, _gdk_win32_print_event (event));
+  /* event morphing, the passed in may not be valid afterwards */
   _gdk_windowing_got_event (_gdk_display, link, event, 0);
-  GDK_NOTE (EVENTS, print_event (event));
+#else
+  _gdk_event_queue_append (_gdk_display, event);
+  GDK_NOTE (EVENTS, _gdk_win32_print_event (event));
+#endif
 }
 
 static void
@@ -926,7 +916,7 @@ fill_key_event_string (GdkEvent *event)
    */
   
   c = 0;
-  if (event->key.keyval != GDK_VoidSymbol)
+  if (event->key.keyval != GDK_KEY_VoidSymbol)
     c = gdk_keyval_to_unicode (event->key.keyval);
 
   if (c)
@@ -963,13 +953,13 @@ fill_key_event_string (GdkEvent *event)
       if (event->key.string)
        event->key.length = bytes_written;
     }
-  else if (event->key.keyval == GDK_Escape)
+  else if (event->key.keyval == GDK_KEY_Escape)
     {
       event->key.length = 1;
       event->key.string = g_strdup ("\033");
     }
-  else if (event->key.keyval == GDK_Return ||
-          event->key.keyval == GDK_KP_Enter)
+  else if (event->key.keyval == GDK_KEY_Return ||
+          event->key.keyval == GDK_KEY_KP_Enter)
     {
       event->key.length = 1;
       event->key.string = g_strdup ("\r");
@@ -985,7 +975,7 @@ fill_key_event_string (GdkEvent *event)
 static GdkFilterReturn
 apply_event_filters (GdkWindow  *window,
                     MSG        *msg,
-                    GList      *filters)
+                    GList     **filters)
 {
   GdkFilterReturn result = GDK_FILTER_CONTINUE;
   GdkEvent *event;
@@ -1003,13 +993,34 @@ apply_event_filters (GdkWindow  *window,
    */
   node = _gdk_event_queue_append (_gdk_display, event);
   
-  tmp_list = filters;
+  tmp_list = *filters;
   while (tmp_list)
     {
       GdkEventFilter *filter = (GdkEventFilter *) tmp_list->data;
-      
-      tmp_list = tmp_list->next;
+      GList *node;
+
+      if ((filter->flags & GDK_EVENT_FILTER_REMOVED) != 0)
+        {
+          tmp_list = tmp_list->next;
+          continue;
+        }
+
+      filter->ref_count++;
       result = filter->function (msg, event, filter->data);
+
+      /* get the next node after running the function since the
+         function may add or remove a next node */
+      node = tmp_list;
+      tmp_list = tmp_list->next;
+
+      filter->ref_count--;
+      if (filter->ref_count == 0)
+        {
+          *filters = g_list_remove_link (*filters, node);
+          g_list_free_1 (node);
+          g_free (filter);
+        }
+
       if (result !=  GDK_FILTER_CONTINUE)
        break;
     }
@@ -1024,7 +1035,7 @@ apply_event_filters (GdkWindow  *window,
     {
       ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
       fixup_event (event);
-      GDK_NOTE (EVENTS, print_event (event));
+      GDK_NOTE (EVENTS, _gdk_win32_print_event (event));
     }
   return result;
 }
@@ -1045,7 +1056,7 @@ apply_event_filters (GdkWindow  *window,
 static void
 show_window_recurse (GdkWindow *window, gboolean hide_window)
 {
-  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
   GSList *children = impl->transient_children;
   GdkWindow *child = NULL;
 
@@ -1068,9 +1079,9 @@ show_window_recurse (GdkWindow *window, gboolean hide_window)
        {
          if (!hide_window)
            {
-             if (GDK_WINDOW_OBJECT (window)->state & GDK_WINDOW_STATE_ICONIFIED)
+             if (gdk_window_get_state (window) & GDK_WINDOW_STATE_ICONIFIED)
                {
-                 if (GDK_WINDOW_OBJECT (window)->state & GDK_WINDOW_STATE_MAXIMIZED)
+                 if (gdk_window_get_state (window) & GDK_WINDOW_STATE_MAXIMIZED)
                    {
                      ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
                    }
@@ -1094,7 +1105,7 @@ static void
 do_show_window (GdkWindow *window, gboolean hide_window)
 {
   GdkWindow *tmp_window = NULL;
-  GdkWindowImplWin32 *tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+  GdkWindowImplWin32 *tmp_impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
   if (!tmp_impl->changing_state)
     {
@@ -1102,7 +1113,7 @@ do_show_window (GdkWindow *window, gboolean hide_window)
       while (tmp_impl->transient_owner != NULL)
        {
          tmp_window = tmp_impl->transient_owner;
-         tmp_impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (tmp_window)->impl);
+         tmp_impl = GDK_WINDOW_IMPL_WIN32 (tmp_window->impl);
        }
 
       /* If we couldn't find one, use the window provided. */
@@ -1119,23 +1130,12 @@ do_show_window (GdkWindow *window, gboolean hide_window)
     }
 }
 
-static gboolean
-gdk_window_is_ancestor (GdkWindow *ancestor,
-                       GdkWindow *window)
-{
-  if (ancestor == NULL || window == NULL)
-    return FALSE;
-
-  return (gdk_window_get_parent (window) == ancestor ||
-         gdk_window_is_ancestor (ancestor, gdk_window_get_parent (window)));
-}
-
 static void
-synthesize_enter_or_leave_event (GdkWindow     *window,
-                                MSG            *msg,
-                                GdkEventType    type,
-                                GdkCrossingMode mode,
-                                GdkNotifyType detail)
+synthesize_enter_or_leave_event (GdkWindow        *window,
+                                 MSG             *msg,
+                                 GdkEventType     type,
+                                 GdkCrossingMode   mode,
+                                 GdkNotifyType     detail)
 {
   GdkEvent *event;
   POINT pt;
@@ -1155,124 +1155,15 @@ synthesize_enter_or_leave_event (GdkWindow     *window,
   event->crossing.detail = detail;
   event->crossing.focus = TRUE; /* FIXME: Set correctly */
   event->crossing.state = 0;   /* FIXME: Set correctly */
+  gdk_event_set_device (event, _gdk_display->core_pointer);
 
   append_event (event);
   
   if (type == GDK_ENTER_NOTIFY &&
-      ((GdkWindowObject *) window)->extension_events != 0)
-    _gdk_input_enter_event (window);
+      window->extension_events != 0)
+    _gdk_device_wintab_update_window_coords (window);
 }
                         
-static void
-synthesize_expose_events (GdkWindow *window)
-{
-  RECT r;
-  HDC hdc;
-  GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (((GdkWindowObject *) window)->impl);
-  GList *list = gdk_window_get_children (window);
-  GList *head = list;
-  GdkEvent *event;
-  int k;
-  
-  while (list)
-    {
-      synthesize_expose_events ((GdkWindow *) list->data);
-      list = list->next;
-    }
-
-  g_list_free (head);
-
-  if (((GdkWindowObject *) window)->input_only)
-    ;
-  else if (!(hdc = GetDC (impl->handle)))
-    WIN32_GDI_FAILED ("GetDC");
-  else
-    {
-      if ((k = GetClipBox (hdc, &r)) == ERROR)
-       WIN32_GDI_FAILED ("GetClipBox");
-      else if (k != NULLREGION)
-       {
-         event = gdk_event_new (GDK_EXPOSE);
-         event->expose.window = window;
-         event->expose.area.x = r.left;
-         event->expose.area.y = r.top;
-         event->expose.area.width = r.right - r.left;
-         event->expose.area.height = r.bottom - r.top;
-         event->expose.region = gdk_region_rectangle (&(event->expose.area));
-         event->expose.count = 0;
-  
-         append_event (event);
-       }
-      GDI_CALL (ReleaseDC, (impl->handle, hdc));
-    }
-}
-
-static void
-update_colors (GdkWindow *window,
-              gboolean   top)
-{
-  HDC hdc;
-  GdkDrawableImplWin32 *impl = GDK_DRAWABLE_IMPL_WIN32 (((GdkWindowObject *) window)->impl);
-  GList *list = gdk_window_get_children (window);
-  GList *head = list;
-
-  GDK_NOTE (COLORMAP, (top ? g_print ("update_colors:") : (void) 0));
-
-  while (list)
-    {
-      update_colors ((GdkWindow *) list->data, FALSE);
-      list = list->next;
-    }
-  g_list_free (head);
-
-  if (((GdkWindowObject *) window)->input_only ||
-      impl->colormap == NULL)
-    return;
-
-  if (!(hdc = GetDC (impl->handle)))
-    WIN32_GDI_FAILED ("GetDC");
-  else
-    {
-      GdkColormapPrivateWin32 *cmapp = GDK_WIN32_COLORMAP_DATA (impl->colormap);
-      HPALETTE holdpal;
-      gint k;
-      
-      if ((holdpal = SelectPalette (hdc, cmapp->hpal, TRUE)) == NULL)
-       WIN32_GDI_FAILED ("SelectPalette");
-      else if ((k = RealizePalette (hdc)) == GDI_ERROR)
-       WIN32_GDI_FAILED ("RealizePalette");
-      else
-       {
-         GDK_NOTE (COLORMAP,
-                   (k > 0 ?
-                    g_print (" %p pal=%p: realized %d colors\n"
-                             "update_colors:",
-                             impl->handle, cmapp->hpal, k) :
-                    (void) 0,
-                    g_print (" %p", impl->handle)));
-         GDI_CALL (UpdateColors, (hdc));
-         SelectPalette (hdc, holdpal, TRUE);
-         RealizePalette (hdc);
-       }
-      GDI_CALL (ReleaseDC, (impl->handle, hdc));
-    }
-  GDK_NOTE (COLORMAP, (top ? g_print ("\n") : (void) 0));
-}
-
-static void
-translate_mouse_coords (GdkWindow *window1,
-                       GdkWindow *window2,
-                       MSG       *msg)
-{
-  POINT pt;
-
-  pt.x = GET_X_LPARAM (msg->lParam);
-  pt.y = GET_Y_LPARAM (msg->lParam);
-  ClientToScreen (GDK_WINDOW_HWND (window1), &pt);
-  ScreenToClient (GDK_WINDOW_HWND (window2), &pt);
-  msg->lParam = MAKELPARAM (pt.x, pt.y);
-}
-
 /* The check_extended flag controls whether to check if the windows want
  * events from extended input devices and if the message should be skipped
  * because an extended input device is active
@@ -1295,7 +1186,7 @@ propagate (GdkWindow  **window,
        * device is used
        */
       if (check_extended &&
-         ((GdkWindowObject *) grab_window)->extension_events != 0 &&
+         grab_window->extension_events != 0 &&
          _gdk_input_ignore_core)
        {
          GDK_NOTE (EVENTS, g_print (" (ignored for grabber)"));
@@ -1320,13 +1211,13 @@ propagate (GdkWindow  **window,
   while (TRUE)
     {
       if (check_extended &&
-         ((GdkWindowObject *) *window)->extension_events != 0 &&
+         (*window)->extension_events != 0 &&
          _gdk_input_ignore_core)
        {
          GDK_NOTE (EVENTS, g_print (" (ignored)"));
          return FALSE;
        }
-      if ((*doesnt_want_it) (((GdkWindowObject *) *window)->event_mask, msg))
+      if ((*doesnt_want_it) ((*window)->event_mask, msg))
        {
          /* Owner doesn't want it, propagate to parent. */
          GdkWindow *parent = gdk_window_get_parent (*window);
@@ -1338,7 +1229,7 @@ propagate (GdkWindow  **window,
                  /* Event source is grabbed with owner_events TRUE */
 
                  if (check_extended &&
-                     ((GdkWindowObject *) grab_window)->extension_events != 0 &&
+                     grab_window->extension_events != 0 &&
                      _gdk_input_ignore_core)
                    {
                      GDK_NOTE (EVENTS, g_print (" (ignored for grabber)"));
@@ -1392,50 +1283,12 @@ doesnt_want_char (gint mask,
   return !(mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK));
 }
 
-static gboolean
-doesnt_want_button_press (gint mask,
-                         MSG *msg)
-{
-  return !(mask & GDK_BUTTON_PRESS_MASK);
-}
-
-static gboolean
-doesnt_want_button_release (gint mask,
-                           MSG *msg)
-{
-  return !(mask & GDK_BUTTON_RELEASE_MASK);
-}
-
-static gboolean
-doesnt_want_button_motion (gint mask,
-                          MSG *msg)
-{
-  return !((mask & GDK_POINTER_MOTION_MASK) ||
-          ((msg->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) && (mask & GDK_BUTTON_MOTION_MASK)) ||
-          ((msg->wParam & MK_LBUTTON) && (mask & GDK_BUTTON1_MOTION_MASK)) ||
-          ((msg->wParam & MK_MBUTTON) && (mask & GDK_BUTTON2_MOTION_MASK)) ||
-          ((msg->wParam & MK_RBUTTON) && (mask & GDK_BUTTON3_MOTION_MASK)));
-}
-
-static gboolean
-doesnt_want_scroll (gint mask,
-                   MSG *msg)
-{
-  /* As there are no separate scroll events in X11, button press
-   * events are used, so higher level code might be selecting for
-   * either GDK_BUTTON_PRESS_MASK or GDK_SCROLL_MASK when it wants GDK
-   * scroll events. Make sure this works in the Win32 backend, too.
-   */
-  return !(mask & (GDK_SCROLL_MASK|GDK_BUTTON_PRESS_MASK));
-}
-
 static void
 handle_configure_event (MSG       *msg,
                        GdkWindow *window)
 {
   RECT client_rect;
   POINT point;
-  GdkWindowObject *window_object;
 
   GetClientRect (msg->hwnd, &client_rect);
   point.x = client_rect.left; /* always 0 */
@@ -1449,17 +1302,15 @@ handle_configure_event (MSG       *msg,
       point.y += _gdk_offset_y;
     }
 
-  window_object = GDK_WINDOW_OBJECT (window);
-
-  window_object->width = client_rect.right - client_rect.left;
-  window_object->height = client_rect.bottom - client_rect.top;
+  window->width = client_rect.right - client_rect.left;
+  window->height = client_rect.bottom - client_rect.top;
   
-  window_object->x = point.x;
-  window_object->y = point.y;
+  window->x = point.x;
+  window->y = point.y;
 
   _gdk_window_update_size (window);
   
-  if (window_object->event_mask & GDK_STRUCTURE_MASK)
+  if (window->event_mask & GDK_STRUCTURE_MASK)
     {
       GdkEvent *event = gdk_event_new (GDK_CONFIGURE);
 
@@ -1475,12 +1326,12 @@ handle_configure_event (MSG       *msg,
     }
 }
 
-GdkRegion *
+cairo_region_t *
 _gdk_win32_hrgn_to_region (HRGN hrgn)
 {
   RGNDATA *rgndata;
   RECT *rects;
-  GdkRegion *result;
+  cairo_region_t *result;
   gint nbytes;
   guint i;
 
@@ -1499,7 +1350,7 @@ _gdk_win32_hrgn_to_region (HRGN hrgn)
       return NULL;
     }
 
-  result = gdk_region_new ();
+  result = cairo_region_create ();
   rects = (RECT *) rgndata->Buffer;
   for (i = 0; i < rgndata->rdh.nCount; i++)
     {
@@ -1510,7 +1361,7 @@ _gdk_win32_hrgn_to_region (HRGN hrgn)
       r.width = rects[i].right - r.x;
       r.height = rects[i].bottom - r.y;
 
-      gdk_region_union_with_rect (result, &r);
+      cairo_region_union_rectangle (result, &r);
     }
 
   g_free (rgndata);
@@ -1538,7 +1389,7 @@ handle_wm_paint (MSG        *msg,
   HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
   HDC hdc;
   PAINTSTRUCT paintstruct;
-  GdkRegion *update_region;
+  cairo_region_t *update_region;
 
   if (GetUpdateRgn (msg->hwnd, hrgn, FALSE) == ERROR)
     {
@@ -1598,29 +1449,51 @@ handle_wm_paint (MSG        *msg,
     }
 
   update_region = _gdk_win32_hrgn_to_region (hrgn);
-  if (!gdk_region_empty (update_region))
+  if (!cairo_region_is_empty (update_region))
     _gdk_window_invalidate_for_expose (window, update_region);
-  gdk_region_destroy (update_region);
+  cairo_region_destroy (update_region);
 
   DeleteObject (hrgn);
 }
 
-static void
-handle_stuff_while_moving_or_resizing (void)
+static VOID CALLBACK 
+modal_timer_proc (HWND     hwnd,
+                 UINT     msg,
+                 UINT_PTR id,
+                 DWORD    time)
 {
   int arbitrary_limit = 1;
-  while (g_main_context_pending (NULL) && arbitrary_limit--)
+
+  while (_modal_operation_in_progress &&
+        g_main_context_pending (NULL) &&
+        arbitrary_limit--)
     g_main_context_iteration (NULL, FALSE);
 }
 
-static VOID CALLBACK
-modal_timer_proc (HWND     hwnd,
-                 UINT     msg,
-                 UINT_PTR id,
-                 DWORD    time)
+void
+_gdk_win32_begin_modal_call (void)
 {
-  if (_sizemove_in_progress)
-    handle_stuff_while_moving_or_resizing ();
+  g_assert (!_modal_operation_in_progress);
+
+  _modal_operation_in_progress = TRUE;
+
+  modal_timer = SetTimer (NULL, 0, 10, modal_timer_proc);
+  if (modal_timer == 0)
+    WIN32_API_FAILED ("SetTimer");
+}
+
+void
+_gdk_win32_end_modal_call (void)
+{
+  g_assert (_modal_operation_in_progress);
+
+  _modal_operation_in_progress = FALSE;
+
+  if (modal_timer != 0)
+    {
+      API_CALL (KillTimer, (NULL, modal_timer));
+      modal_timer = 0;
+   }
 }
 
 static VOID CALLBACK
@@ -1649,10 +1522,10 @@ handle_display_change (void)
 }
 
 static void
-generate_button_event (GdkEventType type,
-                      gint         button,
-                      GdkWindow   *window,
-                      MSG         *msg)
+generate_button_event (GdkEventType      type,
+                       gint              button,
+                       GdkWindow        *window,
+                       MSG              *msg)
 {
   GdkEvent *event = gdk_event_new (type);
 
@@ -1665,7 +1538,7 @@ generate_button_event (GdkEventType type,
   event->button.axes = NULL;
   event->button.state = build_pointer_event_state (msg);
   event->button.button = button;
-  event->button.device = _gdk_display->core_pointer;
+  gdk_event_set_device (event, _gdk_display->core_pointer);
 
   append_event (event);
 }
@@ -1685,7 +1558,7 @@ ensure_stacking_on_unminimize (MSG *msg)
       if (rover_gdkw)
        {
          GdkWindowImplWin32 *rover_impl =
-           (GdkWindowImplWin32 *)((GdkWindowObject *)rover_gdkw)->impl;
+           GDK_WINDOW_IMPL_WIN32 (rover_gdkw->impl);
 
          if (GDK_WINDOW_IS_MAPPED (rover_gdkw) &&
              (rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY ||
@@ -1708,7 +1581,7 @@ static gboolean
 ensure_stacking_on_window_pos_changing (MSG       *msg,
                                        GdkWindow *window)
 {
-  GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)((GdkWindowObject *) window)->impl;
+  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
   WINDOWPOS *windowpos = (WINDOWPOS *) msg->lParam;
 
   if (GetActiveWindow () == msg->hwnd &&
@@ -1736,7 +1609,7 @@ ensure_stacking_on_window_pos_changing (MSG       *msg,
          if (rover_gdkw)
            {
              GdkWindowImplWin32 *rover_impl =
-               (GdkWindowImplWin32 *)((GdkWindowObject *)rover_gdkw)->impl;
+               GDK_WINDOW_IMPL_WIN32 (rover_gdkw->impl);
 
              if (GDK_WINDOW_IS_MAPPED (rover_gdkw) &&
                  (rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY ||
@@ -1763,7 +1636,7 @@ static void
 ensure_stacking_on_activate_app (MSG       *msg,
                                 GdkWindow *window)
 {
-  GdkWindowImplWin32 *impl = (GdkWindowImplWin32 *)((GdkWindowObject *) window)->impl;
+  GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
   if (impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY ||
       impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG ||
@@ -1793,7 +1666,7 @@ ensure_stacking_on_activate_app (MSG       *msg,
          if (rover_gdkw)
            {
              GdkWindowImplWin32 *rover_impl =
-               (GdkWindowImplWin32 *)((GdkWindowObject *)rover_gdkw)->impl;
+               GDK_WINDOW_IMPL_WIN32 (rover_gdkw->impl);
 
              if (GDK_WINDOW_IS_MAPPED (rover_gdkw) &&
                  (rover_impl->type_hint == GDK_WINDOW_TYPE_HINT_UTILITY ||
@@ -1833,12 +1706,12 @@ gdk_event_translate (MSG  *msg,
 
   GdkWindow *orig_window, *new_window, *toplevel;
 
-  GdkPointerGrabInfo *grab = NULL;
+  GdkDeviceManager *device_manager;
+
+  GdkDeviceGrabInfo *keyboard_grab = NULL;
+  GdkDeviceGrabInfo *pointer_grab = NULL;
   GdkWindow *grab_window = NULL;
-  guint grab_mask = 0;
-  gboolean grab_owner_events = FALSE;
 
-  static gint update_colors_counter = 0;
   gint button;
   GdkAtom target;
 
@@ -1851,7 +1724,7 @@ gdk_event_translate (MSG  *msg,
     {
       /* Apply global filters */
 
-      GdkFilterReturn result = apply_event_filters (NULL, msg, _gdk_default_filters);
+      GdkFilterReturn result = apply_event_filters (NULL, msg, &_gdk_default_filters);
       
       /* If result is GDK_FILTER_CONTINUE, we continue as if nothing
        * happened. If it is GDK_FILTER_REMOVE or GDK_FILTER_TRANSLATE,
@@ -1861,7 +1734,7 @@ gdk_event_translate (MSG  *msg,
        return TRUE;
     }
 
-  window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd);
+  window = gdk_win32_handle_table_lookup (msg->hwnd);
   orig_window = window;
 
   if (window == NULL)
@@ -1896,7 +1769,14 @@ gdk_event_translate (MSG  *msg,
        }
       return FALSE;
     }
-  
+
+  device_manager = gdk_display_get_device_manager (_gdk_display);
+
+  keyboard_grab = _gdk_display_get_last_device_grab (_gdk_display,
+                                                     GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard);
+  pointer_grab = _gdk_display_get_last_device_grab (_gdk_display,
+                                                    GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_pointer);
+
   g_object_ref (window);
 
   /* window's refcount has now been increased, so code below should
@@ -1906,11 +1786,11 @@ gdk_event_translate (MSG  *msg,
    */
 #define return GOTO_DONE_INSTEAD
   
-  if (!GDK_WINDOW_DESTROYED (window) && ((GdkWindowObject *) window)->filters)
+  if (!GDK_WINDOW_DESTROYED (window) && window->filters)
     {
       /* Apply per-window filters */
 
-      GdkFilterReturn result = apply_event_filters (window, msg, ((GdkWindowObject *) window)->filters);
+      GdkFilterReturn result = apply_event_filters (window, msg, &window->filters);
 
       if (result == GDK_FILTER_REMOVE || result == GDK_FILTER_TRANSLATE)
        {
@@ -1961,21 +1841,13 @@ gdk_event_translate (MSG  *msg,
 
        case GDK_FILTER_TRANSLATE:
          ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
-         GDK_NOTE (EVENTS, print_event (event));
+         GDK_NOTE (EVENTS, _gdk_win32_print_event (event));
          return_val = TRUE;
          goto done;
 
        case GDK_FILTER_CONTINUE:
-         /* Send unknown client messages on to Gtk for it to use */
-
-         event->client.type = GDK_CLIENT_EVENT;
-         event->client.window = window;
-         event->client.message_type = GDK_POINTER_TO_ATOM (msg->wParam);
-         event->client.data_format = 32;
-         event->client.data.l[0] = msg->lParam;
-         for (i = 1; i < 5; i++)
-           event->client.data.l[i] = 0;
-         GDK_NOTE (EVENTS, print_event (event));
+         /* No more: Send unknown client messages on to Gtk for it to use */
+         GDK_NOTE (EVENTS, _gdk_win32_print_event (event));
          return_val = TRUE;
          goto done;
        }
@@ -2014,7 +1886,7 @@ gdk_event_translate (MSG  *msg,
       /* Let the system handle Alt-Tab, Alt-Space and Alt-F4 unless
        * the keyboard is grabbed.
        */
-      if (_gdk_display->keyboard_grab.window == NULL &&
+      if (!keyboard_grab &&
          (msg->wParam == VK_TAB ||
           msg->wParam == VK_SPACE ||
           msg->wParam == VK_F4))
@@ -2038,9 +1910,10 @@ gdk_event_translate (MSG  *msg,
          in_ime_composition)
        break;
 
-      if (!propagate (&window, msg,
-                     _gdk_display->keyboard_grab.window,
-                     _gdk_display->keyboard_grab.owner_events,
+      if (keyboard_grab &&
+          !propagate (&window, msg,
+                     keyboard_grab->window,
+                     keyboard_grab->owner_events,
                      GDK_ALL_EVENTS_MASK,
                      doesnt_want_key, FALSE))
        break;
@@ -2053,10 +1926,11 @@ gdk_event_translate (MSG  *msg,
                             GDK_KEY_PRESS : GDK_KEY_RELEASE);
       event->key.window = window;
       event->key.time = _gdk_win32_get_next_tick (msg->time);
-      event->key.keyval = GDK_VoidSymbol;
+      event->key.keyval = GDK_KEY_VoidSymbol;
       event->key.string = NULL;
       event->key.length = 0;
       event->key.hardware_keycode = msg->wParam;
+      gdk_event_set_device (event, GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard);
       if (HIWORD (msg->lParam) & KF_EXTENDED)
        {
          switch (msg->wParam)
@@ -2084,12 +1958,16 @@ gdk_event_translate (MSG  *msg,
       
       build_key_event_state (event, key_state);
 
-      gdk_keymap_translate_keyboard_state (NULL,
-                                          event->key.hardware_keycode,
-                                          event->key.state,
-                                          event->key.group,
-                                          &event->key.keyval,
-                                          NULL, NULL, NULL);
+      if (msg->wParam == VK_PACKET &&
+         ToUnicode (VK_PACKET, HIWORD (msg->lParam), key_state, wbuf, 1, 0) == 1)
+       event->key.keyval = gdk_unicode_to_keyval (wbuf[0]);
+      else
+       gdk_keymap_translate_keyboard_state (_gdk_win32_display_get_keymap (_gdk_display),
+                                            event->key.hardware_keycode,
+                                            event->key.state,
+                                            event->key.group,
+                                            &event->key.keyval,
+                                            NULL, NULL, NULL);
 
       fill_key_event_string (event);
 
@@ -2142,9 +2020,10 @@ gdk_event_translate (MSG  *msg,
       if (!(msg->lParam & GCS_RESULTSTR))
        break;
 
-      if (!propagate (&window, msg,
-                     _gdk_display->keyboard_grab.window,
-                     _gdk_display->keyboard_grab.owner_events,
+      if (keyboard_grab &&
+          !propagate (&window, msg,
+                     keyboard_grab->window,
+                     keyboard_grab->owner_events,
                      GDK_ALL_EVENTS_MASK,
                      doesnt_want_char, FALSE))
        break;
@@ -2163,21 +2042,23 @@ gdk_event_translate (MSG  *msg,
 
       for (i = 0; i < ccount; i++)
        {
-         if (((GdkWindowObject *) window)->event_mask & GDK_KEY_PRESS_MASK)
+         if (window->event_mask & GDK_KEY_PRESS_MASK)
            {
              /* Build a key press event */
              event = gdk_event_new (GDK_KEY_PRESS);
              event->key.window = window;
+        gdk_event_set_device (event, GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard);
              build_wm_ime_composition_event (event, msg, wbuf[i], key_state);
 
              append_event (event);
            }
          
-         if (((GdkWindowObject *) window)->event_mask & GDK_KEY_RELEASE_MASK)
+         if (window->event_mask & GDK_KEY_RELEASE_MASK)
            {
              /* Build a key release event.  */
              event = gdk_event_new (GDK_KEY_RELEASE);
              event->key.window = window;
+        gdk_event_set_device (event, GDK_DEVICE_MANAGER_WIN32 (device_manager)->core_keyboard);
              build_wm_ime_composition_event (event, msg, wbuf[i], key_state);
 
              append_event (event);
@@ -2209,9 +2090,12 @@ gdk_event_translate (MSG  *msg,
                g_print (" (%d,%d)",
                         GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
 
+      assign_object (&window, find_window_for_mouse_event (window, msg));
+      /* TODO_CSW?: there used to some synthesize and propagate */
       if (GDK_WINDOW_DESTROYED (window))
        break;
 
+      /* TODO_CSW? Emulate X11's automatic active grab */
       generate_button_event (GDK_BUTTON_PRESS, button,
                             window, msg);
 
@@ -2241,8 +2125,9 @@ gdk_event_translate (MSG  *msg,
                g_print (" (%d,%d)",
                         GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
 
+      assign_object (&window, find_window_for_mouse_event (window, msg));
 #if 0
-      if (((GdkWindowObject *) window)->extension_events != 0 &&
+      if (window->extension_events != 0 &&
          _gdk_input_ignore_core)
        {
          GDK_NOTE (EVENTS, g_print (" (ignored)"));
@@ -2262,18 +2147,22 @@ gdk_event_translate (MSG  *msg,
                         (gpointer) msg->wParam,
                         GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
 
+      assign_object (&window, find_window_for_mouse_event (window, msg));
       toplevel = gdk_window_get_toplevel (window);
       if (current_toplevel != toplevel)
        {
+         GDK_NOTE (EVENTS, g_print (" toplevel %p -> %p", 
+             current_toplevel ? GDK_WINDOW_HWND (current_toplevel) : NULL, 
+             toplevel ? GDK_WINDOW_HWND (toplevel) : NULL));
          if (current_toplevel)
-           synthesize_enter_or_leave_event (current_toplevel, msg, 
-                                            GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR);
-         synthesize_enter_or_leave_event (toplevel, msg, 
-                                          GDK_ENTER_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR);
+           synthesize_enter_or_leave_event (current_toplevel, msg,
+                                       GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR);
+         synthesize_enter_or_leave_event (toplevel, msg,
+                                     GDK_ENTER_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR);
          assign_object (&current_toplevel, toplevel);
          track_mouse_event (TME_LEAVE, GDK_WINDOW_HWND (toplevel));
        }
-      
+
       /* If we haven't moved, don't create any GDK event. Windows
        * sends WM_MOUSEMOVE messages after a new window is shows under
        * the mouse, even if the mouse hasn't moved. This disturbs gtk.
@@ -2295,7 +2184,7 @@ gdk_event_translate (MSG  *msg,
       event->motion.axes = NULL;
       event->motion.state = build_pointer_event_state (msg);
       event->motion.is_hint = FALSE;
-      event->motion.device = _gdk_display->core_pointer;
+      gdk_event_set_device (event, _gdk_display->core_pointer);
 
       append_event (event);
 
@@ -2306,19 +2195,26 @@ gdk_event_translate (MSG  *msg,
       GDK_NOTE (EVENTS,
                g_print (" (%d,%d)",
                         GET_X_LPARAM (msg->lParam), GET_Y_LPARAM (msg->lParam)));
-
+#if 0 /* TODO_CSW? */
+      if (current_toplevel != NULL &&
+         (current_toplevel->event_mask & GDK_LEAVE_NOTIFY_MASK))
+       {
+         synthesize_enter_or_leave_event (current_toplevel, msg,
+                                          GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR);
+       }
+#endif
       break;
 
     case WM_MOUSELEAVE:
       GDK_NOTE (EVENTS, g_print (" %d (%ld,%ld)",
                                 HIWORD (msg->wParam), msg->pt.x, msg->pt.y));
 
-      if (!gdk_win32_handle_table_lookup ((GdkNativeWindow) WindowFromPoint (msg->pt)))
+      if (!gdk_win32_handle_table_lookup (WindowFromPoint (msg->pt)))
        {
          /* we are only interested if we don't know the new window */
          if (current_toplevel)
-           synthesize_enter_or_leave_event (current_toplevel, msg, 
-                                            GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR);
+           synthesize_enter_or_leave_event (current_toplevel, msg,
+                                       GDK_LEAVE_NOTIFY, GDK_CROSSING_NORMAL, GDK_NOTIFY_ANCESTOR);
          assign_object (&current_toplevel, NULL);
        }
       else
@@ -2344,7 +2240,7 @@ gdk_event_translate (MSG  *msg,
        break;
 
       msg->hwnd = hwnd;
-      if ((new_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) msg->hwnd)) == NULL)
+      if ((new_window = gdk_win32_handle_table_lookup (msg->hwnd)) == NULL)
        break;
 
       if (new_window != window)
@@ -2364,7 +2260,7 @@ gdk_event_translate (MSG  *msg,
       event->scroll.x_root = (gint16) GET_X_LPARAM (msg->lParam) + _gdk_offset_x;
       event->scroll.y_root = (gint16) GET_Y_LPARAM (msg->lParam) + _gdk_offset_y;
       event->scroll.state = build_pointer_event_state (msg);
-      event->scroll.device = _gdk_display->core_pointer;
+      gdk_event_set_device (event, _gdk_display->core_pointer);
 
       append_event (event);
       
@@ -2409,41 +2305,12 @@ gdk_event_translate (MSG  *msg,
                 (g_print (" %d", HIWORD (msg->wParam)), 0) : 0));
       break;
 
-    case WM_QUERYNEWPALETTE:
-      if (gdk_visual_get_system ()->type == GDK_VISUAL_PSEUDO_COLOR)
-       {
-         synthesize_expose_events (window);
-         update_colors_counter = 0;
-       }
-      return_val = TRUE;
-      break;
-
-    case WM_PALETTECHANGED:
-      GDK_NOTE (EVENTS_OR_COLORMAP, g_print (" %p", (HWND) msg->wParam));
-      if (gdk_visual_get_system ()->type != GDK_VISUAL_PSEUDO_COLOR)
-       break;
-
-      return_val = TRUE;
-
-      if (msg->hwnd == (HWND) msg->wParam)
-       break;
-
-      if (++update_colors_counter == 5)
-       {
-         synthesize_expose_events (window);
-         update_colors_counter = 0;
-         break;
-       }
-      
-      update_colors (window, TRUE);
-      break;
-
      case WM_MOUSEACTIVATE:
        {
         GdkWindow *tmp;
 
         if (gdk_window_get_window_type (window) == GDK_WINDOW_TEMP 
-            || !((GdkWindowObject *)window)->accept_focus)
+            || !window->accept_focus)
           {
             *ret_valp = MA_NOACTIVATE;
             return_val = TRUE;
@@ -2464,25 +2331,25 @@ gdk_event_translate (MSG  *msg,
        break;
 
     case WM_KILLFOCUS:
-      if (_gdk_display->keyboard_grab.window != NULL &&
-         !GDK_WINDOW_DESTROYED (_gdk_display->keyboard_grab.window))
+      if (keyboard_grab != NULL &&
+         !GDK_WINDOW_DESTROYED (keyboard_grab->window))
        {
-         generate_grab_broken_event (_gdk_display->keyboard_grab.window, FALSE, NULL);
+         generate_grab_broken_event (device_manager, keyboard_grab->window, TRUE, NULL);
        }
 
       /* fallthrough */
     case WM_SETFOCUS:
-      if (_gdk_display->keyboard_grab.window != NULL &&
-         !_gdk_display->keyboard_grab.owner_events)
+      if (keyboard_grab != NULL &&
+         !keyboard_grab->owner_events)
        break;
 
-      if (!(((GdkWindowObject *) window)->event_mask & GDK_FOCUS_CHANGE_MASK))
+      if (!(window->event_mask & GDK_FOCUS_CHANGE_MASK))
        break;
 
       if (GDK_WINDOW_DESTROYED (window))
        break;
 
-      generate_focus_event (window, (msg->message == WM_SETFOCUS));
+      generate_focus_event (device_manager, window, (msg->message == WM_SETFOCUS));
       return_val = TRUE;
       break;
 
@@ -2510,12 +2377,8 @@ gdk_event_translate (MSG  *msg,
       GDK_NOTE (EVENTS, g_print (" %#x %#x",
                                 LOWORD (msg->lParam), HIWORD (msg->lParam)));
 
-#ifdef TODO_CSW
-      grab = _gdk_display_get_last_pointer_grab (_gdk_display);
-      if (grab != NULL)
-       {
-         grab_window = grab->window;
-       }
+      if (pointer_grab != NULL)
+        grab_window = pointer_grab->window;
 
       if (grab_window == NULL && LOWORD (msg->lParam) != HTCLIENT)
        break;
@@ -2523,7 +2386,7 @@ gdk_event_translate (MSG  *msg,
       if (grab_window != NULL && p_grab_cursor != NULL)
        hcursor = p_grab_cursor;
       else if (!GDK_WINDOW_DESTROYED (window))
-       hcursor = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl)->hcursor;
+       hcursor = GDK_WINDOW_IMPL_WIN32 (window->impl)->hcursor;
       else
        hcursor = NULL;
 
@@ -2534,8 +2397,6 @@ gdk_event_translate (MSG  *msg,
          return_val = TRUE;
          *ret_valp = TRUE;
        }
-#endif
-      
       break;
 
     case WM_SHOWWINDOW:
@@ -2548,7 +2409,7 @@ gdk_event_translate (MSG  *msg,
                                     (msg->lParam == SW_PARENTOPENING ? "PARENTOPENING" :
                                      "???")))))));
 
-      if (!(((GdkWindowObject *) window)->event_mask & GDK_STRUCTURE_MASK))
+      if (!(window->event_mask & GDK_STRUCTURE_MASK))
        break;
 
       if (msg->lParam == SW_OTHERUNZOOM ||
@@ -2565,21 +2426,21 @@ gdk_event_translate (MSG  *msg,
 
       if (event->any.type == GDK_UNMAP)
        {
-         impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+         impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
          if (impl->transient_owner && GetForegroundWindow () == GDK_WINDOW_HWND (window))
            {
              SetForegroundWindow (GDK_WINDOW_HWND (impl->transient_owner));
            }
 
-         grab = _gdk_display_get_last_pointer_grab (_gdk_display);
-         if (grab != NULL)
+         if (pointer_grab != NULL)
            {
-             if (grab->window == window)
+             if (pointer_grab->window == window)
                gdk_pointer_ungrab (msg->time);
            }
 
-         if (_gdk_display->keyboard_grab.window == window)
+         if (keyboard_grab &&
+        keyboard_grab->window == window)
            gdk_keyboard_ungrab (msg->time);
        }
 
@@ -2610,13 +2471,13 @@ gdk_event_translate (MSG  *msg,
       if (msg->wParam == SIZE_MINIMIZED)
        {
          /* Don't generate any GDK event. This is *not* an UNMAP. */
-         grab = _gdk_display_get_last_pointer_grab (_gdk_display);
-         if (grab != NULL)
+         if (pointer_grab != NULL)
            {
-             if (grab->window == window)
+             if (pointer_grab->window == window)
                gdk_pointer_ungrab (msg->time);
            }
-         if (_gdk_display->keyboard_grab.window == window)
+         if (keyboard_grab &&
+        keyboard_grab->window == window)
            gdk_keyboard_ungrab (msg->time);
 
          gdk_synthesize_window_state (window,
@@ -2631,7 +2492,7 @@ gdk_event_translate (MSG  *msg,
          GdkWindowState withdrawn_bit =
            IsWindowVisible (msg->hwnd) ? GDK_WINDOW_STATE_WITHDRAWN : 0;
 
-         if (((GdkWindowObject *) window)->state & GDK_WINDOW_STATE_ICONIFIED)
+         if (window->state & GDK_WINDOW_STATE_ICONIFIED)
            ensure_stacking_on_unminimize (msg);
 
          if (!GDK_WINDOW_DESTROYED (window))
@@ -2658,34 +2519,24 @@ gdk_event_translate (MSG  *msg,
                                           GDK_WINDOW_STATE_MAXIMIZED);
            }
 
-         if (((GdkWindowObject *) window)->resize_count > 1)
-           ((GdkWindowObject *) window)->resize_count -= 1;
+         if (window->resize_count > 1)
+           window->resize_count -= 1;
          
-         if (((GdkWindowObject *) window)->extension_events != 0)
-           _gdk_input_configure_event (window);
+         if (window->extension_events != 0)
+      _gdk_device_wintab_update_window_coords (window);
 
          return_val = TRUE;
        }
       break;
 
     case WM_ENTERSIZEMOVE:
-      _sizemove_in_progress = TRUE;
-      modal_timer = SetTimer (NULL, 0, 20, modal_timer_proc);
-      break;
-
-    case WM_EXITSIZEMOVE:
-      _sizemove_in_progress = FALSE;
-      KillTimer (NULL, modal_timer);
-      break;
-
     case WM_ENTERMENULOOP:
-      _sizemove_in_progress = TRUE;
-      modal_timer = SetTimer (NULL, 0, 20, modal_timer_proc);
+      _gdk_win32_begin_modal_call ();
       break;
 
+    case WM_EXITSIZEMOVE:
     case WM_EXITMENULOOP:
-      _sizemove_in_progress = FALSE;
-      KillTimer (NULL, modal_timer);
+      _gdk_win32_end_modal_call ();
       break;
 
     case WM_WINDOWPOSCHANGING:
@@ -2718,7 +2569,7 @@ gdk_event_translate (MSG  *msg,
                                 windowpos->cx, windowpos->cy, windowpos->x, windowpos->y));
 
       /* If position and size haven't changed, don't do anything */
-      if (_sizemove_in_progress &&
+      if (_modal_operation_in_progress &&
          (windowpos->flags & SWP_NOMOVE) &&
          (windowpos->flags & SWP_NOSIZE))
        break;
@@ -2726,22 +2577,22 @@ gdk_event_translate (MSG  *msg,
       /* Once we've entered the moving or sizing modal loop, we won't
        * return to the main loop until we're done sizing or moving.
        */
-      if (_sizemove_in_progress &&
+      if (_modal_operation_in_progress &&
         GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
         !GDK_WINDOW_DESTROYED (window))
        {
-         if (((GdkWindowObject *) window)->event_mask & GDK_STRUCTURE_MASK)
+         if (window->event_mask & GDK_STRUCTURE_MASK)
            {
              GDK_NOTE (EVENTS, g_print (" do magic"));
-             if (((GdkWindowObject *) window)->resize_count > 1)
-               ((GdkWindowObject *) window)->resize_count -= 1;
-             
+             if (window->resize_count > 1)
+               window->resize_count -= 1;
+
              handle_configure_event (msg, window);
              g_main_context_iteration (NULL, FALSE);
-
+#if 0
              /* Dispatch main loop - to realize resizes... */
-             handle_stuff_while_moving_or_resizing ();
-             
+             modal_timer_proc (msg->hwnd, msg->message, 0, msg->time);
+#endif
              /* Claim as handled, so that WM_SIZE and WM_MOVE are avoided */
              return_val = TRUE;
              *ret_valp = 1;
@@ -2766,7 +2617,7 @@ gdk_event_translate (MSG  *msg,
                                 _gdk_win32_rect_to_string (&rect),
                                 _gdk_win32_rect_to_string (drag)));
 
-      impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl);
+      impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
       orig_drag = *drag;
       if (impl->hint_flags & GDK_HINT_RESIZE_INC)
        {
@@ -2969,7 +2820,7 @@ gdk_event_translate (MSG  *msg,
       if (GDK_WINDOW_DESTROYED (window))
        break;
 
-      impl = GDK_WINDOW_IMPL_WIN32 (((GdkWindowObject *) window)->impl);
+      impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
       mmi = (MINMAXINFO*) msg->lParam;
       GDK_NOTE (EVENTS, g_print (" (mintrack:%ldx%ld maxtrack:%ldx%ld "
                                 "maxpos:%+ld%+ld maxsize:%ldx%ld)",
@@ -3043,7 +2894,7 @@ gdk_event_translate (MSG  *msg,
 
       append_event (event);
 
-      impl = GDK_WINDOW_IMPL_WIN32 (GDK_WINDOW_OBJECT (window)->impl);
+      impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
 
       if (impl->transient_owner && GetForegroundWindow() == GDK_WINDOW_HWND (window))
        {
@@ -3054,14 +2905,14 @@ gdk_event_translate (MSG  *msg,
       break;
 
     case WM_DESTROY:
-      grab = _gdk_display_get_last_pointer_grab (_gdk_display);
-      if (grab != NULL)
+      if (pointer_grab != NULL)
        {
-         if (grab->window == window)
+         if (pointer_grab->window == window)
            gdk_pointer_ungrab (msg->time);
        }
 
-      if (_gdk_display->keyboard_grab.window == window)
+      if (keyboard_grab &&
+          keyboard_grab->window == window)
        gdk_keyboard_ungrab (msg->time);
 
       if ((window != NULL) && (msg->hwnd != GetDesktopWindow ()))
@@ -3111,54 +2962,51 @@ gdk_event_translate (MSG  *msg,
       /* We need to render to clipboard immediately, don't call
        * append_event()
        */
-      if (_gdk_event_func)
-       {
-         event = gdk_event_new (GDK_SELECTION_REQUEST);
-         event->selection.window = window;
-         event->selection.send_event = FALSE;
-         event->selection.selection = GDK_SELECTION_CLIPBOARD;
-         event->selection.target = target;
-         event->selection.property = _gdk_selection;
-         event->selection.requestor = msg->hwnd;
-         event->selection.time = msg->time;
-
-         fixup_event (event);
-         GDK_NOTE (EVENTS, g_print (" (calling gdk_event_func)"));
-         GDK_NOTE (EVENTS, print_event (event));
-         (*_gdk_event_func) (event, _gdk_event_data);
-         gdk_event_free (event);
+      event = gdk_event_new (GDK_SELECTION_REQUEST);
+      event->selection.window = window;
+      event->selection.send_event = FALSE;
+      event->selection.selection = GDK_SELECTION_CLIPBOARD;
+      event->selection.target = target;
+      event->selection.property = _gdk_selection;
+      event->selection.requestor = gdk_win32_handle_table_lookup (msg->hwnd);
+      event->selection.time = msg->time;
 
-         /* Now the clipboard owner should have rendered */
-         if (!_delayed_rendering_data)
-           {
-             GDK_NOTE (EVENTS, g_print (" (no _delayed_rendering_data?)"));
-           }
-         else
-           {
-             if (msg->wParam == CF_DIB)
-               {
-                 _delayed_rendering_data =
-                   _gdk_win32_selection_convert_to_dib (_delayed_rendering_data,
-                                                        target);
-                 if (!_delayed_rendering_data)
-                   {
-                     g_warning ("Cannot convert to DIB from delayed rendered image");
-                     break;
-                   }
-               }
-
-             /* The requestor is holding the clipboard, no
-              * OpenClipboard() is required/possible
-              */
-             GDK_NOTE (DND,
-                       g_print (" SetClipboardData(%s,%p)",
-                                _gdk_win32_cf_to_string (msg->wParam),
-                                _delayed_rendering_data));
+      fixup_event (event);
+      GDK_NOTE (EVENTS, g_print (" (calling _gdk_event_emit)"));
+      GDK_NOTE (EVENTS, _gdk_win32_print_event (event));
+      _gdk_event_emit (event);
+      gdk_event_free (event);
 
-             API_CALL (SetClipboardData, (msg->wParam, _delayed_rendering_data));
-             _delayed_rendering_data = NULL;
-           }
-       }
+      /* Now the clipboard owner should have rendered */
+      if (!_delayed_rendering_data)
+        {
+          GDK_NOTE (EVENTS, g_print (" (no _delayed_rendering_data?)"));
+        }
+      else
+        {
+          if (msg->wParam == CF_DIB)
+            {
+              _delayed_rendering_data =
+                _gdk_win32_selection_convert_to_dib (_delayed_rendering_data,
+                                                     target);
+              if (!_delayed_rendering_data)
+                {
+                  g_warning ("Cannot convert to DIB from delayed rendered image");
+                  break;
+                }
+            }
+
+          /* The requestor is holding the clipboard, no
+           * OpenClipboard() is required/possible
+           */
+          GDK_NOTE (DND,
+                    g_print (" SetClipboardData(%s,%p)",
+                             _gdk_win32_cf_to_string (msg->wParam),
+                             _delayed_rendering_data));
+
+          API_CALL (SetClipboardData, (msg->wParam, _delayed_rendering_data));
+          _delayed_rendering_data = NULL;
+        }
       break;
 
     case WM_ACTIVATE:
@@ -3242,7 +3090,7 @@ done:
 }
 
 void
-_gdk_events_queue (GdkDisplay *display)
+_gdk_win32_display_queue_events (GdkDisplay *display)
 {
   MSG msg;
 
@@ -3310,15 +3158,22 @@ gdk_event_dispatch (GSource     *source,
  
   GDK_THREADS_ENTER ();
 
-  _gdk_events_queue (_gdk_display);
+  _gdk_win32_display_queue_events (_gdk_display);
   event = _gdk_event_unqueue (_gdk_display);
 
   if (event)
     {
-      if (_gdk_event_func)
-       (*_gdk_event_func) (event, _gdk_event_data);
+      _gdk_event_emit (event);
       
       gdk_event_free (event);
+
+      /* Do drag & drop if it is still pending */
+      if (_dnd_source_state == GDK_WIN32_DND_PENDING) 
+       {
+         _dnd_source_state = GDK_WIN32_DND_DRAGGING;
+         _gdk_win32_dnd_do_dragdrop ();
+         _dnd_source_state = GDK_WIN32_DND_NONE;
+       }
     }
   
   GDK_THREADS_LEAVE ();
@@ -3339,60 +3194,8 @@ is_modally_blocked (GdkWindow *window)
   return modal_current != NULL ? gdk_window_get_toplevel (window) != modal_current : FALSE;
 }
 
-static void
-check_for_too_much_data (GdkEvent *event)
-{
-  if (event->client.data.l[1] ||
-      event->client.data.l[2] ||
-      event->client.data.l[3] ||
-      event->client.data.l[4])
-    {
-      g_warning ("Only four bytes of data are passed in client messages on Win32\n");
-    }
-}
-
-gboolean
-gdk_event_send_client_message_for_display (GdkDisplay     *display,
-                                           GdkEvent       *event, 
-                                           GdkNativeWindow winid)
-{
-  check_for_too_much_data (event);
-
-  return PostMessageW ((HWND) winid, client_message,
-                      (WPARAM) event->client.message_type,
-                      event->client.data.l[0]);
-}
-
-void
-gdk_screen_broadcast_client_message (GdkScreen *screen, 
-                                    GdkEvent  *event)
-{
-  check_for_too_much_data (event);
-
-  PostMessageW (HWND_BROADCAST, client_message,
-              (WPARAM) event->client.message_type,
-               event->client.data.l[0]);
-}
-
-void
-gdk_flush (void)
-{
-#if 0
-  MSG msg;
-
-  /* Process all messages currently available */
-  while (PeekMessageW (&msg, NULL, 0, 0, PM_REMOVE))
-    {
-      TranslateMessage (&msg);
-      DispatchMessageW (&msg);
-    }
-#endif
-
-  GdiFlush ();
-}
-
 void
-gdk_display_sync (GdkDisplay * display)
+_gdk_win32_display_sync (GdkDisplay * display)
 {
   MSG msg;
 
@@ -3403,27 +3206,3 @@ gdk_display_sync (GdkDisplay * display)
     DispatchMessageW (&msg);
 }
 
-void
-gdk_display_flush (GdkDisplay * display)
-{
-  g_return_if_fail (display == _gdk_display);
-
-  /* Nothing */
-}
-
-gboolean
-gdk_net_wm_supports (GdkAtom property)
-{
-  return FALSE;
-}
-
-void
-_gdk_windowing_event_data_copy (const GdkEvent *src,
-                                GdkEvent       *dst)
-{
-}
-
-void
-_gdk_windowing_event_data_free (GdkEvent *event)
-{
-}