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
 | 
					## Changelog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Added `glfwGetError` function for querying the last error code (#970)
 | 
				
			||||||
- Added `glfwGetKeyScancode` function that allows retrieving platform dependent
 | 
					- Added `glfwGetKeyScancode` function that allows retrieving platform dependent
 | 
				
			||||||
  scancodes for keys (#830)
 | 
					  scancodes for keys (#830)
 | 
				
			||||||
- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
 | 
					- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
 | 
				
			||||||
 | 
				
			|||||||
@ -30,6 +30,7 @@ successfully initialized, and only from the main thread.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 - @ref glfwGetVersion
 | 
					 - @ref glfwGetVersion
 | 
				
			||||||
 - @ref glfwGetVersionString
 | 
					 - @ref glfwGetVersionString
 | 
				
			||||||
 | 
					 - @ref glfwGetError
 | 
				
			||||||
 - @ref glfwSetErrorCallback
 | 
					 - @ref glfwSetErrorCallback
 | 
				
			||||||
 - @ref glfwInitHint
 | 
					 - @ref glfwInitHint
 | 
				
			||||||
 - @ref glfwInit
 | 
					 - @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
 | 
					functions have no return value reserved for errors, so error notification needs
 | 
				
			||||||
a separate channel.  Finally, far from all GLFW functions have return values.
 | 
					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
 | 
					The last error code for the calling thread can be queried at any time with @ref
 | 
				
			||||||
error occurs.  It is set with @ref glfwSetErrorCallback, a function that may be
 | 
					glfwGetError.
 | 
				
			||||||
called regardless of whether GLFW is initialized.
 | 
					
 | 
				
			||||||
 | 
					@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
 | 
					@code
 | 
				
			||||||
glfwSetErrorCallback(error_callback);
 | 
					glfwSetErrorCallback(error_callback);
 | 
				
			||||||
@ -150,24 +167,23 @@ void error_callback(int error, const char* description)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
@endcode
 | 
					@endcode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The error code indicates the general category of the error.  Some error codes,
 | 
					The error callback is called after the error code is set, so calling @ref
 | 
				
			||||||
such as @ref GLFW_NOT_INITIALIZED has only a single meaning, whereas others like
 | 
					glfwGetError from within the error callback returns the same value as the
 | 
				
			||||||
@ref GLFW_PLATFORM_ERROR are used for many different errors.
 | 
					callback argument.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Reported errors are never fatal.  As long as GLFW was successfully initialized,
 | 
					__Reported errors are never fatal.__  As long as GLFW was successfully
 | 
				
			||||||
it will remain initialized and in a safe state until terminated regardless of
 | 
					initialized, it will remain initialized and in a safe state until terminated
 | 
				
			||||||
how many errors occur.  If an error occurs during initialization that causes
 | 
					regardless of how many errors occur.  If an error occurs during initialization
 | 
				
			||||||
@ref glfwInit to fail, any part of the library that was initialized will be
 | 
					that causes @ref glfwInit to fail, any part of the library that was initialized
 | 
				
			||||||
safely terminated.
 | 
					will be safely terminated.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The description string is only valid until the error callback returns, as it may
 | 
					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
 | 
					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
 | 
					more specific error descriptions but means you must make a copy if you want to
 | 
				
			||||||
keep the description string.
 | 
					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 in the
 | 
				
			||||||
do not rely on a currently invalid call to generate a specific error, as that
 | 
					future that same call may generate a different error or become valid.
 | 
				
			||||||
same call may in future versions generate a different error or become valid.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@section coordinate_systems Coordinate systems
 | 
					@section coordinate_systems Coordinate systems
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,15 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@section news_33 New features in 3.3
 | 
					@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
 | 
					@subsection news_33_maximize Window maximization callback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GLFW now supports window maximization notifications with @ref
 | 
					GLFW now supports window maximization notifications with @ref
 | 
				
			||||||
 | 
				
			|||||||
@ -546,6 +546,13 @@ extern "C" {
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @ingroup init
 | 
					 *  @ingroup init
 | 
				
			||||||
 *  @{ */
 | 
					 *  @{ */
 | 
				
			||||||
 | 
					/*! @brief No error has occurred.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  No error has occurred.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *  @analysis Yay.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define GLFW_NO_ERROR               0
 | 
				
			||||||
/*! @brief GLFW has not been initialized.
 | 
					/*! @brief GLFW has not been initialized.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  This occurs if a GLFW function was called that must not be called unless the
 | 
					 *  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);
 | 
					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.
 | 
					/*! @brief Sets the error callback.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  This function sets the error callback, which is called with an error code
 | 
					 *  This function sets the error callback, which is called with an error code
 | 
				
			||||||
 *  and a human-readable description each time a GLFW error occurs.
 | 
					 *  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
 | 
					 *  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
 | 
					 *  are using GLFW from multiple threads, your error callback needs to be
 | 
				
			||||||
 *  written accordingly.
 | 
					 *  written accordingly.
 | 
				
			||||||
@ -1634,6 +1668,7 @@ GLFWAPI const char* glfwGetVersionString(void);
 | 
				
			|||||||
 *  @thread_safety This function must only be called from the main thread.
 | 
					 *  @thread_safety This function must only be called from the main thread.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @sa @ref error_handling
 | 
					 *  @sa @ref error_handling
 | 
				
			||||||
 | 
					 *  @sa @ref glfwGetError
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  @since Added in version 3.0.
 | 
					 *  @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
 | 
					// These are outside of _glfw so they can be used before initialization and
 | 
				
			||||||
// after termination
 | 
					// after termination
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					static int _glfwErrorCode;
 | 
				
			||||||
static GLFWerrorfun _glfwErrorCallback;
 | 
					static GLFWerrorfun _glfwErrorCallback;
 | 
				
			||||||
static _GLFWinitconfig _glfwInitHints =
 | 
					static _GLFWinitconfig _glfwInitHints =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -113,7 +114,11 @@ static void terminate(void)
 | 
				
			|||||||
    _glfwTerminateVulkan();
 | 
					    _glfwTerminateVulkan();
 | 
				
			||||||
    _glfwPlatformTerminate();
 | 
					    _glfwPlatformTerminate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_glfwPlatformIsValidTls(&_glfw.error))
 | 
				
			||||||
 | 
					        _glfwErrorCode = (int) (intptr_t) _glfwPlatformGetTls(&_glfw.error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _glfwPlatformDestroyTls(&_glfw.context);
 | 
					    _glfwPlatformDestroyTls(&_glfw.context);
 | 
				
			||||||
 | 
					    _glfwPlatformDestroyTls(&_glfw.error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset(&_glfw, 0, sizeof(_glfw));
 | 
					    memset(&_glfw, 0, sizeof(_glfw));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -125,6 +130,11 @@ static void terminate(void)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void _glfwInputError(int error, const char* format, ...)
 | 
					void _glfwInputError(int error, const char* format, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    if (_glfw.initialized)
 | 
				
			||||||
 | 
					        _glfwPlatformSetTls(&_glfw.error, (void*) (intptr_t) error);
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        _glfwErrorCode = error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (_glfwErrorCallback)
 | 
					    if (_glfwErrorCallback)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        char buffer[8192];
 | 
					        char buffer[8192];
 | 
				
			||||||
@ -164,15 +174,19 @@ GLFWAPI int glfwInit(void)
 | 
				
			|||||||
    memset(&_glfw, 0, sizeof(_glfw));
 | 
					    memset(&_glfw, 0, sizeof(_glfw));
 | 
				
			||||||
    _glfw.hints.init = _glfwInitHints;
 | 
					    _glfw.hints.init = _glfwInitHints;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!_glfwPlatformCreateTls(&_glfw.context))
 | 
					 | 
				
			||||||
        return GLFW_FALSE;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!_glfwPlatformInit())
 | 
					    if (!_glfwPlatformInit())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        terminate();
 | 
					        terminate();
 | 
				
			||||||
        return GLFW_FALSE;
 | 
					        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.initialized = GLFW_TRUE;
 | 
				
			||||||
    _glfw.timer.offset = _glfwPlatformGetTimerValue();
 | 
					    _glfw.timer.offset = _glfwPlatformGetTimerValue();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -223,6 +237,24 @@ GLFWAPI const char* glfwGetVersionString(void)
 | 
				
			|||||||
    return _glfwPlatformGetVersionString();
 | 
					    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)
 | 
					GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
 | 
					    _GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
 | 
				
			||||||
 | 
				
			|||||||
@ -517,6 +517,7 @@ struct _GLFWlibrary
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    _GLFWjoystick       joysticks[GLFW_JOYSTICK_LAST + 1];
 | 
					    _GLFWjoystick       joysticks[GLFW_JOYSTICK_LAST + 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _GLFWtls            error;
 | 
				
			||||||
    _GLFWtls            context;
 | 
					    _GLFWtls            context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct {
 | 
					    struct {
 | 
				
			||||||
@ -653,6 +654,7 @@ GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
 | 
				
			|||||||
void _glfwPlatformDestroyTls(_GLFWtls* tls);
 | 
					void _glfwPlatformDestroyTls(_GLFWtls* tls);
 | 
				
			||||||
void* _glfwPlatformGetTls(_GLFWtls* tls);
 | 
					void* _glfwPlatformGetTls(_GLFWtls* tls);
 | 
				
			||||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value);
 | 
					void _glfwPlatformSetTls(_GLFWtls* tls, void* value);
 | 
				
			||||||
 | 
					GLFWbool _glfwPlatformIsValidTls(_GLFWtls* tls);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*! @} */
 | 
					/*! @} */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -52,7 +52,6 @@ GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void _glfwPlatformDestroyTls(_GLFWtls* tls)
 | 
					void _glfwPlatformDestroyTls(_GLFWtls* tls)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(tls->posix.allocated == GLFW_TRUE);
 | 
					 | 
				
			||||||
    if (tls->posix.allocated)
 | 
					    if (tls->posix.allocated)
 | 
				
			||||||
        pthread_key_delete(tls->posix.key);
 | 
					        pthread_key_delete(tls->posix.key);
 | 
				
			||||||
    memset(tls, 0, sizeof(_GLFWtls));
 | 
					    memset(tls, 0, sizeof(_GLFWtls));
 | 
				
			||||||
@ -70,3 +69,8 @@ void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
 | 
				
			|||||||
    pthread_setspecific(tls->posix.key, 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)
 | 
					void _glfwPlatformDestroyTls(_GLFWtls* tls)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    assert(tls->win32.allocated == GLFW_TRUE);
 | 
					 | 
				
			||||||
    if (tls->win32.allocated)
 | 
					    if (tls->win32.allocated)
 | 
				
			||||||
        TlsFree(tls->win32.index);
 | 
					        TlsFree(tls->win32.index);
 | 
				
			||||||
    memset(tls, 0, sizeof(_GLFWtls));
 | 
					    memset(tls, 0, sizeof(_GLFWtls));
 | 
				
			||||||
@ -70,3 +69,8 @@ void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
 | 
				
			|||||||
    TlsSetValue(tls->win32.index, value);
 | 
					    TlsSetValue(tls->win32.index, value);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GLFWbool _glfwPlatformIsValidTls(_GLFWtls* tls)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return tls->win32.allocated;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user