mirror of
				https://github.com/glfw/glfw.git
				synced 2025-11-04 06:15:07 +00:00 
			
		
		
		
	Add glfwGetError
Related to #970. If you have opinions on the design or implementation of this function, please come join us in #970 before it is frozen for release.
This commit is contained in:
		
							parent
							
								
									16ddfafeaa
								
							
						
					
					
						commit
						6350641f0a
					
				@ -122,6 +122,7 @@ information on what to include when reporting a bug.
 | 
			
		||||
 | 
			
		||||
## Changelog
 | 
			
		||||
 | 
			
		||||
- Added `glfwGetError` function for querying the last error code (#970)
 | 
			
		||||
- Added `glfwGetKeyScancode` function that allows retrieving platform dependent
 | 
			
		||||
  scancodes for keys (#830)
 | 
			
		||||
- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,7 @@ successfully initialized, and only from the main thread.
 | 
			
		||||
 | 
			
		||||
 - @ref glfwGetVersion
 | 
			
		||||
 - @ref glfwGetVersionString
 | 
			
		||||
 - @ref glfwGetError
 | 
			
		||||
 - @ref glfwSetErrorCallback
 | 
			
		||||
 - @ref glfwInitHint
 | 
			
		||||
 - @ref glfwInit
 | 
			
		||||
@ -131,9 +132,25 @@ not very helpful when trying to figure out _why_ the error occurred.  Other
 | 
			
		||||
functions have no return value reserved for errors, so error notification needs
 | 
			
		||||
a separate channel.  Finally, far from all GLFW functions have return values.
 | 
			
		||||
 | 
			
		||||
This is where the error callback comes in.  This callback is called whenever an
 | 
			
		||||
error occurs.  It is set with @ref glfwSetErrorCallback, a function that may be
 | 
			
		||||
called regardless of whether GLFW is initialized.
 | 
			
		||||
The last error code for the calling thread can be queried at any time with @ref
 | 
			
		||||
glfwGetError.
 | 
			
		||||
 | 
			
		||||
@code
 | 
			
		||||
int error = glfwGetError();
 | 
			
		||||
@endcode
 | 
			
		||||
 | 
			
		||||
If no error has occurred since the last call, @ref GLFW_NO_ERROR is returned.
 | 
			
		||||
The error is cleared before the function returns.
 | 
			
		||||
 | 
			
		||||
The error code indicates the general category of the error.  Some error codes,
 | 
			
		||||
such as @ref GLFW_NOT_INITIALIZED has only a single meaning, whereas others like
 | 
			
		||||
@ref GLFW_PLATFORM_ERROR are used for many different errors.
 | 
			
		||||
 | 
			
		||||
GLFW usually has much more information about the error than its general category
 | 
			
		||||
at the point where it occurred.  This is where the error callback comes in.
 | 
			
		||||
This callback is called whenever an error occurs.  It is set with @ref
 | 
			
		||||
glfwSetErrorCallback, a function that may be called regardless of whether GLFW
 | 
			
		||||
is initialized.
 | 
			
		||||
 | 
			
		||||
@code
 | 
			
		||||
glfwSetErrorCallback(error_callback);
 | 
			
		||||
@ -150,24 +167,23 @@ void error_callback(int error, const char* description)
 | 
			
		||||
}
 | 
			
		||||
@endcode
 | 
			
		||||
 | 
			
		||||
The error code indicates the general category of the error.  Some error codes,
 | 
			
		||||
such as @ref GLFW_NOT_INITIALIZED has only a single meaning, whereas others like
 | 
			
		||||
@ref GLFW_PLATFORM_ERROR are used for many different errors.
 | 
			
		||||
The error callback is called after the error code is set, so calling @ref
 | 
			
		||||
glfwGetError from within the error callback returns the same value as the
 | 
			
		||||
callback argument.
 | 
			
		||||
 | 
			
		||||
Reported errors are never fatal.  As long as GLFW was successfully initialized,
 | 
			
		||||
it will remain initialized and in a safe state until terminated regardless of
 | 
			
		||||
how many errors occur.  If an error occurs during initialization that causes
 | 
			
		||||
@ref glfwInit to fail, any part of the library that was initialized will be
 | 
			
		||||
safely terminated.
 | 
			
		||||
__Reported errors are never fatal.__  As long as GLFW was successfully
 | 
			
		||||
initialized, it will remain initialized and in a safe state until terminated
 | 
			
		||||
regardless of how many errors occur.  If an error occurs during initialization
 | 
			
		||||
that causes @ref glfwInit to fail, any part of the library that was initialized
 | 
			
		||||
will be safely terminated.
 | 
			
		||||
 | 
			
		||||
The description string is only valid until the error callback returns, as it may
 | 
			
		||||
have been generated specifically for that error.  This lets GLFW provide much
 | 
			
		||||
more specific error descriptions but means you must make a copy if you want to
 | 
			
		||||
keep the description string.
 | 
			
		||||
 | 
			
		||||
@note Relying on erroneous behavior is not forward compatible.  In other words,
 | 
			
		||||
do not rely on a currently invalid call to generate a specific error, as that
 | 
			
		||||
same call may in future versions generate a different error or become valid.
 | 
			
		||||
Do not rely on a currently invalid call to generate a specific error, as in the
 | 
			
		||||
future that same call may generate a different error or become valid.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@section coordinate_systems Coordinate systems
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,15 @@
 | 
			
		||||
 | 
			
		||||
@section news_33 New features in 3.3
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@subsection news_33_geterror Error query
 | 
			
		||||
 | 
			
		||||
GLFW now supports querying the last error code for the calling thread with @ref
 | 
			
		||||
glfwGetError.
 | 
			
		||||
 | 
			
		||||
@see @ref error_handling
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@subsection news_33_maximize Window maximization callback
 | 
			
		||||
 | 
			
		||||
GLFW now supports window maximization notifications with @ref
 | 
			
		||||
 | 
			
		||||
@ -546,6 +546,13 @@ extern "C" {
 | 
			
		||||
 *
 | 
			
		||||
 *  @ingroup init
 | 
			
		||||
 *  @{ */
 | 
			
		||||
/*! @brief No error has occurred.
 | 
			
		||||
 *
 | 
			
		||||
 *  No error has occurred.
 | 
			
		||||
 *
 | 
			
		||||
 *  @analysis Yay.
 | 
			
		||||
 */
 | 
			
		||||
#define GLFW_NO_ERROR               0
 | 
			
		||||
/*! @brief GLFW has not been initialized.
 | 
			
		||||
 *
 | 
			
		||||
 *  This occurs if a GLFW function was called that must not be called unless the
 | 
			
		||||
@ -1607,11 +1614,38 @@ GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
 | 
			
		||||
 */
 | 
			
		||||
GLFWAPI const char* glfwGetVersionString(void);
 | 
			
		||||
 | 
			
		||||
/*! @brief Returns and clears the last error for the calling thread.
 | 
			
		||||
 *
 | 
			
		||||
 *  This function returns and clears the [error code](@ref error) of the last
 | 
			
		||||
 *  error that occurred on the calling thread.  If no error has occurred since
 | 
			
		||||
 *  the last call, it returns @ref GLFW_NO_ERROR.
 | 
			
		||||
 *
 | 
			
		||||
 *  @return The last error code for the calling thread, or @ref GLFW_NO_ERROR.
 | 
			
		||||
 *
 | 
			
		||||
 *  @errors None.
 | 
			
		||||
 *
 | 
			
		||||
 *  @remark This function may be called before @ref glfwInit.
 | 
			
		||||
 *
 | 
			
		||||
 *  @thread_safety This function may be called from any thread.
 | 
			
		||||
 *
 | 
			
		||||
 *  @sa @ref error_handling
 | 
			
		||||
 *  @sa @ref glfwSetErrorCallback
 | 
			
		||||
 *
 | 
			
		||||
 *  @since Added in version 3.3.
 | 
			
		||||
 *
 | 
			
		||||
 *  @ingroup init
 | 
			
		||||
 */
 | 
			
		||||
GLFWAPI int glfwGetError(void);
 | 
			
		||||
 | 
			
		||||
/*! @brief Sets the error callback.
 | 
			
		||||
 *
 | 
			
		||||
 *  This function sets the error callback, which is called with an error code
 | 
			
		||||
 *  and a human-readable description each time a GLFW error occurs.
 | 
			
		||||
 *
 | 
			
		||||
 *  The error code is set before the callback is called.  Calling @ref
 | 
			
		||||
 *  glfwGetError from the error callback will return the same value as the error
 | 
			
		||||
 *  code argument.
 | 
			
		||||
 *
 | 
			
		||||
 *  The error callback is called on the thread where the error occurred.  If you
 | 
			
		||||
 *  are using GLFW from multiple threads, your error callback needs to be
 | 
			
		||||
 *  written accordingly.
 | 
			
		||||
@ -1634,6 +1668,7 @@ GLFWAPI const char* glfwGetVersionString(void);
 | 
			
		||||
 *  @thread_safety This function must only be called from the main thread.
 | 
			
		||||
 *
 | 
			
		||||
 *  @sa @ref error_handling
 | 
			
		||||
 *  @sa @ref glfwGetError
 | 
			
		||||
 *
 | 
			
		||||
 *  @since Added in version 3.0.
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										38
									
								
								src/init.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								src/init.c
									
									
									
									
									
								
							@ -43,6 +43,7 @@ _GLFWlibrary _glfw = { GLFW_FALSE };
 | 
			
		||||
// These are outside of _glfw so they can be used before initialization and
 | 
			
		||||
// after termination
 | 
			
		||||
//
 | 
			
		||||
static int _glfwErrorCode;
 | 
			
		||||
static GLFWerrorfun _glfwErrorCallback;
 | 
			
		||||
static _GLFWinitconfig _glfwInitHints =
 | 
			
		||||
{
 | 
			
		||||
@ -113,7 +114,11 @@ static void terminate(void)
 | 
			
		||||
    _glfwTerminateVulkan();
 | 
			
		||||
    _glfwPlatformTerminate();
 | 
			
		||||
 | 
			
		||||
    if (_glfwPlatformIsValidTls(&_glfw.error))
 | 
			
		||||
        _glfwErrorCode = (int) (intptr_t) _glfwPlatformGetTls(&_glfw.error);
 | 
			
		||||
 | 
			
		||||
    _glfwPlatformDestroyTls(&_glfw.context);
 | 
			
		||||
    _glfwPlatformDestroyTls(&_glfw.error);
 | 
			
		||||
 | 
			
		||||
    memset(&_glfw, 0, sizeof(_glfw));
 | 
			
		||||
}
 | 
			
		||||
@ -125,6 +130,11 @@ static void terminate(void)
 | 
			
		||||
 | 
			
		||||
void _glfwInputError(int error, const char* format, ...)
 | 
			
		||||
{
 | 
			
		||||
    if (_glfw.initialized)
 | 
			
		||||
        _glfwPlatformSetTls(&_glfw.error, (void*) (intptr_t) error);
 | 
			
		||||
    else
 | 
			
		||||
        _glfwErrorCode = error;
 | 
			
		||||
 | 
			
		||||
    if (_glfwErrorCallback)
 | 
			
		||||
    {
 | 
			
		||||
        char buffer[8192];
 | 
			
		||||
@ -164,15 +174,19 @@ GLFWAPI int glfwInit(void)
 | 
			
		||||
    memset(&_glfw, 0, sizeof(_glfw));
 | 
			
		||||
    _glfw.hints.init = _glfwInitHints;
 | 
			
		||||
 | 
			
		||||
    if (!_glfwPlatformCreateTls(&_glfw.context))
 | 
			
		||||
        return GLFW_FALSE;
 | 
			
		||||
 | 
			
		||||
    if (!_glfwPlatformInit())
 | 
			
		||||
    {
 | 
			
		||||
        terminate();
 | 
			
		||||
        return GLFW_FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!_glfwPlatformCreateTls(&_glfw.error))
 | 
			
		||||
        return GLFW_FALSE;
 | 
			
		||||
    if (!_glfwPlatformCreateTls(&_glfw.context))
 | 
			
		||||
        return GLFW_FALSE;
 | 
			
		||||
 | 
			
		||||
    _glfwPlatformSetTls(&_glfw.error, (void*) (intptr_t) _glfwErrorCode);
 | 
			
		||||
 | 
			
		||||
    _glfw.initialized = GLFW_TRUE;
 | 
			
		||||
    _glfw.timer.offset = _glfwPlatformGetTimerValue();
 | 
			
		||||
 | 
			
		||||
@ -223,6 +237,24 @@ GLFWAPI const char* glfwGetVersionString(void)
 | 
			
		||||
    return _glfwPlatformGetVersionString();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLFWAPI int glfwGetError(void)
 | 
			
		||||
{
 | 
			
		||||
    int error;
 | 
			
		||||
 | 
			
		||||
    if (_glfw.initialized)
 | 
			
		||||
    {
 | 
			
		||||
        error = (int) (intptr_t) _glfwPlatformGetTls(&_glfw.error);
 | 
			
		||||
        _glfwPlatformSetTls(&_glfw.error, (intptr_t) GLFW_NO_ERROR);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        error = _glfwErrorCode;
 | 
			
		||||
        _glfwErrorCode = GLFW_NO_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
 | 
			
		||||
{
 | 
			
		||||
    _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
 | 
			
		||||
 | 
			
		||||
@ -517,6 +517,7 @@ struct _GLFWlibrary
 | 
			
		||||
 | 
			
		||||
    _GLFWjoystick       joysticks[GLFW_JOYSTICK_LAST + 1];
 | 
			
		||||
 | 
			
		||||
    _GLFWtls            error;
 | 
			
		||||
    _GLFWtls            context;
 | 
			
		||||
 | 
			
		||||
    struct {
 | 
			
		||||
@ -653,6 +654,7 @@ GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
 | 
			
		||||
void _glfwPlatformDestroyTls(_GLFWtls* tls);
 | 
			
		||||
void* _glfwPlatformGetTls(_GLFWtls* tls);
 | 
			
		||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value);
 | 
			
		||||
GLFWbool _glfwPlatformIsValidTls(_GLFWtls* tls);
 | 
			
		||||
 | 
			
		||||
/*! @} */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,6 @@ GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
 | 
			
		||||
 | 
			
		||||
void _glfwPlatformDestroyTls(_GLFWtls* tls)
 | 
			
		||||
{
 | 
			
		||||
    assert(tls->posix.allocated == GLFW_TRUE);
 | 
			
		||||
    if (tls->posix.allocated)
 | 
			
		||||
        pthread_key_delete(tls->posix.key);
 | 
			
		||||
    memset(tls, 0, sizeof(_GLFWtls));
 | 
			
		||||
@ -70,3 +69,8 @@ void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
 | 
			
		||||
    pthread_setspecific(tls->posix.key, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLFWbool _glfwPlatformIsValidTls(_GLFWtls* tls)
 | 
			
		||||
{
 | 
			
		||||
    return tls->posix.allocated;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,6 @@ GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
 | 
			
		||||
 | 
			
		||||
void _glfwPlatformDestroyTls(_GLFWtls* tls)
 | 
			
		||||
{
 | 
			
		||||
    assert(tls->win32.allocated == GLFW_TRUE);
 | 
			
		||||
    if (tls->win32.allocated)
 | 
			
		||||
        TlsFree(tls->win32.index);
 | 
			
		||||
    memset(tls, 0, sizeof(_GLFWtls));
 | 
			
		||||
@ -70,3 +69,8 @@ void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
 | 
			
		||||
    TlsSetValue(tls->win32.index, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLFWbool _glfwPlatformIsValidTls(_GLFWtls* tls)
 | 
			
		||||
{
 | 
			
		||||
    return tls->win32.allocated;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user