gtk/gdk/win32/gdkdisplay-win32.h

204 lines
6.0 KiB
C
Raw Normal View History

/*
* gdkdisplay-win32.h
*
* Copyright 2014 Chun-wei Fan <fanc999@yahoo.com.tw>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "gdkdisplayprivate.h"
#ifndef __GDK_DISPLAY__WIN32_H__
#define __GDK_DISPLAY__WIN32_H__
#include "gdkwin32screen.h"
GDK W32: New cursor class Instead of now-unused GdkWin32Cursor class (a subclass of GdkCursor), add a stand-alone GdkWin32HCursor class that is a wrapper around HCURSOR handle. On creation it's given a display instance, a HCURSOR handle and a boolean that indicates whether the HCURSOR handle can or cannot be destroyed (this depends on how the handle was obtained). That information is stored in a hash table inside the GdkWin32Display singleton, each entry of that table has reference count. When the GdkWin32HCursor object is finalized, it reduces the reference count on the table entry in the GdkWin32Display. When it's created, it either adds such an entry or refs an existing one. This way two pieces of code (or the same piece of code called multiple times) that independently obtain the same HCURSOR from the OS will get to different GdkWin32HCursor instances, but GdkWin32Display will know that both use the same handle. Once the reference count reaches 0 on the table entry, it is freed and the handle (if destroyable) is put on the destruction list, and an idle destruction function is queued. If the same handle is once again registered for use before the idle destructior is invoked (this happens, for example, when an old cursor is destroyed and then replaced with a new one), the handle gets removed from the destruction list. The destructor just calls DestroyCursor() on each handle, calling SetCursor(NULL) before doing that when the handle is in use. This ensures that SetCursor(NULL) (which will cause cursor to disappear, which is bad by itself, and which will also cause flickering if the cursor is set to a non-NULL again shortly afterward) is almost never called, unless GTK messes up and keeps using a cursor beyond its lifetime. This scheme also ensures that non-destructable cursors are not destroyed. It's also possible to call _gdk_win32_display_hcursor_ref() and _gdk_win32_display_hcursor_unref() manually instead of creating GdkWin32HCursor objects, but that is not recommended.
2018-03-29 23:38:05 +00:00
#include "gdkwin32cursor.h"
#ifdef GDK_WIN32_ENABLE_EGL
# include <epoxy/egl.h>
#endif
/* Define values used to set DPI-awareness */
typedef enum _GdkWin32ProcessDpiAwareness {
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2,
PROCESS_PER_MONITOR_DPI_AWARE_V2 = 3, /* Newer HiDPI type for Windows 10 1607+ */
} GdkWin32ProcessDpiAwareness;
/* From https://docs.microsoft.com/en-US/windows/win32/hidpi/dpi-awareness-context */
/* DPI_AWARENESS_CONTEXT is declared by DEFINE_HANDLE */
#ifndef DPI_AWARENESS_CONTEXT_UNAWARE
#define DPI_AWARENESS_CONTEXT_UNAWARE (HANDLE)-1
#endif
#ifndef DPI_AWARENESS_CONTEXT_SYSTEM_AWARE
#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE (HANDLE)-2
#endif
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (HANDLE)-4
#endif
typedef enum _GdkWin32MonitorDpiType {
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
} GdkWin32MonitorDpiType;
/* APIs from shcore.dll */
typedef HRESULT (WINAPI *funcSetProcessDpiAwareness) (GdkWin32ProcessDpiAwareness value);
typedef HRESULT (WINAPI *funcGetProcessDpiAwareness) (HANDLE handle, GdkWin32ProcessDpiAwareness *awareness);
typedef HRESULT (WINAPI *funcGetDpiForMonitor) (HMONITOR monitor,
GdkWin32MonitorDpiType dpi_type,
UINT *dpi_x,
UINT *dpi_y);
typedef struct _GdkWin32ShcoreFuncs
{
HMODULE hshcore;
funcSetProcessDpiAwareness setDpiAwareFunc;
funcGetProcessDpiAwareness getDpiAwareFunc;
funcGetDpiForMonitor getDpiForMonitorFunc;
} GdkWin32ShcoreFuncs;
/* DPI awareness APIs from user32.dll */
typedef BOOL (WINAPI *funcSetProcessDPIAware) (void);
typedef BOOL (WINAPI *funcIsProcessDPIAware) (void);
/*
* funcSPDAC is SetProcessDpiAwarenessContext() and
* funcGTDAC is GetThreadDpiAwarenessContext() and
* funcADACE is AreDpiAwarenessContextsEqual() provided by user32.dll, on
* Windows 10 Creator Edition and later.
* Treat HANDLE as void*, for convenience, since DPI_AWARENESS_CONTEXT is
* declared using DEFINE_HANDLE.
*/
typedef BOOL (WINAPI *funcSPDAC) (void *);
typedef HANDLE (WINAPI *funcGTDAC) (void);
typedef BOOL (WINAPI *funcADACE) (void *, void *);
typedef struct _GdkWin32User32DPIFuncs
{
funcSetProcessDPIAware setDpiAwareFunc;
funcIsProcessDPIAware isDpiAwareFunc;
funcSPDAC setPDAC;
funcGTDAC getTDAC;
funcADACE areDACEqual;
} GdkWin32User32DPIFuncs;
/* Detect running architecture */
typedef BOOL (WINAPI *funcIsWow64Process2) (HANDLE, USHORT *, USHORT *);
typedef struct _GdkWin32KernelCPUFuncs
{
funcIsWow64Process2 isWow64Process2;
} GdkWin32KernelCPUFuncs;
struct _GdkWin32Display
{
GdkDisplay display;
GdkWin32Screen *screen;
Win32CursorTheme *cursor_theme;
2020-07-24 18:40:36 +00:00
char *cursor_theme_name;
int cursor_theme_size;
HWND hwnd;
/* WGL/OpenGL Items */
guint have_wgl : 1;
guint gl_version;
HWND gl_hwnd;
#ifdef GDK_WIN32_ENABLE_EGL
/* EGL (Angle) Items */
guint have_egl : 1;
guint egl_version;
EGLDisplay egl_disp;
HDC hdc_egl_temp;
#endif
GListModel *monitors;
2016-04-20 07:36:00 +00:00
guint hasWglARBCreateContext : 1;
guint hasWglEXTSwapControl : 1;
guint hasWglOMLSyncControl : 1;
guint hasWglARBPixelFormat : 1;
guint hasWglARBmultisample : 1;
#ifdef GDK_WIN32_ENABLE_EGL
guint hasEglKHRCreateContext : 1;
guint hasEglSurfacelessContext : 1;
EGLint egl_min_swap_interval;
#endif
/* HiDPI Items */
guint have_at_least_win81 : 1;
GdkWin32ProcessDpiAwareness dpi_aware_type;
guint has_fixed_scale : 1;
GdkSurface: Rename various functions and variables This is an automatic rename of various things related to the window->surface rename. Public symbols changed by this is: GDK_MODE_WINDOW gdk_device_get_window_at_position gdk_device_get_window_at_position_double gdk_device_get_last_event_window gdk_display_get_monitor_at_window gdk_drag_context_get_source_window gdk_drag_context_get_dest_window gdk_drag_context_get_drag_window gdk_draw_context_get_window gdk_drawing_context_get_window gdk_gl_context_get_window gdk_synthesize_window_state gdk_surface_get_window_type gdk_x11_display_set_window_scale gsk_renderer_new_for_window gsk_renderer_get_window gtk_text_view_buffer_to_window_coords gtk_tree_view_convert_widget_to_bin_window_coords gtk_tree_view_convert_tree_to_bin_window_coords The commands that generated this are: git sed -f g "GDK window" "GDK surface" git sed -f g window_impl surface_impl (cd gdk; git sed -f g impl_window impl_surface) git sed -f g WINDOW_IMPL SURFACE_IMPL git sed -f g GDK_MODE_WINDOW GDK_MODE_SURFACE git sed -f g gdk_draw_context_get_window gdk_draw_context_get_surface git sed -f g gdk_drawing_context_get_window gdk_drawing_context_get_surface git sed -f g gdk_gl_context_get_window gdk_gl_context_get_surface git sed -f g gsk_renderer_get_window gsk_renderer_get_surface git sed -f g gsk_renderer_new_for_window gsk_renderer_new_for_surface (cd gdk; git sed -f g window_type surface_type) git sed -f g gdk_surface_get_window_type gdk_surface_get_surface_type git sed -f g window_at_position surface_at_position git sed -f g event_window event_surface git sed -f g window_coord surface_coord git sed -f g window_state surface_state git sed -f g window_cursor surface_cursor git sed -f g window_scale surface_scale git sed -f g window_events surface_events git sed -f g monitor_at_window monitor_at_surface git sed -f g window_under_pointer surface_under_pointer (cd gdk; git sed -f g for_window for_surface) git sed -f g window_anchor surface_anchor git sed -f g WINDOW_IS_TOPLEVEL SURFACE_IS_TOPLEVEL git sed -f g native_window native_surface git sed -f g source_window source_surface git sed -f g dest_window dest_surface git sed -f g drag_window drag_surface git sed -f g input_window input_surface git checkout NEWS* po-properties po docs/reference/gtk/migrating-3to4.xml
2018-03-20 11:05:26 +00:00
guint surface_scale;
GdkWin32ShcoreFuncs shcore_funcs;
GdkWin32User32DPIFuncs user32_dpi_funcs;
/* Cursor Items (GdkCursor->GdkWin32HCursor) */
GHashTable *cursors;
/* The cursor that is used by current grab (if any) */
GdkWin32HCursor *grab_cursor;
GDK W32: New cursor class Instead of now-unused GdkWin32Cursor class (a subclass of GdkCursor), add a stand-alone GdkWin32HCursor class that is a wrapper around HCURSOR handle. On creation it's given a display instance, a HCURSOR handle and a boolean that indicates whether the HCURSOR handle can or cannot be destroyed (this depends on how the handle was obtained). That information is stored in a hash table inside the GdkWin32Display singleton, each entry of that table has reference count. When the GdkWin32HCursor object is finalized, it reduces the reference count on the table entry in the GdkWin32Display. When it's created, it either adds such an entry or refs an existing one. This way two pieces of code (or the same piece of code called multiple times) that independently obtain the same HCURSOR from the OS will get to different GdkWin32HCursor instances, but GdkWin32Display will know that both use the same handle. Once the reference count reaches 0 on the table entry, it is freed and the handle (if destroyable) is put on the destruction list, and an idle destruction function is queued. If the same handle is once again registered for use before the idle destructior is invoked (this happens, for example, when an old cursor is destroyed and then replaced with a new one), the handle gets removed from the destruction list. The destructor just calls DestroyCursor() on each handle, calling SetCursor(NULL) before doing that when the handle is in use. This ensures that SetCursor(NULL) (which will cause cursor to disappear, which is bad by itself, and which will also cause flickering if the cursor is set to a non-NULL again shortly afterward) is almost never called, unless GTK messes up and keeps using a cursor beyond its lifetime. This scheme also ensures that non-destructable cursors are not destroyed. It's also possible to call _gdk_win32_display_hcursor_ref() and _gdk_win32_display_hcursor_unref() manually instead of creating GdkWin32HCursor objects, but that is not recommended.
2018-03-29 23:38:05 +00:00
/* HCURSOR -> GdkWin32HCursorTableEntry */
GHashTable *cursor_reftable;
/* ID of the idle callback scheduled to destroy cursors */
guint idle_cursor_destructor_id;
/* A list of cursor handles slated for destruction. */
GList *cursors_for_destruction;
/* Message filters */
GList *filters;
/* Running CPU items */
guint running_on_arm64 : 1;
GdkWin32KernelCPUFuncs cpu_funcs;
};
struct _GdkWin32DisplayClass
{
GdkDisplayClass display_class;
};
void _gdk_win32_display_init_monitors (GdkWin32Display *display);
2016-04-20 07:36:00 +00:00
GPtrArray *_gdk_win32_display_get_monitor_list (GdkWin32Display *display);
void gdk_win32_display_check_composited (GdkWin32Display *display);
guint _gdk_win32_display_get_monitor_scale_factor (GdkWin32Display *win32_display,
HMONITOR hmonitor,
HWND hwnd,
2020-07-24 13:54:49 +00:00
int *dpi);
typedef struct _GdkWin32MessageFilter GdkWin32MessageFilter;
struct _GdkWin32MessageFilter
{
GdkWin32MessageFilterFunc function;
gpointer data;
gboolean removed;
guint ref_count;
};
#endif /* __GDK_DISPLAY__WIN32_H__ */