summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2021-07-31 05:43:32 +0200
committerBenjamin Otte <otte@redhat.com>2021-07-31 05:50:14 +0200
commit0d6becdb67f109805981ef838df41eb8b2e4fab3 (patch)
treee8d0d19523af6060ac4ba53432e618b128847391
parent6b760b5d37f7d408b0619c645b0999aa5d5c514e (diff)
downloadgtk+-0d6becdb67f109805981ef838df41eb8b2e4fab3.tar.gz
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.
-rw-r--r--gdk/win32/gdkdisplay-win32.c87
-rw-r--r--gdk/win32/gdkdisplay-win32.h3
-rw-r--r--gdk/win32/gdkevents-win32.c2
-rw-r--r--gdk/win32/gdkprivate-win32.h2
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;