[gtk/wip/otte/win32-cleanup: 4/5] win32: Store the window classes in the display




commit 0d6becdb67f109805981ef838df41eb8b2e4fab3
Author: Benjamin Otte <otte redhat com>
Date:   Sat Jul 31 05:43:32 2021 +0200

    win32: Store the window classes in the display
    
    This way, they are per-display and not hidden in some global variable
    somewhere, which also allows checking if a HWND belongs to a display.

 gdk/win32/gdkdisplay-win32.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
 gdk/win32/gdkdisplay-win32.h |  3 ++
 gdk/win32/gdkevents-win32.c  |  2 +-
 gdk/win32/gdkprivate-win32.h |  2 +-
 4 files changed, 92 insertions(+), 2 deletions(-)
---
diff --git a/gdk/win32/gdkdisplay-win32.c b/gdk/win32/gdkdisplay-win32.c
index 6e30e240fe..51020e7ada 100644
--- a/gdk/win32/gdkdisplay-win32.c
+++ b/gdk/win32/gdkdisplay-win32.c
@@ -497,6 +497,92 @@ gdk_win32_display_create_hwnd (GdkWin32Display *self)
     }
 }
 
+static void
+gdk_win32_display_register_classes (GdkWin32Display *self)
+{
+  HICON hAppIcon = NULL;
+  HICON hAppIconSm = NULL;
+  WNDCLASSEXW wcl;
+
+  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;
+  wcl.hbrBackground = NULL;
+  wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
+  /* MSDN: CS_OWNDC is needed for OpenGL contexts */
+  wcl.style |= CS_OWNDC;
+
+  wcl.lpszClassName = L"gdkSurfaceToplevel";
+  wcl.hIcon = CopyIcon (hAppIcon);
+  wcl.hIconSm = CopyIcon (hAppIconSm);
+  self->toplevel_class = RegisterClassExW (&wcl);
+  if (self->toplevel_class == 0)
+    {
+      WIN32_API_FAILED ("RegisterClassExW");
+      g_error ("That is a fatal error");
+    }
+
+  wcl.lpszClassName = L"gdkSurfaceTemp";
+  wcl.hIcon = CopyIcon (hAppIcon);
+  wcl.hIconSm = CopyIcon (hAppIconSm);
+  wcl.style |= CS_SAVEBITS;
+  self->temp_class = RegisterClassExW (&wcl);
+  if (self->temp_class == 0)
+    {
+      WIN32_API_FAILED ("RegisterClassExW");
+      g_error ("That is a fatal error");
+    }
+
+  if (hAppIcon != hAppIconSm)
+    DestroyIcon (hAppIconSm);
+  DestroyIcon (hAppIcon);
+}
+
 GdkDisplay *
 _gdk_win32_display_open (const char *display_name)
 {
@@ -517,6 +603,7 @@ _gdk_win32_display_open (const char *display_name)
   display = g_object_new (GDK_TYPE_WIN32_DISPLAY, NULL);
   win32_display = GDK_WIN32_DISPLAY (display);
 
+  gdk_win32_display_register_classes (win32_display);
   gdk_win32_display_init_monitors (win32_display);
   
   _gdk_events_init (display);
diff --git a/gdk/win32/gdkdisplay-win32.h b/gdk/win32/gdkdisplay-win32.h
index 3839dd0b7e..c3494b403c 100644
--- a/gdk/win32/gdkdisplay-win32.h
+++ b/gdk/win32/gdkdisplay-win32.h
@@ -118,6 +118,9 @@ struct _GdkWin32Display
 {
   GdkDisplay display;
 
+  ATOM toplevel_class;
+  ATOM temp_class;
+
   Win32CursorTheme *cursor_theme;
   char *cursor_theme_name;
   int cursor_theme_size;
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 216e40962e..23d93df1b0 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -304,7 +304,7 @@ inner_window_procedure (HWND   hwnd,
 }
 
 LRESULT CALLBACK
-_gdk_win32_surface_procedure (HWND   hwnd,
+gdk_win32_surface_procedure (HWND   hwnd,
                              UINT   message,
                              WPARAM wparam,
                              LPARAM lparam)
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index a7f45f1a00..1cfafc1149 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -249,7 +249,7 @@ void    _gdk_other_api_failed        (const char *where,
 #define GDI_CALL(api, arglist) (api arglist ? 1 : (WIN32_GDI_FAILED (#api), 0))
 #define API_CALL(api, arglist) (api arglist ? 1 : (WIN32_API_FAILED (#api), 0))
 
-extern LRESULT CALLBACK _gdk_win32_surface_procedure (HWND, UINT, WPARAM, LPARAM);
+extern LRESULT CALLBACK gdk_win32_surface_procedure (HWND, UINT, WPARAM, LPARAM);
 
 extern HINSTANCE         _gdk_dll_hinstance;
 extern HINSTANCE         _gdk_app_hmodule;


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