1//======================================================================== 2// GLFW 3.5 - www.glfw.org 3//------------------------------------------------------------------------ 4// Copyright (c) 2002-2006 Marcus Geelnard 5// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org> 6// 7// This software is provided 'as-is', without any express or implied 8// warranty. In no event will the authors be held liable for any damages 9// arising from the use of this software. 10// 11// Permission is granted to anyone to use this software for any purpose, 12// including commercial applications, and to alter it and redistribute it 13// freely, subject to the following restrictions: 14// 15// 1. The origin of this software must not be misrepresented; you must not 16// claim that you wrote the original software. If you use this software 17// in a product, an acknowledgment in the product documentation would 18// be appreciated but is not required. 19// 20// 2. Altered source versions must be plainly marked as such, and must not 21// be misrepresented as being the original software. 22// 23// 3. This notice may not be removed or altered from any source 24// distribution. 25// 26//======================================================================== 27 28#include "internal.h" 29 30#include <string.h> 31#include <stdlib.h> 32 33// These construct a string literal from individual numeric constants 34#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r 35#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r) 36 37////////////////////////////////////////////////////////////////////////// 38////// GLFW internal API ////// 39////////////////////////////////////////////////////////////////////////// 40 41static const struct 42{ 43 int ID; 44 GLFWbool (*connect)(int,_GLFWplatform*); 45} supportedPlatforms[] = 46{ 47#if defined(_GLFW_WIN32) 48 { GLFW_PLATFORM_WIN32, _glfwConnectWin32 }, 49#endif 50#if defined(_GLFW_COCOA) 51 { GLFW_PLATFORM_COCOA, _glfwConnectCocoa }, 52#endif 53#if defined(_GLFW_WAYLAND) 54 { GLFW_PLATFORM_WAYLAND, _glfwConnectWayland }, 55#endif 56#if defined(_GLFW_X11) 57 { GLFW_PLATFORM_X11, _glfwConnectX11 }, 58#endif 59}; 60 61GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform) 62{ 63 const size_t count = sizeof(supportedPlatforms) / sizeof(supportedPlatforms[0]); 64 size_t i; 65 66 if (desiredID != GLFW_ANY_PLATFORM && 67 desiredID != GLFW_PLATFORM_WIN32 && 68 desiredID != GLFW_PLATFORM_COCOA && 69 desiredID != GLFW_PLATFORM_WAYLAND && 70 desiredID != GLFW_PLATFORM_X11 && 71 desiredID != GLFW_PLATFORM_NULL) 72 { 73 _glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", desiredID); 74 return GLFW_FALSE; 75 } 76 77 // Only allow the Null platform if specifically requested 78 if (desiredID == GLFW_PLATFORM_NULL) 79 return _glfwConnectNull(desiredID, platform); 80 else if (count == 0) 81 { 82 _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "This binary only supports the Null platform"); 83 return GLFW_FALSE; 84 } 85 86#if defined(_GLFW_WAYLAND) && defined(_GLFW_X11) 87 if (desiredID == GLFW_ANY_PLATFORM) 88 { 89 const char* const session = getenv("XDG_SESSION_TYPE"); 90 if (session) 91 { 92 // Only follow XDG_SESSION_TYPE if it is set correctly and the 93 // environment looks plausble; otherwise fall back to detection 94 if (strcmp(session, "wayland") == 0 && getenv("WAYLAND_DISPLAY")) 95 desiredID = GLFW_PLATFORM_WAYLAND; 96 else if (strcmp(session, "x11") == 0 && getenv("DISPLAY")) 97 desiredID = GLFW_PLATFORM_X11; 98 } 99 } 100#endif 101 102 if (desiredID == GLFW_ANY_PLATFORM) 103 { 104 // If there is exactly one platform available for auto-selection, let it emit the 105 // error on failure as the platform-specific error description may be more helpful 106 if (count == 1) 107 return supportedPlatforms[0].connect(supportedPlatforms[0].ID, platform); 108 109 for (i = 0; i < count; i++) 110 { 111 if (supportedPlatforms[i].connect(desiredID, platform)) 112 return GLFW_TRUE; 113 } 114 115 _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Failed to detect any supported platform"); 116 } 117 else 118 { 119 for (i = 0; i < count; i++) 120 { 121 if (supportedPlatforms[i].ID == desiredID) 122 return supportedPlatforms[i].connect(desiredID, platform); 123 } 124 125 _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "The requested platform is not supported"); 126 } 127 128 return GLFW_FALSE; 129} 130 131////////////////////////////////////////////////////////////////////////// 132////// GLFW public API ////// 133////////////////////////////////////////////////////////////////////////// 134 135GLFWAPI int glfwGetPlatform(void) 136{ 137 _GLFW_REQUIRE_INIT_OR_RETURN(0); 138 return _glfw.platform.platformID; 139} 140 141GLFWAPI int glfwPlatformSupported(int platformID) 142{ 143 const size_t count = sizeof(supportedPlatforms) / sizeof(supportedPlatforms[0]); 144 size_t i; 145 146 if (platformID != GLFW_PLATFORM_WIN32 && 147 platformID != GLFW_PLATFORM_COCOA && 148 platformID != GLFW_PLATFORM_WAYLAND && 149 platformID != GLFW_PLATFORM_X11 && 150 platformID != GLFW_PLATFORM_NULL) 151 { 152 _glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", platformID); 153 return GLFW_FALSE; 154 } 155 156 if (platformID == GLFW_PLATFORM_NULL) 157 return GLFW_TRUE; 158 159 for (i = 0; i < count; i++) 160 { 161 if (platformID == supportedPlatforms[i].ID) 162 return GLFW_TRUE; 163 } 164 165 return GLFW_FALSE; 166} 167 168GLFWAPI const char* glfwGetVersionString(void) 169{ 170 return _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR, 171 GLFW_VERSION_MINOR, 172 GLFW_VERSION_REVISION) 173#if defined(_GLFW_WIN32) 174 " Win32 WGL" 175#endif 176#if defined(_GLFW_COCOA) 177 " Cocoa NSGL" 178#endif 179#if defined(_GLFW_WAYLAND) 180 " Wayland" 181#endif 182#if defined(_GLFW_X11) 183 " X11 GLX" 184#endif 185 " Null" 186 " EGL" 187 " OSMesa" 188#if defined(__MINGW64_VERSION_MAJOR) 189 " MinGW-w64" 190#elif defined(__MINGW32__) 191 " MinGW" 192#elif defined(_MSC_VER) 193 " VisualC" 194#endif 195#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG) 196 " hybrid-GPU" 197#endif 198#if defined(_POSIX_MONOTONIC_CLOCK) 199 " monotonic" 200#endif 201#if defined(_GLFW_BUILD_DLL) 202#if defined(_WIN32) 203 " DLL" 204#elif defined(__APPLE__) 205 " dynamic" 206#else 207 " shared" 208#endif 209#endif 210 ; 211} 212 213