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
41 static 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
_glfwSelectPlatform(int desiredID,_GLFWplatform * platform)61 GLFWbool _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
glfwGetPlatform(void)135 GLFWAPI int glfwGetPlatform(void)
136 {
137 _GLFW_REQUIRE_INIT_OR_RETURN(0);
138 return _glfw.platform.platformID;
139 }
140
glfwPlatformSupported(int platformID)141 GLFWAPI 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
glfwGetVersionString(void)168 GLFWAPI 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