Merge remote-tracking branch 'glfw/master'

This commit is contained in:
ocornut 2015-12-25 21:12:56 +01:00
commit af3f4652ae
58 changed files with 969 additions and 888 deletions

6
.gitignore vendored
View File

@ -34,16 +34,16 @@ src/glfw3ConfigVersion.cmake
# Compiled binaries # Compiled binaries
src/libglfw.so src/libglfw.so
src/libglfw.so.3 src/libglfw.so.3
src/libglfw.so.3.0 src/libglfw.so.3.2
src/libglfw.dylib src/libglfw.dylib
src/libglfw.dylib src/libglfw.dylib
src/libglfw.3.dylib src/libglfw.3.dylib
src/libglfw.3.0.dylib src/libglfw.3.2.dylib
src/libglfw3.a src/libglfw3.a
src/glfw3.lib src/glfw3.lib
src/glfw3.dll src/glfw3.dll
src/glfw3dll.lib src/glfw3dll.lib
src/glfw3dll.a src/libglfw3dll.a
examples/*.app examples/*.app
examples/*.exe examples/*.exe
examples/boing examples/boing

View File

@ -72,17 +72,7 @@ endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Set compiler specific flags # Set compiler specific flags
#-------------------------------------------------------------------- #--------------------------------------------------------------------
if (UNIX)
add_definitions(-Wall)
if (BUILD_SHARED_LIBS)
add_definitions(-fvisibility=hidden)
endif()
endif()
if (MSVC) if (MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL) if (NOT USE_MSVC_RUNTIME_LIBRARY_DLL)
foreach (flag CMAKE_C_FLAGS foreach (flag CMAKE_C_FLAGS
CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG
@ -125,12 +115,6 @@ if (MINGW)
if (_GLFW_HAS_64ASLR) if (_GLFW_HAS_64ASLR)
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--high-entropy-va ${CMAKE_SHARED_LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--high-entropy-va ${CMAKE_SHARED_LINKER_FLAGS}")
endif() endif()
# HACK: When building on MinGW, WINVER and UNICODE need to be defined before
# the inclusion of stddef.h (by glfw3.h), which is itself included before
# win32_platform.h. We define them here until a saner solution can be found
# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack.
add_definitions(-DUNICODE -DWINVER=0x0501)
endif() endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
@ -371,16 +355,6 @@ foreach(arg ${glfw_PKG_LIBS})
set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} ${arg}") set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} ${arg}")
endforeach() endforeach()
#--------------------------------------------------------------------
# Choose library output name
#--------------------------------------------------------------------
if (BUILD_SHARED_LIBS AND UNIX)
# On Unix-like systems, shared libraries can use the soname system.
set(GLFW_LIB_NAME glfw)
else()
set(GLFW_LIB_NAME glfw3)
endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Create generated files # Create generated files
#-------------------------------------------------------------------- #--------------------------------------------------------------------

View File

@ -72,17 +72,29 @@ used by the tests and examples and are not required to build the library.
- Added `GLFW_CONTEXT_NO_ERROR` context hint for `GL_KHR_no_error` support - Added `GLFW_CONTEXT_NO_ERROR` context hint for `GL_KHR_no_error` support
- Added `GLFW_TRUE` and `GLFW_FALSE` as client API independent boolean values - Added `GLFW_TRUE` and `GLFW_FALSE` as client API independent boolean values
- Added `glfwGetGLXWindow` to query the `GLXWindow` of a window - Added `glfwGetGLXWindow` to query the `GLXWindow` of a window
- Added icons to examples on Windows and OS X
- Relaxed rules for native access header macros - Relaxed rules for native access header macros
- Removed dependency on external OpenGL or OpenGL ES headers - Removed dependency on external OpenGL or OpenGL ES headers
- Removed `_GLFW_USE_OPENGL`, `_GLFW_USE_GLESV1` and `_GLFW_USE_GLESV2`
configuration macros
- [Win32] Added support for Windows 8.1 per-monitor DPI - [Win32] Added support for Windows 8.1 per-monitor DPI
- [Win32] Bugfix: Window creation would segfault if video mode setting required
the system to be restarted
- [Win32] Bugfix: MinGW import library lacked the `lib` prefix
- [Win32] Bugfix: Monitor connection and disconnection events were not reported
when no windows existed
- [Cocoa] Removed support for OS X 10.6 - [Cocoa] Removed support for OS X 10.6
- [Cocoa] Bugfix: Full screen windows on secondary monitors were mispositioned
- [X11] Bugfix: Monitor connection and disconnection events were not reported - [X11] Bugfix: Monitor connection and disconnection events were not reported
- [X11] Bugfix: Decoding of UTF-8 text from XIM could continue past the end - [X11] Bugfix: Decoding of UTF-8 text from XIM could continue past the end
- [POSIX] Bugfix: An unrelated TLS key could be deleted by `glfwTerminate` - [POSIX] Bugfix: An unrelated TLS key could be deleted by `glfwTerminate`
- [WGL] Changed extension loading to only be performed once
- [WGL] Removed dependency on external WGL headers - [WGL] Removed dependency on external WGL headers
- [GLX] Replaced legacy renderable with `GLXWindow` - [GLX] Replaced legacy renderable with `GLXWindow`
- [GLX] Removed dependency on external GLX headers - [GLX] Removed dependency on external GLX headers
- [GLX] Bugfix: NetBSD does not provide `libGL.so.1` - [GLX] Bugfix: NetBSD does not provide `libGL.so.1`
- [EGL] Added `_GLFW_USE_EGLPLATFORM_H` configuration macro for controlling
whether to use an existing `EGL/eglplatform.h` header
- [EGL] Removed dependency on external EGL headers - [EGL] Removed dependency on external EGL headers

View File

@ -166,9 +166,17 @@ available on all supported platforms. Some of these are de facto standards
among projects using CMake and so have no `GLFW_` prefix. among projects using CMake and so have no `GLFW_` prefix.
If you are using the GUI version of CMake, these are listed and can be changed If you are using the GUI version of CMake, these are listed and can be changed
from there. If you are using the command-line version, use the `ccmake` tool. from there. If you are using the command-line versionof CMake you can use the
Some package systems like Ubuntu and other distributions based on Debian `ccmake` ncurses GUI to set options. Some package systems like Ubuntu and other
GNU/Linux have this tool in a separate `cmake-curses-gui` package. distributions based on Debian GNU/Linux have this tool in a separate
`cmake-curses-gui` package.
Finally, if you don't want to use any GUI, you can set options from the `cmake`
command-line with the `-D` flag.
@code{.sh}
cmake -DBUILD_SHARED_LIBS=ON .
@endcode
@subsubsection compile_options_shared Shared CMake options @subsubsection compile_options_shared Shared CMake options
@ -261,7 +269,7 @@ configurations and to create contexts. The options are:
Wayland and Mir both require the EGL backend. Wayland and Mir both require the EGL backend.
If you are building GLFW as a shared library / dynamic library / DLL then you If you are building GLFW as a shared library / dynamic library / DLL then you
must also define `_GLFW_BUILD_DLL`. Otherwise, you may not define it. must also define `_GLFW_BUILD_DLL`. Otherwise, you must not define it.
If you are using the X11 window creation API, support for the following X11 If you are using the X11 window creation API, support for the following X11
extensions can be enabled: extensions can be enabled:

View File

@ -87,7 +87,7 @@ disabled with a [compile-time option](@ref compile_options_osx).
You can disable context creation by setting the You can disable context creation by setting the
[GLFW_CLIENT_API](@ref window_hints_ctx) hint to `GLFW_NO_API`. Windows without [GLFW_CLIENT_API](@ref window_hints_ctx) hint to `GLFW_NO_API`. Windows without
contexts may not be passed to @ref glfwMakeContextCurrent or @ref contexts must not be passed to @ref glfwMakeContextCurrent or @ref
glfwSwapBuffers. glfwSwapBuffers.

View File

@ -184,7 +184,7 @@ releases.
@subsection reentrancy Reentrancy @subsection reentrancy Reentrancy
GLFW event processing and object creation and destruction are not reentrant. GLFW event processing and object creation and destruction are not reentrant.
This means that the following functions may not be called from any callback This means that the following functions must not be called from any callback
function: function:
- @ref glfwCreateWindow - @ref glfwCreateWindow
@ -202,7 +202,7 @@ functions not on this list will not be made non-reentrant.
@subsection thread_safety Thread safety @subsection thread_safety Thread safety
Most GLFW functions may only be called from the main thread, but some may be Most GLFW functions must only be called from the main thread, but some may be
called from any thread. However, no GLFW function may be called from any thread called from any thread. However, no GLFW function may be called from any thread
but the main thread until GLFW has been successfully initialized, including but the main thread until GLFW has been successfully initialized, including
functions that may called before initialization. functions that may called before initialization.

View File

@ -67,16 +67,22 @@ glfwSetMonitorCallback(monitor_callback);
@endcode @endcode
The callback function receives the handle for the monitor that has been The callback function receives the handle for the monitor that has been
connected or disconnected and a monitor action. connected or disconnected and the event that occurred.
@code @code
void monitor_callback(GLFWmonitor* monitor, int event) void monitor_callback(GLFWmonitor* monitor, int event)
{ {
if (event == GLFW_CONNECTED)
{
// The monitor was connected
}
else if (event == GLFW_DISCONNECTED)
{
// The monitor was disconnected
}
} }
@endcode @endcode
The action is one of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
@section monitor_properties Monitor properties @section monitor_properties Monitor properties

View File

@ -53,7 +53,7 @@ TinyCThread.
However, GLFW 3 has better support for _use from multiple threads_ than GLFW However, GLFW 3 has better support for _use from multiple threads_ than GLFW
2 had. Contexts can be made current on any thread, although only a single 2 had. Contexts can be made current on any thread, although only a single
thread at a time, and the documentation explicitly states which functions may be thread at a time, and the documentation explicitly states which functions may be
used from any thread and which may only be used from the main thread. used from any thread and which must only be used from the main thread.
@par Removed functions @par Removed functions
`glfwSleep`, `glfwCreateThread`, `glfwDestroyThread`, `glfwWaitThread`, `glfwSleep`, `glfwCreateThread`, `glfwDestroyThread`, `glfwWaitThread`,
@ -416,7 +416,7 @@ these hotkeys to function even when running in full screen mode.
GLFW 3 does not register @ref glfwTerminate with `atexit` at initialization, GLFW 3 does not register @ref glfwTerminate with `atexit` at initialization,
because `exit` calls registered functions from the calling thread and while it because `exit` calls registered functions from the calling thread and while it
is permitted to call `exit` from any thread, @ref glfwTerminate may only be is permitted to call `exit` from any thread, @ref glfwTerminate must only be
called from the main thread. called from the main thread.
To release all resources allocated by GLFW, you should call @ref glfwTerminate To release all resources allocated by GLFW, you should call @ref glfwTerminate

View File

@ -252,7 +252,7 @@ compatible with 1.x.
`GLFW_OPENGL_FORWARD_COMPAT` specifies whether the OpenGL context should be `GLFW_OPENGL_FORWARD_COMPAT` specifies whether the OpenGL context should be
forward-compatible, i.e. one where all functionality deprecated in the requested forward-compatible, i.e. one where all functionality deprecated in the requested
version of OpenGL is removed. This may only be used if the requested OpenGL version of OpenGL is removed. This must only be used if the requested OpenGL
version is 3.0 or above. If OpenGL ES is requested, this hint is ignored. version is 3.0 or above. If OpenGL ES is requested, this hint is ignored.
@par @par

View File

@ -8,6 +8,10 @@ else()
link_libraries(${glfw_LIBRARIES}) link_libraries(${glfw_LIBRARIES})
endif() endif()
if (MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
include_directories("${GLFW_SOURCE_DIR}/include" include_directories("${GLFW_SOURCE_DIR}/include"
"${GLFW_SOURCE_DIR}/deps") "${GLFW_SOURCE_DIR}/deps")

View File

@ -173,7 +173,7 @@ extern "C" {
* version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW * version of the GLFW library. _GLFW_BUILD_DLL is defined by the GLFW
* configuration header when compiling the DLL version of the library. * configuration header when compiling the DLL version of the library.
*/ */
#error "You may not have both GLFW_DLL and _GLFW_BUILD_DLL defined" #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined"
#endif #endif
/* GLFWAPI is used to declare public API functions for export /* GLFWAPI is used to declare public API functions for export
@ -494,7 +494,7 @@ extern "C" {
* @{ */ * @{ */
/*! @brief GLFW has not been initialized. /*! @brief GLFW has not been initialized.
* *
* This occurs if a GLFW function was called that may not be called unless the * This occurs if a GLFW function was called that must not be called unless the
* library is [initialized](@ref intro_init). * library is [initialized](@ref intro_init).
* *
* @par Analysis * @par Analysis
@ -742,6 +742,8 @@ extern "C" {
* @sa @ref context_glext * @sa @ref context_glext
* @sa glfwGetProcAddress * @sa glfwGetProcAddress
* *
* @since Added in GLFW 3.0.
*
* @ingroup context * @ingroup context
*/ */
typedef void (*GLFWglproc)(void); typedef void (*GLFWglproc)(void);
@ -752,6 +754,8 @@ typedef void (*GLFWglproc)(void);
* *
* @see @ref monitor_object * @see @ref monitor_object
* *
* @since Added in GLFW 3.0.
*
* @ingroup monitor * @ingroup monitor
*/ */
typedef struct GLFWmonitor GLFWmonitor; typedef struct GLFWmonitor GLFWmonitor;
@ -762,6 +766,8 @@ typedef struct GLFWmonitor GLFWmonitor;
* *
* @see @ref window_object * @see @ref window_object
* *
* @since Added in GLFW 3.0.
*
* @ingroup window * @ingroup window
*/ */
typedef struct GLFWwindow GLFWwindow; typedef struct GLFWwindow GLFWwindow;
@ -772,6 +778,8 @@ typedef struct GLFWwindow GLFWwindow;
* *
* @see @ref cursor_object * @see @ref cursor_object
* *
* @since Added in GLFW 3.1.
*
* @ingroup cursor * @ingroup cursor
*/ */
typedef struct GLFWcursor GLFWcursor; typedef struct GLFWcursor GLFWcursor;
@ -786,6 +794,8 @@ typedef struct GLFWcursor GLFWcursor;
* @sa @ref error_handling * @sa @ref error_handling
* @sa glfwSetErrorCallback * @sa glfwSetErrorCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup init * @ingroup init
*/ */
typedef void (* GLFWerrorfun)(int,const char*); typedef void (* GLFWerrorfun)(int,const char*);
@ -803,6 +813,8 @@ typedef void (* GLFWerrorfun)(int,const char*);
* @sa @ref window_pos * @sa @ref window_pos
* @sa glfwSetWindowPosCallback * @sa glfwSetWindowPosCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int); typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
@ -818,6 +830,8 @@ typedef void (* GLFWwindowposfun)(GLFWwindow*,int,int);
* @sa @ref window_size * @sa @ref window_size
* @sa glfwSetWindowSizeCallback * @sa glfwSetWindowSizeCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int); typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);
@ -831,6 +845,8 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow*,int,int);
* @sa @ref window_close * @sa @ref window_close
* @sa glfwSetWindowCloseCallback * @sa glfwSetWindowCloseCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowclosefun)(GLFWwindow*); typedef void (* GLFWwindowclosefun)(GLFWwindow*);
@ -844,6 +860,8 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow*);
* @sa @ref window_refresh * @sa @ref window_refresh
* @sa glfwSetWindowRefreshCallback * @sa glfwSetWindowRefreshCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowrefreshfun)(GLFWwindow*); typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
@ -859,6 +877,8 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow*);
* @sa @ref window_focus * @sa @ref window_focus
* @sa glfwSetWindowFocusCallback * @sa glfwSetWindowFocusCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int); typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
@ -875,6 +895,8 @@ typedef void (* GLFWwindowfocusfun)(GLFWwindow*,int);
* @sa @ref window_iconify * @sa @ref window_iconify
* @sa glfwSetWindowIconifyCallback * @sa glfwSetWindowIconifyCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int); typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
@ -891,6 +913,8 @@ typedef void (* GLFWwindowiconifyfun)(GLFWwindow*,int);
* @sa @ref window_fbsize * @sa @ref window_fbsize
* @sa glfwSetFramebufferSizeCallback * @sa glfwSetFramebufferSizeCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup window * @ingroup window
*/ */
typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int); typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);
@ -909,6 +933,8 @@ typedef void (* GLFWframebuffersizefun)(GLFWwindow*,int,int);
* @sa @ref input_mouse_button * @sa @ref input_mouse_button
* @sa glfwSetMouseButtonCallback * @sa glfwSetMouseButtonCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int); typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
@ -924,6 +950,8 @@ typedef void (* GLFWmousebuttonfun)(GLFWwindow*,int,int,int);
* @sa @ref cursor_pos * @sa @ref cursor_pos
* @sa glfwSetCursorPosCallback * @sa glfwSetCursorPosCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double); typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
@ -939,6 +967,8 @@ typedef void (* GLFWcursorposfun)(GLFWwindow*,double,double);
* @sa @ref cursor_enter * @sa @ref cursor_enter
* @sa glfwSetCursorEnterCallback * @sa glfwSetCursorEnterCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWcursorenterfun)(GLFWwindow*,int); typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);
@ -954,6 +984,8 @@ typedef void (* GLFWcursorenterfun)(GLFWwindow*,int);
* @sa @ref scrolling * @sa @ref scrolling
* @sa glfwSetScrollCallback * @sa glfwSetScrollCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWscrollfun)(GLFWwindow*,double,double); typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
@ -972,6 +1004,8 @@ typedef void (* GLFWscrollfun)(GLFWwindow*,double,double);
* @sa @ref input_key * @sa @ref input_key
* @sa glfwSetKeyCallback * @sa glfwSetKeyCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int); typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);
@ -986,6 +1020,8 @@ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);
* @sa @ref input_char * @sa @ref input_char
* @sa glfwSetCharCallback * @sa glfwSetCharCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);
@ -1005,6 +1041,8 @@ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);
* @sa @ref input_char * @sa @ref input_char
* @sa glfwSetCharModsCallback * @sa glfwSetCharModsCallback
* *
* @since Added in GLFW 3.1.
*
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int); typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);
@ -1020,6 +1058,8 @@ typedef void (* GLFWcharmodsfun)(GLFWwindow*,unsigned int,int);
* @sa @ref path_drop * @sa @ref path_drop
* @sa glfwSetDropCallback * @sa glfwSetDropCallback
* *
* @since Added in GLFW 3.1.
*
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);
@ -1034,6 +1074,8 @@ typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);
* @sa @ref monitor_event * @sa @ref monitor_event
* @sa glfwSetMonitorCallback * @sa glfwSetMonitorCallback
* *
* @since Added in GLFW 3.0.
*
* @ingroup monitor * @ingroup monitor
*/ */
typedef void (* GLFWmonitorfun)(GLFWmonitor*,int); typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
@ -1045,6 +1087,8 @@ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
* @sa @ref monitor_modes * @sa @ref monitor_modes
* @sa glfwGetVideoMode glfwGetVideoModes * @sa glfwGetVideoMode glfwGetVideoModes
* *
* @since Added in GLFW 3.0.
*
* @ingroup monitor * @ingroup monitor
*/ */
typedef struct GLFWvidmode typedef struct GLFWvidmode
@ -1076,6 +1120,8 @@ typedef struct GLFWvidmode
* @sa @ref monitor_gamma * @sa @ref monitor_gamma
* @sa glfwGetGammaRamp glfwSetGammaRamp * @sa glfwGetGammaRamp glfwSetGammaRamp
* *
* @since Added in GLFW 3.0.
*
* @ingroup monitor * @ingroup monitor
*/ */
typedef struct GLFWgammaramp typedef struct GLFWgammaramp
@ -1097,6 +1143,8 @@ typedef struct GLFWgammaramp
/*! @brief Image data. /*! @brief Image data.
* *
* @sa @ref cursor_custom * @sa @ref cursor_custom
*
* @since Added in GLFW 3.1.
*/ */
typedef struct GLFWimage typedef struct GLFWimage
{ {
@ -1138,7 +1186,7 @@ typedef struct GLFWimage
* [compile-time option](@ref compile_options_osx). * [compile-time option](@ref compile_options_osx).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref intro_init * @sa @ref intro_init
* @sa glfwTerminate * @sa glfwTerminate
@ -1163,14 +1211,14 @@ GLFWAPI int glfwInit(void);
* *
* @remarks This function may be called before @ref glfwInit. * @remarks This function may be called before @ref glfwInit.
* *
* @warning No window's context may be current on another thread when this * @warning The contexts of any remaining windows must not be current on any
* function is called. * other thread when this function is called.
* *
* @par Reentrancy * @par Reentrancy
* This function may not be called from a callback. * This function must not be called from a callback.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref intro_init * @sa @ref intro_init
* @sa glfwInit * @sa glfwInit
@ -1263,7 +1311,7 @@ GLFWAPI const char* glfwGetVersionString(void);
* @remarks This function may be called before @ref glfwInit. * @remarks This function may be called before @ref glfwInit.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref error_handling * @sa @ref error_handling
* *
@ -1290,7 +1338,7 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun);
* changes or the library is terminated. * changes or the library is terminated.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref monitor_monitors * @sa @ref monitor_monitors
* @sa @ref monitor_event * @sa @ref monitor_event
@ -1311,7 +1359,7 @@ GLFWAPI GLFWmonitor** glfwGetMonitors(int* count);
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @remarks The primary monitor is always first in the array returned by @ref * @remarks The primary monitor is always first in the array returned by @ref
* glfwGetMonitors. * glfwGetMonitors.
@ -1338,7 +1386,7 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void);
* @param[out] ypos Where to store the monitor y-coordinate, or `NULL`. * @param[out] ypos Where to store the monitor y-coordinate, or `NULL`.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref monitor_properties * @sa @ref monitor_properties
* *
@ -1371,7 +1419,7 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos);
* current resolution and system DPI instead of querying the monitor EDID data. * current resolution and system DPI instead of querying the monitor EDID data.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref monitor_properties * @sa @ref monitor_properties
* *
@ -1397,7 +1445,7 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int*
* library is terminated. * library is terminated.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref monitor_properties * @sa @ref monitor_properties
* *
@ -1419,7 +1467,7 @@ GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* monitor);
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref monitor_event * @sa @ref monitor_event
* *
@ -1448,7 +1496,7 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun);
* function is called again for that monitor or the library is terminated. * function is called again for that monitor or the library is terminated.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref monitor_modes * @sa @ref monitor_modes
* @sa glfwGetVideoMode * @sa glfwGetVideoMode
@ -1478,7 +1526,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* monitor, int* count);
* library is terminated. * library is terminated.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref monitor_modes * @sa @ref monitor_modes
* @sa glfwGetVideoModes * @sa glfwGetVideoModes
@ -1499,7 +1547,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
* @param[in] gamma The desired exponent. * @param[in] gamma The desired exponent.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref monitor_gamma * @sa @ref monitor_gamma
* *
@ -1524,7 +1572,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
* library is terminated. * library is terminated.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref monitor_gamma * @sa @ref monitor_gamma
* *
@ -1552,7 +1600,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
* The specified gamma ramp is copied before this function returns. * The specified gamma ramp is copied before this function returns.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref monitor_gamma * @sa @ref monitor_gamma
* *
@ -1568,7 +1616,7 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* monitor, const GLFWgammaramp* ramp);
* [default values](@ref window_hints_values). * [default values](@ref window_hints_values).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_hints * @sa @ref window_hints
* @sa glfwWindowHint * @sa glfwWindowHint
@ -1590,7 +1638,7 @@ GLFWAPI void glfwDefaultWindowHints(void);
* @param[in] hint The new value of the window hint. * @param[in] hint The new value of the window hint.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_hints * @sa @ref window_hints
* @sa glfwDefaultWindowHints * @sa glfwDefaultWindowHints
@ -1667,8 +1715,8 @@ GLFWAPI void glfwWindowHint(int target, int hint);
* `GLFW_ICON,` it will be set as the icon for the window. If no such icon is * `GLFW_ICON,` it will be set as the icon for the window. If no such icon is
* present, the `IDI_WINLOGO` icon will be used instead. * present, the `IDI_WINLOGO` icon will be used instead.
* *
* @remarks __Windows:__ The context to share resources with may not be current * @remarks __Windows:__ The context to share resources with must not be
* on any other thread. * current on any other thread.
* *
* @remarks __OS X:__ The GLFW window has no icon, as it is not a document * @remarks __OS X:__ The GLFW window has no icon, as it is not a document
* window, but the dock icon will be the same as the application bundle's icon. * window, but the dock icon will be the same as the application bundle's icon.
@ -1702,10 +1750,10 @@ GLFWAPI void glfwWindowHint(int target, int hint);
* window creation. * window creation.
* *
* @par Reentrancy * @par Reentrancy
* This function may not be called from a callback. * This function must not be called from a callback.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_creation * @sa @ref window_creation
* @sa glfwDestroyWindow * @sa glfwDestroyWindow
@ -1730,10 +1778,10 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, const char* title, G
* thread when this function is called. * thread when this function is called.
* *
* @par Reentrancy * @par Reentrancy
* This function may not be called from a callback. * This function must not be called from a callback.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_creation * @sa @ref window_creation
* @sa glfwCreateWindow * @sa glfwCreateWindow
@ -1794,7 +1842,7 @@ GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* window, int value);
* you process events. * you process events.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_title * @sa @ref window_title
* *
@ -1822,7 +1870,7 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
* the client area, or `NULL`. * the client area, or `NULL`.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_pos * @sa @ref window_pos
* @sa glfwSetWindowPos * @sa glfwSetWindowPos
@ -1850,7 +1898,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
* @param[in] ypos The y-coordinate of the upper-left corner of the client area. * @param[in] ypos The y-coordinate of the upper-left corner of the client area.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_pos * @sa @ref window_pos
* @sa glfwGetWindowPos * @sa glfwGetWindowPos
@ -1880,7 +1928,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
* client area, or `NULL`. * client area, or `NULL`.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_size * @sa @ref window_size
* @sa glfwSetWindowSize * @sa glfwSetWindowSize
@ -1917,7 +1965,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
* results are undefined. * results are undefined.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_sizelimits * @sa @ref window_sizelimits
* @sa glfwSetWindowAspectRatio * @sa glfwSetWindowAspectRatio
@ -1954,7 +2002,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe
* results are undefined. * results are undefined.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_sizelimits * @sa @ref window_sizelimits
* @sa glfwSetWindowSizeLimits * @sa glfwSetWindowSizeLimits
@ -1983,7 +2031,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
* @param[in] height The desired height of the specified window. * @param[in] height The desired height of the specified window.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_size * @sa @ref window_size
* @sa glfwGetWindowSize * @sa glfwGetWindowSize
@ -2013,7 +2061,7 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
* or `NULL`. * or `NULL`.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_fbsize * @sa @ref window_fbsize
* @sa glfwSetFramebufferSizeCallback * @sa glfwSetFramebufferSizeCallback
@ -2049,7 +2097,7 @@ GLFWAPI void glfwGetFramebufferSize(GLFWwindow* window, int* width, int* height)
* bottom edge of the window frame, or `NULL`. * bottom edge of the window frame, or `NULL`.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_size * @sa @ref window_size
* *
@ -2071,7 +2119,7 @@ GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* window, int* left, int* top, int
* @param[in] window The window to iconify. * @param[in] window The window to iconify.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_iconify * @sa @ref window_iconify
* @sa glfwRestoreWindow * @sa glfwRestoreWindow
@ -2096,7 +2144,7 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* @param[in] window The window to restore. * @param[in] window The window to restore.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_iconify * @sa @ref window_iconify
* @sa glfwIconifyWindow * @sa glfwIconifyWindow
@ -2119,7 +2167,7 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
* @param[in] window The window to make visible. * @param[in] window The window to make visible.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_hide * @sa @ref window_hide
* @sa glfwHideWindow * @sa glfwHideWindow
@ -2139,7 +2187,7 @@ GLFWAPI void glfwShowWindow(GLFWwindow* window);
* @param[in] window The window to hide. * @param[in] window The window to hide.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_hide * @sa @ref window_hide
* @sa glfwShowWindow * @sa glfwShowWindow
@ -2160,7 +2208,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
* occurred. * occurred.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_monitor * @sa @ref window_monitor
* *
@ -2190,7 +2238,7 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
* valid arguments and the library has been [initialized](@ref intro_init). * valid arguments and the library has been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_attribs * @sa @ref window_attribs
* *
@ -2254,7 +2302,7 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_pos * @sa @ref window_pos
* *
@ -2277,7 +2325,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_size * @sa @ref window_size
* *
@ -2311,7 +2359,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
* trigger the close callback for all windows. * trigger the close callback for all windows.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_close * @sa @ref window_close
* *
@ -2341,7 +2389,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_refresh * @sa @ref window_refresh
* *
@ -2371,7 +2419,7 @@ GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GL
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_focus * @sa @ref window_focus
* *
@ -2393,7 +2441,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_iconify * @sa @ref window_iconify
* *
@ -2415,7 +2463,7 @@ GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* window, GL
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref window_fbsize * @sa @ref window_fbsize
* *
@ -2444,10 +2492,10 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window
* Event processing is not required for joystick input to work. * Event processing is not required for joystick input to work.
* *
* @par Reentrancy * @par Reentrancy
* This function may not be called from a callback. * This function must not be called from a callback.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref events * @sa @ref events
* @sa glfwWaitEvents * @sa glfwWaitEvents
@ -2487,10 +2535,10 @@ GLFWAPI void glfwPollEvents(void);
* Event processing is not required for joystick input to work. * Event processing is not required for joystick input to work.
* *
* @par Reentrancy * @par Reentrancy
* This function may not be called from a callback. * This function must not be called from a callback.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref events * @sa @ref events
* @sa glfwPollEvents * @sa glfwPollEvents
@ -2533,7 +2581,7 @@ GLFWAPI void glfwPostEmptyEvent(void);
* `GLFW_STICKY_MOUSE_BUTTONS`. * `GLFW_STICKY_MOUSE_BUTTONS`.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa glfwSetInputMode * @sa glfwSetInputMode
* *
@ -2579,7 +2627,7 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* window, int mode);
* @param[in] value The new value of the specified input mode. * @param[in] value The new value of the specified input mode.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa glfwGetInputMode * @sa glfwGetInputMode
* *
@ -2606,7 +2654,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* window, int mode, int value);
* the library is terminated. * the library is terminated.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref input_key_name * @sa @ref input_key_name
* *
@ -2643,7 +2691,7 @@ GLFWAPI const char* glfwGetKeyName(int key, int scancode);
* @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref input_key * @sa @ref input_key
* *
@ -2672,7 +2720,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
* @return One of `GLFW_PRESS` or `GLFW_RELEASE`. * @return One of `GLFW_PRESS` or `GLFW_RELEASE`.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref input_mouse_button * @sa @ref input_mouse_button
* *
@ -2710,7 +2758,7 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* window, int button);
* top edge of the client area, or `NULL`. * top edge of the client area, or `NULL`.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref cursor_pos * @sa @ref cursor_pos
* @sa glfwSetCursorPos * @sa glfwSetCursorPos
@ -2749,7 +2797,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
* able to set the cursor position directly after window creation. * able to set the cursor position directly after window creation.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref cursor_pos * @sa @ref cursor_pos
* @sa glfwGetCursorPos * @sa glfwGetCursorPos
@ -2785,10 +2833,10 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* window, double xpos, double ypos);
* The specified image data is copied before this function returns. * The specified image data is copied before this function returns.
* *
* @par Reentrancy * @par Reentrancy
* This function may not be called from a callback. * This function must not be called from a callback.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref cursor_object * @sa @ref cursor_object
* @sa glfwDestroyCursor * @sa glfwDestroyCursor
@ -2811,10 +2859,10 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
* [error](@ref error_handling) occurred. * [error](@ref error_handling) occurred.
* *
* @par Reentrancy * @par Reentrancy
* This function may not be called from a callback. * This function must not be called from a callback.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref cursor_object * @sa @ref cursor_object
* @sa glfwCreateCursor * @sa glfwCreateCursor
@ -2834,10 +2882,10 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape);
* @param[in] cursor The cursor object to destroy. * @param[in] cursor The cursor object to destroy.
* *
* @par Reentrancy * @par Reentrancy
* This function may not be called from a callback. * This function must not be called from a callback.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref cursor_object * @sa @ref cursor_object
* @sa glfwCreateCursor * @sa glfwCreateCursor
@ -2863,7 +2911,7 @@ GLFWAPI void glfwDestroyCursor(GLFWcursor* cursor);
* arrow cursor. * arrow cursor.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref cursor_object * @sa @ref cursor_object
* *
@ -2904,7 +2952,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref input_key * @sa @ref input_key
* *
@ -2943,7 +2991,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun cbfun);
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref input_char * @sa @ref input_char
* *
@ -2978,7 +3026,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);
* error occurred. * error occurred.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref input_char * @sa @ref input_char
* *
@ -3006,7 +3054,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref input_mouse_button * @sa @ref input_mouse_button
* *
@ -3033,7 +3081,7 @@ GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* window, GLFWmo
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref cursor_pos * @sa @ref cursor_pos
* *
@ -3056,7 +3104,7 @@ GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* window, GLFWcursor
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref cursor_enter * @sa @ref cursor_enter
* *
@ -3082,7 +3130,7 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref scrolling * @sa @ref scrolling
* *
@ -3109,7 +3157,7 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cb
* library had not been [initialized](@ref intro_init). * library had not been [initialized](@ref intro_init).
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref path_drop * @sa @ref path_drop
* *
@ -3127,7 +3175,7 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
* @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise. * @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref joystick * @sa @ref joystick
* *
@ -3153,7 +3201,7 @@ GLFWAPI int glfwJoystickPresent(int joy);
* function is called again for that joystick or the library is terminated. * function is called again for that joystick or the library is terminated.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref joystick_axis * @sa @ref joystick_axis
* *
@ -3179,7 +3227,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);
* function is called again for that joystick or the library is terminated. * function is called again for that joystick or the library is terminated.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref joystick_button * @sa @ref joystick_button
* *
@ -3208,7 +3256,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
* function is called again for that joystick or the library is terminated. * function is called again for that joystick or the library is terminated.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref joystick_name * @sa @ref joystick_name
* *
@ -3230,7 +3278,7 @@ GLFWAPI const char* glfwGetJoystickName(int joy);
* The specified string is copied before this function returns. * The specified string is copied before this function returns.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref clipboard * @sa @ref clipboard
* @sa glfwGetClipboardString * @sa glfwGetClipboardString
@ -3259,7 +3307,7 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
* is terminated. * is terminated.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref clipboard * @sa @ref clipboard
* @sa glfwSetClipboardString * @sa glfwSetClipboardString
@ -3307,7 +3355,7 @@ GLFWAPI double glfwGetTime(void);
* storing nanoseconds in 64 bits. The limit may be increased in the future. * storing nanoseconds in 64 bits. The limit may be increased in the future.
* *
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function must only be called from the main thread.
* *
* @sa @ref time * @sa @ref time
* *

View File

@ -1,10 +1,4 @@
include_directories("${GLFW_SOURCE_DIR}/src"
"${GLFW_BINARY_DIR}/src"
${glfw_INCLUDE_DIRS})
add_definitions(-D_GLFW_USE_CONFIG_H)
set(common_HEADERS internal.h set(common_HEADERS internal.h
"${GLFW_BINARY_DIR}/src/glfw_config.h" "${GLFW_BINARY_DIR}/src/glfw_config.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h" "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
@ -12,15 +6,14 @@ set(common_HEADERS internal.h
set(common_SOURCES context.c init.c input.c monitor.c window.c) set(common_SOURCES context.c init.c input.c monitor.c window.c)
if (_GLFW_COCOA) if (_GLFW_COCOA)
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h iokit_joystick.h set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
posix_tls.h) posix_tls.h)
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_monitor.m set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m
cocoa_window.m iokit_joystick.m mach_time.c posix_tls.c) cocoa_monitor.m cocoa_window.m cocoa_time.c posix_tls.c)
elseif (_GLFW_WIN32) elseif (_GLFW_WIN32)
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h)
winmm_joystick.h) set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_joystick.c
set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_monitor.c win32_time.c win32_monitor.c win32_time.c win32_tls.c win32_window.c)
win32_tls.c win32_window.c winmm_joystick.c)
elseif (_GLFW_X11) elseif (_GLFW_X11)
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h
linux_joystick.h posix_time.h posix_tls.h) linux_joystick.h posix_time.h posix_tls.h)
@ -59,37 +52,66 @@ endif()
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS}) add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
set_target_properties(glfw PROPERTIES set_target_properties(glfw PROPERTIES
OUTPUT_NAME "${GLFW_LIB_NAME}"
VERSION ${GLFW_VERSION} VERSION ${GLFW_VERSION}
SOVERSION ${GLFW_VERSION_MAJOR} SOVERSION ${GLFW_VERSION_MAJOR}
POSITION_INDEPENDENT_CODE ON POSITION_INDEPENDENT_CODE ON
FOLDER "GLFW3") FOLDER "GLFW3")
target_compile_definitions(glfw PRIVATE -D_GLFW_USE_CONFIG_H)
target_include_directories(glfw PRIVATE
"${GLFW_SOURCE_DIR}/src"
"${GLFW_BINARY_DIR}/src"
${glfw_INCLUDE_DIRS})
# HACK: When building on MinGW, WINVER and UNICODE need to be defined before
# the inclusion of stddef.h (by glfw3.h), which is itself included before
# win32_platform.h. We define them here until a saner solution can be found
# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack.
target_compile_definitions(glfw PRIVATE
"$<$<BOOL:${MINGW}>:UNICODE;WINVER=0x0501>")
# Enable a reasonable set of warnings (no, -Wextra is not reasonable)
target_compile_options(glfw PRIVATE
"$<$<C_COMPILER_ID:Clang>:-Wall>"
"$<$<C_COMPILER_ID:GNU>:-Wall>")
if (BUILD_SHARED_LIBS) if (BUILD_SHARED_LIBS)
if (WIN32) if (WIN32)
# The GLFW DLL needs a special compile-time macro and import library name
set_target_properties(glfw PROPERTIES PREFIX "" IMPORT_PREFIX "")
if (MINGW) if (MINGW)
# Remove the lib prefix on the DLL (but not the import library
set_target_properties(glfw PROPERTIES PREFIX "")
# Add a suffix to the import library to avoid naming conflicts
set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.a") set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.a")
else() else()
# Add a suffix to the import library to avoid naming conflicts
set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib") set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib")
endif() endif()
elseif (APPLE) elseif (APPLE)
# Append -fno-common to the compile flags to work around a bug in # Add -fno-common to work around a bug in Apple's GCC
# Apple's GCC target_compile_options(glfw PRIVATE "-fno-common")
get_target_property(glfw_CFLAGS glfw COMPILE_FLAGS)
if (NOT glfw_CFLAGS)
set(glfw_CFLAGS "")
endif()
set_target_properties(glfw PROPERTIES set_target_properties(glfw PROPERTIES
COMPILE_FLAGS "${glfw_CFLAGS} -fno-common" INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}") elseif (UNIX)
# Hide symbols not explicitly tagged for export from the shared library
target_compile_options(glfw PRIVATE "-fvisibility=hidden")
endif() endif()
target_link_libraries(glfw ${glfw_LIBRARIES}) target_link_libraries(glfw ${glfw_LIBRARIES})
endif() endif()
if (MSVC)
target_compile_definitions(glfw PRIVATE _CRT_SECURE_NO_WARNINGS)
endif()
if (BUILD_SHARED_LIBS AND UNIX)
# On Unix-like systems, shared libraries can use the soname system.
set_target_properties(glfw PROPERTIES OUTPUT_NAME glfw)
else()
set_target_properties(glfw PROPERTIES OUTPUT_NAME glfw3)
endif()
if (GLFW_INSTALL) if (GLFW_INSTALL)
install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}) install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX})
endif() endif()

View File

@ -232,11 +232,14 @@ int _glfwPlatformInit(void)
if (!_glfw.ns.unicodeData) if (!_glfw.ns.unicodeData)
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwInitContextAPI()) if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE; return GLFW_FALSE;
_glfwInitTimer(); if (!_glfwInitNSGL())
_glfwInitJoysticks(); return GLFW_FALSE;
_glfwInitTimerNS();
_glfwInitJoysticksNS();
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -270,8 +273,9 @@ void _glfwPlatformTerminate(void)
free(_glfw.ns.clipboardString); free(_glfw.ns.clipboardString);
_glfwTerminateJoysticks(); _glfwTerminateNSGL();
_glfwTerminateContextAPI(); _glfwTerminateJoysticksNS();
_glfwTerminateThreadLocalStoragePOSIX();
} }
const char* _glfwPlatformGetVersionString(void) const char* _glfwPlatformGetVersionString(void)

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 IOKit - www.glfw.org // GLFW 3.2 Cocoa - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2006-2014 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2014 Camilla Berglund <elmindreda@elmindreda.org>
// //
@ -24,23 +24,22 @@
// //
//======================================================================== //========================================================================
#ifndef _glfw3_iokit_joystick_h_ #ifndef _glfw3_cocoa_joystick_h_
#define _glfw3_iokit_joystick_h_ #define _glfw3_cocoa_joystick_h_
#include <IOKit/IOKitLib.h> #include <IOKit/IOKitLib.h>
#include <IOKit/IOCFPlugIn.h> #include <IOKit/IOCFPlugIn.h>
#include <IOKit/hid/IOHIDLib.h> #include <IOKit/hid/IOHIDLib.h>
#include <IOKit/hid/IOHIDKeys.h> #include <IOKit/hid/IOHIDKeys.h>
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWjoystickNS ns_js
_GLFWjoystickIOKit iokit_js
// IOKit-specific per-joystick data // Cocoa-specific per-joystick data
// //
typedef struct _GLFWjoydevice typedef struct _GLFWjoydeviceNS
{ {
int present; GLFWbool present;
char name[256]; char name[256];
IOHIDDeviceRef deviceRef; IOHIDDeviceRef deviceRef;
@ -51,18 +50,18 @@ typedef struct _GLFWjoydevice
float* axes; float* axes;
unsigned char* buttons; unsigned char* buttons;
} _GLFWjoydevice; } _GLFWjoydeviceNS;
// IOKit-specific joystick API data // Cocoa-specific joystick API data
// //
typedef struct _GLFWjoystickIOKit typedef struct _GLFWjoystickNS
{ {
_GLFWjoydevice devices[GLFW_JOYSTICK_LAST + 1]; _GLFWjoydeviceNS devices[GLFW_JOYSTICK_LAST + 1];
IOHIDManagerRef managerRef; IOHIDManagerRef managerRef;
} _GLFWjoystickIOKit; } _GLFWjoystickNS;
void _glfwInitJoysticks(void); void _glfwInitJoysticksNS(void);
void _glfwTerminateJoysticks(void); void _glfwTerminateJoysticksNS(void);
#endif // _glfw3_iokit_joystick_h_ #endif // _glfw3_cocoa_joystick_h_

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 IOKit - www.glfw.org // GLFW 3.2 Cocoa - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net> // Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
@ -40,7 +40,7 @@
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Joystick element information // Joystick element information
//------------------------------------------------------------------------ //------------------------------------------------------------------------
typedef struct typedef struct _GLFWjoyelementNS
{ {
IOHIDElementRef elementRef; IOHIDElementRef elementRef;
@ -50,14 +50,14 @@ typedef struct
long minReport; long minReport;
long maxReport; long maxReport;
} _GLFWjoyelement; } _GLFWjoyelementNS;
static void getElementsCFArrayHandler(const void* value, void* parameter); static void getElementsCFArrayHandler(const void* value, void* parameter);
// Adds an element to the specified joystick // Adds an element to the specified joystick
// //
static void addJoystickElement(_GLFWjoydevice* joystick, static void addJoystickElement(_GLFWjoydeviceNS* joystick,
IOHIDElementRef elementRef) IOHIDElementRef elementRef)
{ {
IOHIDElementType elementType; IOHIDElementType elementType;
@ -109,7 +109,7 @@ static void addJoystickElement(_GLFWjoydevice* joystick,
if (elementsArray) if (elementsArray)
{ {
_GLFWjoyelement* element = calloc(1, sizeof(_GLFWjoyelement)); _GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS));
CFArrayAppendValue(elementsArray, element); CFArrayAppendValue(elementsArray, element);
@ -126,14 +126,14 @@ static void getElementsCFArrayHandler(const void* value, void* parameter)
{ {
if (CFGetTypeID(value) == IOHIDElementGetTypeID()) if (CFGetTypeID(value) == IOHIDElementGetTypeID())
{ {
addJoystickElement((_GLFWjoydevice*) parameter, addJoystickElement((_GLFWjoydeviceNS*) parameter,
(IOHIDElementRef) value); (IOHIDElementRef) value);
} }
} }
// Returns the value of the specified element of the specified joystick // Returns the value of the specified element of the specified joystick
// //
static long getElementValue(_GLFWjoydevice* joystick, _GLFWjoyelement* element) static long getElementValue(_GLFWjoydeviceNS* joystick, _GLFWjoyelementNS* element)
{ {
IOReturn result = kIOReturnSuccess; IOReturn result = kIOReturnSuccess;
IOHIDValueRef valueRef; IOHIDValueRef valueRef;
@ -163,7 +163,7 @@ static long getElementValue(_GLFWjoydevice* joystick, _GLFWjoyelement* element)
// Removes the specified joystick // Removes the specified joystick
// //
static void removeJoystick(_GLFWjoydevice* joystick) static void removeJoystick(_GLFWjoydeviceNS* joystick)
{ {
int i; int i;
@ -188,70 +188,66 @@ static void removeJoystick(_GLFWjoydevice* joystick)
free(joystick->axes); free(joystick->axes);
free(joystick->buttons); free(joystick->buttons);
memset(joystick, 0, sizeof(_GLFWjoydevice)); memset(joystick, 0, sizeof(_GLFWjoydeviceNS));
} }
// Polls for joystick events and updates GLFW state // Polls for joystick events and updates GLFW state
// //
static void pollJoystickEvents(void) static GLFWbool pollJoystickEvents(_GLFWjoydeviceNS* joystick)
{ {
int joy; CFIndex i;
int buttonIndex = 0;
for (joy = 0; joy <= GLFW_JOYSTICK_LAST; joy++) if (!joystick->present)
return GLFW_FALSE;
for (i = 0; i < CFArrayGetCount(joystick->buttonElements); i++)
{ {
CFIndex i; _GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
int buttonIndex = 0; CFArrayGetValueAtIndex(joystick->buttonElements, i);
_GLFWjoydevice* joystick = _glfw.iokit_js.devices + joy;
if (!joystick->present) if (getElementValue(joystick, button))
continue; joystick->buttons[buttonIndex++] = GLFW_PRESS;
else
joystick->buttons[buttonIndex++] = GLFW_RELEASE;
}
for (i = 0; i < CFArrayGetCount(joystick->buttonElements); i++) for (i = 0; i < CFArrayGetCount(joystick->axisElements); i++)
{
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(joystick->axisElements, i);
long value = getElementValue(joystick, axis);
long readScale = axis->maxReport - axis->minReport;
if (readScale == 0)
joystick->axes[i] = value;
else
joystick->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f;
}
for (i = 0; i < CFArrayGetCount(joystick->hatElements); i++)
{
_GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(joystick->hatElements, i);
// Bit fields of button presses for each direction, including nil
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
long j, value = getElementValue(joystick, hat);
if (value < 0 || value > 8)
value = 8;
for (j = 0; j < 4; j++)
{ {
_GLFWjoyelement* button = (_GLFWjoyelement*) if (directions[value] & (1 << j))
CFArrayGetValueAtIndex(joystick->buttonElements, i);
if (getElementValue(joystick, button))
joystick->buttons[buttonIndex++] = GLFW_PRESS; joystick->buttons[buttonIndex++] = GLFW_PRESS;
else else
joystick->buttons[buttonIndex++] = GLFW_RELEASE; joystick->buttons[buttonIndex++] = GLFW_RELEASE;
} }
for (i = 0; i < CFArrayGetCount(joystick->axisElements); i++)
{
_GLFWjoyelement* axis = (_GLFWjoyelement*)
CFArrayGetValueAtIndex(joystick->axisElements, i);
long value = getElementValue(joystick, axis);
long readScale = axis->maxReport - axis->minReport;
if (readScale == 0)
joystick->axes[i] = value;
else
joystick->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f;
}
for (i = 0; i < CFArrayGetCount(joystick->hatElements); i++)
{
_GLFWjoyelement* hat = (_GLFWjoyelement*)
CFArrayGetValueAtIndex(joystick->hatElements, i);
// Bit fields of button presses for each direction, including nil
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
long j, value = getElementValue(joystick, hat);
if (value < 0 || value > 8)
value = 8;
for (j = 0; j < 4; j++)
{
if (directions[value] & (1 << j))
joystick->buttons[buttonIndex++] = GLFW_PRESS;
else
joystick->buttons[buttonIndex++] = GLFW_RELEASE;
}
}
} }
return GLFW_TRUE;
} }
// Callback for user-initiated joystick addition // Callback for user-initiated joystick addition
@ -261,12 +257,12 @@ static void matchCallback(void* context,
void* sender, void* sender,
IOHIDDeviceRef deviceRef) IOHIDDeviceRef deviceRef)
{ {
_GLFWjoydevice* joystick; _GLFWjoydeviceNS* joystick;
int joy; int joy;
for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++)
{ {
joystick = _glfw.iokit_js.devices + joy; joystick = _glfw.ns_js.devices + joy;
if (!joystick->present) if (!joystick->present)
continue; continue;
@ -277,7 +273,7 @@ static void matchCallback(void* context,
for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++)
{ {
joystick = _glfw.iokit_js.devices + joy; joystick = _glfw.ns_js.devices + joy;
if (!joystick->present) if (!joystick->present)
break; break;
@ -328,7 +324,7 @@ static void removeCallback(void* context,
for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++)
{ {
_GLFWjoydevice* joystick = _glfw.iokit_js.devices + joy; _GLFWjoydeviceNS* joystick = _glfw.ns_js.devices + joy;
if (joystick->deviceRef == deviceRef) if (joystick->deviceRef == deviceRef)
{ {
removeJoystick(joystick); removeJoystick(joystick);
@ -384,12 +380,12 @@ static CFMutableDictionaryRef createMatchingDictionary(long usagePage,
// Initialize joystick interface // Initialize joystick interface
// //
void _glfwInitJoysticks(void) void _glfwInitJoysticksNS(void)
{ {
CFMutableArrayRef matchingCFArrayRef; CFMutableArrayRef matchingCFArrayRef;
_glfw.iokit_js.managerRef = IOHIDManagerCreate(kCFAllocatorDefault, _glfw.ns_js.managerRef = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone); kIOHIDOptionsTypeNone);
matchingCFArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, matchingCFArrayRef = CFArrayCreateMutable(kCFAllocatorDefault,
0, 0,
@ -422,21 +418,21 @@ void _glfwInitJoysticks(void)
CFRelease(matchingCFDictRef); CFRelease(matchingCFDictRef);
} }
IOHIDManagerSetDeviceMatchingMultiple(_glfw.iokit_js.managerRef, IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns_js.managerRef,
matchingCFArrayRef); matchingCFArrayRef);
CFRelease(matchingCFArrayRef); CFRelease(matchingCFArrayRef);
} }
IOHIDManagerRegisterDeviceMatchingCallback(_glfw.iokit_js.managerRef, IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns_js.managerRef,
&matchCallback, NULL); &matchCallback, NULL);
IOHIDManagerRegisterDeviceRemovalCallback(_glfw.iokit_js.managerRef, IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns_js.managerRef,
&removeCallback, NULL); &removeCallback, NULL);
IOHIDManagerScheduleWithRunLoop(_glfw.iokit_js.managerRef, IOHIDManagerScheduleWithRunLoop(_glfw.ns_js.managerRef,
CFRunLoopGetMain(), CFRunLoopGetMain(),
kCFRunLoopDefaultMode); kCFRunLoopDefaultMode);
IOHIDManagerOpen(_glfw.iokit_js.managerRef, kIOHIDOptionsTypeNone); IOHIDManagerOpen(_glfw.ns_js.managerRef, kIOHIDOptionsTypeNone);
// Execute the run loop once in order to register any initially-attached // Execute the run loop once in order to register any initially-attached
// joysticks // joysticks
@ -445,18 +441,18 @@ void _glfwInitJoysticks(void)
// Close all opened joystick handles // Close all opened joystick handles
// //
void _glfwTerminateJoysticks(void) void _glfwTerminateJoysticksNS(void)
{ {
int joy; int joy;
for (joy = 0; joy <= GLFW_JOYSTICK_LAST; joy++) for (joy = 0; joy <= GLFW_JOYSTICK_LAST; joy++)
{ {
_GLFWjoydevice* joystick = _glfw.iokit_js.devices + joy; _GLFWjoydeviceNS* joystick = _glfw.ns_js.devices + joy;
removeJoystick(joystick); removeJoystick(joystick);
} }
CFRelease(_glfw.iokit_js.managerRef); CFRelease(_glfw.ns_js.managerRef);
_glfw.iokit_js.managerRef = NULL; _glfw.ns_js.managerRef = NULL;
} }
@ -466,18 +462,14 @@ void _glfwTerminateJoysticks(void)
int _glfwPlatformJoystickPresent(int joy) int _glfwPlatformJoystickPresent(int joy)
{ {
pollJoystickEvents(); _GLFWjoydeviceNS* joystick = _glfw.ns_js.devices + joy;
return pollJoystickEvents(joystick);
return _glfw.iokit_js.devices[joy].present;
} }
const float* _glfwPlatformGetJoystickAxes(int joy, int* count) const float* _glfwPlatformGetJoystickAxes(int joy, int* count)
{ {
_GLFWjoydevice* joystick = _glfw.iokit_js.devices + joy; _GLFWjoydeviceNS* joystick = _glfw.ns_js.devices + joy;
if (!pollJoystickEvents(joystick))
pollJoystickEvents();
if (!joystick->present)
return NULL; return NULL;
*count = (int) CFArrayGetCount(joystick->axisElements); *count = (int) CFArrayGetCount(joystick->axisElements);
@ -486,11 +478,8 @@ const float* _glfwPlatformGetJoystickAxes(int joy, int* count)
const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
{ {
_GLFWjoydevice* joystick = _glfw.iokit_js.devices + joy; _GLFWjoydeviceNS* joystick = _glfw.ns_js.devices + joy;
if (!pollJoystickEvents(joystick))
pollJoystickEvents();
if (!joystick->present)
return NULL; return NULL;
*count = (int) CFArrayGetCount(joystick->buttonElements) + *count = (int) CFArrayGetCount(joystick->buttonElements) +
@ -500,8 +489,10 @@ const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
const char* _glfwPlatformGetJoystickName(int joy) const char* _glfwPlatformGetJoystickName(int joy)
{ {
pollJoystickEvents(); _GLFWjoydeviceNS* joystick = _glfw.ns_js.devices + joy;
if (!pollJoystickEvents(joystick))
return NULL;
return _glfw.iokit_js.devices[joy].name; return joystick->name;
} }

View File

@ -166,7 +166,7 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
// Change the current video mode // Change the current video mode
// //
GLFWbool _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{ {
CFArrayRef modes; CFArrayRef modes;
CFIndex count, i; CFIndex count, i;
@ -224,7 +224,7 @@ GLFWbool _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
// Restore the previously saved (original) video mode // Restore the previously saved (original) video mode
// //
void _glfwRestoreVideoMode(_GLFWmonitor* monitor) void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
{ {
if (monitor->ns.previousMode) if (monitor->ns.previousMode)
{ {

View File

@ -39,7 +39,7 @@ typedef void* id;
#endif #endif
#include "posix_tls.h" #include "posix_tls.h"
#include "iokit_joystick.h" #include "cocoa_joystick.h"
#if defined(_GLFW_NSGL) #if defined(_GLFW_NSGL)
#include "nsgl_context.h" #include "nsgl_context.h"
@ -120,9 +120,9 @@ typedef struct _GLFWtimeNS
} _GLFWtimeNS; } _GLFWtimeNS;
void _glfwInitTimer(void); void _glfwInitTimerNS(void);
GLFWbool _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoMode(_GLFWmonitor* monitor); void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
#endif // _glfw3_cocoa_platform_h_ #endif // _glfw3_cocoa_platform_h_

View File

@ -43,7 +43,7 @@ static uint64_t getRawTime(void)
// Initialise timer // Initialise timer
// //
void _glfwInitTimer(void) void _glfwInitTimerNS(void)
{ {
mach_timebase_info_data_t info; mach_timebase_info_data_t info;
mach_timebase_info(&info); mach_timebase_info(&info);

View File

@ -64,22 +64,26 @@ static void centerCursor(_GLFWwindow *window)
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
} }
// Transforms the specified y-coordinate between the CG display and NS screen
// coordinate systems
//
static float transformY(float y)
{
return CGDisplayBounds(CGMainDisplayID()).size.height - y;
}
// Enter full screen mode // Enter full screen mode
// //
static GLFWbool enterFullscreenMode(_GLFWwindow* window) static GLFWbool enterFullscreenMode(_GLFWwindow* window)
{ {
GLFWvidmode mode; const GLFWbool status = _glfwSetVideoModeNS(window->monitor, &window->videoMode);
GLFWbool status; const CGRect bounds = CGDisplayBounds(window->monitor->ns.displayID);
int xpos, ypos; const NSRect frame = NSMakeRect(bounds.origin.x,
transformY(bounds.origin.y + bounds.size.height),
status = _glfwSetVideoMode(window->monitor, &window->videoMode); bounds.size.width,
bounds.size.height);
_glfwPlatformGetVideoMode(window->monitor, &mode);
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
[window->ns.object setFrame:NSMakeRect(xpos, ypos, mode.width, mode.height)
display:YES];
[window->ns.object setFrame:frame display:YES];
return status; return status;
} }
@ -87,16 +91,7 @@ static GLFWbool enterFullscreenMode(_GLFWwindow* window)
// //
static void leaveFullscreenMode(_GLFWwindow* window) static void leaveFullscreenMode(_GLFWwindow* window)
{ {
_glfwRestoreVideoMode(window->monitor); _glfwRestoreVideoModeNS(window->monitor);
}
// Transforms the specified y-coordinate between the CG display and NS screen
// coordinate systems
//
static float transformY(float y)
{
const float height = CGDisplayBounds(CGMainDisplayID()).size.height;
return height - y;
} }
// Translates OS X key modifiers into GLFW ones // Translates OS X key modifiers into GLFW ones
@ -267,7 +262,7 @@ static int translateKey(unsigned int key)
int i; int i;
for (i = 0; i < _glfw.monitorCount; i++) for (i = 0; i < _glfw.monitorCount; i++)
_glfwRestoreVideoMode(_glfw.monitors[i]); _glfwRestoreVideoModeNS(_glfw.monitors[i]);
} }
@end @end
@ -891,7 +886,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (ctxconfig->api != GLFW_NO_API) if (ctxconfig->api != GLFW_NO_API)
{ {
if (!_glfwCreateContext(window, ctxconfig, fbconfig)) if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -913,7 +908,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
leaveFullscreenMode(window); leaveFullscreenMode(window);
if (window->context.api != GLFW_NO_API) if (window->context.api != GLFW_NO_API)
_glfwDestroyContext(window); _glfwDestroyContextNSGL(window);
[window->ns.object setDelegate:nil]; [window->ns.object setDelegate:nil];
[window->ns.delegate release]; [window->ns.delegate release];

View File

@ -78,7 +78,7 @@ static const char* getErrorString(EGLint error)
static int getConfigAttrib(EGLConfig config, int attrib) static int getConfigAttrib(EGLConfig config, int attrib)
{ {
int value; int value;
_glfw_eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value); eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
return value; return value;
} }
@ -93,7 +93,7 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* closest; const _GLFWfbconfig* closest;
int i, nativeCount, usableCount; int i, nativeCount, usableCount;
_glfw_eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount); eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
if (!nativeCount) if (!nativeCount)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned"); _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
@ -101,8 +101,7 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
} }
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig)); nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));
_glfw_eglGetConfigs(_glfw.egl.display, nativeConfigs, eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
nativeCount, &nativeCount);
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig)); usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0; usableCount = 0;
@ -177,7 +176,7 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
// Initialize EGL // Initialize EGL
// //
int _glfwInitContextAPI(void) GLFWbool _glfwInitEGL(void)
{ {
int i; int i;
const char* sonames[] = const char* sonames[] =
@ -193,9 +192,6 @@ int _glfwInitContextAPI(void)
NULL NULL
}; };
if (!_glfwCreateContextTLS())
return GLFW_FALSE;
for (i = 0; sonames[i]; i++) for (i = 0; sonames[i]; i++)
{ {
_glfw.egl.handle = _glfw_dlopen(sonames[i]); _glfw.egl.handle = _glfw_dlopen(sonames[i]);
@ -209,56 +205,53 @@ int _glfwInitContextAPI(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfw.egl.GetConfigAttrib = _glfw.egl.GetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib"); _glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
_glfw.egl.GetConfigs = _glfw.egl.GetConfigs = (PFNEGLGETCONFIGSPROC)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigs"); _glfw_dlsym(_glfw.egl.handle, "eglGetConfigs");
_glfw.egl.GetDisplay = _glfw.egl.GetDisplay = (PFNEGLGETDISPLAYPROC)
_glfw_dlsym(_glfw.egl.handle, "eglGetDisplay"); _glfw_dlsym(_glfw.egl.handle, "eglGetDisplay");
_glfw.egl.GetError = _glfw.egl.GetError = (PFNEGLGETERRORPROC)
_glfw_dlsym(_glfw.egl.handle, "eglGetError"); _glfw_dlsym(_glfw.egl.handle, "eglGetError");
_glfw.egl.Initialize = _glfw.egl.Initialize = (PFNEGLINITIALIZEPROC)
_glfw_dlsym(_glfw.egl.handle, "eglInitialize"); _glfw_dlsym(_glfw.egl.handle, "eglInitialize");
_glfw.egl.Terminate = _glfw.egl.Terminate = (PFNEGLTERMINATEPROC)
_glfw_dlsym(_glfw.egl.handle, "eglTerminate"); _glfw_dlsym(_glfw.egl.handle, "eglTerminate");
_glfw.egl.BindAPI = _glfw.egl.BindAPI = (PFNEGLBINDAPIPROC)
_glfw_dlsym(_glfw.egl.handle, "eglBindAPI"); _glfw_dlsym(_glfw.egl.handle, "eglBindAPI");
_glfw.egl.CreateContext = _glfw.egl.CreateContext = (PFNEGLCREATECONTEXTPROC)
_glfw_dlsym(_glfw.egl.handle, "eglCreateContext"); _glfw_dlsym(_glfw.egl.handle, "eglCreateContext");
_glfw.egl.DestroySurface = _glfw.egl.DestroySurface = (PFNEGLDESTROYSURFACEPROC)
_glfw_dlsym(_glfw.egl.handle, "eglDestroySurface"); _glfw_dlsym(_glfw.egl.handle, "eglDestroySurface");
_glfw.egl.DestroyContext = _glfw.egl.DestroyContext = (PFNEGLDESTROYCONTEXTPROC)
_glfw_dlsym(_glfw.egl.handle, "eglDestroyContext"); _glfw_dlsym(_glfw.egl.handle, "eglDestroyContext");
_glfw.egl.CreateWindowSurface = _glfw.egl.CreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC)
_glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface"); _glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface");
_glfw.egl.MakeCurrent = _glfw.egl.MakeCurrent = (PFNEGLMAKECURRENTPROC)
_glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent"); _glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent");
_glfw.egl.SwapBuffers = _glfw.egl.SwapBuffers = (PFNEGLSWAPBUFFERSPROC)
_glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers"); _glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers");
_glfw.egl.SwapInterval = _glfw.egl.SwapInterval = (PFNEGLSWAPINTERVALPROC)
_glfw_dlsym(_glfw.egl.handle, "eglSwapInterval"); _glfw_dlsym(_glfw.egl.handle, "eglSwapInterval");
_glfw.egl.QueryString = _glfw.egl.QueryString = (PFNEGLQUERYSTRINGPROC)
_glfw_dlsym(_glfw.egl.handle, "eglQueryString"); _glfw_dlsym(_glfw.egl.handle, "eglQueryString");
_glfw.egl.GetProcAddress = _glfw.egl.GetProcAddress = (PFNEGLGETPROCADDRESSPROC)
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress"); _glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
_glfw.egl.display = _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
_glfw_eglGetDisplay((EGLNativeDisplayType)_GLFW_EGL_NATIVE_DISPLAY);
if (_glfw.egl.display == EGL_NO_DISPLAY) if (_glfw.egl.display == EGL_NO_DISPLAY)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to get EGL display: %s", "EGL: Failed to get EGL display: %s",
getErrorString(_glfw_eglGetError())); getErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
if (!_glfw_eglInitialize(_glfw.egl.display, if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
&_glfw.egl.major,
&_glfw.egl.minor))
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to initialize EGL: %s", "EGL: Failed to initialize EGL: %s",
getErrorString(_glfw_eglGetError())); getErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -272,18 +265,14 @@ int _glfwInitContextAPI(void)
// Terminate EGL // Terminate EGL
// //
void _glfwTerminateContextAPI(void) void _glfwTerminateEGL(void)
{ {
if (_glfw_eglTerminate)
_glfw_eglTerminate(_glfw.egl.display);
if (_glfw.egl.handle) if (_glfw.egl.handle)
{ {
eglTerminate(_glfw.egl.display);
_glfw_dlclose(_glfw.egl.handle); _glfw_dlclose(_glfw.egl.handle);
_glfw.egl.handle = NULL; _glfw.egl.handle = NULL;
} }
_glfwDestroyContextTLS();
} }
#define setEGLattrib(attribName, attribValue) \ #define setEGLattrib(attribName, attribValue) \
@ -295,9 +284,9 @@ void _glfwTerminateContextAPI(void)
// Create the OpenGL or OpenGL ES context // Create the OpenGL or OpenGL ES context
// //
int _glfwCreateContext(_GLFWwindow* window, GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
int attribs[40]; int attribs[40];
EGLConfig config; EGLConfig config;
@ -315,21 +304,21 @@ int _glfwCreateContext(_GLFWwindow* window,
if (ctxconfig->api == GLFW_OPENGL_ES_API) if (ctxconfig->api == GLFW_OPENGL_ES_API)
{ {
if (!_glfw_eglBindAPI(EGL_OPENGL_ES_API)) if (!eglBindAPI(EGL_OPENGL_ES_API))
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL ES: %s", "EGL: Failed to bind OpenGL ES: %s",
getErrorString(_glfw_eglGetError())); getErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
} }
else else
{ {
if (!_glfw_eglBindAPI(EGL_OPENGL_API)) if (!eglBindAPI(EGL_OPENGL_API))
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL: %s", "EGL: Failed to bind OpenGL: %s",
getErrorString(_glfw_eglGetError())); getErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
} }
@ -401,27 +390,27 @@ int _glfwCreateContext(_GLFWwindow* window,
// Context release behaviors (GL_KHR_context_flush_control) are not yet // Context release behaviors (GL_KHR_context_flush_control) are not yet
// supported on EGL but are not a hard constraint, so ignore and continue // supported on EGL but are not a hard constraint, so ignore and continue
window->context.egl.handle = _glfw_eglCreateContext(_glfw.egl.display, window->context.egl.handle = eglCreateContext(_glfw.egl.display,
config, share, attribs); config, share, attribs);
if (window->context.egl.handle == EGL_NO_CONTEXT) if (window->context.egl.handle == EGL_NO_CONTEXT)
{ {
_glfwInputError(GLFW_VERSION_UNAVAILABLE, _glfwInputError(GLFW_VERSION_UNAVAILABLE,
"EGL: Failed to create context: %s", "EGL: Failed to create context: %s",
getErrorString(_glfw_eglGetError())); getErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
window->context.egl.surface = window->context.egl.surface =
_glfw_eglCreateWindowSurface(_glfw.egl.display, eglCreateWindowSurface(_glfw.egl.display,
config, config,
(EGLNativeWindowType)_GLFW_EGL_NATIVE_WINDOW, _GLFW_EGL_NATIVE_WINDOW,
NULL); NULL);
if (window->context.egl.surface == EGL_NO_SURFACE) if (window->context.egl.surface == EGL_NO_SURFACE)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to create window surface: %s", "EGL: Failed to create window surface: %s",
getErrorString(_glfw_eglGetError())); getErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -498,7 +487,7 @@ int _glfwCreateContext(_GLFWwindow* window,
// Destroy the OpenGL context // Destroy the OpenGL context
// //
void _glfwDestroyContext(_GLFWwindow* window) void _glfwDestroyContextEGL(_GLFWwindow* window)
{ {
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
// NOTE: Do not unload libGL.so.1 while the X11 display is still open, // NOTE: Do not unload libGL.so.1 while the X11 display is still open,
@ -515,13 +504,13 @@ void _glfwDestroyContext(_GLFWwindow* window)
if (window->context.egl.surface) if (window->context.egl.surface)
{ {
_glfw_eglDestroySurface(_glfw.egl.display, window->context.egl.surface); eglDestroySurface(_glfw.egl.display, window->context.egl.surface);
window->context.egl.surface = EGL_NO_SURFACE; window->context.egl.surface = EGL_NO_SURFACE;
} }
if (window->context.egl.handle) if (window->context.egl.handle)
{ {
_glfw_eglDestroyContext(_glfw.egl.display, window->context.egl.handle); eglDestroyContext(_glfw.egl.display, window->context.egl.handle);
window->context.egl.handle = EGL_NO_CONTEXT; window->context.egl.handle = EGL_NO_CONTEXT;
} }
} }
@ -529,9 +518,9 @@ void _glfwDestroyContext(_GLFWwindow* window)
// Returns the Visual and depth of the chosen EGLConfig // Returns the Visual and depth of the chosen EGLConfig
// //
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
GLFWbool _glfwChooseVisual(const _GLFWctxconfig* ctxconfig, GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig, const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth) Visual** visual, int* depth)
{ {
XVisualInfo* result; XVisualInfo* result;
XVisualInfo desired; XVisualInfo desired;
@ -546,8 +535,8 @@ GLFWbool _glfwChooseVisual(const _GLFWctxconfig* ctxconfig,
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfw_eglGetConfigAttrib(_glfw.egl.display, native, eglGetConfigAttrib(_glfw.egl.display, native,
EGL_NATIVE_VISUAL_ID, &visualID); EGL_NATIVE_VISUAL_ID, &visualID);
desired.screen = _glfw.x11.screen; desired.screen = _glfw.x11.screen;
desired.visualid = visualID; desired.visualid = visualID;
@ -577,36 +566,35 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
{ {
if (window) if (window)
{ {
_glfw_eglMakeCurrent(_glfw.egl.display, eglMakeCurrent(_glfw.egl.display,
window->context.egl.surface, window->context.egl.surface,
window->context.egl.surface, window->context.egl.surface,
window->context.egl.handle); window->context.egl.handle);
} }
else else
{ {
_glfw_eglMakeCurrent(_glfw.egl.display, eglMakeCurrent(_glfw.egl.display,
EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT); EGL_NO_CONTEXT);
} }
_glfwSetContextTLS(window); _glfwPlatformSetCurrentContext(window);
} }
void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window)
{ {
_glfw_eglSwapBuffers(_glfw.egl.display, window->context.egl.surface); eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
} }
void _glfwPlatformSwapInterval(int interval) void _glfwPlatformSwapInterval(int interval)
{ {
_glfw_eglSwapInterval(_glfw.egl.display, interval); eglSwapInterval(_glfw.egl.display, interval);
} }
int _glfwPlatformExtensionSupported(const char* extension) int _glfwPlatformExtensionSupported(const char* extension)
{ {
const char* extensions = _glfw_eglQueryString(_glfw.egl.display, const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
EGL_EXTENSIONS);
if (extensions) if (extensions)
{ {
if (_glfwStringInExtensionString(extension, extensions)) if (_glfwStringInExtensionString(extension, extensions))
@ -628,7 +616,7 @@ GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
return proc; return proc;
} }
return _glfw_eglGetProcAddress(procname); return eglGetProcAddress(procname);
} }

View File

@ -96,6 +96,12 @@ typedef MirEGLNativeWindowType EGLNativeWindowType;
#define EGL_NONE 0x3038 #define EGL_NONE 0x3038
#define EGL_EXTENSIONS 0x3055 #define EGL_EXTENSIONS 0x3055
#define EGL_CONTEXT_CLIENT_VERSION 0x3098 #define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_NATIVE_VISUAL_ID 0x302e
#define EGL_NO_SURFACE ((EGLSurface) 0)
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
#define EGL_NO_CONTEXT ((EGLContext) 0)
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 #define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 #define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002 #define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
@ -106,13 +112,9 @@ typedef MirEGLNativeWindowType EGLNativeWindowType;
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004 #define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 #define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb #define EGL_CONTEXT_MINOR_VERSION_KHR 0x30fb
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD #define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30fd
#define EGL_CONTEXT_FLAGS_KHR 0x30fc #define EGL_CONTEXT_FLAGS_KHR 0x30fc
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3 #define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3
#define EGL_NATIVE_VISUAL_ID 0x302e
#define EGL_NO_SURFACE ((EGLSurface) 0)
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
#define EGL_NO_CONTEXT ((EGLContext) 0)
typedef int EGLint; typedef int EGLint;
typedef unsigned int EGLBoolean; typedef unsigned int EGLBoolean;
@ -139,22 +141,22 @@ typedef EGLBoolean (EGLAPIENTRY * PFNEGLSWAPBUFFERSPROC)(EGLDisplay,EGLSurface);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSWAPINTERVALPROC)(EGLDisplay,EGLint); typedef EGLBoolean (EGLAPIENTRY * PFNEGLSWAPINTERVALPROC)(EGLDisplay,EGLint);
typedef const char* (EGLAPIENTRY * PFNEGLQUERYSTRINGPROC)(EGLDisplay,EGLint); typedef const char* (EGLAPIENTRY * PFNEGLQUERYSTRINGPROC)(EGLDisplay,EGLint);
typedef GLFWglproc (EGLAPIENTRY * PFNEGLGETPROCADDRESSPROC)(const char*); typedef GLFWglproc (EGLAPIENTRY * PFNEGLGETPROCADDRESSPROC)(const char*);
#define _glfw_eglGetConfigAttrib _glfw.egl.GetConfigAttrib #define eglGetConfigAttrib _glfw.egl.GetConfigAttrib
#define _glfw_eglGetConfigs _glfw.egl.GetConfigs #define eglGetConfigs _glfw.egl.GetConfigs
#define _glfw_eglGetDisplay _glfw.egl.GetDisplay #define eglGetDisplay _glfw.egl.GetDisplay
#define _glfw_eglGetError _glfw.egl.GetError #define eglGetError _glfw.egl.GetError
#define _glfw_eglInitialize _glfw.egl.Initialize #define eglInitialize _glfw.egl.Initialize
#define _glfw_eglTerminate _glfw.egl.Terminate #define eglTerminate _glfw.egl.Terminate
#define _glfw_eglBindAPI _glfw.egl.BindAPI #define eglBindAPI _glfw.egl.BindAPI
#define _glfw_eglCreateContext _glfw.egl.CreateContext #define eglCreateContext _glfw.egl.CreateContext
#define _glfw_eglDestroySurface _glfw.egl.DestroySurface #define eglDestroySurface _glfw.egl.DestroySurface
#define _glfw_eglDestroyContext _glfw.egl.DestroyContext #define eglDestroyContext _glfw.egl.DestroyContext
#define _glfw_eglCreateWindowSurface _glfw.egl.CreateWindowSurface #define eglCreateWindowSurface _glfw.egl.CreateWindowSurface
#define _glfw_eglMakeCurrent _glfw.egl.MakeCurrent #define eglMakeCurrent _glfw.egl.MakeCurrent
#define _glfw_eglSwapBuffers _glfw.egl.SwapBuffers #define eglSwapBuffers _glfw.egl.SwapBuffers
#define _glfw_eglSwapInterval _glfw.egl.SwapInterval #define eglSwapInterval _glfw.egl.SwapInterval
#define _glfw_eglQueryString _glfw.egl.QueryString #define eglQueryString _glfw.egl.QueryString
#define _glfw_eglGetProcAddress _glfw.egl.GetProcAddress #define eglGetProcAddress _glfw.egl.GetProcAddress
#define _GLFW_PLATFORM_FBCONFIG EGLConfig egl #define _GLFW_PLATFORM_FBCONFIG EGLConfig egl
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextEGL egl #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextEGL egl
@ -206,16 +208,16 @@ typedef struct _GLFWlibraryEGL
} _GLFWlibraryEGL; } _GLFWlibraryEGL;
int _glfwInitContextAPI(void); GLFWbool _glfwInitEGL(void);
void _glfwTerminateContextAPI(void); void _glfwTerminateEGL(void);
int _glfwCreateContext(_GLFWwindow* window, GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig); const _GLFWfbconfig* fbconfig);
void _glfwDestroyContext(_GLFWwindow* window); void _glfwDestroyContextEGL(_GLFWwindow* window);
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
GLFWbool _glfwChooseVisual(const _GLFWctxconfig* ctxconfig, GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig, const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth); Visual** visual, int* depth);
#endif /*_GLFW_X11*/ #endif /*_GLFW_X11*/
#endif // _glfw3_egl_context_h_ #endif // _glfw3_egl_context_h_

View File

@ -42,7 +42,7 @@
static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib) static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
{ {
int value; int value;
_glfw_glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value); glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);
return value; return value;
} }
@ -59,12 +59,12 @@ static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result
// HACK: This is a (hopefully temporary) workaround for Chromium // HACK: This is a (hopefully temporary) workaround for Chromium
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs // (VirtualBox GL) not setting the window bit on any GLXFBConfigs
vendor = _glfw_glXGetClientString(_glfw.x11.display, GLX_VENDOR); vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
if (strcmp(vendor, "Chromium") == 0) if (strcmp(vendor, "Chromium") == 0)
trustWindowBit = GLFW_FALSE; trustWindowBit = GLFW_FALSE;
nativeConfigs = _glfw_glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, nativeConfigs =
&nativeCount); glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
if (!nativeCount) if (!nativeCount)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned"); _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
@ -136,11 +136,11 @@ static GLXContext createLegacyContext(_GLFWwindow* window,
GLXFBConfig fbconfig, GLXFBConfig fbconfig,
GLXContext share) GLXContext share)
{ {
return _glfw_glXCreateNewContext(_glfw.x11.display, return glXCreateNewContext(_glfw.x11.display,
fbconfig, fbconfig,
GLX_RGBA_TYPE, GLX_RGBA_TYPE,
share, share,
True); True);
} }
@ -150,7 +150,7 @@ static GLXContext createLegacyContext(_GLFWwindow* window,
// Initialize GLX // Initialize GLX
// //
int _glfwInitContextAPI(void) GLFWbool _glfwInitGLX(void)
{ {
int i; int i;
const char* sonames[] = const char* sonames[] =
@ -165,9 +165,6 @@ int _glfwInitContextAPI(void)
}; };
if (!_glfwCreateContextTLS())
return GLFW_FALSE;
for (i = 0; sonames[i]; i++) for (i = 0; sonames[i]; i++)
{ {
_glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL); _glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL);
@ -212,17 +209,15 @@ int _glfwInitContextAPI(void)
_glfw.glx.GetVisualFromFBConfig = _glfw.glx.GetVisualFromFBConfig =
dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig"); dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
if (!_glfw_glXQueryExtension(_glfw.x11.display, if (!glXQueryExtension(_glfw.x11.display,
&_glfw.glx.errorBase, &_glfw.glx.errorBase,
&_glfw.glx.eventBase)) &_glfw.glx.eventBase))
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found"); _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");
return GLFW_FALSE; return GLFW_FALSE;
} }
if (!_glfw_glXQueryVersion(_glfw.x11.display, if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor))
&_glfw.glx.major,
&_glfw.glx.minor))
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: Failed to query GLX version"); "GLX: Failed to query GLX version");
@ -298,18 +293,16 @@ int _glfwInitContextAPI(void)
// Terminate GLX // Terminate GLX
// //
void _glfwTerminateContextAPI(void) void _glfwTerminateGLX(void)
{ {
// NOTE: This function may not call any X11 functions, as it is called after // NOTE: This function must not call any X11 functions, as it is called
// XCloseDisplay (see _glfwPlatformTerminate for details) // after XCloseDisplay (see _glfwPlatformTerminate for details)
if (_glfw.glx.handle) if (_glfw.glx.handle)
{ {
dlclose(_glfw.glx.handle); dlclose(_glfw.glx.handle);
_glfw.glx.handle = NULL; _glfw.glx.handle = NULL;
} }
_glfwDestroyContextTLS();
} }
#define setGLXattrib(attribName, attribValue) \ #define setGLXattrib(attribName, attribValue) \
@ -321,9 +314,9 @@ void _glfwTerminateContextAPI(void)
// Create the OpenGL or OpenGL ES context // Create the OpenGL or OpenGL ES context
// //
int _glfwCreateContext(_GLFWwindow* window, GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
int attribs[40]; int attribs[40];
GLXFBConfig native = NULL; GLXFBConfig native = NULL;
@ -372,7 +365,7 @@ int _glfwCreateContext(_GLFWwindow* window,
} }
} }
_glfwGrabXErrorHandler(); _glfwGrabErrorHandlerX11();
if (_glfw.glx.ARB_create_context) if (_glfw.glx.ARB_create_context)
{ {
@ -475,16 +468,16 @@ int _glfwCreateContext(_GLFWwindow* window,
else else
window->context.glx.handle = createLegacyContext(window, native, share); window->context.glx.handle = createLegacyContext(window, native, share);
_glfwReleaseXErrorHandler(); _glfwReleaseErrorHandlerX11();
if (!window->context.glx.handle) if (!window->context.glx.handle)
{ {
_glfwInputXError(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context"); _glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
return GLFW_FALSE; return GLFW_FALSE;
} }
window->context.glx.window = _glfw_glXCreateWindow(_glfw.x11.display, native, window->context.glx.window =
window->x11.handle, NULL); glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL);
if (!window->context.glx.window) if (!window->context.glx.window)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window"); _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
@ -498,26 +491,26 @@ int _glfwCreateContext(_GLFWwindow* window,
// Destroy the OpenGL context // Destroy the OpenGL context
// //
void _glfwDestroyContext(_GLFWwindow* window) void _glfwDestroyContextGLX(_GLFWwindow* window)
{ {
if (window->context.glx.window) if (window->context.glx.window)
{ {
_glfw_glXDestroyWindow(_glfw.x11.display, window->context.glx.window); glXDestroyWindow(_glfw.x11.display, window->context.glx.window);
window->context.glx.window = None; window->context.glx.window = None;
} }
if (window->context.glx.handle) if (window->context.glx.handle)
{ {
_glfw_glXDestroyContext(_glfw.x11.display, window->context.glx.handle); glXDestroyContext(_glfw.x11.display, window->context.glx.handle);
window->context.glx.handle = NULL; window->context.glx.handle = NULL;
} }
} }
// Returns the Visual and depth of the chosen GLXFBConfig // Returns the Visual and depth of the chosen GLXFBConfig
// //
GLFWbool _glfwChooseVisual(const _GLFWctxconfig* ctxconfig, GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig, const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth) Visual** visual, int* depth)
{ {
GLXFBConfig native; GLXFBConfig native;
XVisualInfo* result; XVisualInfo* result;
@ -529,7 +522,7 @@ GLFWbool _glfwChooseVisual(const _GLFWctxconfig* ctxconfig,
return GLFW_FALSE; return GLFW_FALSE;
} }
result = _glfw_glXGetVisualFromFBConfig(_glfw.x11.display, native); result = glXGetVisualFromFBConfig(_glfw.x11.display, native);
if (!result) if (!result)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -553,19 +546,19 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
{ {
if (window) if (window)
{ {
_glfw_glXMakeCurrent(_glfw.x11.display, glXMakeCurrent(_glfw.x11.display,
window->context.glx.window, window->context.glx.window,
window->context.glx.handle); window->context.glx.handle);
} }
else else
_glfw_glXMakeCurrent(_glfw.x11.display, None, NULL); glXMakeCurrent(_glfw.x11.display, None, NULL);
_glfwSetContextTLS(window); _glfwPlatformSetCurrentContext(window);
} }
void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window)
{ {
_glfw_glXSwapBuffers(_glfw.x11.display, window->context.glx.window); glXSwapBuffers(_glfw.x11.display, window->context.glx.window);
} }
void _glfwPlatformSwapInterval(int interval) void _glfwPlatformSwapInterval(int interval)
@ -590,7 +583,7 @@ void _glfwPlatformSwapInterval(int interval)
int _glfwPlatformExtensionSupported(const char* extension) int _glfwPlatformExtensionSupported(const char* extension)
{ {
const char* extensions = const char* extensions =
_glfw_glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen); glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
if (extensions) if (extensions)
{ {
if (_glfwStringInExtensionString(extension, extensions)) if (_glfwStringInExtensionString(extension, extensions))

View File

@ -49,6 +49,7 @@
#define GLX_ACCUM_ALPHA_SIZE 17 #define GLX_ACCUM_ALPHA_SIZE 17
#define GLX_SAMPLES 0x186a1 #define GLX_SAMPLES 0x186a1
#define GLX_VISUAL_ID 0x800b #define GLX_VISUAL_ID 0x800b
#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20b2 #define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20b2
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 #define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
@ -93,19 +94,19 @@ typedef GLXWindow (*PFNGLXCREATEWINDOWPROC)(Display*,GLXFBConfig,Window,const in
typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow); typedef void (*PFNGLXDESTROYWINDOWPROC)(Display*,GLXWindow);
// libGL.so function pointer typedefs // libGL.so function pointer typedefs
#define _glfw_glXGetFBConfigs _glfw.glx.GetFBConfigs #define glXGetFBConfigs _glfw.glx.GetFBConfigs
#define _glfw_glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib #define glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
#define _glfw_glXGetClientString _glfw.glx.GetClientString #define glXGetClientString _glfw.glx.GetClientString
#define _glfw_glXQueryExtension _glfw.glx.QueryExtension #define glXQueryExtension _glfw.glx.QueryExtension
#define _glfw_glXQueryVersion _glfw.glx.QueryVersion #define glXQueryVersion _glfw.glx.QueryVersion
#define _glfw_glXDestroyContext _glfw.glx.DestroyContext #define glXDestroyContext _glfw.glx.DestroyContext
#define _glfw_glXMakeCurrent _glfw.glx.MakeCurrent #define glXMakeCurrent _glfw.glx.MakeCurrent
#define _glfw_glXSwapBuffers _glfw.glx.SwapBuffers #define glXSwapBuffers _glfw.glx.SwapBuffers
#define _glfw_glXQueryExtensionsString _glfw.glx.QueryExtensionsString #define glXQueryExtensionsString _glfw.glx.QueryExtensionsString
#define _glfw_glXCreateNewContext _glfw.glx.CreateNewContext #define glXCreateNewContext _glfw.glx.CreateNewContext
#define _glfw_glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig #define glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig
#define _glfw_glXCreateWindow _glfw.glx.CreateWindow #define glXCreateWindow _glfw.glx.CreateWindow
#define _glfw_glXDestroyWindow _glfw.glx.DestroyWindow #define glXDestroyWindow _glfw.glx.DestroyWindow
#define _GLFW_PLATFORM_FBCONFIG GLXFBConfig glx #define _GLFW_PLATFORM_FBCONFIG GLXFBConfig glx
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx
@ -170,14 +171,14 @@ typedef struct _GLFWlibraryGLX
} _GLFWlibraryGLX; } _GLFWlibraryGLX;
int _glfwInitContextAPI(void); GLFWbool _glfwInitGLX(void);
void _glfwTerminateContextAPI(void); void _glfwTerminateGLX(void);
int _glfwCreateContext(_GLFWwindow* window, GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig); const _GLFWfbconfig* fbconfig);
void _glfwDestroyContext(_GLFWwindow* window); void _glfwDestroyContextGLX(_GLFWwindow* window);
GLFWbool _glfwChooseVisual(const _GLFWctxconfig* ctxconfig, GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig, const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth); Visual** visual, int* depth);
#endif // _glfw3_glx_context_h_ #endif // _glfw3_glx_context_h_

View File

@ -28,9 +28,6 @@
#include "internal.h" #include "internal.h"
#include <stdlib.h> #include <stdlib.h>
#if defined(_MSC_VER)
#include <malloc.h>
#endif
// Internal key state used for sticky keys // Internal key state used for sticky keys
#define _GLFW_STICK 3 #define _GLFW_STICK 3

View File

@ -41,7 +41,7 @@
defined(GLFW_INCLUDE_GLEXT) || \ defined(GLFW_INCLUDE_GLEXT) || \
defined(GLFW_INCLUDE_GLU) || \ defined(GLFW_INCLUDE_GLU) || \
defined(GLFW_DLL) defined(GLFW_DLL)
#error "You may not define any header option macros when compiling GLFW" #error "You must not define any header option macros when compiling GLFW"
#endif #endif
#define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE
@ -124,7 +124,7 @@ typedef int GLFWbool;
* @brief Various utility functions for internal use. * @brief Various utility functions for internal use.
* *
* These functions are shared code and may be used by any part of GLFW * These functions are shared code and may be used by any part of GLFW
* Each platform may add its own utility functions, but those may only be * Each platform may add its own utility functions, but those must only be
* called by the platform-specific code * called by the platform-specific code
*/ */
@ -231,10 +231,10 @@ struct _GLFWfbconfig
int accumBlueBits; int accumBlueBits;
int accumAlphaBits; int accumAlphaBits;
int auxBuffers; int auxBuffers;
int stereo; GLFWbool stereo;
int samples; int samples;
int sRGB; GLFWbool sRGB;
int doublebuffer; GLFWbool doublebuffer;
// This is defined in the context API's context.h // This is defined in the context API's context.h
_GLFW_PLATFORM_FBCONFIG; _GLFW_PLATFORM_FBCONFIG;
@ -637,6 +637,10 @@ void _glfwPlatformPostEmptyEvent(void);
*/ */
void _glfwPlatformMakeContextCurrent(_GLFWwindow* window); void _glfwPlatformMakeContextCurrent(_GLFWwindow* window);
/*! @ingroup platform
*/
void _glfwPlatformSetCurrentContext(_GLFWwindow* context);
/*! @copydoc glfwGetCurrentContext /*! @copydoc glfwGetCurrentContext
* @ingroup platform * @ingroup platform
*/ */
@ -914,6 +918,6 @@ void _glfwFreeMonitors(_GLFWmonitor** monitors, int count);
/*! @ingroup utility /*! @ingroup utility
*/ */
int _glfwIsPrintable(int key); GLFWbool _glfwIsPrintable(int key);
#endif // _glfw3_internal_h_ #endif // _glfw3_internal_h_

View File

@ -45,12 +45,13 @@
// Attempt to open the specified joystick device // Attempt to open the specified joystick device
// //
static void openJoystickDevice(const char* path) static GLFWbool openJoystickDevice(const char* path)
{ {
#if defined(__linux__) #if defined(__linux__)
char axisCount, buttonCount; char axisCount, buttonCount;
char name[256]; char name[256];
int joy, fd, version; int joy, fd, version;
_GLFWjoystickLinux* js;
for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++)
{ {
@ -58,7 +59,7 @@ static void openJoystickDevice(const char* path)
continue; continue;
if (strcmp(_glfw.linux_js.js[joy].path, path) == 0) if (strcmp(_glfw.linux_js.js[joy].path, path) == 0)
return; return GLFW_FALSE;
} }
for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++)
@ -68,13 +69,11 @@ static void openJoystickDevice(const char* path)
} }
if (joy > GLFW_JOYSTICK_LAST) if (joy > GLFW_JOYSTICK_LAST)
return; return GLFW_FALSE;
fd = open(path, O_RDONLY | O_NONBLOCK); fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd == -1) if (fd == -1)
return; return GLFW_FALSE;
_glfw.linux_js.js[joy].fd = fd;
// Verify that the joystick driver version is at least 1.0 // Verify that the joystick driver version is at least 1.0
ioctl(fd, JSIOCGVERSION, &version); ioctl(fd, JSIOCGVERSION, &version);
@ -82,35 +81,34 @@ static void openJoystickDevice(const char* path)
{ {
// It's an old 0.x interface (we don't support it) // It's an old 0.x interface (we don't support it)
close(fd); close(fd);
return; return GLFW_FALSE;
} }
if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0) if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0)
strncpy(name, "Unknown", sizeof(name)); strncpy(name, "Unknown", sizeof(name));
_glfw.linux_js.js[joy].name = strdup(name); js = _glfw.linux_js.js + joy;
_glfw.linux_js.js[joy].path = strdup(path); js->present = GLFW_TRUE;
js->name = strdup(name);
js->path = strdup(path);
js->fd = fd;
ioctl(fd, JSIOCGAXES, &axisCount); ioctl(fd, JSIOCGAXES, &axisCount);
_glfw.linux_js.js[joy].axisCount = (int) axisCount; js->axisCount = (int) axisCount;
js->axes = calloc(axisCount, sizeof(float));
ioctl(fd, JSIOCGBUTTONS, &buttonCount); ioctl(fd, JSIOCGBUTTONS, &buttonCount);
_glfw.linux_js.js[joy].buttonCount = (int) buttonCount; js->buttonCount = (int) buttonCount;
js->buttons = calloc(buttonCount, 1);
_glfw.linux_js.js[joy].axes = calloc(axisCount, sizeof(float));
_glfw.linux_js.js[joy].buttons = calloc(buttonCount, 1);
_glfw.linux_js.js[joy].present = GLFW_TRUE;
#endif // __linux__ #endif // __linux__
return GLFW_TRUE;
} }
// Polls for and processes events for all present joysticks // Polls for and processes events the specified joystick
// //
static void pollJoystickEvents(void) static GLFWbool pollJoystickEvents(_GLFWjoystickLinux* js)
{ {
#if defined(__linux__) #if defined(__linux__)
int i;
struct js_event e;
ssize_t offset = 0; ssize_t offset = 0;
char buffer[16384]; char buffer[16384];
@ -131,53 +129,50 @@ static void pollJoystickEvents(void)
offset += sizeof(struct inotify_event) + e->len; offset += sizeof(struct inotify_event) + e->len;
} }
for (i = 0; i <= GLFW_JOYSTICK_LAST; i++) if (!js->present)
return GLFW_FALSE;
// Read all queued events (non-blocking)
for (;;)
{ {
if (!_glfw.linux_js.js[i].present) struct js_event e;
continue;
// Read all queued events (non-blocking) errno = 0;
for (;;) if (read(js->fd, &e, sizeof(e)) < 0)
{ {
errno = 0; // Reset the joystick slot if the device was disconnected
if (read(_glfw.linux_js.js[i].fd, &e, sizeof(e)) < 0) if (errno == ENODEV)
{ {
if (errno == ENODEV) free(js->axes);
{ free(js->buttons);
// The joystick was disconnected free(js->name);
free(js->path);
free(_glfw.linux_js.js[i].axes); memset(js, 0, sizeof(_GLFWjoystickLinux));
free(_glfw.linux_js.js[i].buttons);
free(_glfw.linux_js.js[i].name);
free(_glfw.linux_js.js[i].path);
memset(&_glfw.linux_js.js[i], 0, sizeof(_glfw.linux_js.js[i]));
}
break;
} }
// We don't care if it's an init event or not break;
e.type &= ~JS_EVENT_INIT;
switch (e.type)
{
case JS_EVENT_AXIS:
_glfw.linux_js.js[i].axes[e.number] =
(float) e.value / 32767.0f;
break;
case JS_EVENT_BUTTON:
_glfw.linux_js.js[i].buttons[e.number] =
e.value ? GLFW_PRESS : GLFW_RELEASE;
break;
default:
break;
}
} }
// Clear the initial-state bit
e.type &= ~JS_EVENT_INIT;
if (e.type == JS_EVENT_AXIS)
js->axes[e.number] = (float) e.value / 32767.0f;
else if (e.type == JS_EVENT_BUTTON)
js->buttons[e.number] = e.value ? GLFW_PRESS : GLFW_RELEASE;
} }
#endif // __linux__ #endif // __linux__
return js->present;
}
// Lexically compare joysticks, used by quicksort
//
static int compareJoysticks(const void* fp, const void* sp)
{
const _GLFWjoystickLinux* fj = fp;
const _GLFWjoystickLinux* sj = sp;
return strcmp(fj->path, sj->path);
} }
@ -187,11 +182,12 @@ static void pollJoystickEvents(void)
// Initialize joystick interface // Initialize joystick interface
// //
int _glfwInitJoysticks(void) GLFWbool _glfwInitJoysticksLinux(void)
{ {
#if defined(__linux__) #if defined(__linux__)
const char* dirname = "/dev/input";
DIR* dir; DIR* dir;
int count = 0;
const char* dirname = "/dev/input";
_glfw.linux_js.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); _glfw.linux_js.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (_glfw.linux_js.inotify == -1) if (_glfw.linux_js.inotify == -1)
@ -237,7 +233,8 @@ int _glfwInitJoysticks(void)
continue; continue;
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name); snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
openJoystickDevice(path); if (openJoystickDevice(path))
count++;
} }
closedir(dir); closedir(dir);
@ -251,6 +248,7 @@ int _glfwInitJoysticks(void)
// Continue with no joysticks detected // Continue with no joysticks detected
} }
qsort(_glfw.linux_js.js, count, sizeof(_GLFWjoystickLinux), compareJoysticks);
#endif // __linux__ #endif // __linux__
return GLFW_TRUE; return GLFW_TRUE;
@ -258,7 +256,7 @@ int _glfwInitJoysticks(void)
// Close all opened joystick handles // Close all opened joystick handles
// //
void _glfwTerminateJoysticks(void) void _glfwTerminateJoysticksLinux(void)
{ {
#if defined(__linux__) #if defined(__linux__)
int i; int i;
@ -294,31 +292,36 @@ void _glfwTerminateJoysticks(void)
int _glfwPlatformJoystickPresent(int joy) int _glfwPlatformJoystickPresent(int joy)
{ {
pollJoystickEvents(); _GLFWjoystickLinux* js = _glfw.linux_js.js + joy;
return pollJoystickEvents(js);
return _glfw.linux_js.js[joy].present;
} }
const float* _glfwPlatformGetJoystickAxes(int joy, int* count) const float* _glfwPlatformGetJoystickAxes(int joy, int* count)
{ {
pollJoystickEvents(); _GLFWjoystickLinux* js = _glfw.linux_js.js + joy;
if (!pollJoystickEvents(js))
return NULL;
*count = _glfw.linux_js.js[joy].axisCount; *count = js->axisCount;
return _glfw.linux_js.js[joy].axes; return js->axes;
} }
const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
{ {
pollJoystickEvents(); _GLFWjoystickLinux* js = _glfw.linux_js.js + joy;
if (!pollJoystickEvents(js))
return NULL;
*count = _glfw.linux_js.js[joy].buttonCount; *count = js->buttonCount;
return _glfw.linux_js.js[joy].buttons; return js->buttons;
} }
const char* _glfwPlatformGetJoystickName(int joy) const char* _glfwPlatformGetJoystickName(int joy)
{ {
pollJoystickEvents(); _GLFWjoystickLinux* js = _glfw.linux_js.js + joy;
if (!pollJoystickEvents(js))
return NULL;
return _glfw.linux_js.js[joy].name; return js->name;
} }

View File

@ -29,35 +29,39 @@
#include <regex.h> #include <regex.h>
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWjoylistLinux linux_js
_GLFWjoystickLinux linux_js
// Linux-specific joystick data
//
typedef struct _GLFWjoystickLinux
{
GLFWbool present;
int fd;
float* axes;
int axisCount;
unsigned char* buttons;
int buttonCount;
char* name;
char* path;
} _GLFWjoystickLinux;
// Linux-specific joystick API data // Linux-specific joystick API data
// //
typedef struct _GLFWjoystickLinux typedef struct _GLFWjoylistLinux
{ {
struct _GLFWjoystickLinux js[GLFW_JOYSTICK_LAST + 1];
{
int present;
int fd;
float* axes;
int axisCount;
unsigned char* buttons;
int buttonCount;
char* name;
char* path;
} js[GLFW_JOYSTICK_LAST + 1];
#if defined(__linux__) #if defined(__linux__)
int inotify; int inotify;
int watch; int watch;
regex_t regex; regex_t regex;
#endif /*__linux__*/ #endif /*__linux__*/
} _GLFWjoystickLinux; } _GLFWjoylistLinux;
int _glfwInitJoysticks(void); GLFWbool _glfwInitJoysticksLinux(void);
void _glfwTerminateJoysticks(void); void _glfwTerminateJoysticksLinux(void);
#endif // _glfw3_linux_joystick_h_ #endif // _glfw3_linux_joystick_h_

View File

@ -179,17 +179,22 @@ int _glfwPlatformInit(void)
createKeyTables(); createKeyTables();
if (!_glfwInitContextAPI()) if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwInitJoysticksLinux())
return GLFW_FALSE;
_glfwInitTimerPOSIX();
// Need the default conf for when we set a NULL cursor // Need the default conf for when we set a NULL cursor
_glfw.mir.default_conf = mir_cursor_configuration_from_name(mir_arrow_cursor_name); _glfw.mir.default_conf = mir_cursor_configuration_from_name(mir_arrow_cursor_name);
_glfwInitTimer();
_glfwInitJoysticks();
_glfw.mir.event_queue = calloc(1, sizeof(EventQueue)); _glfw.mir.event_queue = calloc(1, sizeof(EventQueue));
_glfwInitEventQueue(_glfw.mir.event_queue); _glfwInitEventQueueMir(_glfw.mir.event_queue);
error = pthread_mutex_init(&_glfw.mir.event_mutex, NULL); error = pthread_mutex_init(&_glfw.mir.event_mutex, NULL);
if (error) if (error)
@ -205,10 +210,11 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void) void _glfwPlatformTerminate(void)
{ {
_glfwTerminateContextAPI(); _glfwTerminateEGL();
_glfwTerminateJoysticks(); _glfwTerminateJoysticksLinux();
_glfwTerminateThreadLocalStoragePOSIX();
_glfwDeleteEventQueue(_glfw.mir.event_queue); _glfwDeleteEventQueueMir(_glfw.mir.event_queue);
pthread_mutex_destroy(&_glfw.mir.event_mutex); pthread_mutex_destroy(&_glfw.mir.event_mutex);

View File

@ -43,8 +43,8 @@
#error "The Mir backend depends on EGL platform support" #error "The Mir backend depends on EGL platform support"
#endif #endif
#define _GLFW_EGL_NATIVE_WINDOW window->mir.window #define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->mir.window)
#define _GLFW_EGL_NATIVE_DISPLAY _glfw.mir.display #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowMir mir #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowMir mir
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorMir mir #define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorMir mir
@ -110,7 +110,7 @@ typedef struct _GLFWcursorMir
} _GLFWcursorMir; } _GLFWcursorMir;
extern void _glfwInitEventQueue(EventQueue* queue); extern void _glfwInitEventQueueMir(EventQueue* queue);
extern void _glfwDeleteEventQueue(EventQueue* queue); extern void _glfwDeleteEventQueueMir(EventQueue* queue);
#endif // _glfw3_mir_platform_h_ #endif // _glfw3_mir_platform_h_

View File

@ -310,12 +310,12 @@ static GLFWbool createSurface(_GLFWwindow* window)
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwInitEventQueue(EventQueue* queue) void _glfwInitEventQueueMir(EventQueue* queue)
{ {
TAILQ_INIT(&queue->head); TAILQ_INIT(&queue->head);
} }
void _glfwDeleteEventQueue(EventQueue* queue) void _glfwDeleteEventQueueMir(EventQueue* queue)
{ {
if (queue) if (queue)
{ {
@ -347,7 +347,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
{ {
if (ctxconfig->api != GLFW_NO_API) if (ctxconfig->api != GLFW_NO_API)
{ {
if (!_glfwCreateContext(window, ctxconfig, fbconfig)) if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -388,7 +388,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
window->mir.surface = NULL; window->mir.surface = NULL;
} }
_glfwDestroyContext(window); _glfwDestroyContextEGL(window);
} }
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)

View File

@ -34,28 +34,27 @@
#include <limits.h> #include <limits.h>
// Lexical comparison function for GLFW video modes, used by qsort // Lexically compare video modes, used by qsort
// //
static int compareVideoModes(const void* firstPtr, const void* secondPtr) static int compareVideoModes(const void* fp, const void* sp)
{ {
int firstBPP, secondBPP, firstSize, secondSize; const GLFWvidmode* fm = fp;
const GLFWvidmode* first = firstPtr; const GLFWvidmode* sm = sp;
const GLFWvidmode* second = secondPtr; const int fbpp = fm->redBits + fm->greenBits + fm->blueBits;
const int sbpp = sm->redBits + sm->greenBits + sm->blueBits;
const int farea = fm->width * fm->height;
const int sarea = sm->width * sm->height;
// First sort on color bits per pixel // First sort on color bits per pixel
firstBPP = first->redBits + first->greenBits + first->blueBits; if (fbpp != sbpp)
secondBPP = second->redBits + second->greenBits + second->blueBits; return fbpp - sbpp;
if (firstBPP != secondBPP)
return firstBPP - secondBPP;
// Then sort on screen area, in pixels // Then sort on screen area
firstSize = first->width * first->height; if (farea != sarea)
secondSize = second->width * second->height; return farea - sarea;
if (firstSize != secondSize)
return firstSize - secondSize;
// Lastly sort on refresh rate // Lastly sort on refresh rate
return first->refreshRate - second->refreshRate; return fm->refreshRate - sm->refreshRate;
} }
// Retrieves the available modes for the specified monitor // Retrieves the available modes for the specified monitor
@ -263,9 +262,9 @@ const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
return closest; return closest;
} }
int _glfwCompareVideoModes(const GLFWvidmode* first, const GLFWvidmode* second) int _glfwCompareVideoModes(const GLFWvidmode* fm, const GLFWvidmode* sm)
{ {
return compareVideoModes(first, second); return compareVideoModes(fm, sm);
} }
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)

View File

@ -47,16 +47,16 @@ typedef struct _GLFWcontextNSGL
typedef struct _GLFWlibraryNSGL typedef struct _GLFWlibraryNSGL
{ {
// dlopen handle for OpenGL.framework (for glfwGetProcAddress) // dlopen handle for OpenGL.framework (for glfwGetProcAddress)
void* framework; CFBundleRef framework;
} _GLFWlibraryNSGL; } _GLFWlibraryNSGL;
int _glfwInitContextAPI(void); GLFWbool _glfwInitNSGL(void);
void _glfwTerminateContextAPI(void); void _glfwTerminateNSGL(void);
int _glfwCreateContext(_GLFWwindow* window, GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig); const _GLFWfbconfig* fbconfig);
void _glfwDestroyContext(_GLFWwindow* window); void _glfwDestroyContextNSGL(_GLFWwindow* window);
#endif // _glfw3_nsgl_context_h_ #endif // _glfw3_nsgl_context_h_

View File

@ -33,11 +33,8 @@
// Initialize OpenGL support // Initialize OpenGL support
// //
int _glfwInitContextAPI(void) GLFWbool _glfwInitNSGL(void)
{ {
if (!_glfwCreateContextTLS())
return GLFW_FALSE;
_glfw.nsgl.framework = _glfw.nsgl.framework =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (_glfw.nsgl.framework == NULL) if (_glfw.nsgl.framework == NULL)
@ -52,16 +49,15 @@ int _glfwInitContextAPI(void)
// Terminate OpenGL support // Terminate OpenGL support
// //
void _glfwTerminateContextAPI(void) void _glfwTerminateNSGL(void)
{ {
_glfwDestroyContextTLS();
} }
// Create the OpenGL context // Create the OpenGL context
// //
int _glfwCreateContext(_GLFWwindow* window, GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
unsigned int attributeCount = 0; unsigned int attributeCount = 0;
@ -225,7 +221,7 @@ int _glfwCreateContext(_GLFWwindow* window,
// Destroy the OpenGL context // Destroy the OpenGL context
// //
void _glfwDestroyContext(_GLFWwindow* window) void _glfwDestroyContextNSGL(_GLFWwindow* window)
{ {
[window->context.nsgl.pixelFormat release]; [window->context.nsgl.pixelFormat release];
window->context.nsgl.pixelFormat = nil; window->context.nsgl.pixelFormat = nil;
@ -246,7 +242,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
else else
[NSOpenGLContext clearCurrentContext]; [NSOpenGLContext clearCurrentContext];
_glfwSetContextTLS(window); _glfwPlatformSetCurrentContext(window);
} }
void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window)

View File

@ -59,7 +59,7 @@ static uint64_t getRawTime(void)
// Initialise timer // Initialise timer
// //
void _glfwInitTimer(void) void _glfwInitTimerPOSIX(void)
{ {
#if defined(CLOCK_MONOTONIC) #if defined(CLOCK_MONOTONIC)
struct timespec ts; struct timespec ts;

View File

@ -44,6 +44,6 @@ typedef struct _GLFWtimePOSIX
} _GLFWtimePOSIX; } _GLFWtimePOSIX;
void _glfwInitTimer(void); void _glfwInitTimerPOSIX(void);
#endif // _glfw3_posix_time_h_ #endif // _glfw3_posix_time_h_

View File

@ -32,7 +32,7 @@
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
GLFWbool _glfwCreateContextTLS(void) GLFWbool _glfwInitThreadLocalStoragePOSIX(void)
{ {
if (pthread_key_create(&_glfw.posix_tls.context, NULL) != 0) if (pthread_key_create(&_glfw.posix_tls.context, NULL) != 0)
{ {
@ -45,22 +45,22 @@ GLFWbool _glfwCreateContextTLS(void)
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwDestroyContextTLS(void) void _glfwTerminateThreadLocalStoragePOSIX(void)
{ {
if (_glfw.posix_tls.allocated) if (_glfw.posix_tls.allocated)
pthread_key_delete(_glfw.posix_tls.context); pthread_key_delete(_glfw.posix_tls.context);
} }
void _glfwSetContextTLS(_GLFWwindow* context)
{
pthread_setspecific(_glfw.posix_tls.context, context);
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformSetCurrentContext(_GLFWwindow* context)
{
pthread_setspecific(_glfw.posix_tls.context, context);
}
_GLFWwindow* _glfwPlatformGetCurrentContext(void) _GLFWwindow* _glfwPlatformGetCurrentContext(void)
{ {
return pthread_getspecific(_glfw.posix_tls.context); return pthread_getspecific(_glfw.posix_tls.context);

View File

@ -43,8 +43,7 @@ typedef struct _GLFWtlsPOSIX
} _GLFWtlsPOSIX; } _GLFWtlsPOSIX;
GLFWbool _glfwCreateContextTLS(void); GLFWbool _glfwInitThreadLocalStoragePOSIX(void);
void _glfwDestroyContextTLS(void); void _glfwTerminateThreadLocalStoragePOSIX(void);
void _glfwSetContextTLS(_GLFWwindow* context);
#endif // _glfw3_posix_tls_h_ #endif // _glfw3_posix_tls_h_

View File

@ -39,21 +39,21 @@ static void loadExtensions(void)
// Functions for WGL_EXT_extension_string // Functions for WGL_EXT_extension_string
// NOTE: These are needed by _glfwPlatformExtensionSupported // NOTE: These are needed by _glfwPlatformExtensionSupported
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) _glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
_glfw_wglGetProcAddress("wglGetExtensionsStringEXT"); wglGetProcAddress("wglGetExtensionsStringEXT");
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) _glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
_glfw_wglGetProcAddress("wglGetExtensionsStringARB"); wglGetProcAddress("wglGetExtensionsStringARB");
// Functions for WGL_ARB_create_context // Functions for WGL_ARB_create_context
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) _glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
_glfw_wglGetProcAddress("wglCreateContextAttribsARB"); wglGetProcAddress("wglCreateContextAttribsARB");
// Functions for WGL_EXT_swap_control // Functions for WGL_EXT_swap_control
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) _glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
_glfw_wglGetProcAddress("wglSwapIntervalEXT"); wglGetProcAddress("wglSwapIntervalEXT");
// Functions for WGL_ARB_pixel_format // Functions for WGL_ARB_pixel_format
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) _glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
_glfw_wglGetProcAddress("wglGetPixelFormatAttribivARB"); wglGetProcAddress("wglGetPixelFormatAttribivARB");
// This needs to include every extension used below except for // This needs to include every extension used below except for
// WGL_ARB_extensions_string and WGL_EXT_extensions_string // WGL_ARB_extensions_string and WGL_EXT_extensions_string
@ -265,6 +265,21 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window,
return GLFW_TRUE; return GLFW_TRUE;
} }
// Returns whether desktop compositing is enabled
//
static GLFWbool isCompositionEnabled(void)
{
BOOL enabled;
if (!_glfw_DwmIsCompositionEnabled)
return FALSE;
if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK)
return FALSE;
return enabled;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW internal API //////
@ -272,11 +287,8 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window,
// Initialize WGL // Initialize WGL
// //
int _glfwInitContextAPI(void) GLFWbool _glfwInitWGL(void)
{ {
if (!_glfwCreateContextTLS())
return GLFW_FALSE;
_glfw.wgl.instance = LoadLibraryA("opengl32.dll"); _glfw.wgl.instance = LoadLibraryA("opengl32.dll");
if (!_glfw.wgl.instance) if (!_glfw.wgl.instance)
{ {
@ -300,12 +312,10 @@ int _glfwInitContextAPI(void)
// Terminate WGL // Terminate WGL
// //
void _glfwTerminateContextAPI(void) void _glfwTerminateWGL(void)
{ {
if (_glfw.wgl.instance) if (_glfw.wgl.instance)
FreeLibrary(_glfw.wgl.instance); FreeLibrary(_glfw.wgl.instance);
_glfwDestroyContextTLS();
} }
#define setWGLattrib(attribName, attribValue) \ #define setWGLattrib(attribName, attribValue) \
@ -317,15 +327,18 @@ void _glfwTerminateContextAPI(void)
// Create the OpenGL or OpenGL ES context // Create the OpenGL or OpenGL ES context
// //
int _glfwCreateContext(_GLFWwindow* window, GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
int attribs[40]; int attribs[40];
int pixelFormat = 0; int pixelFormat = 0;
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
HGLRC share = NULL; HGLRC share = NULL;
if (ctxconfig->api == GLFW_NO_API)
return GLFW_TRUE;
if (ctxconfig->share) if (ctxconfig->share)
share = ctxconfig->share->context.wgl.handle; share = ctxconfig->share->context.wgl.handle;
@ -442,8 +455,7 @@ int _glfwCreateContext(_GLFWwindow* window,
} }
else else
{ {
window->context.wgl.handle = window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
_glfw_wglCreateContext(window->context.wgl.dc);
if (!window->context.wgl.handle) if (!window->context.wgl.handle)
{ {
_glfwInputError(GLFW_VERSION_UNAVAILABLE, _glfwInputError(GLFW_VERSION_UNAVAILABLE,
@ -453,7 +465,7 @@ int _glfwCreateContext(_GLFWwindow* window,
if (share) if (share)
{ {
if (!_glfw_wglShareLists(share, window->context.wgl.handle)) if (!wglShareLists(share, window->context.wgl.handle))
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to enable sharing with specified OpenGL context"); "WGL: Failed to enable sharing with specified OpenGL context");
@ -469,20 +481,20 @@ int _glfwCreateContext(_GLFWwindow* window,
// Destroy the OpenGL context // Destroy the OpenGL context
// //
void _glfwDestroyContext(_GLFWwindow* window) void _glfwDestroyContextWGL(_GLFWwindow* window)
{ {
if (window->context.wgl.handle) if (window->context.wgl.handle)
{ {
_glfw_wglDeleteContext(window->context.wgl.handle); wglDeleteContext(window->context.wgl.handle);
window->context.wgl.handle = NULL; window->context.wgl.handle = NULL;
} }
} }
// Analyzes the specified context for possible recreation // Analyzes the specified context for possible recreation
// //
int _glfwAnalyzeContext(_GLFWwindow* window, int _glfwAnalyzeContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
GLFWbool required = GLFW_FALSE; GLFWbool required = GLFW_FALSE;
@ -582,20 +594,17 @@ int _glfwAnalyzeContext(_GLFWwindow* window,
void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
{ {
if (window) if (window)
{ wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle);
_glfw_wglMakeCurrent(window->context.wgl.dc,
window->context.wgl.handle);
}
else else
_glfw_wglMakeCurrent(NULL, NULL); wglMakeCurrent(NULL, NULL);
_glfwSetContextTLS(window); _glfwPlatformSetCurrentContext(window);
} }
void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window)
{ {
// HACK: Use DwmFlush when desktop composition is enabled // HACK: Use DwmFlush when desktop composition is enabled
if (_glfwIsCompositionEnabled() && !window->monitor) if (isCompositionEnabled() && !window->monitor)
{ {
int count = abs(window->context.wgl.interval); int count = abs(window->context.wgl.interval);
while (count--) while (count--)
@ -613,7 +622,7 @@ void _glfwPlatformSwapInterval(int interval)
// HACK: Disable WGL swap interval when desktop composition is enabled to // HACK: Disable WGL swap interval when desktop composition is enabled to
// avoid interfering with DWM vsync // avoid interfering with DWM vsync
if (_glfwIsCompositionEnabled() && !window->monitor) if (isCompositionEnabled() && !window->monitor)
interval = 0; interval = 0;
if (_glfw.wgl.EXT_swap_control) if (_glfw.wgl.EXT_swap_control)
@ -651,7 +660,7 @@ int _glfwPlatformExtensionSupported(const char* extension)
GLFWglproc _glfwPlatformGetProcAddress(const char* procname) GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
{ {
const GLFWglproc proc = (GLFWglproc) _glfw_wglGetProcAddress(procname); const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);
if (proc) if (proc)
return proc; return proc;

View File

@ -86,11 +86,11 @@ typedef BOOL (WINAPI * WGLMAKECURRENT_T)(HDC,HGLRC);
typedef BOOL (WINAPI * WGLSHARELISTS_T)(HGLRC,HGLRC); typedef BOOL (WINAPI * WGLSHARELISTS_T)(HGLRC,HGLRC);
// opengl32.dll function pointer typedefs // opengl32.dll function pointer typedefs
#define _glfw_wglCreateContext _glfw.wgl.CreateContext #define wglCreateContext _glfw.wgl.CreateContext
#define _glfw_wglDeleteContext _glfw.wgl.DeleteContext #define wglDeleteContext _glfw.wgl.DeleteContext
#define _glfw_wglGetProcAddress _glfw.wgl.GetProcAddress #define wglGetProcAddress _glfw.wgl.GetProcAddress
#define _glfw_wglMakeCurrent _glfw.wgl.MakeCurrent #define wglMakeCurrent _glfw.wgl.MakeCurrent
#define _glfw_wglShareLists _glfw.wgl.ShareLists #define wglShareLists _glfw.wgl.ShareLists
#define _GLFW_RECREATION_NOT_NEEDED 0 #define _GLFW_RECREATION_NOT_NEEDED 0
#define _GLFW_RECREATION_REQUIRED 1 #define _GLFW_RECREATION_REQUIRED 1
@ -144,14 +144,14 @@ typedef struct _GLFWlibraryWGL
} _GLFWlibraryWGL; } _GLFWlibraryWGL;
int _glfwInitContextAPI(void); GLFWbool _glfwInitWGL(void);
void _glfwTerminateContextAPI(void); void _glfwTerminateWGL(void);
int _glfwCreateContext(_GLFWwindow* window, GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig); const _GLFWfbconfig* fbconfig);
void _glfwDestroyContext(_GLFWwindow* window); void _glfwDestroyContextWGL(_GLFWwindow* window);
int _glfwAnalyzeContext(_GLFWwindow* window, int _glfwAnalyzeContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig); const _GLFWfbconfig* fbconfig);
#endif // _glfw3_wgl_context_h_ #endif // _glfw3_wgl_context_h_

View File

@ -290,24 +290,9 @@ static HWND createHelperWindow(void)
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Returns whether desktop compositing is enabled
//
BOOL _glfwIsCompositionEnabled(void)
{
BOOL enabled;
if (!_glfw_DwmIsCompositionEnabled)
return FALSE;
if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK)
return FALSE;
return enabled;
}
// Returns a wide string version of the specified UTF-8 string // Returns a wide string version of the specified UTF-8 string
// //
WCHAR* _glfwCreateWideStringFromUTF8(const char* source) WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
{ {
WCHAR* target; WCHAR* target;
int length; int length;
@ -329,7 +314,7 @@ WCHAR* _glfwCreateWideStringFromUTF8(const char* source)
// Returns a UTF-8 string version of the specified wide string // Returns a UTF-8 string version of the specified wide string
// //
char* _glfwCreateUTF8FromWideString(const WCHAR* source) char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
{ {
char* target; char* target;
int length; int length;
@ -356,6 +341,9 @@ char* _glfwCreateUTF8FromWideString(const WCHAR* source)
int _glfwPlatformInit(void) int _glfwPlatformInit(void)
{ {
if (!_glfwInitThreadLocalStorageWin32())
return GLFW_FALSE;
// To make SetForegroundWindow work as we want, we need to fiddle // To make SetForegroundWindow work as we want, we need to fiddle
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early // with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
// as possible in the hope of still being the foreground process) // as possible in the hope of still being the foreground process)
@ -374,7 +362,7 @@ int _glfwPlatformInit(void)
else if (_glfw_SetProcessDPIAware) else if (_glfw_SetProcessDPIAware)
_glfw_SetProcessDPIAware(); _glfw_SetProcessDPIAware();
if (!_glfwRegisterWindowClass()) if (!_glfwRegisterWindowClassWin32())
return GLFW_FALSE; return GLFW_FALSE;
_glfw.win32.helperWindow = createHelperWindow(); _glfw.win32.helperWindow = createHelperWindow();
@ -383,18 +371,23 @@ int _glfwPlatformInit(void)
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
if (!_glfwInitContextAPI()) #if defined(_GLFW_WGL)
if (!_glfwInitWGL())
return GLFW_FALSE; return GLFW_FALSE;
#elif defined(_GLFW_EGL)
if (!_glfwInitEGL())
return GLFW_FALSE;
#endif
_glfwInitTimer(); _glfwInitTimerWin32();
_glfwInitJoysticks(); _glfwInitJoysticksWin32();
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformTerminate(void) void _glfwPlatformTerminate(void)
{ {
_glfwUnregisterWindowClass(); _glfwUnregisterWindowClassWin32();
// Restore previous foreground lock timeout system setting // Restore previous foreground lock timeout system setting
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
@ -403,8 +396,14 @@ void _glfwPlatformTerminate(void)
free(_glfw.win32.clipboardString); free(_glfw.win32.clipboardString);
_glfwTerminateJoysticks(); #if defined(_GLFW_WGL)
_glfwTerminateContextAPI(); _glfwTerminateWGL();
#elif defined(_GLFW_EGL)
_glfwTerminateEGL();
#endif
_glfwTerminateJoysticksWin32();
_glfwTerminateThreadLocalStorageWin32();
if (_glfw.win32.helperWindow) if (_glfw.win32.helperWindow)
DestroyWindow(_glfw.win32.helperWindow); DestroyWindow(_glfw.win32.helperWindow);

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 WinMM - www.glfw.org // GLFW 3.2 Win32 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
@ -52,18 +52,18 @@ static float normalizeAxis(DWORD pos, DWORD min, DWORD max)
// Initialize joystick interface // Initialize joystick interface
// //
void _glfwInitJoysticks(void) void _glfwInitJoysticksWin32(void)
{ {
} }
// Close all opened joystick handles // Close all opened joystick handles
// //
void _glfwTerminateJoysticks(void) void _glfwTerminateJoysticksWin32(void)
{ {
int i; int i;
for (i = 0; i < GLFW_JOYSTICK_LAST; i++) for (i = 0; i < GLFW_JOYSTICK_LAST; i++)
free(_glfw.winmm_js[i].name); free(_glfw.win32_js[i].name);
} }
@ -85,7 +85,7 @@ const float* _glfwPlatformGetJoystickAxes(int joy, int* count)
{ {
JOYCAPS jc; JOYCAPS jc;
JOYINFOEX ji; JOYINFOEX ji;
float* axes = _glfw.winmm_js[joy].axes; float* axes = _glfw.win32_js[joy].axes;
if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR) if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR)
return NULL; return NULL;
@ -118,7 +118,7 @@ const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
{ {
JOYCAPS jc; JOYCAPS jc;
JOYINFOEX ji; JOYINFOEX ji;
unsigned char* buttons = _glfw.winmm_js[joy].buttons; unsigned char* buttons = _glfw.win32_js[joy].buttons;
if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR) if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR)
return NULL; return NULL;
@ -169,9 +169,9 @@ const char* _glfwPlatformGetJoystickName(int joy)
if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR) if (_glfw_joyGetDevCaps(joy, &jc, sizeof(JOYCAPS)) != JOYERR_NOERROR)
return NULL; return NULL;
free(_glfw.winmm_js[joy].name); free(_glfw.win32_js[joy].name);
_glfw.winmm_js[joy].name = _glfwCreateUTF8FromWideString(jc.szPname); _glfw.win32_js[joy].name = _glfwCreateUTF8FromWideStringWin32(jc.szPname);
return _glfw.winmm_js[joy].name; return _glfw.win32_js[joy].name;
} }

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 WinMM - www.glfw.org // GLFW 3.2 Win32 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2006-2014 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2014 Camilla Berglund <elmindreda@elmindreda.org>
// //
@ -24,24 +24,24 @@
// //
//======================================================================== //========================================================================
#ifndef _glfw3_winmm_joystick_h_ #ifndef _glfw3_win32_joystick_h_
#define _glfw3_winmm_joystick_h_ #define _glfw3_win32_joystick_h_
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
_GLFWjoystickWinMM winmm_js[GLFW_JOYSTICK_LAST + 1] _GLFWjoystickWin32 win32_js[GLFW_JOYSTICK_LAST + 1]
// WinMM-specific per-joystick data // Win32-specific per-joystick data
// //
typedef struct _GLFWjoystickWinMM typedef struct _GLFWjoystickWin32
{ {
float axes[6]; float axes[6];
unsigned char buttons[36]; // 32 buttons plus one hat unsigned char buttons[36]; // 32 buttons plus one hat
char* name; char* name;
} _GLFWjoystickWinMM; } _GLFWjoystickWin32;
void _glfwInitJoysticks(void); void _glfwInitJoysticksWin32(void);
void _glfwTerminateJoysticks(void); void _glfwTerminateJoysticksWin32(void);
#endif // _glfw3_winmm_joystick_h_ #endif // _glfw3_win32_joystick_h_

View File

@ -47,7 +47,7 @@
// Change the current video mode // Change the current video mode
// //
GLFWbool _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{ {
GLFWvidmode current; GLFWvidmode current;
const GLFWvidmode* best; const GLFWvidmode* best;
@ -86,7 +86,7 @@ GLFWbool _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
// Restore the previously saved (original) video mode // Restore the previously saved (original) video mode
// //
void _glfwRestoreVideoMode(_GLFWmonitor* monitor) void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
{ {
if (monitor->win32.modeChanged) if (monitor->win32.modeChanged)
{ {
@ -141,7 +141,7 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0)) if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
break; break;
name = _glfwCreateUTF8FromWideString(display.DeviceString); name = _glfwCreateUTF8FromWideStringWin32(display.DeviceString);
if (!name) if (!name)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -266,11 +266,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
if (*count == size) if (*count == size)
{ {
if (*count) size += 128;
size *= 2;
else
size = 128;
result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode)); result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode));
} }
@ -278,6 +274,14 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
result[*count - 1] = mode; result[*count - 1] = mode;
} }
if (!*count)
{
// HACK: Report the current mode if no valid modes were found
result = calloc(1, sizeof(GLFWvidmode));
_glfwPlatformGetVideoMode(monitor, result);
*count = 1;
}
return result; return result;
} }

View File

@ -140,13 +140,12 @@ typedef HRESULT (WINAPI * DWMFLUSH_T)(VOID);
typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS); typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS);
#define _glfw_SetProcessDPIAwareness _glfw.win32.shcore.SetProcessDPIAwareness #define _glfw_SetProcessDPIAwareness _glfw.win32.shcore.SetProcessDPIAwareness
#include "win32_tls.h" #include "win32_joystick.h"
#include "winmm_joystick.h"
#if defined(_GLFW_WGL) #if defined(_GLFW_WGL)
#include "wgl_context.h" #include "wgl_context.h"
#elif defined(_GLFW_EGL) #elif defined(_GLFW_EGL)
#define _GLFW_EGL_NATIVE_WINDOW window->win32.handle #define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->win32.handle)
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY #define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
#include "egl_context.h" #include "egl_context.h"
#else #else
@ -158,6 +157,7 @@ typedef HRESULT (WINAPI * SETPROCESSDPIAWARENESS_T)(PROCESS_DPI_AWARENESS);
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32 #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time #define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time
#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsWin32 win32_tls
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32 #define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32 #define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32
@ -259,17 +259,28 @@ typedef struct _GLFWtimeWin32
} _GLFWtimeWin32; } _GLFWtimeWin32;
GLFWbool _glfwRegisterWindowClass(void); // Win32-specific global TLS data
void _glfwUnregisterWindowClass(void); //
typedef struct _GLFWtlsWin32
{
GLFWbool allocated;
DWORD context;
BOOL _glfwIsCompositionEnabled(void); } _GLFWtlsWin32;
WCHAR* _glfwCreateWideStringFromUTF8(const char* source);
char* _glfwCreateUTF8FromWideString(const WCHAR* source);
void _glfwInitTimer(void); GLFWbool _glfwRegisterWindowClassWin32(void);
void _glfwUnregisterWindowClassWin32(void);
GLFWbool _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); GLFWbool _glfwInitThreadLocalStorageWin32(void);
void _glfwRestoreVideoMode(_GLFWmonitor* monitor); void _glfwTerminateThreadLocalStorageWin32(void);
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
void _glfwInitTimerWin32(void);
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
#endif // _glfw3_win32_platform_h_ #endif // _glfw3_win32_platform_h_

View File

@ -49,7 +49,7 @@ static unsigned __int64 getRawTime(void)
// Initialise timer // Initialise timer
// //
void _glfwInitTimer(void) void _glfwInitTimerWin32(void)
{ {
unsigned __int64 frequency; unsigned __int64 frequency;

View File

@ -32,7 +32,7 @@
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
GLFWbool _glfwCreateContextTLS(void) GLFWbool _glfwInitThreadLocalStorageWin32(void)
{ {
_glfw.win32_tls.context = TlsAlloc(); _glfw.win32_tls.context = TlsAlloc();
if (_glfw.win32_tls.context == TLS_OUT_OF_INDEXES) if (_glfw.win32_tls.context == TLS_OUT_OF_INDEXES)
@ -46,22 +46,22 @@ GLFWbool _glfwCreateContextTLS(void)
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwDestroyContextTLS(void) void _glfwTerminateThreadLocalStorageWin32(void)
{ {
if (_glfw.win32_tls.allocated) if (_glfw.win32_tls.allocated)
TlsFree(_glfw.win32_tls.context); TlsFree(_glfw.win32_tls.context);
} }
void _glfwSetContextTLS(_GLFWwindow* context)
{
TlsSetValue(_glfw.win32_tls.context, context);
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwPlatformSetCurrentContext(_GLFWwindow* context)
{
TlsSetValue(_glfw.win32_tls.context, context);
}
_GLFWwindow* _glfwPlatformGetCurrentContext(void) _GLFWwindow* _glfwPlatformGetCurrentContext(void)
{ {
return TlsGetValue(_glfw.win32_tls.context); return TlsGetValue(_glfw.win32_tls.context);

View File

@ -1,48 +0,0 @@
//========================================================================
// GLFW 3.2 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _glfw3_win32_tls_h_
#define _glfw3_win32_tls_h_
#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsWin32 win32_tls
// Win32-specific global TLS data
//
typedef struct _GLFWtlsWin32
{
GLFWbool allocated;
DWORD context;
} _GLFWtlsWin32;
GLFWbool _glfwCreateContextTLS(void);
void _glfwDestroyContextTLS(void);
void _glfwSetContextTLS(_GLFWwindow* context);
#endif // _glfw3_win32_tls_h_

View File

@ -236,7 +236,7 @@ static GLFWbool enterFullscreenMode(_GLFWwindow* window)
GLFWbool status; GLFWbool status;
int xpos, ypos; int xpos, ypos;
status = _glfwSetVideoMode(window->monitor, &window->videoMode); status = _glfwSetVideoModeWin32(window->monitor, &window->videoMode);
_glfwPlatformGetVideoMode(window->monitor, &mode); _glfwPlatformGetVideoMode(window->monitor, &mode);
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
@ -251,7 +251,7 @@ static GLFWbool enterFullscreenMode(_GLFWwindow* window)
// //
static void leaveFullscreenMode(_GLFWwindow* window) static void leaveFullscreenMode(_GLFWwindow* window)
{ {
_glfwRestoreVideoMode(window->monitor); _glfwRestoreVideoModeWin32(window->monitor);
} }
// Window callback function (handles window messages) // Window callback function (handles window messages)
@ -635,7 +635,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
WCHAR* buffer = calloc(length + 1, sizeof(WCHAR)); WCHAR* buffer = calloc(length + 1, sizeof(WCHAR));
DragQueryFileW(drop, i, buffer, length + 1); DragQueryFileW(drop, i, buffer, length + 1);
paths[i] = _glfwCreateUTF8FromWideString(buffer); paths[i] = _glfwCreateUTF8FromWideStringWin32(buffer);
free(buffer); free(buffer);
} }
@ -683,7 +683,7 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig)
&fullWidth, &fullHeight); &fullWidth, &fullHeight);
} }
wideTitle = _glfwCreateWideStringFromUTF8(wndconfig->title); wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
if (!wideTitle) if (!wideTitle)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -758,7 +758,7 @@ static void destroyWindow(_GLFWwindow* window)
// Registers the GLFW window class // Registers the GLFW window class
// //
GLFWbool _glfwRegisterWindowClass(void) GLFWbool _glfwRegisterWindowClassWin32(void)
{ {
WNDCLASSEXW wc; WNDCLASSEXW wc;
@ -795,7 +795,7 @@ GLFWbool _glfwRegisterWindowClass(void)
// Unregisters the GLFW window class // Unregisters the GLFW window class
// //
void _glfwUnregisterWindowClass(void) void _glfwUnregisterWindowClassWin32(void)
{ {
UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL)); UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));
} }
@ -817,11 +817,11 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (ctxconfig->api != GLFW_NO_API) if (ctxconfig->api != GLFW_NO_API)
{ {
if (!_glfwCreateContext(window, ctxconfig, fbconfig)) #if defined(_GLFW_WGL)
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
#if defined(_GLFW_WGL) status = _glfwAnalyzeContextWGL(window, ctxconfig, fbconfig);
status = _glfwAnalyzeContext(window, ctxconfig, fbconfig);
if (status == _GLFW_RECREATION_IMPOSSIBLE) if (status == _GLFW_RECREATION_IMPOSSIBLE)
return GLFW_FALSE; return GLFW_FALSE;
@ -851,16 +851,19 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
// Next destroy the Win32 window and WGL context (without resetting // Next destroy the Win32 window and WGL context (without resetting
// or destroying the GLFW window object) // or destroying the GLFW window object)
_glfwDestroyContext(window); _glfwDestroyContextWGL(window);
destroyWindow(window); destroyWindow(window);
// ...and then create them again, this time with better APIs // ...and then create them again, this time with better APIs
if (!createWindow(window, wndconfig)) if (!createWindow(window, wndconfig))
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwCreateContext(window, ctxconfig, fbconfig)) if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
#endif // _GLFW_WGL #elif defined(_GLFW_EGL)
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
#endif
} }
if (window->monitor) if (window->monitor)
@ -879,14 +882,20 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
leaveFullscreenMode(window); leaveFullscreenMode(window);
if (window->context.api != GLFW_NO_API) if (window->context.api != GLFW_NO_API)
_glfwDestroyContext(window); {
#if defined(_GLFW_WGL)
_glfwDestroyContextWGL(window);
#elif defined(_GLFW_EGL)
_glfwDestroyContextEGL(window);
#endif
}
destroyWindow(window); destroyWindow(window);
} }
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{ {
WCHAR* wideTitle = _glfwCreateWideStringFromUTF8(title); WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title);
if (!wideTitle) if (!wideTitle)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -1325,7 +1334,7 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
HANDLE stringHandle; HANDLE stringHandle;
size_t wideSize; size_t wideSize;
wideString = _glfwCreateWideStringFromUTF8(string); wideString = _glfwCreateWideStringFromUTF8Win32(string);
if (!wideString) if (!wideString)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -1386,7 +1395,7 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
free(_glfw.win32.clipboardString); free(_glfw.win32.clipboardString);
_glfw.win32.clipboardString = _glfw.win32.clipboardString =
_glfwCreateUTF8FromWideString(GlobalLock(stringHandle)); _glfwCreateUTF8FromWideStringWin32(GlobalLock(stringHandle));
GlobalUnlock(stringHandle); GlobalUnlock(stringHandle);
CloseClipboard(); CloseClipboard();

View File

@ -395,7 +395,7 @@ static void registryHandleGlobal(void* data,
} }
else if (strcmp(interface, "wl_output") == 0) else if (strcmp(interface, "wl_output") == 0)
{ {
_glfwAddOutput(name, version); _glfwAddOutputWayland(name, version);
} }
else if (strcmp(interface, "wl_seat") == 0) else if (strcmp(interface, "wl_seat") == 0)
{ {
@ -581,11 +581,16 @@ int _glfwPlatformInit(void)
// Sync so we got all initial output events // Sync so we got all initial output events
wl_display_roundtrip(_glfw.wl.display); wl_display_roundtrip(_glfw.wl.display);
if (!_glfwInitContextAPI()) if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE; return GLFW_FALSE;
_glfwInitTimer(); if (!_glfwInitEGL())
_glfwInitJoysticks(); return GLFW_FALSE;
if (!_glfwInitJoysticksLinux())
return GLFW_FALSE;
_glfwInitTimerPOSIX();
if (_glfw.wl.pointer && _glfw.wl.shm) if (_glfw.wl.pointer && _glfw.wl.shm)
{ {
@ -605,8 +610,9 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void) void _glfwPlatformTerminate(void)
{ {
_glfwTerminateContextAPI(); _glfwTerminateEGL();
_glfwTerminateJoysticks(); _glfwTerminateJoysticksLinux();
_glfwTerminateThreadLocalStoragePOSIX();
if (_glfw.wl.cursorTheme) if (_glfw.wl.cursorTheme)
wl_cursor_theme_destroy(_glfw.wl.cursorTheme); wl_cursor_theme_destroy(_glfw.wl.cursorTheme);

View File

@ -111,7 +111,7 @@ static const struct wl_output_listener output_listener = {
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwAddOutput(uint32_t name, uint32_t version) void _glfwAddOutputWayland(uint32_t name, uint32_t version)
{ {
_GLFWmonitor *monitor; _GLFWmonitor *monitor;
struct wl_output *output; struct wl_output *output;

View File

@ -41,8 +41,8 @@
#error "The Wayland backend depends on EGL platform support" #error "The Wayland backend depends on EGL platform support"
#endif #endif
#define _GLFW_EGL_NATIVE_WINDOW window->wl.native #define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.native)
#define _GLFW_EGL_NATIVE_DISPLAY _glfw.wl.display #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl
@ -138,6 +138,6 @@ typedef struct _GLFWcursorWayland
} _GLFWcursorWayland; } _GLFWcursorWayland;
void _glfwAddOutput(uint32_t name, uint32_t version); void _glfwAddOutputWayland(uint32_t name, uint32_t version);
#endif // _glfw3_wayland_platform_h_ #endif // _glfw3_wayland_platform_h_

View File

@ -243,7 +243,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (ctxconfig->api != GLFW_NO_API) if (ctxconfig->api != GLFW_NO_API)
{ {
if (!_glfwCreateContext(window, ctxconfig, fbconfig)) if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -278,7 +278,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
_glfwInputWindowFocus(window, GLFW_FALSE); _glfwInputWindowFocus(window, GLFW_FALSE);
} }
_glfwDestroyContext(window); _glfwDestroyContextEGL(window);
if (window->wl.native) if (window->wl.native)
wl_egl_window_destroy(window->wl.native); wl_egl_window_destroy(window->wl.native);

View File

@ -387,24 +387,24 @@ static void detectEWMH(void)
return; return;
// Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
if (_glfwGetWindowProperty(_glfw.x11.root, if (_glfwGetWindowPropertyX11(_glfw.x11.root,
supportingWmCheck, supportingWmCheck,
XA_WINDOW, XA_WINDOW,
(unsigned char**) &windowFromRoot) != 1) (unsigned char**) &windowFromRoot) != 1)
{ {
if (windowFromRoot) if (windowFromRoot)
XFree(windowFromRoot); XFree(windowFromRoot);
return; return;
} }
_glfwGrabXErrorHandler(); _glfwGrabErrorHandlerX11();
// It should be the ID of a child window (of the root) // It should be the ID of a child window (of the root)
// Then we look for the same property on the child window // Then we look for the same property on the child window
if (_glfwGetWindowProperty(*windowFromRoot, if (_glfwGetWindowPropertyX11(*windowFromRoot,
supportingWmCheck, supportingWmCheck,
XA_WINDOW, XA_WINDOW,
(unsigned char**) &windowFromChild) != 1) (unsigned char**) &windowFromChild) != 1)
{ {
XFree(windowFromRoot); XFree(windowFromRoot);
if (windowFromChild) if (windowFromChild)
@ -412,7 +412,7 @@ static void detectEWMH(void)
return; return;
} }
_glfwReleaseXErrorHandler(); _glfwReleaseErrorHandlerX11();
// It should be the ID of that same child window // It should be the ID of that same child window
if (*windowFromRoot != *windowFromChild) if (*windowFromRoot != *windowFromChild)
@ -432,10 +432,10 @@ static void detectEWMH(void)
// Now we need to check the _NET_SUPPORTED property of the root window // Now we need to check the _NET_SUPPORTED property of the root window
// It should be a list of supported WM protocol and state atoms // It should be a list of supported WM protocol and state atoms
atomCount = _glfwGetWindowProperty(_glfw.x11.root, atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
wmSupported, wmSupported,
XA_ATOM, XA_ATOM,
(unsigned char**) &supportedAtoms); (unsigned char**) &supportedAtoms);
// See which of the atoms we support that are supported by the WM // See which of the atoms we support that are supported by the WM
_glfw.x11.NET_WM_STATE = _glfw.x11.NET_WM_STATE =
@ -635,7 +635,7 @@ static Cursor createNULLCursor(void)
memset(pixels, 0, sizeof(pixels)); memset(pixels, 0, sizeof(pixels));
return _glfwCreateCursor(&image, 0, 0); return _glfwCreateCursorX11(&image, 0, 0);
} }
// X error handler // X error handler
@ -653,7 +653,7 @@ static int errorHandler(Display *display, XErrorEvent* event)
// Sets the X error handler callback // Sets the X error handler callback
// //
void _glfwGrabXErrorHandler(void) void _glfwGrabErrorHandlerX11(void)
{ {
_glfw.x11.errorCode = Success; _glfw.x11.errorCode = Success;
XSetErrorHandler(errorHandler); XSetErrorHandler(errorHandler);
@ -661,7 +661,7 @@ void _glfwGrabXErrorHandler(void)
// Clears the X error handler callback // Clears the X error handler callback
// //
void _glfwReleaseXErrorHandler(void) void _glfwReleaseErrorHandlerX11(void)
{ {
// Synchronize to make sure all commands are processed // Synchronize to make sure all commands are processed
XSync(_glfw.x11.display, False); XSync(_glfw.x11.display, False);
@ -670,7 +670,7 @@ void _glfwReleaseXErrorHandler(void)
// Reports the specified error, appending information about the last X error // Reports the specified error, appending information about the last X error
// //
void _glfwInputXError(int error, const char* message) void _glfwInputErrorX11(int error, const char* message)
{ {
char buffer[8192]; char buffer[8192];
XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode, XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode,
@ -681,7 +681,7 @@ void _glfwInputXError(int error, const char* message)
// Creates a native cursor object from the specified image and hotspot // Creates a native cursor object from the specified image and hotspot
// //
Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot) Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
{ {
int i; int i;
Cursor cursor; Cursor cursor;
@ -768,13 +768,21 @@ int _glfwPlatformInit(void)
} }
} }
if (!_glfwInitContextAPI()) if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwInitJoysticks()) #if defined(_GLFW_GLX)
if (!_glfwInitGLX())
return GLFW_FALSE;
#elif defined(_GLFW_EGL)
if (!_glfwInitEGL())
return GLFW_FALSE;
#endif
if (!_glfwInitJoysticksLinux())
return GLFW_FALSE; return GLFW_FALSE;
_glfwInitTimer(); _glfwInitTimerPOSIX();
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -795,6 +803,10 @@ void _glfwPlatformTerminate(void)
_glfw.x11.im = NULL; _glfw.x11.im = NULL;
} }
#if defined(_GLFW_EGL)
_glfwTerminateEGL();
#endif
if (_glfw.x11.display) if (_glfw.x11.display)
{ {
XCloseDisplay(_glfw.x11.display); XCloseDisplay(_glfw.x11.display);
@ -803,8 +815,12 @@ void _glfwPlatformTerminate(void)
// NOTE: This needs to be done after XCloseDisplay, as libGL registers // NOTE: This needs to be done after XCloseDisplay, as libGL registers
// cleanup callbacks that get called by it // cleanup callbacks that get called by it
_glfwTerminateContextAPI(); #if defined(_GLFW_GLX)
_glfwTerminateJoysticks(); _glfwTerminateGLX();
#endif
_glfwTerminateJoysticksLinux();
_glfwTerminateThreadLocalStoragePOSIX();
} }
const char* _glfwPlatformGetVersionString(void) const char* _glfwPlatformGetVersionString(void)

View File

@ -97,7 +97,7 @@ static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi,
// Set the current video mode for the specified monitor // Set the current video mode for the specified monitor
// //
GLFWbool _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{ {
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{ {
@ -164,7 +164,7 @@ GLFWbool _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
// Restore the saved (original) video mode for the specified monitor // Restore the saved (original) video mode for the specified monitor
// //
void _glfwRestoreVideoMode(_GLFWmonitor* monitor) void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
{ {
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{ {

View File

@ -64,8 +64,8 @@
#if defined(_GLFW_GLX) #if defined(_GLFW_GLX)
#include "glx_context.h" #include "glx_context.h"
#elif defined(_GLFW_EGL) #elif defined(_GLFW_EGL)
#define _GLFW_EGL_NATIVE_WINDOW window->x11.handle #define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->x11.handle)
#define _GLFW_EGL_NATIVE_DISPLAY _glfw.x11.display #define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display)
#include "egl_context.h" #include "egl_context.h"
#else #else
#error "No supported context creation API selected" #error "No supported context creation API selected"
@ -253,18 +253,18 @@ typedef struct _GLFWcursorX11
} _GLFWcursorX11; } _GLFWcursorX11;
GLFWbool _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired); GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoMode(_GLFWmonitor* monitor); void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
Cursor _glfwCreateCursor(const GLFWimage* image, int xhot, int yhot); Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot);
unsigned long _glfwGetWindowProperty(Window window, unsigned long _glfwGetWindowPropertyX11(Window window,
Atom property, Atom property,
Atom type, Atom type,
unsigned char** value); unsigned char** value);
void _glfwGrabXErrorHandler(void); void _glfwGrabErrorHandlerX11(void);
void _glfwReleaseXErrorHandler(void); void _glfwReleaseErrorHandlerX11(void);
void _glfwInputXError(int error, const char* message); void _glfwInputErrorX11(int error, const char* message);
#endif // _glfw3_x11_platform_h_ #endif // _glfw3_x11_platform_h_

View File

@ -83,10 +83,10 @@ static int getWindowState(_GLFWwindow* window)
Window icon; Window icon;
} *state = NULL; } *state = NULL;
if (_glfwGetWindowProperty(window->x11.handle, if (_glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.WM_STATE, _glfw.x11.WM_STATE,
_glfw.x11.WM_STATE, _glfw.x11.WM_STATE,
(unsigned char**) &state) >= 2) (unsigned char**) &state) >= 2)
{ {
result = state->state; result = state->state;
} }
@ -272,7 +272,7 @@ static GLFWbool createWindow(_GLFWwindow* window,
ExposureMask | FocusChangeMask | VisibilityChangeMask | ExposureMask | FocusChangeMask | VisibilityChangeMask |
EnterWindowMask | LeaveWindowMask | PropertyChangeMask; EnterWindowMask | LeaveWindowMask | PropertyChangeMask;
_glfwGrabXErrorHandler(); _glfwGrabErrorHandlerX11();
window->x11.handle = XCreateWindow(_glfw.x11.display, window->x11.handle = XCreateWindow(_glfw.x11.display,
_glfw.x11.root, _glfw.x11.root,
@ -285,12 +285,12 @@ static GLFWbool createWindow(_GLFWwindow* window,
wamask, wamask,
&wa); &wa);
_glfwReleaseXErrorHandler(); _glfwReleaseErrorHandlerX11();
if (!window->x11.handle) if (!window->x11.handle)
{ {
_glfwInputXError(GLFW_PLATFORM_ERROR, _glfwInputErrorX11(GLFW_PLATFORM_ERROR,
"X11: Failed to create window"); "X11: Failed to create window");
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -552,10 +552,10 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
Atom* targets; Atom* targets;
unsigned long i, count; unsigned long i, count;
count = _glfwGetWindowProperty(request->requestor, count = _glfwGetWindowPropertyX11(request->requestor,
request->property, request->property,
_glfw.x11.ATOM_PAIR, _glfw.x11.ATOM_PAIR,
(unsigned char**) &targets); (unsigned char**) &targets);
for (i = 0; i < count; i += 2) for (i = 0; i < count; i += 2)
{ {
@ -728,7 +728,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
_glfw.x11.saver.count++; _glfw.x11.saver.count++;
_glfwSetVideoMode(window->monitor, &window->videoMode); _glfwSetVideoModeX11(window->monitor, &window->videoMode);
if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR) if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR)
{ {
@ -793,7 +793,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
// //
static void leaveFullscreenMode(_GLFWwindow* window) static void leaveFullscreenMode(_GLFWwindow* window)
{ {
_glfwRestoreVideoMode(window->monitor); _glfwRestoreVideoModeX11(window->monitor);
_glfw.x11.saver.count--; _glfw.x11.saver.count--;
@ -1243,10 +1243,10 @@ static void processEvent(XEvent *event)
// The converted data from the drag operation has arrived // The converted data from the drag operation has arrived
char* data; char* data;
const int result = const int result =
_glfwGetWindowProperty(event->xselection.requestor, _glfwGetWindowPropertyX11(event->xselection.requestor,
event->xselection.property, event->xselection.property,
event->xselection.target, event->xselection.target,
(unsigned char**) &data); (unsigned char**) &data);
if (result) if (result)
{ {
@ -1429,10 +1429,10 @@ static void processEvent(XEvent *event)
// Retrieve a single window property of the specified type // Retrieve a single window property of the specified type
// Inspired by fghGetWindowProperty from freeglut // Inspired by fghGetWindowProperty from freeglut
// //
unsigned long _glfwGetWindowProperty(Window window, unsigned long _glfwGetWindowPropertyX11(Window window,
Atom property, Atom property,
Atom type, Atom type,
unsigned char** value) unsigned char** value)
{ {
Atom actualType; Atom actualType;
int actualFormat; int actualFormat;
@ -1470,16 +1470,26 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
Visual* visual; Visual* visual;
int depth; int depth;
if (!_glfwChooseVisual(ctxconfig, fbconfig, &visual, &depth)) #if defined(_GLFW_GLX)
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE; return GLFW_FALSE;
#elif defined(_GLFW_EGL)
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE;
#endif
if (!createWindow(window, wndconfig, visual, depth)) if (!createWindow(window, wndconfig, visual, depth))
return GLFW_FALSE; return GLFW_FALSE;
if (ctxconfig->api != GLFW_NO_API) if (ctxconfig->api != GLFW_NO_API)
{ {
if (!_glfwCreateContext(window, ctxconfig, fbconfig)) #if defined(_GLFW_GLX)
if (!_glfwCreateContextGLX(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
#elif defined(_GLFW_EGL)
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
#endif
} }
if (wndconfig->monitor) if (wndconfig->monitor)
@ -1503,7 +1513,13 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
} }
if (window->context.api != GLFW_NO_API) if (window->context.api != GLFW_NO_API)
_glfwDestroyContext(window); {
#if defined(_GLFW_GLX)
_glfwDestroyContextGLX(window);
#elif defined(_GLFW_EGL)
_glfwDestroyContextEGL(window);
#endif
}
if (window->x11.handle) if (window->x11.handle)
{ {
@ -1610,7 +1626,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{ {
if (window->monitor) if (window->monitor)
{ {
_glfwSetVideoMode(window->monitor, &window->videoMode); _glfwSetVideoModeX11(window->monitor, &window->videoMode);
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_FULLSCREEN) if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_FULLSCREEN)
{ {
@ -1751,10 +1767,10 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
} }
} }
if (_glfwGetWindowProperty(window->x11.handle, if (_glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.NET_FRAME_EXTENTS, _glfw.x11.NET_FRAME_EXTENTS,
XA_CARDINAL, XA_CARDINAL,
(unsigned char**) &extents) == 4) (unsigned char**) &extents) == 4)
{ {
if (left) if (left)
*left = extents[0]; *left = extents[0];
@ -1971,7 +1987,7 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image, const GLFWimage* image,
int xhot, int yhot) int xhot, int yhot)
{ {
cursor->x11.handle = _glfwCreateCursor(image, xhot, yhot); cursor->x11.handle = _glfwCreateCursorX11(image, xhot, yhot);
if (!cursor->x11.handle) if (!cursor->x11.handle)
return GLFW_FALSE; return GLFW_FALSE;
@ -2066,10 +2082,10 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
if (event.xselection.property == None) if (event.xselection.property == None)
continue; continue;
if (_glfwGetWindowProperty(event.xselection.requestor, if (_glfwGetWindowPropertyX11(event.xselection.requestor,
event.xselection.property, event.xselection.property,
event.xselection.target, event.xselection.target,
(unsigned char**) &data)) (unsigned char**) &data))
{ {
_glfw.x11.clipboardString = strdup(data); _glfw.x11.clipboardString = strdup(data);
} }

View File

@ -8,6 +8,10 @@ else()
link_libraries(${glfw_LIBRARIES}) link_libraries(${glfw_LIBRARIES})
endif() endif()
if (MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
include_directories("${GLFW_SOURCE_DIR}/include" include_directories("${GLFW_SOURCE_DIR}/include"
"${GLFW_SOURCE_DIR}/deps") "${GLFW_SOURCE_DIR}/deps")

View File

@ -442,7 +442,7 @@ static void monitor_callback(GLFWmonitor* monitor, int event)
x, y, x, y,
widthMM, heightMM); widthMM, heightMM);
} }
else else if (event == GLFW_DISCONNECTED)
{ {
printf("%08x at %0.3f: Monitor %s was disconnected\n", printf("%08x at %0.3f: Monitor %s was disconnected\n",
counter++, counter++,