Merge branch 'master' into multi-monitor

Conflicts:
	.gitignore
	examples/CMakeLists.txt
	include/GL/glfw3.h
	src/CMakeLists.txt
	src/internal.h
	src/win32_platform.h
	src/win32_window.c
	src/x11_fullscreen.c
	src/x11_platform.h
	tests/listmodes.c
This commit is contained in:
Camilla Berglund 2012-07-05 16:15:01 +02:00
commit c06f838d88
82 changed files with 4090 additions and 6527 deletions

33
.gitignore vendored
View File

@ -1,25 +1,30 @@
*.a .DS_Store
CMakeCache.txt CMakeCache.txt
CMakeFiles CMakeFiles
cmake_install.cmake cmake_install.cmake
cmake_uninstall.cmake cmake_uninstall.cmake
.DS_Store docs/Doxyfile
src/config.h examples/*.app
src/libglfw.pc examples/*.exe
src/libglfw.so
src/libglfw.a
src/libglfw.dylib
src/libglfw.lib
src/libglfwdll.lib
src/libglfw.dll
examples/boing examples/boing
examples/gears examples/gears
examples/heightmap examples/heightmap
examples/splitview examples/splitview
examples/triangle examples/triangle
examples/wave examples/wave
examples/*.app src/config.h
examples/*.exe 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/accuracy
tests/defaults tests/defaults
tests/dynamic tests/dynamic
@ -30,12 +35,10 @@ tests/gamma
tests/glfwinfo tests/glfwinfo
tests/iconify tests/iconify
tests/joysticks tests/joysticks
tests/listmodes
tests/peter tests/peter
tests/reopen tests/reopen
tests/sharing tests/sharing
tests/tearing tests/tearing
tests/title
tests/version tests/version
tests/windows tests/windows
tests/*.app
tests/*.exe

View File

@ -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)

View File

@ -1,10 +1,19 @@
This folder contains a collection of toolchains definition in order to This directory contains a collection of toolchain definitions for cross
support cross compilation. The naming scheme is the following: compilation, currently limited to compiling Win32 binaries on Linux.
The toolchain file naming scheme is as follows:
host-system-compiler.cmake host-system-compiler.cmake
to use this at the time you run the initial cmake command use the To use these files you add a special parameter when configuring the source tree:
following parameter
-DCMAKE_TOOLCHAIN_FILE=./toolchains/XXX-XXX-XXX.cmake cmake -DCMAKE_TOOLCHAIN_FILE=<toolchain-file> .
which maps to file in this folder.
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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -1,14 +1,12 @@
# Define the cross compilation environment for cross compiling from linux # Define the environment for cross compiling from Linux to Win32
# to win32 it is to be used when debian cross compilation toolchain is SET(CMAKE_SYSTEM_NAME Windows)
# available. SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_SYSTEM_NAME Windows) # Target system name
SET(CMAKE_SYSTEM_VERSION 1) # Not really used.
SET(CMAKE_C_COMPILER "i586-mingw32msvc-gcc") SET(CMAKE_C_COMPILER "i586-mingw32msvc-gcc")
SET(CMAKE_CXX_COMPILER "i586-mingw32msvc-g++") SET(CMAKE_CXX_COMPILER "i586-mingw32msvc-g++")
SET(CMAKE_RC_COMPILER "i586-mingw32msvc-windres")
SET(CMAKE_RANLIB "i586-mingw32msvc-ranlib") 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 "/usr/i586-mingw32msvc")
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)

View File

@ -1,9 +1,9 @@
# Define the cross compilation environment for cross compiling from linux # Define the environment for cross compiling from Linux to Win32
# to win32
SET(CMAKE_SYSTEM_NAME Windows) # Target system name SET(CMAKE_SYSTEM_NAME Windows) # Target system name
SET(CMAKE_SYSTEM_VERSION 1) SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER "i686-pc-mingw32-gcc") SET(CMAKE_C_COMPILER "i686-pc-mingw32-gcc")
SET(CMAKE_CXX_COMPILER "i686-pc-mingw32-g++") SET(CMAKE_CXX_COMPILER "i686-pc-mingw32-g++")
SET(CMAKE_RC_COMPILER "i686-pc-mingw32-windres")
SET(CMAKE_RANLIB "i686-pc-mingw32-ranlib") SET(CMAKE_RANLIB "i686-pc-mingw32-ranlib")
#Configure the behaviour of the find commands #Configure the behaviour of the find commands

View File

@ -1,7 +1,6 @@
project(GLFW C) project(GLFW C)
cmake_minimum_required(VERSION 2.4) cmake_minimum_required(VERSION 2.8)
cmake_policy(VERSION 2.4)
set(GLFW_VERSION_MAJOR "3") set(GLFW_VERSION_MAJOR "3")
set(GLFW_VERSION_MINOR "0") 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_EXAMPLES "Build the GLFW example programs" ON)
option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON)
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
find_package(OpenGL REQUIRED) 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) if (WIN32)
message(STATUS "Building GLFW for WGL on a Win32 system")
# Define the platform identifier
set(_GLFW_WIN32_WGL 1) 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 # Set up library and include paths
list(APPEND GLFW_INCLUDE_DIR ${OPENGL_INCLUDE_DIR}) list(APPEND glfw_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR})
list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY}) list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY})
endif (WIN32)
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 # Set up GLFW for Xlib and GLX on Unix-like systems with X Windows
#-------------------------------------------------------------------- #--------------------------------------------------------------------
if (UNIX AND NOT APPLE) if (_GLFW_X11_GLX)
message(STATUS "Building GLFW for X11 and GLX on a Unix-like system")
# Define the platform identifier find_package(X11 REQUIRED)
set(_GLFW_X11_GLX 1)
# Set up library and include paths # Set up library and include paths
list(APPEND GLFW_INCLUDE_DIR ${X11_X11_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR}) list(APPEND glfw_INCLUDE_DIRS ${X11_X11_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR})
list(APPEND GLFW_LIBRARIES ${X11_X11_LIB} ${OPENGL_gl_LIBRARY}) list(APPEND glfw_LIBRARIES ${X11_X11_LIB} ${OPENGL_gl_LIBRARY})
find_library(MATH_LIBRARY m) set(GLFW_PKG_DEPS "gl x11")
if (MATH_LIBRARY) set(GLFW_PKG_LIBS "")
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)
include(CheckFunctionExists) 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 for XRandR (modern resolution switching extension)
check_x11_xrandr() if (X11_Xrandr_FOUND)
if (X11_XRANDR_FOUND)
set(_GLFW_HAS_XRANDR 1) set(_GLFW_HAS_XRANDR 1)
list(APPEND GLFW_INCLUDE_DIR ${X11_XRANDR_INCLUDE_DIR}) list(APPEND glfw_INCLUDE_DIRS ${X11_Xrandr_INCLUDE_PATH})
list(APPEND GLFW_LIBRARIES ${X11_XRANDR_LIBRARIES}) list(APPEND glfw_LIBRARIES ${X11_Xrandr_LIB})
endif(X11_XRANDR_FOUND) set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} xrandr")
endif()
# Check for Xf86VidMode (fallback legacy resolution switching extension) # Check for Xf86VidMode (fallback legacy resolution switching extension)
check_x11_xf86vidmode() if (X11_xf86vmode_FOUND)
if (X11_XF86VIDMODE_FOUND)
set(_GLFW_HAS_XF86VIDMODE 1) set(_GLFW_HAS_XF86VIDMODE 1)
list(APPEND GLFW_INCLUDE_DIR ${X11_XF86VIDMODE_INCLUDE_DIR}) list(APPEND glfw_INCLUDE_DIRS ${X11_xf86vmode_INCLUDE_PATH})
list(APPEND GLFW_LIBRARIES ${X11_XF86VIDMODE_LIBRARIES})
endif(X11_XF86VIDMODE_FOUND) # 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 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) check_function_exists(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS)
if (NOT _GLFW_HAS_GLXGETPROCADDRESS) if (NOT _GLFW_HAS_GLXGETPROCADDRESS)
check_function_exists(glXGetProcAddressARB _GLFW_HAS_GLXGETPROCADDRESSARB) check_function_exists(glXGetProcAddressARB _GLFW_HAS_GLXGETPROCADDRESSARB)
endif (NOT _GLFW_HAS_GLXGETPROCADDRESS) endif()
if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB) if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB)
check_function_exists(glXGetProcAddressEXT _GLFW_HAS_GLXGETPROCADDRESSEXT) check_function_exists(glXGetProcAddressEXT _GLFW_HAS_GLXGETPROCADDRESSEXT)
endif (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB) endif()
if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND
NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND
NOT _GLFW_HAS_GLXGETPROCADDRESSEXT) NOT _GLFW_HAS_GLXGETPROCADDRESSEXT)
message(WARNING "No glXGetProcAddressXXX variant found") message(WARNING "No glXGetProcAddressXXX variant found")
endif (NOT _GLFW_HAS_GLXGETPROCADDRESS AND
NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND # Check for dlopen support as a fallback
NOT _GLFW_HAS_GLXGETPROCADDRESSEXT)
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") if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(_GLFW_USE_LINUX_JOYSTICKS 1) set(_GLFW_USE_LINUX_JOYSTICKS 1)
endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") endif()
endif(UNIX AND NOT APPLE) endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Set up GLFW for Cocoa and NSOpenGL on Mac OS X # Set up GLFW for Cocoa and NSOpenGL on Mac OS X
#-------------------------------------------------------------------- #--------------------------------------------------------------------
if (UNIX AND APPLE) if (_GLFW_COCOA_NSGL)
message(STATUS "Building GLFW for Cocoa and NSOpenGL on Mac OS X")
# Define the platform identifier option(GLFW_BUILD_UNIVERSAL "Build GLFW as a Universal Binary" OFF)
set(_GLFW_COCOA_NSGL 1)
option(GLFW_BUILD_UNIVERSAL "Build the GLFW library and examples as Universal Binaries" FALSE)
# Universal build # Universal build
if (GLFW_BUILD_UNIVERSAL) if (GLFW_BUILD_UNIVERSAL)
@ -120,17 +180,25 @@ if (UNIX AND APPLE)
set(CMAKE_C_FLAGS "-mmacosx-version-min=10.5") set(CMAKE_C_FLAGS "-mmacosx-version-min=10.5")
else(GLFW_BUILD_UNIVERSAL) else(GLFW_BUILD_UNIVERSAL)
message(STATUS "Building GLFW only for the native architecture") message(STATUS "Building GLFW only for the native architecture")
endif(GLFW_BUILD_UNIVERSAL) endif()
# Set up library and include paths # Set up library and include paths
find_library(COCOA_FRAMEWORK Cocoa) find_library(COCOA_FRAMEWORK Cocoa)
find_library(IOKIT_FRAMEWORK IOKit) find_library(IOKIT_FRAMEWORK IOKit)
find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation) find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation)
list(APPEND GLFW_LIBRARIES ${COCOA_FRAMEWORK}) list(APPEND glfw_LIBRARIES ${COCOA_FRAMEWORK}
list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY}) ${OPENGL_gl_LIBRARY}
list(APPEND GLFW_LIBRARIES ${IOKIT_FRAMEWORK}) ${IOKIT_FRAMEWORK}
list(APPEND GLFW_LIBRARIES ${CORE_FOUNDATION_FRAMEWORK}) ${CORE_FOUNDATION_FRAMEWORK})
endif(UNIX AND APPLE)
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 # Add subdirectories
@ -139,42 +207,47 @@ add_subdirectory(src)
if (GLFW_BUILD_EXAMPLES) if (GLFW_BUILD_EXAMPLES)
add_subdirectory(examples) add_subdirectory(examples)
endif(GLFW_BUILD_EXAMPLES) endif()
if (GLFW_BUILD_TESTS) if (GLFW_BUILD_TESTS)
add_subdirectory(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 configure_file(${GLFW_SOURCE_DIR}/src/config.h.in
${GLFW_BINARY_DIR}/src/config.h @ONLY) ${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 install(DIRECTORY include/GL DESTINATION include
FILES_MATCHING PATTERN glfw3.h) FILES_MATCHING PATTERN glfw3.h)
install(FILES COPYING.txt readme.html install(FILES COPYING.txt readme.html
DESTINATION share/doc/glfw-${GLFW_VERSION_FULL}/) DESTINATION share/doc/glfw-${GLFW_VERSION_FULL})
# The respective port's CMakeLists.txt file installs the library
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# -- Documentation generation # Create and install pkg-config file on supported platforms
#-------------------------------------------------------------------- #--------------------------------------------------------------------
configure_file("${GLFW_SOURCE_DIR}/docs/Doxyfile.in" if (_GLFW_X11_GLX OR _GLFW_COCOA_NSGL)
"${GLFW_BINARY_DIR}/docs/Doxyfile" configure_file(${GLFW_SOURCE_DIR}/src/libglfw.pc.in
@ONLY) ${GLFW_BINARY_DIR}/src/libglfw.pc @ONLY)
install(FILES ${GLFW_BINARY_DIR}/src/libglfw.pc
DESTINATION lib/pkgconfig)
endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Uninstall operation # Uninstall operation
# Don't generate this target if a higher-level project already has # 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 configure_file(${GLFW_SOURCE_DIR}/cmake_uninstall.cmake.in
${GLFW_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY) ${GLFW_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY)

View File

@ -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

View File

@ -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

View File

@ -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}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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.

View File

@ -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 link_libraries(glfw ${OPENGL_glu_LIBRARY})
# the main CMakeLists.txt
link_libraries(libglfwStatic ${GLFW_LIBRARIES} ${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 include_directories(${GLFW_SOURCE_DIR}/include
${GLFW_SOURCE_DIR}/support ${GLFW_SOURCE_DIR}/support
${OPENGL_INCLUDE_DIR}) ${OPENGL_INCLUDE_DIR})
if(APPLE) if (APPLE)
# Set fancy names for bundles # Set fancy names for bundles
add_executable(Boing MACOSX_BUNDLE boing.c) add_executable(Boing MACOSX_BUNDLE boing.c)
add_executable(Gears MACOSX_BUNDLE gears.c) add_executable(Gears MACOSX_BUNDLE gears.c)
add_executable("Split View" MACOSX_BUNDLE splitview.c) add_executable("Split View" MACOSX_BUNDLE splitview.c)
add_executable(Triangle MACOSX_BUNDLE triangle.c) add_executable(Triangle MACOSX_BUNDLE triangle.c)
add_executable(Wave MACOSX_BUNDLE wave.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)
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) if (MSVC)
# Tell MSVC to use main instead of WinMain for Windows subsystem executables set(WINDOWS_BINARIES boing gears heightmap splitview triangle wave)
set_target_properties(${WINDOWS_BINARIES} PROPERTIES
LINK_FLAGS "/ENTRY:mainCRTStartup") # Tell MSVC to use main instead of WinMain for Windows subsystem executables
endif(MSVC) 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()

View File

@ -30,6 +30,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#define GLFW_INCLUDE_GLU
#include <GL/glfw3.h> #include <GL/glfw3.h>
@ -569,7 +571,7 @@ int main( void )
GLFWwindow window; GLFWwindow window;
/* Init GLFW */ /* Init GLFW */
if( !glfwInit(NULL) ) if( !glfwInit() )
{ {
fprintf( stderr, "Failed to initialize GLFW\n" ); fprintf( stderr, "Failed to initialize GLFW\n" );
exit( EXIT_FAILURE ); exit( EXIT_FAILURE );

View File

@ -323,7 +323,7 @@ int main(int argc, char *argv[])
{ {
GLFWwindow window; GLFWwindow window;
if( !glfwInit(NULL) ) if( !glfwInit() )
{ {
fprintf( stderr, "Failed to initialize GLFW\n" ); fprintf( stderr, "Failed to initialize GLFW\n" );
exit( EXIT_FAILURE ); exit( EXIT_FAILURE );

View File

@ -32,8 +32,6 @@
#include <stddef.h> #include <stddef.h>
#include "getopt.h" #include "getopt.h"
#define GLFW_NO_GLU 1
#include <GL/glfw3.h> #include <GL/glfw3.h>
#include <GL/glext.h> #include <GL/glext.h>
@ -84,7 +82,7 @@ static PFNGLVERTEXATTRIBPOINTERPROC pglVertexAttribPointer = NULL;
#define RESOLVE_GL_FCN(type, var, name) \ #define RESOLVE_GL_FCN(type, var, name) \
if (status == GL_TRUE) \ if (status == GL_TRUE) \
{\ {\
var = glfwGetProcAddress((name));\ var = (type) glfwGetProcAddress((name));\
if ((var) == NULL)\ if ((var) == NULL)\
{\ {\
status = GL_FALSE;\ status = GL_FALSE;\
@ -95,31 +93,31 @@ static PFNGLVERTEXATTRIBPOINTERPROC pglVertexAttribPointer = NULL;
static GLboolean init_opengl(void) static GLboolean init_opengl(void)
{ {
GLboolean status = GL_TRUE; GLboolean status = GL_TRUE;
RESOLVE_GL_FCN(PFN_glCreateShader, pglCreateShader, "glCreateShader"); RESOLVE_GL_FCN(PFNGLCREATESHADERPROC, pglCreateShader, "glCreateShader");
RESOLVE_GL_FCN(PFN_glShaderSource, pglShaderSource, "glShaderSource"); RESOLVE_GL_FCN(PFNGLSHADERSOURCEPROC, pglShaderSource, "glShaderSource");
RESOLVE_GL_FCN(PFN_glCompileShader, pglCompileShader, "glCompileShader"); RESOLVE_GL_FCN(PFNGLCOMPILESHADERPROC, pglCompileShader, "glCompileShader");
RESOLVE_GL_FCN(PFN_glGetShaderiv, pglGetShaderiv, "glGetShaderiv"); RESOLVE_GL_FCN(PFNGLGETSHADERIVPROC, pglGetShaderiv, "glGetShaderiv");
RESOLVE_GL_FCN(PFN_glGetShaderInfoLog, pglGetShaderInfoLog, "glGetShaderInfoLog"); RESOLVE_GL_FCN(PFNGLGETSHADERINFOLOGPROC, pglGetShaderInfoLog, "glGetShaderInfoLog");
RESOLVE_GL_FCN(PFN_glDeleteShader, pglDeleteShader, "glDeleteShader"); RESOLVE_GL_FCN(PFNGLDELETESHADERPROC, pglDeleteShader, "glDeleteShader");
RESOLVE_GL_FCN(PFN_glCreateProgram, pglCreateProgram, "glCreateProgram"); RESOLVE_GL_FCN(PFNGLCREATEPROGRAMPROC, pglCreateProgram, "glCreateProgram");
RESOLVE_GL_FCN(PFN_glAttachShader, pglAttachShader, "glAttachShader"); RESOLVE_GL_FCN(PFNGLATTACHSHADERPROC, pglAttachShader, "glAttachShader");
RESOLVE_GL_FCN(PFN_glLinkProgram, pglLinkProgram, "glLinkProgram"); RESOLVE_GL_FCN(PFNGLLINKPROGRAMPROC, pglLinkProgram, "glLinkProgram");
RESOLVE_GL_FCN(PFN_glUseProgram, pglUseProgram, "glUseProgram"); RESOLVE_GL_FCN(PFNGLUSEPROGRAMPROC, pglUseProgram, "glUseProgram");
RESOLVE_GL_FCN(PFN_glGetProgramiv, pglGetProgramiv, "glGetProgramiv"); RESOLVE_GL_FCN(PFNGLGETPROGRAMIVPROC, pglGetProgramiv, "glGetProgramiv");
RESOLVE_GL_FCN(PFN_glGetProgramInfoLog, pglGetProgramInfoLog, "glGetProgramInfoLog"); RESOLVE_GL_FCN(PFNGLGETPROGRAMINFOLOGPROC, pglGetProgramInfoLog, "glGetProgramInfoLog");
RESOLVE_GL_FCN(PFN_glDeleteProgram, pglDeleteProgram, "glDeleteProgram"); RESOLVE_GL_FCN(PFNGLDELETEPROGRAMPROC, pglDeleteProgram, "glDeleteProgram");
RESOLVE_GL_FCN(PFN_glGetUniformLocation, pglGetUniformLocation, "glGetUniformLocation"); RESOLVE_GL_FCN(PFNGLGETUNIFORMLOCATIONPROC, pglGetUniformLocation, "glGetUniformLocation");
RESOLVE_GL_FCN(PFN_glUniformMatrix4fv, pglUniformMatrix4fv, "glUniformMatrix4fv"); RESOLVE_GL_FCN(PFNGLUNIFORMMATRIX4FVPROC, pglUniformMatrix4fv, "glUniformMatrix4fv");
RESOLVE_GL_FCN(PFN_glGetAttribLocation, pglGetAttribLocation, "glGetAttribLocation"); RESOLVE_GL_FCN(PFNGLGETATTRIBLOCATIONPROC, pglGetAttribLocation, "glGetAttribLocation");
RESOLVE_GL_FCN(PFN_glGenVertexArrays, pglGenVertexArrays, "glGenVertexArrays"); RESOLVE_GL_FCN(PFNGLGENVERTEXARRAYSPROC, pglGenVertexArrays, "glGenVertexArrays");
RESOLVE_GL_FCN(PFN_glDeleteVertexArrays, pglDeleteVertexArrays, "glDeleteVertexArrays"); RESOLVE_GL_FCN(PFNGLDELETEVERTEXARRAYSPROC, pglDeleteVertexArrays, "glDeleteVertexArrays");
RESOLVE_GL_FCN(PFN_glBindVertexArray, pglBindVertexArray, "glBindVertexArray"); RESOLVE_GL_FCN(PFNGLBINDVERTEXARRAYPROC, pglBindVertexArray, "glBindVertexArray");
RESOLVE_GL_FCN(PFN_glGenBuffers, pglGenBuffers, "glGenBuffers"); RESOLVE_GL_FCN(PFNGLGENBUFFERSPROC, pglGenBuffers, "glGenBuffers");
RESOLVE_GL_FCN(PFN_glBindBuffer, pglBindBuffer, "glBindBuffer"); RESOLVE_GL_FCN(PFNGLBINDBUFFERPROC, pglBindBuffer, "glBindBuffer");
RESOLVE_GL_FCN(PFN_glBufferData, pglBufferData, "glBufferData"); RESOLVE_GL_FCN(PFNGLBUFFERDATAPROC, pglBufferData, "glBufferData");
RESOLVE_GL_FCN(PFN_glBufferSubData, pglBufferSubData, "glBufferSubData"); RESOLVE_GL_FCN(PFNGLBUFFERSUBDATAPROC, pglBufferSubData, "glBufferSubData");
RESOLVE_GL_FCN(PFN_glEnableVertexAttribArray, pglEnableVertexAttribArray, "glEnableVertexAttribArray"); RESOLVE_GL_FCN(PFNGLENABLEVERTEXATTRIBARRAYPROC, pglEnableVertexAttribArray, "glEnableVertexAttribArray");
RESOLVE_GL_FCN(PFN_glVertexAttribPointer, pglVertexAttribPointer, "glVertexAttribPointer"); RESOLVE_GL_FCN(PFNGLVERTEXATTRIBPOINTERPROC, pglVertexAttribPointer, "glVertexAttribPointer");
return status; 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"); fprintf(stderr, "ERROR: Unable to initialize GLFW\n");
usage(); usage();

View File

@ -10,7 +10,9 @@
// because I am not a friend of orthogonal projections) // because I am not a friend of orthogonal projections)
//======================================================================== //========================================================================
#define GLFW_INCLUDE_GLU
#include <GL/glfw3.h> #include <GL/glfw3.h>
#include <math.h> #include <math.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -377,7 +379,7 @@ static void windowRefreshFun(GLFWwindow window)
// Mouse position callback function // 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 // Depending on which view was selected, rotate around different axes
switch (active_view) switch (active_view)
@ -402,7 +404,7 @@ static void mousePosFun(GLFWwindow window, int x, int y)
break; break;
} }
// Remember mouse position // Remember cursor position
xpos = x; xpos = x;
ypos = y; ypos = y;
} }
@ -442,7 +444,7 @@ int main(void)
GLFWwindow window; GLFWwindow window;
// Initialise GLFW // Initialise GLFW
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW\n"); fprintf(stderr, "Failed to initialize GLFW\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -470,7 +472,7 @@ int main(void)
// Set callback functions // Set callback functions
glfwSetWindowSizeCallback(windowSizeFun); glfwSetWindowSizeCallback(windowSizeFun);
glfwSetWindowRefreshCallback(windowRefreshFun); glfwSetWindowRefreshCallback(windowRefreshFun);
glfwSetMousePosCallback(mousePosFun); glfwSetCursorPosCallback(cursorPosFun);
glfwSetMouseButtonCallback(mouseButtonFun); glfwSetMouseButtonCallback(mouseButtonFun);
// Main loop // Main loop

View File

@ -7,6 +7,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define GLFW_INCLUDE_GLU
#include <GL/glfw3.h> #include <GL/glfw3.h>
int main(void) int main(void)
@ -15,7 +16,7 @@ int main(void)
GLFWwindow window; GLFWwindow window;
// Initialise GLFW // Initialise GLFW
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW\n"); fprintf(stderr, "Failed to initialize GLFW\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -38,7 +39,7 @@ int main(void)
do do
{ {
double t = glfwGetTime(); double t = glfwGetTime();
glfwGetMousePos(window, &x, NULL); glfwGetCursorPos(window, &x, NULL);
// Get window size (may be different than the requested size) // Get window size (may be different than the requested size)
glfwGetWindowSize(window, &width, &height); glfwGetWindowSize(window, &width, &height);

View File

@ -11,6 +11,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
#define GLFW_INCLUDE_GLU
#include <GL/glfw3.h> #include <GL/glfw3.h>
#ifndef M_PI #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) if (locked)
{ {
@ -341,9 +343,9 @@ void mouse_position_callback(GLFWwindow window, int x, int y)
// Callback function for scroll events // 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) if (zoom < 0)
zoom = 0; zoom = 0;
} }
@ -379,7 +381,7 @@ int main(int argc, char* argv[])
GLFWwindow window; GLFWwindow window;
double t, dt_total, t_old; double t, dt_total, t_old;
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "GLFW initialization failed\n"); fprintf(stderr, "GLFW initialization failed\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -401,7 +403,7 @@ int main(int argc, char* argv[])
// Window resize handler // Window resize handler
glfwSetWindowSizeCallback(window_resize_callback); glfwSetWindowSizeCallback(window_resize_callback);
glfwSetMouseButtonCallback(mouse_button_callback); glfwSetMouseButtonCallback(mouse_button_callback);
glfwSetMousePosCallback(mouse_position_callback); glfwSetCursorPosCallback(cursor_position_callback);
glfwSetScrollCallback(scroll_callback); glfwSetScrollCallback(scroll_callback);
// Initialize OpenGL // Initialize OpenGL

View File

@ -67,6 +67,12 @@ extern "C" {
#endif #endif
#endif /* APIENTRY */ #endif /* APIENTRY */
/* TEMPORARY MinGW-w64 hacks.
*/
#if __MINGW64__
#define WINAPI
#include <stddef.h>
#endif
/* The following three defines are here solely to make some Windows-based /* The following three defines are here solely to make some Windows-based
* <GL/gl.h> files happy. Theoretically we could include <windows.h>, but * <GL/gl.h> files happy. Theoretically we could include <windows.h>, but
@ -113,7 +119,11 @@ extern "C" {
/* ---------------- GLFW related system specific defines ----------------- */ /* ---------------- 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 */ /* We are building a Win32 DLL */
#define GLFWAPI __declspec(dllexport) #define GLFWAPI __declspec(dllexport)
@ -136,15 +146,7 @@ extern "C" {
/* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ /* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */
/* Include the declaration of the size_t type used below. /* Include the chosen OpenGL header and, optionally, the GLU header.
*/
#include <stddef.h>
/* Include standard OpenGL headers: GLFW uses GL_FALSE/GL_TRUE, and it is
* convenient for the user to only have to include <GL/glfw.h>. This also
* solves the problem with Windows <GL/gl.h> and <GL/glu.h> needing some
* special defines which normally requires the user to include <windows.h>
* (which is not a nice solution for portable programs).
*/ */
#if defined(__APPLE_CC__) #if defined(__APPLE_CC__)
#if defined(GLFW_INCLUDE_GL3) #if defined(GLFW_INCLUDE_GL3)
@ -153,7 +155,7 @@ extern "C" {
#define GL_GLEXT_LEGACY #define GL_GLEXT_LEGACY
#include <OpenGL/gl.h> #include <OpenGL/gl.h>
#endif #endif
#ifndef GLFW_NO_GLU #if defined(GLFW_INCLUDE_GLU)
#include <OpenGL/glu.h> #include <OpenGL/glu.h>
#endif #endif
#else #else
@ -162,7 +164,7 @@ extern "C" {
#else #else
#include <GL/gl.h> #include <GL/gl.h>
#endif #endif
#ifndef GLFW_NO_GLU #if defined(GLFW_INCLUDE_GLU)
#include <GL/glu.h> #include <GL/glu.h>
#endif #endif
#endif #endif
@ -455,6 +457,7 @@ extern "C" {
#define GLFW_VERSION_UNAVAILABLE 0x00070007 #define GLFW_VERSION_UNAVAILABLE 0x00070007
#define GLFW_PLATFORM_ERROR 0x00070008 #define GLFW_PLATFORM_ERROR 0x00070008
#define GLFW_WINDOW_NOT_ACTIVE 0x00070009 #define GLFW_WINDOW_NOT_ACTIVE 0x00070009
#define GLFW_FORMAT_UNAVAILABLE 0x0007000A
/* Gamma ramps */ /* Gamma ramps */
#define GLFW_GAMMA_RAMP_SIZE 256 #define GLFW_GAMMA_RAMP_SIZE 256
@ -475,6 +478,9 @@ extern "C" {
/* Monitor handle type */ /* Monitor handle type */
typedef void* GLFWmonitor; typedef void* GLFWmonitor;
/* OpenGL function pointer type */
typedef void (*GLFWglproc)(void);
/* Window handle type */ /* Window handle type */
typedef void* GLFWwindow; typedef void* GLFWwindow;
@ -486,12 +492,11 @@ typedef void (* GLFWwindowrefreshfun)(GLFWwindow);
typedef void (* GLFWwindowfocusfun)(GLFWwindow,int); typedef void (* GLFWwindowfocusfun)(GLFWwindow,int);
typedef void (* GLFWwindowiconifyfun)(GLFWwindow,int); typedef void (* GLFWwindowiconifyfun)(GLFWwindow,int);
typedef void (* GLFWmousebuttonfun)(GLFWwindow,int,int); typedef void (* GLFWmousebuttonfun)(GLFWwindow,int,int);
typedef void (* GLFWmouseposfun)(GLFWwindow,int,int); typedef void (* GLFWcursorposfun)(GLFWwindow,int,int);
typedef void (* GLFWscrollfun)(GLFWwindow,int,int); typedef void (* GLFWcursorenterfun)(GLFWwindow,int);
typedef void (* GLFWscrollfun)(GLFWwindow,double,double);
typedef void (* GLFWkeyfun)(GLFWwindow,int,int); typedef void (* GLFWkeyfun)(GLFWwindow,int,int);
typedef void (* GLFWcharfun)(GLFWwindow,int); typedef void (* GLFWcharfun)(GLFWwindow,int);
typedef void* (* GLFWmallocfun)(size_t);
typedef void (* GLFWfreefun)(void*);
typedef void (* GLFWmonitordevicefun)(GLFWmonitor,int); typedef void (* GLFWmonitordevicefun)(GLFWmonitor,int);
/* The video mode structure used by glfwGetVideoModes */ /* The video mode structure used by glfwGetVideoModes */
@ -512,20 +517,13 @@ typedef struct
unsigned short blue[GLFW_GAMMA_RAMP_SIZE]; unsigned short blue[GLFW_GAMMA_RAMP_SIZE];
} GLFWgammaramp; } GLFWgammaramp;
/* Custom memory allocator interface */
typedef struct
{
GLFWmallocfun malloc;
GLFWfreefun free;
} GLFWallocator;
/************************************************************************* /*************************************************************************
* Prototypes * Prototypes
*************************************************************************/ *************************************************************************/
/* Initialization, termination and version querying */ /* Initialization, termination and version querying */
GLFWAPI int glfwInit(GLFWallocator* allocator); GLFWAPI int glfwInit(void);
GLFWAPI void glfwTerminate(void); GLFWAPI void glfwTerminate(void);
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev);
GLFWAPI const char* glfwGetVersionString(void); 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 void glfwSetInputMode(GLFWwindow window, int mode, int value);
GLFWAPI int glfwGetKey(GLFWwindow window, int key); GLFWAPI int glfwGetKey(GLFWwindow window, int key);
GLFWAPI int glfwGetMouseButton(GLFWwindow window, int button); GLFWAPI int glfwGetMouseButton(GLFWwindow window, int button);
GLFWAPI void glfwGetMousePos(GLFWwindow window, int* xpos, int* ypos); GLFWAPI void glfwGetCursorPos(GLFWwindow window, int* xpos, int* ypos);
GLFWAPI void glfwSetMousePos(GLFWwindow window, int xpos, int ypos); GLFWAPI void glfwSetCursorPos(GLFWwindow window, int xpos, int ypos);
GLFWAPI void glfwGetScrollOffset(GLFWwindow window, int* xoffset, int* yoffset); GLFWAPI void glfwGetScrollOffset(GLFWwindow window, double* xoffset, double* yoffset);
GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun); GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun);
GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun); GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun);
GLFWAPI void glfwSetMouseButtonCallback(GLFWmousebuttonfun 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); GLFWAPI void glfwSetScrollCallback(GLFWscrollfun cbfun);
/* Joystick input */ /* Joystick input */
@ -600,6 +599,10 @@ GLFWAPI int glfwGetJoystickParam(int joy, int param);
GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes); GLFWAPI int glfwGetJoystickPos(int joy, float* pos, int numaxes);
GLFWAPI int glfwGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons); 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 */ /* Time */
GLFWAPI double glfwGetTime(void); GLFWAPI double glfwGetTime(void);
GLFWAPI void glfwSetTime(double time); GLFWAPI void glfwSetTime(double time);
@ -610,7 +613,7 @@ GLFWAPI GLFWwindow glfwGetCurrentContext(void);
GLFWAPI void glfwSwapBuffers(void); GLFWAPI void glfwSwapBuffers(void);
GLFWAPI void glfwSwapInterval(int interval); GLFWAPI void glfwSwapInterval(int interval);
GLFWAPI int glfwExtensionSupported(const char* extension); 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); GLFWAPI void glfwCopyContext(GLFWwindow src, GLFWwindow dst, unsigned long mask);

View File

@ -20,7 +20,8 @@
<li><a href="#credits">Acknowledgements</a></li> <li><a href="#credits">Acknowledgements</a></li>
</ol> </ol>
<a name="intro">
<a name="intro"></a>
<h2>1. Introduction</h2> <h2>1. Introduction</h2>
<p>Welcome to version 3.0 of the GLFW library. GLFW is a free, open source, <p>Welcome to version 3.0 of the GLFW library. GLFW is a free, open source,
@ -34,19 +35,22 @@ settle.</p>
<p><strong>Note</strong> that the threading and image loading APIs from the 2.x <p><strong>Note</strong> that the threading and image loading APIs from the 2.x
series have been removed.</p> series have been removed.</p>
<a name="compiling">
<a name="compiling"></a>
<h2>2. Compiling GLFW and the example programs</h2> <h2>2. Compiling GLFW and the example programs</h2>
<p>To compile GLFW and the accompanying example programs, you will need the <p>To compile GLFW and the accompanying example programs, you will need the
<a href="http://www.cmake.org/">CMake</a> build system.</p> <a href="http://www.cmake.org/">CMake</a> build system.</p>
<a name="installing">
<a name="installing"></a>
<h2>3. Installing GLFW</h2> <h2>3. Installing GLFW</h2>
<p>A rudimentary installation target is provided for all supported platforms <p>A rudimentary installation target is provided for all supported platforms
via the CMake build system.</p> via the CMake build system.</p>
<a name="using">
<a name="using"></a>
<h2>4. Using GLFW</h2> <h2>4. Using GLFW</h2>
<p>There are two aspects to using GLFW:</p> <p>There are two aspects to using GLFW:</p>
@ -66,12 +70,13 @@ GLFW API.</p>
A few rules for successfully designing GLFW-based programs are presented A few rules for successfully designing GLFW-based programs are presented
in the following sections.</p> in the following sections.</p>
<h3>4.1 Include the GLFW header file</h3> <h3>4.1 Include the GLFW header file</h3>
<p>In the files of your program where you use OpenGL or GLFW, you should <p>In the files of your program where you use OpenGL or GLFW, you should
include the <code>GL/glfw.h</code> header file, i.e.:</p> include the <code>GL/glfw3.h</code> header file, i.e.:</p>
<blockquote><code>#include &lt;GL/glfw.h&gt;</code></blockquote> <blockquote><code>#include &lt;GL/glfw3.h&gt;</code></blockquote>
<p>This defines all the constants, types and function prototypes of the GLFW <p>This defines all the constants, types and function prototypes of the GLFW
API. It also includes the <code>gl.h</code> and </code>GL/glu.h</code> header API. It also includes the <code>gl.h</code> and </code>GL/glu.h</code> header
@ -95,7 +100,7 @@ it. This way, the namespace won't be cluttered by the entire Windows API.</p>
<li>Do <em>not</em> include <code>windows.h</code> unless you actually need <li>Do <em>not</em> include <code>windows.h</code> unless you actually need
direct access to the Windows API</li> direct access to the Windows API</li>
<li>If you <em>do</em> need to include <code>windows.h</code>, do it <li>If you <em>do</em> need to include <code>windows.h</code>, do it
<em>before</em> including <code>GL/glfw.h</code> and the GLFW header will <em>before</em> including <code>GL/glfw3.h</code> and the GLFW header will
detect this.</p> detect this.</p>
</ul> </ul>
@ -106,9 +111,9 @@ disable any <code>gl.h</code> that the GLFW header includes and GLEW will work
as expected.</p> as expected.</p>
<h3>4.2 Link with the right libraries</h3> <h3>4.2 Link with the right libraries</h3>
<h4>4.2.1 Windows static library</h4> <h4>4.2.1 Windows static library</h4>
<p>If you link with the static version of GLFW, it is also necessary to <p>If you link with the static version of GLFW, it is also necessary to
@ -219,7 +224,6 @@ by compile.sh at compile time.</p>
<code>-lGLU</code> to your link flags.</p> <code>-lGLU</code> to your link flags.</p>
<h4>4.2.5 Mac OS X static library</h4> <h4>4.2.5 Mac OS X static library</h4>
<p>When compiling and linking a program under Mac OS X that uses GLFW, you <p>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 <em>not</em> work with the Mac OS X native use with the X Window System, and will <em>not</em> work with the Mac OS X native
version of GLFW.</p> version of GLFW.</p>
<a name="changelog">
<a name="changelog"></a>
<h2>5. Version history</h2> <h2>5. Version history</h2>
<h3>v3.0</h3> <h3>v3.0</h3>
<ul> <ul>
<li>Added <code>GLFWwindow</code> window handle type and updated window-related functions and callbacks to take a window handle</li> <li>Added <code>GLFWwindow</code> window handle type and updated window-related functions and callbacks to take a window handle</li>
@ -271,8 +277,8 @@ version of GLFW.</p>
<li>Added <code>glfwGetWindowPos</code> function for querying the position of the specified window</li> <li>Added <code>glfwGetWindowPos</code> function for querying the position of the specified window</li>
<li>Added <code>glfwSetWindowFocusCallback</code> function and <code>GLFWwindowfocusfun</code> type for receiving window focus events</li> <li>Added <code>glfwSetWindowFocusCallback</code> function and <code>GLFWwindowfocusfun</code> type for receiving window focus events</li>
<li>Added <code>glfwSetWindowIconifyCallback</code> function and <code>GLFWwindowiconifyfun</code> type for receiving window iconification events</li> <li>Added <code>glfwSetWindowIconifyCallback</code> function and <code>GLFWwindowiconifyfun</code> type for receiving window iconification events</li>
<li>Added <code>glfwGetClipboardString</code> and <code>glfwSetClipboardString</code> functions for interacting with the system clipboard</li>
<li>Added <code>glfwGetCurrentContext</code> function for retrieving the window whose OpenGL context is current</li> <li>Added <code>glfwGetCurrentContext</code> function for retrieving the window whose OpenGL context is current</li>
<li>Added <code>GLFWallocator</code> type and <code>glfwInit</code> parameter for pluggable memory allocator</li>
<li>Added <code>glfwCopyContext</code> function for copying OpenGL state categories between contexts</li> <li>Added <code>glfwCopyContext</code> function for copying OpenGL state categories between contexts</li>
<li>Added <code>GLFW_OPENGL_ES2_PROFILE</code> profile for creating OpenGL ES 2.0 contexts using the <code>GLX_EXT_create_context_es2_profile</code> and <code>WGL_EXT_create_context_es2_profile</code> extensions</li> <li>Added <code>GLFW_OPENGL_ES2_PROFILE</code> profile for creating OpenGL ES 2.0 contexts using the <code>GLX_EXT_create_context_es2_profile</code> and <code>WGL_EXT_create_context_es2_profile</code> extensions</li>
<li>Added <code>GLFW_OPENGL_ROBUSTNESS</code> window hint and associated strategy tokens for <code>GL_ARB_robustness</code> support</li> <li>Added <code>GLFW_OPENGL_ROBUSTNESS</code> window hint and associated strategy tokens for <code>GL_ARB_robustness</code> support</li>
@ -280,20 +286,25 @@ version of GLFW.</p>
<li>Added <code>GLFW_INCLUDE_GL3</code> macro for telling the GLFW header to include <code>gl3.h</code> header instead of <code>gl.h</code></li> <li>Added <code>GLFW_INCLUDE_GL3</code> macro for telling the GLFW header to include <code>gl3.h</code> header instead of <code>gl.h</code></li>
<li>Added <code>windows</code> simple multi-window test program</li> <li>Added <code>windows</code> simple multi-window test program</li>
<li>Added <code>sharing</code> simple OpenGL object sharing test program</li> <li>Added <code>sharing</code> simple OpenGL object sharing test program</li>
<li>Added <code>dynamic</code> simple dynamic linking test program</li> <li>Added <code>modes</code> video mode enumeration and setting test program</li>
<li>Added a parameter to <code>glfwOpenWindow</code> for specifying a context the new window's context will share objects with</li> <li>Added a parameter to <code>glfwOpenWindow</code> for specifying a context the new window's context will share objects with</li>
<li>Added initial window title parameter to <code>glfwOpenWindow</code></li> <li>Added initial window title parameter to <code>glfwOpenWindow</code></li>
<li>Added <code>glfwSetGamma</code>, <code>glfwSetGammaRamp</code> and <code>glfwGetGammaRamp</code> functions and <code>GLFWgammaramp</code> type for monitor gamma ramp control</li> <li>Added <code>glfwSetGamma</code>, <code>glfwSetGammaRamp</code> and <code>glfwGetGammaRamp</code> functions and <code>GLFWgammaramp</code> type for monitor gamma ramp control</li>
<li>Changed buffer bit depth parameters of <code>glfwOpenWindow</code> to window hints</li> <li>Changed buffer bit depth parameters of <code>glfwOpenWindow</code> to window hints</li>
<li>Changed <code>glfwOpenWindow</code> and <code>glfwSetWindowTitle</code> to use UTF-8 encoded strings</li> <li>Changed <code>glfwOpenWindow</code> and <code>glfwSetWindowTitle</code> to use UTF-8 encoded strings</li>
<li>Changed <code>glfwGetProcAddress</code> to return a (generic) function pointer</li>
<li>Renamed <code>glfw.h</code> to <code>glfw3.h</code> to avoid conflicts with 2.x series</li> <li>Renamed <code>glfw.h</code> to <code>glfw3.h</code> to avoid conflicts with 2.x series</li>
<li>Renamed <code>GLFW_WINDOW</code> token to <code>GLFW_WINDOWED</code></li> <li>Renamed <code>GLFW_WINDOW</code> token to <code>GLFW_WINDOWED</code></li>
<li>Renamed <code>GLFW_WINDOW_NO_RESIZE</code> to <code>GLFW_WINDOW_RESIZABLE</code></li> <li>Renamed <code>GLFW_WINDOW_NO_RESIZE</code> to <code>GLFW_WINDOW_RESIZABLE</code></li>
<li>Renamed <code>GLFW_BUILD_DLL</code> to <code>_GLFW_BUILD_DLL</code></li>
<li>Renamed <code>version</code> test to <code>glfwinfo</code></li> <li>Renamed <code>version</code> test to <code>glfwinfo</code></li>
<li>Renamed <code>GLFW_NO_GLU</code> to <code>GLFW_INCLUDE_GLU</code> and made it disabled by default</li>
<li>Renamed mouse position functions to cursor position equivalents</li>
<li>Replaced ad hoc build system with CMake</li> <li>Replaced ad hoc build system with CMake</li>
<li>Replaced layout-dependent key codes with single, platform-independent set based on US layout</li> <li>Replaced layout-dependent key codes with single, platform-independent set based on US layout</li>
<li>Replaced mouse wheel interface with two-dimensional scrolling interface</li> <li>Replaced mouse wheel interface with two-dimensional, floating point scrolling interface</li>
<li>Replaced <code>glfwEnable</code> and <code>glfwDisable</code> with <code>glfwGetInputMode</code> and <code>glfwSetInputMode</code></li> <li>Replaced <code>glfwEnable</code> and <code>glfwDisable</code> with <code>glfwGetInputMode</code> and <code>glfwSetInputMode</code></li>
<li>Replaced <code>joystick</code> test with graphical version</li>
<li>Made Unicode character input unaffected by <code>GLFW_KEY_REPEAT</code></li> <li>Made Unicode character input unaffected by <code>GLFW_KEY_REPEAT</code></li>
<li>Removed event auto-polling and the <code>GLFW_AUTO_POLL_EVENTS</code> window enable</li> <li>Removed event auto-polling and the <code>GLFW_AUTO_POLL_EVENTS</code> window enable</li>
<li>Removed the Win32 port .def files</li> <li>Removed the Win32 port .def files</li>
@ -309,10 +320,21 @@ version of GLFW.</p>
<li>Bugfix: The default OpenGL version in the <code>glfwinfo</code> test was set to 1.1</li> <li>Bugfix: The default OpenGL version in the <code>glfwinfo</code> test was set to 1.1</li>
<li>Bugfix: The OpenGL profile and forward-compatibility window parameters were not saved after context creation</li> <li>Bugfix: The OpenGL profile and forward-compatibility window parameters were not saved after context creation</li>
<li>Bugfix: The FSAA test did not check for the availability of <code>GL_ARB_multisample</code></li> <li>Bugfix: The FSAA test did not check for the availability of <code>GL_ARB_multisample</code></li>
<li>Bugfix: Cursor centering upon leaving captured cursor mode was reported before the mode was changed to non-captured</li>
<li>[Cocoa] Added support for OpenGL 3.2 core profile in 10.7 Lion and above</li> <li>[Cocoa] Added support for OpenGL 3.2 core profile in 10.7 Lion and above</li>
<li>[Cocoa] Added support for joysticks</li> <li>[Cocoa] Added support for joysticks</li>
<li>[Cocoa] Postponed menu creation to first window creation</li>
<li>[Cocoa] Replaced <code>NSDate</code> time source with <code>mach_absolute_time</code></li>
<li>[Cocoa] Replaced all deprecated CoreGraphics calls with non-deprecated counterparts</li>
<li>[Cocoa] Bugfix: The <code>NSOpenGLPFAFullScreen</code> pixel format attribute caused creation to fail on some machines</li>
<li>[Cocoa] Bugfix: <code>glfwOpenWindow</code> did not properly enforce the forward-compatible and context profile hints</li>
<li>[Cocoa] Bugfix: The loop condition for saving video modes used the wrong index variable</li> <li>[Cocoa] Bugfix: The loop condition for saving video modes used the wrong index variable</li>
<li>[Cocoa] Bugfix: The OpenGL framework was not retrieved, making glfwGetProcAddress crash</li> <li>[Cocoa] Bugfix: The OpenGL framework was not retrieved, making glfwGetProcAddress crash</li>
<li>[Cocoa] Bugfix: <code>glfwInit</code> changed the current directory for unbundled executables</li>
<li>[Cocoa] Bugfix: The <code>GLFW_WINDOW_NO_RESIZE</code> window parameter was always zero</li>
<li>[Cocoa] Bugfix: The cursor position incorrectly rounded during conversion</li>
<li>[Cocoa] Bugfix: Cursor positioning led to nonsensical results for fullscreen windows</li>
<li>[Cocoa] Bugfix: The GLFW window was flagged as restorable</li>
<li>[X11] Added support for the <code>GLX_EXT_swap_control</code> extension as an alternative to <code>GLX_SGI_swap_control</code></li> <li>[X11] Added support for the <code>GLX_EXT_swap_control</code> extension as an alternative to <code>GLX_SGI_swap_control</code></li>
<li>[X11] Added the POSIX <code>CLOCK_MONOTONIC</code> time source as the preferred method</li> <li>[X11] Added the POSIX <code>CLOCK_MONOTONIC</code> time source as the preferred method</li>
<li>[X11] Added dependency on libm, where present</li> <li>[X11] Added dependency on libm, where present</li>
@ -325,6 +347,9 @@ version of GLFW.</p>
<li>[Win32] Bugfix: Window activation and iconification did not work as expected</li> <li>[Win32] Bugfix: Window activation and iconification did not work as expected</li>
<li>[Win32] Bugfix: Software rasterizer pixel formats were not discarded by the WGL_ARB_pixel_format code path</li> <li>[Win32] Bugfix: Software rasterizer pixel formats were not discarded by the WGL_ARB_pixel_format code path</li>
<li>[Win32] Bugfix: The array for WGL context attributes was too small and could overflow</li> <li>[Win32] Bugfix: The array for WGL context attributes was too small and could overflow</li>
<li>[Win32] Bugfix: Alt+F4 hot key was not translated into <code>WM_CLOSE</code></li>
<li>[Win32] Bugfix: The <code>GLFW_WINDOW_NO_RESIZE</code> window parameter was always zero</li>
<li>[Win32] Bugfix: A test was missing for whether all available pixel formats had been disqualified</li>
</ul> </ul>
<h3>v2.7</h3> <h3>v2.7</h3>
@ -759,7 +784,7 @@ version of GLFW.</p>
</ul> </ul>
<a name="structure"> <a name="structure"></a>
<h2>6. Directory structure of the GLFW distribution</h2> <h2>6. Directory structure of the GLFW distribution</h2>
<p>Here is an overview of the directory structure of the GLFW distribution: <p>Here is an overview of the directory structure of the GLFW distribution:
@ -782,7 +807,7 @@ version of GLFW.</p>
</table> </table>
<a name="contact"> <a name="contact"></a>
<h2>7. Contacting the project</h2> <h2>7. Contacting the project</h2>
<p>The official website for GLFW is <a href="http://www.glfw.org/">glfw.org</a>. <p>The official website for GLFW is <a href="http://www.glfw.org/">glfw.org</a>.
@ -806,7 +831,7 @@ GLFW or porting it to your favorite platform, we have a
or you could join us on <code>#glfw</code>. or you could join us on <code>#glfw</code>.
<a name="credits"> <a name="credits"></a>
<h2>8. Acknowledgements</h2> <h2>8. Acknowledgements</h2>
<p>GLFW exists because people around the world donated their time and lent <p>GLFW exists because people around the world donated their time and lent
@ -814,12 +839,16 @@ their skills. Special thanks go out to:</p>
<ul> <ul>
<li>artblanc, for a patch replacing a deprecated Core Graphics call</li>
<li>Bobyshev Alexander and Martins Mozeiko, for the original proposal of <li>Bobyshev Alexander and Martins Mozeiko, for the original proposal of
an FSAA hint and their work on the Win32 implementation of FSAA</li> an FSAA hint and their work on the Win32 implementation of FSAA</li>
<li>Keith Bauer, for his invaluable help with porting and maintaining GLFW on <li>Keith Bauer, for his invaluable help with porting and maintaining GLFW on
Mac OS X, and for his many ideas</li> Mac OS X, and for his many ideas</li>
<li>Lambert Clara, for a bug fix for the modes test</li>
<li>Jarrod Davis, for the Delphi port of GLFW</li> <li>Jarrod Davis, for the Delphi port of GLFW</li>
<li>Olivier Delannoy, for the initial implementation of FSAA support on <li>Olivier Delannoy, for the initial implementation of FSAA support on
@ -833,7 +862,10 @@ their skills. Special thanks go out to:</p>
adding logic for the <code>GLFW_ICON</code> resource</li> adding logic for the <code>GLFW_ICON</code> resource</li>
<li>Ralph Eastwood, for the initial design and implementation of the gamma <li>Ralph Eastwood, for the initial design and implementation of the gamma
correction API</li> correction and clipboard APIs</li>
<li>GeO4d, for the implementation of cursor enter/leave notifications on
Win32.</li>
<li>Gerald Franz, who made GLFW compile under IRIX, and supplied patches <li>Gerald Franz, who made GLFW compile under IRIX, and supplied patches
for the X11 keyboard translation routine</li> for the X11 keyboard translation routine</li>
@ -864,9 +896,14 @@ their skills. Special thanks go out to:</p>
<li>Glenn Lewis, for helping out with support for the D programming <li>Glenn Lewis, for helping out with support for the D programming
language</li> language</li>
<li>Shane Liesegang, for providing a bug fix relating to Cocoa window
restoration</li>
<li>Tristam MacDonald, for his bug reports and feedback on the Cocoa port</li> <li>Tristam MacDonald, for his bug reports and feedback on the Cocoa port</li>
<li>Hans 'Hanmac' Mackowiak, for adding UTF-8 window title support on X11</li> <li>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</li>
<li>David Medlock, for doing the initial Lua port</li> <li>David Medlock, for doing the initial Lua port</li>
@ -889,7 +926,7 @@ their skills. Special thanks go out to:</p>
<li>Steve Sexton, for reporting an input bug in the Carbon port</li> <li>Steve Sexton, for reporting an input bug in the Carbon port</li>
<li>Dmitri Shuralyov, for support, bug reports and testing</li> <li>Dmitri Shuralyov, for support, bug reports, bug fixes and testing</li>
<li>Daniel Skorupski, for reporting a bug in the Win32 DEF file</li> <li>Daniel Skorupski, for reporting a bug in the Win32 DEF file</li>

View File

@ -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 include_directories(${GLFW_SOURCE_DIR}/src
${GLFW_BINARY_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) joystick.c monitor.c opengl.c time.c window.c)
if(_GLFW_COCOA_NSGL) if (_GLFW_COCOA_NSGL)
set(libglfw_SOURCES ${common_SOURCES} cocoa_fullscreen.m cocoa_gamma.m set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h)
cocoa_init.m cocoa_input.m cocoa_joystick.m set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m
cocoa_opengl.m cocoa_time.m cocoa_window.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 # For some reason, CMake doesn't know about .m
set_source_files_properties(${libglfw_SOURCES} PROPERTIES LANGUAGE C) set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
elseif(_GLFW_WIN32_WGL) elseif (_GLFW_WIN32_WGL)
set(libglfw_SOURCES ${common_SOURCES} win32_fullscreen.c win32_gamma.c set(glfw_HEADERS ${common_HEADERS} win32_platform.h)
win32_init.c win32_input.c win32_joystick.c set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_dllmain.c
win32_opengl.c win32_time.c win32_window.c win32_fullscreen.c win32_gamma.c win32_init.c win32_input.c
win32_dllmain.c win32_monitor.c) win32_joystick.c win32_monitor.c win32_opengl.c
elseif(_GLFW_X11_GLX) win32_time.c win32_window.c)
set(libglfw_SOURCES ${common_SOURCES} x11_fullscreen.c x11_gamma.c elseif (_GLFW_X11_GLX)
x11_init.c x11_input.c x11_joystick.c set(glfw_HEADERS ${common_HEADERS} x11_platform.h)
x11_keysym2unicode.c x11_monitor.c x11_opengl.c set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c
x11_time.c x11_window.c) x11_gamma.c x11_init.c x11_input.c x11_joystick.c
else() x11_keysym2unicode.c x11_monitor.c x11_opengl.c x11_time.c
message(FATAL_ERROR "No supported platform was selected") x11_window.c)
endif(_GLFW_COCOA_NSGL) endif()
add_library(libglfwStatic STATIC ${libglfw_SOURCES}) add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
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)
if(WIN32) if (BUILD_SHARED_LIBS)
# 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(APPLE) if (_GLFW_WIN32_WGL)
# Append -fno-common to the compile flags to work around a bug in the Apple GCC # The GLFW DLL needs a special compile-time macro and import library name
get_target_property(CFLAGS libglfwShared COMPILE_FLAGS) set_target_properties(glfw PROPERTIES
if(NOT CFLAGS) PREFIX ""
set(CFLAGS "") IMPORT_PREFIX ""
endif(NOT CFLAGS) IMPORT_SUFFIX "dll.lib")
set_target_properties(libglfwShared PROPERTIES COMPILE_FLAGS "${CFLAGS} -fno-common") elseif (_GLFW_COCOA_NSGL)
endif(APPLE) # 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)

View File

@ -1,10 +1,10 @@
//======================================================================== //========================================================================
// GLFW - An OpenGL library // GLFW - An OpenGL library
// Platform: Cocoa/NSOpenGL // Platform: Any
// API Version: 3.0 // API version: 3.0
// WWW: http://www.glfw.org/ // WWW: http://www.glfw.org/
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -29,28 +29,46 @@
#include "internal.h" #include "internal.h"
#include <math.h>
#include <string.h>
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// 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] - _GLFWwindow* window = (_GLFWwindow*) handle;
_glfwLibrary.NS.timer.t0;
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 = _GLFWwindow* window = (_GLFWwindow*) handle;
[NSDate timeIntervalSinceReferenceDate] - time;
if (!_glfwInitialized)
{
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
return NULL;
}
return _glfwPlatformGetClipboardString(window);
} }

82
src/cocoa_clipboard.m Normal file
View File

@ -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 <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <limits.h>
#include <string.h>
//////////////////////////////////////////////////////////////////////////
////// 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;
}

View File

@ -29,47 +29,166 @@
#include "internal.h" #include "internal.h"
#include <stdlib.h>
#include <limits.h>
//======================================================================== //========================================================================
// Check whether the display mode should be included in enumeration // 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 uint32_t flags = CGDisplayModeGetIOFlags(mode);
// LCD computer monitor as an output device you might not want these if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))
// checks. You might also want to reject modes which are interlaced, return GL_FALSE;
// 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 if (flags & kDisplayModeInterlacedFlag)
// wish to patch this... return GL_FALSE;
return [[mode objectForKey:(id)kCGDisplayBitsPerPixel] intValue] >= 15 &&
[mode objectForKey:(id)kCGDisplayModeIsSafeForHardware] != nil && if (flags & kDisplayModeTelevisionFlag)
[mode objectForKey:(id)kCGDisplayModeIsStretched] == nil; 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 // 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; GLFWvidmode result;
result.width = width; result.width = CGDisplayModeGetWidth(mode);
result.height = height; result.height = CGDisplayModeGetHeight(mode);
result.redBits = bps;
result.greenBits = bps; CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
result.blueBits = bps;
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; 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 ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -80,19 +199,26 @@ static GLFWvidmode vidmodeFromCGDisplayMode(NSDictionary* mode)
int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
{ {
NSArray* modes = (NSArray*) CGDisplayAvailableModes(CGMainDisplayID()); CGDisplayModeRef mode;
unsigned int i, j = 0, n = [modes count]; 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)) if (modeIsGood(mode))
list[j++] = vidmodeFromCGDisplayMode(mode); list[stored++] = vidmodeFromCGDisplayMode(mode);
} }
return j; CFRelease(modes);
return stored;
} }
//======================================================================== //========================================================================
// Get the desktop video mode // Get the desktop video mode
//======================================================================== //========================================================================

View File

@ -32,6 +32,8 @@
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#include <ApplicationServices/ApplicationServices.h>
//************************************************************************ //************************************************************************
//**** GLFW internal functions **** //**** GLFW internal functions ****

View File

@ -27,162 +27,45 @@
// //
//======================================================================== //========================================================================
// Needed for _NSGetProgname
#include <crt_externs.h>
#include "internal.h" #include "internal.h"
#include <sys/param.h> // For MAXPATHLEN
//======================================================================== //========================================================================
// GLFW application class // Change to our application bundle's resources directory, if present
//======================================================================== //========================================================================
@interface GLFWApplication : NSApplication static void changeToResourcesDirectory(void)
@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)) char resourcesPath[MAXPATHLEN];
[[self keyWindow] sendEvent:event];
else
[super sendEvent:event];
}
@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 CFStringRef last = CFURLCopyLastPathComponent(resourcesURL);
// to get the application menu working properly. Need to be careful in if (CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo)
// 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++)
{ {
id name = [infoDictionary objectForKey:GLFWNameKeys[i]]; CFRelease(last);
if (name && CFRelease(resourcesURL);
[name isKindOfClass:[NSString class]] && return;
![@"" isEqualToString:name])
{
return name;
}
} }
// If we get here, we're unbundled CFRelease(last);
if (!_glfwLibrary.NS.unbundled)
if (!CFURLGetFileSystemRepresentation(resourcesURL,
true,
(UInt8*) resourcesPath,
MAXPATHLEN))
{ {
// Could do this only if we discover we're unbundled, but it should CFRelease(resourcesURL);
// do no harm... return;
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;
} }
char** progname = _NSGetProgname(); CFRelease(resourcesURL);
if (progname && *progname)
{
// TODO: UTF-8?
return [NSString stringWithUTF8String:*progname];
}
// Really shouldn't get here chdir(resourcesPath);
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];
} }
@ -198,43 +81,39 @@ int _glfwPlatformInit(void)
{ {
_glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init]; _glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init];
// Implicitly create shared NSApplication instance _glfwLibrary.NSGL.framework =
[GLFWApplication sharedApplication];
_glfwLibrary.NS.OpenGLFramework =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (_glfwLibrary.NS.OpenGLFramework == NULL) if (_glfwLibrary.NSGL.framework == NULL)
{ {
_glfwSetError(GLFW_PLATFORM_ERROR, _glfwSetError(GLFW_PLATFORM_ERROR,
"glfwInit: Failed to locate OpenGL framework"); "glfwInit: Failed to locate OpenGL framework");
return GL_FALSE; return GL_FALSE;
} }
NSString* resourcePath = [[NSBundle mainBundle] resourcePath]; changeToResourcesDirectory();
if (access([resourcePath cStringUsingEncoding:NSUTF8StringEncoding], R_OK) == 0) _glfwLibrary.NS.desktopMode = CGDisplayCopyDisplayMode(CGMainDisplayID());
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());
// Save the original gamma ramp // Save the original gamma ramp
_glfwLibrary.originalRampSize = CGDisplayGammaTableCapacity(CGMainDisplayID()); _glfwLibrary.originalRampSize = CGDisplayGammaTableCapacity(CGMainDisplayID());
_glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp); _glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp);
_glfwLibrary.currentRamp = _glfwLibrary.originalRamp; _glfwLibrary.currentRamp = _glfwLibrary.originalRamp;
_glfwInitTimer();
_glfwInitJoysticks(); _glfwInitJoysticks();
_glfwLibrary.NS.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
if (!_glfwLibrary.NS.eventSource)
return GL_FALSE;
CGEventSourceSetLocalEventsSuppressionInterval(_glfwLibrary.NS.eventSource,
0.0);
return GL_TRUE; return GL_TRUE;
} }
//======================================================================== //========================================================================
// Close window, if open, and shut down GLFW // Close window, if open, and shut down GLFW
//======================================================================== //========================================================================
@ -243,8 +122,17 @@ int _glfwPlatformTerminate(void)
{ {
// TODO: Probably other cleanup // TODO: Probably other cleanup
if (_glfwLibrary.NS.eventSource)
{
CFRelease(_glfwLibrary.NS.eventSource);
_glfwLibrary.NS.eventSource = NULL;
}
// Restore the original gamma ramp // Restore the original gamma ramp
_glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp); if (_glfwLibrary.rampChanged)
_glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
CGDisplayModeRelease(_glfwLibrary.NS.desktopMode);
[NSApp setDelegate:nil]; [NSApp setDelegate:nil];
[_glfwLibrary.NS.delegate release]; [_glfwLibrary.NS.delegate release];
@ -265,7 +153,11 @@ int _glfwPlatformTerminate(void)
const char* _glfwPlatformGetVersionString(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; return version;
} }

View File

@ -152,7 +152,7 @@ static void addJoystickElement(_glfwJoystick* joystick, CFTypeRef refElement)
long number; long number;
CFTypeRef refType; CFTypeRef refType;
_glfwJoystickElement* element = (_glfwJoystickElement*) _glfwMalloc(sizeof(_glfwJoystickElement)); _glfwJoystickElement* element = (_glfwJoystickElement*) malloc(sizeof(_glfwJoystickElement));
CFArrayAppendValue(elementsArray, element); CFArrayAppendValue(elementsArray, element);
@ -242,7 +242,7 @@ static void removeJoystick(_glfwJoystick* joystick)
{ {
_glfwJoystickElement* axes = _glfwJoystickElement* axes =
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, i); (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, i);
_glfwFree(axes); free(axes);
} }
CFArrayRemoveAllValues(joystick->axes); CFArrayRemoveAllValues(joystick->axes);
joystick->numAxes = 0; joystick->numAxes = 0;
@ -251,7 +251,7 @@ static void removeJoystick(_glfwJoystick* joystick)
{ {
_glfwJoystickElement* button = _glfwJoystickElement* button =
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->buttons, i); (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->buttons, i);
_glfwFree(button); free(button);
} }
CFArrayRemoveAllValues(joystick->buttons); CFArrayRemoveAllValues(joystick->buttons);
joystick->numButtons = 0; joystick->numButtons = 0;
@ -260,7 +260,7 @@ static void removeJoystick(_glfwJoystick* joystick)
{ {
_glfwJoystickElement* hat = _glfwJoystickElement* hat =
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->hats, i); (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->hats, i);
_glfwFree(hat); free(hat);
} }
CFArrayRemoveAllValues(joystick->hats); CFArrayRemoveAllValues(joystick->hats);
joystick->hats = 0; joystick->hats = 0;
@ -311,6 +311,13 @@ static void pollJoystickEvents(void)
(_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, j); (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, j);
axes->value = getElementValue(joystick, axes); 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); result = IOMasterPort(bootstrap_port, &masterPort);
hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey);
if (kIOReturnSuccess != result || !hidMatchDictionary) if (kIOReturnSuccess != result || !hidMatchDictionary)
{
if (hidMatchDictionary)
CFRelease(hidMatchDictionary);
return; return;
}
result = IOServiceGetMatchingServices(masterPort, result = IOServiceGetMatchingServices(masterPort,
hidMatchDictionary, hidMatchDictionary,
@ -370,19 +382,27 @@ void _glfwInitJoysticks(void)
/* Check device type */ /* Check device type */
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey));
if (refCF) if (refCF)
{
CFNumberGetValue(refCF, kCFNumberLongType, &usagePage); CFNumberGetValue(refCF, kCFNumberLongType, &usagePage);
if (usagePage != kHIDPage_GenericDesktop)
{
/* We are not interested in this device */
continue;
}
}
refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsageKey));
if (refCF) if (refCF)
{
CFNumberGetValue(refCF, kCFNumberLongType, &usage); CFNumberGetValue(refCF, kCFNumberLongType, &usage);
if ((usagePage != kHIDPage_GenericDesktop) || if ((usage != kHIDUsage_GD_Joystick &&
(usage != kHIDUsage_GD_Joystick && usage != kHIDUsage_GD_GamePad &&
usage != kHIDUsage_GD_GamePad && usage != kHIDUsage_GD_MultiAxisController))
usage != kHIDUsage_GD_MultiAxisController)) {
{ /* We are not interested in this device */
/* We don't interested in this device */ continue;
continue; }
} }
_glfwJoystick* joystick = &_glfwJoysticks[deviceCounter]; _glfwJoystick* joystick = &_glfwJoysticks[deviceCounter];
@ -489,7 +509,7 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
return (int) CFArrayGetCount(_glfwJoysticks[joy].axes); return (int) CFArrayGetCount(_glfwJoysticks[joy].axes);
case GLFW_BUTTONS: case GLFW_BUTTONS:
return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons); return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons) + ((int) CFArrayGetCount(_glfwJoysticks[joy].hats)) * 4;
default: default:
break; break;
@ -552,7 +572,7 @@ int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes)
int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons, int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
int numbuttons) int numbuttons)
{ {
int i; int i, j, button;
if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST) if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST)
return 0; return 0;
@ -565,18 +585,31 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
return 0; return 0;
} }
numbuttons = numbuttons < joystick.numButtons ? numbuttons : joystick.numButtons;
// Update joystick state // Update joystick state
pollJoystickEvents(); pollJoystickEvents();
for (i = 0; i < numbuttons; i++) for (button = 0; button < numbuttons && button < joystick.numButtons; button++)
{ {
_glfwJoystickElement* button = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.buttons, i); _glfwJoystickElement* element = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.buttons, button);
buttons[i] = button->value ? GLFW_PRESS : GLFW_RELEASE; 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;
} }

View File

@ -59,6 +59,7 @@ void _glfwPlatformSwapBuffers(void)
[window->NSGL.context flushBuffer]; [window->NSGL.context flushBuffer];
} }
//======================================================================== //========================================================================
// Set double buffering swap interval // Set double buffering swap interval
//======================================================================== //========================================================================
@ -71,6 +72,7 @@ void _glfwPlatformSwapInterval(int interval)
[window->NSGL.context setValues:&sync forParameter:NSOpenGLCPSwapInterval]; [window->NSGL.context setValues:&sync forParameter:NSOpenGLCPSwapInterval];
} }
//======================================================================== //========================================================================
// Check if an OpenGL extension is available at runtime // Check if an OpenGL extension is available at runtime
//======================================================================== //========================================================================
@ -81,24 +83,26 @@ int _glfwPlatformExtensionSupported(const char* extension)
return GL_FALSE; return GL_FALSE;
} }
//======================================================================== //========================================================================
// Get the function pointer to an OpenGL function // Get the function pointer to an OpenGL function
//======================================================================== //========================================================================
void* _glfwPlatformGetProcAddress(const char* procname) GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
{ {
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,
procname, procname,
kCFStringEncodingASCII); kCFStringEncodingASCII);
void* symbol = CFBundleGetFunctionPointerForName(_glfwLibrary.NS.OpenGLFramework, GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfwLibrary.NSGL.framework,
symbolName); symbolName);
CFRelease(symbolName); CFRelease(symbolName);
return symbol; return symbol;
} }
//======================================================================== //========================================================================
// Copies the specified OpenGL state categories from src to dst // Copies the specified OpenGL state categories from src to dst
//======================================================================== //========================================================================

View File

@ -37,13 +37,15 @@
#if defined(__OBJC__) #if defined(__OBJC__)
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#else #else
#include <ApplicationServices/ApplicationServices.h>
typedef void* id; typedef void* id;
#endif #endif
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS NS #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS NS
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryNS NS
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL NSGL #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 typedef struct _GLFWwindowNS
{ {
id window; id object;
id delegate; id delegate;
id view;
unsigned int modifierFlags; unsigned int modifierFlags;
double fracScrollX;
double fracScrollY;
} _GLFWwindowNS; } _GLFWwindowNS;
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Platform-specific library global data // Platform-specific library global data for Cocoa
//------------------------------------------------------------------------ //------------------------------------------------------------------------
typedef struct _GLFWlibraryNS typedef struct _GLFWlibraryNS
{ {
struct { struct {
double t0; double base;
double resolution;
} timer; } timer;
// dlopen handle for dynamically loading OpenGL extension entry points CGDisplayModeRef desktopMode;
void* OpenGLFramework; CGEventSourceRef eventSource;
GLboolean unbundled; id delegate;
id desktopMode; id autoreleasePool;
id delegate;
id autoreleasePool; char* clipboardString;
} _GLFWlibraryNS; } _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 // Prototypes for platform specific internal functions
//======================================================================== //========================================================================
// Time
void _glfwInitTimer(void);
// Joystick input // Joystick input
void _glfwInitJoysticks(void); void _glfwInitJoysticks(void);
void _glfwTerminateJoysticks(void); void _glfwTerminateJoysticks(void);
// Fullscreen
GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate);
void _glfwRestoreVideoMode(void);
#endif // _platform_h_ #endif // _platform_h_

87
src/cocoa_time.c Normal file
View File

@ -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 <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <mach/mach_time.h>
//========================================================================
// 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);
}

View File

@ -29,6 +29,9 @@
#include "internal.h" #include "internal.h"
// Needed for _NSGetProgname
#include <crt_externs.h>
//======================================================================== //========================================================================
// Delegate for window related notifications // Delegate for window related notifications
@ -66,7 +69,7 @@
[window->NSGL.context update]; [window->NSGL.context update];
NSRect contentRect = 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); _glfwInputWindowSize(window, contentRect.size.width, contentRect.size.height);
} }
@ -76,7 +79,7 @@
[window->NSGL.context update]; [window->NSGL.context update];
NSRect contentRect = NSRect contentRect =
[window->NS.window contentRectForFrameRect:[window->NS.window frame]]; [window->NS.object contentRectForFrameRect:[window->NS.object frame]];
CGPoint mainScreenOrigin = CGDisplayBounds(CGMainDisplayID()).origin; CGPoint mainScreenOrigin = CGDisplayBounds(CGMainDisplayID()).origin;
double mainScreenHeight = CGDisplayBounds(CGMainDisplayID()).size.height; double mainScreenHeight = CGDisplayBounds(CGMainDisplayID()).size.height;
@ -109,6 +112,7 @@
@end @end
//======================================================================== //========================================================================
// Delegate for application related notifications // Delegate for application related notifications
//======================================================================== //========================================================================
@ -130,142 +134,6 @@
@end @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 // 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) 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) if (macKeyCode >= 128)
return -1; return -1;
// This treats keycodes as *positional*; that is, we'll return 'a' // This treats keycodes as *positional*; that is, we'll return 'a'
// for the key left of 's', even on an AZERTY keyboard. The charInput // for the key left of 's', even on an AZERTY keyboard. The charInput
// function should still get 'q' though. // function should still get 'q' though.
return MAC_TO_GLFW_KEYCODE_MAPPING[macKeyCode]; return table[macKeyCode];
} }
//======================================================================== //========================================================================
// Content view class for the GLFW window // Content view class for the GLFW window
//======================================================================== //========================================================================
@ -289,6 +292,7 @@ static int convertMacKeyCode(unsigned int macKeyCode)
@interface GLFWContentView : NSView @interface GLFWContentView : NSView
{ {
_GLFWwindow* window; _GLFWwindow* window;
NSTrackingArea* trackingArea;
} }
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow; - (id)initWithGlfwWindow:(_GLFWwindow *)initWindow;
@ -301,11 +305,22 @@ static int convertMacKeyCode(unsigned int macKeyCode)
{ {
self = [super init]; self = [super init];
if (self != nil) if (self != nil)
{
window = initWindow; window = initWindow;
trackingArea = nil;
[self updateTrackingAreas];
}
return self; return self;
} }
-(void)dealloc
{
[trackingArea release];
[super dealloc];
}
- (BOOL)isOpaque - (BOOL)isOpaque
{ {
return YES; return YES;
@ -342,12 +357,13 @@ static int convertMacKeyCode(unsigned int macKeyCode)
_glfwInputCursorMotion(window, [event deltaX], [event deltaY]); _glfwInputCursorMotion(window, [event deltaX], [event deltaY]);
else else
{ {
NSPoint p = [event locationInWindow]; const NSPoint p = [event locationInWindow];
// Cocoa coordinate system has origin at lower left // 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); _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 - (void)keyDown:(NSEvent *)event
{ {
NSUInteger i, length; NSUInteger i, length;
NSString* characters; 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) if ([event modifierFlags] & NSCommandKeyMask)
{ {
@ -409,7 +455,7 @@ static int convertMacKeyCode(unsigned int macKeyCode)
- (void)flagsChanged:(NSEvent *)event - (void)flagsChanged:(NSEvent *)event
{ {
int mode; int mode, key;
unsigned int newModifierFlags = unsigned int newModifierFlags =
[event modifierFlags] | NSDeviceIndependentModifierFlagsMask; [event modifierFlags] | NSDeviceIndependentModifierFlagsMask;
@ -419,30 +465,193 @@ static int convertMacKeyCode(unsigned int macKeyCode)
mode = GLFW_RELEASE; mode = GLFW_RELEASE;
window->NS.modifierFlags = newModifierFlags; 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 - (void)keyUp:(NSEvent *)event
{ {
int code = convertMacKeyCode([event keyCode]); int key = convertMacKeyCode([event keyCode]);
if (code != -1) if (key != -1)
_glfwInputKey(window, code, GLFW_RELEASE); _glfwInputKey(window, key, GLFW_RELEASE);
} }
- (void)scrollWheel:(NSEvent *)event - (void)scrollWheel:(NSEvent *)event
{ {
double deltaX = window->NS.fracScrollX + [event deltaX]; double deltaX = [event deltaX];
double deltaY = window->NS.fracScrollY + [event deltaY]; double deltaY = [event deltaY];
if ((int) deltaX || (int) deltaY) if (fabs(deltaX) > 0.0 || fabs(deltaY) > 0.0)
_glfwInputScroll(window, (int) deltaX, (int) deltaY); _glfwInputScroll(window, deltaX, deltaY);
window->NS.fracScrollX = (int) (deltaX - floor(deltaX));
window->NS.fracScrollY = (int) (deltaY - floor(deltaY));
} }
@end @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 // Create the Cocoa window
//======================================================================== //========================================================================
@ -463,29 +672,34 @@ static GLboolean createWindow(_GLFWwindow* window,
else else
styleMask = NSBorderlessWindowMask; styleMask = NSBorderlessWindowMask;
window->NS.window = [[NSWindow alloc] window->NS.object = [[NSWindow alloc]
initWithContentRect:NSMakeRect(0, 0, window->width, window->height) initWithContentRect:NSMakeRect(0, 0, window->width, window->height)
styleMask:styleMask styleMask:styleMask
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:NO]; defer:NO];
if (window->NS.window == nil) if (window->NS.object == nil)
{ {
_glfwSetError(GLFW_PLATFORM_ERROR, _glfwSetError(GLFW_PLATFORM_ERROR,
"Cocoa/NSOpenGL: Failed to create window"); "Cocoa/NSOpenGL: Failed to create window");
return GL_FALSE; return GL_FALSE;
} }
[window->NS.window setTitle:[NSString stringWithUTF8String:wndconfig->title]]; window->NS.view = [[GLFWContentView alloc] initWithGlfwWindow:window];
[window->NS.window setContentView:[[GLFWContentView alloc]
initWithGlfwWindow:window]]; [window->NS.object setTitle:[NSString stringWithUTF8String:wndconfig->title]];
[window->NS.window setDelegate:window->NS.delegate]; [window->NS.object setContentView:window->NS.view];
[window->NS.window setAcceptsMouseMovedEvents:YES]; [window->NS.object setDelegate:window->NS.delegate];
[window->NS.window center]; [window->NS.object setAcceptsMouseMovedEvents:YES];
[window->NS.object center];
if ([window->NS.object respondsToSelector:@selector(setRestorable)])
[window->NS.object setRestorable:NO];
return GL_TRUE; return GL_TRUE;
} }
//======================================================================== //========================================================================
// Create the OpenGL context // Create the OpenGL context
//======================================================================== //========================================================================
@ -514,14 +728,23 @@ static GLboolean createContext(_GLFWwindow* window,
return GL_FALSE; 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) if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE)
{ {
_glfwSetError(GLFW_VERSION_UNAVAILABLE, _glfwSetError(GLFW_VERSION_UNAVAILABLE,
"Cocoa/NSOpenGL: The targeted version of Mac OS X " "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; return GL_FALSE;
} }
} }
@ -549,13 +772,12 @@ static GLboolean createContext(_GLFWwindow* window,
#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } #define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); }
// Arbitrary array size here // Arbitrary array size here
NSOpenGLPixelFormatAttribute attributes[24]; NSOpenGLPixelFormatAttribute attributes[40];
ADD_ATTR(NSOpenGLPFADoubleBuffer); ADD_ATTR(NSOpenGLPFADoubleBuffer);
if (wndconfig->mode == GLFW_FULLSCREEN) if (wndconfig->mode == GLFW_FULLSCREEN)
{ {
ADD_ATTR(NSOpenGLPFAFullScreen);
ADD_ATTR(NSOpenGLPFANoRecovery); ADD_ATTR(NSOpenGLPFANoRecovery);
ADD_ATTR2(NSOpenGLPFAScreenMask, ADD_ATTR2(NSOpenGLPFAScreenMask,
CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID())); CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID()));
@ -587,7 +809,7 @@ static GLboolean createContext(_GLFWwindow* window,
ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
if (fbconfig->stereo) if (fbconfig->stereo)
ADD_ATTR(NSOpenGLPFAStereo ); ADD_ATTR(NSOpenGLPFAStereo);
if (fbconfig->samples > 0) if (fbconfig->samples > 0)
{ {
@ -605,7 +827,7 @@ static GLboolean createContext(_GLFWwindow* window,
if (window->NSGL.pixelFormat == nil) if (window->NSGL.pixelFormat == nil)
{ {
_glfwSetError(GLFW_PLATFORM_ERROR, _glfwSetError(GLFW_PLATFORM_ERROR,
"Cocoa/NSOpenGL: Failed to create pixel format"); "Cocoa/NSOpenGL: Failed to create OpenGL pixel format");
return GL_FALSE; return GL_FALSE;
} }
@ -638,9 +860,14 @@ static GLboolean createContext(_GLFWwindow* window,
//======================================================================== //========================================================================
int _glfwPlatformOpenWindow(_GLFWwindow* window, int _glfwPlatformOpenWindow(_GLFWwindow* window,
const _GLFWwndconfig *wndconfig, const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig *fbconfig) 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 // 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 // first time we create a window to keep all window code in this file
if (_glfwLibrary.NS.delegate == nil) if (_glfwLibrary.NS.delegate == nil)
@ -672,56 +899,31 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
else if (colorBits < 15) else if (colorBits < 15)
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 // Don't use accumulation buffer support; it's not accelerated
// Aux buffers probably aren't accelerated either // 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)) if (!createWindow(window, wndconfig))
return GL_FALSE; return GL_FALSE;
if (!createContext(window, wndconfig, fbconfig)) if (!createContext(window, wndconfig, fbconfig))
return GL_FALSE; return GL_FALSE;
[window->NS.window makeKeyAndOrderFront:nil]; [window->NS.object makeKeyAndOrderFront:nil];
[window->NSGL.context setView:[window->NS.window contentView]]; [window->NSGL.context setView:[window->NS.object contentView]];
if (wndconfig->mode == GLFW_FULLSCREEN) if (wndconfig->mode == GLFW_FULLSCREEN)
{ {
CGCaptureAllDisplays(); int bpp = colorBits + fbconfig->alphaBits;
CGDisplaySwitchToMode(CGMainDisplayID(), fullscreenMode);
}
if (wndconfig->mode == GLFW_FULLSCREEN) if (!_glfwSetVideoMode(&window->width,
{ &window->height,
// TODO: Make this work on pre-Leopard systems &bpp,
[[window->NS.window contentView] enterFullScreenMode:[NSScreen mainScreen] &window->refreshRate))
{
return GL_FALSE;
}
[[window->NS.object contentView] enterFullScreenMode:[NSScreen mainScreen]
withOptions:nil]; withOptions:nil];
} }
@ -743,15 +945,13 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
void _glfwPlatformCloseWindow(_GLFWwindow* window) void _glfwPlatformCloseWindow(_GLFWwindow* window)
{ {
[window->NS.window orderOut:nil]; [window->NS.object orderOut:nil];
if (window->mode == GLFW_FULLSCREEN) if (window->mode == GLFW_FULLSCREEN)
{ {
[[window->NS.window contentView] exitFullScreenModeWithOptions:nil]; [[window->NS.object contentView] exitFullScreenModeWithOptions:nil];
CGDisplaySwitchToMode(CGMainDisplayID(), _glfwRestoreVideoMode();
(CFDictionaryRef) _glfwLibrary.NS.desktopMode);
CGReleaseAllDisplays();
} }
[window->NSGL.pixelFormat release]; [window->NSGL.pixelFormat release];
@ -761,34 +961,40 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window)
[window->NSGL.context release]; [window->NSGL.context release];
window->NSGL.context = nil; window->NSGL.context = nil;
[window->NS.window setDelegate:nil]; [window->NS.object setDelegate:nil];
[window->NS.delegate release]; [window->NS.delegate release];
window->NS.delegate = nil; window->NS.delegate = nil;
[window->NS.window close]; [window->NS.view release];
window->NS.window = nil; window->NS.view = nil;
[window->NS.object close];
window->NS.object = nil;
// TODO: Probably more cleanup // TODO: Probably more cleanup
} }
//======================================================================== //========================================================================
// Set the window title // Set the window title
//======================================================================== //========================================================================
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *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 // Set the window size
//======================================================================== //========================================================================
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) 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 // Set the window position
//======================================================================== //========================================================================
@ -796,37 +1002,40 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y)
{ {
NSRect contentRect = 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 // We assume here that the client code wants to position the window within the
// screen the window currently occupies // 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, contentRect.origin = NSMakePoint(screenRect.origin.x + x,
screenRect.origin.y + screenRect.size.height - screenRect.origin.y + screenRect.size.height -
y - contentRect.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]; display:YES];
} }
//======================================================================== //========================================================================
// Iconify the window // Iconify the window
//======================================================================== //========================================================================
void _glfwPlatformIconifyWindow(_GLFWwindow* window) void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{ {
[window->NS.window miniaturize:nil]; [window->NS.object miniaturize:nil];
} }
//======================================================================== //========================================================================
// Restore (un-iconify) the window // Restore (un-iconify) the window
//======================================================================== //========================================================================
void _glfwPlatformRestoreWindow(_GLFWwindow* window) void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{ {
[window->NS.window deminiaturize:nil]; [window->NS.object deminiaturize:nil];
} }
//======================================================================== //========================================================================
// Write back window parameters into GLFW window structure // Write back window parameters into GLFW window structure
//======================================================================== //========================================================================
@ -901,6 +1110,7 @@ void _glfwPlatformRefreshWindowParams(void)
window->glDebug = GL_FALSE; window->glDebug = GL_FALSE;
} }
//======================================================================== //========================================================================
// Poll for new window and input events // Poll for new window and input events
//======================================================================== //========================================================================
@ -925,6 +1135,7 @@ void _glfwPlatformPollEvents(void)
_glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init]; _glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init];
} }
//======================================================================== //========================================================================
// Wait for new window and input events // Wait for new window and input events
//======================================================================== //========================================================================
@ -943,38 +1154,32 @@ void _glfwPlatformWaitEvents( void )
_glfwPlatformPollEvents(); _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, if (window->mode == GLFW_FULLSCREEN)
// 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 NSPoint globalPoint = NSMakePoint(x, y);
// misunderstanding it... CGDisplayMoveCursorToPoint(CGMainDisplayID(), globalPoint);
}
// Also, (x, y) are window coords... else
{
// Also, it doesn't seem possible to write this robustly without NSPoint localPoint = NSMakePoint(x, window->height - y - 1);
// calculating the maximum y coordinate of all screens, since Cocoa's NSPoint globalPoint = [window->NS.object convertBaseToScreen:localPoint];
// "global coordinates" are upside down from CG's... CGPoint mainScreenOrigin = CGDisplayBounds(CGMainDisplayID()).origin;
double mainScreenHeight = CGDisplayBounds(CGMainDisplayID()).size.height;
// Without this (once per app run, but it's convenient to do it here) CGPoint targetPoint = CGPointMake(globalPoint.x - mainScreenOrigin.x,
// events will be suppressed for a default of 0.25 seconds after we mainScreenHeight - globalPoint.y -
// move the cursor. mainScreenOrigin.y);
CGSetLocalEventsSuppressionInterval(0.0); CGDisplayMoveCursorToPoint(CGMainDisplayID(), targetPoint);
}
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);
} }
//======================================================================== //========================================================================
// Set physical mouse cursor mode // Set physical mouse cursor mode
//======================================================================== //========================================================================

View File

@ -42,28 +42,29 @@
// Define this to 1 if building GLFW for Cocoa/NSOpenGL // Define this to 1 if building GLFW for Cocoa/NSOpenGL
#cmakedefine _GLFW_COCOA_NSGL #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 // 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 // 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 // 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 // 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 // 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 // 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 // Define this to 1 if the Linux joystick API is available
#cmakedefine _GLFW_USE_LINUX_JOYSTICKS 1 #cmakedefine _GLFW_USE_LINUX_JOYSTICKS
// 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
// The GLFW version as used by glfwGetVersionString // The GLFW version as used by glfwGetVersionString
#define _GLFW_VERSION_FULL "@GLFW_VERSION_FULL@" #define _GLFW_VERSION_FULL "@GLFW_VERSION_FULL@"

View File

@ -109,6 +109,8 @@ GLFWAPI const char* glfwErrorString(int error)
return "A platform-specific error occurred"; return "A platform-specific error occurred";
case GLFW_WINDOW_NOT_ACTIVE: case GLFW_WINDOW_NOT_ACTIVE:
return "The specified window is 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"; return "ERROR: UNKNOWN ERROR TOKEN PASSED TO glfwErrorString";

View File

@ -112,5 +112,6 @@ GLFWAPI void glfwSetGammaRamp(const GLFWgammaramp* ramp)
_glfwPlatformSetGammaRamp(ramp); _glfwPlatformSetGammaRamp(ramp);
_glfwLibrary.currentRamp = *ramp; _glfwLibrary.currentRamp = *ramp;
_glfwLibrary.rampChanged = GL_TRUE;
} }

View File

@ -35,30 +35,6 @@
#include <stdlib.h> #include <stdlib.h>
//////////////////////////////////////////////////////////////////////////
////// 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 ////// ////// GLFW public API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -67,31 +43,13 @@ void _glfwFree(void* ptr)
// Initialize various GLFW state // Initialize various GLFW state
//======================================================================== //========================================================================
GLFWAPI int glfwInit(GLFWallocator* allocator) GLFWAPI int glfwInit(void)
{ {
if (_glfwInitialized) if (_glfwInitialized)
return GL_TRUE; return GL_TRUE;
memset(&_glfwLibrary, 0, sizeof(_glfwLibrary)); 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 // Not all window hints have zero as their default value, so this
// needs to be here despite the memset above // needs to be here despite the memset above
_glfwSetDefaultWindowHints(); _glfwSetDefaultWindowHints();

View File

@ -35,37 +35,33 @@
// Sets the cursor mode for the specified window // 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 && if (newMode != GLFW_CURSOR_NORMAL &&
mode != GLFW_CURSOR_HIDDEN && newMode != GLFW_CURSOR_HIDDEN &&
mode != GLFW_CURSOR_CAPTURED) newMode != GLFW_CURSOR_CAPTURED)
{ {
_glfwSetError(GLFW_INVALID_ENUM, NULL); _glfwSetError(GLFW_INVALID_ENUM, NULL);
return; return;
} }
if (window->cursorMode == mode) oldMode = window->cursorMode;
if (oldMode == newMode)
return; return;
centerPosX = window->width / 2; centerPosX = window->width / 2;
centerPosY = window->height / 2; centerPosY = window->height / 2;
if (mode == GLFW_CURSOR_CAPTURED) if (oldMode == GLFW_CURSOR_CAPTURED || newMode == GLFW_CURSOR_CAPTURED)
_glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY); _glfwPlatformSetCursorPos(window, centerPosX, centerPosY);
else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
{
_glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY);
_glfwInputCursorMotion(window,
centerPosX - window->cursorPosX,
centerPosY - window->cursorPosY);
}
_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; return;
// Register key action // Register key action
if(action == GLFW_RELEASE && window->stickyKeys) if (action == GLFW_RELEASE && window->stickyKeys)
window->key[key] = GLFW_STICK; window->key[key] = GLFW_STICK;
else else
{ {
@ -200,7 +196,7 @@ void _glfwInputChar(_GLFWwindow* window, int character)
// Register scroll events // Register scroll events
//======================================================================== //========================================================================
void _glfwInputScroll(_GLFWwindow* window, int xoffset, int yoffset) void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
{ {
window->scrollX += xoffset; window->scrollX += xoffset;
window->scrollY += yoffset; window->scrollY += yoffset;
@ -253,15 +249,26 @@ void _glfwInputCursorMotion(_GLFWwindow* window, int x, int y)
window->cursorPosY = y; window->cursorPosY = y;
} }
if (_glfwLibrary.mousePosCallback) if (_glfwLibrary.cursorPosCallback)
{ {
_glfwLibrary.mousePosCallback(window, _glfwLibrary.cursorPosCallback(window,
window->cursorPosX, window->cursorPosX,
window->cursorPosY); window->cursorPosY);
} }
} }
//========================================================================
// Register cursor enter/leave events
//========================================================================
void _glfwInputCursorEnter(_GLFWwindow* window, int entered)
{
if (_glfwLibrary.cursorEnterCallback)
_glfwLibrary.cursorEnterCallback(window, entered);
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW public API ////// ////// GLFW public API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -351,10 +358,8 @@ GLFWAPI int glfwGetKey(GLFWwindow handle, int key)
return GLFW_RELEASE; return GLFW_RELEASE;
} }
// Is it a valid key?
if (key < 0 || key > GLFW_KEY_LAST) if (key < 0 || key > GLFW_KEY_LAST)
{ {
// TODO: Decide whether key is a value or enum
_glfwSetError(GLFW_INVALID_ENUM, _glfwSetError(GLFW_INVALID_ENUM,
"glfwGetKey: The specified key is invalid"); "glfwGetKey: The specified key is invalid");
return GLFW_RELEASE; return GLFW_RELEASE;
@ -385,7 +390,6 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow handle, int button)
return GLFW_RELEASE; return GLFW_RELEASE;
} }
// Is it a valid mouse button?
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
{ {
_glfwSetError(GLFW_INVALID_ENUM, _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 // 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; _GLFWwindow* window = (_GLFWwindow*) handle;
@ -418,7 +422,6 @@ GLFWAPI void glfwGetMousePos(GLFWwindow handle, int* xpos, int* ypos)
return; return;
} }
// Return mouse position
if (xpos != NULL) if (xpos != NULL)
*xpos = window->cursorPosX; *xpos = window->cursorPosX;
@ -432,7 +435,7 @@ GLFWAPI void glfwGetMousePos(GLFWwindow handle, int* xpos, int* ypos)
// the specified window // 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; _GLFWwindow* window = (_GLFWwindow*) handle;
@ -448,11 +451,11 @@ GLFWAPI void glfwSetMousePos(GLFWwindow handle, int xpos, int ypos)
return; 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) if (xpos == window->cursorPosX && ypos == window->cursorPosY)
return; return;
// Set GLFW mouse position // Set GLFW cursor position
window->cursorPosX = xpos; window->cursorPosX = xpos;
window->cursorPosY = ypos; window->cursorPosY = ypos;
@ -461,7 +464,7 @@ GLFWAPI void glfwSetMousePos(GLFWwindow handle, int xpos, int ypos)
return; return;
// Update physical cursor position // 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 // 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; _GLFWwindow* window = (_GLFWwindow*) handle;
@ -539,7 +542,7 @@ GLFWAPI void glfwSetMouseButtonCallback(GLFWmousebuttonfun cbfun)
// Set callback function for mouse moves // Set callback function for mouse moves
//======================================================================== //========================================================================
GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun) GLFWAPI void glfwSetCursorPosCallback(GLFWcursorposfun cbfun)
{ {
if (!_glfwInitialized) if (!_glfwInitialized)
{ {
@ -547,11 +550,10 @@ GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun)
return; return;
} }
// Set callback function _glfwLibrary.cursorPosCallback = cbfun;
_glfwLibrary.mousePosCallback = cbfun;
// Call the callback function to let the application know the current // Call the callback function to let the application know the current
// mouse position // cursor position
if (cbfun) if (cbfun)
{ {
_GLFWwindow* window; _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 // Set callback function for scroll events
//======================================================================== //========================================================================
@ -574,7 +592,6 @@ GLFWAPI void glfwSetScrollCallback(GLFWscrollfun cbfun)
return; return;
} }
// Set callback function
_glfwLibrary.scrollCallback = cbfun; _glfwLibrary.scrollCallback = cbfun;
} }

View File

@ -37,9 +37,9 @@
//======================================================================== //========================================================================
#if defined(_init_c_) #if defined(_init_c_)
#define GLFWGLOBAL #define GLFWGLOBAL
#else #else
#define GLFWGLOBAL extern #define GLFWGLOBAL extern
#endif #endif
@ -51,6 +51,17 @@
#define GLFW_STICK 2 #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 // Platform specific definitions goes in platform.h (which also includes
// glfw.h) // glfw.h)
@ -73,15 +84,16 @@ typedef struct _GLFWlibrary _GLFWlibrary;
typedef struct _GLFWmonitor _GLFWmonitor; typedef struct _GLFWmonitor _GLFWmonitor;
#if defined(_GLFW_COCOA_NSGL) #if defined(_GLFW_COCOA_NSGL)
#include "cocoa_platform.h" #include "cocoa_platform.h"
#elif defined(_GLFW_WIN32_WGL) #elif defined(_GLFW_WIN32_WGL)
#include "win32_platform.h" #include "win32_platform.h"
#elif defined(_GLFW_X11_GLX) #elif defined(_GLFW_X11_GLX)
#include "x11_platform.h" #include "x11_platform.h"
#else #else
#error "No supported platform selected" #error "No supported platform selected"
#endif #endif
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Window hints, set by glfwOpenWindowHint and consumed by glfwOpenWindow // Window hints, set by glfwOpenWindowHint and consumed by glfwOpenWindow
// A bucket of semi-random stuff lumped together for historical reasons // A bucket of semi-random stuff lumped together for historical reasons
@ -186,7 +198,7 @@ struct _GLFWwindow
GLboolean systemKeys; // system keys enabled flag GLboolean systemKeys; // system keys enabled flag
int cursorPosX, cursorPosY; int cursorPosX, cursorPosY;
int cursorMode; int cursorMode;
int scrollX, scrollY; double scrollX, scrollY;
char mouseButton[GLFW_MOUSE_BUTTON_LAST + 1]; char mouseButton[GLFW_MOUSE_BUTTON_LAST + 1];
char key[GLFW_KEY_LAST + 1]; char key[GLFW_KEY_LAST + 1];
@ -259,20 +271,21 @@ struct _GLFWlibrary
GLFWwindowfocusfun windowFocusCallback; GLFWwindowfocusfun windowFocusCallback;
GLFWwindowiconifyfun windowIconifyCallback; GLFWwindowiconifyfun windowIconifyCallback;
GLFWmousebuttonfun mouseButtonCallback; GLFWmousebuttonfun mouseButtonCallback;
GLFWmouseposfun mousePosCallback; GLFWcursorposfun cursorPosCallback;
GLFWcursorenterfun cursorEnterCallback;
GLFWscrollfun scrollCallback; GLFWscrollfun scrollCallback;
GLFWkeyfun keyCallback; GLFWkeyfun keyCallback;
GLFWcharfun charCallback; GLFWcharfun charCallback;
GLFWmonitordevicefun monitorCallback; GLFWmonitordevicefun monitorCallback;
GLFWallocator allocator;
GLFWgammaramp currentRamp; GLFWgammaramp currentRamp;
GLFWgammaramp originalRamp; GLFWgammaramp originalRamp;
int originalRampSize; int originalRampSize;
GLboolean rampChanged;
// This is defined in the current port's platform.h // 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 // Input
void _glfwPlatformEnableSystemKeys(_GLFWwindow* window); void _glfwPlatformEnableSystemKeys(_GLFWwindow* window);
void _glfwPlatformDisableSystemKeys(_GLFWwindow* window); void _glfwPlatformDisableSystemKeys(_GLFWwindow* window);
void _glfwPlatformSetCursorPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
// Fullscreen // Fullscreen
int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount); int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount);
@ -311,6 +326,10 @@ void _glfwPlatformGetDesktopMode(GLFWvidmode* mode);
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp); void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp);
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp); void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp);
// Clipboard
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string);
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window);
// Joystick // Joystick
int _glfwPlatformGetJoystickParam(int joy, int param); int _glfwPlatformGetJoystickParam(int joy, int param);
int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes); 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 _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformIconifyWindow(_GLFWwindow* window); void _glfwPlatformIconifyWindow(_GLFWwindow* window);
void _glfwPlatformRestoreWindow(_GLFWwindow* window); void _glfwPlatformRestoreWindow(_GLFWwindow* window);
void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y);
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
// Event management // Event management
void _glfwPlatformPollEvents(void); void _glfwPlatformPollEvents(void);
@ -341,7 +358,7 @@ void _glfwPlatformSwapBuffers(void);
void _glfwPlatformSwapInterval(int interval); void _glfwPlatformSwapInterval(int interval);
void _glfwPlatformRefreshWindowParams(void); void _glfwPlatformRefreshWindowParams(void);
int _glfwPlatformExtensionSupported(const char* extension); int _glfwPlatformExtensionSupported(const char* extension);
void* _glfwPlatformGetProcAddress(const char* procname); GLFWglproc _glfwPlatformGetProcAddress(const char* procname);
void _glfwPlatformCopyContext(_GLFWwindow* src, _GLFWwindow* dst, unsigned long mask); 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 // Prototypes for platform independent internal functions
//======================================================================== //========================================================================
// Memory management (init.c)
void* _glfwMalloc(size_t size);
void _glfwFree(void* ptr);
// Fullscren management (fullscreen.c) // Fullscren management (fullscreen.c)
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
int _glfwCompareVideoModes(const void* firstPtr, const void* secondPtr); int _glfwCompareVideoModes(const void* firstPtr, const void* secondPtr);
@ -373,9 +386,10 @@ void _glfwInputWindowDamage(_GLFWwindow* window);
// Input event notification (input.c) // Input event notification (input.c)
void _glfwInputKey(_GLFWwindow* window, int key, int action); void _glfwInputKey(_GLFWwindow* window, int key, int action);
void _glfwInputChar(_GLFWwindow* window, int character); 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 _glfwInputMouseClick(_GLFWwindow* window, int button, int action);
void _glfwInputCursorMotion(_GLFWwindow* window, int x, int y); void _glfwInputCursorMotion(_GLFWwindow* window, int x, int y);
void _glfwInputCursorEnter(_GLFWwindow* window, int entered);
// OpenGL context helpers (opengl.c) // OpenGL context helpers (opengl.c)
int _glfwStringInExtensionString(const char* string, const GLubyte* extensions); int _glfwStringInExtensionString(const char* string, const GLubyte* extensions);

View File

@ -5,8 +5,9 @@ libdir=${exec_prefix}/lib
Name: GLFW Name: GLFW
Description: A portable library for OpenGL, window and input Description: A portable library for OpenGL, window and input
Version: 3.0.0 Version: @GLFW_VERSION_FULL@
URL: http://www.glfw.org/ URL: http://www.glfw.org/
Requires.private: gl x11 @GLFW_PKGLIBS@ Requires.private: @GLFW_PKG_DEPS@
Libs: -L${libdir} -lglfw Libs: -L${libdir} -lglfw
Libs.private: @GLFW_PKG_LIBS@
Cflags: -I${includedir} Cflags: -I${includedir}

View File

@ -30,6 +30,8 @@
#include "internal.h" #include "internal.h"
#include <string.h>
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW public API ////// ////// GLFW public API //////

View File

@ -517,8 +517,7 @@ GLFWAPI void glfwSwapBuffers(void)
return; 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. // 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) if (!_glfwInitialized)
{ {

140
src/win32_clipboard.c Normal file
View File

@ -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 <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <limits.h>
#include <string.h>
#include <stdlib.h>
//////////////////////////////////////////////////////////////////////////
////// 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;
}

View File

@ -31,7 +31,7 @@
#include "internal.h" #include "internal.h"
#if defined(GLFW_BUILD_DLL) #if defined(_GLFW_BUILD_DLL)
//======================================================================== //========================================================================
// GLFW DLL entry point // GLFW DLL entry point
@ -45,5 +45,5 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
return TRUE; return TRUE;
} }
#endif // GLFW_BUILD_DLL #endif // _GLFW_BUILD_DLL

View File

@ -42,7 +42,7 @@
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) 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) void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp)
{ {
_glfw_SetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp); SetDeviceGammaRamp(GetDC(GetDesktopWindow()), (WORD*) ramp);
} }

View File

@ -44,40 +44,6 @@
static GLboolean initLibraries(void) 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 #ifndef _GLFW_NO_DLOAD_WINMM
// winmm.dll (for joystick and timer support) // winmm.dll (for joystick and timer support)
@ -113,14 +79,6 @@ static GLboolean initLibraries(void)
static void freeLibraries(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 #ifndef _GLFW_NO_DLOAD_WINMM
if (_glfwLibrary.Win32.winmm.instance != NULL) 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 ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -146,7 +158,7 @@ int _glfwPlatformInit(void)
// as possible in the hope of still being the foreground process) // as possible in the hope of still being the foreground process)
SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
&_glfwLibrary.Win32.foregroundLockTimeout, 0); &_glfwLibrary.Win32.foregroundLockTimeout, 0);
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID) 0, SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),
SPIF_SENDCHANGE); SPIF_SENDCHANGE);
if (!initLibraries()) if (!initLibraries())
@ -180,7 +192,8 @@ int _glfwPlatformInit(void)
int _glfwPlatformTerminate(void) int _glfwPlatformTerminate(void)
{ {
// Restore the original gamma ramp // Restore the original gamma ramp
_glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp); if (_glfwLibrary.rampChanged)
_glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
_glfwTerminateMonitors(); _glfwTerminateMonitors();
@ -196,7 +209,7 @@ int _glfwPlatformTerminate(void)
// Restore previous FOREGROUNDLOCKTIMEOUT system setting // Restore previous FOREGROUNDLOCKTIMEOUT system setting
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
(LPVOID) _glfwLibrary.Win32.foregroundLockTimeout, UIntToPtr(_glfwLibrary.Win32.foregroundLockTimeout),
SPIF_SENDCHANGE); SPIF_SENDCHANGE);
return GL_TRUE; return GL_TRUE;
@ -212,8 +225,6 @@ const char* _glfwPlatformGetVersionString(void)
const char* version = _GLFW_VERSION_FULL const char* version = _GLFW_VERSION_FULL
#if defined(__MINGW32__) #if defined(__MINGW32__)
" MinGW" " MinGW"
#elif defined(__CYGWIN__)
" Cygwin"
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
" Visual C++ " " Visual C++ "
#elif defined(__BORLANDC__) #elif defined(__BORLANDC__)
@ -221,12 +232,9 @@ const char* _glfwPlatformGetVersionString(void)
#else #else
" (unknown compiler)" " (unknown compiler)"
#endif #endif
#if defined(GLFW_BUILD_DLL) #if defined(_GLFW_BUILD_DLL)
" DLL" " DLL"
#endif #endif
#if !defined(_GLFW_NO_DLOAD_GDI32)
" load(gdi32)"
#endif
#if !defined(_GLFW_NO_DLOAD_WINMM) #if !defined(_GLFW_NO_DLOAD_WINMM)
" load(winmm)" " load(winmm)"
#endif #endif

View File

@ -80,6 +80,7 @@ static float calcJoystickPos(DWORD pos, DWORD min, DWORD max)
int _glfwPlatformGetJoystickParam(int joy, int param) int _glfwPlatformGetJoystickParam(int joy, int param)
{ {
JOYCAPS jc; JOYCAPS jc;
int hats;
if (!isJoystickPresent(joy)) if (!isJoystickPresent(joy))
return 0; return 0;
@ -91,6 +92,8 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
// Get joystick capabilities // Get joystick capabilities
_glfw_joyGetDevCaps(joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS)); _glfw_joyGetDevCaps(joy - GLFW_JOYSTICK_1, &jc, sizeof(JOYCAPS));
hats = (jc.wCaps & JOYCAPS_HASPOV) && (jc.wCaps & JOYCAPS_POV4DIR) ? 1 : 0;
switch (param) switch (param)
{ {
case GLFW_AXES: case GLFW_AXES:
@ -98,8 +101,8 @@ int _glfwPlatformGetJoystickParam(int joy, int param)
return jc.wNumAxes; return jc.wNumAxes;
case GLFW_BUTTONS: case GLFW_BUTTONS:
// Return number of joystick axes // Return number of joystick buttons
return jc.wNumButtons; return jc.wNumButtons + hats * 4;
default: default:
break; break;
@ -164,7 +167,10 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
{ {
JOYCAPS jc; JOYCAPS jc;
JOYINFOEX ji; 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)) if (!isJoystickPresent(joy))
return 0; return 0;
@ -174,7 +180,7 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons,
// Get joystick state // Get joystick state
ji.dwSize = sizeof(JOYINFOEX); ji.dwSize = sizeof(JOYINFOEX);
ji.dwFlags = JOY_RETURNBUTTONS; ji.dwFlags = JOY_RETURNBUTTONS | JOY_RETURNPOV;
_glfw_joyGetPosEx(joy - GLFW_JOYSTICK_1, &ji); _glfw_joyGetPosEx(joy - GLFW_JOYSTICK_1, &ji);
// Get states of all requested buttons // 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); (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; return button;
} }

View File

@ -56,7 +56,7 @@ void _glfwPlatformSwapBuffers(void)
{ {
_GLFWwindow* window = _glfwLibrary.currentWindow; _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 // 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);
} }

View File

@ -33,8 +33,13 @@
// We don't need all the fancy stuff // We don't need all the fancy stuff
#define NOMINMAX #ifndef NOMINMAX
#define VC_EXTRALEAN #define NOMINMAX
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN
#endif
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -45,7 +50,15 @@
// thinks it is the only one that gets to do so // thinks it is the only one that gets to do so
#undef APIENTRY #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 <windows.h> #include <windows.h>
#include <mmsystem.h> #include <mmsystem.h>
@ -61,90 +74,8 @@
// Hack: Define things that some windows.h variants don't // 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 <w32api.h>
#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 #ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E #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
#endif #endif
@ -152,17 +83,6 @@ typedef struct tagKBDLLHOOKSTRUCT {
// DLLs that are loaded at glfwInit() // 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 // winmm.dll function pointer typedefs
#ifndef _GLFW_NO_DLOAD_WINMM #ifndef _GLFW_NO_DLOAD_WINMM
typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T) (UINT,LPJOYCAPS,UINT); typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T) (UINT,LPJOYCAPS,UINT);
@ -172,36 +92,17 @@ typedef DWORD (WINAPI * TIMEGETTIME_T) (void);
#endif // _GLFW_NO_DLOAD_WINMM #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 // winmm.dll shortcuts
#ifndef _GLFW_NO_DLOAD_WINMM #ifndef _GLFW_NO_DLOAD_WINMM
#define _glfw_joyGetDevCaps _glfwLibrary.Win32.winmm.joyGetDevCaps #define _glfw_joyGetDevCaps _glfwLibrary.Win32.winmm.joyGetDevCaps
#define _glfw_joyGetPos _glfwLibrary.Win32.winmm.joyGetPos #define _glfw_joyGetPos _glfwLibrary.Win32.winmm.joyGetPos
#define _glfw_joyGetPosEx _glfwLibrary.Win32.winmm.joyGetPosEx #define _glfw_joyGetPosEx _glfwLibrary.Win32.winmm.joyGetPosEx
#define _glfw_timeGetTime _glfwLibrary.Win32.winmm.timeGetTime #define _glfw_timeGetTime _glfwLibrary.Win32.winmm.timeGetTime
#else #else
#define _glfw_joyGetDevCaps joyGetDevCaps #define _glfw_joyGetDevCaps joyGetDevCaps
#define _glfw_joyGetPos joyGetPos #define _glfw_joyGetPos joyGetPos
#define _glfw_joyGetPosEx joyGetPosEx #define _glfw_joyGetPosEx joyGetPosEx
#define _glfw_timeGetTime timeGetTime #define _glfw_timeGetTime timeGetTime
#endif // _GLFW_NO_DLOAD_WINMM #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_WINDOW_STATE _GLFWwindowWin32 Win32
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryWin32 Win32
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL WGL #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL WGL
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 Win32 #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 // GLFW platform specific types
@ -264,12 +168,13 @@ typedef struct _GLFWwindowWin32
// Various platform specific internal variables // Various platform specific internal variables
int desiredRefreshRate; // Desired vertical monitor refresh rate int desiredRefreshRate; // Desired vertical monitor refresh rate
GLboolean cursorCentered; GLboolean cursorCentered;
int oldMouseX, oldMouseY; GLboolean cursorInside;
int oldCursorX, oldCursorY;
} _GLFWwindowWin32; } _GLFWwindowWin32;
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Platform-specific library global data // Platform-specific library global data for Win32
//------------------------------------------------------------------------ //------------------------------------------------------------------------
typedef struct _GLFWlibraryWin32 typedef struct _GLFWlibraryWin32
{ {
@ -277,6 +182,7 @@ typedef struct _GLFWlibraryWin32
ATOM classAtom; // Window class atom ATOM classAtom; // Window class atom
HHOOK keyboardHook; // Keyboard hook handle HHOOK keyboardHook; // Keyboard hook handle
DWORD foregroundLockTimeout; DWORD foregroundLockTimeout;
char* clipboardString;
// Default monitor // Default monitor
struct { struct {
@ -295,20 +201,6 @@ typedef struct _GLFWlibraryWin32
__int64 t0_64; __int64 t0_64;
} timer; } 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 #ifndef _GLFW_NO_DLOAD_WINMM
// winmm.dll // winmm.dll
struct { struct {
@ -331,10 +223,24 @@ typedef struct _GLFWmonitorWin32
} _GLFWmonitorWin32; } _GLFWmonitorWin32;
//------------------------------------------------------------------------
// Platform-specific library global data for WGL
//------------------------------------------------------------------------
typedef struct _GLFWlibraryWGL
{
int dummy;
} _GLFWlibraryWGL;
//======================================================================== //========================================================================
// Prototypes for platform specific internal functions // Prototypes for platform specific internal functions
//======================================================================== //========================================================================
// Wide strings
WCHAR* _glfwCreateWideStringFromUTF8(const char* source);
char* _glfwCreateUTF8FromWideString(const WCHAR* source);
// Time // Time
void _glfwInitTimer(void); void _glfwInitTimer(void);

315
src/win32_window.c Normal file → Executable file
View File

@ -33,55 +33,6 @@
#include <stdlib.h> #include <stdlib.h>
//========================================================================
// 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 // 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) static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
{ {
_GLFWfbconfig* result; _GLFWfbconfig* fbconfigs;
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
int i, count; int i, available;
*found = 0; *found = 0;
if (window->WGL.ARB_pixel_format) 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 else
{ {
count = _glfw_DescribePixelFormat(window->WGL.DC, available = DescribePixelFormat(window->WGL.DC,
1, 1,
sizeof(PIXELFORMATDESCRIPTOR), sizeof(PIXELFORMATDESCRIPTOR),
NULL); NULL);
} }
if (!count) if (!available)
{ {
_glfwSetError(GLFW_OPENGL_UNAVAILABLE, "Win32/WGL: No pixel formats found"); _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "Win32/WGL: No pixel formats found");
return NULL; return NULL;
} }
result = (_GLFWfbconfig*) _glfwMalloc(sizeof(_GLFWfbconfig) * count); fbconfigs = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * available);
if (!result) if (!fbconfigs)
{ {
_glfwSetError(GLFW_OUT_OF_MEMORY, _glfwSetError(GLFW_OUT_OF_MEMORY,
"Win32/WGL: Failed to allocate _GLFWfbconfig array"); "Win32/WGL: Failed to allocate _GLFWfbconfig array");
return NULL; return NULL;
} }
for (i = 1; i <= count; i++) for (i = 1; i <= available; i++)
{ {
_GLFWfbconfig* f = fbconfigs + *found;
if (window->WGL.ARB_pixel_format) if (window->WGL.ARB_pixel_format)
{ {
// Get pixel format attributes through 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; continue;
} }
result[*found].redBits = f->redBits = getPixelFormatAttrib(window, i, WGL_RED_BITS_ARB);
getPixelFormatAttrib(window, i, WGL_RED_BITS_ARB); f->greenBits = getPixelFormatAttrib(window, i, WGL_GREEN_BITS_ARB);
result[*found].greenBits = f->blueBits = getPixelFormatAttrib(window, i, WGL_BLUE_BITS_ARB);
getPixelFormatAttrib(window, i, WGL_GREEN_BITS_ARB); f->alphaBits = getPixelFormatAttrib(window, i, WGL_ALPHA_BITS_ARB);
result[*found].blueBits =
getPixelFormatAttrib(window, i, WGL_BLUE_BITS_ARB);
result[*found].alphaBits =
getPixelFormatAttrib(window, i, WGL_ALPHA_BITS_ARB);
result[*found].depthBits = f->depthBits = getPixelFormatAttrib(window, i, WGL_DEPTH_BITS_ARB);
getPixelFormatAttrib(window, i, WGL_DEPTH_BITS_ARB); f->stencilBits = getPixelFormatAttrib(window, i, WGL_STENCIL_BITS_ARB);
result[*found].stencilBits =
getPixelFormatAttrib(window, i, WGL_STENCIL_BITS_ARB);
result[*found].accumRedBits = f->accumRedBits = getPixelFormatAttrib(window, i, WGL_ACCUM_RED_BITS_ARB);
getPixelFormatAttrib(window, i, WGL_ACCUM_RED_BITS_ARB); f->accumGreenBits = getPixelFormatAttrib(window, i, WGL_ACCUM_GREEN_BITS_ARB);
result[*found].accumGreenBits = f->accumBlueBits = getPixelFormatAttrib(window, i, WGL_ACCUM_BLUE_BITS_ARB);
getPixelFormatAttrib(window, i, WGL_ACCUM_GREEN_BITS_ARB); f->accumAlphaBits = getPixelFormatAttrib(window, i, WGL_ACCUM_ALPHA_BITS_ARB);
result[*found].accumBlueBits =
getPixelFormatAttrib(window, i, WGL_ACCUM_BLUE_BITS_ARB);
result[*found].accumAlphaBits =
getPixelFormatAttrib(window, i, WGL_ACCUM_ALPHA_BITS_ARB);
result[*found].auxBuffers = f->auxBuffers = getPixelFormatAttrib(window, i, WGL_AUX_BUFFERS_ARB);
getPixelFormatAttrib(window, i, WGL_AUX_BUFFERS_ARB); f->stereo = getPixelFormatAttrib(window, i, WGL_STEREO_ARB);
result[*found].stereo =
getPixelFormatAttrib(window, i, WGL_STEREO_ARB);
if (window->WGL.ARB_multisample) if (window->WGL.ARB_multisample)
{ f->samples = getPixelFormatAttrib(window, i, WGL_SAMPLES_ARB);
result[*found].samples =
getPixelFormatAttrib(window, i, WGL_SAMPLES_ARB);
}
else else
result[*found].samples = 0; f->samples = 0;
} }
else else
{ {
// Get pixel format attributes through old-fashioned PFDs // Get pixel format attributes through old-fashioned PFDs
if (!_glfw_DescribePixelFormat(window->WGL.DC, if (!DescribePixelFormat(window->WGL.DC,
i, i,
sizeof(PIXELFORMATDESCRIPTOR), sizeof(PIXELFORMATDESCRIPTOR),
&pfd)) &pfd))
{ {
continue; continue;
} }
@ -315,32 +257,38 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found)
if (pfd.iPixelType != PFD_TYPE_RGBA) if (pfd.iPixelType != PFD_TYPE_RGBA)
continue; continue;
result[*found].redBits = pfd.cRedBits; f->redBits = pfd.cRedBits;
result[*found].greenBits = pfd.cGreenBits; f->greenBits = pfd.cGreenBits;
result[*found].blueBits = pfd.cBlueBits; f->blueBits = pfd.cBlueBits;
result[*found].alphaBits = pfd.cAlphaBits; f->alphaBits = pfd.cAlphaBits;
result[*found].depthBits = pfd.cDepthBits; f->depthBits = pfd.cDepthBits;
result[*found].stencilBits = pfd.cStencilBits; f->stencilBits = pfd.cStencilBits;
result[*found].accumRedBits = pfd.cAccumRedBits; f->accumRedBits = pfd.cAccumRedBits;
result[*found].accumGreenBits = pfd.cAccumGreenBits; f->accumGreenBits = pfd.cAccumGreenBits;
result[*found].accumBlueBits = pfd.cAccumBlueBits; f->accumBlueBits = pfd.cAccumBlueBits;
result[*found].accumAlphaBits = pfd.cAccumAlphaBits; f->accumAlphaBits = pfd.cAccumAlphaBits;
result[*found].auxBuffers = pfd.cAuxBuffers; f->auxBuffers = pfd.cAuxBuffers;
result[*found].stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; f->stereo = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE;
// PFD pixel formats do not support FSAA // PFD pixel formats do not support FSAA
result[*found].samples = 0; f->samples = 0;
} }
result[*found].platformID = i; f->platformID = i;
(*found)++; (*found)++;
} }
return result; if (*found == 0)
{
free(fbconfigs);
return NULL;
}
return fbconfigs;
} }
@ -359,14 +307,14 @@ static GLboolean createContext(_GLFWwindow* window,
if (wndconfig->share) if (wndconfig->share)
share = wndconfig->share->WGL.context; 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, _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
"Win32/WGL: Failed to retrieve PFD for selected pixel format"); "Win32/WGL: Failed to retrieve PFD for selected pixel format");
return GL_FALSE; return GL_FALSE;
} }
if (!_glfw_SetPixelFormat(window->WGL.DC, pixelFormat, &pfd)) if (!SetPixelFormat(window->WGL.DC, pixelFormat, &pfd))
{ {
_glfwSetError(GLFW_OPENGL_UNAVAILABLE, _glfwSetError(GLFW_OPENGL_UNAVAILABLE,
"Win32/WGL: Failed to set selected pixel format"); "Win32/WGL: Failed to set selected pixel format");
@ -500,7 +448,7 @@ static GLboolean createContext(_GLFWwindow* window,
// Hide mouse cursor // 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 // Capture mouse cursor
//======================================================================== //========================================================================
static void captureMouseCursor(_GLFWwindow* window) static void captureCursor(_GLFWwindow* window)
{ {
RECT ClipWindowRect; RECT ClipWindowRect;
@ -528,7 +476,7 @@ static void captureMouseCursor(_GLFWwindow* window)
// Show mouse cursor // Show mouse cursor
//======================================================================== //========================================================================
static void showMouseCursor(_GLFWwindow* window) static void showCursor(_GLFWwindow* window)
{ {
// Un-capture cursor // Un-capture cursor
ReleaseCapture(); ReleaseCapture();
@ -835,7 +783,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// The window was deactivated (or iconified, see above) // The window was deactivated (or iconified, see above)
if (window->cursorMode == GLFW_CURSOR_CAPTURED) if (window->cursorMode == GLFW_CURSOR_CAPTURED)
showMouseCursor(window); showCursor(window);
if (window->mode == GLFW_FULLSCREEN) if (window->mode == GLFW_FULLSCREEN)
{ {
@ -858,7 +806,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// The window was activated // The window was activated
if (window->cursorMode == GLFW_CURSOR_CAPTURED) if (window->cursorMode == GLFW_CURSOR_CAPTURED)
captureMouseCursor(window); captureCursor(window);
if (window->mode == GLFW_FULLSCREEN) if (window->mode == GLFW_FULLSCREEN)
{ {
@ -919,7 +867,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (_glfwLibrary.charCallback) if (_glfwLibrary.charCallback)
translateChar(window, (DWORD) wParam, (DWORD) lParam); translateChar(window, (DWORD) wParam, (DWORD) lParam);
return 0; break;
} }
case WM_KEYUP: case WM_KEYUP:
@ -934,7 +882,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
else else
_glfwInputKey(window, translateKey(wParam, lParam), GLFW_RELEASE); _glfwInputKey(window, translateKey(wParam, lParam), GLFW_RELEASE);
return 0; break;
} }
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
@ -1013,14 +961,14 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOUSEMOVE: case WM_MOUSEMOVE:
{ {
int newMouseX, newMouseY; int newCursorX, newCursorY;
// Get signed (!) mouse position // Get signed (!) cursor position
newMouseX = (int)((short)LOWORD(lParam)); newCursorX = (int)((short)LOWORD(lParam));
newMouseY = (int)((short)HIWORD(lParam)); newCursorY = (int)((short)HIWORD(lParam));
if (newMouseX != window->Win32.oldMouseX || if (newCursorX != window->Win32.oldCursorX ||
newMouseY != window->Win32.oldMouseY) newCursorY != window->Win32.oldCursorY)
{ {
int x, y; int x, y;
@ -1029,28 +977,48 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (_glfwLibrary.activeWindow != window) if (_glfwLibrary.activeWindow != window)
return 0; return 0;
x = newMouseX - window->Win32.oldMouseX; x = newCursorX - window->Win32.oldCursorX;
y = newMouseY - window->Win32.oldMouseY; y = newCursorY - window->Win32.oldCursorY;
} }
else else
{ {
x = newMouseX; x = newCursorX;
y = newMouseY; y = newCursorY;
} }
window->Win32.oldMouseX = newMouseX; window->Win32.oldCursorX = newCursorX;
window->Win32.oldMouseY = newMouseY; window->Win32.oldCursorY = newCursorY;
window->Win32.cursorCentered = GL_FALSE; window->Win32.cursorCentered = GL_FALSE;
_glfwInputCursorMotion(window, x, y); _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; return 0;
} }
case WM_MOUSEWHEEL: case WM_MOUSEWHEEL:
{ {
_glfwInputScroll(window, 0, (((int) wParam) >> 16) / WHEEL_DELTA); _glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);
return 0; return 0;
} }
@ -1058,7 +1026,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{ {
// This message is only sent on Windows Vista and later // 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; return 0;
} }
@ -1291,13 +1259,13 @@ static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* fbconfig)
closest = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); closest = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount);
if (!closest) if (!closest)
{ {
_glfwFree(fbconfigs); free(fbconfigs);
return 0; return 0;
} }
pixelFormat = (int) closest->platformID; pixelFormat = (int) closest->platformID;
_glfwFree(fbconfigs); free(fbconfigs);
fbconfigs = NULL; fbconfigs = NULL;
closest = NULL; closest = NULL;
@ -1314,7 +1282,7 @@ static int createWindow(_GLFWwindow* window,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
DWORD dwStyle, dwExStyle; DWORD dwStyle, dwExStyle;
int length, pixelFormat, fullWidth, fullHeight; int pixelFormat, fullWidth, fullHeight;
RECT wa; RECT wa;
POINT pos; POINT pos;
WCHAR* wideTitle; WCHAR* wideTitle;
@ -1366,12 +1334,12 @@ static int createWindow(_GLFWwindow* window,
else else
SystemParametersInfo(SPI_GETWORKAREA, 0, &wa, 0); SystemParametersInfo(SPI_GETWORKAREA, 0, &wa, 0);
wideTitle = createWideStringFromUTF8(wndconfig->title); wideTitle = _glfwCreateWideStringFromUTF8(wndconfig->title);
if (!wideTitle) if (!wideTitle)
{ {
_glfwSetError(GLFW_PLATFORM_ERROR, _glfwSetError(GLFW_PLATFORM_ERROR,
"glfwOpenWindow: Failed to convert title to wide string"); "glfwOpenWindow: Failed to convert title to wide string");
return; return GL_FALSE;
} }
window->Win32.handle = CreateWindowEx(window->Win32.dwExStyle, window->Win32.handle = CreateWindowEx(window->Win32.dwExStyle,
@ -1392,7 +1360,7 @@ static int createWindow(_GLFWwindow* window,
return GL_FALSE; return GL_FALSE;
} }
_glfwFree(wideTitle); free(wideTitle);
window->WGL.DC = GetDC(window->Win32.handle); window->WGL.DC = GetDC(window->Win32.handle);
if (!window->WGL.DC) if (!window->WGL.DC)
@ -1413,11 +1381,11 @@ static int createWindow(_GLFWwindow* window,
initWGLExtensions(window); initWGLExtensions(window);
// Initialize mouse position data // Initialize cursor position data
GetCursorPos(&pos); GetCursorPos(&pos);
ScreenToClient(window->Win32.handle, &pos); ScreenToClient(window->Win32.handle, &pos);
window->Win32.oldMouseX = window->cursorPosX = pos.x; window->Win32.oldCursorX = window->cursorPosX = pos.x;
window->Win32.oldMouseY = window->cursorPosY = pos.y; window->Win32.oldCursorY = window->cursorPosY = pos.y;
return GL_TRUE; return GL_TRUE;
} }
@ -1475,6 +1443,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window,
GLboolean recreateContext = GL_FALSE; GLboolean recreateContext = GL_FALSE;
window->Win32.desiredRefreshRate = wndconfig->refreshRate; window->Win32.desiredRefreshRate = wndconfig->refreshRate;
window->resizable = wndconfig->resizable;
if (!_glfwLibrary.Win32.classAtom) if (!_glfwLibrary.Win32.classAtom)
{ {
@ -1613,7 +1582,7 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window)
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{ {
WCHAR* wideTitle = createWideStringFromUTF8(title); WCHAR* wideTitle = _glfwCreateWideStringFromUTF8(title);
if (!wideTitle) if (!wideTitle)
{ {
_glfwSetError(GLFW_PLATFORM_ERROR, _glfwSetError(GLFW_PLATFORM_ERROR,
@ -1623,7 +1592,7 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
SetWindowText(window->Win32.handle, wideTitle); 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) void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{ {
//int bpp, refresh;
int newMode = 0;
GLboolean sizeChanged = GL_FALSE; GLboolean sizeChanged = GL_FALSE;
if (window->mode == GLFW_FULLSCREEN) 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) if (width > window->width || height > window->height)
{ {
// The new video mode is larger than the current one, so we resize // 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; sizeChanged = GL_TRUE;
} }
//if (newMode != window->Win32.modeID) // TODO: Change video mode
//_glfwSetVideoModeMODE(newMode);
} }
else else
{ {
@ -1692,7 +1641,13 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) 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); SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
} }
@ -1730,7 +1685,7 @@ void _glfwPlatformRefreshWindowParams(void)
_GLFWwindow* window = _glfwLibrary.currentWindow; _GLFWwindow* window = _glfwLibrary.currentWindow;
// Obtain a detailed description of current pixel format // 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) if (window->WGL.ARB_pixel_format)
{ {
@ -1784,8 +1739,8 @@ void _glfwPlatformRefreshWindowParams(void)
} }
else else
{ {
_glfw_DescribePixelFormat(window->WGL.DC, pixelFormat, DescribePixelFormat(window->WGL.DC, pixelFormat,
sizeof(PIXELFORMATDESCRIPTOR), &pfd); sizeof(PIXELFORMATDESCRIPTOR), &pfd);
// Is current OpenGL context accelerated? // Is current OpenGL context accelerated?
window->accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) || window->accelerated = (pfd.dwFlags & PFD_GENERIC_ACCELERATED) ||
@ -1835,14 +1790,14 @@ void _glfwPlatformPollEvents(void)
window = _glfwLibrary.activeWindow; window = _glfwLibrary.activeWindow;
if (window) if (window)
{ {
window->Win32.cursorCentered = GL_TRUE; window->Win32.cursorCentered = GL_FALSE;
window->Win32.oldMouseX = window->width / 2; window->Win32.oldCursorX = window->width / 2;
window->Win32.oldMouseY = window->height / 2; window->Win32.oldCursorY = window->height / 2;
} }
else else
{ {
//window->Win32.oldMouseX = window->cursorPosX; //window->Win32.oldCursorX = window->cursorPosX;
//window->Win32.oldMouseY = window->cursorPosY; //window->Win32.oldCursorY = window->cursorPosY;
} }
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
@ -1899,9 +1854,9 @@ void _glfwPlatformPollEvents(void)
if (window->cursorMode == GLFW_CURSOR_CAPTURED && if (window->cursorMode == GLFW_CURSOR_CAPTURED &&
!window->Win32.cursorCentered) !window->Win32.cursorCentered)
{ {
_glfwPlatformSetMouseCursorPos(window, _glfwPlatformSetCursorPos(window,
window->width / 2, window->width / 2,
window->height / 2); window->height / 2);
window->Win32.cursorCentered = GL_TRUE; 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; POINT pos;
@ -1946,13 +1901,13 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
switch (mode) switch (mode)
{ {
case GLFW_CURSOR_NORMAL: case GLFW_CURSOR_NORMAL:
showMouseCursor(window); showCursor(window);
break; break;
case GLFW_CURSOR_HIDDEN: case GLFW_CURSOR_HIDDEN:
hideMouseCursor(window); hideCursor(window);
break; break;
case GLFW_CURSOR_CAPTURED: case GLFW_CURSOR_CAPTURED:
captureMouseCursor(window); captureCursor(window);
break; break;
} }
} }

View File

@ -291,7 +291,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height,
height = 480; height = 480;
} }
window = (_GLFWwindow*) _glfwMalloc(sizeof(_GLFWwindow)); window = (_GLFWwindow*) malloc(sizeof(_GLFWwindow));
if (!window) if (!window)
{ {
_glfwSetError(GLFW_OUT_OF_MEMORY, _glfwSetError(GLFW_OUT_OF_MEMORY,
@ -492,7 +492,7 @@ GLFWAPI void glfwCloseWindow(GLFWwindow handle)
*prev = window->next; *prev = window->next;
} }
_glfwFree(window); free(window);
} }
@ -655,7 +655,6 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow handle)
if (!window->iconified) if (!window->iconified)
return; return;
// Restore iconified window
_glfwPlatformRestoreWindow(window); _glfwPlatformRestoreWindow(window);
if (window->mode == GLFW_FULLSCREEN) if (window->mode == GLFW_FULLSCREEN)

191
src/x11_clipboard.c Normal file
View File

@ -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 <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
//////////////////////////////////////////////////////////////////////////
////// 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;
}

View File

@ -42,7 +42,7 @@
// Finds the video mode closest in size to the specified desired size // 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; int i, match, bestmatch;
@ -55,8 +55,7 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
XRRScreenConfiguration* sc; XRRScreenConfiguration* sc;
XRRScreenSize* sizelist; XRRScreenSize* sizelist;
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
RootWindow(_glfwLibrary.X11.display, screen));
sizelist = XRRConfigSizes(sc, &sizecount); sizelist = XRRConfigSizes(sc, &sizecount);
@ -116,7 +115,8 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
int bestmode, modecount; int bestmode, modecount;
// Get a list of all available display modes // Get a list of all available display modes
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen,
&modecount, &modelist); &modecount, &modelist);
// Find the best matching mode // 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 // Default: Simply use the screen resolution
*width = DisplayWidth(_glfwLibrary.X11.display, screen); *width = DisplayWidth(_glfwLibrary.X11.display, _glfwLibrary.X11.screen);
*height = DisplayHeight(_glfwLibrary.X11.display, screen); *height = DisplayHeight(_glfwLibrary.X11.display, _glfwLibrary.X11.screen);
return 0; return 0;
} }
@ -161,7 +161,7 @@ int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate)
// Change the current video mode // Change the current video mode
//======================================================================== //========================================================================
void _glfwSetVideoModeMODE(int screen, int mode, int rate) void _glfwSetVideoModeMODE(int mode, int rate)
{ {
if (_glfwLibrary.X11.RandR.available) if (_glfwLibrary.X11.RandR.available)
{ {
@ -169,15 +169,17 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
XRRScreenConfiguration* sc; XRRScreenConfiguration* sc;
Window root; Window root;
root = RootWindow(_glfwLibrary.X11.display, screen); root = _glfwLibrary.X11.root;
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, root); sc = XRRGetScreenInfo(_glfwLibrary.X11.display, root);
// Remember old size and flag that we have changed the mode // Remember old size and flag that we have changed the mode
if (!_glfwLibrary.X11.FS.modeChanged) if (!_glfwLibrary.X11.FS.modeChanged)
{ {
_glfwLibrary.X11.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwLibrary.X11.FS.oldRotation); _glfwLibrary.X11.FS.oldSizeID = XRRConfigCurrentConfiguration(sc, &_glfwLibrary.X11.FS.oldRotation);
_glfwLibrary.X11.FS.oldWidth = DisplayWidth(_glfwLibrary.X11.display, screen); _glfwLibrary.X11.FS.oldWidth = DisplayWidth(_glfwLibrary.X11.display,
_glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display, screen); _glfwLibrary.X11.screen);
_glfwLibrary.X11.FS.oldHeight = DisplayHeight(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen);
_glfwLibrary.X11.FS.modeChanged = GL_TRUE; _glfwLibrary.X11.FS.modeChanged = GL_TRUE;
} }
@ -214,21 +216,32 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
int modecount; int modecount;
// Get a list of all available display modes // Get a list of all available display modes
XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, XF86VidModeGetAllModeLines(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen,
&modecount, &modelist); &modecount, &modelist);
// Unlock mode switch if necessary // Unlock mode switch if necessary
if (_glfwLibrary.X11.FS.modeChanged) 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 // 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) // 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 // 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 // Remember old mode and flag that we have changed the mode
if (!_glfwLibrary.X11.FS.modeChanged) if (!_glfwLibrary.X11.FS.modeChanged)
@ -247,15 +260,15 @@ void _glfwSetVideoModeMODE(int screen, int mode, int rate)
// Change the current video mode // 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; int bestmode;
// Find a best match mode // Find a best match mode
bestmode = _glfwGetClosestVideoMode(screen, width, height, rate); bestmode = _glfwGetClosestVideoMode(width, height, rate);
// Change mode // 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 // Restore the previously saved (original) video mode
//======================================================================== //========================================================================
void _glfwRestoreVideoMode(int screen) void _glfwRestoreVideoMode(void)
{ {
if (_glfwLibrary.X11.FS.modeChanged) if (_glfwLibrary.X11.FS.modeChanged)
{ {
@ -292,11 +305,13 @@ void _glfwRestoreVideoMode(int screen)
{ {
#if defined(_GLFW_HAS_XF86VIDMODE) #if defined(_GLFW_HAS_XF86VIDMODE)
// Unlock mode switch // 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 // Change the video mode back to the old mode
XF86VidModeSwitchToMode(_glfwLibrary.X11.display, XF86VidModeSwitchToMode(_glfwLibrary.X11.display,
screen, _glfwLibrary.X11.screen,
&_glfwLibrary.X11.FS.oldMode); &_glfwLibrary.X11.FS.oldMode);
#endif /*_GLFW_HAS_XF86VIDMODE*/ #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 _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount)
{ {
int count, k, l, r, g, b, rgba, gl; int count, k, l, r, g, b, rgba, gl;
int depth, screen; int depth;
XVisualInfo* vislist; XVisualInfo* vislist;
XVisualInfo dummy; XVisualInfo dummy;
int viscount, rgbcount, rescount; int viscount, rgbcount, rescount;
@ -354,7 +369,7 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
return 0; return 0;
} }
rgbarray = (int*) _glfwMalloc(sizeof(int) * viscount); rgbarray = (int*) malloc(sizeof(int) * viscount);
rgbcount = 0; rgbcount = 0;
// Build RGB array // Build RGB array
@ -387,6 +402,8 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
} }
} }
XFree(vislist);
rescount = 0; rescount = 0;
resarray = NULL; resarray = NULL;
@ -399,7 +416,7 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
unsigned int a; unsigned int a;
resource = XRRGetScreenResources(_glfwLibrary.X11.display, _glfwLibrary.X11.root); 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++) for (k = 0; k < monitor->X11.output->nmode; k++)
{ {
@ -434,9 +451,11 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
XF86VidModeModeInfo** modelist; XF86VidModeModeInfo** modelist;
int modecount, width, height; 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++) for (k = 0; k < modecount; k++)
{ {
@ -465,10 +484,12 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
if (!resarray) if (!resarray)
{ {
rescount = 1; 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].width = DisplayWidth(_glfwLibrary.X11.display,
resarray[0].height = DisplayHeight(_glfwLibrary.X11.display, screen); _glfwLibrary.X11.screen);
resarray[0].height = DisplayHeight(_glfwLibrary.X11.display,
_glfwLibrary.X11.screen);
} }
// Build permutations of colors and resolutions // Build permutations of colors and resolutions
@ -486,10 +507,8 @@ int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int max
} }
} }
XFree(vislist); free(resarray);
free(rgbarray);
_glfwFree(resarray);
_glfwFree(rgbarray);
return count; return count;
} }

View File

@ -33,6 +33,74 @@
#include <string.h> #include <string.h>
//////////////////////////////////////////////////////////////////////////
////// 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 ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -43,6 +111,15 @@
void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) 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 && if (_glfwLibrary.X11.RandR.available &&
!_glfwLibrary.X11.RandR.gammaBroken) !_glfwLibrary.X11.RandR.gammaBroken)
{ {
@ -85,6 +162,15 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
void _glfwPlatformSetGammaRamp(const 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 && if (_glfwLibrary.X11.RandR.available &&
!_glfwLibrary.X11.RandR.gammaBroken) !_glfwLibrary.X11.RandR.gammaBroken)
{ {

View File

@ -30,37 +30,9 @@
#include "internal.h" #include "internal.h"
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <limits.h>
//========================================================================
// 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
}
//======================================================================== //========================================================================
@ -79,7 +51,11 @@ static int keyCodeToGLFWKeyCode(int keyCode)
// Note: This way we always force "NumLock = ON", which is intentional // Note: This way we always force "NumLock = ON", which is intentional
// since the returned key code should correspond to a physical // since the returned key code should correspond to a physical
// location. // location.
#if defined(_GLFW_HAS_XKB)
keySym = XkbKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 1, 0);
#else
keySym = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 1); keySym = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 1);
#endif
switch (keySym) switch (keySym)
{ {
case XK_KP_0: return GLFW_KEY_KP_0; 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 // Now try pimary keysym for function keys (non-printable keys). These
// should not be layout dependent (i.e. US layout and international // should not be layout dependent (i.e. US layout and international
// layouts should give the same result). // 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); keySym = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 0);
#endif
switch (keySym) switch (keySym)
{ {
case XK_Escape: return GLFW_KEY_ESCAPE; case XK_Escape: return GLFW_KEY_ESCAPE;
@ -252,10 +233,8 @@ static void updateKeyCodeLUT(void)
int keyCode; int keyCode;
// Clear the LUT // Clear the LUT
for (keyCode = 0; keyCode < 256; ++keyCode) for (keyCode = 0; keyCode < 256; keyCode++)
{
_glfwLibrary.X11.keyCodeLUT[keyCode] = -1; _glfwLibrary.X11.keyCodeLUT[keyCode] = -1;
}
#if defined(_GLFW_HAS_XKB) #if defined(_GLFW_HAS_XKB)
// If the Xkb extension is available, use it to determine physical key // 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) if (_glfwLibrary.X11.Xkb.available)
{ {
int i, keyCodeGLFW; int i, keyCodeGLFW;
char name[XkbKeyNameLength+1]; char name[XkbKeyNameLength + 1];
XkbDescPtr descr; XkbDescPtr descr;
// Get keyboard description // Get keyboard description
@ -275,10 +254,9 @@ static void updateKeyCodeLUT(void)
for (keyCode = descr->min_key_code; keyCode <= descr->max_key_code; ++keyCode) for (keyCode = descr->min_key_code; keyCode <= descr->max_key_code; ++keyCode)
{ {
// Get the key name // 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[i] = descr->names->keys[keyCode].name[i];
}
name[XkbKeyNameLength] = 0; name[XkbKeyNameLength] = 0;
// Map the key name to a GLFW key code. Note: We only map printable // 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 // Update the key code LUT
if ((keyCode >= 0) && (keyCode < 256)) if ((keyCode >= 0) && (keyCode < 256))
{
_glfwLibrary.X11.keyCodeLUT[keyCode] = keyCodeGLFW; _glfwLibrary.X11.keyCodeLUT[keyCode] = keyCodeGLFW;
}
} }
// Free the keyboard description // Free the keyboard description
@ -349,7 +325,7 @@ static void updateKeyCodeLUT(void)
// Translate the un-translated key codes using traditional X11 KeySym // Translate the un-translated key codes using traditional X11 KeySym
// lookups // lookups
for (keyCode = 0; keyCode < 256; ++keyCode) for (keyCode = 0; keyCode < 256; keyCode++)
{ {
if (_glfwLibrary.X11.keyCodeLUT[keyCode] < 0) 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 // Initialize X11 display and look for supported X11 extensions
//======================================================================== //========================================================================
@ -411,22 +533,6 @@ static GLboolean initDisplay(void)
_glfwLibrary.X11.RandR.available = GL_FALSE; _glfwLibrary.X11.RandR.available = GL_FALSE;
#endif /*_GLFW_HAS_XRANDR*/ #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 // Check if Xkb is supported on this display
#if defined(_GLFW_HAS_XKB) #if defined(_GLFW_HAS_XKB)
_glfwLibrary.X11.Xkb.majorVersion = 1; _glfwLibrary.X11.Xkb.majorVersion = 1;
@ -447,65 +553,30 @@ static GLboolean initDisplay(void)
// the keyboard mapping. // the keyboard mapping.
updateKeyCodeLUT(); 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; 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) // Create a blank cursor (for locked mouse mode)
//======================================================================== //========================================================================
@ -545,9 +616,6 @@ static Cursor createNULLCursor(void)
static void terminateDisplay(void) static void terminateDisplay(void)
{ {
if (_glfwLibrary.originalRampSize)
_glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
if (_glfwLibrary.X11.display) if (_glfwLibrary.X11.display)
{ {
XCloseDisplay(_glfwLibrary.X11.display); XCloseDisplay(_glfwLibrary.X11.display);
@ -569,13 +637,15 @@ int _glfwPlatformInit(void)
if (!initDisplay()) if (!initDisplay())
return GL_FALSE; return GL_FALSE;
initGammaRamp(); _glfwInitGammaRamp();
if (!_glfwInitOpenGL())
return GL_FALSE;
initEWMH();
_glfwLibrary.X11.cursor = createNULLCursor(); _glfwLibrary.X11.cursor = createNULLCursor();
// Try to load libGL.so if necessary
initLibraries();
_glfwInitJoysticks(); _glfwInitJoysticks();
_glfwInitMonitors(); _glfwInitMonitors();
@ -599,20 +669,19 @@ int _glfwPlatformTerminate(void)
_glfwLibrary.X11.cursor = (Cursor) 0; _glfwLibrary.X11.cursor = (Cursor) 0;
} }
_glfwTerminateGammaRamp();
terminateDisplay(); terminateDisplay();
_glfwTerminateMonitors(); _glfwTerminateMonitors();
_glfwTerminateJoysticks(); _glfwTerminateJoysticks();
// Unload libGL.so if necessary _glfwTerminateOpenGL();
#ifdef _GLFW_DLOPEN_LIBGL
if (_glfwLibrary.X11.libGL != NULL) // Free clipboard memory
{ if (_glfwLibrary.X11.selection.string)
dlclose(_glfwLibrary.X11.libGL); free(_glfwLibrary.X11.selection.string);
_glfwLibrary.X11.libGL = NULL;
}
#endif
return GL_TRUE; return GL_TRUE;
} }
@ -655,6 +724,9 @@ const char* _glfwPlatformGetVersionString(void)
" Linux-joystick-API" " Linux-joystick-API"
#else #else
" no-joystick-support" " no-joystick-support"
#endif
#if defined(_GLFW_BUILD_DLL)
" shared"
#endif #endif
; ;

View File

@ -43,13 +43,13 @@ _GLFWmonitor** _glfwCreateMonitor(_GLFWmonitor** current,
XRROutputInfo* outputInfo, XRROutputInfo* outputInfo,
XRRCrtcInfo* crtcInfo) XRRCrtcInfo* crtcInfo)
{ {
*current = _glfwMalloc(sizeof(_GLFWmonitor)); *current = malloc(sizeof(_GLFWmonitor));
memset(*current, 0, sizeof(_GLFWmonitor)); memset(*current, 0, sizeof(_GLFWmonitor));
(*current)->physicalWidth = outputInfo->mm_width; (*current)->physicalWidth = outputInfo->mm_width;
(*current)->physicalHeight = outputInfo->mm_height; (*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); memcpy((*current)->name, outputInfo->name, strlen(outputInfo->name) + 1);
(*current)->name[strlen(outputInfo->name)] = '\0'; (*current)->name[strlen(outputInfo->name)] = '\0';
@ -71,8 +71,8 @@ _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor)
XRRFreeOutputInfo(monitor->X11.output); XRRFreeOutputInfo(monitor->X11.output);
#endif /*_GLFW_HAS_XRANDR*/ #endif /*_GLFW_HAS_XRANDR*/
_glfwFree(monitor->name); free(monitor->name);
_glfwFree(monitor); free(monitor);
return result; return result;
} }

View File

@ -30,15 +30,656 @@
#include "internal.h" #include "internal.h"
#include <string.h>
#include <stdlib.h>
// This is the only glXGetProcAddress variant not declared by glxext.h // This is the only glXGetProcAddress variant not declared by glxext.h
void (*glXGetProcAddressEXT(const GLubyte* procName))(); 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 ////// ////// 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 // Make the OpenGL context associated with the specified window current
//======================================================================== //========================================================================
@ -75,14 +716,14 @@ void _glfwPlatformSwapInterval(int interval)
{ {
_GLFWwindow* window = _glfwLibrary.currentWindow; _GLFWwindow* window = _glfwLibrary.currentWindow;
if (window->GLX.EXT_swap_control) if (_glfwLibrary.GLX.EXT_swap_control)
{ {
window->GLX.SwapIntervalEXT(_glfwLibrary.X11.display, _glfwLibrary.GLX.SwapIntervalEXT(_glfwLibrary.X11.display,
window->X11.handle, window->X11.handle,
interval); interval);
} }
else if (window->GLX.SGI_swap_control) else if (_glfwLibrary.GLX.SGI_swap_control)
window->GLX.SwapIntervalSGI(interval); _glfwLibrary.GLX.SwapIntervalSGI(interval);
} }
@ -111,9 +752,9 @@ int _glfwPlatformExtensionSupported(const char* extension)
// Get the function pointer to an OpenGL function // 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);
} }

View File

@ -75,17 +75,31 @@
#elif defined(_GLFW_HAS_GLXGETPROCADDRESSEXT) #elif defined(_GLFW_HAS_GLXGETPROCADDRESSEXT)
#define _glfw_glXGetProcAddress(x) glXGetProcAddressEXT(x) #define _glfw_glXGetProcAddress(x) glXGetProcAddressEXT(x)
#elif defined(_GLFW_HAS_DLOPEN) #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 #define _GLFW_DLOPEN_LIBGL
#else #else
#error "No OpenGL entry point retrieval mechanism was enabled" #error "No OpenGL entry point retrieval mechanism was enabled"
#endif #endif
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 X11 #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 X11
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 X11 #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 // GLFW platform specific types
@ -102,27 +116,9 @@ typedef intptr_t GLFWintptr;
//------------------------------------------------------------------------ //------------------------------------------------------------------------
typedef struct _GLFWcontextGLX typedef struct _GLFWcontextGLX
{ {
GLXFBConfigID fbconfigID; // ID of selected GLXFBConfig
GLXContext context; // OpenGL rendering context GLXContext context; // OpenGL rendering context
XVisualInfo* visual; // Visual for selected GLXFBConfig 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; } _GLFWcontextGLX;
@ -134,16 +130,8 @@ typedef struct _GLFWwindowX11
// Platform specific window resources // Platform specific window resources
Colormap colormap; // Window colormap Colormap colormap; // Window colormap
Window handle; // Window handle 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 // Various platform specific internal variables
GLboolean hasEWMH; // True if window manager supports EWMH
GLboolean overrideRedirect; // True if window is OverrideRedirect GLboolean overrideRedirect; // True if window is OverrideRedirect
GLboolean keyboardGrabbed; // True if keyboard is currently grabbed GLboolean keyboardGrabbed; // True if keyboard is currently grabbed
GLboolean cursorGrabbed; // True if cursor 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 typedef struct _GLFWlibraryX11
{ {
@ -164,8 +152,16 @@ typedef struct _GLFWlibraryX11
Window root; Window root;
Cursor cursor; // Invisible cursor for hidden cursor Cursor cursor; // Invisible cursor for hidden cursor
// Server-side GLX version Atom wmDeleteWindow; // WM_DELETE_WINDOW atom
int glxMajor, glxMinor; 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 { struct {
GLboolean available; GLboolean available;
@ -224,10 +220,49 @@ typedef struct _GLFWlibraryX11
uint64_t base; uint64_t base;
} timer; } 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) #if defined(_GLFW_DLOPEN_LIBGL)
void* libGL; // dlopen handle for libGL.so void* libGL; // dlopen handle for libGL.so
#endif #endif
} _GLFWlibraryX11; } _GLFWlibraryGLX;
//------------------------------------------------------------------------ //------------------------------------------------------------------------
@ -264,11 +299,24 @@ typedef struct _GLFWmonitorX11
// Time // Time
void _glfwInitTimer(void); 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 // Fullscreen support
int _glfwGetClosestVideoMode(int screen, int* width, int* height, int* rate); int _glfwGetClosestVideoMode(int* width, int* height, int* rate);
void _glfwSetVideoModeMODE(int screen, int mode, int rate); void _glfwSetVideoModeMODE(int mode, int rate);
void _glfwSetVideoMode(int screen, int* width, int* height, int* rate); void _glfwSetVideoMode(int* width, int* height, int* rate);
void _glfwRestoreVideoMode(int screen); void _glfwRestoreVideoMode(void);
// Joystick input // Joystick input
void _glfwInitJoysticks(void); void _glfwInitJoysticks(void);
@ -281,5 +329,11 @@ _GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor);
// Unicode support // Unicode support
long _glfwKeySym2Unicode(KeySym keysym); long _glfwKeySym2Unicode(KeySym keysym);
// Clipboard handling
GLboolean _glfwReadSelection(XSelectionEvent* request);
Atom _glfwWriteSelection(XSelectionRequestEvent* request);
// Event processing
void _glfwProcessPendingEvents(void);
#endif // _platform_h_ #endif // _platform_h_

View File

@ -30,6 +30,7 @@
#include "internal.h" #include "internal.h"
#include <sys/time.h>
#include <time.h> #include <time.h>
@ -39,7 +40,7 @@
static uint64_t getRawTime(void) static uint64_t getRawTime(void)
{ {
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) #if defined(CLOCK_MONOTONIC)
if (_glfwLibrary.X11.timer.monotonic) if (_glfwLibrary.X11.timer.monotonic)
{ {
struct timespec ts; struct timespec ts;
@ -64,7 +65,7 @@ static uint64_t getRawTime(void)
void _glfwInitTimer(void) void _glfwInitTimer(void)
{ {
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) #if defined(CLOCK_MONOTONIC)
struct timespec ts; struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)

File diff suppressed because it is too large Load Diff

View File

@ -1,69 +1,58 @@
set(STATIC_DEPS libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY}) link_libraries(glfw ${OPENGL_glu_LIBRARY})
set(SHARED_DEPS libglfwShared ${GLFW_LIBRARIES} ${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 include_directories(${GLFW_SOURCE_DIR}/include
${GLFW_SOURCE_DIR}/support ${GLFW_SOURCE_DIR}/support
${OPENGL_INCLUDE_DIR}) ${OPENGL_INCLUDE_DIR})
add_executable(clipboard clipboard.c getopt.c)
add_executable(defaults defaults.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) add_executable(events events.c)
target_link_libraries(events ${STATIC_DEPS})
add_executable(fsaa fsaa.c getopt.c) add_executable(fsaa fsaa.c getopt.c)
target_link_libraries(fsaa ${STATIC_DEPS})
add_executable(fsfocus fsfocus.c) add_executable(fsfocus fsfocus.c)
target_link_libraries(fsfocus ${STATIC_DEPS})
add_executable(gamma gamma.c getopt.c) add_executable(gamma gamma.c getopt.c)
target_link_libraries(gamma ${STATIC_DEPS})
add_executable(glfwinfo glfwinfo.c getopt.c) add_executable(glfwinfo glfwinfo.c getopt.c)
target_link_libraries(glfwinfo ${STATIC_DEPS})
add_executable(iconify iconify.c getopt.c) add_executable(iconify iconify.c getopt.c)
target_link_libraries(iconify ${STATIC_DEPS})
add_executable(joysticks joysticks.c) add_executable(joysticks joysticks.c)
target_link_libraries(joysticks ${STATIC_DEPS}) add_executable(modes modes.c getopt.c)
add_executable(listmodes listmodes.c)
target_link_libraries(listmodes ${STATIC_DEPS})
add_executable(peter peter.c) add_executable(peter peter.c)
target_link_libraries(peter ${STATIC_DEPS})
add_executable(reopen reopen.c) add_executable(reopen reopen.c)
target_link_libraries(reopen ${STATIC_DEPS})
add_executable(accuracy WIN32 MACOSX_BUNDLE accuracy.c) 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) 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) 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) 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) 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(WINDOWS_BINARIES accuracy sharing tearing title windows)
set(CONSOLE_BINARIES defaults events fsaa fsfocus gamma glfwinfo iconify set(CONSOLE_BINARIES clipboard defaults events fsaa fsfocus gamma glfwinfo
joysticks listmodes peter reopen) iconify joysticks modes peter reopen)
if(MSVC) if (MSVC)
# Tell MSVC to use main instead of WinMain for Windows subsystem executables # Tell MSVC to use main instead of WinMain for Windows subsystem executables
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
LINK_FLAGS "/ENTRY:mainCRTStartup") LINK_FLAGS "/ENTRY:mainCRTStartup")
endif(MSVC) 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()

View File

@ -29,6 +29,7 @@
// //
//======================================================================== //========================================================================
#define GLFW_INCLUDE_GLU
#include <GL/glfw3.h> #include <GL/glfw3.h>
#include <stdio.h> #include <stdio.h>
@ -49,7 +50,7 @@ static void window_size_callback(GLFWwindow window, int width, int height)
gluOrtho2D(0.f, window_width, 0.f, window_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_x = x;
cursor_y = y; cursor_y = y;
@ -59,7 +60,7 @@ int main(void)
{ {
GLFWwindow window; GLFWwindow window;
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -74,7 +75,7 @@ int main(void)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
glfwSetMousePosCallback(mouse_position_callback); glfwSetCursorPosCallback(cursor_position_callback);
glfwSetWindowSizeCallback(window_size_callback); glfwSetWindowSizeCallback(window_size_callback);
glfwSwapInterval(1); glfwSwapInterval(1);

153
tests/clipboard.c Normal file
View File

@ -0,0 +1,153 @@
//========================================================================
// Clipboard test program
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
//
// This program is used to test the clipboard functionality.
//
//========================================================================
#include <GL/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#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);
}

View File

@ -69,7 +69,7 @@ int main(void)
int i, width, height; int i, width, height;
GLFWwindow window; GLFWwindow window;
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@ -1,91 +0,0 @@
//========================================================================
// Dynamic linking test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
//
// This test came about as the result of bug #3060461
//
//========================================================================
#define GLFW_DLL
#include <GL/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
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);
}

View File

@ -40,8 +40,9 @@
#include <ctype.h> #include <ctype.h>
#include <locale.h> #include <locale.h>
static GLboolean keyrepeat = 0; static GLboolean keyrepeat = GL_FALSE;
static GLboolean systemkeys = 1; static GLboolean systemkeys = GL_TRUE;
static GLboolean closeable = GL_TRUE;
static unsigned int counter = 0; static unsigned int counter = 0;
static const char* get_key_name(int key) 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) static int window_close_callback(GLFWwindow window)
{ {
printf("%08x at %0.3f: Window close\n", counter++, glfwGetTime()); printf("%08x at %0.3f: Window close\n", counter++, glfwGetTime());
return 1; return closeable;
} }
static void window_refresh_callback(GLFWwindow window) 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)); 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) 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"); printf("(( system keys %s ))\n", systemkeys ? "enabled" : "disabled");
break; 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, ""); setlocale(LC_ALL, "");
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -367,7 +384,8 @@ int main(void)
glfwSetWindowFocusCallback(window_focus_callback); glfwSetWindowFocusCallback(window_focus_callback);
glfwSetWindowIconifyCallback(window_iconify_callback); glfwSetWindowIconifyCallback(window_iconify_callback);
glfwSetMouseButtonCallback(mouse_button_callback); glfwSetMouseButtonCallback(mouse_button_callback);
glfwSetMousePosCallback(mouse_position_callback); glfwSetCursorPosCallback(cursor_position_callback);
glfwSetCursorEnterCallback(cursor_enter_callback);
glfwSetScrollCallback(scroll_callback); glfwSetScrollCallback(scroll_callback);
glfwSetKeyCallback(key_callback); glfwSetKeyCallback(key_callback);
glfwSetCharCallback(char_callback); glfwSetCharCallback(char_callback);

View File

@ -29,6 +29,7 @@
// //
//======================================================================== //========================================================================
#define GLFW_INCLUDE_GLU
#include <GL/glfw3.h> #include <GL/glfw3.h>
#include <GL/glext.h> #include <GL/glext.h>
@ -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())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@ -75,7 +75,7 @@ int main(void)
{ {
GLFWwindow window; GLFWwindow window;
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@ -35,11 +35,20 @@
#include "getopt.h" #include "getopt.h"
#define STEP_SIZE 0.1f
static GLfloat gamma = 1.0f; static GLfloat gamma = 1.0f;
static void usage(void) 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) 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) switch (key)
{ {
case GLFW_KEY_ESCAPE: case GLFW_KEY_ESCAPE:
{
glfwCloseWindow(window); glfwCloseWindow(window);
break; break;
}
case GLFW_KEY_KP_ADD: case GLFW_KEY_KP_ADD:
case GLFW_KEY_Q: case GLFW_KEY_Q:
gamma += 0.1f; {
printf("Gamma: %f\n", gamma); set_gamma(gamma + STEP_SIZE);
glfwSetGamma(gamma);
break; break;
}
case GLFW_KEY_KP_SUBTRACT: case GLFW_KEY_KP_SUBTRACT:
case GLFW_KEY_W: case GLFW_KEY_W:
gamma -= 0.1f; {
printf("Gamma: %f\n", gamma); if (gamma - STEP_SIZE > 0.f)
glfwSetGamma(gamma); set_gamma(gamma - STEP_SIZE);
break; 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())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -124,7 +139,7 @@ int main(int argc, char** argv)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("Gamma: %f\n", gamma); set_gamma(1.f);
glfwSwapInterval(1); glfwSwapInterval(1);
glfwSetKeyCallback(key_callback); glfwSetKeyCallback(key_callback);

View File

@ -51,7 +51,7 @@
static void usage(void) 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 profiles: " PROFILE_NAME_CORE " " PROFILE_NAME_COMPAT " " PROFILE_NAME_ES2 "\n");
printf("available strategies: " STRATEGY_NAME_NONE " " STRATEGY_NAME_LOSE "\n"); printf("available strategies: " STRATEGY_NAME_NONE " " STRATEGY_NAME_LOSE "\n");
} }
@ -183,7 +183,7 @@ int main(int argc, char** argv)
glfwSetErrorCallback(error_callback); glfwSetErrorCallback(error_callback);
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -263,7 +263,7 @@ int main(int argc, char** argv)
if (major > 3 || (major == 3 && minor >= 2)) if (major > 3 || (major == 3 && minor >= 2))
{ {
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); 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", printf("OpenGL profile parsed by GLFW: %s\n",
get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE))); get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE)));

View File

@ -62,6 +62,8 @@ static void key_callback(GLFWwindow window, int key, int action)
static void size_callback(GLFWwindow window, int width, int height) 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); 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())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@ -1,142 +1,216 @@
/*======================================================================== //========================================================================
* This is a small test application for GLFW. // Joystick input test
* joystick input test. // Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
*========================================================================*/ //
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
//
// This test displays the state of every button and axis of every connected
// joystick and/or gamepad
//
//========================================================================
#include <GL/glfw3.h> #include <GL/glfw3.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#define MAX_AXES 10 typedef struct Joystick
#define MAX_BUTTONS 30
struct JoystickState
{ {
int present; GLboolean present;
int num_axes; float* axes;
int num_buttons; unsigned char* buttons;
float axes[MAX_AXES]; int axis_count;
unsigned char buttons[MAX_BUTTONS]; int button_count;
}; } Joystick;
static struct JoystickState states[GLFW_JOYSTICK_LAST + 1]; static Joystick joysticks[GLFW_JOYSTICK_LAST - GLFW_JOYSTICK_1 + 1];
int running; static int joystick_count = 0;
int keyrepeat = 0;
int systemkeys = 1;
static void window_size_callback(GLFWwindow window, int width, int height)
/*========================================================================
* Retrieve joystick states
*========================================================================*/
static void updateJoysticksState(void)
{ {
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); float value = j->axes[i] / 2.f + 0.5f;
states[joy].present = glfwGetJoystickParam(joy, GLFW_PRESENT);
if (states[joy].present == GL_TRUE) 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); draw_joystick(j,
states[joy].num_buttons = glfwGetJoystickButtons(joy, states[joy].buttons, MAX_BUTTONS); 0, i * height / joystick_count,
width, height / joystick_count);
} }
} }
} }
/*======================================================================== static void refresh_joysticks(void)
* Print out the state of all joysticks on the standard output
*========================================================================*/
static void displayJoysticksState(void)
{ {
int joy;
int i; 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]); j->axis_count = axis_count;
for (i = 1; i < states[joy].num_axes; i++) j->axes = realloc(j->axes, j->axis_count * sizeof(float));
printf(", %.3f", states[joy].axes[i]);
printf("\n");
} }
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')); j->button_count = button_count;
j->buttons = realloc(j->buttons, j->button_count);
for (i = 1; i < states[joy].num_buttons; i++) }
printf(", %02d => %c", i, ((states[joy].buttons[i] == GLFW_PRESS) ? 'P' : 'R'));
glfwGetJoystickButtons(GLFW_JOYSTICK_1 + i, j->buttons, j->button_count);
printf("\n");
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) int main(void)
{ {
double start; GLFWwindow window;
double t;
double update;
/* Initialise GLFW */ memset(joysticks, 0, sizeof(joysticks));
if (!glfwInit(NULL))
if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
printf("The program will work for 20 seconds and display every seconds the state of the joysticks\n"); window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Joystick Test", NULL);
printf("Your computer is going to be very slow as the program is doing an active loop .....\n"); if (!window)
start = glfwGetTime();
update = start;
/* print the initial state of all joysticks */
updateJoysticksState();
printf("\n");
displayJoysticksState();
running = GL_TRUE;
/* Main loop */
while (running)
{ {
/* Get time */ glfwTerminate();
t = glfwGetTime();
/* Display the state of all connected joysticks every secons */ fprintf(stderr, "Failed to open GLFW window: %s\n", glfwErrorString(glfwGetError()));
if ((t - update) > 1.0) exit(EXIT_FAILURE);
{
update = t;
printf("\n");
updateJoysticksState();
printf("\n");
displayJoysticksState();
}
/* Check if the window was closed */
if ((t - start) > 20.0)
running = GL_FALSE;
} }
/* Close OpenGL window and terminate GLFW */ glfwSetWindowSizeCallback(window_size_callback);
glfwTerminate(); glfwSwapInterval(1);
return 0; while (glfwIsWindow(window))
{
glClear(GL_COLOR_BUFFER_BIT);
refresh_joysticks();
draw_joysticks();
glfwSwapBuffers();
glfwPollEvents();
}
glfwTerminate();
exit(EXIT_SUCCESS);
} }

View File

@ -1,62 +0,0 @@
//========================================================================
// This is a small test application for GLFW.
// The program lists all available fullscreen video modes.
//========================================================================
#include <GL/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
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);
}

257
tests/modes.c Normal file
View File

@ -0,0 +1,257 @@
//========================================================================
// Video mode test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
//
// This test enumerates or verifies video modes
//
//========================================================================
#include <GL/glfw3.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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);
}

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// Mouse cursor bug test // Cursor input bug test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
// //
// This software is provided 'as-is', without any express or implied // 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 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) 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_x = x;
cursor_y = y; cursor_y = y;
} }
@ -69,7 +69,7 @@ static void key_callback(GLFWwindow window, int key, int action)
case GLFW_KEY_SPACE: case GLFW_KEY_SPACE:
{ {
if (action == GLFW_PRESS) if (action == GLFW_PRESS)
toggle_mouse_cursor(window); toggle_cursor(window);
break; break;
} }
@ -98,11 +98,11 @@ static GLboolean open_window(void)
if (!window_handle) if (!window_handle)
return GL_FALSE; return GL_FALSE;
glfwGetMousePos(window_handle, &cursor_x, &cursor_y); glfwGetCursorPos(window_handle, &cursor_x, &cursor_y);
printf("Mouse position: %i %i\n", cursor_x, cursor_y); printf("Cursor position: %i %i\n", cursor_x, cursor_y);
glfwSetWindowSizeCallback(window_size_callback); glfwSetWindowSizeCallback(window_size_callback);
glfwSetMousePosCallback(mouse_position_callback); glfwSetCursorPosCallback(cursor_position_callback);
glfwSetKeyCallback(key_callback); glfwSetKeyCallback(key_callback);
glfwSwapInterval(1); glfwSwapInterval(1);
@ -111,7 +111,7 @@ static GLboolean open_window(void)
int main(void) int main(void)
{ {
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@ -84,7 +84,7 @@ static GLboolean open_window(int width, int height, int mode)
{ {
double base; double base;
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
return GL_FALSE; return GL_FALSE;

View File

@ -27,6 +27,7 @@
// //
//======================================================================== //========================================================================
#define GLFW_INCLUDE_GLU
#include <GL/glfw3.h> #include <GL/glfw3.h>
#include <stdio.h> #include <stdio.h>
@ -92,8 +93,6 @@ static void draw_quad(GLuint texture)
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor3f(0.6f, 0.f, 0.6f);
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f); glTexCoord2f(0.f, 0.f);
@ -117,7 +116,7 @@ int main(int argc, char** argv)
GLuint texture; GLuint texture;
int x, y; int x, y;
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -142,6 +141,11 @@ int main(int argc, char** argv)
exit(EXIT_FAILURE); 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 // Put the second window to the right of the first one
glfwGetWindowPos(windows[0], &x, &y); glfwGetWindowPos(windows[0], &x, &y);
glfwSetWindowPos(windows[1], x + WIDTH + 50, y); glfwSetWindowPos(windows[1], x + WIDTH + 50, y);

View File

@ -34,23 +34,42 @@
#include <stdlib.h> #include <stdlib.h>
#include <math.h> #include <math.h>
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) static void window_size_callback(GLFWwindow window, int width, int height)
{ {
glViewport(0, 0, width, 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) int main(void)
{ {
float position; float position;
GLFWwindow window; GLFWwindow window;
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Tearing Detector", NULL); window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "", NULL);
if (!window) if (!window)
{ {
glfwTerminate(); glfwTerminate();
@ -59,8 +78,10 @@ int main(void)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
set_swap_interval(1);
glfwSetWindowSizeCallback(window_size_callback); glfwSetWindowSizeCallback(window_size_callback);
glfwSwapInterval(1); glfwSetKeyCallback(key_callback);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f); glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f);

View File

@ -41,7 +41,7 @@ int main(void)
{ {
GLFWwindow window; GLFWwindow window;
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError()));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);

View File

@ -46,7 +46,7 @@ int main(void)
GLboolean running = GL_TRUE; GLboolean running = GL_TRUE;
GLFWwindow windows[4]; GLFWwindow windows[4];
if (!glfwInit(NULL)) if (!glfwInit())
{ {
fprintf(stderr, "Failed to initialize GLFW: %s\n", fprintf(stderr, "Failed to initialize GLFW: %s\n",
glfwErrorString(glfwGetError())); glfwErrorString(glfwGetError()));