[gtk/wip/otte/win32-cleanup: 3/3] win32: Use GWL_USERDATA instead of a global hash table




commit 061115675787950e800c751e8840a1db6715cb7d
Author: Benjamin Otte <otte redhat com>
Date:   Wed Jul 21 03:44:39 2021 +0200

    win32: Use GWL_USERDATA instead of a global hash table
    
    We can delete a whole source file again!
    
    Also deprecate a bunch of stupid and dangerous APIs that shouldn't have
    made it to 4.0, but who's gonna review the Windows backend, amirite?

 gdk/win32/gdkdevice-win32.c  |   9 +-
 gdk/win32/gdkdevice-wintab.c |   5 +-
 gdk/win32/gdkevents-win32.c  |  30 +++----
 gdk/win32/gdkprivate-win32.h |   4 -
 gdk/win32/gdksurface-win32.c | 192 +++++++++++--------------------------------
 gdk/win32/gdkwin32id.c       |  81 ------------------
 gdk/win32/gdkwin32misc.h     |  14 ++--
 gdk/win32/meson.build        |   1 -
 8 files changed, 71 insertions(+), 265 deletions(-)
---
diff --git a/gdk/win32/gdkdevice-win32.c b/gdk/win32/gdkdevice-win32.c
index 283df3c519..9cfcef1b83 100644
--- a/gdk/win32/gdkdevice-win32.c
+++ b/gdk/win32/gdkdevice-win32.c
@@ -72,6 +72,7 @@ gdk_device_win32_query_state (GdkDevice        *device,
                               double           *win_y,
                               GdkModifierType  *mask)
 {
+  GdkDisplay *display = gdk_device_get_display (device);
   POINT point;
   HWND hwnd, hwndc;
   int scale;
@@ -83,8 +84,6 @@ gdk_device_win32_query_state (GdkDevice        *device,
     }
   else
     {
-      GdkDisplay *display = gdk_device_get_display (device);
-
       scale = GDK_WIN32_DISPLAY (display)->surface_scale;
       hwnd = NULL;
     }
@@ -105,7 +104,7 @@ gdk_device_win32_query_state (GdkDevice        *device,
       hwndc = ChildWindowFromPoint (hwnd, point);
 
       if (hwndc && hwndc != hwnd)
-        *child_window = gdk_win32_handle_table_lookup (hwndc);
+        *child_window = gdk_win32_surface_lookup_for_display (display, hwndc);
       else
         *child_window = NULL; /* Direct child unknown to gdk */
     }
@@ -162,6 +161,7 @@ _gdk_device_win32_surface_at_position (GdkDevice       *device,
                                        double          *win_y,
                                        GdkModifierType *mask)
 {
+  GdkDisplay *display = gdk_device_get_display (device);
   GdkSurface *window = NULL;
   GdkWin32Surface *impl = NULL;
   POINT screen_pt, client_pt;
@@ -183,7 +183,8 @@ _gdk_device_win32_surface_at_position (GdkDevice       *device,
   if (!PtInRect (&rect, client_pt))
     hwnd = NULL;
 
-  window = gdk_win32_handle_table_lookup (hwnd);
+  if (hwnd)
+    window = gdk_win32_surface_lookup_for_display (display, hwnd);
 
   if (window && (win_x || win_y))
     {
diff --git a/gdk/win32/gdkdevice-wintab.c b/gdk/win32/gdkdevice-wintab.c
index 4822eb042e..39dc2ac922 100644
--- a/gdk/win32/gdkdevice-wintab.c
+++ b/gdk/win32/gdkdevice-wintab.c
@@ -69,6 +69,7 @@ gdk_device_wintab_query_state (GdkDevice        *device,
                                double           *win_y,
                                GdkModifierType  *mask)
 {
+  GdkDisplay *display = gdk_device_get_display (device);
   GdkDeviceWintab *device_wintab;
   POINT point;
   HWND hwnd, hwndc;
@@ -82,8 +83,6 @@ gdk_device_wintab_query_state (GdkDevice        *device,
     }
   else
     {
-      GdkDisplay *display = gdk_device_get_display (device);
-
       scale = GDK_WIN32_DISPLAY (display)->surface_scale;
       hwnd = NULL;
     }
@@ -104,7 +103,7 @@ gdk_device_wintab_query_state (GdkDevice        *device,
       hwndc = ChildWindowFromPoint (hwnd, point);
 
       if (hwndc && hwndc != hwnd)
-        *child_window = gdk_win32_handle_table_lookup (hwndc);
+        *child_window = gdk_win32_surface_lookup_for_display (display, hwndc);
       else
         *child_window = NULL; /* Direct child unknown to gdk */
     }
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 23d93df1b0..813b9366d6 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -259,15 +259,7 @@ inner_window_procedure (HWND   hwnd,
         {
           surface = (UNALIGNED GdkSurface *) (((LPCREATESTRUCTW) lparam)->lpCreateParams);
           GDK_SURFACE_HWND (surface) = hwnd;
-         /* Take note: we're inserting a pointer into a heap-allocated
-          * object (impl). Inserting a pointer to a stack variable
-          * will break the logic, since stack variables are short-lived.
-          * We insert a pointer to the handle instead of the handle itsel
-          * probably because we need to hash them differently depending
-          * on the bitness of the OS. That pointer is still unique,
-          * so this works out in the end.
-          */
-         gdk_win32_handle_table_insert (&GDK_SURFACE_HWND (surface), surface);
+          SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) surface);
         }
       else
         {
@@ -407,7 +399,7 @@ low_level_keyboard_proc (int    code,
     if (kbd_focus_owner == NULL)
       break;
 
-    gdk_kbd_focus_owner = gdk_win32_handle_table_lookup (kbd_focus_owner);
+    gdk_kbd_focus_owner = GDK_SURFACE (GetWindowLongPtr (kbd_focus_owner, GWLP_USERDATA));
 
     if (gdk_kbd_focus_owner == NULL)
       break;
@@ -636,7 +628,7 @@ find_window_for_mouse_event (GdkDisplay *display,
          ScreenToClient (hwnd, &client_pt);
          GetClientRect (hwnd, &rect);
          if (PtInRect (&rect, client_pt))
-           event_surface = gdk_win32_handle_table_lookup (hwnd);
+           event_surface = GDK_SURFACE (GetWindowLongPtr (hwnd, GWLP_USERDATA));
        }
       if (event_surface == NULL)
        event_surface = grab->surface;
@@ -1814,7 +1806,7 @@ gdk_event_translate (GdkDisplay *display,
        return TRUE;
     }
 
-  window = gdk_win32_handle_table_lookup (msg->hwnd);
+  window = GDK_SURFACE (GetWindowLongPtr (msg->hwnd, GWLP_USERDATA));
 
   keyboard_grab = _gdk_display_get_last_device_grab (display,
                                                      device_manager_win32->core_keyboard);
@@ -2248,7 +2240,7 @@ gdk_event_translate (GdkDisplay *display,
                  ScreenToClient (hwnd, &client_pt);
                  GetClientRect (hwnd, &rect);
                  if (PtInRect (&rect, client_pt))
-                   new_window = gdk_win32_handle_table_lookup (hwnd);
+                   new_window = GDK_SURFACE (GetWindowLongPtr (hwnd, GWLP_USERDATA));
                }
 
              synthesize_crossing_events (display,
@@ -2301,8 +2293,8 @@ gdk_event_translate (GdkDisplay *display,
 
              ScreenToClient (hwnd, &client_pt);
              GetClientRect (hwnd, &rect);
-             if (PtInRect (&rect, client_pt))
-               new_window = gdk_win32_handle_table_lookup (hwnd);
+              if (PtInRect (&rect, client_pt))
+                new_window = gdk_win32_surface_lookup_for_display (display, hwnd);
            }
 
          if (!pointer_grab->owner_events &&
@@ -2403,8 +2395,8 @@ gdk_event_translate (GdkDisplay *display,
 
          ScreenToClient (hwnd, &client_pt);
          GetClientRect (hwnd, &rect);
-         if (PtInRect (&rect, client_pt))
-           new_window = gdk_win32_handle_table_lookup (hwnd);
+          if (PtInRect (&rect, client_pt))
+            new_window = gdk_win32_surface_lookup_for_display (display, hwnd);
        }
 
       if (!ignore_leave)
@@ -2462,7 +2454,7 @@ gdk_event_translate (GdkDisplay *display,
       }
 
       msg->hwnd = hwnd;
-      if ((new_window = gdk_win32_handle_table_lookup (msg->hwnd)) == NULL)
+      if ((new_window = gdk_win32_surface_lookup_for_display (display, hwnd)) == NULL)
        break;
 
       if (new_window != window)
@@ -3023,7 +3015,7 @@ gdk_event_translate (GdkDisplay *display,
         {
           if (msg->lParam != 0)
             {
-               GdkSurface *other_surface = gdk_win32_handle_table_lookup ((HWND) msg->lParam);
+               GdkSurface *other_surface = gdk_win32_surface_lookup_for_display (display, (HWND) 
msg->lParam);
                if (other_surface != NULL &&
                    (GDK_IS_POPUP (other_surface) || GDK_IS_DRAG_SURFACE (other_surface)))
                 {
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index 1cfafc1149..b7cd40d9e5 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -176,10 +176,6 @@ void _gdk_win32_surface_move_region (GdkSurface       *window,
 void _gdk_win32_selection_init (void);
 void _gdk_win32_dnd_exit (void);
 
-void     gdk_win32_handle_table_insert  (HANDLE   *handle,
-                                         gpointer data);
-void     gdk_win32_handle_table_remove  (HANDLE handle);
-
 HRGN      _gdk_win32_cairo_region_to_hrgn (const cairo_region_t *region,
                                            int                   x_origin,
                                            int                   y_origin);
diff --git a/gdk/win32/gdksurface-win32.c b/gdk/win32/gdksurface-win32.c
index 5b1dd2b6a5..93bce05ef1 100644
--- a/gdk/win32/gdksurface-win32.c
+++ b/gdk/win32/gdksurface-win32.c
@@ -177,11 +177,6 @@ gdk_surface_win32_finalize (GObject *object)
 
   surface = GDK_WIN32_SURFACE (object);
 
-  if (!GDK_SURFACE_DESTROYED (surface))
-    {
-      gdk_win32_handle_table_remove (surface->handle);
-    }
-
   g_clear_pointer (&surface->snap_stash, g_free);
   g_clear_pointer (&surface->snap_stash_int, g_free);
 
@@ -319,127 +314,6 @@ get_default_title (void)
   return title;
 }
 
-/* RegisterGdkClass
- *   is a wrapper function for RegisterWindowClassEx.
- *   It creates at least one unique class for every
- *   GdkSurfaceType. If support for single window-specific icons
- *   is ever needed (e.g Dialog specific), every such window should
- *   get its own class
- */
-static ATOM
-RegisterGdkClass (GdkSurfaceType wtype)
-{
-  static ATOM klassTOPLEVEL = 0;
-  static ATOM klassTEMP     = 0;
-  static HICON hAppIcon = NULL;
-  static HICON hAppIconSm = NULL;
-  static WNDCLASSEXW wcl;
-  ATOM klass = 0;
-
-  wcl.cbSize = sizeof (WNDCLASSEX);
-  wcl.style = 0; /* DON'T set CS_<H,V>REDRAW. It causes total redraw
-                  * on WM_SIZE and WM_MOVE. Flicker, Performance!
-                  */
-  wcl.lpfnWndProc = _gdk_win32_surface_procedure;
-  wcl.cbClsExtra = 0;
-  wcl.cbWndExtra = 0;
-  wcl.hInstance = _gdk_dll_hinstance;
-  wcl.hIcon = 0;
-  wcl.hIconSm = 0;
-
-  /* initialize once! */
-  if (0 == hAppIcon && 0 == hAppIconSm)
-    {
-      char sLoc [MAX_PATH+1];
-
-      // try to load first icon of executable program
-      if (0 != GetModuleFileName (NULL, sLoc, MAX_PATH))
-        {
-          ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
-
-          if (0 == hAppIcon && 0 == hAppIconSm)
-            {
-              // fallback : load icon from GTK DLL
-              if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH))
-               {
-                 ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1);
-               }
-            }
-        }
-
-      if (0 == hAppIcon && 0 == hAppIconSm)
-        {
-          hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
-                                GetSystemMetrics (SM_CXICON),
-                                GetSystemMetrics (SM_CYICON), 0);
-          hAppIconSm = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON,
-                                  GetSystemMetrics (SM_CXSMICON),
-                                  GetSystemMetrics (SM_CYSMICON), 0);
-        }
-    }
-
-  if (0 == hAppIcon)
-    hAppIcon = hAppIconSm;
-  else if (0 == hAppIconSm)
-    hAppIconSm = hAppIcon;
-
-  wcl.lpszMenuName = NULL;
-
-  /* initialize once per class */
-  /*
-   * HB: Setting the background brush leads to flicker, because we
-   * don't get asked how to clear the background. This is not what
-   * we want, at least not for input_only windows ...
-   */
-#define ONCE_PER_CLASS() \
-  wcl.hIcon = CopyIcon (hAppIcon); \
-  wcl.hIconSm = CopyIcon (hAppIconSm); \
-  wcl.hbrBackground = NULL; \
-  wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
-
-  /* MSDN: CS_OWNDC is needed for OpenGL contexts */
-  wcl.style |= CS_OWNDC;
-
-  switch (wtype)
-    {
-    case GDK_SURFACE_TOPLEVEL:
-    case GDK_SURFACE_POPUP:
-      if (0 == klassTOPLEVEL)
-        {
-          wcl.lpszClassName = L"gdkSurfaceToplevel";
-
-          ONCE_PER_CLASS ();
-          klassTOPLEVEL = RegisterClassExW (&wcl);
-        }
-      klass = klassTOPLEVEL;
-      break;
-
-    case GDK_SURFACE_TEMP:
-      if (klassTEMP == 0)
-        {
-          wcl.lpszClassName = L"gdkSurfaceTemp";
-          wcl.style |= CS_SAVEBITS;
-          ONCE_PER_CLASS ();
-          klassTEMP = RegisterClassExW (&wcl);
-        }
-
-      klass = klassTEMP;
-
-      break;
-
-    default:
-      g_assert_not_reached ();
-      break;
-    }
-
-  if (klass == 0)
-    {
-      WIN32_API_FAILED ("RegisterClassExW");
-      g_error ("That is a fatal error");
-    }
-  return klass;
-}
-
 /*
  * Create native windows.
  *
@@ -578,16 +452,24 @@ _gdk_win32_display_create_surface (GdkDisplay     *display,
   title = get_default_title ();
   if (!title || !*title)
     title = "";
+  wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
 
-  /* WS_EX_TRANSPARENT means "try draw this window last, and ignore input".
-   * It's the last part we're after. We don't want DND indicator to accept
-   * input, because that will make it a potential drop target, and if it's
-   * under the mouse cursor, this will kill any DND.
-   */
+  switch (surface_type)
+    {
+    case GDK_SURFACE_TOPLEVEL:
+    case GDK_SURFACE_POPUP:
+      klass = display_win32->toplevel_class;
+      break;
 
-  klass = RegisterGdkClass (surface_type);
+    case GDK_SURFACE_TEMP:
+      klass = display_win32->temp_class;
+      break;
 
-  wtitle = g_utf8_to_utf16 (title, -1, NULL, NULL, NULL);
+    default:
+      g_assert_not_reached ();
+      klass = 0;
+      break;
+    }
 
   hwndNew = CreateWindowExW (dwExStyle,
                             MAKEINTRESOURCEW (klass),
@@ -615,15 +497,6 @@ _gdk_win32_display_create_surface (GdkDisplay     *display,
     }
 
   g_object_ref (impl);
-  /* Take note: we're inserting a pointer into a heap-allocated
-   * object (impl). Inserting a pointer to a stack variable
-   * will break the logic, since stack variables are short-lived.
-   * We insert a pointer to the handle instead of the handle itself
-   * probably because we need to hash them differently depending
-   * on the bitness of the OS. That pointer is still unique,
-   * so this works out in the end.
-   */
-  gdk_win32_handle_table_insert (&GDK_SURFACE_HWND (impl), impl);
 
   GDK_NOTE (MISC, g_print ("... \"%s\" %dx%d@%+d%+d %p = %p\n",
                           title,
@@ -734,7 +607,6 @@ gdk_win32_surface_destroy_notify (GdkSurface *window)
       _gdk_surface_destroy (window, TRUE);
     }
 
-  gdk_win32_handle_table_remove (GDK_SURFACE_HWND (window));
   g_object_unref (window);
 }
 
@@ -4242,13 +4114,41 @@ gdk_win32_surface_focus (GdkSurface *window,
   SetFocus (GDK_SURFACE_HWND (window));
 }
 
+/* Yay for nobody cleaning up the win32 API.
+   At least there's no documentation for this crap,
+   so there's nothing we can break.*/
+gpointer
+gdk_win32_handle_table_lookup (HWND handle)
+{
+  return NULL;
+}
+
+/**
+ * gdk_win32_surface_lookup_for_display:
+ * @display: A display
+ * @hwnd: A HWND maybe belonging to a `GdkSurface`
+ * 
+ * Looks up the `GdkSurface` that created the given @hwnd.
+ * 
+ * Returns: (transfer none) (nullable) (type GdkWin32Surface):
+ *   The surface belonging to @hwnd or %NULL
+ */
 GdkSurface *
 gdk_win32_surface_lookup_for_display (GdkDisplay *display,
-                                     HWND        anid)
+                                      HWND        anid)
 {
-  g_return_val_if_fail (display == gdk_display_get_default (), NULL);
+  GdkWin32Display *self;
+  ATOM class;
+
+  g_return_val_if_fail (GDK_IS_WIN32_DISPLAY (display), NULL);
+
+  self = GDK_WIN32_DISPLAY (display);
+
+  class = GetWindowLong (anid, GCW_ATOM);
+  if (class != self->toplevel_class && class != self->temp_class)
+    return NULL;
 
-  return (GdkSurface*) gdk_win32_handle_table_lookup (anid);
+  return GDK_SURFACE (GetWindowLongPtr (anid, GWLP_USERDATA));
 }
 
 gboolean
diff --git a/gdk/win32/gdkwin32misc.h b/gdk/win32/gdkwin32misc.h
index 3582e81572..2542b745d7 100644
--- a/gdk/win32/gdkwin32misc.h
+++ b/gdk/win32/gdkwin32misc.h
@@ -69,21 +69,21 @@ G_BEGIN_DECLS
 #endif
 
 /* Return true if the GdkSurface is a win32 implemented window */
-GDK_AVAILABLE_IN_ALL
+GDK_DEPRECATED_IN_4_4_FOR (GDK_IS_WIN32_SURFACE)
 gboolean      gdk_win32_surface_is_win32 (GdkSurface *window);
-GDK_AVAILABLE_IN_ALL
-HWND          gdk_win32_surface_get_impl_hwnd (GdkSurface *window);
+GDK_DEPRECATED_IN_4_4_FOR (gdk_win32_surface_get_handle)
+HWND gdk_win32_surface_get_impl_hwnd (GdkSurface *window);
 
 /* Return the Gdk* for a particular HANDLE */
-GDK_AVAILABLE_IN_ALL
+GDK_DEPRECATED_IN_4_4
 gpointer      gdk_win32_handle_table_lookup (HWND handle);
 /* Translate from window to Windows handle */
 GDK_AVAILABLE_IN_ALL
 HGDIOBJ       gdk_win32_surface_get_handle (GdkSurface *window);
 
-GDK_AVAILABLE_IN_ALL
-GdkSurface *   gdk_win32_surface_lookup_for_display (GdkDisplay *display,
-                                                     HWND        anid);
+GDK_DEPRECATED_IN_4_4
+GdkSurface *  gdk_win32_surface_lookup_for_display (GdkDisplay *display,
+                                                    HWND        anid);
 
 #if defined (INSIDE_GDK_WIN32) || defined (GTK_COMPILATION) || defined (GTK_COMPILATION)
 
diff --git a/gdk/win32/meson.build b/gdk/win32/meson.build
index 796cec8fb9..de4c219a69 100644
--- a/gdk/win32/meson.build
+++ b/gdk/win32/meson.build
@@ -24,7 +24,6 @@ gdk_win32_sources = files([
   'gdkvulkancontext-win32.c',
   'gdkwin32cursor.h',
   'gdkwin32display.h',
-  'gdkwin32id.c',
   'gdksurface-win32.c',
 ])
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]