1 //========================================================================
2 // GLFW 3.2 - www.glfw.org
3 //------------------------------------------------------------------------
4 // Copyright (c) 2002-2006 Marcus Geelnard
5 // Copyright (c) 2006-2016 Camilla Berglund <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 #include <stdio.h>
33 #include <stdarg.h>
34
35
36 // The three global variables below comprise all global data in GLFW.
37 // Any other global variable is a bug.
38
39 // Global state shared between compilation units of GLFW
40 // These are documented in internal.h
41 //
42 GLFWbool _glfwInitialized = GLFW_FALSE;
43 _GLFWlibrary _glfw;
44
45 // This is outside of _glfw so it can be initialized and usable before
46 // glfwInit is called, which lets that function report errors
47 //
48 static GLFWerrorfun _glfwErrorCallback = NULL;
49
50
51 // Returns a generic string representation of the specified error
52 //
getErrorString(int error)53 static const char* getErrorString(int error)
54 {
55 switch (error)
56 {
57 case GLFW_NOT_INITIALIZED:
58 return "The GLFW library is not initialized";
59 case GLFW_NO_CURRENT_CONTEXT:
60 return "There is no current context";
61 case GLFW_INVALID_ENUM:
62 return "Invalid argument for enum parameter";
63 case GLFW_INVALID_VALUE:
64 return "Invalid value for parameter";
65 case GLFW_OUT_OF_MEMORY:
66 return "Out of memory";
67 case GLFW_API_UNAVAILABLE:
68 return "The requested API is unavailable";
69 case GLFW_VERSION_UNAVAILABLE:
70 return "The requested API version is unavailable";
71 case GLFW_PLATFORM_ERROR:
72 return "A platform-specific error occurred";
73 case GLFW_FORMAT_UNAVAILABLE:
74 return "The requested format is unavailable";
75 case GLFW_NO_WINDOW_CONTEXT:
76 return "The specified window has no context";
77 default:
78 return "ERROR: UNKNOWN GLFW ERROR";
79 }
80 }
81
82
83 //////////////////////////////////////////////////////////////////////////
84 ////// GLFW event API //////
85 //////////////////////////////////////////////////////////////////////////
86
_glfwInputError(int error,const char * format,...)87 void _glfwInputError(int error, const char* format, ...)
88 {
89 if (_glfwErrorCallback)
90 {
91 char buffer[8192];
92 const char* description;
93
94 if (format)
95 {
96 int count;
97 va_list vl;
98
99 va_start(vl, format);
100 count = vsnprintf(buffer, sizeof(buffer), format, vl);
101 va_end(vl);
102
103 if (count < 0)
104 buffer[sizeof(buffer) - 1] = '\0';
105
106 description = buffer;
107 }
108 else
109 description = getErrorString(error);
110
111 _glfwErrorCallback(error, description);
112 }
113 }
114
115
116 //////////////////////////////////////////////////////////////////////////
117 ////// GLFW public API //////
118 //////////////////////////////////////////////////////////////////////////
119
glfwInit(void)120 GLFWAPI int glfwInit(void)
121 {
122 if (_glfwInitialized)
123 return GLFW_TRUE;
124
125 memset(&_glfw, 0, sizeof(_glfw));
126
127 if (!_glfwPlatformInit())
128 {
129 _glfwPlatformTerminate();
130 return GLFW_FALSE;
131 }
132
133 _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
134 _glfwInitialized = GLFW_TRUE;
135
136 _glfw.timerOffset = _glfwPlatformGetTimerValue();
137
138 // Not all window hints have zero as their default value
139 glfwDefaultWindowHints();
140
141 return GLFW_TRUE;
142 }
143
glfwTerminate(void)144 GLFWAPI void glfwTerminate(void)
145 {
146 int i;
147
148 if (!_glfwInitialized)
149 return;
150
151 memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks));
152
153 while (_glfw.windowListHead)
154 glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead);
155
156 while (_glfw.cursorListHead)
157 glfwDestroyCursor((GLFWcursor*) _glfw.cursorListHead);
158
159 for (i = 0; i < _glfw.monitorCount; i++)
160 {
161 _GLFWmonitor* monitor = _glfw.monitors[i];
162 if (monitor->originalRamp.size)
163 _glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
164 }
165
166 _glfwTerminateVulkan();
167
168 _glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount);
169 _glfw.monitors = NULL;
170 _glfw.monitorCount = 0;
171
172 _glfwPlatformTerminate();
173
174 memset(&_glfw, 0, sizeof(_glfw));
175 _glfwInitialized = GLFW_FALSE;
176 }
177
glfwGetVersion(int * major,int * minor,int * rev)178 GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
179 {
180 if (major != NULL)
181 *major = GLFW_VERSION_MAJOR;
182
183 if (minor != NULL)
184 *minor = GLFW_VERSION_MINOR;
185
186 if (rev != NULL)
187 *rev = GLFW_VERSION_REVISION;
188 }
189
glfwGetVersionString(void)190 GLFWAPI const char* glfwGetVersionString(void)
191 {
192 return _glfwPlatformGetVersionString();
193 }
194
glfwSetErrorCallback(GLFWerrorfun cbfun)195 GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
196 {
197 _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
198 return cbfun;
199 }
200
201