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//
42GLFWbool _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//
48static GLFWerrorfun _glfwErrorCallback = NULL;
49
50
51// Returns a generic string representation of the specified error
52//
53static 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
87void _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
120GLFWAPI 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
144GLFWAPI 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
178GLFWAPI 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
190GLFWAPI const char* glfwGetVersionString(void)
191{
192 return _glfwPlatformGetVersionString();
193}
194
195GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
196{
197 _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
198 return cbfun;
199}
200
201