From c1f1a1a62328113d3939d939c2013eb921e95d44 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 21 Jul 2021 03:44:39 +0200 Subject: 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(-) delete mode 100644 gdk/win32/gdkwin32id.c 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_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/gdkwin32id.c b/gdk/win32/gdkwin32id.c deleted file mode 100644 index 006e59fc7c..0000000000 --- a/gdk/win32/gdkwin32id.c +++ /dev/null @@ -1,81 +0,0 @@ -/* GDK - The GIMP Drawing Kit - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -/* - * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS - * file for a list of people on the GTK+ Team. See the ChangeLog - * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. - */ - -#include "config.h" -#include - -#include "gdkprivate-win32.h" - -static GHashTable *handle_ht = NULL; - -static guint -gdk_handle_hash (HANDLE *handle) -{ -#ifdef _WIN64 - return ((guint *) handle)[0] ^ ((guint *) handle)[1]; -#else - return (guint) *handle; -#endif -} - -static int -gdk_handle_equal (HANDLE *a, - HANDLE *b) -{ - return (*a == *b); -} - -void -gdk_win32_handle_table_insert (HANDLE *handle, - gpointer data) -{ - g_return_if_fail (handle != NULL); - - if (!handle_ht) - handle_ht = g_hash_table_new ((GHashFunc) gdk_handle_hash, - (GEqualFunc) gdk_handle_equal); - - g_hash_table_insert (handle_ht, handle, data); -} - -void -gdk_win32_handle_table_remove (HANDLE handle) -{ - if (!handle_ht) - handle_ht = g_hash_table_new ((GHashFunc) gdk_handle_hash, - (GEqualFunc) gdk_handle_equal); - - g_hash_table_remove (handle_ht, &handle); -} - -gpointer -gdk_win32_handle_table_lookup (HWND handle) -{ - gpointer data = NULL; - - if (handle_ht) - data = g_hash_table_lookup (handle_ht, &handle); - - return data; -} 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', ]) -- cgit v1.2.1