mirror of
https://github.com/glfw/glfw.git
synced 2026-09-21 00:30:57 +00:00
Add runtime platform selection
This adds compile-time support for multiple platforms and runtime detection of them. Window system related platform functions are now called from shared code via the function pointer struct _GLFWplatform. The timer, thread and module loading platform functions are still called directly by name and the implementation chosen at link-time. These functions are the same for any backend on a given OS, including the Null backend. The platforms are now enabled via CMake dependent options following the GLFW_BUILD_<platform> pattern instead of a mix of automagic and ad-hoc option names. There is no longer any option for the Null backend as it is now always enabled. Much of the struct stitching work in platform.h was based on an earlier experimental branch for runtime platform selection by @ronchaine. Every platform function related to windows, contexts, monitors, input, event processing and Vulkan have been renamed so that multiple sets of them can exist without colliding. Calls to these are now routed through the _glfw.platform struct member. These changes makes up most of this commit. For Wayland and X11 the client library loading and display creation is used to detect a running compositor/server. The XDG_SESSION_TYPE environment variable is ignored for now, as X11 is still by far the more complete implementation. Closes #1655 Closes #1958
This commit is contained in:
+111
-141
@@ -68,6 +68,7 @@ typedef struct _GLFWctxconfig _GLFWctxconfig;
|
||||
typedef struct _GLFWfbconfig _GLFWfbconfig;
|
||||
typedef struct _GLFWcontext _GLFWcontext;
|
||||
typedef struct _GLFWwindow _GLFWwindow;
|
||||
typedef struct _GLFWplatform _GLFWplatform;
|
||||
typedef struct _GLFWlibrary _GLFWlibrary;
|
||||
typedef struct _GLFWmonitor _GLFWmonitor;
|
||||
typedef struct _GLFWcursor _GLFWcursor;
|
||||
@@ -332,19 +333,7 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
||||
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
|
||||
#endif
|
||||
|
||||
#if defined(_GLFW_COCOA)
|
||||
#include "cocoa_platform.h"
|
||||
#elif defined(_GLFW_WIN32)
|
||||
#include "win32_platform.h"
|
||||
#elif defined(_GLFW_X11)
|
||||
#include "x11_platform.h"
|
||||
#elif defined(_GLFW_WAYLAND)
|
||||
#include "wl_platform.h"
|
||||
#elif defined(_GLFW_OSMESA)
|
||||
#include "null_platform.h"
|
||||
#else
|
||||
#error "No supported window creation API selected"
|
||||
#endif
|
||||
#include "platform.h"
|
||||
|
||||
// Constructs a version number string from the public header macros
|
||||
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
|
||||
@@ -393,6 +382,7 @@ struct _GLFWinitconfig
|
||||
{
|
||||
GLFWbool hatButtons;
|
||||
int angleType;
|
||||
int platformID;
|
||||
struct {
|
||||
GLFWbool menubar;
|
||||
GLFWbool chdir;
|
||||
@@ -527,8 +517,8 @@ struct _GLFWcontext
|
||||
void* buffer;
|
||||
} osmesa;
|
||||
|
||||
// This is defined in the context API's context.h
|
||||
_GLFW_PLATFORM_CONTEXT_STATE;
|
||||
// This is defined in platform.h
|
||||
GLFW_PLATFORM_CONTEXT_STATE
|
||||
};
|
||||
|
||||
// Window and context structure
|
||||
@@ -587,8 +577,8 @@ struct _GLFWwindow
|
||||
GLFWdropfun drop;
|
||||
} callbacks;
|
||||
|
||||
// This is defined in the window API's platform.h
|
||||
_GLFW_PLATFORM_WINDOW_STATE;
|
||||
// This is defined in platform.h
|
||||
GLFW_PLATFORM_WINDOW_STATE
|
||||
};
|
||||
|
||||
// Monitor structure
|
||||
@@ -611,8 +601,8 @@ struct _GLFWmonitor
|
||||
GLFWgammaramp originalRamp;
|
||||
GLFWgammaramp currentRamp;
|
||||
|
||||
// This is defined in the window API's platform.h
|
||||
_GLFW_PLATFORM_MONITOR_STATE;
|
||||
// This is defined in platform.h
|
||||
GLFW_PLATFORM_MONITOR_STATE
|
||||
};
|
||||
|
||||
// Cursor structure
|
||||
@@ -620,9 +610,8 @@ struct _GLFWmonitor
|
||||
struct _GLFWcursor
|
||||
{
|
||||
_GLFWcursor* next;
|
||||
|
||||
// This is defined in the window API's platform.h
|
||||
_GLFW_PLATFORM_CURSOR_STATE;
|
||||
// This is defined in platform.h
|
||||
GLFW_PLATFORM_CURSOR_STATE
|
||||
};
|
||||
|
||||
// Gamepad mapping element structure
|
||||
@@ -661,24 +650,108 @@ struct _GLFWjoystick
|
||||
char guid[33];
|
||||
_GLFWmapping* mapping;
|
||||
|
||||
// This is defined in the joystick API's joystick.h
|
||||
_GLFW_PLATFORM_JOYSTICK_STATE;
|
||||
// This is defined in platform.h
|
||||
GLFW_PLATFORM_JOYSTICK_STATE
|
||||
};
|
||||
|
||||
// Thread local storage structure
|
||||
//
|
||||
struct _GLFWtls
|
||||
{
|
||||
// This is defined in the platform's thread.h
|
||||
_GLFW_PLATFORM_TLS_STATE;
|
||||
// This is defined in platform.h
|
||||
GLFW_PLATFORM_TLS_STATE
|
||||
};
|
||||
|
||||
// Mutex structure
|
||||
//
|
||||
struct _GLFWmutex
|
||||
{
|
||||
// This is defined in the platform's thread.h
|
||||
_GLFW_PLATFORM_MUTEX_STATE;
|
||||
// This is defined in platform.h
|
||||
GLFW_PLATFORM_MUTEX_STATE
|
||||
};
|
||||
|
||||
// Platform API structure
|
||||
//
|
||||
struct _GLFWplatform
|
||||
{
|
||||
int platformID;
|
||||
// init
|
||||
GLFWbool (*init)(void);
|
||||
void (*terminate)(void);
|
||||
// input
|
||||
void (*getCursorPos)(_GLFWwindow*,double*,double*);
|
||||
void (*setCursorPos)(_GLFWwindow*,double,double);
|
||||
void (*setCursorMode)(_GLFWwindow*,int);
|
||||
void (*setRawMouseMotion)(_GLFWwindow*,GLFWbool);
|
||||
GLFWbool (*rawMouseMotionSupported)(void);
|
||||
int (*createCursor)(_GLFWcursor*,const GLFWimage*,int,int);
|
||||
int (*createStandardCursor)(_GLFWcursor*,int);
|
||||
void (*destroyCursor)(_GLFWcursor*);
|
||||
void (*setCursor)(_GLFWwindow*,_GLFWcursor*);
|
||||
const char* (*getScancodeName)(int);
|
||||
int (*getKeyScancode)(int);
|
||||
void (*setClipboardString)(const char*);
|
||||
const char* (*getClipboardString)(void);
|
||||
GLFWbool (*initJoysticks)(void);
|
||||
void (*terminateJoysticks)(void);
|
||||
int (*pollJoystick)(_GLFWjoystick*,int);
|
||||
const char* (*getMappingName)(void);
|
||||
void (*updateGamepadGUID)(char*);
|
||||
// monitor
|
||||
void (*freeMonitor)(_GLFWmonitor*);
|
||||
void (*getMonitorPos)(_GLFWmonitor*,int*,int*);
|
||||
void (*getMonitorContentScale)(_GLFWmonitor*,float*,float*);
|
||||
void (*getMonitorWorkarea)(_GLFWmonitor*,int*,int*,int*,int*);
|
||||
GLFWvidmode* (*getVideoModes)(_GLFWmonitor*,int*);
|
||||
void (*getVideoMode)(_GLFWmonitor*,GLFWvidmode*);
|
||||
GLFWbool (*getGammaRamp)(_GLFWmonitor*,GLFWgammaramp*);
|
||||
void (*setGammaRamp)(_GLFWmonitor*,const GLFWgammaramp*);
|
||||
// window
|
||||
int (*createWindow)(_GLFWwindow*,const _GLFWwndconfig*,const _GLFWctxconfig*,const _GLFWfbconfig*);
|
||||
void (*destroyWindow)(_GLFWwindow*);
|
||||
void (*setWindowTitle)(_GLFWwindow*,const char*);
|
||||
void (*setWindowIcon)(_GLFWwindow*,int,const GLFWimage*);
|
||||
void (*getWindowPos)(_GLFWwindow*,int*,int*);
|
||||
void (*setWindowPos)(_GLFWwindow*,int,int);
|
||||
void (*getWindowSize)(_GLFWwindow*,int*,int*);
|
||||
void (*setWindowSize)(_GLFWwindow*,int,int);
|
||||
void (*setWindowSizeLimits)(_GLFWwindow*,int,int,int,int);
|
||||
void (*setWindowAspectRatio)(_GLFWwindow*,int,int);
|
||||
void (*getFramebufferSize)(_GLFWwindow*,int*,int*);
|
||||
void (*getWindowFrameSize)(_GLFWwindow*,int*,int*,int*,int*);
|
||||
void (*getWindowContentScale)(_GLFWwindow*,float*,float*);
|
||||
void (*iconifyWindow)(_GLFWwindow*);
|
||||
void (*restoreWindow)(_GLFWwindow*);
|
||||
void (*maximizeWindow)(_GLFWwindow*);
|
||||
void (*showWindow)(_GLFWwindow*);
|
||||
void (*hideWindow)(_GLFWwindow*);
|
||||
void (*requestWindowAttention)(_GLFWwindow*);
|
||||
void (*focusWindow)(_GLFWwindow*);
|
||||
void (*setWindowMonitor)(_GLFWwindow*,_GLFWmonitor*,int,int,int,int,int);
|
||||
int (*windowFocused)(_GLFWwindow*);
|
||||
int (*windowIconified)(_GLFWwindow*);
|
||||
int (*windowVisible)(_GLFWwindow*);
|
||||
int (*windowMaximized)(_GLFWwindow*);
|
||||
int (*windowHovered)(_GLFWwindow*);
|
||||
int (*framebufferTransparent)(_GLFWwindow*);
|
||||
float (*getWindowOpacity)(_GLFWwindow*);
|
||||
void (*setWindowResizable)(_GLFWwindow*,GLFWbool);
|
||||
void (*setWindowDecorated)(_GLFWwindow*,GLFWbool);
|
||||
void (*setWindowFloating)(_GLFWwindow*,GLFWbool);
|
||||
void (*setWindowOpacity)(_GLFWwindow*,float);
|
||||
void (*setWindowMousePassthrough)(_GLFWwindow*,GLFWbool);
|
||||
void (*pollEvents)(void);
|
||||
void (*waitEvents)(void);
|
||||
void (*waitEventsTimeout)(double);
|
||||
void (*postEmptyEvent)(void);
|
||||
// EGL
|
||||
EGLenum (*getEGLPlatform)(EGLint**);
|
||||
EGLNativeDisplayType (*getEGLNativeDisplay)(void);
|
||||
EGLNativeWindowType (*getEGLNativeWindow)(_GLFWwindow*);
|
||||
// vulkan
|
||||
void (*getRequiredInstanceExtensions)(char**);
|
||||
int (*getPhysicalDevicePresentationSupport)(VkInstance,VkPhysicalDevice,uint32_t);
|
||||
VkResult (*createWindowSurface)(VkInstance,_GLFWwindow*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||
};
|
||||
|
||||
// Library global data
|
||||
@@ -688,6 +761,8 @@ struct _GLFWlibrary
|
||||
GLFWbool initialized;
|
||||
GLFWallocator allocator;
|
||||
|
||||
_GLFWplatform platform;
|
||||
|
||||
struct {
|
||||
_GLFWinitconfig init;
|
||||
_GLFWfbconfig framebuffer;
|
||||
@@ -714,8 +789,8 @@ struct _GLFWlibrary
|
||||
|
||||
struct {
|
||||
uint64_t offset;
|
||||
// This is defined in the platform's time.h
|
||||
_GLFW_PLATFORM_LIBRARY_TIMER_STATE;
|
||||
// This is defined in platform.h
|
||||
GLFW_PLATFORM_LIBRARY_TIMER_STATE
|
||||
} timer;
|
||||
|
||||
struct {
|
||||
@@ -784,17 +859,12 @@ struct _GLFWlibrary
|
||||
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
||||
#endif
|
||||
GLFWbool KHR_surface;
|
||||
#if defined(_GLFW_WIN32)
|
||||
GLFWbool KHR_win32_surface;
|
||||
#elif defined(_GLFW_COCOA)
|
||||
GLFWbool MVK_macos_surface;
|
||||
GLFWbool EXT_metal_surface;
|
||||
#elif defined(_GLFW_X11)
|
||||
GLFWbool KHR_xlib_surface;
|
||||
GLFWbool KHR_xcb_surface;
|
||||
#elif defined(_GLFW_WAYLAND)
|
||||
GLFWbool KHR_wayland_surface;
|
||||
#endif
|
||||
} vk;
|
||||
|
||||
struct {
|
||||
@@ -802,12 +872,10 @@ struct _GLFWlibrary
|
||||
GLFWjoystickfun joystick;
|
||||
} callbacks;
|
||||
|
||||
// This is defined in the window API's platform.h
|
||||
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
|
||||
// This is defined in the context API's context.h
|
||||
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE;
|
||||
// This is defined in the platform's joystick.h
|
||||
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
|
||||
// These are defined in platform.h
|
||||
GLFW_PLATFORM_LIBRARY_WINDOW_STATE
|
||||
GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
||||
GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
|
||||
};
|
||||
|
||||
// Global state shared between compilation units of GLFW
|
||||
@@ -819,110 +887,10 @@ extern _GLFWlibrary _glfw;
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformInit(void);
|
||||
void _glfwPlatformTerminate(void);
|
||||
const char* _glfwPlatformGetVersionString(void);
|
||||
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos);
|
||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
|
||||
void _glfwPlatformSetRawMouseMotion(_GLFWwindow *window, GLFWbool enabled);
|
||||
GLFWbool _glfwPlatformRawMouseMotionSupported(void);
|
||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||
const GLFWimage* image, int xhot, int yhot);
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
|
||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
|
||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
|
||||
|
||||
const char* _glfwPlatformGetScancodeName(int scancode);
|
||||
int _glfwPlatformGetKeyScancode(int key);
|
||||
|
||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor);
|
||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
|
||||
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
float* xscale, float* yscale);
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
|
||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
||||
GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||
|
||||
void _glfwPlatformSetClipboardString(const char* string);
|
||||
const char* _glfwPlatformGetClipboardString(void);
|
||||
|
||||
GLFWbool _glfwPlatformInitJoysticks(void);
|
||||
void _glfwPlatformTerminateJoysticks(void);
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid);
|
||||
const char* _glfwPlatformGetMappingName(void);
|
||||
|
||||
void _glfwPlatformInitTimer(void);
|
||||
uint64_t _glfwPlatformGetTimerValue(void);
|
||||
uint64_t _glfwPlatformGetTimerFrequency(void);
|
||||
|
||||
int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window);
|
||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
|
||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
int count, const GLFWimage* images);
|
||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos);
|
||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height);
|
||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
|
||||
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||
int minwidth, int minheight,
|
||||
int maxwidth, int maxheight);
|
||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
|
||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
|
||||
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||
int* left, int* top,
|
||||
int* right, int* bottom);
|
||||
void _glfwPlatformGetWindowContentScale(_GLFWwindow* window,
|
||||
float* xscale, float* yscale);
|
||||
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
|
||||
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
|
||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window);
|
||||
void _glfwPlatformHideWindow(_GLFWwindow* window);
|
||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window);
|
||||
void _glfwPlatformFocusWindow(_GLFWwindow* window);
|
||||
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor,
|
||||
int xpos, int ypos, int width, int height,
|
||||
int refreshRate);
|
||||
int _glfwPlatformWindowFocused(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowIconified(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowVisible(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowHovered(_GLFWwindow* window);
|
||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window);
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowMousePassthrough(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
|
||||
|
||||
void _glfwPlatformPollEvents(void);
|
||||
void _glfwPlatformWaitEvents(void);
|
||||
void _glfwPlatformWaitEventsTimeout(double timeout);
|
||||
void _glfwPlatformPostEmptyEvent(void);
|
||||
|
||||
EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs);
|
||||
EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void);
|
||||
EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window);
|
||||
|
||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
|
||||
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||
VkPhysicalDevice device,
|
||||
uint32_t queuefamily);
|
||||
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||
_GLFWwindow* window,
|
||||
const VkAllocationCallbacks* allocator,
|
||||
VkSurfaceKHR* surface);
|
||||
|
||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
|
||||
void _glfwPlatformDestroyTls(_GLFWtls* tls);
|
||||
void* _glfwPlatformGetTls(_GLFWtls* tls);
|
||||
@@ -983,6 +951,8 @@ void _glfwInputError(int code, const char* format, ...);
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwSelectPlatform(int platformID, _GLFWplatform* platform);
|
||||
|
||||
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions);
|
||||
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
||||
const _GLFWfbconfig* alternatives,
|
||||
|
||||
Reference in New Issue
Block a user