diff --git a/.gitignore b/.gitignore
index 53b8f785..ff40c17e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,25 +1,30 @@
-*.a
+.DS_Store
CMakeCache.txt
CMakeFiles
cmake_install.cmake
cmake_uninstall.cmake
-.DS_Store
-src/config.h
-src/libglfw.pc
-src/libglfw.so
-src/libglfw.a
-src/libglfw.dylib
-src/libglfw.lib
-src/libglfwdll.lib
-src/libglfw.dll
+docs/Doxyfile
+examples/*.app
+examples/*.exe
examples/boing
examples/gears
examples/heightmap
examples/splitview
examples/triangle
examples/wave
-examples/*.app
-examples/*.exe
+src/config.h
+src/glfw.dll
+src/glfw.lib
+src/glfwdll.lib
+src/libglfw.a
+src/libglfw.dll
+src/libglfw.dylib
+src/libglfw.lib
+src/libglfw.pc
+src/libglfw.so
+src/libglfwdll.lib
+tests/*.app
+tests/*.exe
tests/accuracy
tests/defaults
tests/dynamic
@@ -30,12 +35,10 @@ tests/gamma
tests/glfwinfo
tests/iconify
tests/joysticks
-tests/listmodes
tests/peter
tests/reopen
tests/sharing
tests/tearing
+tests/title
tests/version
tests/windows
-tests/*.app
-tests/*.exe
diff --git a/CMake/CheckX11Extensions.cmake b/CMake/CheckX11Extensions.cmake
deleted file mode 100644
index a6f9b18b..00000000
--- a/CMake/CheckX11Extensions.cmake
+++ /dev/null
@@ -1,88 +0,0 @@
-# - Check if X11 RandR extension is available
-# Check if the X11 extension RandR is available.
-# This macro defines :
-# - X11_RANDR_FOUND, If set to NO RandR is not available.
-# - X11_RANDR_INCLUDE_DIR, includes directory containing the RandR header.
-# - X11_RANDR_LIBRARIES, libraries to link in the library to use RandR.
-#
-# Created by Olivier Delannoy.
-macro(CHECK_X11_XRANDR)
- message(STATUS "Checking for X11 extension XRandR")
- set(X11_XRANDR_FOUND "NO")
- find_path(X11_XRANDR_INCLUDE_DIR "X11/extensions/Xrandr.h"
- PATHS
- /usr/local/include
- /usr/local/X11/include
- /usr/local/X11R6/include
- /usr/include
- /usr/X11/include
- /usr/X11R6/include)
-
- find_library(X11_XRANDR_LIBRARIES NAMES Xrandr
- PATHS
- /usr/local/lib
- /usr/local/X11/lib
- /usr/local/X11R6/lib
- /usr/lib
- /usr/X11/lib
- /usr/X11R6/lib)
- # Create check if file compiles with randr
-
- if (X11_XRANDR_LIBRARIES AND X11_XRANDR_INCLUDE_DIR)
- set(X11_XRANDR_FOUND "YES")
- endif (X11_XRANDR_LIBRARIES AND X11_XRANDR_INCLUDE_DIR)
-
- if (X11_XRANDR_FOUND)
- message(STATUS "Checking for X11 extension XRandR -- found")
- else (X11_XRANDR_FOUND)
- message(STATUS "Checking for X11 extension XRandR -- not found")
- endif (X11_XRANDR_FOUND)
-
- mark_as_advanced(X11_XRANDR_LIBRARIES X11_XRANDR_INCLUDE_DIR)
-endmacro(CHECK_X11_XRANDR)
-
-
-# - Check if X11 VidMod extension is available
-# Check if the X11 extension VidMod is available.
-# This macro defines :
-# - X11_VIDMOD_FOUND, If set to NO VidMod is not available.
-# - X11_VIDMOD_INCLUDE_DIR, includes directory containing the headers.
-# - X11_VIDMOD_LIBRARIES, libraries to link in the libraries.
-#
-# Created by Olivier Delannoy.
-macro(CHECK_X11_XF86VIDMODE)
- message(STATUS "Checking for X11 extension xf86vidmode")
- set(X11_XF86VIDMODE_FOUND "NO")
- find_path(X11_XF86VIDMODE_INCLUDE_DIR "X11/extensions/xf86vmode.h"
- PATHS
- /usr/local/include
- /usr/local/X11/include
- /usr/local/X11R6/include
- /usr/include
- /usr/X11/include
- /usr/X11R6/include)
-
- find_library(X11_XF86VIDMODE_LIBRARIES NAMES Xxf86vm PATHS
- /usr/local/lib
- /usr/local/X11/lib
- /usr/local/X11R6/lib
- /usr/lib
- /usr/X11/lib
- /usr/X11R6/lib)
- # Add a test case here
- if (X11_XF86VIDMODE_LIBRARIES AND X11_XF86VIDMODE_INCLUDE_DIR)
- set(X11_XF86VIDMODE_FOUND "YES")
- endif (X11_XF86VIDMODE_LIBRARIES AND X11_XF86VIDMODE_INCLUDE_DIR)
-
- if (X11_XF86VIDMODE_FOUND)
- message(STATUS "Checking for X11 extension xf86vidmode -- found")
- else (X11_XF86VIDMODE_FOUND)
- message(STATUS "Checking for X11 extension xf86vidmode -- not found")
- endif(X11_XF86VIDMODE_FOUND)
-
- mark_as_advanced(
- X11_XF86VIDMODE_LIBRARIES
- X11_XF86VIDMODE_INCLUDE_DIR
- )
-
-endmacro(CHECK_X11_XF86VIDMODE)
diff --git a/CMake/README.txt b/CMake/README.txt
index d24854ed..9581f832 100644
--- a/CMake/README.txt
+++ b/CMake/README.txt
@@ -1,10 +1,19 @@
-This folder contains a collection of toolchains definition in order to
-support cross compilation. The naming scheme is the following:
+This directory contains a collection of toolchain definitions for cross
+compilation, currently limited to compiling Win32 binaries on Linux.
+
+The toolchain file naming scheme is as follows:
+
host-system-compiler.cmake
-to use this at the time you run the initial cmake command use the
-following parameter
- -DCMAKE_TOOLCHAIN_FILE=./toolchains/XXX-XXX-XXX.cmake
- which maps to file in this folder.
+To use these files you add a special parameter when configuring the source tree:
+
+ cmake -DCMAKE_TOOLCHAIN_FILE= .
+
+For example, to use the Debian GNU/Linux MinGW package, run CMake like this:
+
+ cmake -DCMAKE_TOOLCHAIN_FILE=CMake/linux-i586-mingw32msvc.cmake .
+
+For more details see this article:
+
+ http://www.paraview.org/Wiki/CMake_Cross_Compiling
-For more details see: http://www.paraview.org/Wiki/CMake_Cross_Compiling
diff --git a/CMake/cygwin-i686-w64-mingw32.cmake b/CMake/cygwin-i686-w64-mingw32.cmake
new file mode 100644
index 00000000..9bd60936
--- /dev/null
+++ b/CMake/cygwin-i686-w64-mingw32.cmake
@@ -0,0 +1,13 @@
+# Define the environment for cross compiling from Linux to Win32
+SET(CMAKE_SYSTEM_NAME Windows) # Target system name
+SET(CMAKE_SYSTEM_VERSION 1)
+SET(CMAKE_C_COMPILER "i686-w64-mingw32-gcc")
+SET(CMAKE_CXX_COMPILER "i686-w64-mingw32-g++")
+SET(CMAKE_RC_COMPILER "i686-w64-mingw32-windres")
+SET(CMAKE_RANLIB "i686-w64-mingw32-ranlib")
+
+# Configure the behaviour of the find commands
+SET(CMAKE_FIND_ROOT_PATH "/usr/i686-w64-mingw32")
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/CMake/cygwin-x86_64-w64-mingw32.cmake b/CMake/cygwin-x86_64-w64-mingw32.cmake
new file mode 100644
index 00000000..84b2c701
--- /dev/null
+++ b/CMake/cygwin-x86_64-w64-mingw32.cmake
@@ -0,0 +1,13 @@
+# Define the environment for cross compiling from Linux to Win32
+SET(CMAKE_SYSTEM_NAME Windows) # Target system name
+SET(CMAKE_SYSTEM_VERSION 1)
+SET(CMAKE_C_COMPILER "x86_64-w64-mingw32-gcc")
+SET(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-g++")
+SET(CMAKE_RC_COMPILER "x86_64-w64-mingw32-windres")
+SET(CMAKE_RANLIB "x86_64-w64-mingw32-ranlib")
+
+# Configure the behaviour of the find commands
+SET(CMAKE_FIND_ROOT_PATH "/usr/x86_64-w64-mingw32")
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/CMake/linux-amd64-mingw32msvc.cmake b/CMake/linux-amd64-mingw32msvc.cmake
new file mode 100644
index 00000000..705e251d
--- /dev/null
+++ b/CMake/linux-amd64-mingw32msvc.cmake
@@ -0,0 +1,13 @@
+# Define the environment for cross compiling from Linux to Win64
+SET(CMAKE_SYSTEM_NAME Windows)
+SET(CMAKE_SYSTEM_VERSION 1)
+SET(CMAKE_C_COMPILER "amd64-mingw32msvc-gcc")
+SET(CMAKE_CXX_COMPILER "amd64-mingw32msvc-g++")
+SET(CMAKE_RC_COMPILER "amd64-mingw32msvc-windres")
+SET(CMAKE_RANLIB "amd64-mingw32msvc-ranlib")
+
+# Configure the behaviour of the find commands
+SET(CMAKE_FIND_ROOT_PATH "/usr/amd64-mingw32msvc")
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/CMake/linux-mingw32msvc.cmake b/CMake/linux-i586-mingw32msvc.cmake
similarity index 51%
rename from CMake/linux-mingw32msvc.cmake
rename to CMake/linux-i586-mingw32msvc.cmake
index 4131bc92..393ddbda 100644
--- a/CMake/linux-mingw32msvc.cmake
+++ b/CMake/linux-i586-mingw32msvc.cmake
@@ -1,14 +1,12 @@
-# Define the cross compilation environment for cross compiling from linux
-# to win32 it is to be used when debian cross compilation toolchain is
-# available.
-SET(CMAKE_SYSTEM_NAME Windows) # Target system name
-SET(CMAKE_SYSTEM_VERSION 1) # Not really used.
+# Define the environment for cross compiling from Linux to Win32
+SET(CMAKE_SYSTEM_NAME Windows)
+SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER "i586-mingw32msvc-gcc")
SET(CMAKE_CXX_COMPILER "i586-mingw32msvc-g++")
+SET(CMAKE_RC_COMPILER "i586-mingw32msvc-windres")
SET(CMAKE_RANLIB "i586-mingw32msvc-ranlib")
-
-#Configure the behaviour of the find commands
+# Configure the behaviour of the find commands
SET(CMAKE_FIND_ROOT_PATH "/usr/i586-mingw32msvc")
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
diff --git a/CMake/linux-i686-pc-mingw32.cmake b/CMake/linux-i686-pc-mingw32.cmake
index 62dc8675..9a46aef7 100644
--- a/CMake/linux-i686-pc-mingw32.cmake
+++ b/CMake/linux-i686-pc-mingw32.cmake
@@ -1,9 +1,9 @@
-# Define the cross compilation environment for cross compiling from linux
-# to win32
+# Define the environment for cross compiling from Linux to Win32
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER "i686-pc-mingw32-gcc")
SET(CMAKE_CXX_COMPILER "i686-pc-mingw32-g++")
+SET(CMAKE_RC_COMPILER "i686-pc-mingw32-windres")
SET(CMAKE_RANLIB "i686-pc-mingw32-ranlib")
#Configure the behaviour of the find commands
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 57967600..44dcb4d4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,6 @@
project(GLFW C)
-cmake_minimum_required(VERSION 2.4)
-cmake_policy(VERSION 2.4)
+cmake_minimum_required(VERSION 2.8)
set(GLFW_VERSION_MAJOR "3")
set(GLFW_VERSION_MINOR "0")
@@ -12,105 +11,166 @@ set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA
option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON)
option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON)
+option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
find_package(OpenGL REQUIRED)
#--------------------------------------------------------------------
-# Set up GLFW for Win32 and WGL on Windows
+# Enable all warnings on GCC, regardless of OS
+#--------------------------------------------------------------------
+if (CMAKE_COMPILER_IS_GNUCC)
+ add_definitions(-Wall)
+endif()
+
+#--------------------------------------------------------------------
+# Export shared library / dynamic library / DLL build option
+#--------------------------------------------------------------------
+if (BUILD_SHARED_LIBS)
+ set(_GLFW_BUILD_DLL 1)
+endif()
+
+#--------------------------------------------------------------------
+# Detect and select target platform
#--------------------------------------------------------------------
if (WIN32)
- message(STATUS "Building GLFW for WGL on a Win32 system")
-
- # Define the platform identifier
set(_GLFW_WIN32_WGL 1)
+ message(STATUS "Building GLFW for WGL on a Win32 system")
+elseif (UNIX AND APPLE)
+ set(_GLFW_COCOA_NSGL 1)
+ message(STATUS "Building GLFW for Cocoa and NSOpenGL on Mac OS X")
+elseif (UNIX AND NOT APPLE)
+ set(_GLFW_X11_GLX 1)
+ message(STATUS "Building GLFW for X11 and GLX on a Unix-like system")
+else()
+ message(FATAL_ERROR "No supported platform was detected")
+endif()
+
+#--------------------------------------------------------------------
+# Set up GLFW for Win32 and WGL on Windows
+#--------------------------------------------------------------------
+if (_GLFW_WIN32_WGL)
# Set up library and include paths
- list(APPEND GLFW_INCLUDE_DIR ${OPENGL_INCLUDE_DIR})
- list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY})
-endif (WIN32)
+ list(APPEND glfw_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR})
+ list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY})
+
+ set(_GLFW_NO_DLOAD_WINMM ${BUILD_SHARED_LIBS})
+
+ if (BUILD_SHARED_LIBS)
+ list(APPEND glfw_LIBRARIES winmm)
+ endif()
+endif()
#--------------------------------------------------------------------
# Set up GLFW for Xlib and GLX on Unix-like systems with X Windows
#--------------------------------------------------------------------
-if (UNIX AND NOT APPLE)
- message(STATUS "Building GLFW for X11 and GLX on a Unix-like system")
+if (_GLFW_X11_GLX)
- # Define the platform identifier
- set(_GLFW_X11_GLX 1)
+ find_package(X11 REQUIRED)
# Set up library and include paths
- list(APPEND GLFW_INCLUDE_DIR ${X11_X11_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR})
- list(APPEND GLFW_LIBRARIES ${X11_X11_LIB} ${OPENGL_gl_LIBRARY})
+ list(APPEND glfw_INCLUDE_DIRS ${X11_X11_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR})
+ list(APPEND glfw_LIBRARIES ${X11_X11_LIB} ${OPENGL_gl_LIBRARY})
- find_library(MATH_LIBRARY m)
- if (MATH_LIBRARY)
- list(APPEND GLFW_LIBRARIES ${MATH_LIBRARY})
- endif(MATH_LIBRARY)
-
- find_library(RT_LIBRARY rt)
- if (RT_LIBRARY)
- list(APPEND GLFW_LIBRARIES ${RT_LIBRARY})
- endif(RT_LIBRARY)
+ set(GLFW_PKG_DEPS "gl x11")
+ set(GLFW_PKG_LIBS "")
include(CheckFunctionExists)
- include(CheckSymbolExists)
- include(${GLFW_SOURCE_DIR}/CMake/CheckX11Extensions.cmake)
- set(CMAKE_REQUIRED_LIBRARIES ${GLFW_LIBRARIES})
-
# Check for XRandR (modern resolution switching extension)
- check_x11_xrandr()
- if (X11_XRANDR_FOUND)
+ if (X11_Xrandr_FOUND)
set(_GLFW_HAS_XRANDR 1)
- list(APPEND GLFW_INCLUDE_DIR ${X11_XRANDR_INCLUDE_DIR})
- list(APPEND GLFW_LIBRARIES ${X11_XRANDR_LIBRARIES})
- endif(X11_XRANDR_FOUND)
+ list(APPEND glfw_INCLUDE_DIRS ${X11_Xrandr_INCLUDE_PATH})
+ list(APPEND glfw_LIBRARIES ${X11_Xrandr_LIB})
+ set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} xrandr")
+ endif()
# Check for Xf86VidMode (fallback legacy resolution switching extension)
- check_x11_xf86vidmode()
- if (X11_XF86VIDMODE_FOUND)
+ if (X11_xf86vmode_FOUND)
set(_GLFW_HAS_XF86VIDMODE 1)
- list(APPEND GLFW_INCLUDE_DIR ${X11_XF86VIDMODE_INCLUDE_DIR})
- list(APPEND GLFW_LIBRARIES ${X11_XF86VIDMODE_LIBRARIES})
- endif(X11_XF86VIDMODE_FOUND)
+ list(APPEND glfw_INCLUDE_DIRS ${X11_xf86vmode_INCLUDE_PATH})
+
+ # NOTE: This is a workaround for CMake bug 0006976 (missing
+ # X11_xf86vmode_LIB variable)
+ if (X11_xf86vmode_LIB)
+ list(APPEND glfw_LIBRARIES ${X11_xf86vmode_LIB})
+ else()
+ list(APPEND glfw_LIBRARIES Xxf86vm)
+ endif()
+
+ set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} xxf86vm")
+ endif()
# Check for Xkb (X keyboard extension)
- check_function_exists(XkbQueryExtension _GLFW_HAS_XKB)
+ if (X11_Xkb_FOUND)
+ set(_GLFW_HAS_XKB 1)
+ list(APPEND glfw_INCLUDE_DIR ${X11_Xkb_INCLUDE_PATH})
+ endif()
+
+ find_library(RT_LIBRARY rt)
+ mark_as_advanced(RT_LIBRARY)
+ if (RT_LIBRARY)
+ list(APPEND glfw_LIBRARIES ${RT_LIBRARY})
+ set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -lrt")
+ endif()
+
+ find_library(MATH_LIBRARY m)
+ mark_as_advanced(MATH_LIBRARY)
+ if (MATH_LIBRARY)
+ list(APPEND glfw_LIBRARIES ${MATH_LIBRARY})
+ set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -lm")
+ endif()
+
+ set(CMAKE_REQUIRED_LIBRARIES ${OPENGL_gl_LIBRARY})
- # Check for glXGetProcAddress
check_function_exists(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS)
if (NOT _GLFW_HAS_GLXGETPROCADDRESS)
check_function_exists(glXGetProcAddressARB _GLFW_HAS_GLXGETPROCADDRESSARB)
- endif (NOT _GLFW_HAS_GLXGETPROCADDRESS)
+ endif()
if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB)
check_function_exists(glXGetProcAddressEXT _GLFW_HAS_GLXGETPROCADDRESSEXT)
- endif (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB)
+ endif()
if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND
NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND
NOT _GLFW_HAS_GLXGETPROCADDRESSEXT)
message(WARNING "No glXGetProcAddressXXX variant found")
- endif (NOT _GLFW_HAS_GLXGETPROCADDRESS AND
- NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND
- NOT _GLFW_HAS_GLXGETPROCADDRESSEXT)
+
+ # Check for dlopen support as a fallback
+
+ find_library(DL_LIBRARY dl)
+ mark_as_advanced(DL_LIBRARY)
+ if (DL_LIBRARY)
+ set(CMAKE_REQUIRED_LIBRARIES ${DL_LIBRARY})
+ else()
+ set(CMAKE_REQUIRED_LIBRARIES "")
+ endif()
+
+ check_function_exists(dlopen _GLFW_HAS_DLOPEN)
+
+ if (NOT _GLFW_HAS_DLOPEN)
+ message(FATAL_ERROR "No entry point retrieval mechanism found")
+ endif()
+
+ if (DL_LIBRARY)
+ list(APPEND glfw_LIBRARIES ${DL_LIBRARY})
+ set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -ldl")
+ endif()
+ endif()
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(_GLFW_USE_LINUX_JOYSTICKS 1)
- endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
-endif(UNIX AND NOT APPLE)
+ endif()
+endif()
#--------------------------------------------------------------------
# Set up GLFW for Cocoa and NSOpenGL on Mac OS X
#--------------------------------------------------------------------
-if (UNIX AND APPLE)
- message(STATUS "Building GLFW for Cocoa and NSOpenGL on Mac OS X")
+if (_GLFW_COCOA_NSGL)
- # Define the platform identifier
- set(_GLFW_COCOA_NSGL 1)
-
- option(GLFW_BUILD_UNIVERSAL "Build the GLFW library and examples as Universal Binaries" FALSE)
+ option(GLFW_BUILD_UNIVERSAL "Build GLFW as a Universal Binary" OFF)
# Universal build
if (GLFW_BUILD_UNIVERSAL)
@@ -120,17 +180,25 @@ if (UNIX AND APPLE)
set(CMAKE_C_FLAGS "-mmacosx-version-min=10.5")
else(GLFW_BUILD_UNIVERSAL)
message(STATUS "Building GLFW only for the native architecture")
- endif(GLFW_BUILD_UNIVERSAL)
+ endif()
# Set up library and include paths
find_library(COCOA_FRAMEWORK Cocoa)
find_library(IOKIT_FRAMEWORK IOKit)
find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation)
- list(APPEND GLFW_LIBRARIES ${COCOA_FRAMEWORK})
- list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY})
- list(APPEND GLFW_LIBRARIES ${IOKIT_FRAMEWORK})
- list(APPEND GLFW_LIBRARIES ${CORE_FOUNDATION_FRAMEWORK})
-endif(UNIX AND APPLE)
+ list(APPEND glfw_LIBRARIES ${COCOA_FRAMEWORK}
+ ${OPENGL_gl_LIBRARY}
+ ${IOKIT_FRAMEWORK}
+ ${CORE_FOUNDATION_FRAMEWORK})
+
+ set(GLFW_PKG_DEPS "")
+ set(GLFW_PKG_LIBS "-framework Cocoa -framework OpenGL -framework IOKit -framework CoreFoundation")
+endif()
+
+#--------------------------------------------------------------------
+# Export GLFW library dependencies
+#--------------------------------------------------------------------
+set(GLFW_LIBRARIES ${glfw_LIBRARIES} CACHE STRING "Dependencies of GLFW")
#--------------------------------------------------------------------
# Add subdirectories
@@ -139,42 +207,47 @@ add_subdirectory(src)
if (GLFW_BUILD_EXAMPLES)
add_subdirectory(examples)
-endif(GLFW_BUILD_EXAMPLES)
+endif()
if (GLFW_BUILD_TESTS)
add_subdirectory(tests)
-endif(GLFW_BUILD_TESTS)
+endif()
#--------------------------------------------------------------------
-# Create shared configuration header
+# Create generated files
#--------------------------------------------------------------------
+configure_file(${GLFW_SOURCE_DIR}/docs/Doxyfile.in
+ ${GLFW_BINARY_DIR}/docs/Doxyfile @ONLY)
+
configure_file(${GLFW_SOURCE_DIR}/src/config.h.in
${GLFW_BINARY_DIR}/src/config.h @ONLY)
#--------------------------------------------------------------------
-# Install standard files
+# Install header and documentation
+# The src directory's CMakeLists.txt file installs the library
#--------------------------------------------------------------------
-
install(DIRECTORY include/GL DESTINATION include
FILES_MATCHING PATTERN glfw3.h)
install(FILES COPYING.txt readme.html
- DESTINATION share/doc/glfw-${GLFW_VERSION_FULL}/)
-
-# The respective port's CMakeLists.txt file installs the library
+ DESTINATION share/doc/glfw-${GLFW_VERSION_FULL})
#--------------------------------------------------------------------
-# -- Documentation generation
+# Create and install pkg-config file on supported platforms
#--------------------------------------------------------------------
-configure_file("${GLFW_SOURCE_DIR}/docs/Doxyfile.in"
- "${GLFW_BINARY_DIR}/docs/Doxyfile"
- @ONLY)
+if (_GLFW_X11_GLX OR _GLFW_COCOA_NSGL)
+ configure_file(${GLFW_SOURCE_DIR}/src/libglfw.pc.in
+ ${GLFW_BINARY_DIR}/src/libglfw.pc @ONLY)
+
+ install(FILES ${GLFW_BINARY_DIR}/src/libglfw.pc
+ DESTINATION lib/pkgconfig)
+endif()
#--------------------------------------------------------------------
# Uninstall operation
# Don't generate this target if a higher-level project already has
#--------------------------------------------------------------------
-if(NOT TARGET uninstall)
+if (NOT TARGET uninstall)
configure_file(${GLFW_SOURCE_DIR}/cmake_uninstall.cmake.in
${GLFW_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY)
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index 6bc7da29..00000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-##########################################################################
-# Makefile for the GLFW documentation.
-##########################################################################
-
-PDFDOCS = glfwrm.pdf glfwug.pdf
-DVIDOCS = glfwrm.dvi glfwug.dvi
-
-
-##########################################################################
-# Build macros
-##########################################################################
-default: pdf
-pdf: $(PDFDOCS)
-dvi: $(DVIDOCS)
-
-
-##########################################################################
-# Clean macros
-##########################################################################
-clean:
- rm -f glfwrm.dvi glfwrm.aux glfwrm.log glfwrm.out glfwrm.pdf glfwrm.toc glfwrm.lot
- rm -f glfwug.dvi glfwug.aux glfwug.log glfwug.out glfwug.pdf glfwug.toc
-
-clean-win:
- @.\\cleanup.bat
-
-
-##########################################################################
-# Rules for building the GLFW Reference Manual
-##########################################################################
-
-glfwrm.pdf: glfwrm.tex glfwrm.toc glfwrm.lot glfwdoc.sty
- pdflatex glfwrm.tex
-
-glfwrm.dvi: glfwrm.tex glfwrm.toc glfwrm.lot glfwdoc.sty
- latex glfwrm.tex
-
-glfwrm.toc: glfwrm.tex glfwdoc.sty
- latex glfwrm.tex
-
-glfwrm.lot: glfwrm.tex glfwdoc.sty
- latex glfwrm.tex
-
-
-##########################################################################
-# Rules for building the GLFW Users Guide
-##########################################################################
-
-glfwug.pdf: glfwug.tex glfwug.toc glfwdoc.sty
- pdflatex glfwug.tex
-
-glfwug.dvi: glfwug.tex glfwug.toc glfwdoc.sty
- latex glfwug.tex
-
-glfwug.toc: glfwug.tex glfwdoc.sty
- latex glfwug.tex
-
diff --git a/docs/cleanup.bat b/docs/cleanup.bat
deleted file mode 100644
index 268a27b6..00000000
--- a/docs/cleanup.bat
+++ /dev/null
@@ -1,22 +0,0 @@
-@echo off
-
-REM ----------------------------------------------------------------------
-REM Windows cleanup batch file for the GLFW documentation.
-REM ----------------------------------------------------------------------
-
-REM GLFW Reference Manual
-if exist glfwrm.dvi del glfwrm.dvi
-if exist glfwrm.aux del glfwrm.aux
-if exist glfwrm.log del glfwrm.log
-if exist glfwrm.out del glfwrm.out
-if exist glfwrm.pdf del glfwrm.pdf
-if exist glfwrm.toc del glfwrm.toc
-if exist glfwrm.lot del glfwrm.lot
-
-REM GLFW Users Guide
-if exist glfwug.dvi del glfwug.dvi
-if exist glfwug.aux del glfwug.aux
-if exist glfwug.log del glfwug.log
-if exist glfwug.out del glfwug.out
-if exist glfwug.pdf del glfwug.pdf
-if exist glfwug.toc del glfwug.toc
diff --git a/docs/glfwdoc.sty b/docs/glfwdoc.sty
deleted file mode 100644
index e415570e..00000000
--- a/docs/glfwdoc.sty
+++ /dev/null
@@ -1,81 +0,0 @@
-%-------------------------------------------------------------------------
-% Common document formatting and macros for GLFW manuals
-%-------------------------------------------------------------------------
-
-% Misc. document info
-\date{\today}
-
-% Packages
-\usepackage{fancyhdr}
-\usepackage{titling}
-\usepackage{lastpage}
-\usepackage{listings}
-\usepackage{color}
-\usepackage[overload]{textcase}
-\usepackage{needspace}
-\usepackage{times}
-
-% Logo macros
-\newcommand{\OpenGL}[1][0]{OpenGL\textsuperscript{\textregistered}}
-\newcommand{\GLFW}[1][0]{GLFW}
-
-% Encoding
-\usepackage[latin1]{inputenc}
-\usepackage[T1]{fontenc}
-
-% Page formatting
-\usepackage[hmargin=2.5cm]{geometry}
-\raggedright
-\raggedbottom
-\sloppy
-\usepackage{parskip}
-
-% Header and footer
-\pagestyle{fancy}
-%\lhead{\textit{GLFW Reference Manual}}
-\lhead{\textit{GLFW \glfwdoctype}}
-\chead{API version \glfwapiver}
-\rhead{Page \thepage/\pageref{LastPage}}
-\lfoot{}
-\cfoot{}
-\rfoot{}
-\renewcommand{\headrulewidth}{0.4pt}
-\renewcommand{\footrulewidth}{0.0pt}
-
-% Titlepage
-\newcommand{\glfwmaketitle}{\begin{titlepage}\ \\%
- \begin{center}%
- \vspace{7.0cm}{\Huge\textbf{GLFW}}\\%
- \rule{10.0cm}{0.5pt}\\%
- \vspace{0.5cm}{\LARGE\textbf{\glfwdoctype}}\\%
- \vspace{0.8cm}{\large\textbf{API version \glfwapiver}}\\%
- \textit{\today}\\%
- \vspace{1.5cm}\textbf{\textcopyright2002-2006 Marcus Geelnard}\\
- \textbf{\textcopyright2006-2010 Camilla Berglund}\\%
- \end{center}\end{titlepage}\newpage}
-
-% Colors
-\definecolor{code}{rgb}{0.9,0.9,1.0}
-\definecolor{link}{rgb}{0.6,0.0,0.0}
-\definecolor{codeA}{rgb}{0.9,1.0,0.9}
-\definecolor{codeB}{rgb}{1.0,0.9,0.9}
-
-% Code listings
-\lstset{frame=single,frameround=tttt,backgroundcolor=\color{code},%
- language=C,basicstyle={\ttfamily},%
- breaklines,breakindent=0pt,postbreak=\space\space\space\space}
-
-
-% A simple hack for keeping lines together
-\newenvironment{mysamepage}[1][2]{\begin{samepage}\needspace{#1\baselineskip}}{\end{samepage}}
-
-% Macros for automating function reference entries
-\newenvironment{refparameters}[1][0]{\begin{mysamepage}\textbf{Parameters}\\}{\end{mysamepage}\bigskip}
-\newenvironment{refreturn}[1][0]{\begin{mysamepage}\textbf{Return values}\\}{\end{mysamepage}\bigskip}
-\newenvironment{refdescription}[1][0]{\begin{mysamepage}\textbf{Description}\\}{\end{mysamepage}\bigskip}
-\newenvironment{refnotes}[1][0]{\begin{mysamepage}\textbf{Notes}\\}{\end{mysamepage}\bigskip}
-
-% hyperref (bookmarks, links etc) - use this package last
-\usepackage[colorlinks=true,linkcolor=link,bookmarks=true,bookmarksopen=true,%
- pdfhighlight=/N,bookmarksnumbered=true,bookmarksopenlevel=1,%
- pdfview=FitH,pdfstartview=FitH]{hyperref}
diff --git a/docs/glfwrm.tex b/docs/glfwrm.tex
deleted file mode 100644
index 48c80b42..00000000
--- a/docs/glfwrm.tex
+++ /dev/null
@@ -1,2364 +0,0 @@
-%-------------------------------------------------------------------------
-% GLFW Reference Manual
-% API Version: 3.0
-%-------------------------------------------------------------------------
-
-% Document class
-\documentclass[a4paper,11pt,oneside]{report}
-
-% Document title and API version
-\newcommand{\glfwdoctype}[1][0]{Reference Manual}
-\newcommand{\glfwapiver}[1][0]{3.0}
-
-% Common document settings and macros
-\input{glfwdoc.sty}
-
-% PDF specific document settings
-\hypersetup{pdftitle={GLFW Reference Manual}}
-\hypersetup{pdfauthor={Camilla Berglund}}
-\hypersetup{pdfkeywords={GLFW,OpenGL,reference,manual}}
-
-
-%-------------------------------------------------------------------------
-% Document body
-%-------------------------------------------------------------------------
-
-\begin{document}
-
-\pagestyle{plain}
-
-% Title page
-\glfwmaketitle
-
-% Summary, trademarks and table of contents
-\pagenumbering{roman}
-\setcounter{page}{1}
-
-%-------------------------------------------------------------------------
-% Summary and Trademarks
-%-------------------------------------------------------------------------
-\chapter*{Summary}
-
-This document is primarily a function reference manual for the \GLFW\ API.
-For a description of how to use \GLFW\ you should refer to the
-\textit{GLFW Users Guide}.
-\vspace{5cm}
-
-\large
-Trademarks
-
-\small
-OpenGL and IRIX are registered trademarks of Silicon Graphics, Inc.\linebreak
-Microsoft and Windows are registered trademarks of Microsoft Corporation.\linebreak
-Mac OS is a registered trademark of Apple Computer, Inc.\linebreak
-Linux is a registered trademark of Linus Torvalds.\linebreak
-FreeBSD is a registered trademark of Wind River Systems, Inc.\linebreak
-Solaris is a trademark of Sun Microsystems, Inc.\linebreak
-UNIX is a registered trademark of The Open Group.\linebreak
-X Window System is a trademark of The Open Group.\linebreak
-POSIX is a trademark of IEEE.\linebreak
-Truevision, TARGA and TGA are registered trademarks of Truevision, Inc.\linebreak
-
-All other trademarks mentioned in this document are the property of their respective owners.
-\normalsize
-
-
-%-------------------------------------------------------------------------
-% Table of contents
-%-------------------------------------------------------------------------
-\tableofcontents
-
-%-------------------------------------------------------------------------
-% List of tables
-%-------------------------------------------------------------------------
-\listoftables
-\pagebreak
-
-
-% Document chapters starts here...
-\pagenumbering{arabic}
-\setcounter{page}{1}
-
-\pagestyle{fancy}
-
-
-%-------------------------------------------------------------------------
-% Introduction
-%-------------------------------------------------------------------------
-\chapter{Introduction}
-\thispagestyle{fancy}
-
-\GLFW\ is a portable API (Application Program Interface) that handles
-operating system specific tasks related to \OpenGL\ programming. While
-\OpenGL\ in general is portable, easy to use and often results in tidy and
-compact code, the operating system specific mechanisms that are required
-to set up and manage an \OpenGL\ window are quite the opposite. \GLFW\ tries
-to remedy this by providing the following functionality:
-
-\begin{itemize}
-\item Opening and managing an \OpenGL\ context and its associated window.
-\item Keyboard, mouse and joystick input.
-\item A high precision timer.
-\item Support for querying and using \OpenGL\ extensions.
-\end{itemize}
-
-All this functionality is implemented as a set of easy-to-use functions,
-which makes it possible to write an \OpenGL\ application framework in just a
-few lines of code. The \GLFW\ API looks and behaves the same on all supported
-platforms, making it very simple to port \GLFW\ based \OpenGL\ applications to
-a variety of platforms.
-
-Currently supported platforms are:
-\begin{itemize}
-\item Microsoft Windows\textsuperscript{\textregistered} (32-bit only).
-\item Unix\textsuperscript{\textregistered} or Unix-like systems running
-resonably a modern version of the X Window
-System\texttrademark\footnote{X11.app on Mac OS X is not supported due to its
-incomplete implementation of GLXFBConfigs} e.g.
-Linux\textsuperscript{\textregistered},
-FreeBSD\textsuperscript{\textregistered} and Solaris\texttrademark (32- and
-64-bit).
-\item Mac OS\textsuperscript{\textregistered} X, using Cocoa\footnote{Joystick
-input is not yet supported on Mac OS X.} (32- and 64-bit).
-\end{itemize}
-
-
-
-%-------------------------------------------------------------------------
-% GLFW Operation
-%-------------------------------------------------------------------------
-\chapter{GLFW Operation Overview}
-\thispagestyle{fancy}
-
-
-%-------------------------------------------------------------------------
-\section{The GLFW Window}
-\GLFW\ only supports having one window open at a time. The window can be either
-a normal desktop window or a fullscreen window. The latter is completely
-undecorated, without window borders, and covers the entire monitor. With a
-fullscreen window, it is also possible to select which video mode to use.
-
-When a window is opened, an \OpenGL\ rendering context is created and
-attached to the entire client area of the window. When the window is closed,
-the \OpenGL\ rendering context is detached and destroyed.
-
-Through a window it is possible to receive user input in the form of
-keyboard and mouse input. User input is exposed through the \GLFW\ API
-primarily via a set of callback functions. Also, \GLFW\ stores most user input
-as internal state that can be queried through different \GLFW\ API functions
-(for instance it is possible to query the position of the mouse cursor with the
-\textbf{glfwGetMousePos} function).
-
-As for user input, it is possible to receive information about window
-state changes, such as window resize or close events, through callback
-functions. It is also possible to query some kinds of information about the
-window information using \GLFW\ API functions.
-
-
-%-------------------------------------------------------------------------
-\section{The GLFW Event Loop}
-The \GLFW\ event loop is an open loop, which means that it is up to the
-programmer to design the loop. Events are processed by calling specific
-\GLFW\ functions, which in turn query the system for new input and window
-events and reports these events back to the program through callback
-functions.
-
-The programmer decides when to call the event processing functions and
-when to abort the event loop.
-
-In pseudo language, a typical event loop might look like this:
-
-\begin{lstlisting}
- repeat until window is closed
- {
- poll events
- draw OpenGL graphics
- }
-\end{lstlisting}
-
-There are two ways to handle events in \GLFW :
-
-\begin{itemize}
- \item Block the event loop while waiting for new events.
- \item Poll for new events and continue the loop regardless of whether there
- are any new events or not.
-\end{itemize}
-
-The first method is useful for interactive applications that do not
-need to refresh the \OpenGL\ display unless the user interacts with the
-application through user input. Typical applications are CAD software
-and other kinds of editors.
-
-The second method is useful for applications that need to refresh the
-\OpenGL\ display constantly, regardless of user input, such as games,
-demos, 3D animations, screen savers and so on.
-
-
-%-------------------------------------------------------------------------
-\section{Callback Functions}
-Using callback functions can be a good method for receiving up to date
-information about window state and user input. When a window has been
-opened, it is possible to register custom callback functions that will
-be called when certain events occur.
-
-Callback functions are called from any of the event polling functions
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or
-\textbf{glfwSwapBuffers}.
-
-Callback functions should \emph{only} be used to gather information. Since
-the callback functions are called from within the internal \GLFW\ event
-polling loops, they should not call any \GLFW\ functions that might
-result in considerable \GLFW\ state changes, nor stall the event polling
-loop for a lengthy period of time.
-
-In other words, most or all \OpenGL\ rendering should be called from the
-main application event loop, not from any of the \GLFW\ callback
-functions. Also, the only \GLFW\ functions that may be safely called from
-callback functions are the different Get functions (e.g.
-\textbf{glfwGetKey}, \textbf{glfwGetTime}, \textbf{glfwGetWindowParam}
-etc.).
-
-
-%-------------------------------------------------------------------------
-% Function Reference
-%-------------------------------------------------------------------------
-\chapter{Function Reference}
-\thispagestyle{fancy}
-
-%-------------------------------------------------------------------------
-\section{GLFW Initialization and Termination}
-Before any other \GLFW\ functions can be used, \GLFW\ must be initialized to
-ensure proper functionality, and before a program terminates \GLFW\ should be
-terminated in order to free allocated resources, memory, etc.
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwInit}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwInit(void)
-\end{lstlisting}
-
-\begin{refparameters}
-none
-\end{refparameters}
-
-\begin{refreturn}
-If the function succeeds, GL\_TRUE is returned.\\
-If the function fails, GL\_FALSE is returned.
-\end{refreturn}
-
-\begin{refdescription}
-The glfwInit function initializes \GLFW. No other \GLFW\ functions may be
-called before this function has succeeded.
-\end{refdescription}
-
-\begin{refnotes}
-This function may take several seconds to complete on some systems, while
-on other systems it may take only a fraction of a second to complete.
-
-This function registers a function calling \textbf{glfwTerminate} with the
-atexit facility of the C library.
-
-On Mac OS X, this function will change the current directory of the application
-to the \textbf{Contents/Resources} subdirectory of the application's bundle, if
-present. For more information on bundles, see the Bundle Programming Guide
-provided by Apple.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwTerminate}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwTerminate(void)
-\end{lstlisting}
-
-\begin{refparameters}
-none
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function terminates \GLFW. Among other things it closes the window, if
-open. This function should be called before a program exits.
-\end{refdescription}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetVersion}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwGetVersion(int* major, int* minor, int* rev)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{major}]\ \\
- Pointer to an integer that will hold the major version number.
-\item [\textit{minor}]\ \\
- Pointer to an integer that will hold the minor version number.
-\item [\textit{rev}]\ \\
- Pointer to an integer that will hold the revision.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns the major and minor version numbers and the revision
-for the currently linked \GLFW\ library.
-\end{refreturn}
-
-\begin{refdescription}
-This function returns the \GLFW\ library version.
-\end{refdescription}
-
-
-%-------------------------------------------------------------------------
-\pagebreak
-\section{Window Handling}
-The primary purpose of \GLFW\ is to provide a simple interface to
-\OpenGL\ context creation and window management. \GLFW\ supports one window at
-a time, which can be either a normal desktop window or a fullscreen window.
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwOpenWindow}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwOpenWindow(int width, int height,
- int redbits, int greenbits, int bluebits,
- int alphabits, int depthbits, int stencilbits,
- int mode)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{width}]\ \\
- The width of the window. If \textit{width} is zero, it will be
- calculated as ${width=\frac{4}{3}height}$, if \textit{height} is not
- zero. If both \textit{width} and \textit{height} are zero,
- \textit{width} will be set to 640.
-\item [\textit{height}]\ \\
- The height of the window. If \textit{height} is zero, it will be
- calculated as ${height=\frac{3}{4}width}$, if \textit{width} is not
- zero. If both \textit{width} and \textit{height} are zero,
- \textit{height} will be set to 480.
-\item [\textit{redbits, greenbits, bluebits}]\ \\
- The number of bits to use for each color component of the color buffer
- (0 means default color depth). For instance, setting \textit{redbits=5,
- greenbits=6 and bluebits=5} will create a 16-bit color buffer, if
- possible.
-\item [\textit{alphabits}]\ \\
- The number of bits to use for the alpha channel of the color buffer (0 means
- no alpha channel).
-\item [\textit{depthbits}]\ \\
- The number of bits to use for the depth buffer (0 means no depth
- buffer).
-\item [\textit{stencilbits}]\ \\
- The number of bits to use for the stencil buffer (0 means no stencil
- buffer).
-\item [\textit{mode}]\ \\
- Selects which type of \OpenGL\ window to use. \textit{mode} must be
- either GLFW\_WINDOW, which will generate a normal desktop window, or
- GLFW\_FULLSCREEN, which will generate a window which covers the entire
- screen. When GLFW\_FULLSCREEN is selected, the video mode will be
- changed to the resolution that closest matches the \textit{width} and
- \textit{height} parameters.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-If the function succeeds, GL\_TRUE is returned.\\
-If the function fails, GL\_FALSE is returned.
-\end{refreturn}
-
-\begin{refdescription}
-This function opens a window that best matches the parameters given to the
-function. How well the resulting window matches the desired window depends
-mostly on the available hardware and \OpenGL\ drivers. In general,
-selecting a fullscreen mode has better chances of generating a close match
-of buffers and channel sizes than does a normal desktop window, since \GLFW\
-can freely select from all the available video modes. A desktop window is
-normally restricted to the video mode of the desktop.
-\end{refdescription}
-
-\begin{refnotes}
-For additional control of window properties, see
-\textbf{glfwOpenWindowHint}.
-
-In fullscreen mode the mouse cursor is hidden by default and the
-screensaver is prohibited from starting. In windowed mode the mouse
-cursor is visible and screensavers are allowed to start. To change the
-visibility of the mouse cursor, use \textbf{glfwEnable} or
-\textbf{glfwDisable} with the argument GLFW\_MOUSE\_CURSOR.
-
-In order to determine the actual properties of an opened window, use
-\textbf{glfwGetWindowParam} and \textbf{glfwGetWindowSize} (or
-\textbf{glfwSetWindowSizeCallback}).
-
-On Microsoft Windows, if the executable has an icon resource named
-\textbf{GLFW\_ICON}, it will be set as the icon for the window. If no such
-icon is present, the \textbf{IDI\_WINLOGO} icon will be used instead.
-
-On Mac OS X the \GLFW\ window has no icon, but programs using \GLFW\ will use
-the application bundle's icon. For more information on bundles, see the Bundle
-Programming Guide provided by Apple.
-
-For information on how the availability of different platform-specific
-extensions affect the behavior of this function, see appendix
-\ref{chap:compatibility}.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\begin{table}[p]
-\begin{center}
-\begin{tabular}{|l|l|p{7.0cm}|} \hline \raggedright
-\textbf{Name} & \textbf{Default} & \textbf{Description} \\ \hline
-GLFW\_REFRESH\_RATE & 0 & Vertical monitor refresh rate in Hz (only used for fullscreen windows). Zero means system default.\\ \hline
-GLFW\_ACCUM\_RED\_BITS & 0 & Number of bits for the red channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_GREEN\_BITS & 0 & Number of bits for the green channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_BLUE\_BITS & 0 & Number of bits for the blue channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_ALPHA\_BITS & 0 & Number of bits for the alpha channel of the accumulation buffer.\\ \hline
-GLFW\_AUX\_BUFFERS & 0 & Number of auxiliary buffers.\\ \hline
-GLFW\_STEREO & GL\_FALSE & Specify if stereo rendering should be supported (can be GL\_TRUE or GL\_FALSE).\\ \hline
-GLFW\_WINDOW\_NO\_RESIZE & GL\_FALSE & Specify whether the window can be resized by the user (not used for fullscreen windows).\\ \hline
-GLFW\_FSAA\_SAMPLES & 0 & Number of samples to use for the multisampling buffer. Zero disables multisampling.\\ \hline
-GLFW\_OPENGL\_VERSION\_MAJOR & 1 & Major number of the desired minimum \OpenGL\ version.\\ \hline
-GLFW\_OPENGL\_VERSION\_MINOR & 1 & Minor number of the desired minimum \OpenGL\ version.\\ \hline
-GLFW\_OPENGL\_FORWARD\_COMPAT & GL\_FALSE & Specify whether the \OpenGL\ context should be forward-compatible (i.e. disallow legacy functionality).
- This should only be used when requesting \OpenGL\ version 3.0 or above.\\ \hline
-GLFW\_OPENGL\_DEBUG\_CONTEXT & GL\_FALSE & Specify whether a debug context should be created.\\ \hline
-GLFW\_OPENGL\_PROFILE & 0 & The \OpenGL\ profile the context should implement, or zero to let the system choose.
- Available profiles are GLFW\_OPENGL\_CORE\_PROFILE and GLFW\_OPENGL\_COMPAT\_PROFILE.\\ \hline
-\end{tabular}
-\end{center}
-\caption{Targets for \textbf{glfwOpenWindowHint}}
-\label{tab:winhints}
-\end{table}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwOpenWindowHint}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwOpenWindowHint(int target, int hint)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{target}]\ \\
- Can be any of the tokens in the table \ref{tab:winhints}.
-\item [\textit{hint}]\ \\
- An integer giving the value of the corresponding token (see table
- \ref{tab:winhints}).
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function sets additional properties for a window that is to be opened.
-For a hint to be registered, the function must be called before calling
-\textbf{glfwOpenWindow}. When the \textbf{glfwOpenWindow} function is
-called, any hints that were registered with the \textbf{glfwOpenWindowHint}
-function are used for setting the corresponding window properties, and
-then all hints are reset to their default values.
-\end{refdescription}
-
-\begin{refnotes}
-In order to determine the actual properties of an opened window, use
-\textbf{glfwGetWindowParam} (after the window has been opened).
-
-GLFW\_STEREO is a hard constraint. If stereo rendering is requested, but no
-stereo rendering capable pixel formats / framebuffer configs are available,
-\textbf{glfwOpenWindow} will fail.
-
-The GLFW\_REFRESH\_RATE hint should be used with caution. Most
-systems have default values for monitor refresh rates that are optimal
-for the specific system. Specifying the refresh rate can override these
-settings, which can result in suboptimal operation. The monitor may be
-unable to display the resulting video signal, or in the worst case it may
-even be damaged!
-
-The GLFW\_WINDOW\_NO\_RESIZE hint applies only to manual resizing by the user.
-A window created with this hint enabled can still be resized by the application
-by calling \textbf{glfwSetWindowSize}.
-
-The GLFW\_OPENGL\_VERSION\_MAJOR and GLFW\_OPENGL\_VERSION\_MINOR hints specify
-the \OpenGL\ version that the created context must be compatible with,
-\emph{not} the exact version to use. It is therefore perfectly safe to use the
-default of version 1.1 for legacy code and you will still get
-backwards-compatible contexts of version 3.0 and above when available.
-
-To make the behavior of the above version hints consistent across both modern
-and legacy drivers, \textbf{glfwOpenWindow} will fail if the modern creation
-mechanism (as specified in \textbf{WGL\_ARB\_create\_context}
-and \textbf{GLX\_ARB\_create\_context}) is unavailable \emph{and} the created
-context is of a version lower than the one that was requested.
-
-At the time of release, the exact meaning of what a "debug context" is (as
-created using the GLFW\_OPENGL\_DEBUG\_CONTEXT hint) has yet to be defined by
-the Khronos ARB WG.
-
-For information on how the availability of different extensions affect the
-behavior of this function, see appendix \ref{chap:compatibility}.
-
-For full details on the workings of the \OpenGL\ version, forward-compatibility
-and debug hints, see the specifications for \textbf{WGL\_ARB\_create\_context}
-and \textbf{GLX\_ARB\_create\_context}, respectively. The relevant \GLFW\
-hints map very closely to their platform-specific counterparts.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwCloseWindow}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwCloseWindow(void)
-\end{lstlisting}
-
-\begin{refparameters}
-none
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function closes an opened window and destroys the associated \OpenGL\
-context.
-\end{refdescription}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetWindowCloseCallback}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetWindowCloseCallback(GLFWwindowclosefun cbfun)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{cbfun}]\ \\
- Pointer to a callback function that will be called when a user requests
- that the window should be closed, typically by clicking the window close
- icon (e.g. the cross in the upper right corner of a window under
- Microsoft Windows), and on Mac OS X also when selecting \textbf{Quit} from
- the application menu. The function should have the following C language
- prototype:
-
- \texttt{int functionname(void);}
-
- Where \textit{functionname} is the name of the callback function. The
- return value of the callback function indicates wether or not the window
- close action should continue. If the function returns GL\_TRUE, the
- window will be closed. If the function returns GL\_FALSE, the window
- will not be closed.
-
- If \textit{cbfun} is NULL, any previously set callback function
- will be unset.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function sets the callback for window close events.
-
-A window has to be opened for this function to have any effect.
-\end{refdescription}
-
-\begin{refnotes}
-Window close events are recorded continuously, but only reported when
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) is called.
-
-The \OpenGL\ context is still valid when this function is called.
-
-Note that the window close callback function is not called when
-\textbf{glfwCloseWindow} is called, but only when the close request
-comes from the window manager.
-
-Do \emph{not} call \textbf{glfwCloseWindow} from a window close
-callback function. Close the window by returning GL\_TRUE from the
-function.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetWindowTitle}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetWindowTitle(const char* title)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{title}]\ \\
- Pointer to a null terminated ISO~8859-1 (8-bit Latin~1) string that
- holds the title of the window.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function changes the title of the opened window.
-\end{refdescription}
-
-\begin{refnotes}
-The title property of a window is often used in situations other than for
-the window title, such as the title of an application icon when it is in
-iconified state.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetWindowSize}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetWindowSize(int width, int height)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{width}]\ \\
- Width of the window.
-\item [\textit{height}]\ \\
- Height of the window.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function changes the size of an opened window. The \textit{width} and
-\textit{height} parameters denote the size of the client area of the
-window (i.e. excluding any window borders and decorations).
-
-If the window is in fullscreen mode, the video mode will be changed to a
-resolution that closest matches the width and height parameters (the
-number of color bits will not be changed).
-\end{refdescription}
-
-\begin{refnotes}
-This function has no effect if the window is iconified.
-
-The \OpenGL\ context is guaranteed to be preserved after calling
-\textbf{glfwSetWindowSize}, even if the video mode is changed.
-
-This function is not affected by the value of the GLFW\_WINDOW\_NO\_RESIZE
-hint.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetWindowPos}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetWindowPos(int x, int y)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{x}]\ \\
- Horizontal position of the window, relative to the upper left corner
- of the desktop.
-\item [\textit{y}]\ \\
- Vertical position of the window, relative to the upper left corner of
- the desktop.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function changes the position of an opened window. It does not have
-any effect on a fullscreen window.
-\end{refdescription}
-
-\begin{refnotes}
-This function has no effect if the window is iconified.
-
-The behaviour of this function on multi-monitor systems is ill-defined.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetWindowSize}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwGetWindowSize(int* width, int* height)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{width}]\ \\
- Pointer to an integer that will hold the width of the window.
-\item [\textit{height}]\ \\
- Pointer to an integer that will hold the height of the window.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The current width and height of the opened window is returned in the
-\textit{width} and \textit{height} parameters, respectively.
-\end{refreturn}
-
-\begin{refdescription}
-This function is used for determining the size of an opened window.
-The returned values are dimensions of the client area of the window
-(i.e. excluding any window borders and decorations).
-\end{refdescription}
-
-\begin{refnotes}
-Even if the size of a fullscreen window does not change once the window
-has been opened, it does not necessarily have to be the same as the size
-that was requested using \textbf{glfwOpenWindow}. Therefor it is wise to
-use this function to determine the true size of the window once it has
-been opened.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetWindowSizeCallback}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetWindowSizeCallback(GLFWwindowsizefun cbfun)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{cbfun}]\ \\
- Pointer to a callback function that will be called every time the
- window size changes. The function should have the following C language
- prototype:
-
- \texttt{void functionname(int width, int height);}
-
- Where \textit{functionname} is the name of the callback function, and
- \textit{width} and \textit{height} are the dimensions of the window
- client area.
-
- If \textit{cbfun} is NULL, any previously set callback function
- will be unset.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function sets the callback for window size change events.
-
-A window has to be opened for this function to have any effect.
-\end{refdescription}
-
-\begin{refnotes}
-Window size changes are recorded continuously, but only reported when
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) is called.
-
-When a callback function is set, it will be called with the current window
-size before this function returns.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwIconifyWindow}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwIconifyWindow(void)
-\end{lstlisting}
-
-\begin{refparameters}
-none
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-Iconify a window. If the window is in fullscreen mode, then the desktop
-video mode will be restored.
-\end{refdescription}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwRestoreWindow}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwRestoreWindow(void)
-\end{lstlisting}
-
-\begin{refparameters}
-none
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-Restore an iconified window. If the window that is restored is in
-fullscreen mode, then the fullscreen video mode will be restored.
-\end{refdescription}
-
-
-%-------------------------------------------------------------------------
-\begin{table}[p]
-\begin{center}
-\begin{tabular}{|l|p{9.5cm}|} \hline \raggedright
-\textbf{Name} & \textbf{Description} \\ \hline
-GLFW\_OPENED & GL\_TRUE if window is opened, else GL\_FALSE.\\ \hline
-GLFW\_ACTIVE & GL\_TRUE if window has focus, else GL\_FALSE.\\ \hline
-GLFW\_ICONIFIED & GL\_TRUE if window is iconified, else GL\_FALSE.\\ \hline
-GLFW\_ACCELERATED & GL\_TRUE if window is hardware accelerated, else GL\_FALSE.\\ \hline
-GLFW\_RED\_BITS & Number of bits for the red color component.\\ \hline
-GLFW\_GREEN\_BITS & Number of bits for the green color component.\\ \hline
-GLFW\_BLUE\_BITS & Number of bits for the blue color component.\\ \hline
-GLFW\_ALPHA\_BITS & Number of bits for the alpha buffer.\\ \hline
-GLFW\_DEPTH\_BITS & Number of bits for the depth buffer.\\ \hline
-GLFW\_STENCIL\_BITS & Number of bits for the stencil buffer.\\ \hline
-GLFW\_REFRESH\_RATE & Vertical monitor refresh rate in Hz. Zero indicates an unknown or a default refresh rate.\\ \hline
-GLFW\_ACCUM\_RED\_BITS & Number of bits for the red channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_GREEN\_BITS & Number of bits for the green channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_BLUE\_BITS & Number of bits for the blue channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_ALPHA\_BITS & Number of bits for the alpha channel of the accumulation buffer.\\ \hline
-GLFW\_AUX\_BUFFERS & Number of auxiliary buffers.\\ \hline
-GLFW\_STEREO & GL\_TRUE if stereo rendering is supported, else GL\_FALSE.\\ \hline
-GLFW\_WINDOW\_NO\_RESIZE & GL\_TRUE if the window cannot be resized by the user, else GL\_FALSE.\\ \hline
-GLFW\_FSAA\_SAMPLES & Number of multisampling buffer samples. Zero indicated multisampling is disabled.\\ \hline
-GLFW\_OPENGL\_VERSION\_MAJOR & Major number of the actual version of the context.\\ \hline
-GLFW\_OPENGL\_VERSION\_MINOR & Minor number of the actual version of the context.\\ \hline
-GLFW\_OPENGL\_FORWARD\_COMPAT & GL\_TRUE if the context is forward-compatible, else GL\_FALSE.\\ \hline
-GLFW\_OPENGL\_DEBUG\_CONTEXT & GL\_TRUE if the context is a debug context.\\ \hline
-GLFW\_OPENGL\_PROFILE & The profile implemented by the context, or zero.\\ \hline
-\end{tabular}
-\end{center}
-\caption{Window parameters for \textbf{glfwGetWindowParam}}
-\label{tab:winparams}
-\end{table}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetWindowParam}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwGetWindowParam(int param)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{param}]\ \\
- A token selecting which parameter the function should return (see
- table \ref{tab:winparams}).
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns the value the window parameter corresponding to the token
-\textit{param}. Table \ref{tab:winparams} lists the available tokens.
-\end{refreturn}
-
-\begin{refdescription}
-This function is used for acquiring various properties of an opened window.
-\end{refdescription}
-
-\begin{refnotes}
-GLFW\_ACCELERATED is only supported under Windows. Other systems will
-always return GL\_TRUE. Under Windows, GLFW\_ACCELERATED means that the
-\OpenGL\ renderer is a 3rd party renderer, rather than the fallback
-Microsoft software \OpenGL\ renderer. In other words, it is not a real
-guarantee that the \OpenGL\ renderer is actually hardware accelerated.
-
-GLFW\_OPENGL\_VERSION\_MAJOR and GLFW\_OPENGL\_VERSION\_MINOR always return the
-same values as those returned by \textbf{glfwGetGLVersion}.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSwapBuffers}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSwapBuffers(void)
-\end{lstlisting}
-
-\begin{refparameters}
-none
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function swaps the back and front color buffers of the window. If
-GLFW\_AUTO\_POLL\_EVENTS is enabled (which is the default),
-\textbf{glfwPollEvents} is called after swapping the front and back
-buffers.
-\end{refdescription}
-
-\begin{refnotes}
-In previous versions of \GLFW , \textbf{glfwPollEvents} was called
-\emph{before} buffer swap. This was changed in order to decrease input
-lag but may affect code that relied on the former behavior.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSwapInterval}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSwapInterval(int interval)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{interval}]\ \\
- Minimum number of monitor vertical retraces between each buffer swap
- performed by \textbf{glfwSwapBuffers}. If \textit{interval} is zero,
- buffer swaps will not be synchronized to the vertical refresh of the
- monitor (also known as 'VSync off').
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function selects the minimum number of monitor vertical retraces that
-should occur between two buffer swaps. If the selected swap interval is
-one, the rate of buffer swaps will never be higher than the vertical
-refresh rate of the monitor. If the selected swap interval is zero, the
-rate of buffer swaps is only limited by the speed of the software and
-the hardware.
-\end{refdescription}
-
-\begin{refnotes}
-This function will only have an effect on hardware and drivers that support
-user selection of the swap interval. ATI drivers in particular have been known
-to ignore this setting.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetWindowRefreshCallback}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetWindowRefreshCallback(GLFWwindowrefreshfun cbfun)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{cbfun}]\ \\
- Pointer to a callback function that will be called when the window client
- area needs to be refreshed. The function should have the following C
- language prototype:
-
- \texttt{void functionname(void);}
-
- Where \textit{functionname} is the name of the callback function.
-
- If \textit{cbfun} is NULL, any previously set callback function
- will be unset.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function sets the callback for window refresh events, which occurs when
-any part of the window client area has been damaged, and needs to be repainted
-(for instance, if a part of the window that was previously occluded by another
-window has become visible).
-
-A window has to be opened for this function to have any effect.
-\end{refdescription}
-
-\begin{refnotes}
-Window refresh events are recorded continuously, but only reported when
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) is called.
-
-Modern windowing systems using hardware compositing, such as Aqua, Aero and
-Compiz, very rarely need to refresh the contents of windows, so the specified
-callback will very rarely be called on such systems.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\pagebreak
-\section{Video Modes}
-Since \GLFW\ supports video mode changes when using a fullscreen window,
-it also provides functionality for querying which video modes are
-supported on a system.
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetVideoModes}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwGetVideoModes(GLFWvidmode* list, int maxcount)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{list}]\ \\
- A vector of \textit{GLFWvidmode} structures, which will be filled out
- by the function.
-\item [\textit{maxcount}]\ \\
- Maximum number of video modes that \textit{list} vector can hold.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns the number of detected video modes (this number
-will never exceed \textit{maxcount}). The \textit{list} vector is
-filled out with the video modes that are supported by the system.
-\end{refreturn}
-
-\begin{refdescription}
-This function returns a list of supported video modes. Each video mode is
-represented by a \textit{GLFWvidmode} structure, which has the following
-definition:
-
-\begin{lstlisting}
-typedef struct {
- int Width, Height; // Video resolution
- int RedBits; // Number of red bits
- int GreenBits; // Number of green bits
- int BlueBits; // Number of blue bits
-} GLFWvidmode;
-\end{lstlisting}
-\end{refdescription}
-
-\begin{refnotes}
-The returned list is sorted, first by color depth ($RedBits + GreenBits +
-BlueBits$), and then by resolution ($Width \times Height$), with the
-lowest resolution, fewest bits per pixel mode first.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetDesktopMode}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwGetDesktopMode(GLFWvidmode* mode)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{mode}]\ \\
- Pointer to a \textit{GLFWvidmode} structure, which will be filled out
- by the function.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The \textit{GLFWvidmode} structure pointed to by \textit{mode} is filled
-out with the desktop video mode.
-\end{refreturn}
-
-\begin{refdescription}
-This function returns the desktop video mode in a \textit{GLFWvidmode}
-structure. See \textbf{glfwGetVideoModes} for a definition of the
-\textit{GLFWvidmode} structure.
-\end{refdescription}
-
-\begin{refnotes}
-The color depth of the desktop display is always reported as the number
-of bits for each individual color component (red, green and blue), even
-if the desktop is not using an RGB or RGBA color format. For instance, an
-indexed 256 color display may report \textit{RedBits} = 3,
-\textit{GreenBits} = 3 and \textit{BlueBits} = 2, which adds up to 8 bits
-in total.
-
-The desktop video mode is the video mode used by the desktop at the time
-the \GLFW\ window was opened, \textit{not} the current video mode (which
-may differ from the desktop video mode if the \GLFW\ window is a
-fullscreen window).
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\pagebreak
-\section{Input Handling}
-\GLFW\ supports three channels of user input: keyboard input, mouse input
-and joystick input.
-
-Keyboard and mouse input can be treated either as events, using callback
-functions, or as state, using functions for polling specific keyboard and
-mouse states. Regardless of which method is used, all keyboard and mouse
-input is collected using window event polling.
-
-Joystick input is asynchronous to the keyboard and mouse input, and does
-not require event polling for keeping up to date joystick information.
-Also, joystick input is independent of any window, so a window does not
-have to be opened for joystick input to be used.
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwPollEvents}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwPollEvents(void)
-\end{lstlisting}
-
-\begin{refparameters}
-none
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function is used for polling for events, such as user input and
-window resize events. Upon calling this function, all window states,
-keyboard states and mouse states are updated. If any related callback
-functions are registered, these are called during the call to
-\textbf{glfwPollEvents}.
-\end{refdescription}
-
-\begin{refnotes}
-\textbf{glfwPollEvents} is called implicitly from \textbf{glfwSwapBuffers}
-if GLFW\_AUTO\_POLL\_EVENTS is enabled (as it is by default). Thus, if
-\textbf{glfwSwapBuffers} is called frequently, which is normally the case,
-there is no need to call \textbf{glfwPollEvents}.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwWaitEvents}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwWaitEvents(void)
-\end{lstlisting}
-
-\begin{refparameters}
-none
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function is used for waiting for events, such as user input and
-window resize events. Upon calling this function, the calling thread will
-be put to sleep until any event appears in the event queue. When events
-are available, they will be processed just as they are processed by
-\textbf{glfwPollEvents}.
-
-If there are any events in the queue when the function is called, the
-function will behave exactly like \textbf{glfwPollEvents} (i.e. process
-all messages and then return, without blocking the calling thread).
-\end{refdescription}
-
-\begin{refnotes}
-It is guaranteed that \textbf{glfwWaitEvents} will wake up on any event that
-can be processed by \textbf{glfwPollEvents}. However, \GLFW\ receives many
-events that are only processed internally and the function may behave
-differently on different systems. Do not make any assumptions about when or why
-\textbf{glfwWaitEvents} will return.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\begin{table}[p]
-\begin{center}
-\begin{tabular}{|l|l|} \hline \raggedright
-\textbf{Name} & \textbf{Description} \\ \hline
-GLFW\_KEY\_\textit{X} & Letter (\textit{X} can be in the range A..Z)\\ \hline
-GLFW\_KEY\_\textit{n} & Number (\textit{n} can be in the range 0..9)\\ \hline
-GLFW\_KEY\_SPACE & Space\\ \hline
-GLFW\_KEY\_MINUS & Minus (-)\\ \hline
-GLFW\_KEY\_EQUAL & Equal (=)\\ \hline
-GLFW\_KEY\_LEFT\_BRACKET & Left bracket ([)\\ \hline
-GLFW\_KEY\_RIGHT\_BRACKET & Right bracket (])\\ \hline
-GLFW\_KEY\_GRAVE\_ACCENT & Grave accent (`)\\ \hline
-GLFW\_KEY\_APOSTROPHE & Apostrophe (')\\ \hline
-GLFW\_KEY\_COMMA & Comma (,)\\ \hline
-GLFW\_KEY\_PERIOD & Period (.)\\ \hline
-GLFW\_KEY\_SEMICOLON & Semicolon (;)\\ \hline
-GLFW\_KEY\_SLASH & Slash ($/$)\\ \hline
-GLFW\_KEY\_BACKSLASH & Backslash ($\backslash$)\\ \hline
-GLFW\_KEY\_WORLD\_1 & Non-US character no. 1\\ \hline
-GLFW\_KEY\_WORLD\_2 & Non-US character no. 2\\ \hline
-\end{tabular}
-\end{center}
-\caption[Key codes for printable keys]{Key codes for printable keys. The keys are named according to the US keyboard layout, but represent physical keys (so for instance, GLFW\_KEY\_Z represents the same physical key, regardless of the system input language).}
-\label{tab:keys1}
-\end{table}
-
-\begin{table}[p]
-\begin{center}
-\begin{tabular}{|l|l|} \hline \raggedright
-\textbf{Name} & \textbf{Description} \\ \hline
-GLFW\_KEY\_ESCAPE & Escape\\ \hline
-GLFW\_KEY\_F\textit{n} & Function key \textit{n} (\textit{n} can be in the range 1..25)\\ \hline
-GLFW\_KEY\_UP & Cursor up\\ \hline
-GLFW\_KEY\_DOWN & Cursor down\\ \hline
-GLFW\_KEY\_LEFT & Cursor left\\ \hline
-GLFW\_KEY\_RIGHT & Cursor right\\ \hline
-GLFW\_KEY\_LEFT\_SHIFT & Left shift key\\ \hline
-GLFW\_KEY\_RIGHT\_SHIFT & Right shift key\\ \hline
-GLFW\_KEY\_LEFT\_CTRL & Left control key\\ \hline
-GLFW\_KEY\_RIGHT\_CTRL & Right control key\\ \hline
-GLFW\_KEY\_LEFT\_ALT & Left alternate function key\\ \hline
-GLFW\_KEY\_RIGHT\_ALT & Right alternate function key\\ \hline
-GLFW\_KEY\_LEFT\_SUPER & Left super key, WinKey, or command key\\ \hline
-GLFW\_KEY\_RIGHT\_SUPER & Right super key, WinKey, or command key\\ \hline
-GLFW\_KEY\_TAB & Tabulator\\ \hline
-GLFW\_KEY\_ENTER & Enter\\ \hline
-GLFW\_KEY\_BACKSPACE & Backspace\\ \hline
-GLFW\_KEY\_INSERT & Insert\\ \hline
-GLFW\_KEY\_DELETE & Delete\\ \hline
-GLFW\_KEY\_PAGE\_UP & Page up\\ \hline
-GLFW\_KEY\_PAGE\_DOWN & Page down\\ \hline
-GLFW\_KEY\_HOME & Home\\ \hline
-GLFW\_KEY\_END & End\\ \hline
-GLFW\_KEY\_KP\_\textit{n} & Keypad numeric key \textit{n} (\textit{n} can be in the range 0..9)\\ \hline
-GLFW\_KEY\_KP\_DIVIDE & Keypad divide ($\div$)\\ \hline
-GLFW\_KEY\_KP\_MULTIPLY & Keypad multiply ($\times$)\\ \hline
-GLFW\_KEY\_KP\_SUBTRACT & Keypad subtract ($-$)\\ \hline
-GLFW\_KEY\_KP\_ADD & Keypad add ($+$)\\ \hline
-GLFW\_KEY\_KP\_DECIMAL & Keypad decimal (. or ,)\\ \hline
-GLFW\_KEY\_KP\_EQUAL & Keypad equal (=)\\ \hline
-GLFW\_KEY\_KP\_ENTER & Keypad enter\\ \hline
-GLFW\_KEY\_NUM\_LOCK & Num lock\\ \hline
-GLFW\_KEY\_CAPS\_LOCK & Caps lock\\ \hline
-GLFW\_KEY\_SCROLL\_LOCK & Scroll lock\\ \hline
-GLFW\_KEY\_PAUSE & Pause key\\ \hline
-GLFW\_KEY\_MENU & Menu key\\ \hline
-\end{tabular}
-\end{center}
-\caption{Key codes for function keys}
-\label{tab:keys2}
-\end{table}
-
-
-%-------------------------------------------------------------------------
-\begin{table}[p]
-\begin{center}
-\begin{tabular}{|l|l|} \hline \raggedright
-\textbf{Name} & \textbf{Description} \\ \hline
-GLFW\_MOUSE\_BUTTON\_LEFT & Left mouse button (button 1) \\ \hline
-GLFW\_MOUSE\_BUTTON\_RIGHT & Right mouse button (button 2) \\ \hline
-GLFW\_MOUSE\_BUTTON\_MIDDLE & Middle mouse button (button 3) \\ \hline
-GLFW\_MOUSE\_BUTTON\_\textit{n} & Mouse button \textit{n} (\textit{n} can be in the range 1..8)\\ \hline
-\end{tabular}
-\end{center}
-\caption{Valid mouse button identifiers}
-\label{tab:mousebuttons}
-\end{table}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetKey}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwGetKey(int key)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{key}]\ \\
- A keyboard key identifier, which can be any of the key codes in tables
- \ref{tab:keys1} and \ref{tab:keys2}.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns GLFW\_PRESS if the key is held down, or GLFW\_RELEASE
-if the key is not held down.
-\end{refreturn}
-
-\begin{refdescription}
-This function queries the current state of a specific keyboard key. The
-physical location of each key depends on the system keyboard layout
-setting.
-\end{refdescription}
-
-\begin{refnotes}
-The constant GLFW\_KEY\_SPACE is equal to 32, which is the ISO~8859-1 code
-for space. This is the only named \GLFW\ key identifier with a value in the
-ISO~8859-1 range.
-
-Not all key codes are supported on all systems. Also, while some keys are
-available on some keyboard layouts, they may not be available on other
-keyboard layouts.
-
-For systems that do not distinguish between left and right versions of
-modifier keys (shift, alt and control), the left version is used (e.g.
-GLFW\_KEY\_LSHIFT).
-
-A window must be opened for the function to have any effect, and
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) must be called before any keyboard
-events are recorded and reported by \textbf{glfwGetKey}.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetMouseButton}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwGetMouseButton(int button)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{button}]\ \\
- A mouse button identifier, which can be one of the mouse button
- identifiers listed in table \ref{tab:mousebuttons}.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns GLFW\_PRESS if the mouse button is held down, or
-GLFW\_RELEASE if the mouse button is not held down.
-\end{refreturn}
-
-\begin{refdescription}
-This function queries the current state of a specific mouse button.
-\end{refdescription}
-
-\begin{refnotes}
-A window must be opened for the function to have any effect, and
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) must be called before any mouse button
-events are recorded and reported by \textbf{glfwGetMouseButton}.
-
-GLFW\_MOUSE\_BUTTON\_LEFT is equal to GLFW\_MOUSE\_BUTTON\_1.
-GLFW\_MOUSE\_BUTTON\_RIGHT is equal to GLFW\_MOUSE\_BUTTON\_2.
-GLFW\_MOUSE\_BUTTON\_MIDDLE is equal to GLFW\_MOUSE\_BUTTON\_3.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetMousePos}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwGetMousePos(int* xpos, int* ypos)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{xpos}]\ \\
- Pointer to an integer that will be set to the horizontal position of the
- mouse cursor.
-\item [\textit{ypos}]\ \\
- Pointer to an integer that will be set to the vertical position of the mouse cursor.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns the current mouse cursor position in \textit{xpos} and
-\textit{ypos}.
-\end{refreturn}
-
-\begin{refdescription}
-This function returns the current mouse position. If the cursor is not
-hidden, the mouse position is the cursor position, relative to the upper
-left corner of the window and with the Y-axis down. If the cursor is hidden,
-the mouse position is a virtual absolute position, not limited to any
-boundaries except to those implied by the maximum number that can be
-represented by a signed integer.
-\end{refdescription}
-
-\begin{refnotes}
-A window must be opened for the function to have any effect, and
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) must be called before any mouse
-movements are recorded and reported by \textbf{glfwGetMousePos}.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetMousePos}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetMousePos(int xpos, int ypos)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{xpos}]\ \\
- Horizontal position of the mouse.
-\item [\textit{ypos}]\ \\
- Vertical position of the mouse.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function changes the position of the mouse. If the cursor is visible (not
-disabled), the cursor will be moved to the specified position, relative to the
-upper left corner of the window client area and with the Y-axis down. If the
-cursor is hidden (disabled), only the mouse position that is reported by \GLFW\
-is changed.
-\end{refdescription}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetMouseWheel}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwGetMouseWheel(void)
-\end{lstlisting}
-
-\begin{refparameters}
-none
-\end{refparameters}
-
-\begin{refreturn}
-The function returns the current mouse wheel position.
-\end{refreturn}
-
-\begin{refdescription}
-This function returns the current mouse wheel position. The mouse wheel can
-be thought of as a third mouse axis, which is available as a separate
-wheel or up/down stick on some mice.
-\end{refdescription}
-
-\begin{refnotes}
-A window must be opened for the function to have any effect, and
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) must be called before any mouse wheel
-movements are recorded and reported by \textbf{glfwGetMouseWheel}.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetMouseWheel}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetMouseWheel(int pos)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{pos}]\ \\
- Position of the mouse wheel.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function changes the position of the mouse wheel.
-\end{refdescription}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetKeyCallback}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetKeyCallback(GLFWkeyfun cbfun)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{cbfun}]\ \\
- Pointer to a callback function that will be called every time a key is
- pressed or released. The function should have the following C language
- prototype:
-
- \texttt{void functionname(int key, int action);}
-
- Where \textit{functionname} is the name of the callback function,
- \textit{key} is a key code (see tables \ref{tab:keys1} and \ref{tab:keys2}),
- and \textit{action} is either GLFW\_PRESS or GLFW\_RELEASE.
-
- If \textit{cbfun} is NULL, any previously set callback function
- will be unset.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function sets the callback for keyboard key events. The callback function
-is called every time the state of a single key is changed (from released to
-pressed or vice versa). The reported keys are unaffected by any modifiers (such
-as shift or alt) and each modifier is reported as a separate key.
-
-A window has to be opened for this function to have any effect.
-\end{refdescription}
-
-\begin{refnotes}
-Keyboard key events are not intended for text input and many languages
-will not be able to be input using it. Use Unicode character events for
-text input instead.
-
-Keyboard events are recorded continuously, but only reported when
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) is called.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetCharCallback}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetCharCallback(GLFWcharfun cbfun)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{cbfun}]\ \\
- Pointer to a callback function that will be called every time a
- printable character is generated by the keyboard. The function should
- have the following C language prototype:
-
- \texttt{void functionname(int character, int action);}
-
- Where \textit{functionname} is the name of the callback function,
- \textit{character} is a Unicode (ISO~10646) character, and
- \textit{action} is either GLFW\_PRESS or GLFW\_RELEASE.
-
- If \textit{cbfun} is NULL, any previously set callback function
- will be unset.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function sets the callback for keyboard character events. The callback
-function is called every time a key that results in a printable Unicode
-character is pressed or released. Characters are affected by modifiers (such
-as shift or alt).
-
-A window has to be opened for this function to have any effect.
-\end{refdescription}
-
-\begin{refnotes}
-Character events are recorded continuously, but only reported when
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) is called.
-
-Control characters such as tab and carriage return are not reported to
-the character callback function, since they are not part of the Unicode
-character set. Use the key callback function for such events (see
-\textbf{glfwSetKeyCallback}).
-
-The Unicode character set supports character codes above 255, so never
-cast a Unicode character to an eight bit data type (e.g. the C language
-'char' type) without first checking that the character code is less than
-256. Also note that Unicode character codes 0 to 255 are equal to
-ISO~8859-1 (Latin~1).
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetMouseButtonCallback}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{cbfun}]\ \\
- Pointer to a callback function that will be called every time a mouse
- button is pressed or released. The function should have the following C
- language prototype:
-
- \texttt{void functionname(int button, int action);}
-
- Where \textit{functionname} is the name of the callback function,
- \textit{button} is a mouse button identifier (see table
- \ref{tab:mousebuttons} on page \pageref{tab:mousebuttons}), and
- \textit{action} is either GLFW\_PRESS or GLFW\_RELEASE.
-
- If \textit{cbfun} is NULL, any previously set callback function
- will be unset.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function sets the callback for mouse button events.
-
-A window has to be opened for this function to have any effect.
-\end{refdescription}
-
-\begin{refnotes}
-Mouse button events are recorded continuously, but only reported when
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) is called.
-
-GLFW\_MOUSE\_BUTTON\_LEFT is equal to GLFW\_MOUSE\_BUTTON\_1.
-GLFW\_MOUSE\_BUTTON\_RIGHT is equal to GLFW\_MOUSE\_BUTTON\_2.
-GLFW\_MOUSE\_BUTTON\_MIDDLE is equal to GLFW\_MOUSE\_BUTTON\_3.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetMousePosCallback}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetMousePosCallback(GLFWmouseposfun cbfun)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{cbfun}]\ \\
- Pointer to a callback function that will be called every time the mouse
- is moved. The function should have the following C language prototype:
-
- \texttt{void functionname(int x, int y);}
-
- Where \textit{functionname} is the name of the callback function, and
- \textit{x} and \textit{y} are the mouse coordinates (see
- \textbf{glfwGetMousePos} for more information on mouse coordinates).
-
- If \textit{cbfun} is NULL, any previously set callback function
- will be unset.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function sets the callback for mouse motion events.
-
-A window has to be opened for this function to have any effect.
-\end{refdescription}
-
-\begin{refnotes}
-Mouse motion events are recorded continuously, but only reported when
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) is called.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetMouseWheelCallback}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetMouseWheelCallback(GLFWmousewheelfun cbfun)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{cbfun}]\ \\
- Pointer to a callback function that will be called every time the mouse
- wheel is moved. The function should have the following C language
- prototype:
-
- \texttt{void functionname(int pos);}
-
- Where \textit{functionname} is the name of the callback function, and
- \textit{pos} is the mouse wheel position.
-
- If \textit{cbfun} is NULL, any previously set callback function
- will be unset.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function sets the callback for mouse wheel events.
-
-A window has to be opened for this function to have any effect.
-\end{refdescription}
-
-\begin{refnotes}
-Mouse wheel events are recorded continuously, but only reported when
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled) is called.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\begin{table}[p]
-\begin{center}
-\begin{tabular}{|l|l|}\hline \raggedright
-\textbf{Name} & \textbf{Return value}\\ \hline
-GLFW\_PRESENT & GL\_TRUE if the joystick is connected, else GL\_FALSE.\\ \hline
-GLFW\_AXES & Number of axes supported by the joystick.\\ \hline
-GLFW\_BUTTONS & Number of buttons supported by the joystick.\\ \hline
-\end{tabular}
-\end{center}
-\caption{Joystick parameters for \textbf{glfwGetJoystickParam}}
-\label{tab:joyparams}
-\end{table}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetJoystickParam}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwGetJoystickParam(int joy, int param)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{joy}]\ \\
- A joystick identifier, which should be GLFW\_JOYSTICK\_\textit{n}, where
- \textit{n} is in the range 1 to 16.
-\item [\textit{param}]\ \\
- A token selecting which parameter the function should return (see table
- \ref{tab:joyparams}).
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns different parameters depending on the value of
-\textit{param}. Table \ref{tab:joyparams} lists valid \textit{param}
-values, and their corresponding return values.
-\end{refreturn}
-
-\begin{refdescription}
-This function is used for acquiring various properties of a joystick.
-\end{refdescription}
-
-\begin{refnotes}
-The joystick information is updated every time the function is called.
-
-No window has to be opened for joystick information to be available.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetJoystickPos}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwGetJoystickPos(int joy, float* pos, int numaxes)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{joy}]\ \\
- A joystick identifier, which should be GLFW\_JOYSTICK\_\textit{n}, where
- \textit{n} is in the range 1 to 16.
-\item [\textit{pos}]\ \\
- An array that will hold the positional values for all requested axes.
-\item [\textit{numaxes}]\ \\
- Specifies how many axes should be returned.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns the number of actually returned axes. This is the
-minimum of \textit{numaxes} and the number of axes supported by the
-joystick. If the joystick is not supported or connected, the function will
-return 0 (zero).
-\end{refreturn}
-
-\begin{refdescription}
-This function queries the current position of one or more axes of a
-joystick. The positional values are returned in an array, where the first
-element represents the first axis of the joystick (normally the X axis).
-Each position is in the range -1.0 to 1.0. Where applicable, the positive
-direction of an axis is right, forward or up, and the negative direction
-is left, back or down.
-
-If \textit{numaxes} exceeds the number of axes supported by the joystick,
-or if the joystick is not available, the unused elements in the
-\textit{pos} array will be set to 0.0 (zero).
-\end{refdescription}
-
-\begin{refnotes}
-The joystick state is updated every time the function is called, so there
-is no need to call \textbf{glfwPollEvents} or \textbf{glfwWaitEvents} for
-joystick state to be updated.
-
-Use \textbf{glfwGetJoystickParam} to retrieve joystick capabilities, such
-as joystick availability and number of supported axes.
-
-No window has to be opened for joystick input to be available.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetJoystickButtons}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwGetJoystickButtons(int joy, unsigned char* buttons,
- int numbuttons)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{joy}]\ \\
- A joystick identifier, which should be GLFW\_JOYSTICK\_\textit{n}, where
- \textit{n} is in the range 1 to 16.
-\item [\textit{buttons}]\ \\
- An array that will hold the button states for all requested buttons.
-\item [\textit{numbuttons}]\ \\
- Specifies how many buttons should be returned.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns the number of actually returned buttons. This is the
-minimum of \textit{numbuttons} and the number of buttons supported by the
-joystick. If the joystick is not supported or connected, the function will
-return 0 (zero).
-\end{refreturn}
-
-\begin{refdescription}
-This function queries the current state of one or more buttons of a
-joystick. The button states are returned in an array, where the first
-element represents the first button of the joystick. Each state can be
-either GLFW\_PRESS or GLFW\_RELEASE.
-
-If \textit{numbuttons} exceeds the number of buttons supported by the
-joystick, or if the joystick is not available, the unused elements in the
-\textit{buttons} array will be set to GLFW\_RELEASE.
-\end{refdescription}
-
-\begin{refnotes}
-The joystick state is updated every time the function is called, so there
-is no need to call \textbf{glfwPollEvents} or \textbf{glfwWaitEvents} for
-joystick state to be updated.
-
-Use \textbf{glfwGetJoystickParam} to retrieve joystick capabilities, such
-as joystick availability and number of supported buttons.
-
-No window has to be opened for joystick input to be available.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\pagebreak
-\section{Timing}
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetTime}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-double glfwGetTime(void)
-\end{lstlisting}
-
-\begin{refparameters}
-none
-\end{refparameters}
-
-\begin{refreturn}
-The function returns the value of the high precision timer. The time is
-measured in seconds, and is returned as a double precision floating point
-value.
-\end{refreturn}
-
-\begin{refdescription}
-This function returns the state of a high precision timer. Unless the timer
-has been set by the \textbf{glfwSetTime} function, the time is measured as
-the number of seconds that have passed since \textbf{glfwInit} was called.
-\end{refdescription}
-
-\begin{refnotes}
-The resolution of the timer depends on which system the program is running
-on.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwSetTime}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwSetTime(double time)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{time}]\ \\
- Time (in seconds) that the timer should be set to.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-This function sets the current time of the high precision timer to the
-specified time. Subsequent calls to \textbf{glfwGetTime} will be relative
-to this time. The time is given in seconds.
-\end{refdescription}
-
-
-%-------------------------------------------------------------------------
-\pagebreak
-\section{OpenGL Extension Support}
-One of the great features of \OpenGL\ is its support for extensions, which
-allow independent vendors to supply non-standard functionality in their
-\OpenGL\ implementations. As the mechanism for querying extensions varies
-among systems, \GLFW\ provides an operating system independent interface for
-querying \OpenGL\ version, extensions and entry points.
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwExtensionSupported}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-int glfwExtensionSupported(const char* extension)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{extension}]\ \\
- A null terminated ISO~8859-1 string containing the name of an \OpenGL\
- extension.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns GL\_TRUE if the extension is supported. Otherwise it
-returns GL\_FALSE.
-\end{refreturn}
-
-\begin{refdescription}
-This function does a string search in the list of supported \OpenGL\
-extensions to find if the specified extension is listed.
-\end{refdescription}
-
-\begin{refnotes}
-An \OpenGL\ context must be created before this function can be called
-(i.e. an \OpenGL\ window must have been opened with
-\textbf{glfwOpenWindow}).
-
-In addition to checking for \OpenGL\ extensions, \GLFW\ also checks for
-extensions in the operating system ``glue API'', such as WGL extensions
-under Microsoft Windows and GLX extensions under the X Window System.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetProcAddress}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void* glfwGetProcAddress(const char* procname)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{procname}]\ \\
- A null terminated ISO~8859-1 string containing the name of an \OpenGL\
- extension function.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns the address of the specified \OpenGL\ function, if it
-is available. Otherwise NULL is returned.
-\end{refreturn}
-
-\begin{refdescription}
-This function acquires the pointer to an \OpenGL\ extension function. Some
-(but not all) \OpenGL\ extensions define new API functions, which are
-usually not available through normal linking. It is therefore necessary to
-get access to those API functions at runtime.
-\end{refdescription}
-
-\begin{refnotes}
-An \OpenGL\ context must be created before this function can be called
-(i.e. an \OpenGL\ window must have been opened with
-\textbf{glfwOpenWindow}).
-
-Some systems do not support dynamic function pointer retrieval, in which
-case \textbf{glfwGetProcAddress} will always return NULL.
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwGetGLVersion}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwGetGLVersion(int* major, int* minor, int* rev)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{major}]\ \\
- Pointer to an integer that will hold the major version number.
-\item [\textit{minor}]\ \\
- Pointer to an integer that will hold the minor version number.
-\item [\textit{rev}]\ \\
- Pointer to an integer that will hold the revision.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-The function returns the major and minor version numbers and the revision
-for the currently used \OpenGL\ implementation.
-\end{refreturn}
-
-\begin{refdescription}
-This function returns the \OpenGL\ implementation version. This is a
-convenient function that parses the version number information at the beginning
-of the string returned by calling \texttt{glGetString(~GL\_VERSION~)}. The
-\OpenGL\ version information can be used to determine what functionality is
-supported by the used \OpenGL\ implementation.
-\end{refdescription}
-
-\begin{refnotes}
-An \OpenGL\ context must be created before this function can be called
-(i.e. an \OpenGL\ window must have been opened with
-\textbf{glfwOpenWindow}).
-\end{refnotes}
-
-
-%-------------------------------------------------------------------------
-\pagebreak
-\section{Miscellaneous}
-
-
-%-------------------------------------------------------------------------
-\subsection{glfwEnable/glfwDisable}
-
-\textbf{C language syntax}
-\begin{lstlisting}
-void glfwEnable(int token)
-void glfwDisable(int token)
-\end{lstlisting}
-
-\begin{refparameters}
-\begin{description}
-\item [\textit{token}]\ \\
- A value specifying a feature to enable or disable. Valid tokens are
- listed in table \ref{tab:enable}.
-\end{description}
-\end{refparameters}
-
-\begin{refreturn}
-none
-\end{refreturn}
-
-\begin{refdescription}
-\textbf{glfwEnable} is used to enable a certain feature, while
-\textbf{glfwDisable} is used to disable it. Below follows a description of
-each feature.
-\end{refdescription}
-
-
-\begin{table}[p]
-\begin{center}
-\begin{tabular}{|l|p{5.0cm}|p{3.0cm}|} \hline \raggedright
-\textbf{Name} & \textbf{Controls} & \textbf{Default}\\ \hline
-\hyperlink{lnk:autopollevents}{GLFW\_AUTO\_POLL\_EVENTS} & Automatic event polling when \textbf{glfwSwapBuffers} is called & Enabled\\ \hline
-\hyperlink{lnk:keyrepeat}{GLFW\_KEY\_REPEAT} & Keyboard key repeat & Disabled\\ \hline
-\hyperlink{lnk:mousecursor}{GLFW\_MOUSE\_CURSOR} & Mouse cursor visibility & Enabled in windowed mode. Disabled in fullscreen mode.\\ \hline
-\hyperlink{lnk:stickykeys}{GLFW\_STICKY\_KEYS} & Keyboard key ``stickiness'' & Disabled\\ \hline
-\hyperlink{lnk:stickymousebuttons}{GLFW\_STICKY\_MOUSE\_BUTTONS} & Mouse button ``stickiness'' & Disabled\\ \hline
-\hyperlink{lnk:systemkeys}{GLFW\_SYSTEM\_KEYS} & Special system key actions & Enabled\\ \hline
-\end{tabular}
-\end{center}
-\caption{Tokens for \textbf{glfwEnable}/\textbf{glfwDisable}}
-\label{tab:enable}
-\end{table}
-
-
-\bigskip\begin{mysamepage}\hypertarget{lnk:autopollevents}{}
-\textbf{GLFW\_AUTO\_POLL\_EVENTS}\\
-When GLFW\_AUTO\_POLL\_EVENTS is enabled, \textbf{glfwPollEvents} is
-automatically called each time that \textbf{glfwSwapBuffers} is called,
-immediately after the buffer swap itself.
-
-When GLFW\_AUTO\_POLL\_EVENTS is disabled, calling
-\textbf{glfwSwapBuffers} will not result in a call to
-\textbf{glfwPollEvents}. This can be useful if for example \textbf{glfwSwapBuffers}
-needs to be called from within a callback function, since calling
-\textbf{glfwPollEvents} from a callback function is not allowed.
-\end{mysamepage}
-
-
-\bigskip\begin{mysamepage}\hypertarget{lnk:keyrepeat}{}
-\textbf{GLFW\_KEY\_REPEAT}\\
-When GLFW\_KEY\_REPEAT is enabled, the key and character callback
-functions are called repeatedly when a key is held down long enough
-(according to the system key repeat configuration).
-
-When GLFW\_KEY\_REPEAT is disabled, the key and character callback
-functions are only called once when a key is pressed (and once when it is
-released).
-\end{mysamepage}
-
-
-\bigskip\begin{mysamepage}\hypertarget{lnk:mousecursor}{}
-\textbf{GLFW\_MOUSE\_CURSOR}\\
-When GLFW\_MOUSE\_CURSOR is enabled, the mouse cursor is visible, and
-mouse coordinates are relative to the upper left corner of the client area
-of the \GLFW\ window. The coordinates are limited to the client area of
-the window.
-
-When GLFW\_MOUSE\_CURSOR is disabled, the mouse cursor is invisible, and
-mouse coordinates are not limited to the drawing area of the window. It is
-as if the mouse coordinates are received directly from the mouse, without
-being restricted or manipulated by the windowing system.
-\end{mysamepage}
-
-
-\bigskip\begin{mysamepage}\hypertarget{lnk:stickykeys}{}
-\textbf{GLFW\_STICKY\_KEYS}\\
-When GLFW\_STICKY\_KEYS is enabled, keys which are pressed will not be
-released until they are physically released and checked with
-\textbf{glfwGetKey}. This behavior makes it possible to catch keys that
-were pressed and then released again between two calls to
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or
-\textbf{glfwSwapBuffers}, which would otherwise have been reported as
-released. Care should be taken when using this mode, since keys that are
-not checked with \textbf{glfwGetKey} will never be released. Note also
-that enabling GLFW\_STICKY\_KEYS does not affect the behavior of the
-keyboard callback functionality.
-
-When GLFW\_STICKY\_KEYS is disabled, the status of a key that is reported
-by \textbf{glfwGetKey} is always the physical state of the key. Disabling
-GLFW\_STICKY\_KEYS also clears the sticky information for all keys.
-\end{mysamepage}
-
-
-\bigskip\begin{mysamepage}\hypertarget{lnk:stickymousebuttons}{}
-\textbf{GLFW\_STICKY\_MOUSE\_BUTTONS}\\
-When GLFW\_STICKY\_MOUSE\_BUTTONS is enabled, mouse buttons that are pressed
-will not be released until they are physically released and checked with
-\textbf{glfwGetMouseButton}. This behavior makes it possible to catch mouse
-buttons which were pressed and then released again between two calls to
-\textbf{glfwPollEvents}, \textbf{glfwWaitEvents} or \textbf{glfwSwapBuffers}
-(with GLFW\_AUTO\_POLL\_EVENTS enabled), which would otherwise have been
-reported as released. Care should be taken when using this mode, since mouse
-buttons that are not checked with \textbf{glfwGetMouseButton} will never be
-released. Note also that enabling GLFW\_STICKY\_MOUSE\_BUTTONS does not affect
-the behavior of the mouse button callback functionality.
-
-When GLFW\_STICKY\_MOUSE\_BUTTONS is disabled, the status of a mouse
-button that is reported by \textbf{glfwGetMouseButton} is always the
-physical state of the mouse button. Disabling GLFW\_STICKY\_MOUSE\_BUTTONS
-also clears the sticky information for all mouse buttons.
-\end{mysamepage}
-
-
-\bigskip\begin{mysamepage}\hypertarget{lnk:systemkeys}{}
-\textbf{GLFW\_SYSTEM\_KEYS}\\
-When GLFW\_SYSTEM\_KEYS is enabled, pressing standard system key
-combinations, such as \texttt{Alt+Tab} under Windows, will give the normal
-behavior. Note that when \texttt{Alt+Tab} is issued under Windows in this
-mode so that the \GLFW\ application is deselected when \GLFW\ is operating
-in fullscreen mode, the \GLFW\ application window will be minimized and
-the video mode will be set to the original desktop mode. When the \GLFW\
-application is re-selected, the video mode will be set to the \GLFW\ video
-mode again.
-
-When GLFW\_SYSTEM\_KEYS is disabled, pressing standard system key
-combinations will have no effect, since those key combinations are blocked
-by \GLFW . This mode can be useful in situations when the \GLFW\ program
-must not be interrupted (normally for games in fullscreen mode).
-\end{mysamepage}
-
-
-%-------------------------------------------------------------------------
-% GLFW Standards Conformance
-%-------------------------------------------------------------------------
-\appendix
-\chapter{GLFW Compatibility}
-\label{chap:compatibility}
-\thispagestyle{fancy}
-
-This chapter describes the various API extensions used by this version of
-\GLFW . It lists what are essentially implementation details, but which are
-nonetheless vital knowledge for developers wishing to deploy their applications
-on machines with varied specifications.
-
-Note that the information in this appendix is not a part of the API
-specification but merely list some of the preconditions for certain parts of
-the API to function on a given machine. As such, any part of it may change in
-future versions without this being considered a breaking API change.
-
-%-------------------------------------------------------------------------
-\section{ICCCM and EWMH Conformance}
-
-As \GLFW\ uses \textbf{Xlib}, directly, without any intervening toolkit
-library, it has sole responsibility for interacting well with the many and
-varied window managers in use on Unix-like systems. In order for applications
-and window managers to work well together, a number of standards and
-conventions have been developed that regulate behavior outside the scope of the
-X11 API; most importantly the \textbf{Inter-Client Communication Conventions
-Manual} (ICCCM) and \textbf{Extended Window Manager Hints} (EWMH) standards.
-
-\GLFW\ uses the ICCCM \textbf{WM\_DELETE\_WINDOW} protocol to intercept the user
-attempting to close the \GLFW\ window. If the running window manager does not
-support this protocol, the close callback will never be called.
-
-\GLFW\ uses the EWMH \textbf{\_NET\_WM\_PING} protocol, allowing the window
-manager notify the user when the application has stopped responding, i.e. when
-it has ceased to process events. If the running window manager does not
-support this protocol, the user will not be notified if the application locks
-up.
-
-\GLFW\ uses the EWMH \textbf{\_NET\_WM\_STATE} protocol to tell the window
-manager to make the \GLFW\ window fullscreen. If the running window manager
-does not support this protocol, fullscreen windows may not work properly.
-\GLFW\ has a fallback code path in case this protocol is unavailable, but every
-window manager behaves slightly differently in this regard.
-
-%-------------------------------------------------------------------------
-\section{GLX Extensions}
-
-The \textbf{GLX} API is used to create \OpenGL\ contexts on Unix-like systems
-using the X Window System.
-
-\GLFW\ uses the \textbf{GLXFBConfig} API to enumerate and select framebuffer
-pixel formats. This requires either \textbf{GLX} 1.3 or greater, or the
-\textbf{GLX\_SGIX\_fbconfig} extension. Where both are available, the SGIX
-extension is preferred. If neither is available, \GLFW\ will be unable to open
-windows.
-
-% This paragraph repeated almost verbatim below
-\GLFW\ uses the \textbf{GLX\_SGI\_swap\_control} extension to provide vertical
-retrace synchronization (or ``vsync''). Where this extension is unavailable,
-calling \textbf{glfwSwapInterval} will have no effect.
-
-% This paragraph repeated almost verbatim below
-\GLFW\ uses the \textbf{GLX\_ARB\_multisample} extension to create contexts
-with multisampling anti-aliasing. Where this extension is unavailable, the
-GLFW\_FSAA\_SAMPLES hint will have no effect.
-
-% This paragraph repeated almost verbatim below
-\GLFW\ uses the \textbf{GLX\_ARB\_create\_context} extension when available,
-even when creating \OpenGL\ contexts of version 2.1 and below. Where this
-extension is unavailable, the GLFW\_OPENGL\_VERSION\_MAJOR and
-GLFW\_OPENGL\_VERSION\_MINOR hints will only be partially supported, the
-GLFW\_OPENGL\_DEBUG\_CONTEXT hint will have no effect, and setting the
-GLFW\_OPENGL\_PROFILE or GLFW\_FORWARD\_COMPAT hints to a non-zero value will
-cause \textbf{glfwOpenWindow} to fail.
-
-% This paragraph repeated almost verbatim below
-\GLFW\ uses the \textbf{GLX\_ARB\_create\_context\_profile} extension to
-provide support for context profiles. Where this extension is unavailable,
-setting the GLFW\_OPENGL\_PROFILE hint to anything but zero will cause
-\textbf{glfwOpenWindow} to fail.
-
-%-------------------------------------------------------------------------
-\section{WGL Extensions}
-
-The \textbf{WGL} API is used to create \OpenGL\ contexts on Microsoft Windows
-and other implementations of the Win32 API, such as Wine.
-
-\GLFW\ uses either the \textbf{WGL\_EXT\_extension\_string} or the
-\textbf{WGL\_ARB\_extension\_string} extension to check for the presence of all
-other \textbf{WGL} extensions listed below. If both are available, the EXT one
-is preferred. If neither is available, no other extensions are used and many
-\GLFW\ features related to context creation will have no effect or cause errors
-when used.
-
-% This paragraph repeated almost verbatim above
-\GLFW\ uses the \textbf{WGL\_EXT\_swap\_control} extension to provide vertical
-retrace synchronization (or ``vsync''). Where this extension is unavailable,
-calling \textbf{glfwSwapInterval} will have no effect.
-
-% This paragraph repeated almost verbatim above
-\GLFW\ uses the \textbf{WGL\_ARB\_pixel\_format} and
-\textbf{WGL\_ARB\_multisample} extensions to create contexts with multisampling
-anti-aliasing. Where these extensions are unavailable, the GLFW\_FSAA\_SAMPLES
-hint will have no effect.
-
-% This paragraph repeated almost verbatim above
-\GLFW\ uses the \textbf{WGL\_ARB\_create\_context} extension when available,
-even when creating \OpenGL\ contexts of version 2.1 and below. Where this
-extension is unavailable, the GLFW\_OPENGL\_VERSION\_MAJOR and
-GLFW\_OPENGL\_VERSION\_MINOR hints will only be partially supported, the
-GLFW\_OPENGL\_DEBUG\_CONTEXT hint will have no effect, and setting the
-GLFW\_OPENGL\_PROFILE or GLFW\_FORWARD\_COMPAT hints to a non-zero value will
-cause \textbf{glfwOpenWindow} to fail.
-
-% This paragraph repeated almost verbatim above
-\GLFW\ uses the \textbf{WGL\_ARB\_create\_context\_profile} extension to
-provide support for context profiles. Where this extension is unavailable,
-setting the GLFW\_OPENGL\_PROFILE hint to anything but zero will cause
-\textbf{glfwOpenWindow} to fail.
-
-%-------------------------------------------------------------------------
-\section{OpenGL 3.0+ on Mac OS X}
-
-At the time of writing, Mac OS X does not support OpenGL 3.0 or above.
-Because of this, the GLFW\_OPENGL\_VERSION\_MAJOR and
-GLFW\_OPENGL\_VERSION\_MINOR hints will fail if given a version above 2.1, the
-GLFW\_OPENGL\_DEBUG\_CONTEXT hint will have no effect, and setting the
-GLFW\_OPENGL\_PROFILE or GLFW\_FORWARD\_COMPAT hints to a non-zero value will
-cause \textbf{glfwOpenWindow} to fail.
-
-
-\end{document}
diff --git a/docs/glfwug.tex b/docs/glfwug.tex
deleted file mode 100644
index 4f769a2c..00000000
--- a/docs/glfwug.tex
+++ /dev/null
@@ -1,1313 +0,0 @@
-%-------------------------------------------------------------------------
-% GLFW Users Guide
-% API Version: 3.0
-%-------------------------------------------------------------------------
-
-% Document class
-\documentclass[a4paper,11pt,oneside]{report}
-
-% Document title and API version
-\newcommand{\glfwdoctype}[1][0]{Users Guide}
-\newcommand{\glfwapiver}[1][0]{3.0}
-
-% Common document settings and macros
-\input{glfwdoc.sty}
-
-% PDF specific document settings
-\hypersetup{pdftitle={GLFW Users Guide}}
-\hypersetup{pdfauthor={Marcus Geelnard}}
-\hypersetup{pdfkeywords={GLFW,OpenGL,guide,manual}}
-
-
-%-------------------------------------------------------------------------
-% Document body
-%-------------------------------------------------------------------------
-
-\begin{document}
-
-\pagestyle{plain}
-
-% Title page
-\glfwmaketitle
-
-% Summary, trademarks and table of contents
-\pagenumbering{roman}
-\setcounter{page}{1}
-
-%-------------------------------------------------------------------------
-% Summary and Trademarks
-%-------------------------------------------------------------------------
-\chapter*{Summary}
-
-This document is a users guide for the \GLFW\ API that gives a practical
-introduction to using \GLFW . For a more detailed description of the
-\GLFW\ API you should refer to the \textit{GLFW Reference Manual}.
-\vspace{5cm}
-
-\large
-Trademarks
-
-\small
-OpenGL and IRIX are registered trademarks of Silicon Graphics, Inc.\linebreak
-Microsoft and Windows are registered trademarks of Microsoft Corporation.\linebreak
-Mac OS is a registered trademark of Apple Computer, Inc.\linebreak
-Linux is a registered trademark of Linus Torvalds.\linebreak
-FreeBSD is a registered trademark of Wind River Systems, Inc.\linebreak
-Solaris is a trademark of Sun Microsystems, Inc.\linebreak
-UNIX is a registered trademark of The Open Group.\linebreak
-X Window System is a trademark of The Open Group.\linebreak
-POSIX is a trademark of IEEE.\linebreak
-Truevision, TARGA and TGA are registered trademarks of Truevision, Inc.\linebreak
-IBM is a registered trademark of IBM Corporation.\linebreak
-
-All other trademarks mentioned in this document are the property of their respective owners.
-\normalsize
-
-
-%-------------------------------------------------------------------------
-% Table of contents
-%-------------------------------------------------------------------------
-\tableofcontents
-\pagebreak
-
-
-% Document chapters starts here...
-\pagenumbering{arabic}
-\setcounter{page}{1}
-
-\pagestyle{fancy}
-
-
-%-------------------------------------------------------------------------
-% Introduction
-%-------------------------------------------------------------------------
-\chapter{Introduction}
-\thispagestyle{fancy}
-\GLFW\ is a portable API (Application Program Interface) that handles
-operating system specific tasks related to \OpenGL\ programming. While
-\OpenGL\ in general is portable, easy to use and often results in tidy and
-compact code, the operating system specific mechanisms that are required
-to set up and manage an \OpenGL\ window are quite the opposite. \GLFW\ tries
-to remedy this by providing the following functionality:
-
-\begin{itemize}
-\item Opening and managing an \OpenGL\ window.
-\item Keyboard, mouse and joystick input.
-\item High precision time input.
-\item Support for querying and using \OpenGL\ extensions.
-\end{itemize}
-\vspace{18pt}
-
-All this functionality is implemented as a set of easy-to-use functions,
-which makes it possible to write an \OpenGL\ application framework in just a
-few lines of code. The \GLFW\ API is operating system and platform independent,
-making it very simple to port \GLFW\ based \OpenGL\ applications between the
-supported platforms.
-
-Currently supported platforms are:
-\begin{itemize}
-\item Microsoft Windows\textsuperscript{\textregistered}
-\item Unix\textsuperscript{\textregistered} or Unix-like systems running the
-X Window System\texttrademark with GLX version 1.3 or later
-\item Mac OS X\textsuperscript{\textregistered} 10.5 and later, using Cocoa\footnote{Support for joysticks missing at the time of writing.}
-\end{itemize}
-
-There is also deprecated support for Mac OS X versions 10.3 and 10.4, using the Carbon API.
-
-
-%-------------------------------------------------------------------------
-% Getting Started
-%-------------------------------------------------------------------------
-\chapter{Getting Started}
-\thispagestyle{fancy}
-In this chapter you will learn how to write a simple \OpenGL\ application
-using \GLFW . We start by initializing \GLFW , then we open a window and
-read some user keyboard input.
-
-
-%-------------------------------------------------------------------------
-\section{Initializing GLFW}
-Before using any of the \GLFW\ functions, it is necessary to call
-\textbf{glfwInit}. It initializes the parts of \GLFW\ that are not dependent on
-a window, such as time and joystick input. The C syntax is:
-
-\begin{lstlisting}
-int glfwInit(void)
-\end{lstlisting}
-
-\textbf{glfwInit} returns GL\_TRUE if initialization succeeded, or
-GL\_FALSE if it failed.
-
-When your application is done using \GLFW , typically at the very end of
-the program, you should call \textbf{glfwTerminate}. The C syntax is:
-
-\begin{lstlisting}
-void glfwTerminate(void)
-\end{lstlisting}
-
-This releases any resources allocated by GLFW and closes the window if it is
-open. After this call, you must call \textbf{glfwInit} again before using any
-\GLFW\ functions).
-
-%-------------------------------------------------------------------------
-\section{Opening An OpenGL Window}
-Opening an \OpenGL\ window is done with the \textbf{glfwOpenWindow} function.
-The function takes nine arguments, which are used to describe the following
-properties of the requested window:
-
-\begin{itemize}
-\item Window dimensions (width and height) in pixels.
-\item Color and alpha buffer bit depth.
-\item Depth buffer (Z-buffer) bit depth.
-\item Stencil buffer bit depth.
-\item Whether to use fullscreen or windowed mode.
-\end{itemize}
-
-The C language syntax for \textbf{glfwOpenWindow} is:
-\begin{lstlisting}
-int glfwOpenWindow(int width, int height,
- int redbits, int greenbits, int bluebits,
- int alphabits, int depthbits, int stencilbits,
- int mode)
-\end{lstlisting}
-
-\textbf{glfwOpenWindow} returns GL\_TRUE if the window was opened
-correctly, or GL\_FALSE if \GLFW\ failed to open the window.
-
-\GLFW\ tries to open a window that best matches the requested parameters.
-Some parameters may be omitted by setting them to zero, which will result
-in \GLFW\ either using a default value, or the related functionality to be
-disabled. For instance, if \textit{width} and \textit{height} are both
-zero, \GLFW\ will use a window resolution of 640x480. If
-\textit{depthbits} is zero, the opened window may not have a depth buffer.
-
-The \textit{mode} argument is used to specify if the window is to be a
-fullscreen window or a regular window.
-
-If \textit{mode} is GLFW\_FULLSCREEN, the window will cover the entire
-screen and no window border or decorations will be visible. If possible, the
-video mode will be changed to the mode that closest matches the \textit{width},
-\textit{height}, \textit{redbits}, \textit{greenbits}, \textit{bluebits} and
-\textit{alphabits} arguments. Furthermore, the mouse pointer will be hidden,
-and screensavers are prohibited. This is usually the best mode for games and
-demos.
-
-If \textit{mode} is GLFW\_WINDOW, the window will be opened as a normal,
-decorated window on the desktop. The mouse pointer will not be hidden and
-screensavers are allowed to be activated.
-
-To close the window, you can either use \textbf{glfwTerminate}, as
-described earlier, or you can use the more explicit approach by calling
-\textbf{glfwCloseWindow}, which has the C syntax:
-
-\begin{lstlisting}
-void glfwCloseWindow(void)
-\end{lstlisting}
-
-Note that you do not need to call \textbf{glfwTerminate} and \textbf{glfwInit}
-before opening a new window after having closed the current one using
-\textbf{glfwCloseWindow}.
-
-
-%-------------------------------------------------------------------------
-\section{Using Keyboard Input}
-\GLFW\ provides several means for receiving user input, which will be
-discussed in more detail in chapter \ref{par:inputhandling}. One of the
-simplest ways of checking for keyboard input is to use the function
-\textbf{glfwGetKey}:
-
-\begin{lstlisting}
-int glfwGetKey(int key)
-\end{lstlisting}
-
-It queries the current status of individual keyboard keys. The argument
-\textit{key} specifies which key to check, and it must be a valid GLFW key code
-(see the \textit{GLFW Reference Manual} for a list of key codes).
-\textbf{glfwGetKey} returns GLFW\_PRESS if the key is currently held down, or
-GLFW\_RELEASE if the key is not being held down. For example:
-
-\begin{lstlisting}
-A_pressed = glfwGetKey(GLFW_KEY_A);
-esc_pressed = glfwGetKey(GLFW_KEY_ESCAPE);
-\end{lstlisting}
-
-In order for \textbf{glfwGetKey} to have any effect, you need to poll for
-input events on a regular basis. This can be done in one of two ways:
-
-\begin{enumerate}
-\item Implicitly by calling \textbf{glfwSwapBuffers} often.
-\item Explicitly by calling \textbf{glfwPollEvents} often.
-\end{enumerate}
-
-In general you do not have to care about this, since you will normally
-call \textbf{glfwSwapBuffers} to swap front and back rendering buffers
-every animation frame anyway. If, however, this is not the case, you
-should call \textbf{glfwPollEvents} in the order of 10-100 times per
-second in order for \GLFW\ to maintain an up to date input state.
-
-
-%-------------------------------------------------------------------------
-\section{Putting It Together: A Minimal GLFW Application}
-Now that you know how to initialize \GLFW , open a window and poll for
-keyboard input, let us exemplify this with a simple \OpenGL\ program:
-
-\begin{lstlisting}
-#include
-#include
-
-int main(void)
-{
- int running = GL_TRUE;
-
- // Initialize GLFW
- if (!glfwInit())
- exit(EXIT_FAILURE);
-
- // Open an OpenGL window
- if (!glfwOpenWindow(300,300, 0,0,0,0,0,0, GLFW_WINDOW))
- {
- glfwTerminate();
- exit(EXIT_FAILURE);
- }
-
- // Main loop
- while (running)
- {
- // OpenGL rendering goes here...
- glClear(GL_COLOR_BUFFER_BIT);
-
- // Swap front and back rendering buffers
- glfwSwapBuffers();
-
- // Check if ESC key was pressed or window was closed
- running = !glfwGetKey(GLFW_KEY_ESCAPE) &&
- glfwGetWindowParam(GLFW_OPENED);
- }
-
- // Close window and terminate GLFW
- glfwTerminate();
-
- // Exit program
- exit(EXIT_SUCCESS);
-}
-\end{lstlisting}
-
-The program opens a 300x300 window and runs in a loop until the escape key
-is pressed, or the window was closed. All the \OpenGL\ ``rendering'' that
-is done in this example is to clear the window.
-
-
-%-------------------------------------------------------------------------
-% Window Operations
-%-------------------------------------------------------------------------
-\chapter{Window Operations}
-\thispagestyle{fancy}
-In this chapter, you will learn more about window related \GLFW\
-functionality, including setting and getting window properties, buffer
-swap control and video mode querying.
-
-
-%-------------------------------------------------------------------------
-\section{Setting Window Properties}
-In the previous chapter the \textbf{glfwOpenWindow} function was
-described, which specifies the sizes of the color, alpha, depth and
-stencil buffers. It is also possible to request a specific minimum OpenGL
-version, multisampling anti-aliasing, an accumulation buffer, stereo
-rendering and more by using the \textbf{glfwOpenWindowHint} function:
-
-\begin{lstlisting}
-void glfwOpenWindowHint(int target, int hint)
-\end{lstlisting}
-
-The \textit{target} argument can be one of the constants listed in table~
-\ref{tab:winhints}, and \textit{hint} is the value to assign to the
-specified target.
-
-%-------------------------------------------------------------------------
-\begin{table}[p]
-\begin{center}
-\begin{tabular}{|l|l|p{7.0cm}|} \hline \raggedright
-\textbf{Name} & \textbf{Default} & \textbf{Description} \\ \hline
-GLFW\_REFRESH\_RATE & 0 & Vertical monitor refresh rate in Hz (only used for fullscreen windows). Zero means system default.\\ \hline
-GLFW\_ACCUM\_RED\_BITS & 0 & Number of bits for the red channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_GREEN\_BITS & 0 & Number of bits for the green channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_BLUE\_BITS & 0 & Number of bits for the blue channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_ALPHA\_BITS & 0 & Number of bits for the alpha channel of the accumulation buffer.\\ \hline
-GLFW\_AUX\_BUFFERS & 0 & Number of auxiliary buffers.\\ \hline
-GLFW\_STEREO & GL\_FALSE & Specify if stereo rendering should be supported (can be GL\_TRUE or GL\_FALSE).\\ \hline
-GLFW\_WINDOW\_NO\_RESIZE & GL\_FALSE & Specify whether the window can be resized by the user (not used for fullscreen windows).\\ \hline
-GLFW\_FSAA\_SAMPLES & 0 & Number of samples to use for the multisampling buffer. Zero disables multisampling.\\ \hline
-GLFW\_OPENGL\_VERSION\_MAJOR & 1 & Major number of the desired minimum OpenGL version.\\ \hline
-GLFW\_OPENGL\_VERSION\_MINOR & 1 & Minor number of the desired minimum OpenGL version.\\ \hline
-GLFW\_OPENGL\_FORWARD\_COMPAT & GL\_FALSE & Specify whether the OpenGL context should be forward-compatible (i.e. disallow legacy functionality).
- This should only be used when requesting OpenGL version 3.0 or above.\\ \hline
-GLFW\_OPENGL\_DEBUG\_CONTEXT & GL\_FALSE & Specify whether a debug context should be created.\\ \hline
-GLFW\_OPENGL\_PROFILE & 0 & The OpenGL profile the context should implement, or zero to let the system choose.
- Available profiles are GLFW\_OPENGL\_CORE\_PROFILE and GLFW\_OPENGL\_COMPAT\_PROFILE.\\ \hline
-\end{tabular}
-\end{center}
-\caption{Targets for \textbf{glfwOpenWindowHint}}
-\label{tab:winhints}
-\end{table}
-%-------------------------------------------------------------------------
-
-For a hint to have any effect, the \textbf{glfwOpenWindowHint} function
-must be called before opening the window with the \textbf{glfwOpenWindow}
-function.
-
-To request an accumulation buffer, set the GLFW\_ACCUM\_x\_BITS targets to
-values greater than zero (usually eight or sixteen bits per component).
-To request auxiliary buffers, set the GLFW\_AUX\_BUFFERS target to a value
-greater than zero. To request a stereo rendering capable window, set the
-GLFW\_STEREO target to GL\_TRUE.
-
-If you want to enable fullscreen antialiasing, set the GLFW\_FSAA\_SAMPLES
-target to a value greater than zero. If the windowing system is unable to
-fulfil the request, \GLFW\ will degrade gracefully and disable FSAA if necessary.
-
-The GLFW\_REFRESH\_RATE target should be used with caution, since it may
-result in suboptimal operation, or even a blank or damaged screen.
-
-If you want to create a forward-compatible \OpenGL\ context, set the
-GLFW\_OPENGL\_FORWARD\_COMPAT hint to GL\_TRUE. Note that such contexts are
-only available for \OpenGL\ version 3.0 and above, so you will need to specify
-a valid minimum version using the GLFW\_OPENGL\_VERSION\_MAJOR and
-GLFW\_OPENGL\_VERSION\_MINOR hints.
-
-If you want to create a context using the core profile as available in \OpenGL\
-version 3.2 and above, set the GLFW\_OPENGL\_PROFILE hint accordingly. Note that
-as above you have to set a valid minimum version for this to work.
-
-Also note that at the time of this release, Mac OS X did not support \OpenGL\
-version 3.0 or above; thus GLFW cannot create contexts of versions above 2.1
-on that platform.
-
-Besides the parameters that are given with the \textbf{glfwOpenWindow} and
-\textbf{glfwOpenWindowHint} functions, a few more properties of a window
-can be changed after the window has been opened, namely the window title,
-window size, and window position.
-
-To change the window title of an open window, use the
-\textbf{glfwSetWindowTitle} function:
-
-\begin{lstlisting}
-void glfwSetWindowTitle(const char* title)
-\end{lstlisting}
-
-\textit{title} is a null terminated ISO~8859-1 (8-bit Latin~1) string that
-will be used as the window title. It will also be used as the application
-name (for instance in the application list when using \texttt{Alt+Tab}
-under Windows, or as the icon name when the window is iconified under
-the X Window System). The default window name is ``GLFW Window'', which
-will be used unless \textbf{glfwSetWindowTitle} is called after the window
-has been opened.
-
-To change the size of a window, call \textbf{glfwSetWindowSize}:
-
-\begin{lstlisting}
-void glfwSetWindowSize(int width, int height)
-\end{lstlisting}
-
-Where \textit{width} and \textit{height} are the new dimensions of the
-window.
-
-To change the position of a window, call \textbf{glfwSetWindowPos}:
-
-\begin{lstlisting}
-void glfwSetWindowPos(int x, int y)
-\end{lstlisting}
-
-Where \textit{x} and \textit{y} are the new desktop coordinates of the
-window. This function does not have any effect when in fullscreen mode.
-
-
-%-------------------------------------------------------------------------
-\section{Getting Window Properties}
-When opening a window, the opened window will not necessarily have the
-requested properties, so you should always check the parameters that your
-application relies on (e.g. number of stencil bits) using
-\textbf{glfwGetWindowParam}, which has the C syntax:
-
-\begin{lstlisting}
-int glfwGetWindowParam(int param)
-\end{lstlisting}
-
-The argument \textit{param} can be one of the tokens listed in table
-\ref{tab:winparams}, and the return value is an integer holding the
-requested value.
-
-%-------------------------------------------------------------------------
-\begin{table}[p]
-\begin{center}
-\begin{tabular}{|l|p{9.5cm}|} \hline \raggedright
-\textbf{Name} & \textbf{Description} \\ \hline
-GLFW\_OPENED & GL\_TRUE if window is opened, else GL\_FALSE.\\ \hline
-GLFW\_ACTIVE & GL\_TRUE if window has focus, else GL\_FALSE.\\ \hline
-GLFW\_ICONIFIED & GL\_TRUE if window is iconified, else GL\_FALSE.\\ \hline
-GLFW\_ACCELERATED & GL\_TRUE if window is hardware accelerated, else GL\_FALSE.\\ \hline
-GLFW\_RED\_BITS & Number of bits for the red color component.\\ \hline
-GLFW\_GREEN\_BITS & Number of bits for the green color component.\\ \hline
-GLFW\_BLUE\_BITS & Number of bits for the blue color component.\\ \hline
-GLFW\_ALPHA\_BITS & Number of bits for the alpha buffer.\\ \hline
-GLFW\_DEPTH\_BITS & Number of bits for the depth buffer.\\ \hline
-GLFW\_STENCIL\_BITS & Number of bits for the stencil buffer.\\ \hline
-GLFW\_REFRESH\_RATE & Vertical monitor refresh rate in Hz. Zero indicates an unknown or a default refresh rate.\\ \hline
-GLFW\_ACCUM\_RED\_BITS & Number of bits for the red channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_GREEN\_BITS & Number of bits for the green channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_BLUE\_BITS & Number of bits for the blue channel of the accumulation buffer.\\ \hline
-GLFW\_ACCUM\_ALPHA\_BITS & Number of bits for the alpha channel of the accumulation buffer.\\ \hline
-GLFW\_AUX\_BUFFERS & Number of auxiliary buffers.\\ \hline
-GLFW\_STEREO & GL\_TRUE if stereo rendering is supported, else GL\_FALSE.\\ \hline
-GLFW\_WINDOW\_NO\_RESIZE & GL\_TRUE if the window cannot be resized by the user, else GL\_FALSE.\\ \hline
-GLFW\_FSAA\_SAMPLES & Number of multisampling buffer samples. Zero indicated multisampling is disabled.\\ \hline
-GLFW\_OPENGL\_VERSION\_MAJOR & Major number of the actual version of the context.\\ \hline
-GLFW\_OPENGL\_VERSION\_MINOR & Minor number of the actual version of the context.\\ \hline
-GLFW\_OPENGL\_FORWARD\_COMPAT & GL\_TRUE if the context is forward-compatible, else GL\_FALSE.\\ \hline
-GLFW\_OPENGL\_DEBUG\_CONTEXT & GL\_TRUE if the context is a debug context.\\ \hline
-GLFW\_OPENGL\_PROFILE & The profile implemented by the context, or zero.\\ \hline
-\end{tabular}
-\end{center}
-\caption{Window parameters for \textbf{glfwGetWindowParam}}
-\label{tab:winparams}
-\end{table}
-%-------------------------------------------------------------------------
-
-Another useful function is \textbf{glfwSetWindowSizeCallback}, which
-specifies a user function that will be called every time the window size
-has changed. The C syntax is:
-
-\begin{lstlisting}
-void glfwSetWindowSizeCallback(GLFWwindowsizefun cbfun)
-\end{lstlisting}
-
-The user function \textit{fun} should be of the type:
-
-\begin{lstlisting}
-void fun(int width, int height)
-\end{lstlisting}
-
-The first argument passed to the user function is the width of the window,
-and the second argument is the height of the window. Here is an example
-of how to use a window size callback function:
-
-\begin{lstlisting}
-int windowWidth, windowHeight;
-
-void WindowResize(int width, int height)
-{
- windowWidth = width;
- windowHeight = height;
-}
-
-int main(void)
-{
- ...
- glfwSetWindowSizeCallback(WindowResize);
- ...
-}
-\end{lstlisting}
-
-Using a callback function for getting the window size is mostly useful for
-windowed applications, since the window size may be changed at any time by
-the user. It can also be used to determine the actual fullscreen
-resolution.
-
-An alternative to using a callback function for getting the window size,
-is to use the function \textbf{glfwGetWindowSize}:
-
-\begin{lstlisting}
-void glfwGetWindowSize(int* width, int* height)
-\end{lstlisting}
-
-The variables pointed to by \textit{width} and \textit{height} are set to the
-current window dimensions. Note that either of these may be NULL; that
-argument is then ignored.
-
-
-%-------------------------------------------------------------------------
-\section{Buffer Swapping}
-\GLFW\ windows are always double buffered. That means that you have two
-rendering buffers; a front buffer and a back buffer. The front buffer is
-the buffer that is being displayed, and the back buffer is not displayed.
-\OpenGL\ lets you select which of these two buffers you want to render to
-(with the \textbf{glDrawBuffer} command), but the default (and preferred)
-rendering buffer is the back buffer. This way you will avoid flickering
-and artifacts caused by graphics being only partly drawn at the same time
-as the video raster beam is displaying the graphics on the monitor.
-
-When an entire frame has been rendered to the back buffer, it is time to
-swap the back and the front buffers in order to display the rendered
-frame, and begin rendering a new frame. This is done with the command
-\textbf{glfwSwapBuffers}. The C syntax is:
-
-\begin{lstlisting}
-void glfwSwapBuffers(void)
-\end{lstlisting}
-
-After swapping the front and back rendering buffers, \textbf{glfwSwapBuffers}
-by default calls \textbf{glfwPollEvents}\footnote{This behavior can be disabled
-by calling \textbf{glfwDisable} with the argument GLFW\_AUTO\_POLL\_EVENTS.}.
-This is to ensure frequent polling of events, such as keyboard and mouse input,
-and window reshaping events. Even if a given application does not use input
-events, without frequent polling of events (at \emph{least} once every few
-seconds), most modern window systems will flag the application as unresponsive
-and may suggest that the user terminate it.
-
-Sometimes it can be useful to select when the buffer swap will occur. With
-the function \textbf{glfwSwapInterval} it is possible to select the
-minimum number of vertical retraces the video raster line should do before
-swapping the buffers:
-
-\begin{lstlisting}
-void glfwSwapInterval(int interval)
-\end{lstlisting}
-
-If \textit{interval} is zero, the swap will take place immediately when
-\textbf{glfwSwapBuffers} is called, without waiting for a vertical retrace
-(also known as ``vsync off''). Otherwise at least \textit{interval}
-retraces will pass between each buffer swap (also known as ``vsync on'').
-Using a swap interval of zero can be useful for benchmarking purposes,
-when it is not desirable to measure the time it takes to wait for the
-vertical retrace. However, a swap interval of 1 generally gives better
-visual quality.
-
-It should be noted that not all \OpenGL\ implementations and hardware support
-this function, in which case \textbf{glfwSwapInterval} will have no effect. ATI
-Radeon cards under Microsoft Windows are especially notorious in this regard.
-Sometimes it is only possible to affect the swap interval through driver
-settings (e.g. the display settings under Windows, or as an environment
-variable setting under Unix).
-
-
-%-------------------------------------------------------------------------
-\section{Querying Video Modes}
-Although \GLFW\ generally does a good job at selecting a suitable video
-mode for you when you open a fullscreen window, it is sometimes useful to
-know exactly which modes are available on a certain system. For example,
-you may want to present the user with a list of video modes to select
-from. To get a list of available video modes, you can use the function
-\textbf{glfwGetVideoModes}:
-
-\begin{lstlisting}
-int glfwGetVideoModes(GLFWvidmode* list, int maxcount)
-\end{lstlisting}
-
-The argument \textit{list} is a vector of GLFWvidmode structures, and
-\textit{maxcount} is the maximum number of video modes that your vector can
-hold. \textbf{glfwGetVideoModes} will return the number of video modes detected
-on the system, up to \textit{maxcount}.
-
-The GLFWvidmode structure looks like this:
-
-\begin{lstlisting}
-typedef struct {
- int Width, Height; // Video resolution
- int RedBits; // Red bits per pixel
- int GreenBits; // Green bits per pixel
- int BlueBits; // Blue bits per pixel
-} GLFWvidmode;
-\end{lstlisting}
-
-Here is an example of retrieving all available video modes:
-
-\begin{lstlisting}
-int nummodes;
-GLFWvidmode list[200];
-nummodes = glfwGetVideoModes(list, 200);
-\end{lstlisting}
-
-The returned list is sorted, first by color depth ($RedBits + GreenBits +
-BlueBits$), and then by resolution ($Width\times Height$), with the
-lowest resolution, fewest bits per pixel mode first.
-
-To get the desktop video mode, use the function
-\textbf{glfwGetDesktopMode}:
-
-\begin{lstlisting}
-void glfwGetDesktopMode(GLFWvidmode* mode)
-\end{lstlisting}
-
-The function returns the resolution and color depth of the user desktop in
-the mode structure. Note that the user desktop mode is independent of the
-current video mode if a \GLFW\ fullscreen window has been opened.
-
-
-%-------------------------------------------------------------------------
-% Input Handling
-%-------------------------------------------------------------------------
-\chapter{Input Handling}
-\label{par:inputhandling}
-\thispagestyle{fancy}
-In this chapter you will learn how to use keyboard, mouse and joystick
-input, using either polling or callback functions.
-
-
-%-------------------------------------------------------------------------
-\section{Event Polling}
-The first thing to know about input handling in \GLFW\ is that all
-keyboard and mouse input is collected by checking for input events. This
-has do be done manually by calling either \textbf{glfwPollEvents} or
-\textbf{glfwSwapBuffers} (which implicitly calls \textbf{glfwPollEvents}
-for you). Normally this is not a cause for concern, as
-\textbf{glfwSwapBuffers} is called every frame, which should be often
-enough (about 10-100 times per second for a normal \OpenGL\ application) that
-the window will feel responsive.
-
-One exception is when an application is updating its view only in response to input.
-In this case the \textbf{glfwWaitEvents} is useful, as it blocks the calling
-thread until an event arrives. The refresh callback, set with
-\textbf{glfwSetWindowRefreshCallback}, may also be useful for such
-applications, especially on unbuffered window systems.
-
-If it is not desirable that \textbf{glfwPollEvents is} called implicitly
-from \textbf{glfwSwapBuffers}, call \textbf{glfwDisable} with the argument
-GLFW\_AUTO\_POLL\_EVENTS.
-
-Note that event polling is not needed for joystick input, since all
-relevant joystick state is gathered every time a joystick function is
-called.
-
-
-%-------------------------------------------------------------------------
-\section{Keyboard Input}
-\GLFW\ provides three mechanisms for getting keyboard input:
-
-\begin{itemize}
-\item Manually polling the state of individual keys.
-\item Automatically receive new key state for any key, using a callback
- function.
-\item Automatically receive characters, using a callback function.
-\end{itemize}
-
-Depending on what the keyboard input will be used for, different methods may be
-preferred. The main difference between the two last methods is that while
-characters are affected by modifier keys (such as shift), key state is
-independent of any modifier keys. Also, special keys (such as function keys,
-cursor keys and modifier keys) are not reported to the character callback
-function.
-
-%-------------------------------------------------------------------------
-\subsection{Key state}
-To check if a key is held down or not at any given moment, use the
-function \textbf{glfwGetKey}:
-
-\begin{lstlisting}
-int glfwGetKey(int key)
-\end{lstlisting}
-
-It queries the current status of individual keyboard keys. The argument
-\textit{key} specifies which key to check, which must be a valid GLFW key code.
-\textbf{glfwGetKey} returns GLFW\_PRESS (or 1) if the key is currently
-held down, or GLFW\_RELEASE (or 0) if the key is not being held down.
-
-In most situations, it may be useful to know if a key has been pressed and
-released between two calls to \textbf{glfwGetKey} (especially if the
-animation is fairly slow, which may allow the user to press and release a
-key between two calls to \textbf{glfwGetKey}). This can be accomplished by
-enabling sticky keys, which is done by calling \textbf{glfwEnable} with
-the argument GLFW\_STICKY\_KEYS, as in the following example:
-
-\begin{lstlisting}
-glfwEnable(GLFW_STICKY_KEYS);
-\end{lstlisting}
-
-When sticky keys are enabled, a key will not be released until it is
-checked with \textbf{glfwGetKey}. To disable sticky keys, call
-\textbf{glfwDisable} witht the argument GLFW\_STICKY\_KEYS. Then all keys
-that are not currently held down will be released and future key releases
-will take place immediately when the user releases the key without
-waiting for \textbf{glfwGetKey} to check the key. By default sticky keys
-are disabled.
-
-Sticky keys are often very useful and should be used in most cases where
-\textbf{glfwGetKey} is used. There is however a danger involved with
-enabling sticky keys, and that is that keys that are pressed by the user
-but are not checked with \textbf{glfwGetKey}, may remain ``pressed'' for a
-very long time. A typical situation where this may be dangerous is in a
-program that consists of two or more sections (e.g. a menu section and a
-game section). If the first section enables sticky keys but does not check
-for keys which the second section checks for, there is a potential of
-recording many key presses in the first section that will be detected in
-the second section. To avoid this problem, always disable sticky keys
-before leaving a section of a program.
-
-A usually better alternative to using \textbf{glfwGetKey} is to register a
-keyboard input callback function with \textbf{glfwSetKeyCallback}:
-
-\begin{lstlisting}
-void glfwSetKeyCallback(GLFWkeyfun cbfun)
-\end{lstlisting}
-
-The argument \textit{fun} is a pointer to a callback function. The
-callback function shall take two integer arguments. The first is the key
-identifier, and the second is the new key state, which can be GLFW\_PRESS
-or GLFW\_RELEASE. To unregister a callback function, call
-\textbf{glfwSetKeyCallback} with \textit{fun} = NULL.
-
-Using the callback function, you can be sure not to miss any key press or
-release events, regardless of how many may have occurred during the last frame.
-It also encourages event-based design, where the application responds only to
-actual events instead of having to poll for every supported event.
-
-%-------------------------------------------------------------------------
-\subsection{Character input}
-If the keyboard is to be used as a text input device (e.g. in a user
-dialog) rather than as a set of independent buttons, a character callback
-function is more suitable. To register a character callback function, use
-\textbf{glfwSetCharCallback}:
-
-\begin{lstlisting}
-void glfwSetCharCallback(GLFWcharfun cbfun)
-\end{lstlisting}
-
-The argument \textit{fun} is a pointer to a callback function. The
-callback function shall take two integer arguments. The first is a Unicode
-code point, and the second is GLFW\_PRESS if the key that generated
-the character was pressed, or GLFW\_RELEASE if it was released. To
-unregister a callback function, call \textbf{glfwSetCharCallback} with
-\textit{fun} = NULL.
-
-The Unicode character set is an international standard for encoding
-characters. It is much more comprehensive than seven or eight bit
-character sets (e.g. US-ASCII and Latin~1), and includes characters for
-most written languages in the world. It should be noted that Unicode
-character codes 0 to 255 are the same as for ISO~8859-1 (Latin~1), so as
-long as a proper range check is performed on the Unicode character code,
-it can be used just as an eight bit Latin~1 character code (which can be
-useful if full Unicode support is not possible).
-
-
-%-------------------------------------------------------------------------
-\subsection{Key repeat}
-By default, \GLFW\ does not report key repeats when a key is held down.
-To activate key repeat, call \textbf{glfwEnable} with the argument
-GLFW\_KEY\_REPEAT:
-
-\begin{lstlisting}
-glfwEnable(GLFW_KEY_REPEAT);
-\end{lstlisting}
-
-This will let a registered key or character callback function receive key
-repeat events when a key is held down.
-
-
-%-------------------------------------------------------------------------
-\subsection{Special system keys}
-On most systems there are some special system keys that are normally not
-intercepted by an application. For instance, under Windows it is possible
-to switch programs by pressing \texttt{ALT+TAB}, which brings up a list of
-running programs to select from. In certain situations it can be desirable
-to prevent such special system keys from interfering with the program.
-With \GLFW\ it is possible to do by calling \textbf{glfwDisable} with the
-argument GLFW\_SYSTEM\_KEYS:
-
-\begin{lstlisting}
-glfwDisable(GLFW_SYSTEM_KEYS);
-\end{lstlisting}
-
-By doing so, most system keys will have no effect and will not interfere
-with your program. System keys can be re-enabled by calling
-\textbf{glfwEnable} with the argument GLFW\_SYSTEM\_KEYS. By default,
-system keys are enabled.
-
-
-%-------------------------------------------------------------------------
-\section{Mouse Input}
-Just like for keyboard input, mouse input can be realized with either
-polling or callback functions.
-
-
-%-------------------------------------------------------------------------
-\subsection{Mouse position}
-To query the position of the mouse cursor, call \textbf{glfwGetMousePos}:
-
-\begin{lstlisting}
-void glfwGetMousePos(int* x, int* y)
-\end{lstlisting}
-
-The variables pointed to by \textit{x} and \textit{y} will be updated with the
-current position of the mouse cursor relative to the upper-left corner of the
-client area of the \GLFW\ window.
-
-An alternative is to use a callback function, which can be set with
-\textbf{glfwSetMousePosCallback}:
-
-\begin{lstlisting}
-void glfwSetMousePosCallback(GLFWmouseposfun cbfun)
-\end{lstlisting}
-
-The function that \textit{fun} points to will be called every time the
-mouse cursor moves. The first argument to the callback function is
-the cursor x-coordinate and the second the cursor y-coordinate, both relative
-to the upper-left corner of the client area of the \GLFW\ window.
-
-Note that while the \textbf{glfwGetMousePos} function only reports the final
-position after cursor movement events have been processed, using a callback
-function lets the application see each and every such event.
-
-
-%-------------------------------------------------------------------------
-\subsection{Mouse buttons}
-To query the state of a mouse button, call \textbf{glfwGetMouseButton}:
-
-\begin{lstlisting}
-int glfwGetMouseButton(int button)
-\end{lstlisting}
-
-The argument \textit{button} can be any \GLFW\ mouse button token, i.e.
-GLFW\_MOUSE\_BUTTON\_1 through GLFW\_MOUSE\_BUTTON\_8 or one of
-GLFW\_MOUSE\_BUTTON\_LEFT, GLFW\_MOUSE\_BUTTON\_RIGHT or
-GLFW\_MOUSE\_BUTTON\_MIDDLE. \textbf{glfwGetMouseButton} will return
-GLFW\_PRESS (which is a non-zero value) if the corresponding mouse button is
-held down, otherwise it will return GLFW\_RELEASE (which is equal to zero).
-
-Just as it is possible to make keys ``sticky'', it is also possible to make
-each mouse button appear as held down until it is checked with
-\textbf{glfwGetMouseButton}. To enable sticky mouse buttons, call
-\textbf{glfwEnable} with the argument GLFW\_STICKY\_MOUSE\_BUTTONS.
-
-When sticky mouse buttons are enabled, a mouse button will not be released
-until it is checked with \textbf{glfwGetMouseButton}. To disable sticky
-mouse buttons, call \textbf{glfwDisable} with the argument
-GLFW\_STICKY\_MOUSE\_BUTTONS. Then all mouse buttons that are not
-currently held down will be released and future mouse button releases
-will take place immediately when the user releases the mouse button
-without waiting for \textbf{glfwGetMouseButton} to check for the mouse
-button. By default sticky mouse buttons are disabled.
-
-There is also a callback function for mouse button activities, which can
-be set with \textbf{glfwSetMouseButtonCallback}:
-
-\begin{lstlisting}
-void glfwSetMouseButtonCallback(GLFWmousebuttonfun fun)
-\end{lstlisting}
-
-The argument \textit{fun} specifies a function that will be called
-whenever a mouse button is pressed or released, or NULL to unregister a
-callback function. The first argument to the callback function is a mouse
-button identifier, and the second is either GLFW\_PRESS or GLFW\_RELEASE,
-depending on the new state of the corresponding mouse button.
-
-
-%-------------------------------------------------------------------------
-\subsection{Mouse wheel}
-Some mice have a mouse wheel, most commonly used for vertical scrolling. Also,
-most modern touchpads allow the user to scroll at least vertically, either by
-reserving an area for scrolling or through multi-finger gestures. To get the
-position of the mouse wheel, call \textbf{glfwGetMouseWheel}:
-
-\begin{lstlisting}
-int glfwGetMouseWheel(void)
-\end{lstlisting}
-
-The function returns an integer that represents the position of the mouse
-wheel. When the user turns the wheel, the wheel position will increase or
-decrease. Note that since scrolling hardware has no absolute position, \GLFW\
-simply sets the position to zero when the window is opened.
-
-It is also possible to register a callback function for mouse wheel events
-with the \textbf{glfwSetMouseWheelCallback} function:
-
-\begin{lstlisting}
-void glfwSetMouseWheelCallback(GLFWmousewheelfun fun)
-\end{lstlisting}
-
-The argument \textit{fun} specifies a function that will be called
-whenever the mouse wheel is moved, or NULL to unregister a callback
-function. The argument to the callback function is the position of the
-mouse wheel.
-
-
-%-------------------------------------------------------------------------
-\subsection{Hiding the mouse cursor}
-It is possible to hide the mouse cursor with the function call:
-
-\begin{lstlisting}
-glfwDisable(GLFW_MOUSE_CURSOR);
-\end{lstlisting}
-
-Hiding the mouse cursor has three effects:
-
-\begin{enumerate}
-\item The cursor becomes invisible.
-\item The cursor is guaranteed to be confined to the window.
-\item Mouse coordinates are not limited to the window size.
-\end{enumerate}
-
-To show the mouse cursor again, call \textbf{glfwEnable} with the
-argument GLFW\_MOUSE\_CURSOR:
-
-\begin{lstlisting}
-glfwEnable(GLFW_MOUSE_CURSOR);
-\end{lstlisting}
-
-By default the mouse cursor is hidden if a window is opened in fullscreen
-mode, otherwise it is not hidden.
-
-
-%-------------------------------------------------------------------------
-\section{Joystick Input}
-\GLFW\ has support for up to sixteen joysticks, and an infinite\footnote{%
-There are of course actual limitations posed by the underlying hardware,
-drivers and operation system.} number of axes and buttons per joystick.
-Unlike keyboard and mouse input, joystick input does not need an opened
-window, and \textbf{glfwPollEvents} or \textbf{glfwSwapBuffers} does not
-have to be called in order for joystick state to be updated.
-
-
-%-------------------------------------------------------------------------
-\subsection{Joystick capabilities}
-First, it is often necessary to determine if a joystick is connected and
-what its capabilities are. To get this information the function
-\textbf{glfwGetJoystickParam} can be used:
-
-\begin{lstlisting}
-int glfwGetJoystickParam(int joy, int param)
-\end{lstlisting}
-
-The \textit{joy} argument specifies which joystick to retrieve the
-parameter from, and it should be GLFW\_JOYSTICK\_\textit{n}, where
-\textit{n} is in the range 1 to 16. The \textit{param} argument specifies
-which parameter to retrieve. To determine if a joystick is connected,
-\textit{param} should be GLFW\_PRESENT, which will cause the function to
-return GL\_TRUE if the joystick is connected, or GL\_FALSE if it is not.
-To determine the number of axes or buttons that are supported by the
-joystick, \textit{param} should be GLFW\_AXES or GLFW\_BUTTONS,
-respectively.
-
-Note that \GLFW\ supports both D-pads and POVs, even though they are not
-explicitly mentioned in the API. D-pads are exposed as a set of four buttons
-and POVs are as two axes.
-
-
-%-------------------------------------------------------------------------
-\subsection{Joystick position}
-To get the current axis positions of the joystick, the
-\textbf{glfwGetJoystickPos} is used:
-
-\begin{lstlisting}
-int glfwGetJoystickPos(int joy, float* pos, int numaxes)
-\end{lstlisting}
-
-As with \textbf{glfwGetJoystickParam}, the \textit{joy} argument
-specifies which joystick to retrieve information from. The
-\textit{numaxes} argument specifies how many axes to return positions for and the
-\textit{pos} argument specifies an array in which they
-are stored. The function returns the actual number of axes that were
-returned, which could be less than \textit{numaxes} if the joystick does
-not support all the requested axes, or if the joystick is not connected.
-
-For instance, to get the position of the first two axes (the X and Y axes)
-of joystick 1, the following code can be used:
-
-\begin{lstlisting}
-float position[2];
-
-glfwGetJoystickPos(GLFW_JOYSTICK_1, position, 2);
-\end{lstlisting}
-
-After this call, the first element of the \textit{position} array will
-hold the X axis position of the joystick, and the second element will hold
-the Y axis position. In this example we do not use the information about
-how many axes were really returned.
-
-The position of an axis can be in the range -1.0 to 1.0, where positive
-values represent right, forward or up directions, while negative values
-represent left, back or down directions. If a requested axis is not
-supported by the joystick, the corresponding array element will be set
-to zero. The same goes for the situation when the joystick is not
-connected (all axes are treated as unsupported).
-
-
-%-------------------------------------------------------------------------
-\subsection{Joystick buttons}
-A function similar to the \textbf{glfwGetJoystickPos} function is
-available for querying the state of joystick buttons, namely the
-\textbf{glfwGetJoystickButtons} function:
-
-\begin{lstlisting}
-int glfwGetJoystickButtons(int joy, unsigned char* buttons,
- int numbuttons)
-\end{lstlisting}
-
-The function works just like the \textbf{glfwGetJoystickAxis} function, except
-that it returns the state of joystick buttons instead of axis positions. Each
-button in the array specified by the \textit{buttons} argument can be either
-GLFW\_PRESS or GLFW\_RELEASE, indicating whether the corresponding button is
-currently held down or not. Unsupported buttons will have the value
-GLFW\_RELEASE.
-
-
-%-------------------------------------------------------------------------
-% Timing
-%-------------------------------------------------------------------------
-\chapter{Timing}
-\thispagestyle{fancy}
-
-%-------------------------------------------------------------------------
-\section{High Resolution Timer}
-In most applications, it is useful to know exactly how much time has
-passed between point $A$ and point $B$ in a program. A typical situation
-is in a game, where you need to know how much time has passed between two
-rendered frames in order to calculate the correct movement and physics
-etc. Another example is when you want to benchmark a certain piece of
-code.
-
-\GLFW\ provides a high-resolution timer, which reports a double precision
-floating point value representing the number of seconds that have passed
-since \textbf{glfwInit} was called. The timer is accessed with the
-function \textbf{glfwGetTime}:
-
-\begin{lstlisting}
-double glfwGetTime(void)
-\end{lstlisting}
-
-The precision of the timer depends on which computer and operating
-system you are running, but it is almost guaranteed to be better than
-$10~ms$, and in most cases it is much better than $1~ms$ (on a modern PC
-you can get resolutions in the order of $1~ns$).
-
-It is possible to set the value of the high precision timer using the
-\textbf{glfwSetTime} function:
-
-\begin{lstlisting}
-void glfwSetTime(double time)
-\end{lstlisting}
-
-The argument \textit{time} is the time, in seconds, that the timer should
-be set to.
-
-
-%-------------------------------------------------------------------------
-% OpenGL Extension Support
-%-------------------------------------------------------------------------
-\chapter{OpenGL Extension Support}
-\thispagestyle{fancy}
-One of the benefits of \OpenGL\ is that it is extensible. Independent
-hardware vendors (IHVs) may include functionality in their \OpenGL\
-implementations that exceed that of the \OpenGL\ standard.
-
-An extension is defined by:
-
-\begin{enumerate}
-\item An extension name (e.g. GL\_ARB\_multitexture).
-\item New OpenGL tokens (e.g. GL\_TEXTURE1\_ARB).
-\item New OpenGL functions (e.g. \textbf{glActiveTextureARB}).
-\end{enumerate}
-
-A list of official extensions, together with their definitions, can be
-found at the \textit{OpenGL Registry}
-(\url{http://www.opengl.org/registry/}).
-
-To use a certain extension, the following steps must be performed:
-
-\begin{enumerate}
-\item A compile time check for the support of the extension.
-\item A run time check for the support of the extension.
-\item Fetch function pointers for the extended \OpenGL\ functions (done at
- run time).
-\end{enumerate}
-
-How this is done using \GLFW\ is described in the following sections.
-Please note that this chapter covers some advanced topics, and is quite
-specific to the C programming language.
-
-For a much easier way to get access to \OpenGL\ extensions, you should probably
-use a dedicated extension loading library such as GLEW or GLee. This kind of
-library greatly reduces the amount of work necessary to use \OpenGL\
-extensions. GLEW in particular has been extensively tested with and works well
-with \GLFW .
-
-
-%-------------------------------------------------------------------------
-\section{Compile Time Check}
-The compile time check is necessary to perform in order to know if the
-compiler include files have defined the necessary tokens. It is very easy
-to do. The include file \texttt{GL/gl.h} will define a constant with the
-same name as the extension, if all the extension tokens are defined. Here
-is an example of how to check for the extension GL\_ARB\_multitexture:
-
-\begin{lstlisting}
-#ifdef GL_ARB_multitexture
- // Extension is supported by the include files
-#else
- // Extension is not supported by the include files
- // Get a more up-to-date file!
-#endif
-\end{lstlisting}
-
-
-%-------------------------------------------------------------------------
-\section{Runtime Check}
-Even if the compiler include files have defined all the necessary tokens, a
-given machine may not actually support the extension (it may have a graphics
-card with a different \OpenGL\ implementation, or an older driver). That is why
-it is necessary to do a run time check for the extension support as well. This
-is done with the \GLFW\ function \textbf{glfwExtensionSupported}, which has the
-C syntax:
-
-\begin{lstlisting}
-int glfwExtensionSupported(const char* extension)
-\end{lstlisting}
-
-The argument \textit{extension} is a null terminated ASCII string
-with the extension name. \textbf{glfwExtensionSupported} returns GL\_TRUE
-if the extension is supported, otherwise it returns GL\_FALSE.
-
-Let us extend the previous example of checking for support of the
-extension GL\_ARB\_multitexture. This time we add a run time check, and a
-variable which we set to GL\_TRUE if the extension is supported, or
-GL\_FALSE if it is not supported.
-
-\begin{lstlisting}
-int multitexture_supported;
-
-#ifdef GL_ARB_multitexture
- // Check if extension is supported at run time
- multitexture_supported = glfwExtensionSupported("GL_ARB_multitexture");
-#else
- // Extension is not supported by the include files
- // Get a more up-to-date file!
- multitexture_supported = GL_FALSE;
-#endif
-\end{lstlisting}
-
-Now it is easy to check for the extension within the program, simply do:
-
-\begin{lstlisting}
- if (multitexture_supported)
- {
- // Use multi texturing
- }
- else
- {
- // Use some other solution (or fail)
- }
-\end{lstlisting}
-
-
-%-------------------------------------------------------------------------
-\section{Fetching Function Pointers}
-Some extensions, though not all, require the use of new \OpenGL\ functions.
-These entry points are not necessarily exposed by your link libraries, making
-it necessary to find them dynamically at run time. You can retrieve these
-entry points using the \textbf{glfwGetProcAddress} function:
-
-\begin{lstlisting}
-void* glfwGetProcAddress(const char* procname)
-\end{lstlisting}
-
-The argument \textit{procname} is a null terminated ASCII string
-holding the name of the \OpenGL\ function. \textbf{glfwGetProcAddress}
-returns the address to the function if the function is available,
-otherwise NULL is returned.
-
-Obviously, fetching the function pointer is trivial. For instance, if we
-want to obtain the pointer to \textbf{glActiveTextureARB}, we simply call:
-
-\begin{lstlisting}
-glActiveTextureARB = glfwGetProcAddress("glActiveTextureARB");
-\end{lstlisting}
-
-However, there are many possible naming and type definition conflicts
-involved with such an operation, which may result in compiler warnings or
-errors. My proposed solution is the following:
-
-\begin{itemize}
-\item Do not use the function name for the variable name. Use something
- similar, perhaps by adding a prefix or suffix, and then use
- \texttt{\#define} to map the function name to your variable.
-\item The standard type definition naming convention for function pointers
- is \texttt{PFN\textit{xxxx}PROC}, where \texttt{\textit{xxxx}} is
- the uppercase version of the function name (e.g.
- \texttt{PFNGLACTIVETEXTUREARBPROC}). Either make sure your compiler uses
- a compatible \texttt{gl.h} and/or \texttt{glext.h} file and rely on it to
- define these types, or use define the types yourself using a different
- naming convention (for example \texttt{\textit{xxxx}\_T}) and do the
- type definitions yourself.
-\end{itemize}
-
-Here is a slightly longer example of how to use an extension, this time using
-our own function pointer type definition):
-
-\begin{lstlisting}
-// Type definition of the function pointer
-typedef void (APIENTRY * GLACTIVETEXTUREARB_T) (GLenum texture);
-
-// Function pointer
-GLACTIVETEXTUREARB_T _ActiveTextureARB;
-#define glActiveTextureARB _ActiveTextureARB
-
-// Extension availability flag
-int multitexture_supported;
-
-#ifdef GL_ARB_multitexture
- // Check if extension is supported at run time
- if (glfwExtensionSupported("GL_ARB_multitexture"))
- {
- // Get the function pointer
- glActiveTextureARB = (GLACTIVETEXTUREARB_T)
- glfwGetProcAddress("glActiveTextureARB");
-
- multitexture_supported = GL_TRUE;
- }
- else
- {
- multitexture_supported = GL_FALSE;
- }
-#else
- // Extension is not supported by the include files
- multitexture_supported = GL_FALSE;
-#endif
-\end{lstlisting}
-
-Even this example leaves some things to be desired. First of all, the
-GL\_ARB\_multitexture extension defines many more functions than the single
-function used above. Secondly, checking if an extension is supported using
-\textbf{glfwExtensionSupported} is not enough to ensure that the corresponding
-functions will be valid. You also need to check that the all function pointers
-returned by \textbf{glfwGetProcAddress} are non-NULL.
-
-
-%-------------------------------------------------------------------------
-\subsection{Function pointer type definitions}
-To make a function pointer type definition, you need to know the function
-prototype. This can often be found in the extension definitions (e.g. at
-the \textit{OpenGL Registry}). All the entry points that are defined by an
-extension are listed with their C prototype definitions under the section
-\textit{New Procedures and Functions} in the extension definition.
-
-For instance, if we look at the definition of the
-GL\_ARB\_texture\_compression extension, we find a list of new functions.
-One of these is declared like this:
-
-\begin{lstlisting}
-void GetCompressedTexImageARB(enum target, int lod, void* img);
-\end{lstlisting}
-
-Like in most official \OpenGL\ documentation, all the \texttt{GL} and
-\texttt{gl} prefixes have been left out. In other words, the real function
-prototype would look like this:
-
-\begin{lstlisting}
-void glGetCompressedTexImageARB(GLenum target, GLint lod, void* img);
-\end{lstlisting}
-
-All we have to do to turn this prototype definition into a function
-pointer type definition, is to replace the function name with
-\texttt{(APIENTRY * \textit{xxxx}\_T)}, where \textit{xxxx} is the
-uppercase version of the name (according to the proposed naming
-convention). The keyword \texttt{APIENTRY} is needed to be compatible
-between different platforms. The \GLFW\ header file \texttt{GL/glfw.h}
-ensures that \texttt{APIENTRY} is properly defined on all supported platforms.
-
-In other words, for the function \textbf{glGetCompressedTexImageARB} we
-get:
-
-\begin{lstlisting}
-typedef void (APIENTRY * GLGETCOMPRESSEDTEXIMAGEARB_T)
- (GLenum target, GLint level, void* img);
-\end{lstlisting}
-
-
-\end{document}
diff --git a/docs/readme.txt b/docs/readme.txt
deleted file mode 100644
index f34521a2..00000000
--- a/docs/readme.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-Introduction
-------------
-
-The GLFW documentation is written in LaTeX. Besides being powerful, LaTeX is
-also very attractive since all the necessary tools for dealing with LaTeX
-documentation are both free and ported to a wide variety of platforms. Another
-advantage is that the LaTeX files are written in plain text, which means that
-version control systems such as CVS handle them perfectly without having to
-treat the documents as binary files.
-
-
-The documents
--------------
-
-There are two main documents:
-
- glfwrm.tex - The GLFW Reference Manual
- glfwug.tex - The GLFW Users Guide
-
-In addition, there is a common LaTeX style file that sets up things
-such as page formatting and useful macros:
-
- glfwdoc.sty - Common GLFW document styles and macros
-
-
-Requirements
-------------
-
-Of course you need LaTeX installed on your system in order to compile the GLFW
-documentation. If you are using a Unix-like operating system, then your
-package system most likely has a version of LaTeX adapted for your system. If
-not, the easiest way to get a full LaTeX system is to download/get the TeXLive
-CD from http://www.tug.org/texlive/. It has all the necessary software for
-Windows, Mac OS X and most popular Unix-like operating systems.
-
-A number of LaTeX packages have to be installed in order to compile the
-GLFW documentation successfully:
-
- color
- fancyhdr
- hyperref
- lastpage
- listings
- needspace
- textcase
- times
- titling
-
-These packages are all available on the TeXLive CD. Just make sure that
-you have checked all these packages when installing TeXLive, or get them
-in some other way if you do not have the TeXLive CD.
-
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index e850a312..3e7065c6 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,34 +1,53 @@
-# This line is used to link with static libraries
-# Note that the library list should be updated to be obtained from
-# the main CMakeLists.txt
-link_libraries(libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
+
+link_libraries(glfw ${OPENGL_glu_LIBRARY})
+
+if (BUILD_SHARED_LIBS)
+ add_definitions(-DGLFW_DLL)
+ link_libraries(${OPENGL_gl_LIBRARY} ${MATH_LIBRARY})
+else()
+ link_libraries(${glfw_LIBRARIES})
+endif()
include_directories(${GLFW_SOURCE_DIR}/include
${GLFW_SOURCE_DIR}/support
${OPENGL_INCLUDE_DIR})
-if(APPLE)
- # Set fancy names for bundles
- add_executable(Boing MACOSX_BUNDLE boing.c)
- add_executable(Gears MACOSX_BUNDLE gears.c)
- add_executable("Split View" MACOSX_BUNDLE splitview.c)
- add_executable(Triangle MACOSX_BUNDLE triangle.c)
- add_executable(Wave MACOSX_BUNDLE wave.c)
-else(APPLE)
- # Set boring names for executables
- add_executable(boing WIN32 boing.c)
- add_executable(gears WIN32 gears.c)
- add_executable(heightmap WIN32 heightmap.c getopt.c)
- add_executable(splitview WIN32 splitview.c)
- add_executable(triangle WIN32 triangle.c)
- add_executable(wave WIN32 wave.c)
-endif(APPLE)
+if (APPLE)
+ # Set fancy names for bundles
+ add_executable(Boing MACOSX_BUNDLE boing.c)
+ add_executable(Gears MACOSX_BUNDLE gears.c)
+ add_executable("Split View" MACOSX_BUNDLE splitview.c)
+ add_executable(Triangle MACOSX_BUNDLE triangle.c)
+ add_executable(Wave MACOSX_BUNDLE wave.c)
-set(WINDOWS_BINARIES boing gears heightmap splitview triangle wave)
+ set_target_properties(Boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing")
+ set_target_properties(Gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears")
+ set_target_properties("Split View" PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Split View")
+ set_target_properties(Triangle PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Triangle")
+ set_target_properties(Wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
+else()
+ # Set boring names for executables
+ add_executable(boing WIN32 boing.c)
+ add_executable(gears WIN32 gears.c)
+ add_executable(heightmap WIN32 heightmap.c getopt.c)
+ add_executable(splitview WIN32 splitview.c)
+ add_executable(triangle WIN32 triangle.c)
+ add_executable(wave WIN32 wave.c)
+endif()
-if(MSVC)
- # Tell MSVC to use main instead of WinMain for Windows subsystem executables
- set_target_properties(${WINDOWS_BINARIES} PROPERTIES
- LINK_FLAGS "/ENTRY:mainCRTStartup")
-endif(MSVC)
+if (MSVC)
+ set(WINDOWS_BINARIES boing gears heightmap splitview triangle wave)
+
+ # Tell MSVC to use main instead of WinMain for Windows subsystem executables
+ set_target_properties(${WINDOWS_BINARIES} PROPERTIES
+ LINK_FLAGS "/ENTRY:mainCRTStartup")
+endif()
+
+if (APPLE)
+ set(BUNDLE_BINARIES Boing Gears "Split View" Triangle Wave)
+
+ set_target_properties(${BUNDLE_BINARIES} PROPERTIES
+ MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
+ MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL})
+endif()
diff --git a/examples/boing.c b/examples/boing.c
index 8cf5b1dc..49d602ca 100644
--- a/examples/boing.c
+++ b/examples/boing.c
@@ -30,6 +30,8 @@
#include
#include
#include
+
+#define GLFW_INCLUDE_GLU
#include
@@ -569,7 +571,7 @@ int main( void )
GLFWwindow window;
/* Init GLFW */
- if( !glfwInit(NULL) )
+ if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
exit( EXIT_FAILURE );
diff --git a/examples/gears.c b/examples/gears.c
index cbf9eab9..53d601f3 100644
--- a/examples/gears.c
+++ b/examples/gears.c
@@ -323,7 +323,7 @@ int main(int argc, char *argv[])
{
GLFWwindow window;
- if( !glfwInit(NULL) )
+ if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
exit( EXIT_FAILURE );
diff --git a/examples/heightmap.c b/examples/heightmap.c
index a55df291..e926581a 100644
--- a/examples/heightmap.c
+++ b/examples/heightmap.c
@@ -32,8 +32,6 @@
#include
#include "getopt.h"
-
-#define GLFW_NO_GLU 1
#include
#include
@@ -84,7 +82,7 @@ static PFNGLVERTEXATTRIBPOINTERPROC pglVertexAttribPointer = NULL;
#define RESOLVE_GL_FCN(type, var, name) \
if (status == GL_TRUE) \
{\
- var = glfwGetProcAddress((name));\
+ var = (type) glfwGetProcAddress((name));\
if ((var) == NULL)\
{\
status = GL_FALSE;\
@@ -95,31 +93,31 @@ static PFNGLVERTEXATTRIBPOINTERPROC pglVertexAttribPointer = NULL;
static GLboolean init_opengl(void)
{
GLboolean status = GL_TRUE;
- RESOLVE_GL_FCN(PFN_glCreateShader, pglCreateShader, "glCreateShader");
- RESOLVE_GL_FCN(PFN_glShaderSource, pglShaderSource, "glShaderSource");
- RESOLVE_GL_FCN(PFN_glCompileShader, pglCompileShader, "glCompileShader");
- RESOLVE_GL_FCN(PFN_glGetShaderiv, pglGetShaderiv, "glGetShaderiv");
- RESOLVE_GL_FCN(PFN_glGetShaderInfoLog, pglGetShaderInfoLog, "glGetShaderInfoLog");
- RESOLVE_GL_FCN(PFN_glDeleteShader, pglDeleteShader, "glDeleteShader");
- RESOLVE_GL_FCN(PFN_glCreateProgram, pglCreateProgram, "glCreateProgram");
- RESOLVE_GL_FCN(PFN_glAttachShader, pglAttachShader, "glAttachShader");
- RESOLVE_GL_FCN(PFN_glLinkProgram, pglLinkProgram, "glLinkProgram");
- RESOLVE_GL_FCN(PFN_glUseProgram, pglUseProgram, "glUseProgram");
- RESOLVE_GL_FCN(PFN_glGetProgramiv, pglGetProgramiv, "glGetProgramiv");
- RESOLVE_GL_FCN(PFN_glGetProgramInfoLog, pglGetProgramInfoLog, "glGetProgramInfoLog");
- RESOLVE_GL_FCN(PFN_glDeleteProgram, pglDeleteProgram, "glDeleteProgram");
- RESOLVE_GL_FCN(PFN_glGetUniformLocation, pglGetUniformLocation, "glGetUniformLocation");
- RESOLVE_GL_FCN(PFN_glUniformMatrix4fv, pglUniformMatrix4fv, "glUniformMatrix4fv");
- RESOLVE_GL_FCN(PFN_glGetAttribLocation, pglGetAttribLocation, "glGetAttribLocation");
- RESOLVE_GL_FCN(PFN_glGenVertexArrays, pglGenVertexArrays, "glGenVertexArrays");
- RESOLVE_GL_FCN(PFN_glDeleteVertexArrays, pglDeleteVertexArrays, "glDeleteVertexArrays");
- RESOLVE_GL_FCN(PFN_glBindVertexArray, pglBindVertexArray, "glBindVertexArray");
- RESOLVE_GL_FCN(PFN_glGenBuffers, pglGenBuffers, "glGenBuffers");
- RESOLVE_GL_FCN(PFN_glBindBuffer, pglBindBuffer, "glBindBuffer");
- RESOLVE_GL_FCN(PFN_glBufferData, pglBufferData, "glBufferData");
- RESOLVE_GL_FCN(PFN_glBufferSubData, pglBufferSubData, "glBufferSubData");
- RESOLVE_GL_FCN(PFN_glEnableVertexAttribArray, pglEnableVertexAttribArray, "glEnableVertexAttribArray");
- RESOLVE_GL_FCN(PFN_glVertexAttribPointer, pglVertexAttribPointer, "glVertexAttribPointer");
+ RESOLVE_GL_FCN(PFNGLCREATESHADERPROC, pglCreateShader, "glCreateShader");
+ RESOLVE_GL_FCN(PFNGLSHADERSOURCEPROC, pglShaderSource, "glShaderSource");
+ RESOLVE_GL_FCN(PFNGLCOMPILESHADERPROC, pglCompileShader, "glCompileShader");
+ RESOLVE_GL_FCN(PFNGLGETSHADERIVPROC, pglGetShaderiv, "glGetShaderiv");
+ RESOLVE_GL_FCN(PFNGLGETSHADERINFOLOGPROC, pglGetShaderInfoLog, "glGetShaderInfoLog");
+ RESOLVE_GL_FCN(PFNGLDELETESHADERPROC, pglDeleteShader, "glDeleteShader");
+ RESOLVE_GL_FCN(PFNGLCREATEPROGRAMPROC, pglCreateProgram, "glCreateProgram");
+ RESOLVE_GL_FCN(PFNGLATTACHSHADERPROC, pglAttachShader, "glAttachShader");
+ RESOLVE_GL_FCN(PFNGLLINKPROGRAMPROC, pglLinkProgram, "glLinkProgram");
+ RESOLVE_GL_FCN(PFNGLUSEPROGRAMPROC, pglUseProgram, "glUseProgram");
+ RESOLVE_GL_FCN(PFNGLGETPROGRAMIVPROC, pglGetProgramiv, "glGetProgramiv");
+ RESOLVE_GL_FCN(PFNGLGETPROGRAMINFOLOGPROC, pglGetProgramInfoLog, "glGetProgramInfoLog");
+ RESOLVE_GL_FCN(PFNGLDELETEPROGRAMPROC, pglDeleteProgram, "glDeleteProgram");
+ RESOLVE_GL_FCN(PFNGLGETUNIFORMLOCATIONPROC, pglGetUniformLocation, "glGetUniformLocation");
+ RESOLVE_GL_FCN(PFNGLUNIFORMMATRIX4FVPROC, pglUniformMatrix4fv, "glUniformMatrix4fv");
+ RESOLVE_GL_FCN(PFNGLGETATTRIBLOCATIONPROC, pglGetAttribLocation, "glGetAttribLocation");
+ RESOLVE_GL_FCN(PFNGLGENVERTEXARRAYSPROC, pglGenVertexArrays, "glGenVertexArrays");
+ RESOLVE_GL_FCN(PFNGLDELETEVERTEXARRAYSPROC, pglDeleteVertexArrays, "glDeleteVertexArrays");
+ RESOLVE_GL_FCN(PFNGLBINDVERTEXARRAYPROC, pglBindVertexArray, "glBindVertexArray");
+ RESOLVE_GL_FCN(PFNGLGENBUFFERSPROC, pglGenBuffers, "glGenBuffers");
+ RESOLVE_GL_FCN(PFNGLBINDBUFFERPROC, pglBindBuffer, "glBindBuffer");
+ RESOLVE_GL_FCN(PFNGLBUFFERDATAPROC, pglBufferData, "glBufferData");
+ RESOLVE_GL_FCN(PFNGLBUFFERSUBDATAPROC, pglBufferSubData, "glBufferSubData");
+ RESOLVE_GL_FCN(PFNGLENABLEVERTEXATTRIBARRAYPROC, pglEnableVertexAttribArray, "glEnableVertexAttribArray");
+ RESOLVE_GL_FCN(PFNGLVERTEXATTRIBPOINTERPROC, pglVertexAttribPointer, "glVertexAttribPointer");
return status;
}
/**********************************************************************
@@ -573,7 +571,7 @@ int main(int argc, char** argv)
}
}
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "ERROR: Unable to initialize GLFW\n");
usage();
diff --git a/examples/splitview.c b/examples/splitview.c
index 3fcdd1d8..c584f9af 100644
--- a/examples/splitview.c
+++ b/examples/splitview.c
@@ -10,7 +10,9 @@
// because I am not a friend of orthogonal projections)
//========================================================================
+#define GLFW_INCLUDE_GLU
#include
+
#include
#include
#include
@@ -377,7 +379,7 @@ static void windowRefreshFun(GLFWwindow window)
// Mouse position callback function
//========================================================================
-static void mousePosFun(GLFWwindow window, int x, int y)
+static void cursorPosFun(GLFWwindow window, int x, int y)
{
// Depending on which view was selected, rotate around different axes
switch (active_view)
@@ -402,7 +404,7 @@ static void mousePosFun(GLFWwindow window, int x, int y)
break;
}
- // Remember mouse position
+ // Remember cursor position
xpos = x;
ypos = y;
}
@@ -442,7 +444,7 @@ int main(void)
GLFWwindow window;
// Initialise GLFW
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW\n");
exit(EXIT_FAILURE);
@@ -470,7 +472,7 @@ int main(void)
// Set callback functions
glfwSetWindowSizeCallback(windowSizeFun);
glfwSetWindowRefreshCallback(windowRefreshFun);
- glfwSetMousePosCallback(mousePosFun);
+ glfwSetCursorPosCallback(cursorPosFun);
glfwSetMouseButtonCallback(mouseButtonFun);
// Main loop
diff --git a/examples/triangle.c b/examples/triangle.c
index e952cc70..ee340496 100644
--- a/examples/triangle.c
+++ b/examples/triangle.c
@@ -7,6 +7,7 @@
#include
#include
+#define GLFW_INCLUDE_GLU
#include
int main(void)
@@ -15,7 +16,7 @@ int main(void)
GLFWwindow window;
// Initialise GLFW
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW\n");
exit(EXIT_FAILURE);
@@ -38,7 +39,7 @@ int main(void)
do
{
double t = glfwGetTime();
- glfwGetMousePos(window, &x, NULL);
+ glfwGetCursorPos(window, &x, NULL);
// Get window size (may be different than the requested size)
glfwGetWindowSize(window, &width, &height);
diff --git a/examples/wave.c b/examples/wave.c
index 9ffcd3f7..54574839 100644
--- a/examples/wave.c
+++ b/examples/wave.c
@@ -11,6 +11,8 @@
#include
#include
#include
+
+#define GLFW_INCLUDE_GLU
#include
#ifndef M_PI
@@ -321,10 +323,10 @@ void mouse_button_callback(GLFWwindow window, int button, int action)
//========================================================================
-// Callback function for mouse motion events
+// Callback function for cursor motion events
//========================================================================
-void mouse_position_callback(GLFWwindow window, int x, int y)
+void cursor_position_callback(GLFWwindow window, int x, int y)
{
if (locked)
{
@@ -341,9 +343,9 @@ void mouse_position_callback(GLFWwindow window, int x, int y)
// Callback function for scroll events
//========================================================================
-void scroll_callback(GLFWwindow window, int x, int y)
+void scroll_callback(GLFWwindow window, double x, double y)
{
- zoom += y / 4.f;
+ zoom += (float) y / 4.f;
if (zoom < 0)
zoom = 0;
}
@@ -379,7 +381,7 @@ int main(int argc, char* argv[])
GLFWwindow window;
double t, dt_total, t_old;
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "GLFW initialization failed\n");
exit(EXIT_FAILURE);
@@ -401,7 +403,7 @@ int main(int argc, char* argv[])
// Window resize handler
glfwSetWindowSizeCallback(window_resize_callback);
glfwSetMouseButtonCallback(mouse_button_callback);
- glfwSetMousePosCallback(mouse_position_callback);
+ glfwSetCursorPosCallback(cursor_position_callback);
glfwSetScrollCallback(scroll_callback);
// Initialize OpenGL
diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h
index 82a2f89c..b7ea88c5 100644
--- a/include/GL/glfw3.h
+++ b/include/GL/glfw3.h
@@ -67,6 +67,12 @@ extern "C" {
#endif
#endif /* APIENTRY */
+/* TEMPORARY MinGW-w64 hacks.
+ */
+#if __MINGW64__
+ #define WINAPI
+#include
+#endif
/* The following three defines are here solely to make some Windows-based
* files happy. Theoretically we could include , but
@@ -113,7 +119,11 @@ extern "C" {
/* ---------------- GLFW related system specific defines ----------------- */
-#if defined(_WIN32) && defined(GLFW_BUILD_DLL)
+#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL)
+ #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined"
+#endif
+
+#if defined(_WIN32) && defined(_GLFW_BUILD_DLL)
/* We are building a Win32 DLL */
#define GLFWAPI __declspec(dllexport)
@@ -136,15 +146,7 @@ extern "C" {
/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
-/* Include the declaration of the size_t type used below.
- */
-#include
-
-/* Include standard OpenGL headers: GLFW uses GL_FALSE/GL_TRUE, and it is
- * convenient for the user to only have to include . This also
- * solves the problem with Windows and needing some
- * special defines which normally requires the user to include
- * (which is not a nice solution for portable programs).
+/* Include the chosen OpenGL header and, optionally, the GLU header.
*/
#if defined(__APPLE_CC__)
#if defined(GLFW_INCLUDE_GL3)
@@ -153,7 +155,7 @@ extern "C" {
#define GL_GLEXT_LEGACY
#include
#endif
- #ifndef GLFW_NO_GLU
+ #if defined(GLFW_INCLUDE_GLU)
#include
#endif
#else
@@ -162,7 +164,7 @@ extern "C" {
#else
#include
#endif
- #ifndef GLFW_NO_GLU
+ #if defined(GLFW_INCLUDE_GLU)
#include
#endif
#endif
@@ -455,6 +457,7 @@ extern "C" {
#define GLFW_VERSION_UNAVAILABLE 0x00070007
#define GLFW_PLATFORM_ERROR 0x00070008
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009
+#define GLFW_FORMAT_UNAVAILABLE 0x0007000A
/* Gamma ramps */
#define GLFW_GAMMA_RAMP_SIZE 256
@@ -475,6 +478,9 @@ extern "C" {
/* Monitor handle type */
typedef void* GLFWmonitor;
+/* OpenGL function pointer type */
+typedef void (*GLFWglproc)(void);
+
/* Window handle type */
typedef void* GLFWwindow;
@@ -486,12 +492,11 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow);
typedef void (* GLFWwindowfocusfun)(GLFWwindow,int);
typedef void (* GLFWwindowiconifyfun)(GLFWwindow,int);
typedef void (* GLFWmousebuttonfun)(GLFWwindow,int,int);
-typedef void (* GLFWmouseposfun)(GLFWwindow,int,int);
-typedef void (* GLFWscrollfun)(GLFWwindow,int,int);
+typedef void (* GLFWcursorposfun)(GLFWwindow,int,int);
+typedef void (* GLFWcursorenterfun)(GLFWwindow,int);
+typedef void (* GLFWscrollfun)(GLFWwindow,double,double);
typedef void (* GLFWkeyfun)(GLFWwindow,int,int);
typedef void (* GLFWcharfun)(GLFWwindow,int);
-typedef void* (* GLFWmallocfun)(size_t);
-typedef void (* GLFWfreefun)(void*);
typedef void (* GLFWmonitordevicefun)(GLFWmonitor,int);
/* The video mode structure used by glfwGetVideoModes */
@@ -512,20 +517,13 @@ typedef struct
unsigned short blue[GLFW_GAMMA_RAMP_SIZE];
} GLFWgammaramp;
-/* Custom memory allocator interface */
-typedef struct
-{
- GLFWmallocfun malloc;
- GLFWfreefun free;
-} GLFWallocator;
-
/*************************************************************************
* Prototypes
*************************************************************************/
/* Initialization, termination and version querying */
-GLFWAPI int glfwInit(GLFWallocator* allocator);
+GLFWAPI int glfwInit(void);
GLFWAPI void glfwTerminate(void);
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
GLFWAPI const char* glfwGetVersionString(void);
@@ -586,13 +584,14 @@ GLFWAPI int glfwGetInputMode(GLFWwindow window, int mode);
GLFWAPI void glfwSetInputMode(GLFWwindow window, int mode, int value);
GLFWAPI int glfwGetKey(GLFWwindow window, int key);
GLFWAPI int glfwGetMouseButton(GLFWwindow window, int button);
-GLFWAPI void glfwGetMousePos(GLFWwindow window, int* xpos, int* ypos);
-GLFWAPI void glfwSetMousePos(GLFWwindow window, int xpos, int ypos);
-GLFWAPI void glfwGetScrollOffset(GLFWwindow window, int* xoffset, int* yoffset);
+GLFWAPI void glfwGetCursorPos(GLFWwindow window, int* xpos, int* ypos);
+GLFWAPI void glfwSetCursorPos(GLFWwindow window, int xpos, int ypos);
+GLFWAPI void glfwGetScrollOffset(GLFWwindow window, double* xoffset, double* yoffset);
GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun);
GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun);
GLFWAPI void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun);
-GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun);
+GLFWAPI void glfwSetCursorPosCallback(GLFWcursorposfun cbfun);
+GLFWAPI void glfwSetCursorEnterCallback(GLFWcursorenterfun cbfun);
GLFWAPI void glfwSetScrollCallback(GLFWscrollfun cbfun);
/* Joystick input */
@@ -600,6 +599,10 @@ GLFWAPI int glfwGetJoystickParam(int joy, int param);
GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes);
GLFWAPI int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons);
+/* Clipboard */
+GLFWAPI void glfwSetClipboardString(GLFWwindow window, const char* string);
+GLFWAPI const char* glfwGetClipboardString(GLFWwindow window);
+
/* Time */
GLFWAPI double glfwGetTime(void);
GLFWAPI void glfwSetTime(double time);
@@ -610,7 +613,7 @@ GLFWAPI GLFWwindow glfwGetCurrentContext(void);
GLFWAPI void glfwSwapBuffers(void);
GLFWAPI void glfwSwapInterval(int interval);
GLFWAPI int glfwExtensionSupported(const char* extension);
-GLFWAPI void* glfwGetProcAddress(const char* procname);
+GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
GLFWAPI void glfwCopyContext(GLFWwindow src, GLFWwindow dst, unsigned long mask);
diff --git a/readme.html b/readme.html
index b14945e8..3ef85423 100644
--- a/readme.html
+++ b/readme.html
@@ -20,7 +20,8 @@
Acknowledgements
-
+
+
1. Introduction
Welcome to version 3.0 of the GLFW library. GLFW is a free, open source,
@@ -34,19 +35,22 @@ settle.
Note that the threading and image loading APIs from the 2.x
series have been removed.
-
+
+
2. Compiling GLFW and the example programs
To compile GLFW and the accompanying example programs, you will need the
CMake build system.
-
+
+
3. Installing GLFW
A rudimentary installation target is provided for all supported platforms
via the CMake build system.
-
+
+
4. Using GLFW
There are two aspects to using GLFW:
@@ -66,12 +70,13 @@ GLFW API.
A few rules for successfully designing GLFW-based programs are presented
in the following sections.
+
4.1 Include the GLFW header file
In the files of your program where you use OpenGL or GLFW, you should
-include the GL/glfw.h
header file, i.e.:
+include the GL/glfw3.h
header file, i.e.:
-#include <GL/glfw.h>
+#include <GL/glfw3.h>
This defines all the constants, types and function prototypes of the GLFW
API. It also includes the gl.h
and GL/glu.h header
@@ -95,7 +100,7 @@ it. This way, the namespace won't be cluttered by the entire Windows API.
Do not include windows.h
unless you actually need
direct access to the Windows API
If you do need to include windows.h
, do it
- before including GL/glfw.h
and the GLFW header will
+ before including GL/glfw3.h
and the GLFW header will
detect this.
@@ -106,9 +111,9 @@ disable any gl.h
that the GLFW header includes and GLEW will work
as expected.
-
4.2 Link with the right libraries
+
4.2.1 Windows static library
If you link with the static version of GLFW, it is also necessary to
@@ -219,7 +224,6 @@ by compile.sh at compile time.
-lGLU
to your link flags.
-
4.2.5 Mac OS X static library
When compiling and linking a program under Mac OS X that uses GLFW, you
@@ -256,9 +260,11 @@ that even though your machine may have Unix-style OpenGL libraries, they are for
use with the X Window System, and will not work with the Mac OS X native
version of GLFW.
-
+
+
5. Version history
+
v3.0
- Added
GLFWwindow
window handle type and updated window-related functions and callbacks to take a window handle
@@ -271,8 +277,8 @@ version of GLFW.
- Added
glfwGetWindowPos
function for querying the position of the specified window
- Added
glfwSetWindowFocusCallback
function and GLFWwindowfocusfun
type for receiving window focus events
- Added
glfwSetWindowIconifyCallback
function and GLFWwindowiconifyfun
type for receiving window iconification events
+ - Added
glfwGetClipboardString
and glfwSetClipboardString
functions for interacting with the system clipboard
- Added
glfwGetCurrentContext
function for retrieving the window whose OpenGL context is current
- - Added
GLFWallocator
type and glfwInit
parameter for pluggable memory allocator
- Added
glfwCopyContext
function for copying OpenGL state categories between contexts
- Added
GLFW_OPENGL_ES2_PROFILE
profile for creating OpenGL ES 2.0 contexts using the GLX_EXT_create_context_es2_profile
and WGL_EXT_create_context_es2_profile
extensions
- Added
GLFW_OPENGL_ROBUSTNESS
window hint and associated strategy tokens for GL_ARB_robustness
support
@@ -280,20 +286,25 @@ version of GLFW.
- Added
GLFW_INCLUDE_GL3
macro for telling the GLFW header to include gl3.h
header instead of gl.h
- Added
windows
simple multi-window test program
- Added
sharing
simple OpenGL object sharing test program
- - Added
dynamic
simple dynamic linking test program
+ - Added
modes
video mode enumeration and setting test program
- Added a parameter to
glfwOpenWindow
for specifying a context the new window's context will share objects with
- Added initial window title parameter to
glfwOpenWindow
- Added
glfwSetGamma
, glfwSetGammaRamp
and glfwGetGammaRamp
functions and GLFWgammaramp
type for monitor gamma ramp control
- Changed buffer bit depth parameters of
glfwOpenWindow
to window hints
- Changed
glfwOpenWindow
and glfwSetWindowTitle
to use UTF-8 encoded strings
+ - Changed
glfwGetProcAddress
to return a (generic) function pointer
- Renamed
glfw.h
to glfw3.h
to avoid conflicts with 2.x series
- Renamed
GLFW_WINDOW
token to GLFW_WINDOWED
- Renamed
GLFW_WINDOW_NO_RESIZE
to GLFW_WINDOW_RESIZABLE
+ - Renamed
GLFW_BUILD_DLL
to _GLFW_BUILD_DLL
- Renamed
version
test to glfwinfo
+ - Renamed
GLFW_NO_GLU
to GLFW_INCLUDE_GLU
and made it disabled by default
+ - Renamed mouse position functions to cursor position equivalents
- Replaced ad hoc build system with CMake
- Replaced layout-dependent key codes with single, platform-independent set based on US layout
- - Replaced mouse wheel interface with two-dimensional scrolling interface
+ - Replaced mouse wheel interface with two-dimensional, floating point scrolling interface
- Replaced
glfwEnable
and glfwDisable
with glfwGetInputMode
and glfwSetInputMode
+ - Replaced
joystick
test with graphical version
- Made Unicode character input unaffected by
GLFW_KEY_REPEAT
- Removed event auto-polling and the
GLFW_AUTO_POLL_EVENTS
window enable
- Removed the Win32 port .def files
@@ -309,10 +320,21 @@ version of GLFW.
- Bugfix: The default OpenGL version in the
glfwinfo
test was set to 1.1
- Bugfix: The OpenGL profile and forward-compatibility window parameters were not saved after context creation
- Bugfix: The FSAA test did not check for the availability of
GL_ARB_multisample
+ - Bugfix: Cursor centering upon leaving captured cursor mode was reported before the mode was changed to non-captured
- [Cocoa] Added support for OpenGL 3.2 core profile in 10.7 Lion and above
- [Cocoa] Added support for joysticks
+ - [Cocoa] Postponed menu creation to first window creation
+ - [Cocoa] Replaced
NSDate
time source with mach_absolute_time
+ - [Cocoa] Replaced all deprecated CoreGraphics calls with non-deprecated counterparts
+ - [Cocoa] Bugfix: The
NSOpenGLPFAFullScreen
pixel format attribute caused creation to fail on some machines
+ - [Cocoa] Bugfix:
glfwOpenWindow
did not properly enforce the forward-compatible and context profile hints
- [Cocoa] Bugfix: The loop condition for saving video modes used the wrong index variable
- [Cocoa] Bugfix: The OpenGL framework was not retrieved, making glfwGetProcAddress crash
+ - [Cocoa] Bugfix:
glfwInit
changed the current directory for unbundled executables
+ - [Cocoa] Bugfix: The
GLFW_WINDOW_NO_RESIZE
window parameter was always zero
+ - [Cocoa] Bugfix: The cursor position incorrectly rounded during conversion
+ - [Cocoa] Bugfix: Cursor positioning led to nonsensical results for fullscreen windows
+ - [Cocoa] Bugfix: The GLFW window was flagged as restorable
- [X11] Added support for the
GLX_EXT_swap_control
extension as an alternative to GLX_SGI_swap_control
- [X11] Added the POSIX
CLOCK_MONOTONIC
time source as the preferred method
- [X11] Added dependency on libm, where present
@@ -325,6 +347,9 @@ version of GLFW.
- [Win32] Bugfix: Window activation and iconification did not work as expected
- [Win32] Bugfix: Software rasterizer pixel formats were not discarded by the WGL_ARB_pixel_format code path
- [Win32] Bugfix: The array for WGL context attributes was too small and could overflow
+ - [Win32] Bugfix: Alt+F4 hot key was not translated into
WM_CLOSE
+ - [Win32] Bugfix: The
GLFW_WINDOW_NO_RESIZE
window parameter was always zero
+ - [Win32] Bugfix: A test was missing for whether all available pixel formats had been disqualified
v2.7
@@ -759,7 +784,7 @@ version of GLFW.
-
+
6. Directory structure of the GLFW distribution
Here is an overview of the directory structure of the GLFW distribution:
@@ -782,7 +807,7 @@ version of GLFW.
-
+
7. Contacting the project
The official website for GLFW is glfw.org.
@@ -806,7 +831,7 @@ GLFW or porting it to your favorite platform, we have a
or you could join us on #glfw
.
-
+
8. Acknowledgements
GLFW exists because people around the world donated their time and lent
@@ -814,12 +839,16 @@ their skills. Special thanks go out to:
+ - artblanc, for a patch replacing a deprecated Core Graphics call
+
- Bobyshev Alexander and Martins Mozeiko, for the original proposal of
an FSAA hint and their work on the Win32 implementation of FSAA
- Keith Bauer, for his invaluable help with porting and maintaining GLFW on
Mac OS X, and for his many ideas
+ - Lambert Clara, for a bug fix for the modes test
+
- Jarrod Davis, for the Delphi port of GLFW
- Olivier Delannoy, for the initial implementation of FSAA support on
@@ -833,7 +862,10 @@ their skills. Special thanks go out to:
adding logic for the
GLFW_ICON
resource
- Ralph Eastwood, for the initial design and implementation of the gamma
- correction API
+ correction and clipboard APIs
+
+ GeO4d, for the implementation of cursor enter/leave notifications on
+ Win32.
Gerald Franz, who made GLFW compile under IRIX, and supplied patches
for the X11 keyboard translation routine
@@ -864,9 +896,14 @@ their skills. Special thanks go out to:
Glenn Lewis, for helping out with support for the D programming
language
+ Shane Liesegang, for providing a bug fix relating to Cocoa window
+ restoration
+
Tristam MacDonald, for his bug reports and feedback on the Cocoa port
- Hans 'Hanmac' Mackowiak, for adding UTF-8 window title support on X11
+ Hans 'Hanmac' Mackowiak, for the initial implementation of cursor
+ enter/leave callbacks on X11, adding UTF-8 window title support on X11 and
+ a fix for the Xkb support
David Medlock, for doing the initial Lua port
@@ -889,7 +926,7 @@ their skills. Special thanks go out to:
Steve Sexton, for reporting an input bug in the Carbon port
- Dmitri Shuralyov, for support, bug reports and testing
+ Dmitri Shuralyov, for support, bug reports, bug fixes and testing
Daniel Skorupski, for reporting a bug in the Win32 DEF file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2a399678..ee9241a7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,72 +1,57 @@
-if(WIN32)
- add_definitions(-DWINVER=0x0501)
-endif(WIN32)
-
-if(UNIX)
- if(_GLFW_HAS_XRANDR)
- set(GLFW_PKGLIBS "${GLFW_PKGLIBS} xrandr")
- endif(_GLFW_HAS_XRANDR)
- if(_GLFW_HAS_XF86VIDMODE)
- set(GLFW_PKGLIBS "${GLFW_PKGLIBS} xxf86vm")
- endif(_GLFW_HAS_XF86VIDMODE)
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libglfw.pc.cmake
- ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc @ONLY)
- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc DESTINATION lib/pkgconfig)
-endif(UNIX)
-
include_directories(${GLFW_SOURCE_DIR}/src
${GLFW_BINARY_DIR}/src
- ${GLFW_INCLUDE_DIR})
+ ${glfw_INCLUDE_DIRS})
-set(common_SOURCES error.c fullscreen.c gamma.c init.c input.c
+set(common_HEADERS ${GLFW_SOURCE_DIR}/include/GL/glfw3.h internal.h)
+set(common_SOURCES clipboard.c error.c fullscreen.c gamma.c init.c input.c
joystick.c monitor.c opengl.c time.c window.c)
-if(_GLFW_COCOA_NSGL)
- set(libglfw_SOURCES ${common_SOURCES} cocoa_fullscreen.m cocoa_gamma.m
- cocoa_init.m cocoa_input.m cocoa_joystick.m
- cocoa_opengl.m cocoa_time.m cocoa_window.m)
+if (_GLFW_COCOA_NSGL)
+ set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h)
+ set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m
+ cocoa_gamma.c cocoa_init.m cocoa_input.m cocoa_joystick.m
+ cocoa_opengl.m cocoa_time.c cocoa_window.m)
# For some reason, CMake doesn't know about .m
- set_source_files_properties(${libglfw_SOURCES} PROPERTIES LANGUAGE C)
-elseif(_GLFW_WIN32_WGL)
- set(libglfw_SOURCES ${common_SOURCES} win32_fullscreen.c win32_gamma.c
- win32_init.c win32_input.c win32_joystick.c
- win32_opengl.c win32_time.c win32_window.c
- win32_dllmain.c win32_monitor.c)
-elseif(_GLFW_X11_GLX)
- set(libglfw_SOURCES ${common_SOURCES} x11_fullscreen.c x11_gamma.c
- x11_init.c x11_input.c x11_joystick.c
- x11_keysym2unicode.c x11_monitor.c x11_opengl.c
- x11_time.c x11_window.c)
-else()
- message(FATAL_ERROR "No supported platform was selected")
-endif(_GLFW_COCOA_NSGL)
+ set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
+elseif (_GLFW_WIN32_WGL)
+ set(glfw_HEADERS ${common_HEADERS} win32_platform.h)
+ set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_dllmain.c
+ win32_fullscreen.c win32_gamma.c win32_init.c win32_input.c
+ win32_joystick.c win32_monitor.c win32_opengl.c
+ win32_time.c win32_window.c)
+elseif (_GLFW_X11_GLX)
+ set(glfw_HEADERS ${common_HEADERS} x11_platform.h)
+ set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c
+ x11_gamma.c x11_init.c x11_input.c x11_joystick.c
+ x11_keysym2unicode.c x11_monitor.c x11_opengl.c x11_time.c
+ x11_window.c)
+endif()
-add_library(libglfwStatic STATIC ${libglfw_SOURCES})
-add_library(libglfwShared SHARED ${libglfw_SOURCES})
-target_link_libraries(libglfwShared ${GLFW_LIBRARIES})
-set_target_properties(libglfwStatic libglfwShared PROPERTIES
- CLEAN_DIRECT_OUTPUT 1
- OUTPUT_NAME glfw)
+add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
-if(WIN32)
- # The GLFW DLL needs a special compile-time macro and import library name
- set_target_properties(libglfwShared PROPERTIES
- DEFINE_SYMBOL GLFW_BUILD_DLL
- PREFIX ""
- IMPORT_PREFIX ""
- IMPORT_SUFFIX "dll.lib")
-endif(WIN32)
+if (BUILD_SHARED_LIBS)
-if(APPLE)
- # Append -fno-common to the compile flags to work around a bug in the Apple GCC
- get_target_property(CFLAGS libglfwShared COMPILE_FLAGS)
- if(NOT CFLAGS)
- set(CFLAGS "")
- endif(NOT CFLAGS)
- set_target_properties(libglfwShared PROPERTIES COMPILE_FLAGS "${CFLAGS} -fno-common")
-endif(APPLE)
+ if (_GLFW_WIN32_WGL)
+ # The GLFW DLL needs a special compile-time macro and import library name
+ set_target_properties(glfw PROPERTIES
+ PREFIX ""
+ IMPORT_PREFIX ""
+ IMPORT_SUFFIX "dll.lib")
+ elseif (_GLFW_COCOA_NSGL)
+ # Append -fno-common to the compile flags to work around a bug in the Apple GCC
+ get_target_property(glfw_CFLAGS glfw COMPILE_FLAGS)
+ if (NOT glfw_CFLAGS)
+ set(glfw_CFLAGS "")
+ endif()
+ set_target_properties(glfw PROPERTIES
+ COMPILE_FLAGS "${glfw_CFLAGS} -fno-common")
+ endif()
-install(TARGETS libglfwStatic libglfwShared DESTINATION lib)
+ target_link_libraries(glfw ${glfw_LIBRARIES})
+ target_link_libraries(glfw LINK_INTERFACE_LIBRARIES)
+endif()
+
+install(TARGETS glfw DESTINATION lib)
diff --git a/src/cocoa_time.m b/src/clipboard.c
similarity index 66%
rename from src/cocoa_time.m
rename to src/clipboard.c
index d7e7d2b8..0bdea5b4 100644
--- a/src/cocoa_time.m
+++ b/src/clipboard.c
@@ -1,10 +1,10 @@
//========================================================================
// GLFW - An OpenGL library
-// Platform: Cocoa/NSOpenGL
-// API Version: 3.0
+// Platform: Any
+// API version: 3.0
// WWW: http://www.glfw.org/
//------------------------------------------------------------------------
-// Copyright (c) 2009-2010 Camilla Berglund
+// Copyright (c) 2010 Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
@@ -29,28 +29,46 @@
#include "internal.h"
+#include
+#include
+
//////////////////////////////////////////////////////////////////////////
-////// GLFW platform API //////
+////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
//========================================================================
-// Return timer value in seconds
+// Set the clipboard contents
//========================================================================
-double _glfwPlatformGetTime(void)
+GLFWAPI void glfwSetClipboardString(GLFWwindow handle, const char* string)
{
- return [NSDate timeIntervalSinceReferenceDate] -
- _glfwLibrary.NS.timer.t0;
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+
+ if (!_glfwInitialized)
+ {
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
+ return;
+ }
+
+ _glfwPlatformSetClipboardString(window, string);
}
+
//========================================================================
-// Set timer value in seconds
+// Return the current clipboard contents
//========================================================================
-void _glfwPlatformSetTime(double time)
+GLFWAPI const char* glfwGetClipboardString(GLFWwindow handle)
{
- _glfwLibrary.NS.timer.t0 =
- [NSDate timeIntervalSinceReferenceDate] - time;
+ _GLFWwindow* window = (_GLFWwindow*) handle;
+
+ if (!_glfwInitialized)
+ {
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
+ return NULL;
+ }
+
+ return _glfwPlatformGetClipboardString(window);
}
diff --git a/src/cocoa_clipboard.m b/src/cocoa_clipboard.m
new file mode 100644
index 00000000..56b98437
--- /dev/null
+++ b/src/cocoa_clipboard.m
@@ -0,0 +1,82 @@
+//========================================================================
+// GLFW - An OpenGL library
+// Platform: Cocoa/NSOpenGL
+// API version: 3.0
+// WWW: http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2010 Camilla Berglund
+//
+// 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.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include
+#include
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Set the clipboard contents
+//========================================================================
+
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
+{
+ NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil];
+
+ NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
+ [pasteboard declareTypes:types owner:nil];
+ [pasteboard setString:[NSString stringWithUTF8String:string]
+ forType:NSStringPboardType];
+}
+
+
+//========================================================================
+// Return the current clipboard contents
+//========================================================================
+
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
+{
+ NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
+
+ if (![[pasteboard types] containsObject:NSStringPboardType])
+ {
+ _glfwSetError(GLFW_FORMAT_UNAVAILABLE, NULL);
+ return NULL;
+ }
+
+ NSString* object = [pasteboard stringForType:NSStringPboardType];
+ if (!object)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Cocoa/NSGL: Failed to retrieve object from pasteboard");
+ return NULL;
+ }
+
+ free(_glfwLibrary.NS.clipboardString);
+ _glfwLibrary.NS.clipboardString = strdup([object UTF8String]);
+
+ return _glfwLibrary.NS.clipboardString;
+}
+
diff --git a/src/cocoa_fullscreen.m b/src/cocoa_fullscreen.m
index 370296b8..147913fb 100644
--- a/src/cocoa_fullscreen.m
+++ b/src/cocoa_fullscreen.m
@@ -29,47 +29,166 @@
#include "internal.h"
+#include
+#include
+
//========================================================================
// Check whether the display mode should be included in enumeration
//========================================================================
-static BOOL modeIsGood(NSDictionary* mode)
+static GLboolean modeIsGood(CGDisplayModeRef mode)
{
- // This is a bit controversial, if you've got something other than an
- // LCD computer monitor as an output device you might not want these
- // checks. You might also want to reject modes which are interlaced,
- // or TV out. There is no one-size-fits-all policy that can work here.
- // This seems like a decent compromise, but certain applications may
- // wish to patch this...
- return [[mode objectForKey:(id)kCGDisplayBitsPerPixel] intValue] >= 15 &&
- [mode objectForKey:(id)kCGDisplayModeIsSafeForHardware] != nil &&
- [mode objectForKey:(id)kCGDisplayModeIsStretched] == nil;
+ uint32_t flags = CGDisplayModeGetIOFlags(mode);
+ if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))
+ return GL_FALSE;
+
+ if (flags & kDisplayModeInterlacedFlag)
+ return GL_FALSE;
+
+ if (flags & kDisplayModeTelevisionFlag)
+ return GL_FALSE;
+
+ if (flags & kDisplayModeStretchedFlag)
+ return GL_FALSE;
+
+ CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
+ if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
+ CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
+ {
+ CFRelease(format);
+ return GL_FALSE;
+ }
+
+ CFRelease(format);
+ return GL_TRUE;
}
+
//========================================================================
// Convert Core Graphics display mode to GLFW video mode
//========================================================================
-static GLFWvidmode vidmodeFromCGDisplayMode(NSDictionary* mode)
+static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode)
{
- unsigned int width =
- [[mode objectForKey:(id)kCGDisplayWidth] unsignedIntValue];
- unsigned int height =
- [[mode objectForKey:(id)kCGDisplayHeight] unsignedIntValue];
- unsigned int bps =
- [[mode objectForKey:(id)kCGDisplayBitsPerSample] unsignedIntValue];
-
GLFWvidmode result;
- result.width = width;
- result.height = height;
- result.redBits = bps;
- result.greenBits = bps;
- result.blueBits = bps;
+ result.width = CGDisplayModeGetWidth(mode);
+ result.height = CGDisplayModeGetHeight(mode);
+
+ CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
+
+ if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
+ {
+ result.redBits = 5;
+ result.greenBits = 5;
+ result.blueBits = 5;
+ }
+ else
+ {
+ result.redBits = 8;
+ result.greenBits = 8;
+ result.blueBits = 8;
+ }
+
+ CFRelease(format);
return result;
}
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Change the current video mode
+//========================================================================
+
+GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate)
+{
+ CGDisplayModeRef bestMode = NULL;
+ CFArrayRef modes;
+ CFIndex count, i;
+ unsigned int leastSizeDiff = UINT_MAX;
+ double leastRateDiff = DBL_MAX;
+
+ modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
+ count = CFArrayGetCount(modes);
+
+ for (i = 0; i < count; i++)
+ {
+ CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
+ if (!modeIsGood(mode))
+ continue;
+
+ int modeBPP;
+
+ // Identify display mode pixel encoding
+ {
+ CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
+
+ if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
+ modeBPP = 16;
+ else
+ modeBPP = 32;
+
+ CFRelease(format);
+ }
+
+ int modeWidth = (int) CGDisplayModeGetWidth(mode);
+ int modeHeight = (int) CGDisplayModeGetHeight(mode);
+
+ unsigned int sizeDiff = (abs(modeBPP - *bpp) << 25) |
+ ((modeWidth - *width) * (modeWidth - *width) +
+ (modeHeight - *height) * (modeHeight - *height));
+
+ double rateDiff;
+
+ if (*refreshRate > 0)
+ rateDiff = fabs(CGDisplayModeGetRefreshRate(mode) - *refreshRate);
+ else
+ {
+ // If no refresh rate was specified, then they're all the same
+ rateDiff = 0;
+ }
+
+ if ((sizeDiff < leastSizeDiff) ||
+ (sizeDiff == leastSizeDiff && (rateDiff < leastRateDiff)))
+ {
+ bestMode = mode;
+
+ leastSizeDiff = sizeDiff;
+ leastRateDiff = rateDiff;
+ }
+ }
+
+ if (!bestMode)
+ {
+ CFRelease(modes);
+ return GL_FALSE;
+ }
+
+ CGDisplayCapture(CGMainDisplayID());
+ CGDisplaySetDisplayMode(CGMainDisplayID(), bestMode, NULL);
+
+ CFRelease(modes);
+ return GL_TRUE;
+}
+
+
+//========================================================================
+// Restore the previously saved (original) video mode
+//========================================================================
+
+void _glfwRestoreVideoMode(void)
+{
+ CGDisplaySetDisplayMode(CGMainDisplayID(),
+ _glfwLibrary.NS.desktopMode,
+ NULL);
+
+ CGDisplayRelease(CGMainDisplayID());
+}
+
+
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
@@ -80,19 +199,26 @@ static GLFWvidmode vidmodeFromCGDisplayMode(NSDictionary* mode)
int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
{
- NSArray* modes = (NSArray*) CGDisplayAvailableModes(CGMainDisplayID());
- unsigned int i, j = 0, n = [modes count];
+ CGDisplayModeRef mode;
+ CFArrayRef modes;
+ CFIndex count, i;
+ int stored = 0;
- for (i = 0; i < n && j < (unsigned)maxcount; i++)
+ modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
+ count = CFArrayGetCount(modes);
+
+ for (i = 0; i < count && stored < maxcount; i++)
{
- NSDictionary *mode = [modes objectAtIndex:i];
+ mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
if (modeIsGood(mode))
- list[j++] = vidmodeFromCGDisplayMode(mode);
+ list[stored++] = vidmodeFromCGDisplayMode(mode);
}
- return j;
+ CFRelease(modes);
+ return stored;
}
+
//========================================================================
// Get the desktop video mode
//========================================================================
diff --git a/src/cocoa_gamma.m b/src/cocoa_gamma.c
similarity index 98%
rename from src/cocoa_gamma.m
rename to src/cocoa_gamma.c
index eb291082..53c47a89 100644
--- a/src/cocoa_gamma.m
+++ b/src/cocoa_gamma.c
@@ -32,6 +32,8 @@
#include
#include
+#include
+
//************************************************************************
//**** GLFW internal functions ****
diff --git a/src/cocoa_init.m b/src/cocoa_init.m
index bf4f7c2e..7c208b90 100644
--- a/src/cocoa_init.m
+++ b/src/cocoa_init.m
@@ -27,162 +27,45 @@
//
//========================================================================
-// Needed for _NSGetProgname
-#include
-
#include "internal.h"
-
+#include // For MAXPATHLEN
//========================================================================
-// GLFW application class
+// Change to our application bundle's resources directory, if present
//========================================================================
-@interface GLFWApplication : NSApplication
-@end
-
-@implementation GLFWApplication
-
-// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
-// This works around an AppKit bug, where key up events while holding
-// down the command key don't get sent to the key window.
-- (void)sendEvent:(NSEvent *)event
+static void changeToResourcesDirectory(void)
{
- if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask))
- [[self keyWindow] sendEvent:event];
- else
- [super sendEvent:event];
-}
+ char resourcesPath[MAXPATHLEN];
-@end
+ CFBundleRef bundle = CFBundleGetMainBundle();
+ if (!bundle)
+ return;
+ CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle);
-// Prior to Snow Leopard, we need to use this oddly-named semi-private API
-// to get the application menu working properly. Need to be careful in
-// case it goes away in a future OS update.
-@interface NSApplication (NSAppleMenu)
-- (void)setAppleMenu:(NSMenu*)m;
-@end
-
-// Keys to search for as potential application names
-NSString* GLFWNameKeys[] =
-{
- @"CFBundleDisplayName",
- @"CFBundleName",
- @"CFBundleExecutable",
-};
-
-
-//========================================================================
-// Try to figure out what the calling application is called
-//========================================================================
-static NSString* findAppName(void)
-{
- unsigned int i;
- NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
-
- for (i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++)
+ CFStringRef last = CFURLCopyLastPathComponent(resourcesURL);
+ if (CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo)
{
- id name = [infoDictionary objectForKey:GLFWNameKeys[i]];
- if (name &&
- [name isKindOfClass:[NSString class]] &&
- ![@"" isEqualToString:name])
- {
- return name;
- }
+ CFRelease(last);
+ CFRelease(resourcesURL);
+ return;
}
- // If we get here, we're unbundled
- if (!_glfwLibrary.NS.unbundled)
+ CFRelease(last);
+
+ if (!CFURLGetFileSystemRepresentation(resourcesURL,
+ true,
+ (UInt8*) resourcesPath,
+ MAXPATHLEN))
{
- // Could do this only if we discover we're unbundled, but it should
- // do no harm...
- ProcessSerialNumber psn = { 0, kCurrentProcess };
- TransformProcessType(&psn, kProcessTransformToForegroundApplication);
-
- // Having the app in front of the terminal window is also generally
- // handy. There is an NSApplication API to do this, but...
- SetFrontProcess(&psn);
-
- _glfwLibrary.NS.unbundled = GL_TRUE;
+ CFRelease(resourcesURL);
+ return;
}
- char** progname = _NSGetProgname();
- if (progname && *progname)
- {
- // TODO: UTF-8?
- return [NSString stringWithUTF8String:*progname];
- }
+ CFRelease(resourcesURL);
- // Really shouldn't get here
- return @"GLFW Application";
-}
-
-//========================================================================
-// Set up the menu bar (manually)
-// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
-// could go away at any moment, lots of stuff that really should be
-// localize(d|able), etc. Loading a nib would save us this horror, but that
-// doesn't seem like a good thing to require of GLFW's clients.
-//========================================================================
-static void setUpMenuBar(void)
-{
- NSString* appName = findAppName();
-
- NSMenu* bar = [[NSMenu alloc] init];
- [NSApp setMainMenu:bar];
-
- NSMenuItem* appMenuItem =
- [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
- NSMenu* appMenu = [[NSMenu alloc] init];
- [appMenuItem setSubmenu:appMenu];
-
- [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]
- action:@selector(orderFrontStandardAboutPanel:)
- keyEquivalent:@""];
- [appMenu addItem:[NSMenuItem separatorItem]];
- NSMenu* servicesMenu = [[NSMenu alloc] init];
- [NSApp setServicesMenu:servicesMenu];
- [[appMenu addItemWithTitle:@"Services"
- action:NULL
- keyEquivalent:@""] setSubmenu:servicesMenu];
- [appMenu addItem:[NSMenuItem separatorItem]];
- [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]
- action:@selector(hide:)
- keyEquivalent:@"h"];
- [[appMenu addItemWithTitle:@"Hide Others"
- action:@selector(hideOtherApplications:)
- keyEquivalent:@"h"]
- setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];
- [appMenu addItemWithTitle:@"Show All"
- action:@selector(unhideAllApplications:)
- keyEquivalent:@""];
- [appMenu addItem:[NSMenuItem separatorItem]];
- [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]
- action:@selector(terminate:)
- keyEquivalent:@"q"];
-
- NSMenuItem* windowMenuItem =
- [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
- NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
- [NSApp setWindowsMenu:windowMenu];
- [windowMenuItem setSubmenu:windowMenu];
-
- [windowMenu addItemWithTitle:@"Miniaturize"
- action:@selector(performMiniaturize:)
- keyEquivalent:@"m"];
- [windowMenu addItemWithTitle:@"Zoom"
- action:@selector(performZoom:)
- keyEquivalent:@""];
- [windowMenu addItem:[NSMenuItem separatorItem]];
- [windowMenu addItemWithTitle:@"Bring All to Front"
- action:@selector(arrangeInFront:)
- keyEquivalent:@""];
-
- // At least guard the call to private API to avoid an exception if it
- // goes away. Hopefully that means the worst we'll break in future is to
- // look ugly...
- if ([NSApp respondsToSelector:@selector(setAppleMenu:)])
- [NSApp setAppleMenu:appMenu];
+ chdir(resourcesPath);
}
@@ -198,43 +81,39 @@ int _glfwPlatformInit(void)
{
_glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init];
- // Implicitly create shared NSApplication instance
- [GLFWApplication sharedApplication];
-
- _glfwLibrary.NS.OpenGLFramework =
+ _glfwLibrary.NSGL.framework =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
- if (_glfwLibrary.NS.OpenGLFramework == NULL)
+ if (_glfwLibrary.NSGL.framework == NULL)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
"glfwInit: Failed to locate OpenGL framework");
return GL_FALSE;
}
- NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
+ changeToResourcesDirectory();
- if (access([resourcePath cStringUsingEncoding:NSUTF8StringEncoding], R_OK) == 0)
- chdir([resourcePath cStringUsingEncoding:NSUTF8StringEncoding]);
-
- // Setting up menu bar must go exactly here else weirdness ensues
- setUpMenuBar();
-
- [NSApp finishLaunching];
-
- _glfwPlatformSetTime(0.0);
-
- _glfwLibrary.NS.desktopMode =
- (NSDictionary*) CGDisplayCurrentMode(CGMainDisplayID());
+ _glfwLibrary.NS.desktopMode = CGDisplayCopyDisplayMode(CGMainDisplayID());
// Save the original gamma ramp
_glfwLibrary.originalRampSize = CGDisplayGammaTableCapacity(CGMainDisplayID());
_glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp);
_glfwLibrary.currentRamp = _glfwLibrary.originalRamp;
+ _glfwInitTimer();
+
_glfwInitJoysticks();
+ _glfwLibrary.NS.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
+ if (!_glfwLibrary.NS.eventSource)
+ return GL_FALSE;
+
+ CGEventSourceSetLocalEventsSuppressionInterval(_glfwLibrary.NS.eventSource,
+ 0.0);
+
return GL_TRUE;
}
+
//========================================================================
// Close window, if open, and shut down GLFW
//========================================================================
@@ -243,8 +122,17 @@ int _glfwPlatformTerminate(void)
{
// TODO: Probably other cleanup
+ if (_glfwLibrary.NS.eventSource)
+ {
+ CFRelease(_glfwLibrary.NS.eventSource);
+ _glfwLibrary.NS.eventSource = NULL;
+ }
+
// Restore the original gamma ramp
- _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
+ if (_glfwLibrary.rampChanged)
+ _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
+
+ CGDisplayModeRelease(_glfwLibrary.NS.desktopMode);
[NSApp setDelegate:nil];
[_glfwLibrary.NS.delegate release];
@@ -265,7 +153,11 @@ int _glfwPlatformTerminate(void)
const char* _glfwPlatformGetVersionString(void)
{
- const char* version = _GLFW_VERSION_FULL " Cocoa";
+ const char* version = _GLFW_VERSION_FULL
+#if defined(_GLFW_BUILD_DLL)
+ " dynamic"
+#endif
+ ;
return version;
}
diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m
index 0aa10a4a..97510fdf 100644
--- a/src/cocoa_joystick.m
+++ b/src/cocoa_joystick.m
@@ -152,7 +152,7 @@ static void addJoystickElement(_glfwJoystick* joystick, CFTypeRef refElement)
long number;
CFTypeRef refType;
- _glfwJoystickElement* element = (_glfwJoystickElement*) _glfwMalloc(sizeof(_glfwJoystickElement));
+ _glfwJoystickElement* element = (_glfwJoystickElement*) malloc(sizeof(_glfwJoystickElement));
CFArrayAppendValue(elementsArray, element);
@@ -242,7 +242,7 @@ static void removeJoystick(_glfwJoystick* joystick)
{
_glfwJoystickElement* axes =
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, i);
- _glfwFree(axes);
+ free(axes);
}
CFArrayRemoveAllValues(joystick->axes);
joystick->numAxes = 0;
@@ -251,7 +251,7 @@ static void removeJoystick(_glfwJoystick* joystick)
{
_glfwJoystickElement* button =
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->buttons, i);
- _glfwFree(button);
+ free(button);
}
CFArrayRemoveAllValues(joystick->buttons);
joystick->numButtons = 0;
@@ -260,7 +260,7 @@ static void removeJoystick(_glfwJoystick* joystick)
{
_glfwJoystickElement* hat =
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->hats, i);
- _glfwFree(hat);
+ free(hat);
}
CFArrayRemoveAllValues(joystick->hats);
joystick->hats = 0;
@@ -311,6 +311,13 @@ static void pollJoystickEvents(void)
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, j);
axes->value = getElementValue(joystick, axes);
}
+
+ for (j = 0; j < joystick->numHats; j++)
+ {
+ _glfwJoystickElement* hat =
+ (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->hats, j);
+ hat->value = getElementValue(joystick, hat);
+ }
}
}
}
@@ -336,7 +343,12 @@ void _glfwInitJoysticks(void)
result = IOMasterPort(bootstrap_port, &masterPort);
hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
if (kIOReturnSuccess != result || !hidMatchDictionary)
+ {
+ if (hidMatchDictionary)
+ CFRelease(hidMatchDictionary);
+
return;
+ }
result = IOServiceGetMatchingServices(masterPort,
hidMatchDictionary,
@@ -370,19 +382,27 @@ void _glfwInitJoysticks(void)
/* Check device type */
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey));
if (refCF)
+ {
CFNumberGetValue(refCF, kCFNumberLongType, &usagePage);
+ if (usagePage != kHIDPage_GenericDesktop)
+ {
+ /* We are not interested in this device */
+ continue;
+ }
+ }
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsageKey));
if (refCF)
- CFNumberGetValue(refCF, kCFNumberLongType, &usage);
-
- if ((usagePage != kHIDPage_GenericDesktop) ||
- (usage != kHIDUsage_GD_Joystick &&
- usage != kHIDUsage_GD_GamePad &&
- usage != kHIDUsage_GD_MultiAxisController))
{
- /* We don't interested in this device */
- continue;
+ CFNumberGetValue(refCF, kCFNumberLongType, &usage);
+
+ if ((usage != kHIDUsage_GD_Joystick &&
+ usage != kHIDUsage_GD_GamePad &&
+ usage != kHIDUsage_GD_MultiAxisController))
+ {
+ /* We are not interested in this device */
+ continue;
+ }
}
_glfwJoystick* joystick = &_glfwJoysticks[deviceCounter];
@@ -489,7 +509,7 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
return (int) CFArrayGetCount(_glfwJoysticks[joy].axes);
case GLFW_BUTTONS:
- return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons);
+ return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons) + ((int) CFArrayGetCount(_glfwJoysticks[joy].hats)) * 4;
default:
break;
@@ -552,7 +572,7 @@ int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes)
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
int numbuttons)
{
- int i;
+ int i, j, button;
if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST)
return 0;
@@ -565,18 +585,31 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
return 0;
}
- numbuttons = numbuttons < joystick.numButtons ? numbuttons : joystick.numButtons;
-
// Update joystick state
pollJoystickEvents();
- for (i = 0; i < numbuttons; i++)
+ for (button = 0; button < numbuttons && button < joystick.numButtons; button++)
{
- _glfwJoystickElement* button = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.buttons, i);
- buttons[i] = button->value ? GLFW_PRESS : GLFW_RELEASE;
+ _glfwJoystickElement* element = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.buttons, button);
+ buttons[button] = element->value ? GLFW_PRESS : GLFW_RELEASE;
}
- return numbuttons;
+ // Virtual buttons - Inject data from hats
+ // Each hat is exposed as 4 buttons which exposes 8 directions with concurrent button presses
+
+ const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 }; // Bit fields of button presses for each direction, including nil
+
+ for (i = 0; i < joystick.numHats; i++)
+ {
+ _glfwJoystickElement* hat = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.hats, i);
+ int value = hat->value;
+ if (value < 0 || value > 8) value = 8;
+
+ for (j = 0; j < 4 && button < numbuttons; j++)
+ {
+ buttons[button++] = directions[value] & (1 << j) ? GLFW_PRESS : GLFW_RELEASE;
+ }
+ }
+
+ return button;
}
-
-
diff --git a/src/cocoa_opengl.m b/src/cocoa_opengl.m
index bd3827fc..b04efaee 100644
--- a/src/cocoa_opengl.m
+++ b/src/cocoa_opengl.m
@@ -59,6 +59,7 @@ void _glfwPlatformSwapBuffers(void)
[window->NSGL.context flushBuffer];
}
+
//========================================================================
// Set double buffering swap interval
//========================================================================
@@ -71,6 +72,7 @@ void _glfwPlatformSwapInterval(int interval)
[window->NSGL.context setValues:&sync forParameter:NSOpenGLCPSwapInterval];
}
+
//========================================================================
// Check if an OpenGL extension is available at runtime
//========================================================================
@@ -81,24 +83,26 @@ int _glfwPlatformExtensionSupported(const char* extension)
return GL_FALSE;
}
+
//========================================================================
// Get the function pointer to an OpenGL function
//========================================================================
-void* _glfwPlatformGetProcAddress(const char* procname)
+GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
{
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,
procname,
kCFStringEncodingASCII);
- void* symbol = CFBundleGetFunctionPointerForName(_glfwLibrary.NS.OpenGLFramework,
- symbolName);
+ GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfwLibrary.NSGL.framework,
+ symbolName);
CFRelease(symbolName);
return symbol;
}
+
//========================================================================
// Copies the specified OpenGL state categories from src to dst
//========================================================================
diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h
index d5daf775..97e903d7 100644
--- a/src/cocoa_platform.h
+++ b/src/cocoa_platform.h
@@ -37,13 +37,15 @@
#if defined(__OBJC__)
#import
#else
+#include
typedef void* id;
#endif
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS NS
-#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryNS NS
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL NSGL
+#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS NS
+#define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryNSGL NSGL
//========================================================================
@@ -71,39 +73,55 @@ typedef struct _GLFWcontextNSGL
//------------------------------------------------------------------------
typedef struct _GLFWwindowNS
{
- id window;
+ id object;
id delegate;
+ id view;
unsigned int modifierFlags;
- double fracScrollX;
- double fracScrollY;
} _GLFWwindowNS;
//------------------------------------------------------------------------
-// Platform-specific library global data
+// Platform-specific library global data for Cocoa
//------------------------------------------------------------------------
typedef struct _GLFWlibraryNS
{
struct {
- double t0;
+ double base;
+ double resolution;
} timer;
- // dlopen handle for dynamically loading OpenGL extension entry points
- void* OpenGLFramework;
- GLboolean unbundled;
- id desktopMode;
- id delegate;
- id autoreleasePool;
+ CGDisplayModeRef desktopMode;
+ CGEventSourceRef eventSource;
+ id delegate;
+ id autoreleasePool;
+
+ char* clipboardString;
} _GLFWlibraryNS;
+//------------------------------------------------------------------------
+// Platform-specific library global data for NSGL
+//------------------------------------------------------------------------
+typedef struct _GLFWlibraryNSGL
+{
+ // dlopen handle for dynamically loading OpenGL extension entry points
+ void* framework;
+} _GLFWlibraryNSGL;
+
+
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
+// Time
+void _glfwInitTimer(void);
+
// Joystick input
void _glfwInitJoysticks(void);
void _glfwTerminateJoysticks(void);
+// Fullscreen
+GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate);
+void _glfwRestoreVideoMode(void);
#endif // _platform_h_
diff --git a/src/cocoa_time.c b/src/cocoa_time.c
new file mode 100644
index 00000000..745b4239
--- /dev/null
+++ b/src/cocoa_time.c
@@ -0,0 +1,87 @@
+//========================================================================
+// GLFW - An OpenGL library
+// Platform: Cocoa/NSOpenGL
+// API Version: 3.0
+// WWW: http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2009-2010 Camilla Berglund
+//
+// 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.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include
+
+
+//========================================================================
+// Return raw time
+//========================================================================
+
+static uint64_t getRawTime(void)
+{
+ return mach_absolute_time();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Initialise timer
+//========================================================================
+
+void _glfwInitTimer(void)
+{
+ mach_timebase_info_data_t info;
+ mach_timebase_info(&info);
+
+ _glfwLibrary.NS.timer.resolution = (double) info.numer / (info.denom * 1.0e9);
+ _glfwLibrary.NS.timer.base = getRawTime();
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Return timer value in seconds
+//========================================================================
+
+double _glfwPlatformGetTime(void)
+{
+ return (double) (getRawTime() - _glfwLibrary.NS.timer.base) *
+ _glfwLibrary.NS.timer.resolution;
+}
+
+
+//========================================================================
+// Set timer value in seconds
+//========================================================================
+
+void _glfwPlatformSetTime(double time)
+{
+ _glfwLibrary.NS.timer.base = getRawTime() -
+ (uint64_t) (time / _glfwLibrary.NS.timer.resolution);
+}
+
diff --git a/src/cocoa_window.m b/src/cocoa_window.m
index 264ba6ef..3523806a 100644
--- a/src/cocoa_window.m
+++ b/src/cocoa_window.m
@@ -29,6 +29,9 @@
#include "internal.h"
+// Needed for _NSGetProgname
+#include
+
//========================================================================
// Delegate for window related notifications
@@ -66,7 +69,7 @@
[window->NSGL.context update];
NSRect contentRect =
- [window->NS.window contentRectForFrameRect:[window->NS.window frame]];
+ [window->NS.object contentRectForFrameRect:[window->NS.object frame]];
_glfwInputWindowSize(window, contentRect.size.width, contentRect.size.height);
}
@@ -76,7 +79,7 @@
[window->NSGL.context update];
NSRect contentRect =
- [window->NS.window contentRectForFrameRect:[window->NS.window frame]];
+ [window->NS.object contentRectForFrameRect:[window->NS.object frame]];
CGPoint mainScreenOrigin = CGDisplayBounds(CGMainDisplayID()).origin;
double mainScreenHeight = CGDisplayBounds(CGMainDisplayID()).size.height;
@@ -109,6 +112,7 @@
@end
+
//========================================================================
// Delegate for application related notifications
//========================================================================
@@ -130,142 +134,6 @@
@end
-//========================================================================
-// Keyboard symbol translation table
-//========================================================================
-
-// TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject.
-static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] =
-{
- /* 00 */ GLFW_KEY_A,
- /* 01 */ GLFW_KEY_S,
- /* 02 */ GLFW_KEY_D,
- /* 03 */ GLFW_KEY_F,
- /* 04 */ GLFW_KEY_H,
- /* 05 */ GLFW_KEY_G,
- /* 06 */ GLFW_KEY_Z,
- /* 07 */ GLFW_KEY_X,
- /* 08 */ GLFW_KEY_C,
- /* 09 */ GLFW_KEY_V,
- /* 0a */ GLFW_KEY_GRAVE_ACCENT,
- /* 0b */ GLFW_KEY_B,
- /* 0c */ GLFW_KEY_Q,
- /* 0d */ GLFW_KEY_W,
- /* 0e */ GLFW_KEY_E,
- /* 0f */ GLFW_KEY_R,
- /* 10 */ GLFW_KEY_Y,
- /* 11 */ GLFW_KEY_T,
- /* 12 */ GLFW_KEY_1,
- /* 13 */ GLFW_KEY_2,
- /* 14 */ GLFW_KEY_3,
- /* 15 */ GLFW_KEY_4,
- /* 16 */ GLFW_KEY_6,
- /* 17 */ GLFW_KEY_5,
- /* 18 */ GLFW_KEY_EQUAL,
- /* 19 */ GLFW_KEY_9,
- /* 1a */ GLFW_KEY_7,
- /* 1b */ GLFW_KEY_MINUS,
- /* 1c */ GLFW_KEY_8,
- /* 1d */ GLFW_KEY_0,
- /* 1e */ GLFW_KEY_RIGHT_BRACKET,
- /* 1f */ GLFW_KEY_O,
- /* 20 */ GLFW_KEY_U,
- /* 21 */ GLFW_KEY_LEFT_BRACKET,
- /* 22 */ GLFW_KEY_I,
- /* 23 */ GLFW_KEY_P,
- /* 24 */ GLFW_KEY_ENTER,
- /* 25 */ GLFW_KEY_L,
- /* 26 */ GLFW_KEY_J,
- /* 27 */ GLFW_KEY_APOSTROPHE,
- /* 28 */ GLFW_KEY_K,
- /* 29 */ GLFW_KEY_SEMICOLON,
- /* 2a */ GLFW_KEY_BACKSLASH,
- /* 2b */ GLFW_KEY_COMMA,
- /* 2c */ GLFW_KEY_SLASH,
- /* 2d */ GLFW_KEY_N,
- /* 2e */ GLFW_KEY_M,
- /* 2f */ GLFW_KEY_PERIOD,
- /* 30 */ GLFW_KEY_TAB,
- /* 31 */ GLFW_KEY_SPACE,
- /* 32 */ GLFW_KEY_WORLD_1,
- /* 33 */ GLFW_KEY_BACKSPACE,
- /* 34 */ -1,
- /* 35 */ GLFW_KEY_ESCAPE,
- /* 36 */ GLFW_KEY_RIGHT_SUPER,
- /* 37 */ GLFW_KEY_LEFT_SUPER,
- /* 38 */ GLFW_KEY_LEFT_SHIFT,
- /* 39 */ GLFW_KEY_CAPS_LOCK,
- /* 3a */ GLFW_KEY_LEFT_ALT,
- /* 3b */ GLFW_KEY_LEFT_CONTROL,
- /* 3c */ GLFW_KEY_RIGHT_SHIFT,
- /* 3d */ GLFW_KEY_RIGHT_ALT,
- /* 3e */ GLFW_KEY_RIGHT_CONTROL,
- /* 3f */ -1, /* Function */
- /* 40 */ GLFW_KEY_F17,
- /* 41 */ GLFW_KEY_KP_DECIMAL,
- /* 42 */ -1,
- /* 43 */ GLFW_KEY_KP_MULTIPLY,
- /* 44 */ -1,
- /* 45 */ GLFW_KEY_KP_ADD,
- /* 46 */ -1,
- /* 47 */ GLFW_KEY_NUM_LOCK, /* Really KeypadClear... */
- /* 48 */ -1, /* VolumeUp */
- /* 49 */ -1, /* VolumeDown */
- /* 4a */ -1, /* Mute */
- /* 4b */ GLFW_KEY_KP_DIVIDE,
- /* 4c */ GLFW_KEY_KP_ENTER,
- /* 4d */ -1,
- /* 4e */ GLFW_KEY_KP_SUBTRACT,
- /* 4f */ GLFW_KEY_F18,
- /* 50 */ GLFW_KEY_F19,
- /* 51 */ GLFW_KEY_KP_EQUAL,
- /* 52 */ GLFW_KEY_KP_0,
- /* 53 */ GLFW_KEY_KP_1,
- /* 54 */ GLFW_KEY_KP_2,
- /* 55 */ GLFW_KEY_KP_3,
- /* 56 */ GLFW_KEY_KP_4,
- /* 57 */ GLFW_KEY_KP_5,
- /* 58 */ GLFW_KEY_KP_6,
- /* 59 */ GLFW_KEY_KP_7,
- /* 5a */ GLFW_KEY_F20,
- /* 5b */ GLFW_KEY_KP_8,
- /* 5c */ GLFW_KEY_KP_9,
- /* 5d */ -1,
- /* 5e */ -1,
- /* 5f */ -1,
- /* 60 */ GLFW_KEY_F5,
- /* 61 */ GLFW_KEY_F6,
- /* 62 */ GLFW_KEY_F7,
- /* 63 */ GLFW_KEY_F3,
- /* 64 */ GLFW_KEY_F8,
- /* 65 */ GLFW_KEY_F9,
- /* 66 */ -1,
- /* 67 */ GLFW_KEY_F11,
- /* 68 */ -1,
- /* 69 */ GLFW_KEY_F13,
- /* 6a */ GLFW_KEY_F16,
- /* 6b */ GLFW_KEY_F14,
- /* 6c */ -1,
- /* 6d */ GLFW_KEY_F10,
- /* 6e */ -1,
- /* 6f */ GLFW_KEY_F12,
- /* 70 */ -1,
- /* 71 */ GLFW_KEY_F15,
- /* 72 */ GLFW_KEY_INSERT, /* Really Help... */
- /* 73 */ GLFW_KEY_HOME,
- /* 74 */ GLFW_KEY_PAGE_UP,
- /* 75 */ GLFW_KEY_DELETE,
- /* 76 */ GLFW_KEY_F4,
- /* 77 */ GLFW_KEY_END,
- /* 78 */ GLFW_KEY_F2,
- /* 79 */ GLFW_KEY_PAGE_DOWN,
- /* 7a */ GLFW_KEY_F1,
- /* 7b */ GLFW_KEY_LEFT,
- /* 7c */ GLFW_KEY_RIGHT,
- /* 7d */ GLFW_KEY_DOWN,
- /* 7e */ GLFW_KEY_UP,
- /* 7f */ -1,
-};
//========================================================================
// Converts a Mac OS X keycode to a GLFW keycode
@@ -273,15 +141,150 @@ static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] =
static int convertMacKeyCode(unsigned int macKeyCode)
{
+ // Keyboard symbol translation table
+ // TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject.
+ static const unsigned int table[128] =
+ {
+ /* 00 */ GLFW_KEY_A,
+ /* 01 */ GLFW_KEY_S,
+ /* 02 */ GLFW_KEY_D,
+ /* 03 */ GLFW_KEY_F,
+ /* 04 */ GLFW_KEY_H,
+ /* 05 */ GLFW_KEY_G,
+ /* 06 */ GLFW_KEY_Z,
+ /* 07 */ GLFW_KEY_X,
+ /* 08 */ GLFW_KEY_C,
+ /* 09 */ GLFW_KEY_V,
+ /* 0a */ GLFW_KEY_GRAVE_ACCENT,
+ /* 0b */ GLFW_KEY_B,
+ /* 0c */ GLFW_KEY_Q,
+ /* 0d */ GLFW_KEY_W,
+ /* 0e */ GLFW_KEY_E,
+ /* 0f */ GLFW_KEY_R,
+ /* 10 */ GLFW_KEY_Y,
+ /* 11 */ GLFW_KEY_T,
+ /* 12 */ GLFW_KEY_1,
+ /* 13 */ GLFW_KEY_2,
+ /* 14 */ GLFW_KEY_3,
+ /* 15 */ GLFW_KEY_4,
+ /* 16 */ GLFW_KEY_6,
+ /* 17 */ GLFW_KEY_5,
+ /* 18 */ GLFW_KEY_EQUAL,
+ /* 19 */ GLFW_KEY_9,
+ /* 1a */ GLFW_KEY_7,
+ /* 1b */ GLFW_KEY_MINUS,
+ /* 1c */ GLFW_KEY_8,
+ /* 1d */ GLFW_KEY_0,
+ /* 1e */ GLFW_KEY_RIGHT_BRACKET,
+ /* 1f */ GLFW_KEY_O,
+ /* 20 */ GLFW_KEY_U,
+ /* 21 */ GLFW_KEY_LEFT_BRACKET,
+ /* 22 */ GLFW_KEY_I,
+ /* 23 */ GLFW_KEY_P,
+ /* 24 */ GLFW_KEY_ENTER,
+ /* 25 */ GLFW_KEY_L,
+ /* 26 */ GLFW_KEY_J,
+ /* 27 */ GLFW_KEY_APOSTROPHE,
+ /* 28 */ GLFW_KEY_K,
+ /* 29 */ GLFW_KEY_SEMICOLON,
+ /* 2a */ GLFW_KEY_BACKSLASH,
+ /* 2b */ GLFW_KEY_COMMA,
+ /* 2c */ GLFW_KEY_SLASH,
+ /* 2d */ GLFW_KEY_N,
+ /* 2e */ GLFW_KEY_M,
+ /* 2f */ GLFW_KEY_PERIOD,
+ /* 30 */ GLFW_KEY_TAB,
+ /* 31 */ GLFW_KEY_SPACE,
+ /* 32 */ GLFW_KEY_WORLD_1,
+ /* 33 */ GLFW_KEY_BACKSPACE,
+ /* 34 */ -1,
+ /* 35 */ GLFW_KEY_ESCAPE,
+ /* 36 */ GLFW_KEY_RIGHT_SUPER,
+ /* 37 */ GLFW_KEY_LEFT_SUPER,
+ /* 38 */ GLFW_KEY_LEFT_SHIFT,
+ /* 39 */ GLFW_KEY_CAPS_LOCK,
+ /* 3a */ GLFW_KEY_LEFT_ALT,
+ /* 3b */ GLFW_KEY_LEFT_CONTROL,
+ /* 3c */ GLFW_KEY_RIGHT_SHIFT,
+ /* 3d */ GLFW_KEY_RIGHT_ALT,
+ /* 3e */ GLFW_KEY_RIGHT_CONTROL,
+ /* 3f */ -1, /* Function */
+ /* 40 */ GLFW_KEY_F17,
+ /* 41 */ GLFW_KEY_KP_DECIMAL,
+ /* 42 */ -1,
+ /* 43 */ GLFW_KEY_KP_MULTIPLY,
+ /* 44 */ -1,
+ /* 45 */ GLFW_KEY_KP_ADD,
+ /* 46 */ -1,
+ /* 47 */ GLFW_KEY_NUM_LOCK, /* Really KeypadClear... */
+ /* 48 */ -1, /* VolumeUp */
+ /* 49 */ -1, /* VolumeDown */
+ /* 4a */ -1, /* Mute */
+ /* 4b */ GLFW_KEY_KP_DIVIDE,
+ /* 4c */ GLFW_KEY_KP_ENTER,
+ /* 4d */ -1,
+ /* 4e */ GLFW_KEY_KP_SUBTRACT,
+ /* 4f */ GLFW_KEY_F18,
+ /* 50 */ GLFW_KEY_F19,
+ /* 51 */ GLFW_KEY_KP_EQUAL,
+ /* 52 */ GLFW_KEY_KP_0,
+ /* 53 */ GLFW_KEY_KP_1,
+ /* 54 */ GLFW_KEY_KP_2,
+ /* 55 */ GLFW_KEY_KP_3,
+ /* 56 */ GLFW_KEY_KP_4,
+ /* 57 */ GLFW_KEY_KP_5,
+ /* 58 */ GLFW_KEY_KP_6,
+ /* 59 */ GLFW_KEY_KP_7,
+ /* 5a */ GLFW_KEY_F20,
+ /* 5b */ GLFW_KEY_KP_8,
+ /* 5c */ GLFW_KEY_KP_9,
+ /* 5d */ -1,
+ /* 5e */ -1,
+ /* 5f */ -1,
+ /* 60 */ GLFW_KEY_F5,
+ /* 61 */ GLFW_KEY_F6,
+ /* 62 */ GLFW_KEY_F7,
+ /* 63 */ GLFW_KEY_F3,
+ /* 64 */ GLFW_KEY_F8,
+ /* 65 */ GLFW_KEY_F9,
+ /* 66 */ -1,
+ /* 67 */ GLFW_KEY_F11,
+ /* 68 */ -1,
+ /* 69 */ GLFW_KEY_F13,
+ /* 6a */ GLFW_KEY_F16,
+ /* 6b */ GLFW_KEY_F14,
+ /* 6c */ -1,
+ /* 6d */ GLFW_KEY_F10,
+ /* 6e */ -1,
+ /* 6f */ GLFW_KEY_F12,
+ /* 70 */ -1,
+ /* 71 */ GLFW_KEY_F15,
+ /* 72 */ GLFW_KEY_INSERT, /* Really Help... */
+ /* 73 */ GLFW_KEY_HOME,
+ /* 74 */ GLFW_KEY_PAGE_UP,
+ /* 75 */ GLFW_KEY_DELETE,
+ /* 76 */ GLFW_KEY_F4,
+ /* 77 */ GLFW_KEY_END,
+ /* 78 */ GLFW_KEY_F2,
+ /* 79 */ GLFW_KEY_PAGE_DOWN,
+ /* 7a */ GLFW_KEY_F1,
+ /* 7b */ GLFW_KEY_LEFT,
+ /* 7c */ GLFW_KEY_RIGHT,
+ /* 7d */ GLFW_KEY_DOWN,
+ /* 7e */ GLFW_KEY_UP,
+ /* 7f */ -1,
+ };
+
if (macKeyCode >= 128)
return -1;
// This treats keycodes as *positional*; that is, we'll return 'a'
// for the key left of 's', even on an AZERTY keyboard. The charInput
// function should still get 'q' though.
- return MAC_TO_GLFW_KEYCODE_MAPPING[macKeyCode];
+ return table[macKeyCode];
}
+
//========================================================================
// Content view class for the GLFW window
//========================================================================
@@ -289,6 +292,7 @@ static int convertMacKeyCode(unsigned int macKeyCode)
@interface GLFWContentView : NSView
{
_GLFWwindow* window;
+ NSTrackingArea* trackingArea;
}
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow;
@@ -301,11 +305,22 @@ static int convertMacKeyCode(unsigned int macKeyCode)
{
self = [super init];
if (self != nil)
+ {
window = initWindow;
+ trackingArea = nil;
+
+ [self updateTrackingAreas];
+ }
return self;
}
+-(void)dealloc
+{
+ [trackingArea release];
+ [super dealloc];
+}
+
- (BOOL)isOpaque
{
return YES;
@@ -342,12 +357,13 @@ static int convertMacKeyCode(unsigned int macKeyCode)
_glfwInputCursorMotion(window, [event deltaX], [event deltaY]);
else
{
- NSPoint p = [event locationInWindow];
+ const NSPoint p = [event locationInWindow];
// Cocoa coordinate system has origin at lower left
- p.y = [[window->NS.window contentView] bounds].size.height - p.y;
+ const int x = lround(floor(p.x));
+ const int y = window->height - lround(ceil(p.y));
- _glfwInputCursorMotion(window, p.x, p.y);
+ _glfwInputCursorMotion(window, x, y);
}
}
@@ -381,15 +397,45 @@ static int convertMacKeyCode(unsigned int macKeyCode)
_glfwInputMouseClick(window, [event buttonNumber], GLFW_RELEASE);
}
+- (void)mouseExited:(NSEvent *)event
+{
+ _glfwInputCursorEnter(window, GL_FALSE);
+}
+
+- (void)mouseEntered:(NSEvent *)event
+{
+ _glfwInputCursorEnter(window, GL_TRUE);
+}
+
+- (void)updateTrackingAreas
+{
+ if (trackingArea != nil)
+ {
+ [self removeTrackingArea:trackingArea];
+ [trackingArea release];
+ }
+
+ NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited |
+ NSTrackingActiveAlways |
+ NSTrackingInVisibleRect;
+
+ trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
+ options:options
+ owner:self
+ userInfo:nil];
+
+ [self addTrackingArea:trackingArea];
+}
+
- (void)keyDown:(NSEvent *)event
{
NSUInteger i, length;
NSString* characters;
- int code = convertMacKeyCode([event keyCode]);
+ int key = convertMacKeyCode([event keyCode]);
- if (code != -1)
+ if (key != -1)
{
- _glfwInputKey(window, code, GLFW_PRESS);
+ _glfwInputKey(window, key, GLFW_PRESS);
if ([event modifierFlags] & NSCommandKeyMask)
{
@@ -409,7 +455,7 @@ static int convertMacKeyCode(unsigned int macKeyCode)
- (void)flagsChanged:(NSEvent *)event
{
- int mode;
+ int mode, key;
unsigned int newModifierFlags =
[event modifierFlags] | NSDeviceIndependentModifierFlagsMask;
@@ -419,30 +465,193 @@ static int convertMacKeyCode(unsigned int macKeyCode)
mode = GLFW_RELEASE;
window->NS.modifierFlags = newModifierFlags;
- _glfwInputKey(window, MAC_TO_GLFW_KEYCODE_MAPPING[[event keyCode]], mode);
+
+ key = convertMacKeyCode([event keyCode]);
+ if (key != -1)
+ _glfwInputKey(window, key, mode);
}
- (void)keyUp:(NSEvent *)event
{
- int code = convertMacKeyCode([event keyCode]);
- if (code != -1)
- _glfwInputKey(window, code, GLFW_RELEASE);
+ int key = convertMacKeyCode([event keyCode]);
+ if (key != -1)
+ _glfwInputKey(window, key, GLFW_RELEASE);
}
- (void)scrollWheel:(NSEvent *)event
{
- double deltaX = window->NS.fracScrollX + [event deltaX];
- double deltaY = window->NS.fracScrollY + [event deltaY];
+ double deltaX = [event deltaX];
+ double deltaY = [event deltaY];
- if ((int) deltaX || (int) deltaY)
- _glfwInputScroll(window, (int) deltaX, (int) deltaY);
-
- window->NS.fracScrollX = (int) (deltaX - floor(deltaX));
- window->NS.fracScrollY = (int) (deltaY - floor(deltaY));
+ if (fabs(deltaX) > 0.0 || fabs(deltaY) > 0.0)
+ _glfwInputScroll(window, deltaX, deltaY);
}
@end
+
+//========================================================================
+// GLFW application class
+//========================================================================
+
+@interface GLFWApplication : NSApplication
+@end
+
+@implementation GLFWApplication
+
+// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
+// This works around an AppKit bug, where key up events while holding
+// down the command key don't get sent to the key window.
+- (void)sendEvent:(NSEvent *)event
+{
+ if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask))
+ [[self keyWindow] sendEvent:event];
+ else
+ [super sendEvent:event];
+}
+
+@end
+
+
+//========================================================================
+// Try to figure out what the calling application is called
+//========================================================================
+
+static NSString* findAppName(void)
+{
+ unsigned int i;
+ NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
+
+ // Keys to search for as potential application names
+ NSString* GLFWNameKeys[] =
+ {
+ @"CFBundleDisplayName",
+ @"CFBundleName",
+ @"CFBundleExecutable",
+ };
+
+ for (i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++)
+ {
+ id name = [infoDictionary objectForKey:GLFWNameKeys[i]];
+ if (name &&
+ [name isKindOfClass:[NSString class]] &&
+ ![@"" isEqualToString:name])
+ {
+ return name;
+ }
+ }
+
+ // If we get here, we're unbundled
+ ProcessSerialNumber psn = { 0, kCurrentProcess };
+ TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+
+ // Having the app in front of the terminal window is also generally
+ // handy. There is an NSApplication API to do this, but...
+ SetFrontProcess(&psn);
+
+ char** progname = _NSGetProgname();
+ if (progname && *progname)
+ {
+ // TODO: UTF-8?
+ return [NSString stringWithUTF8String:*progname];
+ }
+
+ // Really shouldn't get here
+ return @"GLFW Application";
+}
+
+
+//========================================================================
+// Set up the menu bar (manually)
+// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
+// could go away at any moment, lots of stuff that really should be
+// localize(d|able), etc. Loading a nib would save us this horror, but that
+// doesn't seem like a good thing to require of GLFW's clients.
+//========================================================================
+
+static void createMenuBar(void)
+{
+ NSString* appName = findAppName();
+
+ NSMenu* bar = [[NSMenu alloc] init];
+ [NSApp setMainMenu:bar];
+
+ NSMenuItem* appMenuItem =
+ [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
+ NSMenu* appMenu = [[NSMenu alloc] init];
+ [appMenuItem setSubmenu:appMenu];
+
+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]
+ action:@selector(orderFrontStandardAboutPanel:)
+ keyEquivalent:@""];
+ [appMenu addItem:[NSMenuItem separatorItem]];
+ NSMenu* servicesMenu = [[NSMenu alloc] init];
+ [NSApp setServicesMenu:servicesMenu];
+ [[appMenu addItemWithTitle:@"Services"
+ action:NULL
+ keyEquivalent:@""] setSubmenu:servicesMenu];
+ [appMenu addItem:[NSMenuItem separatorItem]];
+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]
+ action:@selector(hide:)
+ keyEquivalent:@"h"];
+ [[appMenu addItemWithTitle:@"Hide Others"
+ action:@selector(hideOtherApplications:)
+ keyEquivalent:@"h"]
+ setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];
+ [appMenu addItemWithTitle:@"Show All"
+ action:@selector(unhideAllApplications:)
+ keyEquivalent:@""];
+ [appMenu addItem:[NSMenuItem separatorItem]];
+ [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]
+ action:@selector(terminate:)
+ keyEquivalent:@"q"];
+
+ NSMenuItem* windowMenuItem =
+ [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
+ NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
+ [NSApp setWindowsMenu:windowMenu];
+ [windowMenuItem setSubmenu:windowMenu];
+
+ [windowMenu addItemWithTitle:@"Miniaturize"
+ action:@selector(performMiniaturize:)
+ keyEquivalent:@"m"];
+ [windowMenu addItemWithTitle:@"Zoom"
+ action:@selector(performZoom:)
+ keyEquivalent:@""];
+ [windowMenu addItem:[NSMenuItem separatorItem]];
+ [windowMenu addItemWithTitle:@"Bring All to Front"
+ action:@selector(arrangeInFront:)
+ keyEquivalent:@""];
+
+ // Prior to Snow Leopard, we need to use this oddly-named semi-private API
+ // to get the application menu working properly.
+ [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu];
+}
+
+
+//========================================================================
+// Initialize the Cocoa Application Kit
+//========================================================================
+
+static GLboolean initializeAppKit(void)
+{
+ if (NSApp)
+ return GL_TRUE;
+
+ // Implicitly create shared NSApplication instance
+ [GLFWApplication sharedApplication];
+
+ // Setting up the menu bar must go between sharedApplication
+ // above and finishLaunching below, in order to properly emulate the
+ // behavior of NSApplicationMain
+ createMenuBar();
+
+ [NSApp finishLaunching];
+
+ return GL_TRUE;
+}
+
+
//========================================================================
// Create the Cocoa window
//========================================================================
@@ -463,29 +672,34 @@ static GLboolean createWindow(_GLFWwindow* window,
else
styleMask = NSBorderlessWindowMask;
- window->NS.window = [[NSWindow alloc]
+ window->NS.object = [[NSWindow alloc]
initWithContentRect:NSMakeRect(0, 0, window->width, window->height)
styleMask:styleMask
backing:NSBackingStoreBuffered
defer:NO];
- if (window->NS.window == nil)
+ if (window->NS.object == nil)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
"Cocoa/NSOpenGL: Failed to create window");
return GL_FALSE;
}
- [window->NS.window setTitle:[NSString stringWithUTF8String:wndconfig->title]];
- [window->NS.window setContentView:[[GLFWContentView alloc]
- initWithGlfwWindow:window]];
- [window->NS.window setDelegate:window->NS.delegate];
- [window->NS.window setAcceptsMouseMovedEvents:YES];
- [window->NS.window center];
+ window->NS.view = [[GLFWContentView alloc] initWithGlfwWindow:window];
+
+ [window->NS.object setTitle:[NSString stringWithUTF8String:wndconfig->title]];
+ [window->NS.object setContentView:window->NS.view];
+ [window->NS.object setDelegate:window->NS.delegate];
+ [window->NS.object setAcceptsMouseMovedEvents:YES];
+ [window->NS.object center];
+
+ if ([window->NS.object respondsToSelector:@selector(setRestorable)])
+ [window->NS.object setRestorable:NO];
return GL_TRUE;
}
+
//========================================================================
// Create the OpenGL context
//========================================================================
@@ -514,14 +728,23 @@ static GLboolean createContext(_GLFWwindow* window,
return GL_FALSE;
}
- if (wndconfig->glProfile)
+ if (wndconfig->glMajor > 2)
{
- // Fail if a profile other than core was explicitly selected
+ if (!wndconfig->glForward)
+ {
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE,
+ "Cocoa/NSOpenGL: The targeted version of Mac OS X "
+ "only supports OpenGL 3.2 contexts if they are "
+ "forward-compatible");
+ return GL_FALSE;
+ }
+
if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE)
{
_glfwSetError(GLFW_VERSION_UNAVAILABLE,
"Cocoa/NSOpenGL: The targeted version of Mac OS X "
- "only supports the OpenGL core profile");
+ "only supports OpenGL 3.2 contexts if they use the "
+ "core profile");
return GL_FALSE;
}
}
@@ -549,13 +772,12 @@ static GLboolean createContext(_GLFWwindow* window,
#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); }
// Arbitrary array size here
- NSOpenGLPixelFormatAttribute attributes[24];
+ NSOpenGLPixelFormatAttribute attributes[40];
ADD_ATTR(NSOpenGLPFADoubleBuffer);
if (wndconfig->mode == GLFW_FULLSCREEN)
{
- ADD_ATTR(NSOpenGLPFAFullScreen);
ADD_ATTR(NSOpenGLPFANoRecovery);
ADD_ATTR2(NSOpenGLPFAScreenMask,
CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID()));
@@ -587,7 +809,7 @@ static GLboolean createContext(_GLFWwindow* window,
ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
if (fbconfig->stereo)
- ADD_ATTR(NSOpenGLPFAStereo );
+ ADD_ATTR(NSOpenGLPFAStereo);
if (fbconfig->samples > 0)
{
@@ -605,7 +827,7 @@ static GLboolean createContext(_GLFWwindow* window,
if (window->NSGL.pixelFormat == nil)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
- "Cocoa/NSOpenGL: Failed to create pixel format");
+ "Cocoa/NSOpenGL: Failed to create OpenGL pixel format");
return GL_FALSE;
}
@@ -638,9 +860,14 @@ static GLboolean createContext(_GLFWwindow* window,
//========================================================================
int _glfwPlatformOpenWindow(_GLFWwindow* window,
- const _GLFWwndconfig *wndconfig,
- const _GLFWfbconfig *fbconfig)
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWfbconfig* fbconfig)
{
+ if (!initializeAppKit())
+ return GL_FALSE;
+
+ window->resizable = wndconfig->resizable;
+
// We can only have one application delegate, but we only allocate it the
// first time we create a window to keep all window code in this file
if (_glfwLibrary.NS.delegate == nil)
@@ -672,56 +899,31 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
else if (colorBits < 15)
colorBits = 15;
- // Ignored hints:
- // OpenGLMajor, OpenGLMinor, OpenGLForward:
- // pending Mac OS X support for OpenGL 3.x
- // OpenGLDebug
- // pending it meaning anything on Mac OS X
-
// Don't use accumulation buffer support; it's not accelerated
// Aux buffers probably aren't accelerated either
- CFDictionaryRef fullscreenMode = NULL;
- if (wndconfig->mode == GLFW_FULLSCREEN)
- {
- // I think it's safe to pass 0 to the refresh rate for this function
- // rather than conditionalizing the code to call the version which
- // doesn't specify refresh...
- fullscreenMode =
- CGDisplayBestModeForParametersAndRefreshRateWithProperty(
- CGMainDisplayID(),
- colorBits + fbconfig->alphaBits,
- window->width, window->height,
- wndconfig->refreshRate,
- // Controversial, see macosx_fullscreen.m for discussion
- kCGDisplayModeIsSafeForHardware,
- NULL);
-
- window->width =
- [[(id)fullscreenMode objectForKey:(id)kCGDisplayWidth] intValue];
- window->height =
- [[(id)fullscreenMode objectForKey:(id)kCGDisplayHeight] intValue];
- }
-
if (!createWindow(window, wndconfig))
return GL_FALSE;
if (!createContext(window, wndconfig, fbconfig))
return GL_FALSE;
- [window->NS.window makeKeyAndOrderFront:nil];
- [window->NSGL.context setView:[window->NS.window contentView]];
+ [window->NS.object makeKeyAndOrderFront:nil];
+ [window->NSGL.context setView:[window->NS.object contentView]];
if (wndconfig->mode == GLFW_FULLSCREEN)
{
- CGCaptureAllDisplays();
- CGDisplaySwitchToMode(CGMainDisplayID(), fullscreenMode);
- }
+ int bpp = colorBits + fbconfig->alphaBits;
- if (wndconfig->mode == GLFW_FULLSCREEN)
- {
- // TODO: Make this work on pre-Leopard systems
- [[window->NS.window contentView] enterFullScreenMode:[NSScreen mainScreen]
+ if (!_glfwSetVideoMode(&window->width,
+ &window->height,
+ &bpp,
+ &window->refreshRate))
+ {
+ return GL_FALSE;
+ }
+
+ [[window->NS.object contentView] enterFullScreenMode:[NSScreen mainScreen]
withOptions:nil];
}
@@ -743,15 +945,13 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
void _glfwPlatformCloseWindow(_GLFWwindow* window)
{
- [window->NS.window orderOut:nil];
+ [window->NS.object orderOut:nil];
if (window->mode == GLFW_FULLSCREEN)
{
- [[window->NS.window contentView] exitFullScreenModeWithOptions:nil];
+ [[window->NS.object contentView] exitFullScreenModeWithOptions:nil];
- CGDisplaySwitchToMode(CGMainDisplayID(),
- (CFDictionaryRef) _glfwLibrary.NS.desktopMode);
- CGReleaseAllDisplays();
+ _glfwRestoreVideoMode();
}
[window->NSGL.pixelFormat release];
@@ -761,34 +961,40 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window)
[window->NSGL.context release];
window->NSGL.context = nil;
- [window->NS.window setDelegate:nil];
+ [window->NS.object setDelegate:nil];
[window->NS.delegate release];
window->NS.delegate = nil;
- [window->NS.window close];
- window->NS.window = nil;
+ [window->NS.view release];
+ window->NS.view = nil;
+
+ [window->NS.object close];
+ window->NS.object = nil;
// TODO: Probably more cleanup
}
+
//========================================================================
// Set the window title
//========================================================================
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title)
{
- [window->NS.window setTitle:[NSString stringWithUTF8String:title]];
+ [window->NS.object setTitle:[NSString stringWithUTF8String:title]];
}
+
//========================================================================
// Set the window size
//========================================================================
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
- [window->NS.window setContentSize:NSMakeSize(width, height)];
+ [window->NS.object setContentSize:NSMakeSize(width, height)];
}
+
//========================================================================
// Set the window position
//========================================================================
@@ -796,37 +1002,40 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y)
{
NSRect contentRect =
- [window->NS.window contentRectForFrameRect:[window->NS.window frame]];
+ [window->NS.object contentRectForFrameRect:[window->NS.object frame]];
// We assume here that the client code wants to position the window within the
// screen the window currently occupies
- NSRect screenRect = [[window->NS.window screen] visibleFrame];
+ NSRect screenRect = [[window->NS.object screen] visibleFrame];
contentRect.origin = NSMakePoint(screenRect.origin.x + x,
screenRect.origin.y + screenRect.size.height -
y - contentRect.size.height);
- [window->NS.window setFrame:[window->NS.window frameRectForContentRect:contentRect]
+ [window->NS.object setFrame:[window->NS.object frameRectForContentRect:contentRect]
display:YES];
}
+
//========================================================================
// Iconify the window
//========================================================================
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
- [window->NS.window miniaturize:nil];
+ [window->NS.object miniaturize:nil];
}
+
//========================================================================
// Restore (un-iconify) the window
//========================================================================
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
- [window->NS.window deminiaturize:nil];
+ [window->NS.object deminiaturize:nil];
}
+
//========================================================================
// Write back window parameters into GLFW window structure
//========================================================================
@@ -901,6 +1110,7 @@ void _glfwPlatformRefreshWindowParams(void)
window->glDebug = GL_FALSE;
}
+
//========================================================================
// Poll for new window and input events
//========================================================================
@@ -925,6 +1135,7 @@ void _glfwPlatformPollEvents(void)
_glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init];
}
+
//========================================================================
// Wait for new window and input events
//========================================================================
@@ -943,38 +1154,32 @@ void _glfwPlatformWaitEvents( void )
_glfwPlatformPollEvents();
}
+
//========================================================================
-// Set physical mouse cursor position
+// Set physical cursor position
//========================================================================
-void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y)
+void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y)
{
- // The library seems to assume that after calling this the mouse won't move,
- // but obviously it will, and escape the app's window, and activate other apps,
- // and other badness in pain. I think the API's just silly, but maybe I'm
- // misunderstanding it...
-
- // Also, (x, y) are window coords...
-
- // Also, it doesn't seem possible to write this robustly without
- // calculating the maximum y coordinate of all screens, since Cocoa's
- // "global coordinates" are upside down from CG's...
-
- // Without this (once per app run, but it's convenient to do it here)
- // events will be suppressed for a default of 0.25 seconds after we
- // move the cursor.
- CGSetLocalEventsSuppressionInterval(0.0);
-
- NSPoint localPoint = NSMakePoint(x, y);
- NSPoint globalPoint = [window->NS.window convertBaseToScreen:localPoint];
- CGPoint mainScreenOrigin = CGDisplayBounds(CGMainDisplayID()).origin;
- double mainScreenHeight = CGDisplayBounds(CGMainDisplayID()).size.height;
- CGPoint targetPoint = CGPointMake(globalPoint.x - mainScreenOrigin.x,
- mainScreenHeight - globalPoint.y -
- mainScreenOrigin.y);
- CGDisplayMoveCursorToPoint(CGMainDisplayID(), targetPoint);
+ if (window->mode == GLFW_FULLSCREEN)
+ {
+ NSPoint globalPoint = NSMakePoint(x, y);
+ CGDisplayMoveCursorToPoint(CGMainDisplayID(), globalPoint);
+ }
+ else
+ {
+ NSPoint localPoint = NSMakePoint(x, window->height - y - 1);
+ NSPoint globalPoint = [window->NS.object convertBaseToScreen:localPoint];
+ CGPoint mainScreenOrigin = CGDisplayBounds(CGMainDisplayID()).origin;
+ double mainScreenHeight = CGDisplayBounds(CGMainDisplayID()).size.height;
+ CGPoint targetPoint = CGPointMake(globalPoint.x - mainScreenOrigin.x,
+ mainScreenHeight - globalPoint.y -
+ mainScreenOrigin.y);
+ CGDisplayMoveCursorToPoint(CGMainDisplayID(), targetPoint);
+ }
}
+
//========================================================================
// Set physical mouse cursor mode
//========================================================================
diff --git a/src/config.h.in b/src/config.h.in
index f966356c..01d541a2 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -42,28 +42,29 @@
// Define this to 1 if building GLFW for Cocoa/NSOpenGL
#cmakedefine _GLFW_COCOA_NSGL
+// Define this to 1 if building as a shared library / dynamic library / DLL
+#cmakedefine _GLFW_BUILD_DLL
+
+// Define this to 1 to disable dynamic loading of winmm
+#cmakedefine _GLFW_NO_DLOAD_WINMM
+
// Define this to 1 if XRandR is available
-#cmakedefine _GLFW_HAS_XRANDR 1
+#cmakedefine _GLFW_HAS_XRANDR
// Define this to 1 if Xf86VidMode is available
-#cmakedefine _GLFW_HAS_XF86VIDMODE 1
+#cmakedefine _GLFW_HAS_XF86VIDMODE
// Define this to 1 if Xkb is available
-#cmakedefine _GLFW_HAS_XKB 1
+#cmakedefine _GLFW_HAS_XKB
// Define this to 1 if glXGetProcAddress is available
-#cmakedefine _GLFW_HAS_GLXGETPROCADDRESS 1
+#cmakedefine _GLFW_HAS_GLXGETPROCADDRESS
// Define this to 1 if glXGetProcAddressARB is available
-#cmakedefine _GLFW_HAS_GLXGETPROCADDRESSARB 1
+#cmakedefine _GLFW_HAS_GLXGETPROCADDRESSARB
// Define this to 1 if glXGetProcAddressEXT is available
-#cmakedefine _GLFW_HAS_GLXGETPROCADDRESSEXT 1
+#cmakedefine _GLFW_HAS_GLXGETPROCADDRESSEXT
// Define this to 1 if the Linux joystick API is available
-#cmakedefine _GLFW_USE_LINUX_JOYSTICKS 1
-
-// Define this to 1 to not load gdi32.dll dynamically
-#cmakedefine _GLFW_NO_DLOAD_GDI32 1
-// Define this to 1 to not load winmm.dll dynamically
-#cmakedefine _GLFW_NO_DLOAD_WINMM 1
+#cmakedefine _GLFW_USE_LINUX_JOYSTICKS
// The GLFW version as used by glfwGetVersionString
#define _GLFW_VERSION_FULL "@GLFW_VERSION_FULL@"
diff --git a/src/error.c b/src/error.c
index 2b46a72c..062fb76a 100644
--- a/src/error.c
+++ b/src/error.c
@@ -109,6 +109,8 @@ GLFWAPI const char* glfwErrorString(int error)
return "A platform-specific error occurred";
case GLFW_WINDOW_NOT_ACTIVE:
return "The specified window is not active";
+ case GLFW_FORMAT_UNAVAILABLE:
+ return "The requested format is unavailable";
}
return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString";
diff --git a/src/gamma.c b/src/gamma.c
index 34cb22f5..21940b0e 100644
--- a/src/gamma.c
+++ b/src/gamma.c
@@ -112,5 +112,6 @@ GLFWAPI void glfwSetGammaRamp(const GLFWgammaramp* ramp)
_glfwPlatformSetGammaRamp(ramp);
_glfwLibrary.currentRamp = *ramp;
+ _glfwLibrary.rampChanged = GL_TRUE;
}
diff --git a/src/init.c b/src/init.c
index 8a28b5cc..336cfe25 100644
--- a/src/init.c
+++ b/src/init.c
@@ -35,30 +35,6 @@
#include
-//////////////////////////////////////////////////////////////////////////
-////// GLFW internal API //////
-//////////////////////////////////////////////////////////////////////////
-
-//========================================================================
-// Allocate memory using the allocator
-//========================================================================
-
-void* _glfwMalloc(size_t size)
-{
- return _glfwLibrary.allocator.malloc(size);
-}
-
-
-//========================================================================
-// Free memory using the allocator
-//========================================================================
-
-void _glfwFree(void* ptr)
-{
- _glfwLibrary.allocator.free(ptr);
-}
-
-
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
@@ -67,31 +43,13 @@ void _glfwFree(void* ptr)
// Initialize various GLFW state
//========================================================================
-GLFWAPI int glfwInit(GLFWallocator* allocator)
+GLFWAPI int glfwInit(void)
{
if (_glfwInitialized)
return GL_TRUE;
memset(&_glfwLibrary, 0, sizeof(_glfwLibrary));
- if (allocator)
- {
- // Verify that the specified model is complete
- if (!allocator->malloc || !allocator->free)
- {
- _glfwSetError(GLFW_INVALID_VALUE, NULL);
- return GL_FALSE;
- }
-
- _glfwLibrary.allocator = *allocator;
- }
- else
- {
- // Use the libc malloc and free
- _glfwLibrary.allocator.malloc = malloc;
- _glfwLibrary.allocator.free = free;
- }
-
// Not all window hints have zero as their default value, so this
// needs to be here despite the memset above
_glfwSetDefaultWindowHints();
diff --git a/src/input.c b/src/input.c
index 0ad3c1b8..37da571a 100644
--- a/src/input.c
+++ b/src/input.c
@@ -35,37 +35,33 @@
// Sets the cursor mode for the specified window
//========================================================================
-static void setCursorMode(_GLFWwindow* window, int mode)
+static void setCursorMode(_GLFWwindow* window, int newMode)
{
- int centerPosX, centerPosY;
+ int oldMode, centerPosX, centerPosY;
- if (mode != GLFW_CURSOR_NORMAL &&
- mode != GLFW_CURSOR_HIDDEN &&
- mode != GLFW_CURSOR_CAPTURED)
+ if (newMode != GLFW_CURSOR_NORMAL &&
+ newMode != GLFW_CURSOR_HIDDEN &&
+ newMode != GLFW_CURSOR_CAPTURED)
{
_glfwSetError(GLFW_INVALID_ENUM, NULL);
return;
}
- if (window->cursorMode == mode)
+ oldMode = window->cursorMode;
+ if (oldMode == newMode)
return;
centerPosX = window->width / 2;
centerPosY = window->height / 2;
- if (mode == GLFW_CURSOR_CAPTURED)
- _glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY);
- else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
- {
- _glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY);
- _glfwInputCursorMotion(window,
- centerPosX - window->cursorPosX,
- centerPosY - window->cursorPosY);
- }
+ if (oldMode == GLFW_CURSOR_CAPTURED || newMode == GLFW_CURSOR_CAPTURED)
+ _glfwPlatformSetCursorPos(window, centerPosX, centerPosY);
- _glfwPlatformSetCursorMode(window, mode);
+ _glfwPlatformSetCursorMode(window, newMode);
+ window->cursorMode = newMode;
- window->cursorMode = mode;
+ if (oldMode == GLFW_CURSOR_CAPTURED)
+ _glfwInputCursorMotion(window, window->cursorPosX, window->cursorPosY);
}
@@ -167,7 +163,7 @@ void _glfwInputKey(_GLFWwindow* window, int key, int action)
return;
// Register key action
- if(action == GLFW_RELEASE && window->stickyKeys)
+ if (action == GLFW_RELEASE && window->stickyKeys)
window->key[key] = GLFW_STICK;
else
{
@@ -200,7 +196,7 @@ void _glfwInputChar(_GLFWwindow* window, int character)
// Register scroll events
//========================================================================
-void _glfwInputScroll(_GLFWwindow* window, int xoffset, int yoffset)
+void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
{
window->scrollX += xoffset;
window->scrollY += yoffset;
@@ -253,15 +249,26 @@ void _glfwInputCursorMotion(_GLFWwindow* window, int x, int y)
window->cursorPosY = y;
}
- if (_glfwLibrary.mousePosCallback)
+ if (_glfwLibrary.cursorPosCallback)
{
- _glfwLibrary.mousePosCallback(window,
- window->cursorPosX,
- window->cursorPosY);
+ _glfwLibrary.cursorPosCallback(window,
+ window->cursorPosX,
+ window->cursorPosY);
}
}
+//========================================================================
+// Register cursor enter/leave events
+//========================================================================
+
+void _glfwInputCursorEnter(_GLFWwindow* window, int entered)
+{
+ if (_glfwLibrary.cursorEnterCallback)
+ _glfwLibrary.cursorEnterCallback(window, entered);
+}
+
+
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
@@ -351,10 +358,8 @@ GLFWAPI int glfwGetKey(GLFWwindow handle, int key)
return GLFW_RELEASE;
}
- // Is it a valid key?
if (key < 0 || key > GLFW_KEY_LAST)
{
- // TODO: Decide whether key is a value or enum
_glfwSetError(GLFW_INVALID_ENUM,
"glfwGetKey: The specified key is invalid");
return GLFW_RELEASE;
@@ -385,7 +390,6 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow handle, int button)
return GLFW_RELEASE;
}
- // Is it a valid mouse button?
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
{
_glfwSetError(GLFW_INVALID_ENUM,
@@ -408,7 +412,7 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow handle, int button)
// Returns the last reported cursor position for the specified window
//========================================================================
-GLFWAPI void glfwGetMousePos(GLFWwindow handle, int* xpos, int* ypos)
+GLFWAPI void glfwGetCursorPos(GLFWwindow handle, int* xpos, int* ypos)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
@@ -418,7 +422,6 @@ GLFWAPI void glfwGetMousePos(GLFWwindow handle, int* xpos, int* ypos)
return;
}
- // Return mouse position
if (xpos != NULL)
*xpos = window->cursorPosX;
@@ -432,7 +435,7 @@ GLFWAPI void glfwGetMousePos(GLFWwindow handle, int* xpos, int* ypos)
// the specified window
//========================================================================
-GLFWAPI void glfwSetMousePos(GLFWwindow handle, int xpos, int ypos)
+GLFWAPI void glfwSetCursorPos(GLFWwindow handle, int xpos, int ypos)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
@@ -448,11 +451,11 @@ GLFWAPI void glfwSetMousePos(GLFWwindow handle, int xpos, int ypos)
return;
}
- // Don't do anything if the mouse position did not change
+ // Don't do anything if the cursor position did not change
if (xpos == window->cursorPosX && ypos == window->cursorPosY)
return;
- // Set GLFW mouse position
+ // Set GLFW cursor position
window->cursorPosX = xpos;
window->cursorPosY = ypos;
@@ -461,7 +464,7 @@ GLFWAPI void glfwSetMousePos(GLFWwindow handle, int xpos, int ypos)
return;
// Update physical cursor position
- _glfwPlatformSetMouseCursorPos(window, xpos, ypos);
+ _glfwPlatformSetCursorPos(window, xpos, ypos);
}
@@ -469,7 +472,7 @@ GLFWAPI void glfwSetMousePos(GLFWwindow handle, int xpos, int ypos)
// Returns the scroll offset for the specified window
//========================================================================
-GLFWAPI void glfwGetScrollOffset(GLFWwindow handle, int* xoffset, int* yoffset)
+GLFWAPI void glfwGetScrollOffset(GLFWwindow handle, double* xoffset, double* yoffset)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
@@ -539,7 +542,7 @@ GLFWAPI void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun)
// Set callback function for mouse moves
//========================================================================
-GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun)
+GLFWAPI void glfwSetCursorPosCallback(GLFWcursorposfun cbfun)
{
if (!_glfwInitialized)
{
@@ -547,11 +550,10 @@ GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun)
return;
}
- // Set callback function
- _glfwLibrary.mousePosCallback = cbfun;
+ _glfwLibrary.cursorPosCallback = cbfun;
// Call the callback function to let the application know the current
- // mouse position
+ // cursor position
if (cbfun)
{
_GLFWwindow* window;
@@ -562,6 +564,22 @@ GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun)
}
+//========================================================================
+// Set callback function for cursor enter/leave events
+//========================================================================
+
+GLFWAPI void glfwSetCursorEnterCallback(GLFWcursorenterfun cbfun)
+{
+ if (!_glfwInitialized)
+ {
+ _glfwSetError(GLFW_NOT_INITIALIZED, NULL);
+ return;
+ }
+
+ _glfwLibrary.cursorEnterCallback = cbfun;
+}
+
+
//========================================================================
// Set callback function for scroll events
//========================================================================
@@ -574,7 +592,6 @@ GLFWAPI void glfwSetScrollCallback(GLFWscrollfun cbfun)
return;
}
- // Set callback function
_glfwLibrary.scrollCallback = cbfun;
}
diff --git a/src/internal.h b/src/internal.h
index 16485b0e..54c16d39 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -37,9 +37,9 @@
//========================================================================
#if defined(_init_c_)
-#define GLFWGLOBAL
+ #define GLFWGLOBAL
#else
-#define GLFWGLOBAL extern
+ #define GLFWGLOBAL extern
#endif
@@ -51,6 +51,17 @@
#define GLFW_STICK 2
+//========================================================================
+// Internal type declarations
+//========================================================================
+
+typedef struct _GLFWhints _GLFWhints;
+typedef struct _GLFWwndconfig _GLFWwndconfig;
+typedef struct _GLFWfbconfig _GLFWfbconfig;
+typedef struct _GLFWwindow _GLFWwindow;
+typedef struct _GLFWlibrary _GLFWlibrary;
+
+
//------------------------------------------------------------------------
// Platform specific definitions goes in platform.h (which also includes
// glfw.h)
@@ -73,15 +84,16 @@ typedef struct _GLFWlibrary _GLFWlibrary;
typedef struct _GLFWmonitor _GLFWmonitor;
#if defined(_GLFW_COCOA_NSGL)
-#include "cocoa_platform.h"
+ #include "cocoa_platform.h"
#elif defined(_GLFW_WIN32_WGL)
-#include "win32_platform.h"
+ #include "win32_platform.h"
#elif defined(_GLFW_X11_GLX)
-#include "x11_platform.h"
+ #include "x11_platform.h"
#else
-#error "No supported platform selected"
+ #error "No supported platform selected"
#endif
+
//------------------------------------------------------------------------
// Window hints, set by glfwOpenWindowHint and consumed by glfwOpenWindow
// A bucket of semi-random stuff lumped together for historical reasons
@@ -186,7 +198,7 @@ struct _GLFWwindow
GLboolean systemKeys; // system keys enabled flag
int cursorPosX, cursorPosY;
int cursorMode;
- int scrollX, scrollY;
+ double scrollX, scrollY;
char mouseButton[GLFW_MOUSE_BUTTON_LAST + 1];
char key[GLFW_KEY_LAST + 1];
@@ -259,20 +271,21 @@ struct _GLFWlibrary
GLFWwindowfocusfun windowFocusCallback;
GLFWwindowiconifyfun windowIconifyCallback;
GLFWmousebuttonfun mouseButtonCallback;
- GLFWmouseposfun mousePosCallback;
+ GLFWcursorposfun cursorPosCallback;
+ GLFWcursorenterfun cursorEnterCallback;
GLFWscrollfun scrollCallback;
GLFWkeyfun keyCallback;
GLFWcharfun charCallback;
GLFWmonitordevicefun monitorCallback;
- GLFWallocator allocator;
-
GLFWgammaramp currentRamp;
GLFWgammaramp originalRamp;
int originalRampSize;
+ GLboolean rampChanged;
// This is defined in the current port's platform.h
- _GLFW_PLATFORM_LIBRARY_STATE;
+ _GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
+ _GLFW_PLATFORM_LIBRARY_OPENGL_STATE;
};
@@ -302,6 +315,8 @@ const char* _glfwPlatformGetVersionString(void);
// Input
void _glfwPlatformEnableSystemKeys(_GLFWwindow* window);
void _glfwPlatformDisableSystemKeys(_GLFWwindow* window);
+void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y);
+void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
// Fullscreen
int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount);
@@ -311,6 +326,10 @@ void _glfwPlatformGetDesktopMode(GLFWvidmode* mode);
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp);
+// Clipboard
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string);
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window);
+
// Joystick
int _glfwPlatformGetJoystickParam(int joy, int param);
int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes);
@@ -328,8 +347,6 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
-void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y);
-void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
// Event management
void _glfwPlatformPollEvents(void);
@@ -341,7 +358,7 @@ void _glfwPlatformSwapBuffers(void);
void _glfwPlatformSwapInterval(int interval);
void _glfwPlatformRefreshWindowParams(void);
int _glfwPlatformExtensionSupported(const char* extension);
-void* _glfwPlatformGetProcAddress(const char* procname);
+GLFWglproc _glfwPlatformGetProcAddress(const char* procname);
void _glfwPlatformCopyContext(_GLFWwindow* src, _GLFWwindow* dst, unsigned long mask);
@@ -349,10 +366,6 @@ void _glfwPlatformCopyContext(_GLFWwindow* src, _GLFWwindow* dst, unsigned long
// Prototypes for platform independent internal functions
//========================================================================
-// Memory management (init.c)
-void* _glfwMalloc(size_t size);
-void _glfwFree(void* ptr);
-
// Fullscren management (fullscreen.c)
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
int _glfwCompareVideoModes(const void* firstPtr, const void* secondPtr);
@@ -373,9 +386,10 @@ void _glfwInputWindowDamage(_GLFWwindow* window);
// Input event notification (input.c)
void _glfwInputKey(_GLFWwindow* window, int key, int action);
void _glfwInputChar(_GLFWwindow* window, int character);
-void _glfwInputScroll(_GLFWwindow* window, int x, int y);
+void _glfwInputScroll(_GLFWwindow* window, double x, double y);
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action);
void _glfwInputCursorMotion(_GLFWwindow* window, int x, int y);
+void _glfwInputCursorEnter(_GLFWwindow* window, int entered);
// OpenGL context helpers (opengl.c)
int _glfwStringInExtensionString(const char* string, const GLubyte* extensions);
diff --git a/src/libglfw.pc.cmake b/src/libglfw.pc.in
similarity index 66%
rename from src/libglfw.pc.cmake
rename to src/libglfw.pc.in
index 47cfb4f5..be6275aa 100644
--- a/src/libglfw.pc.cmake
+++ b/src/libglfw.pc.in
@@ -5,8 +5,9 @@ libdir=${exec_prefix}/lib
Name: GLFW
Description: A portable library for OpenGL, window and input
-Version: 3.0.0
+Version: @GLFW_VERSION_FULL@
URL: http://www.glfw.org/
-Requires.private: gl x11 @GLFW_PKGLIBS@
-Libs: -L${libdir} -lglfw
+Requires.private: @GLFW_PKG_DEPS@
+Libs: -L${libdir} -lglfw
+Libs.private: @GLFW_PKG_LIBS@
Cflags: -I${includedir}
diff --git a/src/monitor.c b/src/monitor.c
index 0cc8f511..021afd19 100644
--- a/src/monitor.c
+++ b/src/monitor.c
@@ -30,6 +30,8 @@
#include "internal.h"
+#include
+
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
diff --git a/src/opengl.c b/src/opengl.c
index f4c6984c..67b5e728 100644
--- a/src/opengl.c
+++ b/src/opengl.c
@@ -517,8 +517,7 @@ GLFWAPI void glfwSwapBuffers(void)
return;
}
- if (_glfwLibrary.currentWindow)
- _glfwPlatformSwapBuffers();
+ _glfwPlatformSwapBuffers();
}
@@ -614,7 +613,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
// This function can be used to get access to extended OpenGL functions.
//========================================================================
-GLFWAPI void* glfwGetProcAddress(const char* procname)
+GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
{
if (!_glfwInitialized)
{
diff --git a/src/win32_clipboard.c b/src/win32_clipboard.c
new file mode 100644
index 00000000..2b8742ce
--- /dev/null
+++ b/src/win32_clipboard.c
@@ -0,0 +1,140 @@
+//========================================================================
+// GLFW - An OpenGL library
+// Platform: Win32/WGL
+// API version: 3.0
+// WWW: http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2010 Camilla Berglund
+//
+// 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.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include
+#include
+#include
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Set the clipboard contents
+//========================================================================
+
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
+{
+ WCHAR* wideString;
+ HANDLE stringHandle;
+ size_t wideSize;
+
+ wideString = _glfwCreateWideStringFromUTF8(string);
+ if (!wideString)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to convert clipboard string to "
+ "wide string");
+ return;
+ }
+
+ wideSize = (wcslen(wideString) + 1) * sizeof(WCHAR);
+
+ stringHandle = GlobalAlloc(GMEM_MOVEABLE, wideSize);
+ if (!stringHandle)
+ {
+ free(wideString);
+
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to allocate global handle for clipboard");
+ return;
+ }
+
+ memcpy(GlobalLock(stringHandle), wideString, wideSize);
+ GlobalUnlock(stringHandle);
+
+ if (!OpenClipboard(window->Win32.handle))
+ {
+ GlobalFree(stringHandle);
+ free(wideString);
+
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to open clipboard");
+ return;
+ }
+
+ EmptyClipboard();
+ SetClipboardData(CF_UNICODETEXT, stringHandle);
+ CloseClipboard();
+
+ free(wideString);
+}
+
+
+//========================================================================
+// Return the current clipboard contents
+//========================================================================
+
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
+{
+ HANDLE stringHandle;
+
+ if (!IsClipboardFormatAvailable(CF_UNICODETEXT))
+ {
+ _glfwSetError(GLFW_FORMAT_UNAVAILABLE, NULL);
+ return NULL;
+ }
+
+ if (!OpenClipboard(window->Win32.handle))
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to open clipboard");
+ return NULL;
+ }
+
+ stringHandle = GetClipboardData(CF_UNICODETEXT);
+ if (!stringHandle)
+ {
+ CloseClipboard();
+
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to retrieve clipboard data");
+ return NULL;
+ }
+
+ free(_glfwLibrary.Win32.clipboardString);
+ _glfwLibrary.Win32.clipboardString =
+ _glfwCreateUTF8FromWideString(GlobalLock(stringHandle));
+
+ GlobalUnlock(stringHandle);
+ CloseClipboard();
+
+ if (!_glfwLibrary.Win32.clipboardString)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "Win32/WGL: Failed to convert wide string to UTF-8");
+ return NULL;
+ }
+
+ return _glfwLibrary.Win32.clipboardString;
+}
+
diff --git a/src/win32_dllmain.c b/src/win32_dllmain.c
index a999af0e..95258ccc 100644
--- a/src/win32_dllmain.c
+++ b/src/win32_dllmain.c
@@ -31,7 +31,7 @@
#include "internal.h"
-#if defined(GLFW_BUILD_DLL)
+#if defined(_GLFW_BUILD_DLL)
//========================================================================
// GLFW DLL entry point
@@ -45,5 +45,5 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
return TRUE;
}
-#endif // GLFW_BUILD_DLL
+#endif // _GLFW_BUILD_DLL
diff --git a/src/win32_gamma.c b/src/win32_gamma.c
index f131c3bd..36fbd3a4 100644
--- a/src/win32_gamma.c
+++ b/src/win32_gamma.c
@@ -42,7 +42,7 @@
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
{
- _glfw_GetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
+ GetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
}
@@ -52,6 +52,6 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp)
{
- _glfw_SetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
+ SetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
}
diff --git a/src/win32_init.c b/src/win32_init.c
index dfed24e4..6865851d 100644
--- a/src/win32_init.c
+++ b/src/win32_init.c
@@ -44,40 +44,6 @@
static GLboolean initLibraries(void)
{
-#ifndef _GLFW_NO_DLOAD_GDI32
- // gdi32.dll (OpenGL pixel format functions & SwapBuffers)
-
- _glfwLibrary.Win32.gdi.instance = LoadLibrary(L"gdi32.dll");
- if (!_glfwLibrary.Win32.gdi.instance)
- return GL_FALSE;
-
- _glfwLibrary.Win32.gdi.ChoosePixelFormat = (CHOOSEPIXELFORMAT_T)
- GetProcAddress(_glfwLibrary.Win32.gdi.instance, "ChoosePixelFormat");
- _glfwLibrary.Win32.gdi.DescribePixelFormat = (DESCRIBEPIXELFORMAT_T)
- GetProcAddress(_glfwLibrary.Win32.gdi.instance, "DescribePixelFormat");
- _glfwLibrary.Win32.gdi.GetPixelFormat = (GETPIXELFORMAT_T)
- GetProcAddress(_glfwLibrary.Win32.gdi.instance, "GetPixelFormat");
- _glfwLibrary.Win32.gdi.SetPixelFormat = (SETPIXELFORMAT_T)
- GetProcAddress(_glfwLibrary.Win32.gdi.instance, "SetPixelFormat");
- _glfwLibrary.Win32.gdi.SwapBuffers = (SWAPBUFFERS_T)
- GetProcAddress(_glfwLibrary.Win32.gdi.instance, "SwapBuffers");
- _glfwLibrary.Win32.gdi.GetDeviceGammaRamp = (GETDEVICEGAMMARAMP_T)
- GetProcAddress(_glfwLibrary.Win32.gdi.instance, "GetDeviceGammaRamp");
- _glfwLibrary.Win32.gdi.SetDeviceGammaRamp = (SETDEVICEGAMMARAMP_T)
- GetProcAddress(_glfwLibrary.Win32.gdi.instance, "SetDeviceGammaRamp");
-
- if (!_glfwLibrary.Win32.gdi.ChoosePixelFormat ||
- !_glfwLibrary.Win32.gdi.DescribePixelFormat ||
- !_glfwLibrary.Win32.gdi.GetPixelFormat ||
- !_glfwLibrary.Win32.gdi.SetPixelFormat ||
- !_glfwLibrary.Win32.gdi.SwapBuffers ||
- !_glfwLibrary.Win32.gdi.GetDeviceGammaRamp ||
- !_glfwLibrary.Win32.gdi.SetDeviceGammaRamp)
- {
- return GL_FALSE;
- }
-#endif // _GLFW_NO_DLOAD_GDI32
-
#ifndef _GLFW_NO_DLOAD_WINMM
// winmm.dll (for joystick and timer support)
@@ -113,14 +79,6 @@ static GLboolean initLibraries(void)
static void freeLibraries(void)
{
-#ifndef _GLFW_NO_DLOAD_GDI32
- if (_glfwLibrary.Win32.gdi.instance != NULL)
- {
- FreeLibrary(_glfwLibrary.Win32.gdi.instance);
- _glfwLibrary.Win32.gdi.instance = NULL;
- }
-#endif // _GLFW_NO_DLOAD_GDI32
-
#ifndef _GLFW_NO_DLOAD_WINMM
if (_glfwLibrary.Win32.winmm.instance != NULL)
{
@@ -131,6 +89,60 @@ static void freeLibraries(void)
}
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Returns a wide string version of the specified UTF-8 string
+//========================================================================
+
+WCHAR* _glfwCreateWideStringFromUTF8(const char* source)
+{
+ WCHAR* target;
+ int length;
+
+ length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
+ if (!length)
+ return NULL;
+
+ target = (WCHAR*) malloc(sizeof(WCHAR) * (length + 1));
+
+ if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, length + 1))
+ {
+ free(target);
+ return NULL;
+ }
+
+ return target;
+}
+
+
+//========================================================================
+// Returns a UTF-8 string version of the specified wide string
+//========================================================================
+
+char* _glfwCreateUTF8FromWideString(const WCHAR* source)
+{
+ char* target;
+ int length;
+
+ length = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
+ if (!length)
+ return NULL;
+
+ target = (char*) malloc(length + 1);
+
+ if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length + 1, NULL, NULL))
+ {
+ free(target);
+ return NULL;
+ }
+
+ return target;
+}
+
+
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
@@ -146,7 +158,7 @@ int _glfwPlatformInit(void)
// as possible in the hope of still being the foreground process)
SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
&_glfwLibrary.Win32.foregroundLockTimeout, 0);
- SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID) 0,
+ SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),
SPIF_SENDCHANGE);
if (!initLibraries())
@@ -180,7 +192,8 @@ int _glfwPlatformInit(void)
int _glfwPlatformTerminate(void)
{
// Restore the original gamma ramp
- _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
+ if (_glfwLibrary.rampChanged)
+ _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
_glfwTerminateMonitors();
@@ -196,7 +209,7 @@ int _glfwPlatformTerminate(void)
// Restore previous FOREGROUNDLOCKTIMEOUT system setting
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
- (LPVOID) _glfwLibrary.Win32.foregroundLockTimeout,
+ UIntToPtr(_glfwLibrary.Win32.foregroundLockTimeout),
SPIF_SENDCHANGE);
return GL_TRUE;
@@ -212,8 +225,6 @@ const char* _glfwPlatformGetVersionString(void)
const char* version = _GLFW_VERSION_FULL
#if defined(__MINGW32__)
" MinGW"
-#elif defined(__CYGWIN__)
- " Cygwin"
#elif defined(_MSC_VER)
" Visual C++ "
#elif defined(__BORLANDC__)
@@ -221,12 +232,9 @@ const char* _glfwPlatformGetVersionString(void)
#else
" (unknown compiler)"
#endif
-#if defined(GLFW_BUILD_DLL)
+#if defined(_GLFW_BUILD_DLL)
" DLL"
#endif
-#if !defined(_GLFW_NO_DLOAD_GDI32)
- " load(gdi32)"
-#endif
#if !defined(_GLFW_NO_DLOAD_WINMM)
" load(winmm)"
#endif
diff --git a/src/win32_joystick.c b/src/win32_joystick.c
index 0ab84aaf..c27218db 100644
--- a/src/win32_joystick.c
+++ b/src/win32_joystick.c
@@ -80,6 +80,7 @@ static float calcJoystickPos(DWORD pos, DWORD min, DWORD max)
int _glfwPlatformGetJoystickParam(int joy, int param)
{
JOYCAPS jc;
+ int hats;
if (!isJoystickPresent(joy))
return 0;
@@ -91,6 +92,8 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
// Get joystick capabilities
_glfw_joyGetDevCaps(joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS));
+ hats = (jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR) ? 1 : 0;
+
switch (param)
{
case GLFW_AXES:
@@ -98,8 +101,8 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
return jc.wNumAxes;
case GLFW_BUTTONS:
- // Return number of joystick axes
- return jc.wNumButtons;
+ // Return number of joystick buttons
+ return jc.wNumButtons + hats * 4;
default:
break;
@@ -164,7 +167,10 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
{
JOYCAPS jc;
JOYINFOEX ji;
- int button;
+ int button, hats;
+
+ // Bit fields of button presses for each direction, including nil
+ const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
if (!isJoystickPresent(joy))
return 0;
@@ -174,7 +180,7 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
// Get joystick state
ji.dwSize = sizeof(JOYINFOEX);
- ji.dwFlags = JOY_RETURNBUTTONS;
+ ji.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNPOV;
_glfw_joyGetPosEx(joy - GLFW_JOYSTICK_1, &ji);
// Get states of all requested buttons
@@ -184,6 +190,24 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
(ji.dwButtons & (1UL << button) ? GLFW_PRESS : GLFW_RELEASE);
}
+ // Virtual buttons - Inject data from hats
+ // Each hat is exposed as 4 buttons which exposes 8 directions with
+ // concurrent button presses
+ // NOTE: this API exposes only one hat
+
+ hats = (jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR) ? 1 : 0;
+
+ if (hats > 0)
+ {
+ int j;
+ int value = ji.dwPOV / 100 / 45;
+ if (value < 0 || value > 8) value = 8;
+
+ for (j = 0; j < 4 && button < numbuttons; j++)
+ {
+ buttons[button++] = directions[value] & (1 << j) ? GLFW_PRESS : GLFW_RELEASE;
+ }
+ }
+
return button;
}
-
diff --git a/src/win32_opengl.c b/src/win32_opengl.c
index 0ffd594c..5e94d7da 100644
--- a/src/win32_opengl.c
+++ b/src/win32_opengl.c
@@ -56,7 +56,7 @@ void _glfwPlatformSwapBuffers(void)
{
_GLFWwindow* window = _glfwLibrary.currentWindow;
- _glfw_SwapBuffers(window->WGL.DC);
+ SwapBuffers(window->WGL.DC);
}
@@ -111,9 +111,9 @@ int _glfwPlatformExtensionSupported(const char* extension)
// Get the function pointer to an OpenGL function
//========================================================================
-void* _glfwPlatformGetProcAddress(const char* procname)
+GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
{
- return (void*) wglGetProcAddress(procname);
+ return (GLFWglproc) wglGetProcAddress(procname);
}
diff --git a/src/win32_platform.h b/src/win32_platform.h
index 6c2f207d..aa3305ef 100644
--- a/src/win32_platform.h
+++ b/src/win32_platform.h
@@ -33,8 +33,13 @@
// We don't need all the fancy stuff
-#define NOMINMAX
-#define VC_EXTRALEAN
+#ifndef NOMINMAX
+ #define NOMINMAX
+#endif
+
+#ifndef VC_EXTRALEAN
+ #define VC_EXTRALEAN
+#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
@@ -45,7 +50,15 @@
// thinks it is the only one that gets to do so
#undef APIENTRY
-#define UNICODE
+// GLFW on Windows is Unicode only and does not work in MBCS mode
+#ifndef UNICODE
+ #define UNICODE
+#endif
+
+// GLFW requires Windows XP
+#ifndef WINVER
+ #define WINVER 0x0501
+#endif
#include
#include
@@ -61,90 +74,8 @@
// Hack: Define things that some windows.h variants don't
//========================================================================
-// Some old versions of w32api (used by MinGW and Cygwin) define
-// WH_KEYBOARD_LL without typedef:ing KBDLLHOOKSTRUCT (!)
-#if defined(__MINGW32__) || defined(__CYGWIN__)
-#include
-#if defined(WH_KEYBOARD_LL) && (__W32API_MAJOR_VERSION == 1) && (__W32API_MINOR_VERSION <= 2)
-#undef WH_KEYBOARD_LL
-#endif
-#endif
-
-//------------------------------------------------------------------------
-// ** NOTE ** If this gives you compiler errors and you are using MinGW
-// (or Dev-C++), update to w32api version 1.3 or later:
-// http://sourceforge.net/project/showfiles.php?group_id=2435
-//------------------------------------------------------------------------
-#ifndef WH_KEYBOARD_LL
-#define WH_KEYBOARD_LL 13
-typedef struct tagKBDLLHOOKSTRUCT {
- DWORD vkCode;
- DWORD scanCode;
- DWORD flags;
- DWORD time;
- DWORD dwExtraInfo;
-} KBDLLHOOKSTRUCT, FAR *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
-#endif // WH_KEYBOARD_LL
-
-#ifndef LLKHF_ALTDOWN
-#define LLKHF_ALTDOWN 0x00000020
-#endif
-
-#ifndef SPI_SETSCREENSAVERRUNNING
-#define SPI_SETSCREENSAVERRUNNING 97
-#endif
-#ifndef SPI_GETANIMATION
-#define SPI_GETANIMATION 72
-#endif
-#ifndef SPI_SETANIMATION
-#define SPI_SETANIMATION 73
-#endif
-#ifndef SPI_GETFOREGROUNDLOCKTIMEOUT
-#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000
-#endif
-#ifndef SPI_SETFOREGROUNDLOCKTIMEOUT
-#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001
-#endif
-
-#ifndef CDS_FULLSCREEN
-#define CDS_FULLSCREEN 4
-#endif
-
-#ifndef PFD_GENERIC_ACCELERATED
-#define PFD_GENERIC_ACCELERATED 0x00001000
-#endif
-#ifndef PFD_DEPTH_DONTCARE
-#define PFD_DEPTH_DONTCARE 0x20000000
-#endif
-
-#ifndef ENUM_CURRENT_SETTINGS
-#define ENUM_CURRENT_SETTINGS -1
-#endif
-#ifndef ENUM_REGISTRY_SETTINGS
-#define ENUM_REGISTRY_SETTINGS -2
-#endif
-
-#ifndef WM_MOUSEWHEEL
-#define WM_MOUSEWHEEL 0x020A
-#endif
-#ifndef WHEEL_DELTA
-#define WHEEL_DELTA 120
-#endif
#ifndef WM_MOUSEHWHEEL
-#define WM_MOUSEHWHEEL 0x020E
-#endif
-
-#ifndef WM_XBUTTONDOWN
-#define WM_XBUTTONDOWN 0x020B
-#endif
-#ifndef WM_XBUTTONUP
-#define WM_XBUTTONUP 0x020C
-#endif
-#ifndef XBUTTON1
-#define XBUTTON1 1
-#endif
-#ifndef XBUTTON2
-#define XBUTTON2 2
+ #define WM_MOUSEHWHEEL 0x020E
#endif
@@ -152,17 +83,6 @@ typedef struct tagKBDLLHOOKSTRUCT {
// DLLs that are loaded at glfwInit()
//========================================================================
-// gdi32.dll function pointer typedefs
-#ifndef _GLFW_NO_DLOAD_GDI32
-typedef int (WINAPI * CHOOSEPIXELFORMAT_T) (HDC,CONST PIXELFORMATDESCRIPTOR*);
-typedef int (WINAPI * DESCRIBEPIXELFORMAT_T) (HDC,int,UINT,LPPIXELFORMATDESCRIPTOR);
-typedef int (WINAPI * GETPIXELFORMAT_T) (HDC);
-typedef BOOL (WINAPI * SETPIXELFORMAT_T) (HDC,int,const PIXELFORMATDESCRIPTOR*);
-typedef BOOL (WINAPI * SWAPBUFFERS_T) (HDC);
-typedef BOOL (WINAPI * GETDEVICEGAMMARAMP_T) (HDC,PVOID);
-typedef BOOL (WINAPI * SETDEVICEGAMMARAMP_T) (HDC,PVOID);
-#endif // _GLFW_NO_DLOAD_GDI32
-
// winmm.dll function pointer typedefs
#ifndef _GLFW_NO_DLOAD_WINMM
typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T) (UINT,LPJOYCAPS,UINT);
@@ -172,36 +92,17 @@ typedef DWORD (WINAPI * TIMEGETTIME_T) (void);
#endif // _GLFW_NO_DLOAD_WINMM
-// gdi32.dll shortcuts
-#ifndef _GLFW_NO_DLOAD_GDI32
-#define _glfw_ChoosePixelFormat _glfwLibrary.Win32.gdi.ChoosePixelFormat
-#define _glfw_DescribePixelFormat _glfwLibrary.Win32.gdi.DescribePixelFormat
-#define _glfw_GetPixelFormat _glfwLibrary.Win32.gdi.GetPixelFormat
-#define _glfw_SetPixelFormat _glfwLibrary.Win32.gdi.SetPixelFormat
-#define _glfw_SwapBuffers _glfwLibrary.Win32.gdi.SwapBuffers
-#define _glfw_GetDeviceGammaRamp _glfwLibrary.Win32.gdi.GetDeviceGammaRamp
-#define _glfw_SetDeviceGammaRamp _glfwLibrary.Win32.gdi.SetDeviceGammaRamp
-#else
-#define _glfw_ChoosePixelFormat ChoosePixelFormat
-#define _glfw_DescribePixelFormat DescribePixelFormat
-#define _glfw_GetPixelFormat GetPixelFormat
-#define _glfw_SetPixelFormat SetPixelFormat
-#define _glfw_SwapBuffers SwapBuffers
-#define _glfw_GetDeviceGammaRamp GetDeviceGammaRamp
-#define _glfw_SetDeviceGammaRamp SetDeviceGammaRamp
-#endif // _GLFW_NO_DLOAD_GDI32
-
// winmm.dll shortcuts
#ifndef _GLFW_NO_DLOAD_WINMM
-#define _glfw_joyGetDevCaps _glfwLibrary.Win32.winmm.joyGetDevCaps
-#define _glfw_joyGetPos _glfwLibrary.Win32.winmm.joyGetPos
-#define _glfw_joyGetPosEx _glfwLibrary.Win32.winmm.joyGetPosEx
-#define _glfw_timeGetTime _glfwLibrary.Win32.winmm.timeGetTime
+ #define _glfw_joyGetDevCaps _glfwLibrary.Win32.winmm.joyGetDevCaps
+ #define _glfw_joyGetPos _glfwLibrary.Win32.winmm.joyGetPos
+ #define _glfw_joyGetPosEx _glfwLibrary.Win32.winmm.joyGetPosEx
+ #define _glfw_timeGetTime _glfwLibrary.Win32.winmm.timeGetTime
#else
-#define _glfw_joyGetDevCaps joyGetDevCaps
-#define _glfw_joyGetPos joyGetPos
-#define _glfw_joyGetPosEx joyGetPosEx
-#define _glfw_timeGetTime timeGetTime
+ #define _glfw_joyGetDevCaps joyGetDevCaps
+ #define _glfw_joyGetPos joyGetPos
+ #define _glfw_joyGetPosEx joyGetPosEx
+ #define _glfw_timeGetTime timeGetTime
#endif // _GLFW_NO_DLOAD_WINMM
@@ -211,10 +112,13 @@ typedef DWORD (WINAPI * TIMEGETTIME_T) (void);
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 Win32
-#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryWin32 Win32
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL WGL
+
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 Win32
+#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 Win32
+#define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryWGL WGL
+
//========================================================================
// GLFW platform specific types
@@ -264,12 +168,13 @@ typedef struct _GLFWwindowWin32
// Various platform specific internal variables
int desiredRefreshRate; // Desired vertical monitor refresh rate
GLboolean cursorCentered;
- int oldMouseX, oldMouseY;
+ GLboolean cursorInside;
+ int oldCursorX, oldCursorY;
} _GLFWwindowWin32;
//------------------------------------------------------------------------
-// Platform-specific library global data
+// Platform-specific library global data for Win32
//------------------------------------------------------------------------
typedef struct _GLFWlibraryWin32
{
@@ -277,6 +182,7 @@ typedef struct _GLFWlibraryWin32
ATOM classAtom; // Window class atom
HHOOK keyboardHook; // Keyboard hook handle
DWORD foregroundLockTimeout;
+ char* clipboardString;
// Default monitor
struct {
@@ -295,20 +201,6 @@ typedef struct _GLFWlibraryWin32
__int64 t0_64;
} timer;
-#ifndef _GLFW_NO_DLOAD_GDI32
- // gdi32.dll
- struct {
- HINSTANCE instance;
- CHOOSEPIXELFORMAT_T ChoosePixelFormat;
- DESCRIBEPIXELFORMAT_T DescribePixelFormat;
- GETPIXELFORMAT_T GetPixelFormat;
- SETPIXELFORMAT_T SetPixelFormat;
- SWAPBUFFERS_T SwapBuffers;
- GETDEVICEGAMMARAMP_T GetDeviceGammaRamp;
- SETDEVICEGAMMARAMP_T SetDeviceGammaRamp;
- } gdi;
-#endif // _GLFW_NO_DLOAD_GDI32
-
#ifndef _GLFW_NO_DLOAD_WINMM
// winmm.dll
struct {
@@ -331,10 +223,24 @@ typedef struct _GLFWmonitorWin32
} _GLFWmonitorWin32;
+//------------------------------------------------------------------------
+// Platform-specific library global data for WGL
+//------------------------------------------------------------------------
+typedef struct _GLFWlibraryWGL
+{
+ int dummy;
+
+} _GLFWlibraryWGL;
+
+
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
+// Wide strings
+WCHAR* _glfwCreateWideStringFromUTF8(const char* source);
+char* _glfwCreateUTF8FromWideString(const WCHAR* source);
+
// Time
void _glfwInitTimer(void);
diff --git a/src/win32_window.c b/src/win32_window.c
old mode 100644
new mode 100755
index 7f9e37a1..dd14a77f
--- a/src/win32_window.c
+++ b/src/win32_window.c
@@ -33,55 +33,6 @@
#include
-//========================================================================
-// Convert the specified UTF-8 string to a wide string
-//========================================================================
-
-static WCHAR* createWideStringFromUTF8(const char* source)
-{
- WCHAR* target;
- int length;
-
- length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
- if (!length)
- return NULL;
-
- target = (WCHAR*) _glfwMalloc(sizeof(WCHAR) * (length + 1));
-
- if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, length + 1))
- {
- _glfwFree(target);
- return NULL;
- }
-
- return target;
-}
-
-
-//========================================================================
-// Convert BPP to RGB bits based on "best guess"
-//========================================================================
-
-static void bpp2rgb(int bpp, int* r, int* g, int* b)
-{
- int delta;
-
- // We assume that by 32 they really meant 24
- if (bpp == 32)
- bpp = 24;
-
- // Convert "bits per pixel" to red, green & blue sizes
-
- *r = *g = *b = bpp / 3;
- delta = bpp - (*r * 3);
- if (delta >= 1)
- *g = *g + 1;
-
- if (delta == 2)
- *r = *r + 1;
-}
-
-
//========================================================================
// Enable/disable minimize/restore animations
//========================================================================
@@ -197,38 +148,44 @@ static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib
static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
{
- _GLFWfbconfig* result;
+ _GLFWfbconfig* fbconfigs;
PIXELFORMATDESCRIPTOR pfd;
- int i, count;
+ int i, available;
*found = 0;
if (window->WGL.ARB_pixel_format)
- count = getPixelFormatAttrib(window, 1, WGL_NUMBER_PIXEL_FORMATS_ARB);
+ {
+ available = getPixelFormatAttrib(window,
+ 1,
+ WGL_NUMBER_PIXEL_FORMATS_ARB);
+ }
else
{
- count = _glfw_DescribePixelFormat(window->WGL.DC,
- 1,
- sizeof(PIXELFORMATDESCRIPTOR),
- NULL);
+ available = DescribePixelFormat(window->WGL.DC,
+ 1,
+ sizeof(PIXELFORMATDESCRIPTOR),
+ NULL);
}
- if (!count)
+ if (!available)
{
_glfwSetError(GLFW_OPENGL_UNAVAILABLE, "Win32/WGL: No pixel formats found");
return NULL;
}
- result = (_GLFWfbconfig*) _glfwMalloc(sizeof(_GLFWfbconfig) * count);
- if (!result)
+ fbconfigs = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * available);
+ if (!fbconfigs)
{
_glfwSetError(GLFW_OUT_OF_MEMORY,
"Win32/WGL: Failed to allocate _GLFWfbconfig array");
return NULL;
}
- for (i = 1; i <= count; i++)
+ for (i = 1; i <= available; i++)
{
+ _GLFWfbconfig* f = fbconfigs + *found;
+
if (window->WGL.ARB_pixel_format)
{
// Get pixel format attributes through WGL_ARB_pixel_format
@@ -251,50 +208,35 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
continue;
}
- result[*found].redBits =
- getPixelFormatAttrib(window, i, WGL_RED_BITS_ARB);
- result[*found].greenBits =
- getPixelFormatAttrib(window, i, WGL_GREEN_BITS_ARB);
- result[*found].blueBits =
- getPixelFormatAttrib(window, i, WGL_BLUE_BITS_ARB);
- result[*found].alphaBits =
- getPixelFormatAttrib(window, i, WGL_ALPHA_BITS_ARB);
+ f->redBits = getPixelFormatAttrib(window, i, WGL_RED_BITS_ARB);
+ f->greenBits = getPixelFormatAttrib(window, i, WGL_GREEN_BITS_ARB);
+ f->blueBits = getPixelFormatAttrib(window, i, WGL_BLUE_BITS_ARB);
+ f->alphaBits = getPixelFormatAttrib(window, i, WGL_ALPHA_BITS_ARB);
- result[*found].depthBits =
- getPixelFormatAttrib(window, i, WGL_DEPTH_BITS_ARB);
- result[*found].stencilBits =
- getPixelFormatAttrib(window, i, WGL_STENCIL_BITS_ARB);
+ f->depthBits = getPixelFormatAttrib(window, i, WGL_DEPTH_BITS_ARB);
+ f->stencilBits = getPixelFormatAttrib(window, i, WGL_STENCIL_BITS_ARB);
- result[*found].accumRedBits =
- getPixelFormatAttrib(window, i, WGL_ACCUM_RED_BITS_ARB);
- result[*found].accumGreenBits =
- getPixelFormatAttrib(window, i, WGL_ACCUM_GREEN_BITS_ARB);
- result[*found].accumBlueBits =
- getPixelFormatAttrib(window, i, WGL_ACCUM_BLUE_BITS_ARB);
- result[*found].accumAlphaBits =
- getPixelFormatAttrib(window, i, WGL_ACCUM_ALPHA_BITS_ARB);
+ f->accumRedBits = getPixelFormatAttrib(window, i, WGL_ACCUM_RED_BITS_ARB);
+ f->accumGreenBits = getPixelFormatAttrib(window, i, WGL_ACCUM_GREEN_BITS_ARB);
+ f->accumBlueBits = getPixelFormatAttrib(window, i, WGL_ACCUM_BLUE_BITS_ARB);
+ f->accumAlphaBits = getPixelFormatAttrib(window, i, WGL_ACCUM_ALPHA_BITS_ARB);
- result[*found].auxBuffers =
- getPixelFormatAttrib(window, i, WGL_AUX_BUFFERS_ARB);
- result[*found].stereo =
- getPixelFormatAttrib(window, i, WGL_STEREO_ARB);
+ f->auxBuffers = getPixelFormatAttrib(window, i, WGL_AUX_BUFFERS_ARB);
+ f->stereo = getPixelFormatAttrib(window, i, WGL_STEREO_ARB);
if (window->WGL.ARB_multisample)
- {
- result[*found].samples =
- getPixelFormatAttrib(window, i, WGL_SAMPLES_ARB);
- }
+ f->samples = getPixelFormatAttrib(window, i, WGL_SAMPLES_ARB);
else
- result[*found].samples = 0;
+ f->samples = 0;
}
else
{
// Get pixel format attributes through old-fashioned PFDs
- if (!_glfw_DescribePixelFormat(window->WGL.DC,
- i,
- sizeof(PIXELFORMATDESCRIPTOR),
- &pfd))
+ if (!DescribePixelFormat(window->WGL.DC,
+ i,
+ sizeof(PIXELFORMATDESCRIPTOR),
+ &pfd))
{
continue;
}
@@ -315,32 +257,38 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
if (pfd.iPixelType != PFD_TYPE_RGBA)
continue;
- result[*found].redBits = pfd.cRedBits;
- result[*found].greenBits = pfd.cGreenBits;
- result[*found].blueBits = pfd.cBlueBits;
- result[*found].alphaBits = pfd.cAlphaBits;
+ f->redBits = pfd.cRedBits;
+ f->greenBits = pfd.cGreenBits;
+ f->blueBits = pfd.cBlueBits;
+ f->alphaBits = pfd.cAlphaBits;
- result[*found].depthBits = pfd.cDepthBits;
- result[*found].stencilBits = pfd.cStencilBits;
+ f->depthBits = pfd.cDepthBits;
+ f->stencilBits = pfd.cStencilBits;
- result[*found].accumRedBits = pfd.cAccumRedBits;
- result[*found].accumGreenBits = pfd.cAccumGreenBits;
- result[*found].accumBlueBits = pfd.cAccumBlueBits;
- result[*found].accumAlphaBits = pfd.cAccumAlphaBits;
+ f->accumRedBits = pfd.cAccumRedBits;
+ f->accumGreenBits = pfd.cAccumGreenBits;
+ f->accumBlueBits = pfd.cAccumBlueBits;
+ f->accumAlphaBits = pfd.cAccumAlphaBits;
- result[*found].auxBuffers = pfd.cAuxBuffers;
- result[*found].stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE;
+ f->auxBuffers = pfd.cAuxBuffers;
+ f->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE;
// PFD pixel formats do not support FSAA
- result[*found].samples = 0;
+ f->samples = 0;
}
- result[*found].platformID = i;
+ f->platformID = i;
(*found)++;
}
- return result;
+ if (*found == 0)
+ {
+ free(fbconfigs);
+ return NULL;
+ }
+
+ return fbconfigs;
}
@@ -359,14 +307,14 @@ static GLboolean createContext(_GLFWwindow* window,
if (wndconfig->share)
share = wndconfig->share->WGL.context;
- if (!_glfw_DescribePixelFormat(window->WGL.DC, pixelFormat, sizeof(pfd), &pfd))
+ if (!DescribePixelFormat(window->WGL.DC, pixelFormat, sizeof(pfd), &pfd))
{
_glfwSetError(GLFW_OPENGL_UNAVAILABLE,
"Win32/WGL: Failed to retrieve PFD for selected pixel format");
return GL_FALSE;
}
- if (!_glfw_SetPixelFormat(window->WGL.DC, pixelFormat, &pfd))
+ if (!SetPixelFormat(window->WGL.DC, pixelFormat, &pfd))
{
_glfwSetError(GLFW_OPENGL_UNAVAILABLE,
"Win32/WGL: Failed to set selected pixel format");
@@ -500,7 +448,7 @@ static GLboolean createContext(_GLFWwindow* window,
// Hide mouse cursor
//========================================================================
-static void hideMouseCursor(_GLFWwindow* window)
+static void hideCursor(_GLFWwindow* window)
{
}
@@ -509,7 +457,7 @@ static void hideMouseCursor(_GLFWwindow* window)
// Capture mouse cursor
//========================================================================
-static void captureMouseCursor(_GLFWwindow* window)
+static void captureCursor(_GLFWwindow* window)
{
RECT ClipWindowRect;
@@ -528,7 +476,7 @@ static void captureMouseCursor(_GLFWwindow* window)
// Show mouse cursor
//========================================================================
-static void showMouseCursor(_GLFWwindow* window)
+static void showCursor(_GLFWwindow* window)
{
// Un-capture cursor
ReleaseCapture();
@@ -835,7 +783,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// The window was deactivated (or iconified, see above)
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
- showMouseCursor(window);
+ showCursor(window);
if (window->mode == GLFW_FULLSCREEN)
{
@@ -858,7 +806,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// The window was activated
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
- captureMouseCursor(window);
+ captureCursor(window);
if (window->mode == GLFW_FULLSCREEN)
{
@@ -919,7 +867,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (_glfwLibrary.charCallback)
translateChar(window, (DWORD) wParam, (DWORD) lParam);
- return 0;
+ break;
}
case WM_KEYUP:
@@ -934,7 +882,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
else
_glfwInputKey(window, translateKey(wParam, lParam), GLFW_RELEASE);
- return 0;
+ break;
}
case WM_LBUTTONDOWN:
@@ -1013,14 +961,14 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOUSEMOVE:
{
- int newMouseX, newMouseY;
+ int newCursorX, newCursorY;
- // Get signed (!) mouse position
- newMouseX = (int)((short)LOWORD(lParam));
- newMouseY = (int)((short)HIWORD(lParam));
+ // Get signed (!) cursor position
+ newCursorX = (int)((short)LOWORD(lParam));
+ newCursorY = (int)((short)HIWORD(lParam));
- if (newMouseX != window->Win32.oldMouseX ||
- newMouseY != window->Win32.oldMouseY)
+ if (newCursorX != window->Win32.oldCursorX ||
+ newCursorY != window->Win32.oldCursorY)
{
int x, y;
@@ -1029,28 +977,48 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (_glfwLibrary.activeWindow != window)
return 0;
- x = newMouseX - window->Win32.oldMouseX;
- y = newMouseY - window->Win32.oldMouseY;
+ x = newCursorX - window->Win32.oldCursorX;
+ y = newCursorY - window->Win32.oldCursorY;
}
else
{
- x = newMouseX;
- y = newMouseY;
+ x = newCursorX;
+ y = newCursorY;
}
- window->Win32.oldMouseX = newMouseX;
- window->Win32.oldMouseY = newMouseY;
+ window->Win32.oldCursorX = newCursorX;
+ window->Win32.oldCursorY = newCursorY;
window->Win32.cursorCentered = GL_FALSE;
_glfwInputCursorMotion(window, x, y);
}
+ if (!window->Win32.cursorInside)
+ {
+ TRACKMOUSEEVENT tme;
+ ZeroMemory(&tme, sizeof(tme));
+ tme.cbSize = sizeof(tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = window->Win32.handle;
+ TrackMouseEvent(&tme);
+
+ window->Win32.cursorInside = GL_TRUE;
+ _glfwInputCursorEnter(window, GL_TRUE);
+ }
+
+ return 0;
+ }
+
+ case WM_MOUSELEAVE:
+ {
+ window->Win32.cursorInside = GL_FALSE;
+ _glfwInputCursorEnter(window, GL_FALSE);
return 0;
}
case WM_MOUSEWHEEL:
{
- _glfwInputScroll(window, 0, (((int) wParam) >> 16) / WHEEL_DELTA);
+ _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);
return 0;
}
@@ -1058,7 +1026,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{
// This message is only sent on Windows Vista and later
- _glfwInputScroll(window, (((int) wParam) >> 16) / WHEEL_DELTA, 0);
+ _glfwInputScroll(window, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA, 0.0);
return 0;
}
@@ -1291,13 +1259,13 @@ static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* fbconfig)
closest = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
if (!closest)
{
- _glfwFree(fbconfigs);
+ free(fbconfigs);
return 0;
}
pixelFormat = (int) closest->platformID;
- _glfwFree(fbconfigs);
+ free(fbconfigs);
fbconfigs = NULL;
closest = NULL;
@@ -1314,7 +1282,7 @@ static int createWindow(_GLFWwindow* window,
const _GLFWfbconfig* fbconfig)
{
DWORD dwStyle, dwExStyle;
- int length, pixelFormat, fullWidth, fullHeight;
+ int pixelFormat, fullWidth, fullHeight;
RECT wa;
POINT pos;
WCHAR* wideTitle;
@@ -1366,12 +1334,12 @@ static int createWindow(_GLFWwindow* window,
else
SystemParametersInfo(SPI_GETWORKAREA, 0, &wa, 0);
- wideTitle = createWideStringFromUTF8(wndconfig->title);
+ wideTitle = _glfwCreateWideStringFromUTF8(wndconfig->title);
if (!wideTitle)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
"glfwOpenWindow: Failed to convert title to wide string");
- return;
+ return GL_FALSE;
}
window->Win32.handle = CreateWindowEx(window->Win32.dwExStyle,
@@ -1392,7 +1360,7 @@ static int createWindow(_GLFWwindow* window,
return GL_FALSE;
}
- _glfwFree(wideTitle);
+ free(wideTitle);
window->WGL.DC = GetDC(window->Win32.handle);
if (!window->WGL.DC)
@@ -1413,11 +1381,11 @@ static int createWindow(_GLFWwindow* window,
initWGLExtensions(window);
- // Initialize mouse position data
+ // Initialize cursor position data
GetCursorPos(&pos);
ScreenToClient(window->Win32.handle, &pos);
- window->Win32.oldMouseX = window->cursorPosX = pos.x;
- window->Win32.oldMouseY = window->cursorPosY = pos.y;
+ window->Win32.oldCursorX = window->cursorPosX = pos.x;
+ window->Win32.oldCursorY = window->cursorPosY = pos.y;
return GL_TRUE;
}
@@ -1475,6 +1443,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
GLboolean recreateContext = GL_FALSE;
window->Win32.desiredRefreshRate = wndconfig->refreshRate;
+ window->resizable = wndconfig->resizable;
if (!_glfwLibrary.Win32.classAtom)
{
@@ -1613,7 +1582,7 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window)
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{
- WCHAR* wideTitle = createWideStringFromUTF8(title);
+ WCHAR* wideTitle = _glfwCreateWideStringFromUTF8(title);
if (!wideTitle)
{
_glfwSetError(GLFW_PLATFORM_ERROR,
@@ -1623,7 +1592,7 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
SetWindowText(window->Win32.handle, wideTitle);
- _glfwFree(wideTitle);
+ free(wideTitle);
}
@@ -1633,29 +1602,10 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
- //int bpp, refresh;
- int newMode = 0;
GLboolean sizeChanged = GL_FALSE;
if (window->mode == GLFW_FULLSCREEN)
{
- // Get some info about the current mode
-
- DEVMODE dm;
-
- dm.dmSize = sizeof(DEVMODE);
- //if (EnumDisplaySettings(NULL, window->Win32.modeID, &dm))
- //{
- // We need to keep BPP the same for the OpenGL context to keep working
- //bpp = dm.dmBitsPerPel;
-
- // Get closest match for target video mode
- //refresh = window->Win32.desiredRefreshRate;
- //newMode = _glfwGetClosestVideoModeBPP(&width, &height, &bpp, &refresh);
- //}
- //else
- //newMode = window->Win32.modeID;
-
if (width > window->width || height > window->height)
{
// The new video mode is larger than the current one, so we resize
@@ -1667,8 +1617,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
sizeChanged = GL_TRUE;
}
- //if (newMode != window->Win32.modeID)
- //_glfwSetVideoModeMODE(newMode);
+ // TODO: Change video mode
}
else
{
@@ -1692,7 +1641,13 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y)
{
- SetWindowPos(window->Win32.handle, HWND_TOP, x, y, 0, 0,
+ RECT rect;
+
+ GetClientRect(window->Win32.handle, &rect);
+ AdjustWindowRectEx(&rect, window->Win32.dwStyle, FALSE, window->Win32.dwExStyle);
+
+ SetWindowPos(window->Win32.handle, HWND_TOP,
+ x + rect.left, y + rect.top, 0, 0,
SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
}
@@ -1730,7 +1685,7 @@ void _glfwPlatformRefreshWindowParams(void)
_GLFWwindow* window = _glfwLibrary.currentWindow;
// Obtain a detailed description of current pixel format
- pixelFormat = _glfw_GetPixelFormat(window->WGL.DC);
+ pixelFormat = GetPixelFormat(window->WGL.DC);
if (window->WGL.ARB_pixel_format)
{
@@ -1784,8 +1739,8 @@ void _glfwPlatformRefreshWindowParams(void)
}
else
{
- _glfw_DescribePixelFormat(window->WGL.DC, pixelFormat,
- sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+ DescribePixelFormat(window->WGL.DC, pixelFormat,
+ sizeof(PIXELFORMATDESCRIPTOR), &pfd);
// Is current OpenGL context accelerated?
window->accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) ||
@@ -1835,14 +1790,14 @@ void _glfwPlatformPollEvents(void)
window = _glfwLibrary.activeWindow;
if (window)
{
- window->Win32.cursorCentered = GL_TRUE;
- window->Win32.oldMouseX = window->width / 2;
- window->Win32.oldMouseY = window->height / 2;
+ window->Win32.cursorCentered = GL_FALSE;
+ window->Win32.oldCursorX = window->width / 2;
+ window->Win32.oldCursorY = window->height / 2;
}
else
{
- //window->Win32.oldMouseX = window->cursorPosX;
- //window->Win32.oldMouseY = window->cursorPosY;
+ //window->Win32.oldCursorX = window->cursorPosX;
+ //window->Win32.oldCursorY = window->cursorPosY;
}
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
@@ -1899,9 +1854,9 @@ void _glfwPlatformPollEvents(void)
if (window->cursorMode == GLFW_CURSOR_CAPTURED &&
!window->Win32.cursorCentered)
{
- _glfwPlatformSetMouseCursorPos(window,
- window->width / 2,
- window->height / 2);
+ _glfwPlatformSetCursorPos(window,
+ window->width / 2,
+ window->height / 2);
window->Win32.cursorCentered = GL_TRUE;
}
}
@@ -1921,10 +1876,10 @@ void _glfwPlatformWaitEvents(void)
//========================================================================
-// Set physical mouse cursor position
+// Set physical cursor position
//========================================================================
-void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y)
+void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y)
{
POINT pos;
@@ -1946,13 +1901,13 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
switch (mode)
{
case GLFW_CURSOR_NORMAL:
- showMouseCursor(window);
+ showCursor(window);
break;
case GLFW_CURSOR_HIDDEN:
- hideMouseCursor(window);
+ hideCursor(window);
break;
case GLFW_CURSOR_CAPTURED:
- captureMouseCursor(window);
+ captureCursor(window);
break;
}
}
diff --git a/src/window.c b/src/window.c
index de89b069..f8939e37 100644
--- a/src/window.c
+++ b/src/window.c
@@ -291,7 +291,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
height = 480;
}
- window = (_GLFWwindow*) _glfwMalloc(sizeof(_GLFWwindow));
+ window = (_GLFWwindow*) malloc(sizeof(_GLFWwindow));
if (!window)
{
_glfwSetError(GLFW_OUT_OF_MEMORY,
@@ -492,7 +492,7 @@ GLFWAPI void glfwCloseWindow(GLFWwindow handle)
*prev = window->next;
}
- _glfwFree(window);
+ free(window);
}
@@ -655,7 +655,6 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow handle)
if (!window->iconified)
return;
- // Restore iconified window
_glfwPlatformRestoreWindow(window);
if (window->mode == GLFW_FULLSCREEN)
diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c
new file mode 100644
index 00000000..a833ed1f
--- /dev/null
+++ b/src/x11_clipboard.c
@@ -0,0 +1,191 @@
+//========================================================================
+// GLFW - An OpenGL library
+// Platform: X11/GLX
+// API version: 3.0
+// WWW: http://www.glfw.org/
+//------------------------------------------------------------------------
+// Copyright (c) 2010 Camilla Berglund
+//
+// 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.
+//
+//========================================================================
+
+#include "internal.h"
+
+#include
+#include
+#include
+#include
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Save the contents of the specified property
+//========================================================================
+
+GLboolean _glfwReadSelection(XSelectionEvent* request)
+{
+ Atom actualType;
+ int actualFormat;
+ unsigned long itemCount, bytesAfter;
+ char* data;
+
+ if (request->property == None)
+ return GL_FALSE;
+
+ XGetWindowProperty(_glfwLibrary.X11.display,
+ request->requestor,
+ request->property,
+ 0, LONG_MAX,
+ False,
+ request->target,
+ &actualType,
+ &actualFormat,
+ &itemCount,
+ &bytesAfter,
+ (unsigned char**) &data);
+
+ if (actualType == None)
+ return GL_FALSE;
+
+ free(_glfwLibrary.X11.selection.string);
+ _glfwLibrary.X11.selection.string = strdup(data);
+
+ XFree(data);
+ return GL_TRUE;
+}
+
+
+//========================================================================
+// Set the specified property to the contents of the requested selection
+//========================================================================
+
+Atom _glfwWriteSelection(XSelectionRequestEvent* request)
+{
+ int i;
+ Atom property = request->property;
+
+ if (property == None)
+ property = _glfwLibrary.X11.selection.property;
+
+ if (request->target == _glfwLibrary.X11.selection.targets)
+ {
+ // The list of supported targets was requested
+
+ XChangeProperty(_glfwLibrary.X11.display,
+ request->requestor,
+ property,
+ XA_ATOM,
+ 32,
+ PropModeReplace,
+ (unsigned char*) _glfwLibrary.X11.selection.formats,
+ _GLFW_CLIPBOARD_FORMAT_COUNT);
+
+ return property;
+ }
+
+ for (i = 0; i < _GLFW_CLIPBOARD_FORMAT_COUNT; i++)
+ {
+ if (request->target == _glfwLibrary.X11.selection.formats[i])
+ {
+ // The requested target is one we support
+
+ XChangeProperty(_glfwLibrary.X11.display,
+ request->requestor,
+ property,
+ request->target,
+ 8,
+ PropModeReplace,
+ (unsigned char*) _glfwLibrary.X11.selection.string,
+ strlen(_glfwLibrary.X11.selection.string));
+
+ return property;
+ }
+ }
+
+ return None;
+}
+
+
+//////////////////////////////////////////////////////////////////////////
+////// GLFW platform API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Set the clipboard contents
+//========================================================================
+
+void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
+{
+ // Store the new string in preparation for a selection request event
+ free(_glfwLibrary.X11.selection.string);
+ _glfwLibrary.X11.selection.string = strdup(string);
+
+ // Set the specified window as owner of the selection
+ XSetSelectionOwner(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.selection.atom,
+ window->X11.handle, CurrentTime);
+}
+
+
+//========================================================================
+// Return the current clipboard contents
+//========================================================================
+
+const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
+{
+ int i;
+
+ _glfwLibrary.X11.selection.status = _GLFW_CONVERSION_INACTIVE;
+
+ for (i = 0; i < _GLFW_CLIPBOARD_FORMAT_COUNT; i++)
+ {
+ // Request conversion to the selected format
+ _glfwLibrary.X11.selection.target =
+ _glfwLibrary.X11.selection.formats[i];
+
+ XConvertSelection(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.selection.atom,
+ _glfwLibrary.X11.selection.target,
+ _glfwLibrary.X11.selection.property,
+ window->X11.handle, CurrentTime);
+
+ // Process the resulting SelectionNotify event
+ XSync(_glfwLibrary.X11.display, False);
+ while (_glfwLibrary.X11.selection.status == _GLFW_CONVERSION_INACTIVE)
+ _glfwPlatformWaitEvents();
+
+ if (_glfwLibrary.X11.selection.status == _GLFW_CONVERSION_SUCCEEDED)
+ break;
+ }
+
+ if (_glfwLibrary.X11.selection.status == _GLFW_CONVERSION_FAILED)
+ {
+ _glfwSetError(GLFW_FORMAT_UNAVAILABLE,
+ "X11/GLX: Failed to convert selection to string");
+ return NULL;
+ }
+
+ return _glfwLibrary.X11.selection.string;
+}
+
diff --git a/src/x11_fullscreen.c b/src/x11_fullscreen.c
index f0a3f194..2ff8a731 100644
--- a/src/x11_fullscreen.c
+++ b/src/x11_fullscreen.c
@@ -42,7 +42,7 @@
// Finds the video mode closest in size to the specified desired size
//========================================================================
-int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
+int _glfwGetClosestVideoMode(int* width, int* height, int* rate)
{
int i, match, bestmatch;
@@ -55,8 +55,7 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
XRRScreenConfiguration* sc;
XRRScreenSize* sizelist;
- sc = XRRGetScreenInfo(_glfwLibrary.X11.display,
- RootWindow(_glfwLibrary.X11.display, screen));
+ sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
sizelist = XRRConfigSizes(sc, &sizecount);
@@ -116,7 +115,8 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
int bestmode, modecount;
// Get a list of all available display modes
- XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen,
+ XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
&modecount, &modelist);
// Find the best matching mode
@@ -150,8 +150,8 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
}
// Default: Simply use the screen resolution
- *width = DisplayWidth(_glfwLibrary.X11.display, screen);
- *height = DisplayHeight(_glfwLibrary.X11.display, screen);
+ *width = DisplayWidth(_glfwLibrary.X11.display, _glfwLibrary.X11.screen);
+ *height = DisplayHeight(_glfwLibrary.X11.display, _glfwLibrary.X11.screen);
return 0;
}
@@ -161,7 +161,7 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
// Change the current video mode
//========================================================================
-void _glfwSetVideoModeMODE(int screen, int mode, int rate)
+void _glfwSetVideoModeMODE(int mode, int rate)
{
if (_glfwLibrary.X11.RandR.available)
{
@@ -169,15 +169,17 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
XRRScreenConfiguration* sc;
Window root;
- root = RootWindow(_glfwLibrary.X11.display, screen);
+ root = _glfwLibrary.X11.root;
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, root);
// Remember old size and flag that we have changed the mode
if (!_glfwLibrary.X11.FS.modeChanged)
{
_glfwLibrary.X11.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwLibrary.X11.FS.oldRotation);
- _glfwLibrary.X11.FS.oldWidth = DisplayWidth(_glfwLibrary.X11.display, screen);
- _glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display, screen);
+ _glfwLibrary.X11.FS.oldWidth = DisplayWidth(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen);
+ _glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen);
_glfwLibrary.X11.FS.modeChanged = GL_TRUE;
}
@@ -214,21 +216,32 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
int modecount;
// Get a list of all available display modes
- XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen,
+ XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
&modecount, &modelist);
// Unlock mode switch if necessary
if (_glfwLibrary.X11.FS.modeChanged)
- XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, screen, 0);
+ {
+ XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ 0);
+ }
// Change the video mode to the desired mode
- XF86VidModeSwitchToMode(_glfwLibrary.X11.display, screen, modelist[mode]);
+ XF86VidModeSwitchToMode(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ modelist[mode]);
// Set viewport to upper left corner (where our window will be)
- XF86VidModeSetViewPort(_glfwLibrary.X11.display, screen, 0, 0);
+ XF86VidModeSetViewPort(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ 0, 0);
// Lock mode switch
- XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, screen, 1);
+ XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ 1);
// Remember old mode and flag that we have changed the mode
if (!_glfwLibrary.X11.FS.modeChanged)
@@ -247,15 +260,15 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
// Change the current video mode
//========================================================================
-void _glfwSetVideoMode(int screen, int* width, int* height, int* rate)
+void _glfwSetVideoMode(int* width, int* height, int* rate)
{
int bestmode;
// Find a best match mode
- bestmode = _glfwGetClosestVideoMode(screen, width, height, rate);
+ bestmode = _glfwGetClosestVideoMode(width, height, rate);
// Change mode
- _glfwSetVideoModeMODE(screen, bestmode, *rate);
+ _glfwSetVideoModeMODE(bestmode, *rate);
}
@@ -263,7 +276,7 @@ void _glfwSetVideoMode(int screen, int* width, int* height, int* rate)
// Restore the previously saved (original) video mode
//========================================================================
-void _glfwRestoreVideoMode(int screen)
+void _glfwRestoreVideoMode(void)
{
if (_glfwLibrary.X11.FS.modeChanged)
{
@@ -292,11 +305,13 @@ void _glfwRestoreVideoMode(int screen)
{
#if defined(_GLFW_HAS_XF86VIDMODE)
// Unlock mode switch
- XF86VidModeLockModeSwitch(_glfwLibrary.X11.display, screen, 0);
+ XF86VidModeLockModeSwitch(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ 0);
// Change the video mode back to the old mode
XF86VidModeSwitchToMode(_glfwLibrary.X11.display,
- screen,
+ _glfwLibrary.X11.screen,
&_glfwLibrary.X11.FS.oldMode);
#endif /*_GLFW_HAS_XF86VIDMODE*/
}
@@ -338,7 +353,7 @@ int _glfwCompareResolution(const void* left, const void* right)
int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount)
{
int count, k, l, r, g, b, rgba, gl;
- int depth, screen;
+ int depth;
XVisualInfo* vislist;
XVisualInfo dummy;
int viscount, rgbcount, rescount;
@@ -354,7 +369,7 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
return 0;
}
- rgbarray = (int*) _glfwMalloc(sizeof(int) * viscount);
+ rgbarray = (int*) malloc(sizeof(int) * viscount);
rgbcount = 0;
// Build RGB array
@@ -387,6 +402,8 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
}
}
+ XFree(vislist);
+
rescount = 0;
resarray = NULL;
@@ -399,7 +416,7 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
unsigned int a;
resource = XRRGetScreenResources(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
- resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * monitor->X11.output->nmode);
+ resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * monitor->X11.output->nmode);
for (k = 0; k < monitor->X11.output->nmode; k++)
{
@@ -434,9 +451,11 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
XF86VidModeModeInfo** modelist;
int modecount, width, height;
- XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, &modecount, &modelist);
+ XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ &modecount, &modelist);
- resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * modecount);
+ resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * modecount);
for (k = 0; k < modecount; k++)
{
@@ -465,10 +484,12 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
if (!resarray)
{
rescount = 1;
- resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * rescount);
+ resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * rescount);
- resarray[0].width = DisplayWidth(_glfwLibrary.X11.display, screen);
- resarray[0].height = DisplayHeight(_glfwLibrary.X11.display, screen);
+ resarray[0].width = DisplayWidth(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen);
+ resarray[0].height = DisplayHeight(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen);
}
// Build permutations of colors and resolutions
@@ -486,10 +507,8 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
}
}
- XFree(vislist);
-
- _glfwFree(resarray);
- _glfwFree(rgbarray);
+ free(resarray);
+ free(rgbarray);
return count;
}
diff --git a/src/x11_gamma.c b/src/x11_gamma.c
index fe02a939..44cd1139 100644
--- a/src/x11_gamma.c
+++ b/src/x11_gamma.c
@@ -33,6 +33,74 @@
#include
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Detect gamma ramp support and save original gamma ramp, if available
+//========================================================================
+
+void _glfwInitGammaRamp(void)
+{
+#ifdef _GLFW_HAS_XRANDR
+ // RandR gamma support is only available with version 1.2 and above
+ if (_glfwLibrary.X11.RandR.available &&
+ (_glfwLibrary.X11.RandR.majorVersion > 1 ||
+ (_glfwLibrary.X11.RandR.majorVersion == 1 &&
+ _glfwLibrary.X11.RandR.minorVersion >= 2)))
+ {
+ // FIXME: Assumes that all monitors have the same size gamma tables
+ // This is reasonable as I suspect the that if they did differ, it
+ // would imply that setting the gamma size to an arbitary size is
+ // possible as well.
+ XRRScreenResources* rr = XRRGetScreenResources(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.root);
+
+ _glfwLibrary.originalRampSize = XRRGetCrtcGammaSize(_glfwLibrary.X11.display,
+ rr->crtcs[0]);
+ if (!_glfwLibrary.originalRampSize)
+ {
+ // This is probably Nvidia RandR with broken gamma support
+ // Flag it as useless and try Xf86VidMode below, if available
+ _glfwLibrary.X11.RandR.gammaBroken = GL_TRUE;
+ }
+
+ XRRFreeScreenResources(rr);
+ }
+#endif /*_GLFW_HAS_XRANDR*/
+
+#if defined(_GLFW_HAS_XF86VIDMODE)
+ if (_glfwLibrary.X11.VidMode.available &&
+ !_glfwLibrary.originalRampSize)
+ {
+ // Get the gamma size using XF86VidMode
+ XF86VidModeGetGammaRampSize(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ &_glfwLibrary.originalRampSize);
+ }
+#endif /*_GLFW_HAS_XF86VIDMODE*/
+
+ if (_glfwLibrary.originalRampSize)
+ {
+ // Save the original gamma ramp
+ _glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp);
+ _glfwLibrary.currentRamp = _glfwLibrary.originalRamp;
+ }
+}
+
+
+//========================================================================
+// Restore original gamma ramp if necessary
+//========================================================================
+
+void _glfwTerminateGammaRamp(void)
+{
+ if (_glfwLibrary.originalRampSize && _glfwLibrary.rampChanged)
+ _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
+}
+
+
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
@@ -43,6 +111,15 @@
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
{
+ // For now, don't support anything that is not GLFW_GAMMA_RAMP_SIZE
+ if (_glfwLibrary.originalRampSize != GLFW_GAMMA_RAMP_SIZE)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "X11/GLX: Failed to get gamma ramp due to size "
+ "incompatibility");
+ return;
+ }
+
if (_glfwLibrary.X11.RandR.available &&
!_glfwLibrary.X11.RandR.gammaBroken)
{
@@ -85,6 +162,15 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp)
{
+ // For now, don't support anything that is not GLFW_GAMMA_RAMP_SIZE
+ if (_glfwLibrary.originalRampSize != GLFW_GAMMA_RAMP_SIZE)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "X11/GLX: Failed to set gamma ramp due to size "
+ "incompatibility");
+ return;
+ }
+
if (_glfwLibrary.X11.RandR.available &&
!_glfwLibrary.X11.RandR.gammaBroken)
{
diff --git a/src/x11_init.c b/src/x11_init.c
index 5697eb37..654e9fc9 100644
--- a/src/x11_init.c
+++ b/src/x11_init.c
@@ -30,37 +30,9 @@
#include "internal.h"
-#include
#include
#include
-
-
-//========================================================================
-// Dynamically load libraries
-//========================================================================
-
-static void initLibraries(void)
-{
-#ifdef _GLFW_DLOPEN_LIBGL
- int i;
- char* libGL_names[ ] =
- {
- "libGL.so",
- "libGL.so.1",
- "/usr/lib/libGL.so",
- "/usr/lib/libGL.so.1",
- NULL
- };
-
- _glfwLibrary.X11.libGL = NULL;
- for (i = 0; libGL_names[i] != NULL; i++)
- {
- _glfwLibrary.X11.libGL = dlopen(libGL_names[i], RTLD_LAZY | RTLD_GLOBAL);
- if (_glfwLibrary.X11.libGL)
- break;
- }
-#endif
-}
+#include
//========================================================================
@@ -79,7 +51,11 @@ static int keyCodeToGLFWKeyCode(int keyCode)
// Note: This way we always force "NumLock = ON", which is intentional
// since the returned key code should correspond to a physical
// location.
+#if defined(_GLFW_HAS_XKB)
+ keySym = XkbKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 1, 0);
+#else
keySym = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 1);
+#endif
switch (keySym)
{
case XK_KP_0: return GLFW_KEY_KP_0;
@@ -102,7 +78,12 @@ static int keyCodeToGLFWKeyCode(int keyCode)
// Now try pimary keysym for function keys (non-printable keys). These
// should not be layout dependent (i.e. US layout and international
// layouts should give the same result).
+#if defined(_GLFW_HAS_XKB)
+ keySym = XkbKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 0, 0);
+#else
keySym = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 0);
+#endif
+
switch (keySym)
{
case XK_Escape: return GLFW_KEY_ESCAPE;
@@ -252,10 +233,8 @@ static void updateKeyCodeLUT(void)
int keyCode;
// Clear the LUT
- for (keyCode = 0; keyCode < 256; ++keyCode)
- {
+ for (keyCode = 0; keyCode < 256; keyCode++)
_glfwLibrary.X11.keyCodeLUT[keyCode] = -1;
- }
#if defined(_GLFW_HAS_XKB)
// If the Xkb extension is available, use it to determine physical key
@@ -263,7 +242,7 @@ static void updateKeyCodeLUT(void)
if (_glfwLibrary.X11.Xkb.available)
{
int i, keyCodeGLFW;
- char name[XkbKeyNameLength+1];
+ char name[XkbKeyNameLength + 1];
XkbDescPtr descr;
// Get keyboard description
@@ -275,10 +254,9 @@ static void updateKeyCodeLUT(void)
for (keyCode = descr->min_key_code; keyCode <= descr->max_key_code; ++keyCode)
{
// Get the key name
- for (i = 0; i < XkbKeyNameLength; ++i)
- {
+ for (i = 0; i < XkbKeyNameLength; i++)
name[i] = descr->names->keys[keyCode].name[i];
- }
+
name[XkbKeyNameLength] = 0;
// Map the key name to a GLFW key code. Note: We only map printable
@@ -337,9 +315,7 @@ static void updateKeyCodeLUT(void)
// Update the key code LUT
if ((keyCode >= 0) && (keyCode < 256))
- {
_glfwLibrary.X11.keyCodeLUT[keyCode] = keyCodeGLFW;
- }
}
// Free the keyboard description
@@ -349,7 +325,7 @@ static void updateKeyCodeLUT(void)
// Translate the un-translated key codes using traditional X11 KeySym
// lookups
- for (keyCode = 0; keyCode < 256; ++keyCode)
+ for (keyCode = 0; keyCode < 256; keyCode++)
{
if (_glfwLibrary.X11.keyCodeLUT[keyCode] < 0)
{
@@ -360,6 +336,152 @@ static void updateKeyCodeLUT(void)
}
+//========================================================================
+// Retrieve a single window property of the specified type
+// Inspired by fghGetWindowProperty from freeglut
+//========================================================================
+
+static unsigned long getWindowProperty(Window window,
+ Atom property,
+ Atom type,
+ unsigned char** value)
+{
+ Atom actualType;
+ int actualFormat;
+ unsigned long itemCount, bytesAfter;
+
+ XGetWindowProperty(_glfwLibrary.X11.display,
+ window,
+ property,
+ 0,
+ LONG_MAX,
+ False,
+ type,
+ &actualType,
+ &actualFormat,
+ &itemCount,
+ &bytesAfter,
+ value);
+
+ if (actualType != type)
+ return 0;
+
+ return itemCount;
+}
+
+
+//========================================================================
+// Check whether the specified atom is supported
+//========================================================================
+
+static Atom getSupportedAtom(Atom* supportedAtoms,
+ unsigned long atomCount,
+ const char* atomName)
+{
+ Atom atom = XInternAtom(_glfwLibrary.X11.display, atomName, True);
+ if (atom != None)
+ {
+ unsigned long i;
+
+ for (i = 0; i < atomCount; i++)
+ {
+ if (supportedAtoms[i] == atom)
+ return atom;
+ }
+ }
+
+ return None;
+}
+
+
+//========================================================================
+// Check whether the running window manager is EWMH-compliant
+//========================================================================
+
+static void initEWMH(void)
+{
+ Window* windowFromRoot = NULL;
+ Window* windowFromChild = NULL;
+
+ // First we need a couple of atoms, which should already be there
+ Atom supportingWmCheck =
+ XInternAtom(_glfwLibrary.X11.display, "_NET_SUPPORTING_WM_CHECK", True);
+ Atom wmSupported =
+ XInternAtom(_glfwLibrary.X11.display, "_NET_SUPPORTED", True);
+ if (supportingWmCheck == None || wmSupported == None)
+ return;
+
+ // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
+ if (getWindowProperty(_glfwLibrary.X11.root,
+ supportingWmCheck,
+ XA_WINDOW,
+ (unsigned char**) &windowFromRoot) != 1)
+ {
+ XFree(windowFromRoot);
+ return;
+ }
+
+ // It should be the ID of a child window (of the root)
+ // Then we look for the same property on the child window
+ if (getWindowProperty(*windowFromRoot,
+ supportingWmCheck,
+ XA_WINDOW,
+ (unsigned char**) &windowFromChild) != 1)
+ {
+ XFree(windowFromRoot);
+ XFree(windowFromChild);
+ return;
+ }
+
+ // It should be the ID of that same child window
+ if (*windowFromRoot != *windowFromChild)
+ {
+ XFree(windowFromRoot);
+ XFree(windowFromChild);
+ return;
+ }
+
+ XFree(windowFromRoot);
+ XFree(windowFromChild);
+
+ // We are now fairly sure that an EWMH-compliant window manager is running
+
+ Atom* supportedAtoms;
+ unsigned long atomCount;
+
+ // 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
+ atomCount = getWindowProperty(_glfwLibrary.X11.root,
+ wmSupported,
+ XA_ATOM,
+ (unsigned char**) &supportedAtoms);
+
+ // See which of the atoms we support that are supported by the WM
+
+ _glfwLibrary.X11.wmState =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
+
+ _glfwLibrary.X11.wmStateFullscreen =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
+
+ _glfwLibrary.X11.wmName =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME");
+
+ _glfwLibrary.X11.wmIconName =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_ICON_NAME");
+
+ _glfwLibrary.X11.wmPing =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING");
+
+ _glfwLibrary.X11.wmActiveWindow =
+ getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
+
+ XFree(supportedAtoms);
+
+ _glfwLibrary.X11.hasEWMH = GL_TRUE;
+}
+
+
//========================================================================
// Initialize X11 display and look for supported X11 extensions
//========================================================================
@@ -411,22 +533,6 @@ static GLboolean initDisplay(void)
_glfwLibrary.X11.RandR.available = GL_FALSE;
#endif /*_GLFW_HAS_XRANDR*/
- // Check if GLX is supported on this display
- if (!glXQueryExtension(_glfwLibrary.X11.display, NULL, NULL))
- {
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: GLX supported not found");
- return GL_FALSE;
- }
-
- if (!glXQueryVersion(_glfwLibrary.X11.display,
- &_glfwLibrary.X11.glxMajor,
- &_glfwLibrary.X11.glxMinor))
- {
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
- "X11/GLX: Failed to query GLX version");
- return GL_FALSE;
- }
-
// Check if Xkb is supported on this display
#if defined(_GLFW_HAS_XKB)
_glfwLibrary.X11.Xkb.majorVersion = 1;
@@ -447,65 +553,30 @@ static GLboolean initDisplay(void)
// the keyboard mapping.
updateKeyCodeLUT();
+ // Find or create selection property atom
+ _glfwLibrary.X11.selection.property =
+ XInternAtom(_glfwLibrary.X11.display, "GLFW_SELECTION", False);
+
+ // Find or create clipboard atom
+ _glfwLibrary.X11.selection.atom =
+ XInternAtom(_glfwLibrary.X11.display, "CLIPBOARD", False);
+
+ // Find or create selection target atoms
+ _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_UTF8] =
+ XInternAtom(_glfwLibrary.X11.display, "UTF8_STRING", False);
+ _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_COMPOUND] =
+ XInternAtom(_glfwLibrary.X11.display, "COMPOUND_STRING", False);
+ _glfwLibrary.X11.selection.formats[_GLFW_CLIPBOARD_FORMAT_STRING] =
+ XA_STRING;
+
+ _glfwLibrary.X11.selection.targets = XInternAtom(_glfwLibrary.X11.display,
+ "TARGETS",
+ False);
+
return GL_TRUE;
}
-//========================================================================
-// Detect gamma ramp support and save original gamma ramp, if available
-//========================================================================
-
-static void initGammaRamp(void)
-{
-#ifdef _GLFW_HAS_XRANDR
- // RandR gamma support is only available with version 1.2 and above
- if (_glfwLibrary.X11.RandR.available &&
- (_glfwLibrary.X11.RandR.majorVersion > 1 ||
- _glfwLibrary.X11.RandR.majorVersion == 1 &&
- _glfwLibrary.X11.RandR.minorVersion >= 2))
- {
- // FIXME: Assumes that all monitors have the same size gamma tables
- // This is reasonable as I suspect the that if they did differ, it
- // would imply that setting the gamma size to an arbitary size is
- // possible as well.
- XRRScreenResources* rr = XRRGetScreenResources(_glfwLibrary.X11.display,
- _glfwLibrary.X11.root);
-
- _glfwLibrary.originalRampSize = XRRGetCrtcGammaSize(_glfwLibrary.X11.display,
- rr->crtcs[0]);
- if (!_glfwLibrary.originalRampSize)
- {
- // This is probably Nvidia RandR with broken gamma support
- // Flag it as useless and try Xf86VidMode below, if available
- _glfwLibrary.X11.RandR.gammaBroken = GL_TRUE;
- fprintf(stderr,
- "Ignoring broken nVidia implementation of RandR 1.2+ gamma\n");
- }
-
- XRRFreeScreenResources(rr);
- }
-#endif /*_GLFW_HAS_XRANDR*/
-
-#if defined(_GLFW_HAS_XF86VIDMODE)
- if (_glfwLibrary.X11.VidMode.available &&
- !_glfwLibrary.originalRampSize)
- {
- // Get the gamma size using XF86VidMode
- XF86VidModeGetGammaRampSize(_glfwLibrary.X11.display,
- _glfwLibrary.X11.screen,
- &_glfwLibrary.originalRampSize);
- }
-#endif /*_GLFW_HAS_XF86VIDMODE*/
-
- if (!_glfwLibrary.originalRampSize)
- fprintf(stderr, "No supported gamma ramp API found\n");
-
- // Save the original gamma ramp
- _glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp);
- _glfwLibrary.currentRamp = _glfwLibrary.originalRamp;
-}
-
-
//========================================================================
// Create a blank cursor (for locked mouse mode)
//========================================================================
@@ -545,9 +616,6 @@ static Cursor createNULLCursor(void)
static void terminateDisplay(void)
{
- if (_glfwLibrary.originalRampSize)
- _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
-
if (_glfwLibrary.X11.display)
{
XCloseDisplay(_glfwLibrary.X11.display);
@@ -569,13 +637,15 @@ int _glfwPlatformInit(void)
if (!initDisplay())
return GL_FALSE;
- initGammaRamp();
+ _glfwInitGammaRamp();
+
+ if (!_glfwInitOpenGL())
+ return GL_FALSE;
+
+ initEWMH();
_glfwLibrary.X11.cursor = createNULLCursor();
- // Try to load libGL.so if necessary
- initLibraries();
-
_glfwInitJoysticks();
_glfwInitMonitors();
@@ -599,20 +669,19 @@ int _glfwPlatformTerminate(void)
_glfwLibrary.X11.cursor = (Cursor) 0;
}
+ _glfwTerminateGammaRamp();
+
terminateDisplay();
_glfwTerminateMonitors();
_glfwTerminateJoysticks();
- // Unload libGL.so if necessary
-#ifdef _GLFW_DLOPEN_LIBGL
- if (_glfwLibrary.X11.libGL != NULL)
- {
- dlclose(_glfwLibrary.X11.libGL);
- _glfwLibrary.X11.libGL = NULL;
- }
-#endif
+ _glfwTerminateOpenGL();
+
+ // Free clipboard memory
+ if (_glfwLibrary.X11.selection.string)
+ free(_glfwLibrary.X11.selection.string);
return GL_TRUE;
}
@@ -655,6 +724,9 @@ const char* _glfwPlatformGetVersionString(void)
" Linux-joystick-API"
#else
" no-joystick-support"
+#endif
+#if defined(_GLFW_BUILD_DLL)
+ " shared"
#endif
;
diff --git a/src/x11_monitor.c b/src/x11_monitor.c
index d22bcda7..d22c1c59 100644
--- a/src/x11_monitor.c
+++ b/src/x11_monitor.c
@@ -43,13 +43,13 @@ _GLFWmonitor** _glfwCreateMonitor(_GLFWmonitor** current,
XRROutputInfo* outputInfo,
XRRCrtcInfo* crtcInfo)
{
- *current = _glfwMalloc(sizeof(_GLFWmonitor));
+ *current = malloc(sizeof(_GLFWmonitor));
memset(*current, 0, sizeof(_GLFWmonitor));
(*current)->physicalWidth = outputInfo->mm_width;
(*current)->physicalHeight = outputInfo->mm_height;
- (*current)->name = _glfwMalloc(strlen(outputInfo->name) + 1);
+ (*current)->name = malloc(strlen(outputInfo->name) + 1);
memcpy((*current)->name, outputInfo->name, strlen(outputInfo->name) + 1);
(*current)->name[strlen(outputInfo->name)] = '\0';
@@ -71,8 +71,8 @@ _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor)
XRRFreeOutputInfo(monitor->X11.output);
#endif /*_GLFW_HAS_XRANDR*/
- _glfwFree(monitor->name);
- _glfwFree(monitor);
+ free(monitor->name);
+ free(monitor);
return result;
}
diff --git a/src/x11_opengl.c b/src/x11_opengl.c
index fd8bd313..dc2788c8 100644
--- a/src/x11_opengl.c
+++ b/src/x11_opengl.c
@@ -30,15 +30,656 @@
#include "internal.h"
+#include
+#include
+
// This is the only glXGetProcAddress variant not declared by glxext.h
void (*glXGetProcAddressEXT(const GLubyte* procName))();
+//========================================================================
+// Returns the specified attribute of the specified GLXFBConfig
+// NOTE: Do not call this unless we have found GLX 1.3+ or GLX_SGIX_fbconfig
+//========================================================================
+
+static int getFBConfigAttrib(_GLFWwindow* window, GLXFBConfig fbconfig, int attrib)
+{
+ int value;
+
+ if (_glfwLibrary.GLX.SGIX_fbconfig)
+ {
+ _glfwLibrary.GLX.GetFBConfigAttribSGIX(_glfwLibrary.X11.display,
+ fbconfig, attrib, &value);
+ }
+ else
+ glXGetFBConfigAttrib(_glfwLibrary.X11.display, fbconfig, attrib, &value);
+
+ return value;
+}
+
+
+//========================================================================
+// Return a list of available and usable framebuffer configs
+//========================================================================
+
+static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
+{
+ GLXFBConfig* fbconfigs;
+ _GLFWfbconfig* result;
+ int i, count = 0;
+ const char* vendor;
+ GLboolean trustWindowBit = GL_TRUE;
+
+ *found = 0;
+
+ if (_glfwLibrary.GLX.majorVersion == 1 && _glfwLibrary.GLX.minorVersion < 3)
+ {
+ if (!_glfwLibrary.GLX.SGIX_fbconfig)
+ {
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
+ "X11/GLX: GLXFBConfig support not found");
+ return NULL;
+ }
+ }
+
+ vendor = glXGetClientString(_glfwLibrary.X11.display, GLX_VENDOR);
+
+ if (strcmp(vendor, "Chromium") == 0)
+ {
+ // This is a (hopefully temporary) workaround for Chromium (VirtualBox
+ // GL) not setting the window bit on any GLXFBConfigs
+ trustWindowBit = GL_FALSE;
+ }
+
+ if (_glfwLibrary.GLX.SGIX_fbconfig)
+ {
+ fbconfigs = _glfwLibrary.GLX.ChooseFBConfigSGIX(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ NULL,
+ &count);
+ if (!count)
+ {
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
+ "X11/GLX: No GLXFBConfigs returned");
+ return NULL;
+ }
+ }
+ else
+ {
+ fbconfigs = glXGetFBConfigs(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ &count);
+ if (!count)
+ {
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
+ "X11/GLX: No GLXFBConfigs returned");
+ return NULL;
+ }
+ }
+
+ result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count);
+ if (!result)
+ {
+ _glfwSetError(GLFW_OUT_OF_MEMORY,
+ "X11/GLX: Failed to allocate _GLFWfbconfig array");
+ return NULL;
+ }
+
+ for (i = 0; i < count; i++)
+ {
+ _GLFWfbconfig* f = result + *found;
+
+ if (!getFBConfigAttrib(window, fbconfigs[i], GLX_DOUBLEBUFFER) ||
+ !getFBConfigAttrib(window, fbconfigs[i], GLX_VISUAL_ID))
+ {
+ // Only consider double-buffered GLXFBConfigs with associated visuals
+ continue;
+ }
+
+ if (!(getFBConfigAttrib(window,
+ fbconfigs[i],
+ GLX_RENDER_TYPE) & GLX_RGBA_BIT))
+ {
+ // Only consider RGBA GLXFBConfigs
+ continue;
+ }
+
+ if (!(getFBConfigAttrib(window, fbconfigs[i], GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))
+ {
+ if (trustWindowBit)
+ {
+ // Only consider window GLXFBConfigs
+ continue;
+ }
+ }
+
+ f->redBits = getFBConfigAttrib(window, fbconfigs[i], GLX_RED_SIZE);
+ f->greenBits = getFBConfigAttrib(window, fbconfigs[i], GLX_GREEN_SIZE);
+ f->blueBits = getFBConfigAttrib(window, fbconfigs[i], GLX_BLUE_SIZE);
+
+ f->alphaBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ALPHA_SIZE);
+ f->depthBits = getFBConfigAttrib(window, fbconfigs[i], GLX_DEPTH_SIZE);
+ f->stencilBits = getFBConfigAttrib(window, fbconfigs[i], GLX_STENCIL_SIZE);
+
+ f->accumRedBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_RED_SIZE);
+ f->accumGreenBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_GREEN_SIZE);
+ f->accumBlueBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_BLUE_SIZE);
+ f->accumAlphaBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_ALPHA_SIZE);
+
+ f->auxBuffers = getFBConfigAttrib(window, fbconfigs[i], GLX_AUX_BUFFERS);
+ f->stereo = getFBConfigAttrib(window, fbconfigs[i], GLX_STEREO);
+
+ if (_glfwLibrary.GLX.ARB_multisample)
+ f->samples = getFBConfigAttrib(window, fbconfigs[i], GLX_SAMPLES);
+ else
+ f->samples = 0;
+
+ f->platformID = (GLFWintptr) getFBConfigAttrib(window, fbconfigs[i], GLX_FBCONFIG_ID);
+
+ (*found)++;
+ }
+
+ XFree(fbconfigs);
+
+ return result;
+}
+
+
+//========================================================================
+// Error handler for BadMatch errors when requesting context with
+// unavailable OpenGL versions using the GLX_ARB_create_context extension
+//========================================================================
+
+static int errorHandler(Display *display, XErrorEvent* event)
+{
+ return 0;
+}
+
+
+//========================================================================
+// Read back framebuffer parameters from the context
+//========================================================================
+
+static void refreshContextParams(_GLFWwindow* window, GLXFBConfigID fbconfigID)
+{
+ int dummy;
+ GLXFBConfig* fbconfig;
+
+ int attribs[] = { GLX_FBCONFIG_ID, fbconfigID, None };
+
+ if (_glfwLibrary.GLX.SGIX_fbconfig)
+ {
+ fbconfig = _glfwLibrary.GLX.ChooseFBConfigSGIX(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ attribs,
+ &dummy);
+ }
+ else
+ {
+ fbconfig = glXChooseFBConfig(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ attribs,
+ &dummy);
+ }
+
+ if (fbconfig == NULL)
+ {
+ // This should never ever happen
+ // TODO: Flag this as an error and propagate up
+ _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Cannot find known "
+ "GLXFBConfig by ID. This cannot "
+ "happen. Have a nice day.\n");
+ abort();
+ }
+
+ // There is no clear definition of an "accelerated" context on X11/GLX, and
+ // true sounds better than false, so we hardcode true here
+ window->accelerated = GL_TRUE;
+
+ window->redBits = getFBConfigAttrib(window, *fbconfig, GLX_RED_SIZE);
+ window->greenBits = getFBConfigAttrib(window, *fbconfig, GLX_GREEN_SIZE);
+ window->blueBits = getFBConfigAttrib(window, *fbconfig, GLX_BLUE_SIZE);
+
+ window->alphaBits = getFBConfigAttrib(window, *fbconfig, GLX_ALPHA_SIZE);
+ window->depthBits = getFBConfigAttrib(window, *fbconfig, GLX_DEPTH_SIZE);
+ window->stencilBits = getFBConfigAttrib(window, *fbconfig, GLX_STENCIL_SIZE);
+
+ window->accumRedBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_RED_SIZE);
+ window->accumGreenBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_GREEN_SIZE);
+ window->accumBlueBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_BLUE_SIZE);
+ window->accumAlphaBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_ALPHA_SIZE);
+
+ window->auxBuffers = getFBConfigAttrib(window, *fbconfig, GLX_AUX_BUFFERS);
+ window->stereo = getFBConfigAttrib(window, *fbconfig, GLX_STEREO) ? GL_TRUE : GL_FALSE;
+
+ // Get FSAA buffer sample count
+ if (_glfwLibrary.GLX.ARB_multisample)
+ window->samples = getFBConfigAttrib(window, *fbconfig, GLX_SAMPLES);
+ else
+ window->samples = 0;
+
+ XFree(fbconfig);
+}
+
+
+//========================================================================
+// Create the actual OpenGL context
+//========================================================================
+
+#define setGLXattrib(attribs, index, attribName, attribValue) \
+ attribs[index++] = attribName; \
+ attribs[index++] = attribValue;
+
+static int createContext(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ GLXFBConfigID fbconfigID)
+{
+ int attribs[40];
+ int dummy, index;
+ GLXFBConfig* fbconfig;
+ GLXContext share = NULL;
+
+ if (wndconfig->share)
+ share = wndconfig->share->GLX.context;
+
+ // Retrieve the previously selected GLXFBConfig
+ {
+ index = 0;
+
+ setGLXattrib(attribs, index, GLX_FBCONFIG_ID, (int) fbconfigID);
+ setGLXattrib(attribs, index, None, None);
+
+ if (_glfwLibrary.GLX.SGIX_fbconfig)
+ {
+ fbconfig = _glfwLibrary.GLX.ChooseFBConfigSGIX(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ attribs,
+ &dummy);
+ }
+ else
+ {
+ fbconfig = glXChooseFBConfig(_glfwLibrary.X11.display,
+ _glfwLibrary.X11.screen,
+ attribs,
+ &dummy);
+ }
+
+ if (fbconfig == NULL)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "X11/GLX: Failed to retrieve the selected GLXFBConfig");
+ return GL_FALSE;
+ }
+ }
+
+ // Retrieve the corresponding visual
+ if (_glfwLibrary.GLX.SGIX_fbconfig)
+ {
+ window->GLX.visual = _glfwLibrary.GLX.GetVisualFromFBConfigSGIX(_glfwLibrary.X11.display,
+ *fbconfig);
+ }
+ else
+ {
+ window->GLX.visual = glXGetVisualFromFBConfig(_glfwLibrary.X11.display,
+ *fbconfig);
+ }
+
+ if (window->GLX.visual == NULL)
+ {
+ XFree(fbconfig);
+
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "X11/GLX: Failed to retrieve visual for GLXFBConfig");
+ return GL_FALSE;
+ }
+
+ if (_glfwLibrary.GLX.ARB_create_context)
+ {
+ index = 0;
+
+ if (wndconfig->glMajor != 1 || wndconfig->glMinor != 0)
+ {
+ // Request an explicitly versioned context
+
+ setGLXattrib(attribs, index, GLX_CONTEXT_MAJOR_VERSION_ARB, wndconfig->glMajor);
+ setGLXattrib(attribs, index, GLX_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor);
+ }
+
+ if (wndconfig->glForward || wndconfig->glDebug || wndconfig->glRobustness)
+ {
+ int flags = 0;
+
+ if (wndconfig->glForward)
+ flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
+
+ if (wndconfig->glDebug)
+ flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
+
+ if (wndconfig->glRobustness)
+ flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
+
+ setGLXattrib(attribs, index, GLX_CONTEXT_FLAGS_ARB, flags);
+ }
+
+ if (wndconfig->glProfile)
+ {
+ int flags = 0;
+
+ if (!_glfwLibrary.GLX.ARB_create_context_profile)
+ {
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE,
+ "X11/GLX: An OpenGL profile requested but "
+ "GLX_ARB_create_context_profile is unavailable");
+ return GL_FALSE;
+ }
+
+ if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
+ !_glfwLibrary.GLX.EXT_create_context_es2_profile)
+ {
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE,
+ "X11/GLX: OpenGL ES 2.x profile requested but "
+ "GLX_EXT_create_context_es2_profile is unavailable");
+ return GL_FALSE;
+ }
+
+ if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE)
+ flags = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+ else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE)
+ flags = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
+ else if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE)
+ flags = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
+
+ setGLXattrib(attribs, index, GLX_CONTEXT_PROFILE_MASK_ARB, flags);
+ }
+
+ if (wndconfig->glRobustness)
+ {
+ int strategy;
+
+ if (!_glfwLibrary.GLX.ARB_create_context_robustness)
+ {
+ _glfwSetError(GLFW_VERSION_UNAVAILABLE,
+ "X11/GLX: An OpenGL robustness strategy was "
+ "requested but GLX_ARB_create_context_robustness "
+ "is unavailable");
+ return GL_FALSE;
+ }
+
+ if (wndconfig->glRobustness == GLFW_OPENGL_NO_RESET_NOTIFICATION)
+ strategy = GLX_NO_RESET_NOTIFICATION_ARB;
+ else if (wndconfig->glRobustness == GLFW_OPENGL_LOSE_CONTEXT_ON_RESET)
+ strategy = GLX_LOSE_CONTEXT_ON_RESET_ARB;
+
+ setGLXattrib(attribs,
+ index,
+ GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
+ strategy);
+ }
+
+ setGLXattrib(attribs, index, None, None);
+
+ // This is the only place we set an Xlib error handler, and we only do
+ // it because glXCreateContextAttribsARB generates a BadMatch error if
+ // the requested OpenGL version is unavailable (instead of a civilized
+ // response like returning NULL)
+ XSetErrorHandler(errorHandler);
+
+ window->GLX.context =
+ _glfwLibrary.GLX.CreateContextAttribsARB(_glfwLibrary.X11.display,
+ *fbconfig,
+ share,
+ True,
+ attribs);
+
+ // We are done, so unset the error handler again (see above)
+ XSetErrorHandler(NULL);
+ }
+ else
+ {
+ if (_glfwLibrary.GLX.SGIX_fbconfig)
+ {
+ window->GLX.context =
+ _glfwLibrary.GLX.CreateContextWithConfigSGIX(_glfwLibrary.X11.display,
+ *fbconfig,
+ GLX_RGBA_TYPE,
+ share,
+ True);
+ }
+ else
+ {
+ window->GLX.context = glXCreateNewContext(_glfwLibrary.X11.display,
+ *fbconfig,
+ GLX_RGBA_TYPE,
+ share,
+ True);
+ }
+ }
+
+ XFree(fbconfig);
+
+ if (window->GLX.context == NULL)
+ {
+ // TODO: Handle all the various error codes here
+
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "X11/GLX: Failed to create OpenGL context");
+ return GL_FALSE;
+ }
+
+ refreshContextParams(window, fbconfigID);
+
+ return GL_TRUE;
+}
+
+#undef setGLXattrib
+
+
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
+//========================================================================
+// Initialize GLX
+//========================================================================
+
+int _glfwInitOpenGL(void)
+{
+#ifdef _GLFW_DLOPEN_LIBGL
+ int i;
+ char* libGL_names[ ] =
+ {
+ "libGL.so",
+ "libGL.so.1",
+ "/usr/lib/libGL.so",
+ "/usr/lib/libGL.so.1",
+ NULL
+ };
+
+ for (i = 0; libGL_names[i] != NULL; i++)
+ {
+ _glfwLibrary.GLX.libGL = dlopen(libGL_names[i], RTLD_LAZY | RTLD_GLOBAL);
+ if (_glfwLibrary.GLX.libGL)
+ break;
+ }
+
+ if (!_glfwLibrary.GLX.libGL)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR, "X11/GLX: Failed to find libGL");
+ return GL_FALSE;
+ }
+#endif
+
+ // Check if GLX is supported on this display
+ if (!glXQueryExtension(_glfwLibrary.X11.display, NULL, NULL))
+ {
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: GLX supported not found");
+ return GL_FALSE;
+ }
+
+ if (!glXQueryVersion(_glfwLibrary.X11.display,
+ &_glfwLibrary.GLX.majorVersion,
+ &_glfwLibrary.GLX.minorVersion))
+ {
+ _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
+ "X11/GLX: Failed to query GLX version");
+ return GL_FALSE;
+ }
+
+ if (_glfwPlatformExtensionSupported("GLX_EXT_swap_control"))
+ {
+ _glfwLibrary.GLX.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
+ _glfwPlatformGetProcAddress("glXSwapIntervalEXT");
+
+ if (_glfwLibrary.GLX.SwapIntervalEXT)
+ _glfwLibrary.GLX.EXT_swap_control = GL_TRUE;
+ }
+
+ if (_glfwPlatformExtensionSupported("GLX_SGI_swap_control"))
+ {
+ _glfwLibrary.GLX.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
+ _glfwPlatformGetProcAddress("glXSwapIntervalSGI");
+
+ if (_glfwLibrary.GLX.SwapIntervalSGI)
+ _glfwLibrary.GLX.SGI_swap_control = GL_TRUE;
+ }
+
+ if (_glfwPlatformExtensionSupported("GLX_SGIX_fbconfig"))
+ {
+ _glfwLibrary.GLX.GetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)
+ _glfwPlatformGetProcAddress("glXGetFBConfigAttribSGIX");
+ _glfwLibrary.GLX.ChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)
+ _glfwPlatformGetProcAddress("glXChooseFBConfigSGIX");
+ _glfwLibrary.GLX.CreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)
+ _glfwPlatformGetProcAddress("glXCreateContextWithConfigSGIX");
+ _glfwLibrary.GLX.GetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)
+ _glfwPlatformGetProcAddress("glXGetVisualFromFBConfigSGIX");
+
+ if (_glfwLibrary.GLX.GetFBConfigAttribSGIX &&
+ _glfwLibrary.GLX.ChooseFBConfigSGIX &&
+ _glfwLibrary.GLX.CreateContextWithConfigSGIX &&
+ _glfwLibrary.GLX.GetVisualFromFBConfigSGIX)
+ {
+ _glfwLibrary.GLX.SGIX_fbconfig = GL_TRUE;
+ }
+ }
+
+ if (_glfwPlatformExtensionSupported("GLX_ARB_multisample"))
+ _glfwLibrary.GLX.ARB_multisample = GL_TRUE;
+
+ if (_glfwPlatformExtensionSupported("GLX_ARB_create_context"))
+ {
+ _glfwLibrary.GLX.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
+ _glfwPlatformGetProcAddress("glXCreateContextAttribsARB");
+
+ if (_glfwLibrary.GLX.CreateContextAttribsARB)
+ _glfwLibrary.GLX.ARB_create_context = GL_TRUE;
+ }
+
+ if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_robustness"))
+ _glfwLibrary.GLX.ARB_create_context_robustness = GL_TRUE;
+
+ if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_profile"))
+ _glfwLibrary.GLX.ARB_create_context_profile = GL_TRUE;
+
+ if (_glfwPlatformExtensionSupported("GLX_EXT_create_context_es2_profile"))
+ _glfwLibrary.GLX.EXT_create_context_es2_profile = GL_TRUE;
+
+ return GL_TRUE;
+}
+
+
+//========================================================================
+// Terminate GLX
+//========================================================================
+
+void _glfwTerminateOpenGL(void)
+{
+ // Unload libGL.so if necessary
+#ifdef _GLFW_DLOPEN_LIBGL
+ if (_glfwLibrary.GLX.libGL != NULL)
+ {
+ dlclose(_glfwLibrary.GLX.libGL);
+ _glfwLibrary.GLX.libGL = NULL;
+ }
+#endif
+}
+
+
+//========================================================================
+// Prepare for creation of the OpenGL context
+//========================================================================
+
+int _glfwCreateContext(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWfbconfig* fbconfig)
+{
+ _GLFWfbconfig closest;
+
+ // Choose the best available fbconfig
+ {
+ unsigned int fbcount;
+ _GLFWfbconfig* fbconfigs;
+ const _GLFWfbconfig* result;
+
+ fbconfigs = getFBConfigs(window, &fbcount);
+ if (!fbconfigs)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "X11/GLX: No usable GLXFBConfigs found");
+ return GL_FALSE;
+ }
+
+ result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
+ if (!result)
+ {
+ _glfwSetError(GLFW_PLATFORM_ERROR,
+ "X11/GLX: No GLXFBConfig matched the criteria");
+
+ free(fbconfigs);
+ return GL_FALSE;
+ }
+
+ closest = *result;
+ free(fbconfigs);
+ }
+
+ return createContext(window, wndconfig, closest.platformID);
+}
+
+
+//========================================================================
+// Destroy the OpenGL context
+//========================================================================
+
+void _glfwDestroyContext(_GLFWwindow* window)
+{
+ if (window->GLX.visual)
+ {
+ XFree(window->GLX.visual);
+ window->GLX.visual = NULL;
+ }
+
+ if (window->GLX.context)
+ {
+ // Release and destroy the context
+ glXMakeCurrent(_glfwLibrary.X11.display, None, NULL);
+ glXDestroyContext(_glfwLibrary.X11.display, window->GLX.context);
+ window->GLX.context = NULL;
+ }
+}
+
+
+//========================================================================
+// Return the X visual associated with the specified context
+//========================================================================
+
+XVisualInfo* _glfwGetContextVisual(_GLFWwindow* window)
+{
+ return window->GLX.visual;
+}
+
+
//========================================================================
// Make the OpenGL context associated with the specified window current
//========================================================================
@@ -75,14 +716,14 @@ void _glfwPlatformSwapInterval(int interval)
{
_GLFWwindow* window = _glfwLibrary.currentWindow;
- if (window->GLX.EXT_swap_control)
+ if (_glfwLibrary.GLX.EXT_swap_control)
{
- window->GLX.SwapIntervalEXT(_glfwLibrary.X11.display,
- window->X11.handle,
- interval);
+ _glfwLibrary.GLX.SwapIntervalEXT(_glfwLibrary.X11.display,
+ window->X11.handle,
+ interval);
}
- else if (window->GLX.SGI_swap_control)
- window->GLX.SwapIntervalSGI(interval);
+ else if (_glfwLibrary.GLX.SGI_swap_control)
+ _glfwLibrary.GLX.SwapIntervalSGI(interval);
}
@@ -111,9 +752,9 @@ int _glfwPlatformExtensionSupported(const char* extension)
// Get the function pointer to an OpenGL function
//========================================================================
-void* _glfwPlatformGetProcAddress(const char* procname)
+GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
{
- return (void*) _glfw_glXGetProcAddress((const GLubyte*) procname);
+ return _glfw_glXGetProcAddress((const GLubyte*) procname);
}
diff --git a/src/x11_platform.h b/src/x11_platform.h
index 1163a53f..69192993 100644
--- a/src/x11_platform.h
+++ b/src/x11_platform.h
@@ -75,17 +75,31 @@
#elif defined(_GLFW_HAS_GLXGETPROCADDRESSEXT)
#define _glfw_glXGetProcAddress(x) glXGetProcAddressEXT(x)
#elif defined(_GLFW_HAS_DLOPEN)
- #define _glfw_glXGetProcAddress(x) dlsym(_glfwLibrary.X11.libGL, x)
+ #define _glfw_glXGetProcAddress(x) dlsym(_glfwLibrary.GLX.libGL, x)
#define _GLFW_DLOPEN_LIBGL
#else
#error "No OpenGL entry point retrieval mechanism was enabled"
#endif
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 X11
-#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
+
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 X11
+#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 X11
+#define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryGLX GLX
+
+// Clipboard format atom indices
+#define _GLFW_CLIPBOARD_FORMAT_UTF8 0
+#define _GLFW_CLIPBOARD_FORMAT_COMPOUND 1
+#define _GLFW_CLIPBOARD_FORMAT_STRING 2
+#define _GLFW_CLIPBOARD_FORMAT_COUNT 3
+
+// Clipboard conversion status tokens
+#define _GLFW_CONVERSION_INACTIVE 0
+#define _GLFW_CONVERSION_SUCCEEDED 1
+#define _GLFW_CONVERSION_FAILED 2
+
//========================================================================
// GLFW platform specific types
@@ -102,27 +116,9 @@ typedef intptr_t GLFWintptr;
//------------------------------------------------------------------------
typedef struct _GLFWcontextGLX
{
- GLXFBConfigID fbconfigID; // ID of selected GLXFBConfig
GLXContext context; // OpenGL rendering context
XVisualInfo* visual; // Visual for selected GLXFBConfig
- // GLX extensions
- PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
- PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
- PFNGLXGETFBCONFIGATTRIBSGIXPROC GetFBConfigAttribSGIX;
- PFNGLXCHOOSEFBCONFIGSGIXPROC ChooseFBConfigSGIX;
- PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC CreateContextWithConfigSGIX;
- PFNGLXGETVISUALFROMFBCONFIGSGIXPROC GetVisualFromFBConfigSGIX;
- PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
- GLboolean SGIX_fbconfig;
- GLboolean SGI_swap_control;
- GLboolean EXT_swap_control;
- GLboolean ARB_multisample;
- GLboolean ARB_create_context;
- GLboolean ARB_create_context_profile;
- GLboolean ARB_create_context_robustness;
- GLboolean EXT_create_context_es2_profile;
-
} _GLFWcontextGLX;
@@ -134,16 +130,8 @@ typedef struct _GLFWwindowX11
// Platform specific window resources
Colormap colormap; // Window colormap
Window handle; // Window handle
- Atom wmDeleteWindow; // WM_DELETE_WINDOW atom
- Atom wmName; // _NET_WM_NAME atom
- Atom wmIconName; // _NET_WM_ICON_NAME atom
- Atom wmPing; // _NET_WM_PING atom
- Atom wmState; // _NET_WM_STATE atom
- Atom wmStateFullscreen; // _NET_WM_STATE_FULLSCREEN atom
- Atom wmActiveWindow; // _NET_ACTIVE_WINDOW atom
// Various platform specific internal variables
- GLboolean hasEWMH; // True if window manager supports EWMH
GLboolean overrideRedirect; // True if window is OverrideRedirect
GLboolean keyboardGrabbed; // True if keyboard is currently grabbed
GLboolean cursorGrabbed; // True if cursor is currently grabbed
@@ -155,7 +143,7 @@ typedef struct _GLFWwindowX11
//------------------------------------------------------------------------
-// Platform-specific library global data
+// Platform-specific library global data for X11
//------------------------------------------------------------------------
typedef struct _GLFWlibraryX11
{
@@ -164,8 +152,16 @@ typedef struct _GLFWlibraryX11
Window root;
Cursor cursor; // Invisible cursor for hidden cursor
- // Server-side GLX version
- int glxMajor, glxMinor;
+ Atom wmDeleteWindow; // WM_DELETE_WINDOW atom
+ Atom wmName; // _NET_WM_NAME atom
+ Atom wmIconName; // _NET_WM_ICON_NAME atom
+ Atom wmPing; // _NET_WM_PING atom
+ Atom wmState; // _NET_WM_STATE atom
+ Atom wmStateFullscreen; // _NET_WM_STATE_FULLSCREEN atom
+ Atom wmActiveWindow; // _NET_ACTIVE_WINDOW atom
+
+ // True if window manager supports EWMH
+ GLboolean hasEWMH;
struct {
GLboolean available;
@@ -224,10 +220,49 @@ typedef struct _GLFWlibraryX11
uint64_t base;
} timer;
+ // Selection data
+ struct {
+ Atom atom;
+ Atom formats[_GLFW_CLIPBOARD_FORMAT_COUNT];
+ char* string;
+ Atom target;
+ Atom targets;
+ Atom property;
+ int status;
+ } selection;
+
+} _GLFWlibraryX11;
+
+
+//------------------------------------------------------------------------
+// Platform-specific library global data for GLX
+//------------------------------------------------------------------------
+typedef struct _GLFWlibraryGLX
+{
+ // Server-side GLX version
+ int majorVersion, minorVersion;
+
+ // GLX extensions
+ PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
+ PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
+ PFNGLXGETFBCONFIGATTRIBSGIXPROC GetFBConfigAttribSGIX;
+ PFNGLXCHOOSEFBCONFIGSGIXPROC ChooseFBConfigSGIX;
+ PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC CreateContextWithConfigSGIX;
+ PFNGLXGETVISUALFROMFBCONFIGSGIXPROC GetVisualFromFBConfigSGIX;
+ PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
+ GLboolean SGIX_fbconfig;
+ GLboolean SGI_swap_control;
+ GLboolean EXT_swap_control;
+ GLboolean ARB_multisample;
+ GLboolean ARB_create_context;
+ GLboolean ARB_create_context_profile;
+ GLboolean ARB_create_context_robustness;
+ GLboolean EXT_create_context_es2_profile;
+
#if defined(_GLFW_DLOPEN_LIBGL)
void* libGL; // dlopen handle for libGL.so
#endif
-} _GLFWlibraryX11;
+} _GLFWlibraryGLX;
//------------------------------------------------------------------------
@@ -264,11 +299,24 @@ typedef struct _GLFWmonitorX11
// Time
void _glfwInitTimer(void);
+// Gamma
+void _glfwInitGammaRamp(void);
+void _glfwTerminateGammaRamp(void);
+
+// OpenGL support
+int _glfwInitOpenGL(void);
+void _glfwTerminateOpenGL(void);
+int _glfwCreateContext(_GLFWwindow* window,
+ const _GLFWwndconfig* wndconfig,
+ const _GLFWfbconfig* fbconfig);
+void _glfwDestroyContext(_GLFWwindow* window);
+XVisualInfo* _glfwGetContextVisual(_GLFWwindow* window);
+
// Fullscreen support
-int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate);
-void _glfwSetVideoModeMODE(int screen, int mode, int rate);
-void _glfwSetVideoMode(int screen, int* width, int* height, int* rate);
-void _glfwRestoreVideoMode(int screen);
+int _glfwGetClosestVideoMode(int* width, int* height, int* rate);
+void _glfwSetVideoModeMODE(int mode, int rate);
+void _glfwSetVideoMode(int* width, int* height, int* rate);
+void _glfwRestoreVideoMode(void);
// Joystick input
void _glfwInitJoysticks(void);
@@ -281,5 +329,11 @@ _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor);
// Unicode support
long _glfwKeySym2Unicode(KeySym keysym);
+// Clipboard handling
+GLboolean _glfwReadSelection(XSelectionEvent* request);
+Atom _glfwWriteSelection(XSelectionRequestEvent* request);
+
+// Event processing
+void _glfwProcessPendingEvents(void);
#endif // _platform_h_
diff --git a/src/x11_time.c b/src/x11_time.c
index e2203941..f1445233 100644
--- a/src/x11_time.c
+++ b/src/x11_time.c
@@ -30,6 +30,7 @@
#include "internal.h"
+#include
#include
@@ -39,7 +40,7 @@
static uint64_t getRawTime(void)
{
-#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
+#if defined(CLOCK_MONOTONIC)
if (_glfwLibrary.X11.timer.monotonic)
{
struct timespec ts;
@@ -64,7 +65,7 @@ static uint64_t getRawTime(void)
void _glfwInitTimer(void)
{
-#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
+#if defined(CLOCK_MONOTONIC)
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
diff --git a/src/x11_window.c b/src/x11_window.c
index 9eb315fd..5cc7f6f4 100644
--- a/src/x11_window.c
+++ b/src/x11_window.c
@@ -30,7 +30,6 @@
#include "internal.h"
-#include
#include
#include
#include
@@ -41,19 +40,8 @@
#define _NET_WM_STATE_TOGGLE 2
// Additional mouse button names for XButtonEvent
-#define Button6 6
-#define Button7 7
-
-//========================================================================
-// Error handler for BadMatch errors when requesting context with
-// unavailable OpenGL versions using the GLX_ARB_create_context extension
-//========================================================================
-
-static int errorHandler(Display *display, XErrorEvent* event)
-{
- return 0;
-}
-
+#define Button6 6
+#define Button7 7
//========================================================================
// Checks whether the event is a MapNotify for the specified window
@@ -65,154 +53,6 @@ static Bool isMapNotify(Display* d, XEvent* e, char* arg)
}
-//========================================================================
-// Retrieve a single window property of the specified type
-// Inspired by fghGetWindowProperty from freeglut
-//========================================================================
-
-static unsigned long getWindowProperty(Window window,
- Atom property,
- Atom type,
- unsigned char** value)
-{
- Atom actualType;
- int actualFormat;
- unsigned long itemCount, bytesAfter;
-
- XGetWindowProperty(_glfwLibrary.X11.display,
- window,
- property,
- 0,
- LONG_MAX,
- False,
- type,
- &actualType,
- &actualFormat,
- &itemCount,
- &bytesAfter,
- value);
-
- if (actualType != type)
- return 0;
-
- return itemCount;
-}
-
-
-//========================================================================
-// Check whether the specified atom is supported
-//========================================================================
-
-static Atom getSupportedAtom(Atom* supportedAtoms,
- unsigned long atomCount,
- const char* atomName)
-{
- Atom atom = XInternAtom(_glfwLibrary.X11.display, atomName, True);
- if (atom != None)
- {
- unsigned long i;
-
- for (i = 0; i < atomCount; i++)
- {
- if (supportedAtoms[i] == atom)
- return atom;
- }
- }
-
- return None;
-}
-
-
-//========================================================================
-// Check whether the running window manager is EWMH-compliant
-//========================================================================
-
-static GLboolean hasEWMH(_GLFWwindow* window)
-{
- Window* windowFromRoot = NULL;
- Window* windowFromChild = NULL;
-
- // Hey kids; let's see if the window manager supports EWMH!
-
- // First we need a couple of atoms, which should already be there
- Atom supportingWmCheck =
- XInternAtom(_glfwLibrary.X11.display, "_NET_SUPPORTING_WM_CHECK", True);
- Atom wmSupported =
- XInternAtom(_glfwLibrary.X11.display, "_NET_SUPPORTED", True);
- if (supportingWmCheck == None || wmSupported == None)
- return GL_FALSE;
-
- // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
- if (getWindowProperty(_glfwLibrary.X11.root,
- supportingWmCheck,
- XA_WINDOW,
- (unsigned char**) &windowFromRoot) != 1)
- {
- XFree(windowFromRoot);
- return GL_FALSE;
- }
-
- // It should be the ID of a child window (of the root)
- // Then we look for the same property on the child window
- if (getWindowProperty(*windowFromRoot,
- supportingWmCheck,
- XA_WINDOW,
- (unsigned char**) &windowFromChild) != 1)
- {
- XFree(windowFromRoot);
- XFree(windowFromChild);
- return GL_FALSE;
- }
-
- // It should be the ID of that same child window
- if (*windowFromRoot != *windowFromChild)
- {
- XFree(windowFromRoot);
- XFree(windowFromChild);
- return GL_FALSE;
- }
-
- XFree(windowFromRoot);
- XFree(windowFromChild);
-
- // We are now fairly sure that an EWMH-compliant window manager is running
-
- Atom* supportedAtoms;
- unsigned long atomCount;
-
- // 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
- atomCount = getWindowProperty(_glfwLibrary.X11.root,
- wmSupported,
- XA_ATOM,
- (unsigned char**) &supportedAtoms);
-
- // See which of the atoms we support that are supported by the WM
-
- window->X11.wmState =
- getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
-
- window->X11.wmStateFullscreen =
- getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
-
- window->X11.wmName =
- getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME");
-
- window->X11.wmIconName =
- getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_ICON_NAME");
-
- window->X11.wmPing =
- getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING");
-
- window->X11.wmActiveWindow =
- getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
-
- XFree(supportedAtoms);
-
- return GL_TRUE;
-}
-
-
//========================================================================
// Translates an X Window key to internal coding
//========================================================================
@@ -247,417 +87,6 @@ static int translateChar(XKeyEvent* event)
}
-//========================================================================
-// Returns the specified attribute of the specified GLXFBConfig
-// NOTE: Do not call this unless we have found GLX 1.3+ or GLX_SGIX_fbconfig
-//========================================================================
-
-static int getFBConfigAttrib(_GLFWwindow* window, GLXFBConfig fbconfig, int attrib)
-{
- int value;
-
- if (window->GLX.SGIX_fbconfig)
- {
- window->GLX.GetFBConfigAttribSGIX(_glfwLibrary.X11.display,
- fbconfig, attrib, &value);
- }
- else
- glXGetFBConfigAttrib(_glfwLibrary.X11.display, fbconfig, attrib, &value);
-
- return value;
-}
-
-
-//========================================================================
-// Return a list of available and usable framebuffer configs
-//========================================================================
-
-static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
-{
- GLXFBConfig* fbconfigs;
- _GLFWfbconfig* result;
- int i, count = 0;
-
- *found = 0;
-
- if (_glfwLibrary.X11.glxMajor == 1 && _glfwLibrary.X11.glxMinor < 3)
- {
- if (!window->GLX.SGIX_fbconfig)
- {
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
- "X11/GLX: GLXFBConfig support not found");
- return NULL;
- }
- }
-
- if (window->GLX.SGIX_fbconfig)
- {
- fbconfigs = window->GLX.ChooseFBConfigSGIX(_glfwLibrary.X11.display,
- _glfwLibrary.X11.screen,
- NULL,
- &count);
- if (!count)
- {
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
- "X11/GLX: No GLXFBConfigs returned");
- return NULL;
- }
- }
- else
- {
- fbconfigs = glXGetFBConfigs(_glfwLibrary.X11.display,
- _glfwLibrary.X11.screen,
- &count);
- if (!count)
- {
- _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
- "X11/GLX: No GLXFBConfigs returned");
- return NULL;
- }
- }
-
- result = (_GLFWfbconfig*) _glfwMalloc(sizeof(_GLFWfbconfig) * count);
- if (!result)
- {
- _glfwSetError(GLFW_OUT_OF_MEMORY,
- "X11/GLX: Failed to allocate _GLFWfbconfig array");
- return NULL;
- }
-
- for (i = 0; i < count; i++)
- {
- if (!getFBConfigAttrib(window, fbconfigs[i], GLX_DOUBLEBUFFER) ||
- !getFBConfigAttrib(window, fbconfigs[i], GLX_VISUAL_ID))
- {
- // Only consider double-buffered GLXFBConfigs with associated visuals
- continue;
- }
-
- if (!(getFBConfigAttrib(window,
- fbconfigs[i],
- GLX_RENDER_TYPE) & GLX_RGBA_BIT))
- {
- // Only consider RGBA GLXFBConfigs
- continue;
- }
-
- if (!(getFBConfigAttrib(window, fbconfigs[i], GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))
- {
- // Only consider window GLXFBConfigs
- continue;
- }
-
- result[*found].redBits = getFBConfigAttrib(window, fbconfigs[i], GLX_RED_SIZE);
- result[*found].greenBits = getFBConfigAttrib(window, fbconfigs[i], GLX_GREEN_SIZE);
- result[*found].blueBits = getFBConfigAttrib(window, fbconfigs[i], GLX_BLUE_SIZE);
-
- result[*found].alphaBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ALPHA_SIZE);
- result[*found].depthBits = getFBConfigAttrib(window, fbconfigs[i], GLX_DEPTH_SIZE);
- result[*found].stencilBits = getFBConfigAttrib(window, fbconfigs[i], GLX_STENCIL_SIZE);
-
- result[*found].accumRedBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_RED_SIZE);
- result[*found].accumGreenBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_GREEN_SIZE);
- result[*found].accumBlueBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_BLUE_SIZE);
- result[*found].accumAlphaBits = getFBConfigAttrib(window, fbconfigs[i], GLX_ACCUM_ALPHA_SIZE);
-
- result[*found].auxBuffers = getFBConfigAttrib(window, fbconfigs[i], GLX_AUX_BUFFERS);
- result[*found].stereo = getFBConfigAttrib(window, fbconfigs[i], GLX_STEREO);
-
- if (window->GLX.ARB_multisample)
- result[*found].samples = getFBConfigAttrib(window, fbconfigs[i], GLX_SAMPLES);
- else
- result[*found].samples = 0;
-
- result[*found].platformID = (GLFWintptr) getFBConfigAttrib(window, fbconfigs[i], GLX_FBCONFIG_ID);
-
- (*found)++;
- }
-
- XFree(fbconfigs);
-
- return result;
-}
-
-
-//========================================================================
-// Create the OpenGL context
-//========================================================================
-
-#define setGLXattrib(attribs, index, attribName, attribValue) \
- attribs[index++] = attribName; \
- attribs[index++] = attribValue;
-
-static int createContext(_GLFWwindow* window,
- const _GLFWwndconfig* wndconfig,
- GLXFBConfigID fbconfigID)
-{
- int attribs[40];
- int dummy, index;
- GLXFBConfig* fbconfig;
- GLXContext share = NULL;
-
- if (wndconfig->share)
- share = wndconfig->share->GLX.context;
-
- // Retrieve the previously selected GLXFBConfig
- {
- index = 0;
-
- setGLXattrib(attribs, index, GLX_FBCONFIG_ID, (int) fbconfigID);
- setGLXattrib(attribs, index, None, None);
-
- if (window->GLX.SGIX_fbconfig)
- {
- fbconfig = window->GLX.ChooseFBConfigSGIX(_glfwLibrary.X11.display,
- _glfwLibrary.X11.screen,
- attribs,
- &dummy);
- }
- else
- {
- fbconfig = glXChooseFBConfig(_glfwLibrary.X11.display,
- _glfwLibrary.X11.screen,
- attribs,
- &dummy);
- }
-
- if (fbconfig == NULL)
- {
- _glfwSetError(GLFW_PLATFORM_ERROR,
- "X11/GLX: Failed to retrieve the selected GLXFBConfig");
- return GL_FALSE;
- }
- }
-
- // Retrieve the corresponding visual
- if (window->GLX.SGIX_fbconfig)
- {
- window->GLX.visual = window->GLX.GetVisualFromFBConfigSGIX(_glfwLibrary.X11.display,
- *fbconfig);
- }
- else
- {
- window->GLX.visual = glXGetVisualFromFBConfig(_glfwLibrary.X11.display,
- *fbconfig);
- }
-
- if (window->GLX.visual == NULL)
- {
- XFree(fbconfig);
-
- _glfwSetError(GLFW_PLATFORM_ERROR,
- "X11/GLX: Failed to retrieve visual for GLXFBConfig");
- return GL_FALSE;
- }
-
- if (window->GLX.ARB_create_context)
- {
- index = 0;
-
- if (wndconfig->glMajor != 1 || wndconfig->glMinor != 0)
- {
- // Request an explicitly versioned context
-
- setGLXattrib(attribs, index, GLX_CONTEXT_MAJOR_VERSION_ARB, wndconfig->glMajor);
- setGLXattrib(attribs, index, GLX_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor);
- }
-
- if (wndconfig->glForward || wndconfig->glDebug || wndconfig->glRobustness)
- {
- int flags = 0;
-
- if (wndconfig->glForward)
- flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
-
- if (wndconfig->glDebug)
- flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
-
- if (wndconfig->glRobustness)
- flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
-
- setGLXattrib(attribs, index, GLX_CONTEXT_FLAGS_ARB, flags);
- }
-
- if (wndconfig->glProfile)
- {
- int flags = 0;
-
- if (!window->GLX.ARB_create_context_profile)
- {
- _glfwSetError(GLFW_VERSION_UNAVAILABLE,
- "X11/GLX: An OpenGL profile requested but "
- "GLX_ARB_create_context_profile is unavailable");
- return GL_FALSE;
- }
-
- if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE &&
- !window->GLX.EXT_create_context_es2_profile)
- {
- _glfwSetError(GLFW_VERSION_UNAVAILABLE,
- "X11/GLX: OpenGL ES 2.x profile requested but "
- "GLX_EXT_create_context_es2_profile is unavailable");
- return GL_FALSE;
- }
-
- if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE)
- flags = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
- else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE)
- flags = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
- else if (wndconfig->glProfile == GLFW_OPENGL_ES2_PROFILE)
- flags = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
-
- setGLXattrib(attribs, index, GLX_CONTEXT_PROFILE_MASK_ARB, flags);
- }
-
- if (wndconfig->glRobustness)
- {
- int strategy;
-
- if (!window->GLX.ARB_create_context_robustness)
- {
- _glfwSetError(GLFW_VERSION_UNAVAILABLE,
- "X11/GLX: An OpenGL robustness strategy was "
- "requested but GLX_ARB_create_context_robustness "
- "is unavailable");
- return GL_FALSE;
- }
-
- if (wndconfig->glRobustness == GLFW_OPENGL_NO_RESET_NOTIFICATION)
- strategy = GLX_NO_RESET_NOTIFICATION_ARB;
- else if (wndconfig->glRobustness == GLFW_OPENGL_LOSE_CONTEXT_ON_RESET)
- strategy = GLX_LOSE_CONTEXT_ON_RESET_ARB;
-
- setGLXattrib(attribs,
- index,
- GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
- strategy);
- }
-
- setGLXattrib(attribs, index, None, None);
-
- // This is the only place we set an Xlib error handler, and we only do
- // it because glXCreateContextAttribsARB generates a BadMatch error if
- // the requested OpenGL version is unavailable (instead of a civilized
- // response like returning NULL)
- XSetErrorHandler(errorHandler);
-
- window->GLX.context =
- window->GLX.CreateContextAttribsARB(_glfwLibrary.X11.display,
- *fbconfig,
- share,
- True,
- attribs);
-
- // We are done, so unset the error handler again (see above)
- XSetErrorHandler(NULL);
- }
- else
- {
- if (window->GLX.SGIX_fbconfig)
- {
- window->GLX.context =
- window->GLX.CreateContextWithConfigSGIX(_glfwLibrary.X11.display,
- *fbconfig,
- GLX_RGBA_TYPE,
- share,
- True);
- }
- else
- {
- window->GLX.context = glXCreateNewContext(_glfwLibrary.X11.display,
- *fbconfig,
- GLX_RGBA_TYPE,
- share,
- True);
- }
- }
-
- XFree(fbconfig);
-
- if (window->GLX.context == NULL)
- {
- // TODO: Handle all the various error codes here
-
- _glfwSetError(GLFW_PLATFORM_ERROR,
- "X11/GLX: Failed to create OpenGL context");
- return GL_FALSE;
- }
-
- window->GLX.fbconfigID = fbconfigID;
-
- return GL_TRUE;
-}
-
-#undef setGLXattrib
-
-
-//========================================================================
-// Initialize GLX-specific extensions
-//========================================================================
-
-static void initGLXExtensions(_GLFWwindow* window)
-{
- if (_glfwPlatformExtensionSupported("GLX_EXT_swap_control"))
- {
- window->GLX.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
- _glfwPlatformGetProcAddress("glXSwapIntervalEXT");
-
- if (window->GLX.SwapIntervalEXT)
- window->GLX.EXT_swap_control = GL_TRUE;
- }
-
- if (_glfwPlatformExtensionSupported("GLX_SGI_swap_control"))
- {
- window->GLX.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
- _glfwPlatformGetProcAddress("glXSwapIntervalSGI");
-
- if (window->GLX.SwapIntervalSGI)
- window->GLX.SGI_swap_control = GL_TRUE;
- }
-
- if (_glfwPlatformExtensionSupported("GLX_SGIX_fbconfig"))
- {
- window->GLX.GetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)
- _glfwPlatformGetProcAddress("glXGetFBConfigAttribSGIX");
- window->GLX.ChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)
- _glfwPlatformGetProcAddress("glXChooseFBConfigSGIX");
- window->GLX.CreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)
- _glfwPlatformGetProcAddress("glXCreateContextWithConfigSGIX");
- window->GLX.GetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)
- _glfwPlatformGetProcAddress("glXGetVisualFromFBConfigSGIX");
-
- if (window->GLX.GetFBConfigAttribSGIX &&
- window->GLX.ChooseFBConfigSGIX &&
- window->GLX.CreateContextWithConfigSGIX &&
- window->GLX.GetVisualFromFBConfigSGIX)
- {
- window->GLX.SGIX_fbconfig = GL_TRUE;
- }
- }
-
- if (_glfwPlatformExtensionSupported("GLX_ARB_multisample"))
- window->GLX.ARB_multisample = GL_TRUE;
-
- if (_glfwPlatformExtensionSupported("GLX_ARB_create_context"))
- {
- window->GLX.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
- _glfwPlatformGetProcAddress("glXCreateContextAttribsARB");
-
- if (window->GLX.CreateContextAttribsARB)
- window->GLX.ARB_create_context = GL_TRUE;
- }
-
- if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_robustness"))
- window->GLX.ARB_create_context_robustness = GL_TRUE;
-
- if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_profile"))
- window->GLX.ARB_create_context_profile = GL_TRUE;
-
- if (_glfwPlatformExtensionSupported("GLX_EXT_create_context_es2_profile"))
- window->GLX.EXT_create_context_es2_profile = GL_TRUE;
-}
-
-
//========================================================================
// Create the X11 window (and its colormap)
//========================================================================
@@ -668,13 +97,14 @@ static GLboolean createWindow(_GLFWwindow* window,
XEvent event;
unsigned long wamask;
XSetWindowAttributes wa;
+ XVisualInfo* visual = _glfwGetContextVisual(window);
// Every window needs a colormap
// Create one based on the visual used by the current context
window->X11.colormap = XCreateColormap(_glfwLibrary.X11.display,
_glfwLibrary.X11.root,
- window->GLX.visual->visual,
+ visual->visual,
AllocNone);
// Create the actual window
@@ -685,7 +115,8 @@ static GLboolean createWindow(_GLFWwindow* window,
wa.border_pixel = 0;
wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
- ExposureMask | FocusChangeMask | VisibilityChangeMask;
+ ExposureMask | FocusChangeMask | VisibilityChangeMask |
+ EnterWindowMask | LeaveWindowMask;
if (wndconfig->mode == GLFW_WINDOWED)
{
@@ -703,9 +134,9 @@ static GLboolean createWindow(_GLFWwindow* window,
0, 0, // Upper left corner of this window on root
window->width, window->height,
0, // Border width
- window->GLX.visual->depth, // Color depth
+ visual->depth, // Color depth
InputOutput,
- window->GLX.visual->visual,
+ visual->visual,
wamask,
&wa
);
@@ -720,10 +151,7 @@ static GLboolean createWindow(_GLFWwindow* window,
}
}
- // Check whether an EWMH-compliant window manager is running
- window->X11.hasEWMH = hasEWMH(window);
-
- if (window->mode == GLFW_FULLSCREEN && !window->X11.hasEWMH)
+ if (window->mode == GLFW_FULLSCREEN && !_glfwLibrary.X11.hasEWMH)
{
// This is the butcher's way of removing window decorations
// Setting the override-redirect attribute on a window makes the window
@@ -744,9 +172,9 @@ static GLboolean createWindow(_GLFWwindow* window,
}
// Find or create the protocol atom for window close notifications
- window->X11.wmDeleteWindow = XInternAtom(_glfwLibrary.X11.display,
- "WM_DELETE_WINDOW",
- False);
+ _glfwLibrary.X11.wmDeleteWindow = XInternAtom(_glfwLibrary.X11.display,
+ "WM_DELETE_WINDOW",
+ False);
// Declare the WM protocols we support
{
@@ -755,14 +183,14 @@ static GLboolean createWindow(_GLFWwindow* window,
// The WM_DELETE_WINDOW ICCCM protocol
// Basic window close notification protocol
- if (window->X11.wmDeleteWindow != None)
- protocols[count++] = window->X11.wmDeleteWindow;
+ if (_glfwLibrary.X11.wmDeleteWindow != None)
+ protocols[count++] = _glfwLibrary.X11.wmDeleteWindow;
// The _NET_WM_PING EWMH protocol
// Tells the WM to ping our window and flag us as unresponsive if we
// don't reply within a few seconds
- if (window->X11.wmPing != None)
- protocols[count++] = window->X11.wmPing;
+ if (_glfwLibrary.X11.wmPing != None)
+ protocols[count++] = _glfwLibrary.X11.wmPing;
if (count > 0)
{
@@ -823,10 +251,10 @@ static GLboolean createWindow(_GLFWwindow* window,
//========================================================================
-// Hide mouse cursor
+// Hide cursor
//========================================================================
-static void hideMouseCursor(_GLFWwindow* window)
+static void hideCursor(_GLFWwindow* window)
{
if (!window->X11.cursorHidden)
{
@@ -839,12 +267,12 @@ static void hideMouseCursor(_GLFWwindow* window)
//========================================================================
-// Capture mouse cursor
+// Capture cursor
//========================================================================
-static void captureMouseCursor(_GLFWwindow* window)
+static void captureCursor(_GLFWwindow* window)
{
- hideMouseCursor(window);
+ hideCursor(window);
if (!window->X11.cursorGrabbed)
{
@@ -862,13 +290,13 @@ static void captureMouseCursor(_GLFWwindow* window)
//========================================================================
-// Show mouse cursor
+// Show cursor
//========================================================================
-static void showMouseCursor(_GLFWwindow* window)
+static void showCursor(_GLFWwindow* window)
{
// Un-grab cursor (only in windowed mode: in fullscreen mode we still
- // want the mouse grabbed in order to confine the cursor to the window
+ // want the cursor grabbed in order to confine the cursor to the window
// area)
if (window->X11.cursorGrabbed)
{
@@ -907,15 +335,14 @@ static void enterFullscreenMode(_GLFWwindow* window)
_glfwLibrary.X11.saver.changed = GL_TRUE;
}
- _glfwSetVideoMode(_glfwLibrary.X11.screen,
- &window->width, &window->height,
+ _glfwSetVideoMode(&window->width, &window->height,
&window->refreshRate);
- if (window->X11.hasEWMH &&
- window->X11.wmState != None &&
- window->X11.wmStateFullscreen != None)
+ if (_glfwLibrary.X11.hasEWMH &&
+ _glfwLibrary.X11.wmState != None &&
+ _glfwLibrary.X11.wmStateFullscreen != None)
{
- if (window->X11.wmActiveWindow != None)
+ if (_glfwLibrary.X11.wmActiveWindow != None)
{
// Ask the window manager to raise and focus the GLFW window
// Only focused windows with the _NET_WM_STATE_FULLSCREEN state end
@@ -927,7 +354,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
event.type = ClientMessage;
event.xclient.window = window->X11.handle;
event.xclient.format = 32; // Data is 32-bit longs
- event.xclient.message_type = window->X11.wmActiveWindow;
+ event.xclient.message_type = _glfwLibrary.X11.wmActiveWindow;
event.xclient.data.l[0] = 1; // Sender is a normal application
event.xclient.data.l[1] = 0; // We don't really know the timestamp
@@ -948,9 +375,9 @@ static void enterFullscreenMode(_GLFWwindow* window)
event.type = ClientMessage;
event.xclient.window = window->X11.handle;
event.xclient.format = 32; // Data is 32-bit longs
- event.xclient.message_type = window->X11.wmState;
+ event.xclient.message_type = _glfwLibrary.X11.wmState;
event.xclient.data.l[0] = _NET_WM_STATE_ADD;
- event.xclient.data.l[1] = window->X11.wmStateFullscreen;
+ event.xclient.data.l[1] = _glfwLibrary.X11.wmStateFullscreen;
event.xclient.data.l[2] = 0; // No secondary property
event.xclient.data.l[3] = 1; // Sender is a normal application
@@ -974,7 +401,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
}
// HACK: Try to get window inside viewport (for virtual displays) by moving
- // the mouse cursor to the upper left corner (and then to the center)
+ // the cursor to the upper left corner (and then to the center)
// This hack should be harmless on saner systems as well
XWarpPointer(_glfwLibrary.X11.display, None, window->X11.handle, 0,0,0,0, 0,0);
XWarpPointer(_glfwLibrary.X11.display, None, window->X11.handle, 0,0,0,0,
@@ -988,7 +415,7 @@ static void enterFullscreenMode(_GLFWwindow* window)
static void leaveFullscreenMode(_GLFWwindow* window)
{
- _glfwRestoreVideoMode(_glfwLibrary.X11.screen);
+ _glfwRestoreVideoMode();
// Did we change the screen saver setting?
if (_glfwLibrary.X11.saver.changed)
@@ -1003,9 +430,9 @@ static void leaveFullscreenMode(_GLFWwindow* window)
_glfwLibrary.X11.saver.changed = GL_FALSE;
}
- if (window->X11.hasEWMH &&
- window->X11.wmState != None &&
- window->X11.wmStateFullscreen != None)
+ if (_glfwLibrary.X11.hasEWMH &&
+ _glfwLibrary.X11.wmState != None &&
+ _glfwLibrary.X11.wmStateFullscreen != None)
{
// Ask the window manager to make the GLFW window a normal window
// Normal windows usually have frames and other decorations
@@ -1016,9 +443,9 @@ static void leaveFullscreenMode(_GLFWwindow* window)
event.type = ClientMessage;
event.xclient.window = window->X11.handle;
event.xclient.format = 32; // Data is 32-bit longs
- event.xclient.message_type = window->X11.wmState;
+ event.xclient.message_type = _glfwLibrary.X11.wmState;
event.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
- event.xclient.data.l[1] = window->X11.wmStateFullscreen;
+ event.xclient.data.l[1] = _glfwLibrary.X11.wmStateFullscreen;
event.xclient.data.l[2] = 0; // No secondary property
event.xclient.data.l[3] = 1; // Sender is a normal application
@@ -1143,14 +570,14 @@ static void processSingleEvent(void)
// XFree86 3.3.2 and later translates mouse wheel up/down into
// mouse button 4 & 5 presses
else if (event.xbutton.button == Button4)
- _glfwInputScroll(window, 0, 1);
+ _glfwInputScroll(window, 0.0, 1.0);
else if (event.xbutton.button == Button5)
- _glfwInputScroll(window, 0, -1);
+ _glfwInputScroll(window, 0.0, -1.0);
else if (event.xbutton.button == Button6)
- _glfwInputScroll(window, -1, 0);
+ _glfwInputScroll(window, -1.0, 0.0);
else if (event.xbutton.button == Button7)
- _glfwInputScroll(window, 1, 0);
+ _glfwInputScroll(window, 1.0, 0.0);
break;
}
@@ -1186,9 +613,43 @@ static void processSingleEvent(void)
break;
}
+ case EnterNotify:
+ {
+ // The cursor entered the window
+ window = findWindow(event.xcrossing.window);
+ if (window == NULL)
+ {
+ fprintf(stderr, "Cannot find GLFW window structure for EnterNotify event\n");
+ return;
+ }
+
+ if (window->cursorMode == GLFW_CURSOR_HIDDEN)
+ hideCursor(window);
+
+ _glfwInputCursorEnter(window, GL_TRUE);
+ break;
+ }
+
+ case LeaveNotify:
+ {
+ // The cursor left the window
+ window = findWindow(event.xcrossing.window);
+ if (window == NULL)
+ {
+ fprintf(stderr, "Cannot find GLFW window structure for LeaveNotify event\n");
+ return;
+ }
+
+ if (window->cursorMode == GLFW_CURSOR_HIDDEN)
+ showCursor(window);
+
+ _glfwInputCursorEnter(window, GL_FALSE);
+ break;
+ }
+
case MotionNotify:
{
- // The mouse cursor was moved
+ // The cursor was moved
window = findWindow(event.xmotion.window);
if (window == NULL)
{
@@ -1199,7 +660,7 @@ static void processSingleEvent(void)
if (event.xmotion.x != window->X11.cursorPosX ||
event.xmotion.y != window->X11.cursorPosY)
{
- // The mouse cursor was moved and we didn't do it
+ // The cursor was moved and we didn't do it
int x, y;
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
@@ -1257,15 +718,15 @@ static void processSingleEvent(void)
return;
}
- if ((Atom) event.xclient.data.l[0] == window->X11.wmDeleteWindow)
+ if ((Atom) event.xclient.data.l[0] == _glfwLibrary.X11.wmDeleteWindow)
{
// The window manager was asked to close the window, for example by
// the user pressing a 'close' window decoration button
window->closeRequested = GL_TRUE;
}
- else if (window->X11.wmPing != None &&
- (Atom) event.xclient.data.l[0] == window->X11.wmPing)
+ else if (_glfwLibrary.X11.wmPing != None &&
+ (Atom) event.xclient.data.l[0] == _glfwLibrary.X11.wmPing)
{
// The window manager is pinging us to make sure we are still
// responding to events
@@ -1322,7 +783,7 @@ static void processSingleEvent(void)
_glfwInputWindowFocus(window, GL_TRUE);
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
- captureMouseCursor(window);
+ captureCursor(window);
break;
}
@@ -1340,7 +801,7 @@ static void processSingleEvent(void)
_glfwInputWindowFocus(window, GL_FALSE);
if (window->cursorMode == GLFW_CURSOR_CAPTURED)
- showMouseCursor(window);
+ showCursor(window);
break;
}
@@ -1359,7 +820,52 @@ static void processSingleEvent(void)
break;
}
- // Was the window destroyed?
+ case SelectionClear:
+ {
+ // The ownership of the selection was lost
+
+ free(_glfwLibrary.X11.selection.string);
+ _glfwLibrary.X11.selection.string = NULL;
+ break;
+ }
+
+ case SelectionNotify:
+ {
+ // The selection conversion status is available
+
+ XSelectionEvent* request = &event.xselection;
+
+ if (_glfwReadSelection(request))
+ _glfwLibrary.X11.selection.status = _GLFW_CONVERSION_SUCCEEDED;
+ else
+ _glfwLibrary.X11.selection.status = _GLFW_CONVERSION_FAILED;
+
+ break;
+ }
+
+ case SelectionRequest:
+ {
+ // The contents of the selection was requested
+
+ XSelectionRequestEvent* request = &event.xselectionrequest;
+
+ XEvent response;
+ memset(&response, 0, sizeof(response));
+
+ response.xselection.property = _glfwWriteSelection(request);
+ response.xselection.type = SelectionNotify;
+ response.xselection.display = request->display;
+ response.xselection.requestor = request->requestor;
+ response.xselection.selection = request->selection;
+ response.xselection.target = request->target;
+ response.xselection.time = request->time;
+
+ XSendEvent(_glfwLibrary.X11.display,
+ request->requestor,
+ False, 0, &response);
+ break;
+ }
+
case DestroyNotify:
return;
@@ -1383,6 +889,23 @@ static void processSingleEvent(void)
}
+//////////////////////////////////////////////////////////////////////////
+////// GLFW internal API //////
+//////////////////////////////////////////////////////////////////////////
+
+//========================================================================
+// Processes all pending events
+//========================================================================
+
+void _glfwProcessPendingEvents(void)
+{
+ int i, count = XPending(_glfwLibrary.X11.display);
+
+ for (i = 0; i < count; i++)
+ processSingleEvent();
+}
+
+
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
@@ -1396,35 +919,10 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig* fbconfig)
{
- _GLFWfbconfig closest;
-
window->refreshRate = wndconfig->refreshRate;
window->resizable = wndconfig->resizable;
- initGLXExtensions(window);
-
- // Choose the best available fbconfig
- {
- unsigned int fbcount;
- _GLFWfbconfig* fbconfigs;
- const _GLFWfbconfig* result;
-
- fbconfigs = getFBConfigs(window, &fbcount);
- if (!fbconfigs)
- return GL_FALSE;
-
- result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
- if (!result)
- {
- _glfwFree(fbconfigs);
- return GL_FALSE;
- }
-
- closest = *result;
- _glfwFree(fbconfigs);
- }
-
- if (!createContext(window, wndconfig, (GLXFBConfigID) closest.platformID))
+ if (!_glfwCreateContext(window, wndconfig, fbconfig))
return GL_FALSE;
if (!createWindow(window, wndconfig))
@@ -1446,7 +944,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
}
// Process the window map event and any other that may have arrived
- _glfwPlatformPollEvents();
+ _glfwProcessPendingEvents();
// Retrieve and set initial cursor position
{
@@ -1481,19 +979,7 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window)
if (window->mode == GLFW_FULLSCREEN)
leaveFullscreenMode(window);
- if (window->GLX.context)
- {
- // Release and destroy the context
- glXMakeCurrent(_glfwLibrary.X11.display, None, NULL);
- glXDestroyContext(_glfwLibrary.X11.display, window->GLX.context);
- window->GLX.context = NULL;
- }
-
- if (window->GLX.visual)
- {
- XFree(window->GLX.visual);
- window->GLX.visual = NULL;
- }
+ _glfwDestroyContext(window);
if (window->X11.handle)
{
@@ -1534,18 +1020,18 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
NULL, NULL, NULL);
#endif
- if (window->X11.wmName != None)
+ if (_glfwLibrary.X11.wmName != None)
{
XChangeProperty(_glfwLibrary.X11.display, window->X11.handle,
- window->X11.wmName, type, 8,
+ _glfwLibrary.X11.wmName, type, 8,
PropModeReplace,
(unsigned char*) title, strlen(title));
}
- if (window->X11.wmIconName != None)
+ if (_glfwLibrary.X11.wmIconName != None)
{
XChangeProperty(_glfwLibrary.X11.display, window->X11.handle,
- window->X11.wmIconName, type, 8,
+ _glfwLibrary.X11.wmIconName, type, 8,
PropModeReplace,
(unsigned char*) title, strlen(title));
}
@@ -1566,8 +1052,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
if (window->mode == GLFW_FULLSCREEN)
{
// Get the closest matching video mode for the specified window size
- mode = _glfwGetClosestVideoMode(_glfwLibrary.X11.screen,
- &width, &height, &rate);
+ mode = _glfwGetClosestVideoMode(&width, &height, &rate);
}
if (!window->resizable)
@@ -1594,7 +1079,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
if (window->mode == GLFW_FULLSCREEN)
{
// Change video mode, keeping current refresh rate
- _glfwSetVideoModeMODE(_glfwLibrary.X11.screen, mode, window->refreshRate);
+ _glfwSetVideoModeMODE(mode, window->refreshRate);
}
// Set window size (if not already changed)
@@ -1655,8 +1140,6 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
void _glfwPlatformRefreshWindowParams(void)
{
- int dummy;
- GLXFBConfig* fbconfig;
#if defined(_GLFW_HAS_XRANDR)
XRRScreenConfiguration* sc;
#endif /*_GLFW_HAS_XRANDR*/
@@ -1667,58 +1150,6 @@ void _glfwPlatformRefreshWindowParams(void)
#endif /*_GLFW_HAS_XF86VIDMODE*/
_GLFWwindow* window = _glfwLibrary.currentWindow;
- int attribs[] = { GLX_FBCONFIG_ID, window->GLX.fbconfigID, None };
-
- if (window->GLX.SGIX_fbconfig)
- {
- fbconfig = window->GLX.ChooseFBConfigSGIX(_glfwLibrary.X11.display,
- _glfwLibrary.X11.screen,
- attribs,
- &dummy);
- }
- else
- {
- fbconfig = glXChooseFBConfig(_glfwLibrary.X11.display,
- _glfwLibrary.X11.screen,
- attribs,
- &dummy);
- }
-
- if (fbconfig == NULL)
- {
- // This should never ever happen
- // TODO: Flag this as an error and propagate up
- fprintf(stderr, "Cannot find known GLXFBConfig by ID. "
- "This cannot happen. Have a nice day.\n");
- abort();
- }
-
- // There is no clear definition of an "accelerated" context on X11/GLX, and
- // true sounds better than false, so we hardcode true here
- window->accelerated = GL_TRUE;
-
- window->redBits = getFBConfigAttrib(window, *fbconfig, GLX_RED_SIZE);
- window->greenBits = getFBConfigAttrib(window, *fbconfig, GLX_GREEN_SIZE);
- window->blueBits = getFBConfigAttrib(window, *fbconfig, GLX_BLUE_SIZE);
-
- window->alphaBits = getFBConfigAttrib(window, *fbconfig, GLX_ALPHA_SIZE);
- window->depthBits = getFBConfigAttrib(window, *fbconfig, GLX_DEPTH_SIZE);
- window->stencilBits = getFBConfigAttrib(window, *fbconfig, GLX_STENCIL_SIZE);
-
- window->accumRedBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_RED_SIZE);
- window->accumGreenBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_GREEN_SIZE);
- window->accumBlueBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_BLUE_SIZE);
- window->accumAlphaBits = getFBConfigAttrib(window, *fbconfig, GLX_ACCUM_ALPHA_SIZE);
-
- window->auxBuffers = getFBConfigAttrib(window, *fbconfig, GLX_AUX_BUFFERS);
- window->stereo = getFBConfigAttrib(window, *fbconfig, GLX_STEREO) ? GL_TRUE : GL_FALSE;
-
- // Get FSAA buffer sample count
- if (window->GLX.ARB_multisample)
- window->samples = getFBConfigAttrib(window, *fbconfig, GLX_SAMPLES);
- else
- window->samples = 0;
-
// Retrieve refresh rate if possible
if (_glfwLibrary.X11.RandR.available)
{
@@ -1745,8 +1176,6 @@ void _glfwPlatformRefreshWindowParams(void)
// Zero means unknown according to the GLFW spec
window->refreshRate = 0;
}
-
- XFree(fbconfig);
}
@@ -1769,9 +1198,9 @@ void _glfwPlatformPollEvents(void)
if (window->cursorMode == GLFW_CURSOR_CAPTURED &&
!window->X11.cursorCentered)
{
- _glfwPlatformSetMouseCursorPos(window,
- window->width / 2,
- window->height / 2);
+ _glfwPlatformSetCursorPos(window,
+ window->width / 2,
+ window->height / 2);
window->X11.cursorCentered = GL_TRUE;
// NOTE: This is a temporary fix. It works as long as you use
@@ -1800,10 +1229,10 @@ void _glfwPlatformWaitEvents(void)
//========================================================================
-// Set physical mouse cursor position
+// Set physical cursor position
//========================================================================
-void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y)
+void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y)
{
// Store the new position so we can recognise it later
window->X11.cursorPosX = x;
@@ -1814,7 +1243,7 @@ void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y)
//========================================================================
-// Set physical mouse cursor mode
+// Set physical cursor mode
//========================================================================
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
@@ -1822,13 +1251,13 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
switch (mode)
{
case GLFW_CURSOR_NORMAL:
- showMouseCursor(window);
+ showCursor(window);
break;
case GLFW_CURSOR_HIDDEN:
- hideMouseCursor(window);
+ hideCursor(window);
break;
case GLFW_CURSOR_CAPTURED:
- captureMouseCursor(window);
+ captureCursor(window);
break;
}
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index d7ac0954..55862fac 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,69 +1,58 @@
-set(STATIC_DEPS libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
-set(SHARED_DEPS libglfwShared ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
+link_libraries(glfw ${OPENGL_glu_LIBRARY})
+
+if (BUILD_SHARED_LIBS)
+ add_definitions(-DGLFW_DLL)
+ link_libraries(${OPENGL_gl_LIBRARY} ${MATH_LIBRARY})
+else()
+ link_libraries(${glfw_LIBRARIES})
+endif()
include_directories(${GLFW_SOURCE_DIR}/include
${GLFW_SOURCE_DIR}/support
${OPENGL_INCLUDE_DIR})
+add_executable(clipboard clipboard.c getopt.c)
add_executable(defaults defaults.c)
-target_link_libraries(defaults ${STATIC_DEPS})
-
-add_executable(dynamic dynamic.c)
-target_link_libraries(dynamic ${SHARED_DEPS})
-
add_executable(events events.c)
-target_link_libraries(events ${STATIC_DEPS})
-
add_executable(fsaa fsaa.c getopt.c)
-target_link_libraries(fsaa ${STATIC_DEPS})
-
add_executable(fsfocus fsfocus.c)
-target_link_libraries(fsfocus ${STATIC_DEPS})
-
add_executable(gamma gamma.c getopt.c)
-target_link_libraries(gamma ${STATIC_DEPS})
-
add_executable(glfwinfo glfwinfo.c getopt.c)
-target_link_libraries(glfwinfo ${STATIC_DEPS})
-
add_executable(iconify iconify.c getopt.c)
-target_link_libraries(iconify ${STATIC_DEPS})
-
add_executable(joysticks joysticks.c)
-target_link_libraries(joysticks ${STATIC_DEPS})
-
-add_executable(listmodes listmodes.c)
-target_link_libraries(listmodes ${STATIC_DEPS})
-
+add_executable(modes modes.c getopt.c)
add_executable(peter peter.c)
-target_link_libraries(peter ${STATIC_DEPS})
-
add_executable(reopen reopen.c)
-target_link_libraries(reopen ${STATIC_DEPS})
add_executable(accuracy WIN32 MACOSX_BUNDLE accuracy.c)
-target_link_libraries(accuracy ${STATIC_DEPS})
+set_target_properties(accuracy PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Accuracy")
add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c)
-target_link_libraries(sharing ${STATIC_DEPS})
+set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing")
add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c)
-target_link_libraries(tearing ${STATIC_DEPS})
+set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing")
add_executable(title WIN32 MACOSX_BUNDLE title.c)
-target_link_libraries(title ${STATIC_DEPS})
+set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title")
add_executable(windows WIN32 MACOSX_BUNDLE windows.c)
-target_link_libraries(windows ${STATIC_DEPS})
+set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows")
set(WINDOWS_BINARIES accuracy sharing tearing title windows)
-set(CONSOLE_BINARIES defaults events fsaa fsfocus gamma glfwinfo iconify
- joysticks listmodes peter reopen)
+set(CONSOLE_BINARIES clipboard defaults events fsaa fsfocus gamma glfwinfo
+ iconify joysticks modes peter reopen)
-if(MSVC)
- # Tell MSVC to use main instead of WinMain for Windows subsystem executables
- set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
- LINK_FLAGS "/ENTRY:mainCRTStartup")
-endif(MSVC)
+if (MSVC)
+ # Tell MSVC to use main instead of WinMain for Windows subsystem executables
+ set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
+ LINK_FLAGS "/ENTRY:mainCRTStartup")
+endif()
+
+if (APPLE)
+ set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
+ MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
+ MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL})
+endif()
diff --git a/tests/accuracy.c b/tests/accuracy.c
index 38f1374e..cfb70271 100644
--- a/tests/accuracy.c
+++ b/tests/accuracy.c
@@ -29,6 +29,7 @@
//
//========================================================================
+#define GLFW_INCLUDE_GLU
#include
#include
@@ -49,7 +50,7 @@ static void window_size_callback(GLFWwindow window, int width, int height)
gluOrtho2D(0.f, window_width, 0.f, window_height);
}
-static void mouse_position_callback(GLFWwindow window, int x, int y)
+static void cursor_position_callback(GLFWwindow window, int x, int y)
{
cursor_x = x;
cursor_y = y;
@@ -59,7 +60,7 @@ int main(void)
{
GLFWwindow window;
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
@@ -74,7 +75,7 @@ int main(void)
exit(EXIT_FAILURE);
}
- glfwSetMousePosCallback(mouse_position_callback);
+ glfwSetCursorPosCallback(cursor_position_callback);
glfwSetWindowSizeCallback(window_size_callback);
glfwSwapInterval(1);
diff --git a/tests/clipboard.c b/tests/clipboard.c
new file mode 100644
index 00000000..3b732290
--- /dev/null
+++ b/tests/clipboard.c
@@ -0,0 +1,153 @@
+//========================================================================
+// Clipboard test program
+// Copyright (c) Camilla Berglund
+//
+// 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.
+//
+//========================================================================
+//
+// This program is used to test the clipboard functionality.
+//
+//========================================================================
+
+#include
+
+#include
+#include
+
+#include "getopt.h"
+
+static void usage(void)
+{
+ printf("Usage: clipboard [-h]\n");
+}
+
+static GLboolean control_is_down(GLFWwindow window)
+{
+ return glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) ||
+ glfwGetKey(window, GLFW_KEY_RIGHT_CONTROL);
+}
+
+static void key_callback(GLFWwindow window, int key, int action)
+{
+ if (action != GLFW_PRESS)
+ return;
+
+ switch (key)
+ {
+ case GLFW_KEY_ESCAPE:
+ glfwCloseWindow(window);
+ break;
+
+ case GLFW_KEY_V:
+ if (control_is_down(window))
+ {
+ const char* string;
+
+ string = glfwGetClipboardString(window);
+ if (string)
+ printf("Clipboard contains \"%s\"\n", string);
+ else
+ printf("Clipboard does not contain a string\n");
+ }
+ break;
+
+ case GLFW_KEY_C:
+ if (control_is_down(window))
+ {
+ const char* string = "Hello GLFW World!";
+ glfwSetClipboardString(window, string);
+ printf("Setting clipboard to \"%s\"\n", string);
+ }
+ break;
+ }
+}
+
+static void size_callback(GLFWwindow window, int width, int height)
+{
+ glViewport(0, 0, width, height);
+}
+
+static void error_callback(int error, const char* description)
+{
+ fprintf(stderr, "Error in %s\n", description);
+}
+
+int main(int argc, char** argv)
+{
+ int ch;
+ GLFWwindow window;
+
+ while ((ch = getopt(argc, argv, "h")) != -1)
+ {
+ switch (ch)
+ {
+ case 'h':
+ usage();
+ exit(EXIT_SUCCESS);
+
+ default:
+ usage();
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ glfwSetErrorCallback(error_callback);
+
+ if (!glfwInit())
+ {
+ fprintf(stderr, "Failed to initialize GLFW\n");
+ exit(EXIT_FAILURE);
+ }
+
+ window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Clipboard Test", NULL);
+ if (!window)
+ {
+ glfwTerminate();
+
+ fprintf(stderr, "Failed to open GLFW window\n");
+ exit(EXIT_FAILURE);
+ }
+
+ glfwSwapInterval(1);
+ glfwSetKeyCallback(key_callback);
+ glfwSetWindowSizeCallback(size_callback);
+
+ glMatrixMode(GL_PROJECTION);
+ glOrtho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f);
+ glMatrixMode(GL_MODELVIEW);
+
+ glClearColor(0.5f, 0.5f, 0.5f, 0);
+
+ while (glfwIsWindow(window))
+ {
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glColor3f(0.8f, 0.2f, 0.4f);
+ glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
+
+ glfwSwapBuffers();
+ glfwWaitEvents();
+ }
+
+ glfwTerminate();
+ exit(EXIT_SUCCESS);
+}
+
diff --git a/tests/defaults.c b/tests/defaults.c
index b50abaaa..d7c5a02c 100644
--- a/tests/defaults.c
+++ b/tests/defaults.c
@@ -69,7 +69,7 @@ int main(void)
int i, width, height;
GLFWwindow window;
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
diff --git a/tests/dynamic.c b/tests/dynamic.c
deleted file mode 100644
index b4257271..00000000
--- a/tests/dynamic.c
+++ /dev/null
@@ -1,91 +0,0 @@
-//========================================================================
-// Dynamic linking test
-// Copyright (c) Camilla Berglund
-//
-// 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.
-//
-//========================================================================
-//
-// This test came about as the result of bug #3060461
-//
-//========================================================================
-
-#define GLFW_DLL
-#include
-
-#include
-#include
-
-static void window_size_callback(GLFWwindow window, int width, int height)
-{
- glViewport(0, 0, width, height);
-}
-
-int main(void)
-{
- GLFWwindow window;
- int major, minor, rev;
- glfwGetVersion(&major, &minor, &rev);
-
- printf("GLFW header version: %i.%i.%i\n",
- GLFW_VERSION_MAJOR,
- GLFW_VERSION_MINOR,
- GLFW_VERSION_REVISION);
- printf("GLFW library version: %i.%i.%i\n", major, minor, rev);
- printf("GLFW library version string: %s\n", glfwGetVersionString());
-
- if (major != GLFW_VERSION_MAJOR ||
- minor != GLFW_VERSION_MINOR ||
- rev != GLFW_VERSION_REVISION)
- {
- fprintf(stderr, "GLFW library version mismatch\n");
- exit(EXIT_FAILURE);
- }
-
- if (!glfwInit(NULL))
- {
- fprintf(stderr, "Failed to initialize GLFW\n");
- exit(EXIT_FAILURE);
- }
-
- window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Dynamic Linking Test", NULL);
- if (!window)
- {
- glfwTerminate();
-
- fprintf(stderr, "Failed to open GLFW window\n");
- exit(EXIT_FAILURE);
- }
-
- glfwSetWindowSizeCallback(window_size_callback);
- glfwSwapInterval(1);
-
- while (glfwIsWindow(window))
- {
- glClear(GL_COLOR_BUFFER_BIT);
-
- glfwSwapBuffers();
- glfwPollEvents();
- }
-
- glfwTerminate();
- exit(EXIT_SUCCESS);
-}
-
diff --git a/tests/events.c b/tests/events.c
index a5a7bfa6..4e85c086 100644
--- a/tests/events.c
+++ b/tests/events.c
@@ -40,8 +40,9 @@
#include
#include
-static GLboolean keyrepeat = 0;
-static GLboolean systemkeys = 1;
+static GLboolean keyrepeat = GL_FALSE;
+static GLboolean systemkeys = GL_TRUE;
+static GLboolean closeable = GL_TRUE;
static unsigned int counter = 0;
static const char* get_key_name(int key)
@@ -243,7 +244,7 @@ static void window_size_callback(GLFWwindow window, int width, int height)
static int window_close_callback(GLFWwindow window)
{
printf("%08x at %0.3f: Window close\n", counter++, glfwGetTime());
- return 1;
+ return closeable;
}
static void window_refresh_callback(GLFWwindow window)
@@ -282,14 +283,22 @@ static void mouse_button_callback(GLFWwindow window, int button, int action)
printf(" was %s\n", get_action_name(action));
}
-static void mouse_position_callback(GLFWwindow window, int x, int y)
+static void cursor_position_callback(GLFWwindow window, int x, int y)
{
- printf("%08x at %0.3f: Mouse position: %i %i\n", counter++, glfwGetTime(), x, y);
+ printf("%08x at %0.3f: Cursor position: %i %i\n", counter++, glfwGetTime(), x, y);
}
-static void scroll_callback(GLFWwindow window, int x, int y)
+static void cursor_enter_callback(GLFWwindow window, int entered)
{
- printf("%08x at %0.3f: Scroll: %i %i\n", counter++, glfwGetTime(), x, y);
+ printf("%08x at %0.3f: Cursor %s window\n",
+ counter++,
+ glfwGetTime(),
+ entered ? "entered" : "left");
+}
+
+static void scroll_callback(GLFWwindow window, double x, double y)
+{
+ printf("%08x at %0.3f: Scroll: %0.3f %0.3f\n", counter++, glfwGetTime(), x, y);
}
static void key_callback(GLFWwindow window, int key, int action)
@@ -325,6 +334,14 @@ static void key_callback(GLFWwindow window, int key, int action)
printf("(( system keys %s ))\n", systemkeys ? "enabled" : "disabled");
break;
}
+
+ case GLFW_KEY_C:
+ {
+ closeable = !closeable;
+
+ printf("(( closing %s ))\n", closeable ? "enabled" : "disabled");
+ break;
+ }
}
}
@@ -353,7 +370,7 @@ int main(void)
setlocale(LC_ALL, "");
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
@@ -367,7 +384,8 @@ int main(void)
glfwSetWindowFocusCallback(window_focus_callback);
glfwSetWindowIconifyCallback(window_iconify_callback);
glfwSetMouseButtonCallback(mouse_button_callback);
- glfwSetMousePosCallback(mouse_position_callback);
+ glfwSetCursorPosCallback(cursor_position_callback);
+ glfwSetCursorEnterCallback(cursor_enter_callback);
glfwSetScrollCallback(scroll_callback);
glfwSetKeyCallback(key_callback);
glfwSetCharCallback(char_callback);
diff --git a/tests/fsaa.c b/tests/fsaa.c
index e2fcf387..9c45ddcc 100644
--- a/tests/fsaa.c
+++ b/tests/fsaa.c
@@ -29,6 +29,7 @@
//
//========================================================================
+#define GLFW_INCLUDE_GLU
#include
#include
@@ -81,7 +82,7 @@ int main(int argc, char** argv)
}
}
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
diff --git a/tests/fsfocus.c b/tests/fsfocus.c
index bf634d54..951409a6 100644
--- a/tests/fsfocus.c
+++ b/tests/fsfocus.c
@@ -75,7 +75,7 @@ int main(void)
{
GLFWwindow window;
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
diff --git a/tests/gamma.c b/tests/gamma.c
index dd10784e..b8ec6c45 100644
--- a/tests/gamma.c
+++ b/tests/gamma.c
@@ -35,11 +35,20 @@
#include "getopt.h"
+#define STEP_SIZE 0.1f
+
static GLfloat gamma = 1.0f;
static void usage(void)
{
- printf("Usage: gammatest [-h] [-f]\n");
+ printf("Usage: gamma [-h] [-f]\n");
+}
+
+static void set_gamma(float value)
+{
+ gamma = value;
+ printf("Gamma: %f\n", gamma);
+ glfwSetGamma(gamma);
}
static void key_callback(GLFWwindow window, int key, int action)
@@ -50,20 +59,26 @@ static void key_callback(GLFWwindow window, int key, int action)
switch (key)
{
case GLFW_KEY_ESCAPE:
+ {
glfwCloseWindow(window);
break;
+ }
+
case GLFW_KEY_KP_ADD:
case GLFW_KEY_Q:
- gamma += 0.1f;
- printf("Gamma: %f\n", gamma);
- glfwSetGamma(gamma);
+ {
+ set_gamma(gamma + STEP_SIZE);
break;
+ }
+
case GLFW_KEY_KP_SUBTRACT:
case GLFW_KEY_W:
- gamma -= 0.1f;
- printf("Gamma: %f\n", gamma);
- glfwSetGamma(gamma);
+ {
+ if (gamma - STEP_SIZE > 0.f)
+ set_gamma(gamma - STEP_SIZE);
+
break;
+ }
}
}
@@ -96,7 +111,7 @@ int main(int argc, char** argv)
}
}
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
@@ -124,7 +139,7 @@ int main(int argc, char** argv)
exit(EXIT_FAILURE);
}
- printf("Gamma: %f\n", gamma);
+ set_gamma(1.f);
glfwSwapInterval(1);
glfwSetKeyCallback(key_callback);
diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c
index efaff6b9..45cb8616 100644
--- a/tests/glfwinfo.c
+++ b/tests/glfwinfo.c
@@ -51,7 +51,7 @@
static void usage(void)
{
- printf("Usage: version [-h] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE] [-r STRATEGY]\n");
+ printf("Usage: glfwinfo [-h] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE] [-r STRATEGY]\n");
printf("available profiles: " PROFILE_NAME_CORE " " PROFILE_NAME_COMPAT " " PROFILE_NAME_ES2 "\n");
printf("available strategies: " STRATEGY_NAME_NONE " " STRATEGY_NAME_LOSE "\n");
}
@@ -183,7 +183,7 @@ int main(int argc, char** argv)
glfwSetErrorCallback(error_callback);
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
@@ -263,7 +263,7 @@ int main(int argc, char** argv)
if (major > 3 || (major == 3 && minor >= 2))
{
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
- printf("OpenGL profile mask: 0x%08x (%s)\n", mask, get_profile_name(mask));
+ printf("OpenGL profile mask: %s (0x%08x)\n", get_profile_name(mask), mask);
printf("OpenGL profile parsed by GLFW: %s\n",
get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE)));
diff --git a/tests/iconify.c b/tests/iconify.c
index 1ee235f1..dbc4d9cf 100644
--- a/tests/iconify.c
+++ b/tests/iconify.c
@@ -62,6 +62,8 @@ static void key_callback(GLFWwindow window, int key, int action)
static void size_callback(GLFWwindow window, int width, int height)
{
+ printf("%0.2f Size %ix%i\n", glfwGetTime(), width, height);
+
glViewport(0, 0, width, height);
}
@@ -90,7 +92,7 @@ int main(int argc, char** argv)
}
}
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
diff --git a/tests/joysticks.c b/tests/joysticks.c
index d777d431..2f208d2b 100644
--- a/tests/joysticks.c
+++ b/tests/joysticks.c
@@ -1,142 +1,216 @@
-/*========================================================================
- * This is a small test application for GLFW.
- * joystick input test.
- *========================================================================*/
+//========================================================================
+// Joystick input test
+// Copyright (c) Camilla Berglund
+//
+// 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.
+//
+//========================================================================
+//
+// This test displays the state of every button and axis of every connected
+// joystick and/or gamepad
+//
+//========================================================================
#include
#include
+#include
#include
-#include
-#define MAX_AXES 10
-#define MAX_BUTTONS 30
-
-struct JoystickState
+typedef struct Joystick
{
- int present;
- int num_axes;
- int num_buttons;
- float axes[MAX_AXES];
- unsigned char buttons[MAX_BUTTONS];
-};
+ GLboolean present;
+ float* axes;
+ unsigned char* buttons;
+ int axis_count;
+ int button_count;
+} Joystick;
-static struct JoystickState states[GLFW_JOYSTICK_LAST + 1];
+static Joystick joysticks[GLFW_JOYSTICK_LAST - GLFW_JOYSTICK_1 + 1];
-int running;
-int keyrepeat = 0;
-int systemkeys = 1;
+static int joystick_count = 0;
-
-/*========================================================================
- * Retrieve joystick states
- *========================================================================*/
-static void updateJoysticksState(void)
+static void window_size_callback(GLFWwindow window, int width, int height)
{
- int joy;
+ glViewport(0, 0, width, height);
+}
- for (joy = GLFW_JOYSTICK_1; joy < GLFW_JOYSTICK_LAST + 1; joy++)
+static void draw_joystick(Joystick* j, int x, int y, int width, int height)
+{
+ int i;
+ int axis_width, axis_height;
+ int button_width, button_height;
+
+ axis_width = width / j->axis_count;
+ axis_height = 3 * height / 4;
+
+ button_width = width / j->button_count;
+ button_height = height / 4;
+
+ for (i = 0; i < j->axis_count; i++)
{
- printf("Updating information for joystick %d\n", joy);
- states[joy].present = glfwGetJoystickParam(joy, GLFW_PRESENT);
- if (states[joy].present == GL_TRUE)
+ float value = j->axes[i] / 2.f + 0.5f;
+
+ glColor3f(0.3f, 0.3f, 0.3f);
+ glRecti(x + i * axis_width,
+ y,
+ x + (i + 1) * axis_width,
+ y + axis_height);
+
+ glColor3f(1.f, 1.f, 1.f);
+ glRecti(x + i * axis_width,
+ y + (int) (value * (axis_height - 5)),
+ x + (i + 1) * axis_width,
+ y + 5 + (int) (value * (axis_height - 5)));
+ }
+
+ for (i = 0; i < j->button_count; i++)
+ {
+ if (j->buttons[i])
+ glColor3f(1.f, 1.f, 1.f);
+ else
+ glColor3f(0.3f, 0.3f, 0.3f);
+
+ glRecti(x + i * button_width,
+ y + axis_height,
+ x + (i + 1) * button_width,
+ y + axis_height + button_height);
+ }
+}
+
+static void draw_joysticks(void)
+{
+ int i, width, height;
+
+ glfwGetWindowSize(glfwGetCurrentContext(), &width, &height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.f, width, height, 0.f, 1.f, -1.f);
+ glMatrixMode(GL_MODELVIEW);
+
+ for (i = 0; i < sizeof(joysticks) / sizeof(Joystick); i++)
+ {
+ Joystick* j = joysticks + i;
+
+ if (j->present)
{
- states[joy].num_axes = glfwGetJoystickPos(joy, states[joy].axes, MAX_AXES);
- states[joy].num_buttons = glfwGetJoystickButtons(joy, states[joy].buttons, MAX_BUTTONS);
+ draw_joystick(j,
+ 0, i * height / joystick_count,
+ width, height / joystick_count);
}
}
}
-/*========================================================================
- * Print out the state of all joysticks on the standard output
- *========================================================================*/
-static void displayJoysticksState(void)
+static void refresh_joysticks(void)
{
- int joy;
int i;
- for (joy = GLFW_JOYSTICK_1; joy < GLFW_JOYSTICK_LAST + 1; joy++)
+ for (i = 0; i < sizeof(joysticks) / sizeof(Joystick); i++)
{
- printf("Joystick %d: %s\n", joy, (states[joy].present == GL_TRUE ? "present" : "not connected"));
+ Joystick* j = joysticks + i;
- if (states[joy].present == GL_TRUE)
+ if (glfwGetJoystickParam(GLFW_JOYSTICK_1 + i, GLFW_PRESENT))
{
- if (states[joy].num_axes > 0)
+ int axis_count, button_count;
+
+ axis_count = glfwGetJoystickParam(GLFW_JOYSTICK_1 + i, GLFW_AXES);
+ if (axis_count != j->axis_count)
{
- printf(" axes: %.3f", states[joy].axes[0]);
- for (i = 1; i < states[joy].num_axes; i++)
- printf(", %.3f", states[joy].axes[i]);
-
- printf("\n");
+ j->axis_count = axis_count;
+ j->axes = realloc(j->axes, j->axis_count * sizeof(float));
}
- else
- printf(" axes: none\n");
- if (states[joy].num_buttons > 0)
+ glfwGetJoystickPos(GLFW_JOYSTICK_1 + i, j->axes, j->axis_count);
+
+ button_count = glfwGetJoystickParam(GLFW_JOYSTICK_1 + i, GLFW_BUTTONS);
+ if (button_count != j->button_count)
{
- printf(" buttons: 00 => %c", ((states[joy].buttons[0] == GLFW_PRESS) ? 'P' : 'R'));
-
- for (i = 1; i < states[joy].num_buttons; i++)
- printf(", %02d => %c", i, ((states[joy].buttons[i] == GLFW_PRESS) ? 'P' : 'R'));
-
- printf("\n");
+ j->button_count = button_count;
+ j->buttons = realloc(j->buttons, j->button_count);
+ }
+
+ glfwGetJoystickButtons(GLFW_JOYSTICK_1 + i, j->buttons, j->button_count);
+
+ if (!j->present)
+ {
+ printf("Found joystick %i with %i axes, %i buttons\n",
+ i + 1, j->axis_count, j->button_count);
+
+ joystick_count++;
+ }
+
+ j->present = GL_TRUE;
+ }
+ else
+ {
+ if (j->present)
+ {
+ free(j->axes);
+ free(j->buttons);
+ memset(j, 0, sizeof(Joystick));
+
+ printf("Lost joystick %i\n", i + 1);
+
+ joystick_count--;
}
- else
- printf(" buttons: none\n");
}
}
}
int main(void)
{
- double start;
- double t;
- double update;
+ GLFWwindow window;
- /* Initialise GLFW */
- if (!glfwInit(NULL))
+ memset(joysticks, 0, sizeof(joysticks));
+
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
}
- printf("The program will work for 20 seconds and display every seconds the state of the joysticks\n");
- printf("Your computer is going to be very slow as the program is doing an active loop .....\n");
-
- start = glfwGetTime();
- update = start;
-
- /* print the initial state of all joysticks */
- updateJoysticksState();
- printf("\n");
- displayJoysticksState();
-
- running = GL_TRUE;
-
- /* Main loop */
- while (running)
+ window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Joystick Test", NULL);
+ if (!window)
{
- /* Get time */
- t = glfwGetTime();
+ glfwTerminate();
- /* Display the state of all connected joysticks every secons */
- if ((t - update) > 1.0)
- {
- update = t;
- printf("\n");
- updateJoysticksState();
- printf("\n");
- displayJoysticksState();
- }
-
- /* Check if the window was closed */
- if ((t - start) > 20.0)
- running = GL_FALSE;
+ fprintf(stderr, "Failed to open GLFW window: %s\n", glfwErrorString(glfwGetError()));
+ exit(EXIT_FAILURE);
}
- /* Close OpenGL window and terminate GLFW */
- glfwTerminate();
+ glfwSetWindowSizeCallback(window_size_callback);
+ glfwSwapInterval(1);
- return 0;
+ while (glfwIsWindow(window))
+ {
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ refresh_joysticks();
+ draw_joysticks();
+
+ glfwSwapBuffers();
+ glfwPollEvents();
+ }
+
+ glfwTerminate();
+ exit(EXIT_SUCCESS);
}
diff --git a/tests/listmodes.c b/tests/listmodes.c
deleted file mode 100644
index 5f2d53a6..00000000
--- a/tests/listmodes.c
+++ /dev/null
@@ -1,62 +0,0 @@
-//========================================================================
-// This is a small test application for GLFW.
-// The program lists all available fullscreen video modes.
-//========================================================================
-
-#include
-
-#include
-#include
-
-static void print_mode(GLFWvidmode* mode)
-{
- printf("%i x %i x %i (%i %i %i)\n",
- mode->width, mode->height,
- mode->redBits + mode->greenBits + mode->blueBits,
- mode->redBits, mode->greenBits, mode->blueBits);
-}
-
-int main(void)
-{
- GLFWmonitor monitor;
- GLFWvidmode dtmode, modes[400];
- int modecount, i;
-
- if (!glfwInit(NULL))
- {
- fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
- exit(EXIT_FAILURE);
- }
-
- // Show desktop video mode
- glfwGetDesktopMode(&dtmode);
- printf("Desktop mode: ");
- print_mode(&dtmode);
-
- monitor = NULL;
-
- while ((monitor = glfwGetNextMonitor(monitor)))
- {
- printf("Monitor name: %s\n"
- "Physical dimensions: %dmm x %dmm\n"
- "Logical position: (%d,%d)\n",
- glfwGetMonitorString(monitor, GLFW_MONITOR_NAME),
- glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_WIDTH),
- glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_HEIGHT),
- glfwGetMonitorParam(monitor, GLFW_MONITOR_SCREEN_POS_X),
- glfwGetMonitorParam(monitor, GLFW_MONITOR_SCREEN_POS_Y));
-
- // List available video modes
- modecount = glfwGetVideoModes(monitor, modes, sizeof(modes) / sizeof(GLFWvidmode));
- printf("Available modes:\n");
-
- for (i = 0; i < modecount; i++)
- {
- printf("%3i: ", i);
- print_mode(modes + i);
- }
- }
-
- exit(EXIT_SUCCESS);
-}
-
diff --git a/tests/modes.c b/tests/modes.c
new file mode 100644
index 00000000..d7ae0bfb
--- /dev/null
+++ b/tests/modes.c
@@ -0,0 +1,257 @@
+//========================================================================
+// Video mode test
+// Copyright (c) Camilla Berglund
+//
+// 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.
+//
+//========================================================================
+//
+// This test enumerates or verifies video modes
+//
+//========================================================================
+
+#include
+
+#include
+#include
+#include
+
+#include "getopt.h"
+
+static GLFWwindow window = NULL;
+
+enum Mode
+{
+ LIST_MODE,
+ TEST_MODE
+};
+
+static void usage(void)
+{
+ printf("Usage: modes [-t]\n");
+ printf(" modes -h\n");
+}
+
+static const char* format_mode(GLFWvidmode* mode)
+{
+ static char buffer[512];
+
+ snprintf(buffer, sizeof(buffer),
+ "%i x %i x %i (%i %i %i)",
+ mode->width, mode->height,
+ mode->redBits + mode->greenBits + mode->blueBits,
+ mode->redBits, mode->greenBits, mode->blueBits);
+
+ buffer[sizeof(buffer) - 1] = '\0';
+ return buffer;
+}
+
+static void error_callback(int error, const char* description)
+{
+ fprintf(stderr, "Error: %s\n", description);
+}
+
+static void window_size_callback(GLFWwindow window, int width, int height)
+{
+ printf("Window resized to %ix%i\n", width, height);
+
+ glViewport(0, 0, width, height);
+}
+
+static int window_close_callback(GLFWwindow dummy)
+{
+ window = NULL;
+ return GL_TRUE;
+}
+
+static void key_callback(GLFWwindow dummy, int key, int action)
+{
+ if (key == GLFW_KEY_ESCAPE)
+ {
+ glfwCloseWindow(window);
+ window = NULL;
+ }
+}
+
+static GLFWvidmode* get_video_modes(GLFWmonitor monitor, size_t* found)
+{
+ size_t count = 0;
+ GLFWvidmode* modes = NULL;
+
+ for (;;)
+ {
+ count += 256;
+ modes = realloc(modes, sizeof(GLFWvidmode) * count);
+
+ *found = glfwGetVideoModes(monitor, modes, count);
+ if (*found < count)
+ break;
+ }
+
+ return modes;
+}
+
+static void list_modes(GLFWmonitor monitor)
+{
+ size_t count, i;
+ GLFWvidmode desktop_mode;
+
+ glfwGetDesktopMode(&desktop_mode);
+ printf("Desktop mode: %s\n", format_mode(&desktop_mode));
+
+ GLFWvidmode* modes = get_video_modes(monitor, &count);
+
+ printf("Monitor %s:\n", glfwGetMonitorString(monitor, GLFW_MONITOR_NAME));
+
+ for (i = 0; i < count; i++)
+ {
+ printf("%3u: %s", (unsigned int) i, format_mode(modes + i));
+
+ if (memcmp(&desktop_mode, modes + i, sizeof(GLFWvidmode)) == 0)
+ printf(" (desktop mode)");
+
+ putchar('\n');
+ }
+
+ free(modes);
+}
+
+static void test_modes(GLFWmonitor monitor)
+{
+ int width, height;
+ size_t i, count;
+ GLFWvidmode* modes = get_video_modes(monitor, &count);
+
+ glfwSetWindowSizeCallback(window_size_callback);
+ glfwSetWindowCloseCallback(window_close_callback);
+ glfwSetKeyCallback(key_callback);
+
+ for (i = 0; i < count; i++)
+ {
+ GLFWvidmode* mode = modes + i;
+
+ glfwOpenWindowHint(GLFW_RED_BITS, mode->redBits);
+ glfwOpenWindowHint(GLFW_GREEN_BITS, mode->greenBits);
+ glfwOpenWindowHint(GLFW_BLUE_BITS, mode->blueBits);
+
+ printf("Testing mode %u on monitor %s: %s",
+ (unsigned int) i,
+ glfwGetMonitorString(monitor, GLFW_MONITOR_NAME),
+ format_mode(mode));
+
+ window = glfwOpenWindow(mode->width, mode->height,
+ GLFW_FULLSCREEN, "Video Mode Test",
+ NULL);
+ if (!window)
+ {
+ printf("Failed to enter mode %u: %s\n",
+ (unsigned int) i,
+ format_mode(mode));
+ continue;
+ }
+
+ glfwSetTime(0.0);
+ glfwSwapInterval(1);
+
+ while (glfwGetTime() < 5.0)
+ {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glfwSwapBuffers();
+ glfwPollEvents();
+
+ if (!window)
+ {
+ printf("User terminated program\n");
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ if (glfwGetWindowParam(window, GLFW_RED_BITS) != mode->redBits ||
+ glfwGetWindowParam(window, GLFW_GREEN_BITS) != mode->greenBits ||
+ glfwGetWindowParam(window, GLFW_BLUE_BITS) != mode->blueBits)
+ {
+ printf("*** Color bit mismatch: (%i %i %i) instead of (%i %i %i)\n",
+ glfwGetWindowParam(window, GLFW_RED_BITS),
+ glfwGetWindowParam(window, GLFW_GREEN_BITS),
+ glfwGetWindowParam(window, GLFW_BLUE_BITS),
+ mode->redBits,
+ mode->greenBits,
+ mode->blueBits);
+ }
+
+ glfwGetWindowSize(window, &width, &height);
+
+ if (width != mode->width || height != mode->height)
+ {
+ printf("*** Size mismatch: %ix%i instead of %ix%i\n",
+ width, height,
+ mode->width, mode->height);
+ }
+
+ printf("Closing window\n");
+
+ glfwCloseWindow(window);
+ glfwPollEvents();
+ window = NULL;
+ }
+
+ free(modes);
+}
+
+int main(int argc, char** argv)
+{
+ int ch, mode = LIST_MODE;
+ GLFWmonitor monitor = NULL;
+
+ while ((ch = getopt(argc, argv, "th")) != -1)
+ {
+ switch (ch)
+ {
+ case 'h':
+ usage();
+ exit(EXIT_SUCCESS);
+ case 't':
+ mode = TEST_MODE;
+ break;
+ default:
+ usage();
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ glfwSetErrorCallback(error_callback);
+
+ if (!glfwInit())
+ exit(EXIT_FAILURE);
+
+ while ((monitor = glfwGetNextMonitor(monitor)))
+ {
+ if (mode == LIST_MODE)
+ list_modes(monitor);
+ else if (mode == TEST_MODE)
+ test_modes(monitor);
+ }
+
+ exit(EXIT_SUCCESS);
+}
+
diff --git a/tests/peter.c b/tests/peter.c
index 7c808229..b9f21f22 100644
--- a/tests/peter.c
+++ b/tests/peter.c
@@ -1,5 +1,5 @@
//========================================================================
-// Mouse cursor bug test
+// Cursor input bug test
// Copyright (c) Camilla Berglund
//
// This software is provided 'as-is', without any express or implied
@@ -41,7 +41,7 @@ static int cursor_y;
static GLboolean open_window(void);
-static void toggle_mouse_cursor(GLFWwindow window)
+static void toggle_cursor(GLFWwindow window)
{
if (glfwGetInputMode(window, GLFW_CURSOR_MODE) == GLFW_CURSOR_CAPTURED)
{
@@ -55,9 +55,9 @@ static void toggle_mouse_cursor(GLFWwindow window)
}
}
-static void mouse_position_callback(GLFWwindow window, int x, int y)
+static void cursor_position_callback(GLFWwindow window, int x, int y)
{
- printf("Mouse moved to: %i %i (%i %i)\n", x, y, x - cursor_x, y - cursor_y);
+ printf("Cursor moved to: %i %i (%i %i)\n", x, y, x - cursor_x, y - cursor_y);
cursor_x = x;
cursor_y = y;
}
@@ -69,7 +69,7 @@ static void key_callback(GLFWwindow window, int key, int action)
case GLFW_KEY_SPACE:
{
if (action == GLFW_PRESS)
- toggle_mouse_cursor(window);
+ toggle_cursor(window);
break;
}
@@ -98,11 +98,11 @@ static GLboolean open_window(void)
if (!window_handle)
return GL_FALSE;
- glfwGetMousePos(window_handle, &cursor_x, &cursor_y);
- printf("Mouse position: %i %i\n", cursor_x, cursor_y);
+ glfwGetCursorPos(window_handle, &cursor_x, &cursor_y);
+ printf("Cursor position: %i %i\n", cursor_x, cursor_y);
glfwSetWindowSizeCallback(window_size_callback);
- glfwSetMousePosCallback(mouse_position_callback);
+ glfwSetCursorPosCallback(cursor_position_callback);
glfwSetKeyCallback(key_callback);
glfwSwapInterval(1);
@@ -111,7 +111,7 @@ static GLboolean open_window(void)
int main(void)
{
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
diff --git a/tests/reopen.c b/tests/reopen.c
index 484be996..2922cb84 100644
--- a/tests/reopen.c
+++ b/tests/reopen.c
@@ -84,7 +84,7 @@ static GLboolean open_window(int width, int height, int mode)
{
double base;
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
return GL_FALSE;
diff --git a/tests/sharing.c b/tests/sharing.c
index 8be0e30b..6f1df980 100644
--- a/tests/sharing.c
+++ b/tests/sharing.c
@@ -27,6 +27,7 @@
//
//========================================================================
+#define GLFW_INCLUDE_GLU
#include
#include
@@ -92,8 +93,6 @@ static void draw_quad(GLuint texture)
glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glColor3f(0.6f, 0.f, 0.6f);
-
glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f);
@@ -117,7 +116,7 @@ int main(int argc, char** argv)
GLuint texture;
int x, y;
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
@@ -142,6 +141,11 @@ int main(int argc, char** argv)
exit(EXIT_FAILURE);
}
+ // Set drawing color for the first context and copy it to the second
+ glfwMakeContextCurrent(windows[0]);
+ glColor3f(0.6f, 0.f, 0.6f);
+ glfwCopyContext(windows[0], windows[1], GL_CURRENT_BIT);
+
// Put the second window to the right of the first one
glfwGetWindowPos(windows[0], &x, &y);
glfwSetWindowPos(windows[1], x + WIDTH + 50, y);
diff --git a/tests/tearing.c b/tests/tearing.c
index 044f8ecc..1eab454e 100644
--- a/tests/tearing.c
+++ b/tests/tearing.c
@@ -34,23 +34,42 @@
#include
#include
+static int swap_interval;
+
+static void set_swap_interval(int value)
+{
+ char title[256];
+
+ swap_interval = value;
+ glfwSwapInterval(swap_interval);
+
+ sprintf(title, "Tearing detector (interval %i)", swap_interval);
+ glfwSetWindowTitle(glfwGetCurrentContext(), title);
+}
+
static void window_size_callback(GLFWwindow window, int width, int height)
{
glViewport(0, 0, width, height);
}
+static void key_callback(GLFWwindow window, int key, int action)
+{
+ if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
+ set_swap_interval(!swap_interval);
+}
+
int main(void)
{
float position;
GLFWwindow window;
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
}
- window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Tearing Detector", NULL);
+ window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "", NULL);
if (!window)
{
glfwTerminate();
@@ -59,8 +78,10 @@ int main(void)
exit(EXIT_FAILURE);
}
+ set_swap_interval(1);
+
glfwSetWindowSizeCallback(window_size_callback);
- glfwSwapInterval(1);
+ glfwSetKeyCallback(key_callback);
glMatrixMode(GL_PROJECTION);
glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f);
diff --git a/tests/title.c b/tests/title.c
index 35344a04..7b342d94 100644
--- a/tests/title.c
+++ b/tests/title.c
@@ -41,7 +41,7 @@ int main(void)
{
GLFWwindow window;
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE);
diff --git a/tests/windows.c b/tests/windows.c
index f5844762..c7ff32b2 100644
--- a/tests/windows.c
+++ b/tests/windows.c
@@ -46,7 +46,7 @@ int main(void)
GLboolean running = GL_TRUE;
GLFWwindow windows[4];
- if (!glfwInit(NULL))
+ if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW: %s\n",
glfwErrorString(glfwGetError()));