diff --git a/.gitignore b/.gitignore index fad26de1..0496a03c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ src/libglfw.pc src/libglfw.so src/libglfw.a src/libglfw.dylib +src/glfw.lib +src/glfw.dll +src/glfwdll.lib examples/boing examples/gears examples/heightmap diff --git a/CMake/README.txt b/CMake/README.txt index d24854ed..9581f832 100644 --- a/CMake/README.txt +++ b/CMake/README.txt @@ -1,10 +1,19 @@ -This folder contains a collection of toolchains definition in order to -support cross compilation. The naming scheme is the following: +This directory contains a collection of toolchain definitions for cross +compilation, currently limited to compiling Win32 binaries on Linux. + +The toolchain file naming scheme is as follows: + host-system-compiler.cmake -to use this at the time you run the initial cmake command use the -following parameter - -DCMAKE_TOOLCHAIN_FILE=./toolchains/XXX-XXX-XXX.cmake - which maps to file in this folder. +To use these files you add a special parameter when configuring the source tree: + + cmake -DCMAKE_TOOLCHAIN_FILE= . + +For example, to use the Debian GNU/Linux MinGW package, run CMake like this: + + cmake -DCMAKE_TOOLCHAIN_FILE=CMake/linux-i586-mingw32msvc.cmake . + +For more details see this article: + + http://www.paraview.org/Wiki/CMake_Cross_Compiling -For more details see: http://www.paraview.org/Wiki/CMake_Cross_Compiling diff --git a/CMake/linux-amd64-mingw32msvc.cmake b/CMake/linux-amd64-mingw32msvc.cmake new file mode 100644 index 00000000..5b68540e --- /dev/null +++ b/CMake/linux-amd64-mingw32msvc.cmake @@ -0,0 +1,15 @@ +# Define the cross compilation environment for cross compiling from linux +# to Win64 it is to be used when Debian cross compilation toolchain is +# available. +SET(CMAKE_SYSTEM_NAME Windows) # Target system name +SET(CMAKE_SYSTEM_VERSION 1) # Not really used. +SET(CMAKE_C_COMPILER "amd64-mingw32msvc-gcc") +SET(CMAKE_CXX_COMPILER "amd64-mingw32msvc-g++") +SET(CMAKE_RANLIB "amd64-mingw32msvc-ranlib") + + +#Configure the behaviour of the find commands +SET(CMAKE_FIND_ROOT_PATH "/usr/amd64-mingw32msvc") +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/CMake/linux-mingw32msvc.cmake b/CMake/linux-i586-mingw32msvc.cmake similarity index 100% rename from CMake/linux-mingw32msvc.cmake rename to CMake/linux-i586-mingw32msvc.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e6554c5..522aaf76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,6 @@ project(GLFW C) -cmake_minimum_required(VERSION 2.4) -cmake_policy(VERSION 2.4) +cmake_minimum_required(VERSION 2.8) set(GLFW_VERSION_MAJOR "3") set(GLFW_VERSION_MINOR "0") @@ -12,106 +11,157 @@ set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON) option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) +option(BUILD_SHARED_LIBS "Build shared libraries" OFF) find_package(OpenGL REQUIRED) #-------------------------------------------------------------------- -# Set up GLFW for Win32 and WGL on Windows +# Enable all warnings on GCC, regardless of OS +#-------------------------------------------------------------------- +if (CMAKE_COMPILER_IS_GNUCC) + add_definitions(-Wall) +endif() + +#-------------------------------------------------------------------- +# Detect and select target platform #-------------------------------------------------------------------- if (WIN32) - message(STATUS "Building GLFW for WGL on a Win32 system") - - # Define the platform identifier set(_GLFW_WIN32_WGL 1) + message(STATUS "Building GLFW for WGL on a Win32 system") +elseif (UNIX AND APPLE) + set(_GLFW_COCOA_NSGL 1) + message(STATUS "Building GLFW for Cocoa and NSOpenGL on Mac OS X") +elseif (UNIX AND NOT APPLE) + set(_GLFW_X11_GLX 1) + message(STATUS "Building GLFW for X11 and GLX on a Unix-like system") +else() + message(FATAL_ERROR "No supported platform was detected") +endif() + +#-------------------------------------------------------------------- +# Set up GLFW for Win32 and WGL on Windows +#-------------------------------------------------------------------- +if (_GLFW_WIN32_WGL) # Set up library and include paths - list(APPEND GLFW_INCLUDE_DIR ${OPENGL_INCLUDE_DIR}) - list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY}) -endif (WIN32) + list(APPEND glfw_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR}) + list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY}) + + if (BUILD_SHARED_LIBS) + list(APPEND glfw_LIBRARIES winmm) + endif() +endif() #-------------------------------------------------------------------- # Set up GLFW for Xlib and GLX on Unix-like systems with X Windows #-------------------------------------------------------------------- -if (UNIX AND NOT APPLE) - message(STATUS "Building GLFW for X11 and GLX on a Unix-like system") - - # Define the platform identifier - set(_GLFW_X11_GLX 1) +if (_GLFW_X11_GLX) find_package(X11 REQUIRED) # Set up library and include paths - list(APPEND GLFW_INCLUDE_DIR ${X11_X11_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR}) - list(APPEND GLFW_LIBRARIES ${X11_X11_LIB} ${OPENGL_gl_LIBRARY}) + list(APPEND glfw_INCLUDE_DIRS ${X11_X11_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR}) + list(APPEND glfw_LIBRARIES ${X11_X11_LIB} ${OPENGL_gl_LIBRARY}) - find_library(MATH_LIBRARY m) - if (MATH_LIBRARY) - list(APPEND GLFW_LIBRARIES ${MATH_LIBRARY}) - endif(MATH_LIBRARY) - - find_library(RT_LIBRARY rt) - if (RT_LIBRARY) - list(APPEND GLFW_LIBRARIES ${RT_LIBRARY}) - endif(RT_LIBRARY) + set(GLFW_PKG_DEPS "gl x11") + set(GLFW_PKG_LIBS "") include(CheckFunctionExists) - include(CheckSymbolExists) - set(CMAKE_REQUIRED_LIBRARIES ${GLFW_LIBRARIES}) - # Check for XRandR (modern resolution switching extension) if (X11_Xrandr_FOUND) set(_GLFW_HAS_XRANDR 1) - list(APPEND GLFW_INCLUDE_DIR ${X11_Xrandr_INCLUDE_PATH}) - list(APPEND GLFW_LIBRARIES ${X11_Xrandr_LIB}) + list(APPEND glfw_INCLUDE_DIRS ${X11_Xrandr_INCLUDE_PATH}) + list(APPEND glfw_LIBRARIES ${X11_Xrandr_LIB}) + set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} xrandr") endif() # Check for Xf86VidMode (fallback legacy resolution switching extension) if (X11_xf86vmode_FOUND) set(_GLFW_HAS_XF86VIDMODE 1) - list(APPEND GLFW_INCLUDE_DIR ${X11_xf86vmode_INCLUDE_PATH}) + list(APPEND glfw_INCLUDE_DIRS ${X11_xf86vmode_INCLUDE_PATH}) + + # NOTE: This is a workaround for CMake bug 0006976 (missing + # X11_xf86vmode_LIB variable) + if (X11_xf86vmode_LIB) + list(APPEND glfw_LIBRARIES ${X11_xf86vmode_LIB}) + else() + list(APPEND glfw_LIBRARIES Xxf86vm) + endif() + + set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} xxf86vm") endif() # Check for Xkb (X keyboard extension) if (X11_Xkb_FOUND) set(_GLFW_HAS_XKB 1) - list(APPEND GLFW_INCLUDE_DIR ${X11_Xkb_INCLUDE_PATH}) + list(APPEND glfw_INCLUDE_DIR ${X11_Xkb_INCLUDE_PATH}) endif() - # Check for glXGetProcAddress + 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_function_exists(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS) if (NOT _GLFW_HAS_GLXGETPROCADDRESS) check_function_exists(glXGetProcAddressARB _GLFW_HAS_GLXGETPROCADDRESSARB) - endif (NOT _GLFW_HAS_GLXGETPROCADDRESS) + endif() if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB) check_function_exists(glXGetProcAddressEXT _GLFW_HAS_GLXGETPROCADDRESSEXT) - endif (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB) + endif() if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND NOT _GLFW_HAS_GLXGETPROCADDRESSEXT) message(WARNING "No glXGetProcAddressXXX variant found") - endif (NOT _GLFW_HAS_GLXGETPROCADDRESS AND - NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND - NOT _GLFW_HAS_GLXGETPROCADDRESSEXT) + + # Check for dlopen support as a fallback + + find_library(DL_LIBRARY dl) + mark_as_advanced(DL_LIBRARY) + if (DL_LIBRARY) + set(CMAKE_REQUIRED_LIBRARIES ${DL_LIBRARY}) + else() + set(CMAKE_REQUIRED_LIBRARIES "") + endif() + + check_function_exists(dlopen _GLFW_HAS_DLOPEN) + + if (NOT _GLFW_HAS_DLOPEN) + message(FATAL_ERROR "No entry point retrieval mechanism found") + endif() + + if (DL_LIBRARY) + list(APPEND glfw_LIBRARIES ${DL_LIBRARY}) + set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -ldl") + endif() + endif() if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(_GLFW_USE_LINUX_JOYSTICKS 1) - endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") -endif(UNIX AND NOT APPLE) + endif() +endif() #-------------------------------------------------------------------- # Set up GLFW for Cocoa and NSOpenGL on Mac OS X #-------------------------------------------------------------------- -if (UNIX AND APPLE) - message(STATUS "Building GLFW for Cocoa and NSOpenGL on Mac OS X") +if (_GLFW_COCOA_NSGL) - # Define the platform identifier - set(_GLFW_COCOA_NSGL 1) - - option(GLFW_BUILD_UNIVERSAL "Build the GLFW library and examples as Universal Binaries" FALSE) + option(GLFW_BUILD_UNIVERSAL "Build GLFW as a Universal Binary" OFF) # Universal build if (GLFW_BUILD_UNIVERSAL) @@ -121,17 +171,22 @@ if (UNIX AND APPLE) set(CMAKE_C_FLAGS "-mmacosx-version-min=10.5") else(GLFW_BUILD_UNIVERSAL) message(STATUS "Building GLFW only for the native architecture") - endif(GLFW_BUILD_UNIVERSAL) + endif() # Set up library and include paths find_library(COCOA_FRAMEWORK Cocoa) find_library(IOKIT_FRAMEWORK IOKit) find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation) - list(APPEND GLFW_LIBRARIES ${COCOA_FRAMEWORK}) - list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY}) - list(APPEND GLFW_LIBRARIES ${IOKIT_FRAMEWORK}) - list(APPEND GLFW_LIBRARIES ${CORE_FOUNDATION_FRAMEWORK}) -endif(UNIX AND APPLE) + list(APPEND glfw_LIBRARIES ${COCOA_FRAMEWORK} + ${OPENGL_gl_LIBRARY} + ${IOKIT_FRAMEWORK} + ${CORE_FOUNDATION_FRAMEWORK}) +endif() + +#-------------------------------------------------------------------- +# Export GLFW library dependencies +#-------------------------------------------------------------------- +set(GLFW_LIBRARIES ${glfw_LIBRARIES} CACHE STRING "Dependencies of GLFW") #-------------------------------------------------------------------- # Add subdirectories @@ -140,11 +195,11 @@ add_subdirectory(src) if (GLFW_BUILD_EXAMPLES) add_subdirectory(examples) -endif(GLFW_BUILD_EXAMPLES) +endif() if (GLFW_BUILD_TESTS) add_subdirectory(tests) -endif(GLFW_BUILD_TESTS) +endif() #-------------------------------------------------------------------- # Create shared configuration header @@ -160,9 +215,9 @@ install(DIRECTORY include/GL DESTINATION include FILES_MATCHING PATTERN glfw3.h) 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 +# The src directory's CMakeLists.txt file installs the library #-------------------------------------------------------------------- # -- Documentation generation @@ -175,7 +230,7 @@ configure_file("${GLFW_SOURCE_DIR}/docs/Doxyfile.in" # Uninstall operation # Don't generate this target if a higher-level project already has #-------------------------------------------------------------------- -if(NOT TARGET uninstall) +if (NOT TARGET uninstall) configure_file(${GLFW_SOURCE_DIR}/cmake_uninstall.cmake.in ${GLFW_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d511b22d..76135a92 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,34 +1,53 @@ -# This line is used to link with static libraries -# Note that the library list should be updated to be obtained from -# the main CMakeLists.txt -link_libraries(libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY}) + +link_libraries(glfw ${OPENGL_glu_LIBRARY}) + +if (BUILD_SHARED_LIBS) + add_definitions(-DGLFW_DLL) + link_libraries(${OPENGL_gl_LIBRARY}) +else() + link_libraries(${glfw_LIBRARIES}) +endif() include_directories(${GLFW_SOURCE_DIR}/include ${GLFW_SOURCE_DIR}/support ${OPENGL_INCLUDE_DIR}) -if(APPLE) - # Set fancy names for bundles - add_executable(Boing MACOSX_BUNDLE boing.c) - add_executable(Gears MACOSX_BUNDLE gears.c) - add_executable("Split View" MACOSX_BUNDLE splitview.c) - add_executable(Triangle MACOSX_BUNDLE triangle.c) - add_executable(Wave MACOSX_BUNDLE wave.c) -else(APPLE) - # Set boring names for executables - add_executable(boing WIN32 boing.c) - add_executable(gears WIN32 gears.c) - add_executable(heightmap WIN32 heightmap.c getopt.c) - add_executable(splitview WIN32 splitview.c) - add_executable(triangle WIN32 triangle.c) - add_executable(wave WIN32 wave.c) -endif(APPLE) +if (APPLE) + # Set fancy names for bundles + add_executable(Boing MACOSX_BUNDLE boing.c) + add_executable(Gears MACOSX_BUNDLE gears.c) + add_executable("Split View" MACOSX_BUNDLE splitview.c) + add_executable(Triangle MACOSX_BUNDLE triangle.c) + add_executable(Wave MACOSX_BUNDLE wave.c) -set(WINDOWS_BINARIES boing gears heightmap splitview triangle wave) + set_target_properties(Boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing") + set_target_properties(Gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears") + set_target_properties("Split View" PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Split View") + set_target_properties(Triangle PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Triangle") + set_target_properties(Wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave") +else() + # Set boring names for executables + add_executable(boing WIN32 boing.c) + add_executable(gears WIN32 gears.c) + add_executable(heightmap WIN32 heightmap.c getopt.c) + add_executable(splitview WIN32 splitview.c) + add_executable(triangle WIN32 triangle.c) + add_executable(wave WIN32 wave.c) +endif() -if(MSVC) - # Tell MSVC to use main instead of WinMain for Windows subsystem executables - set_target_properties(${WINDOWS_BINARIES} PROPERTIES - LINK_FLAGS "/ENTRY:mainCRTStartup") -endif(MSVC) +if (MSVC) + set(WINDOWS_BINARIES boing gears heightmap splitview triangle wave) + + # Tell MSVC to use main instead of WinMain for Windows subsystem executables + set_target_properties(${WINDOWS_BINARIES} PROPERTIES + LINK_FLAGS "/ENTRY:mainCRTStartup") +endif() + +if (APPLE) + set(BUNDLE_BINARIES Boing Gears "Split View" Triangle Wave) + + set_target_properties(${BUNDLE_BINARIES} PROPERTIES + MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} + MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}) +endif() diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index 5ad6f289..e6c9fc35 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -67,6 +67,12 @@ extern "C" { #endif #endif /* APIENTRY */ +/* TEMPORARY MinGW-w64 hacks. + */ +#if __MINGW64__ + #define WINAPI +#include +#endif /* The following three defines are here solely to make some Windows-based * files happy. Theoretically we could include , but @@ -113,7 +119,11 @@ extern "C" { /* ---------------- GLFW related system specific defines ----------------- */ -#if defined(_WIN32) && defined(GLFW_BUILD_DLL) +#if defined(GLFW_DLL) && defined(_GLFW_BUILD_DLL) + #error "You must not have both GLFW_DLL and _GLFW_BUILD_DLL defined" +#endif + +#if defined(_WIN32) && defined(_GLFW_BUILD_DLL) /* We are building a Win32 DLL */ #define GLFWAPI __declspec(dllexport) @@ -136,10 +146,6 @@ extern "C" { /* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ -/* Include the declaration of the size_t type used below. - */ -#include - /* Include standard OpenGL headers: GLFW uses GL_FALSE/GL_TRUE, and it is * convenient for the user to only have to include . This also * solves the problem with Windows and needing some diff --git a/readme.html b/readme.html index 5ab86c64..f631acd7 100644 --- a/readme.html +++ b/readme.html @@ -279,7 +279,7 @@ version of GLFW.

  • Added GLFW_INCLUDE_GL3 macro for telling the GLFW header to include gl3.h header instead of gl.h
  • Added windows simple multi-window test program
  • Added sharing simple OpenGL object sharing test program
  • -
  • Added dynamic simple dynamic linking test program
  • +
  • Added modes video mode enumeration and setting test program
  • Added a parameter to glfwOpenWindow for specifying a context the new window's context will share objects with
  • Added initial window title parameter to glfwOpenWindow
  • Added glfwSetGamma, glfwSetGammaRamp and glfwGetGammaRamp functions and GLFWgammaramp type for monitor gamma ramp control
  • @@ -288,6 +288,7 @@ version of GLFW.

  • Renamed glfw.h to glfw3.h to avoid conflicts with 2.x series
  • Renamed GLFW_WINDOW token to GLFW_WINDOWED
  • Renamed GLFW_WINDOW_NO_RESIZE to GLFW_WINDOW_RESIZABLE
  • +
  • Renamed GLFW_BUILD_DLL to _GLFW_BUILD_DLL
  • Renamed version test to glfwinfo
  • Replaced ad hoc build system with CMake
  • Replaced layout-dependent key codes with single, platform-independent set based on US layout
  • @@ -312,9 +313,13 @@ version of GLFW.

  • [Cocoa] Added support for joysticks
  • [Cocoa] Postponed menu creation to first window creation
  • [Cocoa] Replaced NSDate time source with mach_absolute_time
  • +
  • [Cocoa] Replaced all deprecated CoreGraphics calls with non-deprecated counterparts
  • +
  • [Cocoa] Bugfix: The NSOpenGLPFAFullScreen pixel format attribute caused creation to fail on some machines
  • +
  • [Cocoa] Bugfix: glfwOpenWindow did not properly enforce the forward-compatible and context profile hints
  • [Cocoa] Bugfix: The loop condition for saving video modes used the wrong index variable
  • [Cocoa] Bugfix: The OpenGL framework was not retrieved, making glfwGetProcAddress crash
  • [Cocoa] Bugfix: glfwInit changed the current directory for unbundled executables
  • +
  • [Cocoa] Bugfix: The GLFW_WINDOW_NO_RESIZE window parameter was always zero
  • [X11] Added support for the GLX_EXT_swap_control extension as an alternative to GLX_SGI_swap_control
  • [X11] Added the POSIX CLOCK_MONOTONIC time source as the preferred method
  • [X11] Added dependency on libm, where present
  • @@ -328,6 +333,7 @@ version of GLFW.

  • [Win32] Bugfix: Software rasterizer pixel formats were not discarded by the WGL_ARB_pixel_format code path
  • [Win32] Bugfix: The array for WGL context attributes was too small and could overflow
  • [Win32] Bugfix: Alt+F4 hot key was not translated into WM_CLOSE
  • +
  • [Win32] Bugfix: The GLFW_WINDOW_NO_RESIZE window parameter was always zero
  • v2.7

    @@ -817,6 +823,8 @@ their skills. Special thanks go out to:

      +
    • artblanc, for a patch replacing a deprecated Core Graphics call
    • +
    • Bobyshev Alexander and Martins Mozeiko, for the original proposal of an FSAA hint and their work on the Win32 implementation of FSAA
    • @@ -869,7 +877,8 @@ their skills. Special thanks go out to:

    • Tristam MacDonald, for his bug reports and feedback on the Cocoa port
    • -
    • Hans 'Hanmac' Mackowiak, for adding UTF-8 window title support on X11
    • +
    • Hans 'Hanmac' Mackowiak, for adding UTF-8 window title support on X11 and + a fix for the Xkb support
    • David Medlock, for doing the initial Lua port
    • diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f308c299..8276faa3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,69 +1,59 @@ -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) +if (_GLFW_X11_GLX) 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) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc + DESTINATION lib/pkgconfig) +endif() include_directories(${GLFW_SOURCE_DIR}/src ${GLFW_BINARY_DIR}/src - ${GLFW_INCLUDE_DIR}) + ${glfw_INCLUDE_DIRS}) set(common_SOURCES clipboard.c error.c fullscreen.c gamma.c init.c input.c joystick.c opengl.c time.c window.c) -if(_GLFW_COCOA_NSGL) - set(libglfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m - cocoa_gamma.c cocoa_init.m cocoa_input.m - cocoa_joystick.m cocoa_opengl.m cocoa_time.c - cocoa_window.m) +if (_GLFW_COCOA_NSGL) + set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_fullscreen.m + cocoa_gamma.c cocoa_init.m cocoa_input.m cocoa_joystick.m + cocoa_opengl.m cocoa_time.c cocoa_window.m) # For some reason, CMake doesn't know about .m - set_source_files_properties(${libglfw_SOURCES} PROPERTIES LANGUAGE C) -elseif(_GLFW_WIN32_WGL) - set(libglfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_fullscreen.c - win32_gamma.c win32_init.c win32_input.c win32_joystick.c - win32_opengl.c win32_time.c win32_window.c - win32_dllmain.c) -elseif(_GLFW_X11_GLX) - set(libglfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c - x11_gamma.c x11_init.c x11_input.c x11_joystick.c - x11_keysym2unicode.c x11_opengl.c x11_time.c - x11_window.c) -else() - message(FATAL_ERROR "No supported platform was selected") -endif(_GLFW_COCOA_NSGL) + set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C) +elseif (_GLFW_WIN32_WGL) + set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_fullscreen.c + win32_gamma.c win32_init.c win32_input.c win32_joystick.c + win32_opengl.c win32_time.c win32_window.c win32_dllmain.c) +elseif (_GLFW_X11_GLX) + set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_fullscreen.c + x11_gamma.c x11_init.c x11_input.c x11_joystick.c + x11_keysym2unicode.c x11_opengl.c x11_time.c x11_window.c) +endif() -add_library(libglfwStatic STATIC ${libglfw_SOURCES}) -add_library(libglfwShared SHARED ${libglfw_SOURCES}) -target_link_libraries(libglfwShared ${GLFW_LIBRARIES}) -set_target_properties(libglfwStatic libglfwShared PROPERTIES - CLEAN_DIRECT_OUTPUT 1 - OUTPUT_NAME glfw) +add_library(glfw ${glfw_SOURCES}) -if(WIN32) - # The GLFW DLL needs a special compile-time macro and import library name - set_target_properties(libglfwShared PROPERTIES - DEFINE_SYMBOL GLFW_BUILD_DLL - PREFIX "" - IMPORT_PREFIX "" - IMPORT_SUFFIX "dll.lib") -endif(WIN32) +if (BUILD_SHARED_LIBS) -if(APPLE) - # Append -fno-common to the compile flags to work around a bug in the Apple GCC - get_target_property(CFLAGS libglfwShared COMPILE_FLAGS) - if(NOT CFLAGS) - set(CFLAGS "") - endif(NOT CFLAGS) - set_target_properties(libglfwShared PROPERTIES COMPILE_FLAGS "${CFLAGS} -fno-common") -endif(APPLE) + if (_GLFW_WIN32_WGL) + # The GLFW DLL needs a special compile-time macro and import library name + set_target_properties(glfw PROPERTIES + COMPILE_DEFINITIONS "_GLFW_BUILD_DLL;_GLFW_NO_DLOAD_GDI32;_GLFW_NO_DLOAD_WINMM" + PREFIX "" + IMPORT_PREFIX "" + IMPORT_SUFFIX "dll.lib") + elseif (_GLFW_COCOA_NSGL) + # Append -fno-common to the compile flags to work around a bug in the Apple GCC + get_target_property(glfw_CFLAGS glfw COMPILE_FLAGS) + if (NOT glfw_CFLAGS) + set(glfw_CFLAGS "") + endif() + set_target_properties(glfw PROPERTIES + COMPILE_FLAGS "${glfw_CFLAGS} -fno-common") + endif() -install(TARGETS libglfwStatic libglfwShared DESTINATION lib) + target_link_libraries(glfw ${glfw_LIBRARIES}) + target_link_libraries(glfw LINK_INTERFACE_LIBRARIES) +endif() + +install(TARGETS glfw DESTINATION lib) diff --git a/src/cocoa_fullscreen.m b/src/cocoa_fullscreen.m index 370296b8..147913fb 100644 --- a/src/cocoa_fullscreen.m +++ b/src/cocoa_fullscreen.m @@ -29,47 +29,166 @@ #include "internal.h" +#include +#include + //======================================================================== // Check whether the display mode should be included in enumeration //======================================================================== -static BOOL modeIsGood(NSDictionary* mode) +static GLboolean modeIsGood(CGDisplayModeRef mode) { - // This is a bit controversial, if you've got something other than an - // LCD computer monitor as an output device you might not want these - // checks. You might also want to reject modes which are interlaced, - // or TV out. There is no one-size-fits-all policy that can work here. - // This seems like a decent compromise, but certain applications may - // wish to patch this... - return [[mode objectForKey:(id)kCGDisplayBitsPerPixel] intValue] >= 15 && - [mode objectForKey:(id)kCGDisplayModeIsSafeForHardware] != nil && - [mode objectForKey:(id)kCGDisplayModeIsStretched] == nil; + uint32_t flags = CGDisplayModeGetIOFlags(mode); + if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag)) + return GL_FALSE; + + if (flags & kDisplayModeInterlacedFlag) + return GL_FALSE; + + if (flags & kDisplayModeTelevisionFlag) + return GL_FALSE; + + if (flags & kDisplayModeStretchedFlag) + return GL_FALSE; + + CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); + if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) && + CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0)) + { + CFRelease(format); + return GL_FALSE; + } + + CFRelease(format); + return GL_TRUE; } + //======================================================================== // Convert Core Graphics display mode to GLFW video mode //======================================================================== -static GLFWvidmode vidmodeFromCGDisplayMode(NSDictionary* mode) +static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode) { - unsigned int width = - [[mode objectForKey:(id)kCGDisplayWidth] unsignedIntValue]; - unsigned int height = - [[mode objectForKey:(id)kCGDisplayHeight] unsignedIntValue]; - unsigned int bps = - [[mode objectForKey:(id)kCGDisplayBitsPerSample] unsignedIntValue]; - GLFWvidmode result; - result.width = width; - result.height = height; - result.redBits = bps; - result.greenBits = bps; - result.blueBits = bps; + result.width = CGDisplayModeGetWidth(mode); + result.height = CGDisplayModeGetHeight(mode); + + CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); + + if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) + { + result.redBits = 5; + result.greenBits = 5; + result.blueBits = 5; + } + else + { + result.redBits = 8; + result.greenBits = 8; + result.blueBits = 8; + } + + CFRelease(format); return result; } +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Change the current video mode +//======================================================================== + +GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate) +{ + CGDisplayModeRef bestMode = NULL; + CFArrayRef modes; + CFIndex count, i; + unsigned int leastSizeDiff = UINT_MAX; + double leastRateDiff = DBL_MAX; + + modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL); + count = CFArrayGetCount(modes); + + for (i = 0; i < count; i++) + { + CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); + if (!modeIsGood(mode)) + continue; + + int modeBPP; + + // Identify display mode pixel encoding + { + CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); + + if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) + modeBPP = 16; + else + modeBPP = 32; + + CFRelease(format); + } + + int modeWidth = (int) CGDisplayModeGetWidth(mode); + int modeHeight = (int) CGDisplayModeGetHeight(mode); + + unsigned int sizeDiff = (abs(modeBPP - *bpp) << 25) | + ((modeWidth - *width) * (modeWidth - *width) + + (modeHeight - *height) * (modeHeight - *height)); + + double rateDiff; + + if (*refreshRate > 0) + rateDiff = fabs(CGDisplayModeGetRefreshRate(mode) - *refreshRate); + else + { + // If no refresh rate was specified, then they're all the same + rateDiff = 0; + } + + if ((sizeDiff < leastSizeDiff) || + (sizeDiff == leastSizeDiff && (rateDiff < leastRateDiff))) + { + bestMode = mode; + + leastSizeDiff = sizeDiff; + leastRateDiff = rateDiff; + } + } + + if (!bestMode) + { + CFRelease(modes); + return GL_FALSE; + } + + CGDisplayCapture(CGMainDisplayID()); + CGDisplaySetDisplayMode(CGMainDisplayID(), bestMode, NULL); + + CFRelease(modes); + return GL_TRUE; +} + + +//======================================================================== +// Restore the previously saved (original) video mode +//======================================================================== + +void _glfwRestoreVideoMode(void) +{ + CGDisplaySetDisplayMode(CGMainDisplayID(), + _glfwLibrary.NS.desktopMode, + NULL); + + CGDisplayRelease(CGMainDisplayID()); +} + + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// @@ -80,19 +199,26 @@ static GLFWvidmode vidmodeFromCGDisplayMode(NSDictionary* mode) int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) { - NSArray* modes = (NSArray*) CGDisplayAvailableModes(CGMainDisplayID()); - unsigned int i, j = 0, n = [modes count]; + CGDisplayModeRef mode; + CFArrayRef modes; + CFIndex count, i; + int stored = 0; - for (i = 0; i < n && j < (unsigned)maxcount; i++) + modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL); + count = CFArrayGetCount(modes); + + for (i = 0; i < count && stored < maxcount; i++) { - NSDictionary *mode = [modes objectAtIndex:i]; + mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); if (modeIsGood(mode)) - list[j++] = vidmodeFromCGDisplayMode(mode); + list[stored++] = vidmodeFromCGDisplayMode(mode); } - return j; + CFRelease(modes); + return stored; } + //======================================================================== // Get the desktop video mode //======================================================================== diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 16ea6e68..16bd98eb 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -33,6 +33,7 @@ //======================================================================== // Change to our application bundle's resources directory, if present //======================================================================== + static void changeToResourcesDirectory(void) { char resourcesPath[MAXPATHLEN]; @@ -78,6 +79,8 @@ static void changeToResourcesDirectory(void) int _glfwPlatformInit(void) { + _glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init]; + _glfwLibrary.NS.OpenGLFramework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); if (_glfwLibrary.NS.OpenGLFramework == NULL) @@ -89,8 +92,7 @@ int _glfwPlatformInit(void) changeToResourcesDirectory(); - _glfwLibrary.NS.desktopMode = - (NSDictionary*) CGDisplayCurrentMode(CGMainDisplayID()); + _glfwLibrary.NS.desktopMode = CGDisplayCopyDisplayMode(CGMainDisplayID()); // Save the original gamma ramp _glfwLibrary.originalRampSize = CGDisplayGammaTableCapacity(CGMainDisplayID()); @@ -101,9 +103,17 @@ int _glfwPlatformInit(void) _glfwInitJoysticks(); + _glfwLibrary.NS.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + if (!_glfwLibrary.NS.eventSource) + return GL_FALSE; + + CGEventSourceSetLocalEventsSuppressionInterval(_glfwLibrary.NS.eventSource, + 0.0); + return GL_TRUE; } + //======================================================================== // Close window, if open, and shut down GLFW //======================================================================== @@ -112,9 +122,17 @@ int _glfwPlatformTerminate(void) { // TODO: Probably other cleanup + if (_glfwLibrary.NS.eventSource) + { + CFRelease(_glfwLibrary.NS.eventSource); + _glfwLibrary.NS.eventSource = NULL; + } + // Restore the original gamma ramp _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp); + CGDisplayModeRelease(_glfwLibrary.NS.desktopMode); + [NSApp setDelegate:nil]; [_glfwLibrary.NS.delegate release]; _glfwLibrary.NS.delegate = nil; diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index a167692f..45b3be0f 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -579,4 +579,3 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons, return numbuttons; } - diff --git a/src/cocoa_opengl.m b/src/cocoa_opengl.m index bd3827fc..0ea39076 100644 --- a/src/cocoa_opengl.m +++ b/src/cocoa_opengl.m @@ -59,6 +59,7 @@ void _glfwPlatformSwapBuffers(void) [window->NSGL.context flushBuffer]; } + //======================================================================== // Set double buffering swap interval //======================================================================== @@ -71,6 +72,7 @@ void _glfwPlatformSwapInterval(int interval) [window->NSGL.context setValues:&sync forParameter:NSOpenGLCPSwapInterval]; } + //======================================================================== // Check if an OpenGL extension is available at runtime //======================================================================== @@ -81,6 +83,7 @@ int _glfwPlatformExtensionSupported(const char* extension) return GL_FALSE; } + //======================================================================== // Get the function pointer to an OpenGL function //======================================================================== @@ -99,6 +102,7 @@ void* _glfwPlatformGetProcAddress(const char* procname) return symbol; } + //======================================================================== // Copies the specified OpenGL state categories from src to dst //======================================================================== diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 1a90af01..b70fb184 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -37,6 +37,7 @@ #if defined(__OBJC__) #import #else +#include typedef void* id; #endif @@ -90,10 +91,11 @@ typedef struct _GLFWlibraryNS } timer; // dlopen handle for dynamically loading OpenGL extension entry points - void* OpenGLFramework; - id desktopMode; - id delegate; - id autoreleasePool; + void* OpenGLFramework; + CGDisplayModeRef desktopMode; + CGEventSourceRef eventSource; + id delegate; + id autoreleasePool; } _GLFWlibraryNS; @@ -108,5 +110,8 @@ void _glfwInitTimer(void); void _glfwInitJoysticks(void); void _glfwTerminateJoysticks(void); +// Fullscreen +GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate); +void _glfwRestoreVideoMode(void); #endif // _platform_h_ diff --git a/src/cocoa_time.c b/src/cocoa_time.c index 4facbffb..745b4239 100644 --- a/src/cocoa_time.c +++ b/src/cocoa_time.c @@ -74,6 +74,7 @@ double _glfwPlatformGetTime(void) _glfwLibrary.NS.timer.resolution; } + //======================================================================== // Set timer value in seconds //======================================================================== diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 221dcc5e..98c220ed 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -112,6 +112,7 @@ @end + //======================================================================== // Delegate for application related notifications //======================================================================== @@ -133,142 +134,6 @@ @end -//======================================================================== -// Keyboard symbol translation table -//======================================================================== - -// TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject. -static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] = -{ - /* 00 */ GLFW_KEY_A, - /* 01 */ GLFW_KEY_S, - /* 02 */ GLFW_KEY_D, - /* 03 */ GLFW_KEY_F, - /* 04 */ GLFW_KEY_H, - /* 05 */ GLFW_KEY_G, - /* 06 */ GLFW_KEY_Z, - /* 07 */ GLFW_KEY_X, - /* 08 */ GLFW_KEY_C, - /* 09 */ GLFW_KEY_V, - /* 0a */ GLFW_KEY_GRAVE_ACCENT, - /* 0b */ GLFW_KEY_B, - /* 0c */ GLFW_KEY_Q, - /* 0d */ GLFW_KEY_W, - /* 0e */ GLFW_KEY_E, - /* 0f */ GLFW_KEY_R, - /* 10 */ GLFW_KEY_Y, - /* 11 */ GLFW_KEY_T, - /* 12 */ GLFW_KEY_1, - /* 13 */ GLFW_KEY_2, - /* 14 */ GLFW_KEY_3, - /* 15 */ GLFW_KEY_4, - /* 16 */ GLFW_KEY_6, - /* 17 */ GLFW_KEY_5, - /* 18 */ GLFW_KEY_EQUAL, - /* 19 */ GLFW_KEY_9, - /* 1a */ GLFW_KEY_7, - /* 1b */ GLFW_KEY_MINUS, - /* 1c */ GLFW_KEY_8, - /* 1d */ GLFW_KEY_0, - /* 1e */ GLFW_KEY_RIGHT_BRACKET, - /* 1f */ GLFW_KEY_O, - /* 20 */ GLFW_KEY_U, - /* 21 */ GLFW_KEY_LEFT_BRACKET, - /* 22 */ GLFW_KEY_I, - /* 23 */ GLFW_KEY_P, - /* 24 */ GLFW_KEY_ENTER, - /* 25 */ GLFW_KEY_L, - /* 26 */ GLFW_KEY_J, - /* 27 */ GLFW_KEY_APOSTROPHE, - /* 28 */ GLFW_KEY_K, - /* 29 */ GLFW_KEY_SEMICOLON, - /* 2a */ GLFW_KEY_BACKSLASH, - /* 2b */ GLFW_KEY_COMMA, - /* 2c */ GLFW_KEY_SLASH, - /* 2d */ GLFW_KEY_N, - /* 2e */ GLFW_KEY_M, - /* 2f */ GLFW_KEY_PERIOD, - /* 30 */ GLFW_KEY_TAB, - /* 31 */ GLFW_KEY_SPACE, - /* 32 */ GLFW_KEY_WORLD_1, - /* 33 */ GLFW_KEY_BACKSPACE, - /* 34 */ -1, - /* 35 */ GLFW_KEY_ESCAPE, - /* 36 */ GLFW_KEY_RIGHT_SUPER, - /* 37 */ GLFW_KEY_LEFT_SUPER, - /* 38 */ GLFW_KEY_LEFT_SHIFT, - /* 39 */ GLFW_KEY_CAPS_LOCK, - /* 3a */ GLFW_KEY_LEFT_ALT, - /* 3b */ GLFW_KEY_LEFT_CONTROL, - /* 3c */ GLFW_KEY_RIGHT_SHIFT, - /* 3d */ GLFW_KEY_RIGHT_ALT, - /* 3e */ GLFW_KEY_RIGHT_CONTROL, - /* 3f */ -1, /* Function */ - /* 40 */ GLFW_KEY_F17, - /* 41 */ GLFW_KEY_KP_DECIMAL, - /* 42 */ -1, - /* 43 */ GLFW_KEY_KP_MULTIPLY, - /* 44 */ -1, - /* 45 */ GLFW_KEY_KP_ADD, - /* 46 */ -1, - /* 47 */ GLFW_KEY_NUM_LOCK, /* Really KeypadClear... */ - /* 48 */ -1, /* VolumeUp */ - /* 49 */ -1, /* VolumeDown */ - /* 4a */ -1, /* Mute */ - /* 4b */ GLFW_KEY_KP_DIVIDE, - /* 4c */ GLFW_KEY_KP_ENTER, - /* 4d */ -1, - /* 4e */ GLFW_KEY_KP_SUBTRACT, - /* 4f */ GLFW_KEY_F18, - /* 50 */ GLFW_KEY_F19, - /* 51 */ GLFW_KEY_KP_EQUAL, - /* 52 */ GLFW_KEY_KP_0, - /* 53 */ GLFW_KEY_KP_1, - /* 54 */ GLFW_KEY_KP_2, - /* 55 */ GLFW_KEY_KP_3, - /* 56 */ GLFW_KEY_KP_4, - /* 57 */ GLFW_KEY_KP_5, - /* 58 */ GLFW_KEY_KP_6, - /* 59 */ GLFW_KEY_KP_7, - /* 5a */ GLFW_KEY_F20, - /* 5b */ GLFW_KEY_KP_8, - /* 5c */ GLFW_KEY_KP_9, - /* 5d */ -1, - /* 5e */ -1, - /* 5f */ -1, - /* 60 */ GLFW_KEY_F5, - /* 61 */ GLFW_KEY_F6, - /* 62 */ GLFW_KEY_F7, - /* 63 */ GLFW_KEY_F3, - /* 64 */ GLFW_KEY_F8, - /* 65 */ GLFW_KEY_F9, - /* 66 */ -1, - /* 67 */ GLFW_KEY_F11, - /* 68 */ -1, - /* 69 */ GLFW_KEY_F13, - /* 6a */ GLFW_KEY_F16, - /* 6b */ GLFW_KEY_F14, - /* 6c */ -1, - /* 6d */ GLFW_KEY_F10, - /* 6e */ -1, - /* 6f */ GLFW_KEY_F12, - /* 70 */ -1, - /* 71 */ GLFW_KEY_F15, - /* 72 */ GLFW_KEY_INSERT, /* Really Help... */ - /* 73 */ GLFW_KEY_HOME, - /* 74 */ GLFW_KEY_PAGE_UP, - /* 75 */ GLFW_KEY_DELETE, - /* 76 */ GLFW_KEY_F4, - /* 77 */ GLFW_KEY_END, - /* 78 */ GLFW_KEY_F2, - /* 79 */ GLFW_KEY_PAGE_DOWN, - /* 7a */ GLFW_KEY_F1, - /* 7b */ GLFW_KEY_LEFT, - /* 7c */ GLFW_KEY_RIGHT, - /* 7d */ GLFW_KEY_DOWN, - /* 7e */ GLFW_KEY_UP, - /* 7f */ -1, -}; //======================================================================== // Converts a Mac OS X keycode to a GLFW keycode @@ -276,15 +141,150 @@ static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] = static int convertMacKeyCode(unsigned int macKeyCode) { + // Keyboard symbol translation table + // TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject. + static const unsigned int table[128] = + { + /* 00 */ GLFW_KEY_A, + /* 01 */ GLFW_KEY_S, + /* 02 */ GLFW_KEY_D, + /* 03 */ GLFW_KEY_F, + /* 04 */ GLFW_KEY_H, + /* 05 */ GLFW_KEY_G, + /* 06 */ GLFW_KEY_Z, + /* 07 */ GLFW_KEY_X, + /* 08 */ GLFW_KEY_C, + /* 09 */ GLFW_KEY_V, + /* 0a */ GLFW_KEY_GRAVE_ACCENT, + /* 0b */ GLFW_KEY_B, + /* 0c */ GLFW_KEY_Q, + /* 0d */ GLFW_KEY_W, + /* 0e */ GLFW_KEY_E, + /* 0f */ GLFW_KEY_R, + /* 10 */ GLFW_KEY_Y, + /* 11 */ GLFW_KEY_T, + /* 12 */ GLFW_KEY_1, + /* 13 */ GLFW_KEY_2, + /* 14 */ GLFW_KEY_3, + /* 15 */ GLFW_KEY_4, + /* 16 */ GLFW_KEY_6, + /* 17 */ GLFW_KEY_5, + /* 18 */ GLFW_KEY_EQUAL, + /* 19 */ GLFW_KEY_9, + /* 1a */ GLFW_KEY_7, + /* 1b */ GLFW_KEY_MINUS, + /* 1c */ GLFW_KEY_8, + /* 1d */ GLFW_KEY_0, + /* 1e */ GLFW_KEY_RIGHT_BRACKET, + /* 1f */ GLFW_KEY_O, + /* 20 */ GLFW_KEY_U, + /* 21 */ GLFW_KEY_LEFT_BRACKET, + /* 22 */ GLFW_KEY_I, + /* 23 */ GLFW_KEY_P, + /* 24 */ GLFW_KEY_ENTER, + /* 25 */ GLFW_KEY_L, + /* 26 */ GLFW_KEY_J, + /* 27 */ GLFW_KEY_APOSTROPHE, + /* 28 */ GLFW_KEY_K, + /* 29 */ GLFW_KEY_SEMICOLON, + /* 2a */ GLFW_KEY_BACKSLASH, + /* 2b */ GLFW_KEY_COMMA, + /* 2c */ GLFW_KEY_SLASH, + /* 2d */ GLFW_KEY_N, + /* 2e */ GLFW_KEY_M, + /* 2f */ GLFW_KEY_PERIOD, + /* 30 */ GLFW_KEY_TAB, + /* 31 */ GLFW_KEY_SPACE, + /* 32 */ GLFW_KEY_WORLD_1, + /* 33 */ GLFW_KEY_BACKSPACE, + /* 34 */ -1, + /* 35 */ GLFW_KEY_ESCAPE, + /* 36 */ GLFW_KEY_RIGHT_SUPER, + /* 37 */ GLFW_KEY_LEFT_SUPER, + /* 38 */ GLFW_KEY_LEFT_SHIFT, + /* 39 */ GLFW_KEY_CAPS_LOCK, + /* 3a */ GLFW_KEY_LEFT_ALT, + /* 3b */ GLFW_KEY_LEFT_CONTROL, + /* 3c */ GLFW_KEY_RIGHT_SHIFT, + /* 3d */ GLFW_KEY_RIGHT_ALT, + /* 3e */ GLFW_KEY_RIGHT_CONTROL, + /* 3f */ -1, /* Function */ + /* 40 */ GLFW_KEY_F17, + /* 41 */ GLFW_KEY_KP_DECIMAL, + /* 42 */ -1, + /* 43 */ GLFW_KEY_KP_MULTIPLY, + /* 44 */ -1, + /* 45 */ GLFW_KEY_KP_ADD, + /* 46 */ -1, + /* 47 */ GLFW_KEY_NUM_LOCK, /* Really KeypadClear... */ + /* 48 */ -1, /* VolumeUp */ + /* 49 */ -1, /* VolumeDown */ + /* 4a */ -1, /* Mute */ + /* 4b */ GLFW_KEY_KP_DIVIDE, + /* 4c */ GLFW_KEY_KP_ENTER, + /* 4d */ -1, + /* 4e */ GLFW_KEY_KP_SUBTRACT, + /* 4f */ GLFW_KEY_F18, + /* 50 */ GLFW_KEY_F19, + /* 51 */ GLFW_KEY_KP_EQUAL, + /* 52 */ GLFW_KEY_KP_0, + /* 53 */ GLFW_KEY_KP_1, + /* 54 */ GLFW_KEY_KP_2, + /* 55 */ GLFW_KEY_KP_3, + /* 56 */ GLFW_KEY_KP_4, + /* 57 */ GLFW_KEY_KP_5, + /* 58 */ GLFW_KEY_KP_6, + /* 59 */ GLFW_KEY_KP_7, + /* 5a */ GLFW_KEY_F20, + /* 5b */ GLFW_KEY_KP_8, + /* 5c */ GLFW_KEY_KP_9, + /* 5d */ -1, + /* 5e */ -1, + /* 5f */ -1, + /* 60 */ GLFW_KEY_F5, + /* 61 */ GLFW_KEY_F6, + /* 62 */ GLFW_KEY_F7, + /* 63 */ GLFW_KEY_F3, + /* 64 */ GLFW_KEY_F8, + /* 65 */ GLFW_KEY_F9, + /* 66 */ -1, + /* 67 */ GLFW_KEY_F11, + /* 68 */ -1, + /* 69 */ GLFW_KEY_F13, + /* 6a */ GLFW_KEY_F16, + /* 6b */ GLFW_KEY_F14, + /* 6c */ -1, + /* 6d */ GLFW_KEY_F10, + /* 6e */ -1, + /* 6f */ GLFW_KEY_F12, + /* 70 */ -1, + /* 71 */ GLFW_KEY_F15, + /* 72 */ GLFW_KEY_INSERT, /* Really Help... */ + /* 73 */ GLFW_KEY_HOME, + /* 74 */ GLFW_KEY_PAGE_UP, + /* 75 */ GLFW_KEY_DELETE, + /* 76 */ GLFW_KEY_F4, + /* 77 */ GLFW_KEY_END, + /* 78 */ GLFW_KEY_F2, + /* 79 */ GLFW_KEY_PAGE_DOWN, + /* 7a */ GLFW_KEY_F1, + /* 7b */ GLFW_KEY_LEFT, + /* 7c */ GLFW_KEY_RIGHT, + /* 7d */ GLFW_KEY_DOWN, + /* 7e */ GLFW_KEY_UP, + /* 7f */ -1, + }; + if (macKeyCode >= 128) return -1; // This treats keycodes as *positional*; that is, we'll return 'a' // for the key left of 's', even on an AZERTY keyboard. The charInput // function should still get 'q' though. - return MAC_TO_GLFW_KEYCODE_MAPPING[macKeyCode]; + return table[macKeyCode]; } + //======================================================================== // Content view class for the GLFW window //======================================================================== @@ -388,11 +388,11 @@ static int convertMacKeyCode(unsigned int macKeyCode) { NSUInteger i, length; NSString* characters; - int code = convertMacKeyCode([event keyCode]); + int key = convertMacKeyCode([event keyCode]); - if (code != -1) + if (key != -1) { - _glfwInputKey(window, code, GLFW_PRESS); + _glfwInputKey(window, key, GLFW_PRESS); if ([event modifierFlags] & NSCommandKeyMask) { @@ -412,7 +412,7 @@ static int convertMacKeyCode(unsigned int macKeyCode) - (void)flagsChanged:(NSEvent *)event { - int mode; + int mode, key; unsigned int newModifierFlags = [event modifierFlags] | NSDeviceIndependentModifierFlagsMask; @@ -422,14 +422,17 @@ static int convertMacKeyCode(unsigned int macKeyCode) mode = GLFW_RELEASE; window->NS.modifierFlags = newModifierFlags; - _glfwInputKey(window, MAC_TO_GLFW_KEYCODE_MAPPING[[event keyCode]], mode); + + key = convertMacKeyCode([event keyCode]); + if (key != -1) + _glfwInputKey(window, key, mode); } - (void)keyUp:(NSEvent *)event { - int code = convertMacKeyCode([event keyCode]); - if (code != -1) - _glfwInputKey(window, code, GLFW_RELEASE); + int key = convertMacKeyCode([event keyCode]); + if (key != -1) + _glfwInputKey(window, key, GLFW_RELEASE); } - (void)scrollWheel:(NSEvent *)event @@ -446,6 +449,7 @@ static int convertMacKeyCode(unsigned int macKeyCode) @end + //======================================================================== // GLFW application class //======================================================================== @@ -469,13 +473,6 @@ static int convertMacKeyCode(unsigned int macKeyCode) @end -// Prior to Snow Leopard, we need to use this oddly-named semi-private API -// to get the application menu working properly. Need to be careful in -// case it goes away in a future OS update. -@interface NSApplication (NSAppleMenu) -- (void)setAppleMenu:(NSMenu*)m; -@end - //======================================================================== // Try to figure out what the calling application is called //======================================================================== @@ -523,6 +520,7 @@ static NSString* findAppName(void) return @"GLFW Application"; } + //======================================================================== // Set up the menu bar (manually) // This is nasty, nasty stuff -- calls to undocumented semi-private APIs that @@ -530,7 +528,8 @@ static NSString* findAppName(void) // 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) + +static void createMenuBar(void) { NSString* appName = findAppName(); @@ -584,37 +583,35 @@ static void setUpMenuBar(void) 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]; + // 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 initializeCocoa(void) + +static GLboolean initializeAppKit(void) { if (NSApp) return GL_TRUE; - _glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init]; - // 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 - setUpMenuBar(); + createMenuBar(); [NSApp finishLaunching]; return GL_TRUE; } + //======================================================================== // Create the Cocoa window //======================================================================== @@ -658,6 +655,7 @@ static GLboolean createWindow(_GLFWwindow* window, return GL_TRUE; } + //======================================================================== // Create the OpenGL context //======================================================================== @@ -686,14 +684,23 @@ static GLboolean createContext(_GLFWwindow* window, return GL_FALSE; } - if (wndconfig->glProfile) + if (wndconfig->glMajor > 2) { - // Fail if a profile other than core was explicitly selected + if (!wndconfig->glForward) + { + _glfwSetError(GLFW_VERSION_UNAVAILABLE, + "Cocoa/NSOpenGL: The targeted version of Mac OS X " + "only supports OpenGL 3.2 contexts if they are " + "forward-compatible"); + return GL_FALSE; + } + if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE) { _glfwSetError(GLFW_VERSION_UNAVAILABLE, "Cocoa/NSOpenGL: The targeted version of Mac OS X " - "only supports the OpenGL core profile"); + "only supports OpenGL 3.2 contexts if they use the " + "core profile"); return GL_FALSE; } } @@ -721,13 +728,12 @@ static GLboolean createContext(_GLFWwindow* window, #define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } // Arbitrary array size here - NSOpenGLPixelFormatAttribute attributes[24]; + NSOpenGLPixelFormatAttribute attributes[40]; ADD_ATTR(NSOpenGLPFADoubleBuffer); if (wndconfig->mode == GLFW_FULLSCREEN) { - ADD_ATTR(NSOpenGLPFAFullScreen); ADD_ATTR(NSOpenGLPFANoRecovery); ADD_ATTR2(NSOpenGLPFAScreenMask, CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID())); @@ -813,9 +819,11 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWfbconfig* fbconfig) { - if (!initializeCocoa()) + if (!initializeAppKit()) return GL_FALSE; + window->resizable = wndconfig->resizable; + // We can only have one application delegate, but we only allocate it the // first time we create a window to keep all window code in this file if (_glfwLibrary.NS.delegate == nil) @@ -850,28 +858,6 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, // Don't use accumulation buffer support; it's not accelerated // Aux buffers probably aren't accelerated either - CFDictionaryRef fullscreenMode = NULL; - if (wndconfig->mode == GLFW_FULLSCREEN) - { - // I think it's safe to pass 0 to the refresh rate for this function - // rather than conditionalizing the code to call the version which - // doesn't specify refresh... - fullscreenMode = - CGDisplayBestModeForParametersAndRefreshRateWithProperty( - CGMainDisplayID(), - colorBits + fbconfig->alphaBits, - window->width, window->height, - wndconfig->refreshRate, - // Controversial, see macosx_fullscreen.m for discussion - kCGDisplayModeIsSafeForHardware, - NULL); - - window->width = - [[(id)fullscreenMode objectForKey:(id)kCGDisplayWidth] intValue]; - window->height = - [[(id)fullscreenMode objectForKey:(id)kCGDisplayHeight] intValue]; - } - if (!createWindow(window, wndconfig)) return GL_FALSE; @@ -883,8 +869,15 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, if (wndconfig->mode == GLFW_FULLSCREEN) { - CGCaptureAllDisplays(); - CGDisplaySwitchToMode(CGMainDisplayID(), fullscreenMode); + int bpp = colorBits + fbconfig->alphaBits; + + if (!_glfwSetVideoMode(&window->width, + &window->height, + &bpp, + &window->refreshRate)) + { + return GL_FALSE; + } [[window->NS.window contentView] enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; @@ -914,9 +907,7 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window) { [[window->NS.window contentView] exitFullScreenModeWithOptions:nil]; - CGDisplaySwitchToMode(CGMainDisplayID(), - (CFDictionaryRef) _glfwLibrary.NS.desktopMode); - CGReleaseAllDisplays(); + _glfwRestoreVideoMode(); } [window->NSGL.pixelFormat release]; @@ -936,6 +927,7 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window) // TODO: Probably more cleanup } + //======================================================================== // Set the window title //======================================================================== @@ -945,6 +937,7 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) [window->NS.window setTitle:[NSString stringWithUTF8String:title]]; } + //======================================================================== // Set the window size //======================================================================== @@ -954,6 +947,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) [window->NS.window setContentSize:NSMakeSize(width, height)]; } + //======================================================================== // Set the window position //======================================================================== @@ -974,6 +968,7 @@ void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) display:YES]; } + //======================================================================== // Iconify the window //======================================================================== @@ -983,6 +978,7 @@ void _glfwPlatformIconifyWindow(_GLFWwindow* window) [window->NS.window miniaturize:nil]; } + //======================================================================== // Restore (un-iconify) the window //======================================================================== @@ -992,6 +988,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) [window->NS.window deminiaturize:nil]; } + //======================================================================== // Write back window parameters into GLFW window structure //======================================================================== @@ -1066,6 +1063,7 @@ void _glfwPlatformRefreshWindowParams(void) window->glDebug = GL_FALSE; } + //======================================================================== // Poll for new window and input events //======================================================================== @@ -1090,6 +1088,7 @@ void _glfwPlatformPollEvents(void) _glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init]; } + //======================================================================== // Wait for new window and input events //======================================================================== @@ -1108,6 +1107,7 @@ void _glfwPlatformWaitEvents( void ) _glfwPlatformPollEvents(); } + //======================================================================== // Set physical mouse cursor position //======================================================================== @@ -1125,11 +1125,6 @@ void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y) // calculating the maximum y coordinate of all screens, since Cocoa's // "global coordinates" are upside down from CG's... - // Without this (once per app run, but it's convenient to do it here) - // events will be suppressed for a default of 0.25 seconds after we - // move the cursor. - CGSetLocalEventsSuppressionInterval(0.0); - NSPoint localPoint = NSMakePoint(x, y); NSPoint globalPoint = [window->NS.window convertBaseToScreen:localPoint]; CGPoint mainScreenOrigin = CGDisplayBounds(CGMainDisplayID()).origin; @@ -1140,6 +1135,7 @@ void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y) CGDisplayMoveCursorToPoint(CGMainDisplayID(), targetPoint); } + //======================================================================== // Set physical mouse cursor mode //======================================================================== diff --git a/src/config.h.in b/src/config.h.in index f966356c..46a6e2aa 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -60,11 +60,6 @@ // Define this to 1 if the Linux joystick API is available #cmakedefine _GLFW_USE_LINUX_JOYSTICKS 1 -// Define this to 1 to not load gdi32.dll dynamically -#cmakedefine _GLFW_NO_DLOAD_GDI32 1 -// Define this to 1 to not load winmm.dll dynamically -#cmakedefine _GLFW_NO_DLOAD_WINMM 1 - // The GLFW version as used by glfwGetVersionString #define _GLFW_VERSION_FULL "@GLFW_VERSION_FULL@" diff --git a/src/input.c b/src/input.c index ec894a27..ded88712 100644 --- a/src/input.c +++ b/src/input.c @@ -167,7 +167,7 @@ void _glfwInputKey(_GLFWwindow* window, int key, int action) return; // Register key action - if(action == GLFW_RELEASE && window->stickyKeys) + if (action == GLFW_RELEASE && window->stickyKeys) window->key[key] = GLFW_STICK; else { diff --git a/src/libglfw.pc.cmake b/src/libglfw.pc.cmake index 1a712d9d..f83ad126 100644 --- a/src/libglfw.pc.cmake +++ b/src/libglfw.pc.cmake @@ -7,7 +7,7 @@ Name: GLFW Description: A portable library for OpenGL, window and input Version: 3.0.0 URL: http://www.glfw.org/ -Requires.private: gl x11 @GLFW_PKGLIBS@ +Requires.private: @GLFW_PKG_DEPS@ Libs: -L${libdir} -lglfw -Libs.private: @GLFW_LIBRARIES@ +Libs.private: @GLFW_PKG_LIBS@ Cflags: -I${includedir} diff --git a/src/win32_dllmain.c b/src/win32_dllmain.c index a999af0e..95258ccc 100644 --- a/src/win32_dllmain.c +++ b/src/win32_dllmain.c @@ -31,7 +31,7 @@ #include "internal.h" -#if defined(GLFW_BUILD_DLL) +#if defined(_GLFW_BUILD_DLL) //======================================================================== // GLFW DLL entry point @@ -45,5 +45,5 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) return TRUE; } -#endif // GLFW_BUILD_DLL +#endif // _GLFW_BUILD_DLL diff --git a/src/win32_init.c b/src/win32_init.c index 4e1b7863..55232fd7 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -200,7 +200,7 @@ int _glfwPlatformInit(void) // as possible in the hope of still being the foreground process) SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &_glfwLibrary.Win32.foregroundLockTimeout, 0); - SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, (LPVOID) 0, + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0), SPIF_SENDCHANGE); if (!initLibraries()) @@ -246,7 +246,7 @@ int _glfwPlatformTerminate(void) // Restore previous FOREGROUNDLOCKTIMEOUT system setting SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, - (LPVOID) _glfwLibrary.Win32.foregroundLockTimeout, + UIntToPtr(_glfwLibrary.Win32.foregroundLockTimeout), SPIF_SENDCHANGE); return GL_TRUE; @@ -271,7 +271,7 @@ const char* _glfwPlatformGetVersionString(void) #else " (unknown compiler)" #endif -#if defined(GLFW_BUILD_DLL) +#if defined(_GLFW_BUILD_DLL) " DLL" #endif #if !defined(_GLFW_NO_DLOAD_GDI32) diff --git a/src/win32_platform.h b/src/win32_platform.h index 82b8c9ca..0f6362c1 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -51,7 +51,9 @@ #endif // GLFW requires Windows XP +#ifndef WINVER #define WINVER 0x0501 +#endif #include #include diff --git a/src/win32_window.c b/src/win32_window.c index 24788a33..dd25c3ce 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -34,30 +34,6 @@ #include -//======================================================================== -// 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 //======================================================================== @@ -1441,6 +1417,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, GLboolean recreateContext = GL_FALSE; window->Win32.desiredRefreshRate = wndconfig->refreshRate; + window->resizable = wndconfig->resizable; if (!_glfwLibrary.Win32.classAtom) { @@ -1599,29 +1576,10 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) { - //int bpp, refresh; - int newMode = 0; GLboolean sizeChanged = GL_FALSE; if (window->mode == GLFW_FULLSCREEN) { - // Get some info about the current mode - - DEVMODE dm; - - dm.dmSize = sizeof(DEVMODE); - //if (EnumDisplaySettings(NULL, window->Win32.modeID, &dm)) - //{ - // We need to keep BPP the same for the OpenGL context to keep working - //bpp = dm.dmBitsPerPel; - - // Get closest match for target video mode - //refresh = window->Win32.desiredRefreshRate; - //newMode = _glfwGetClosestVideoModeBPP(&width, &height, &bpp, &refresh); - //} - //else - //newMode = window->Win32.modeID; - if (width > window->width || height > window->height) { // The new video mode is larger than the current one, so we resize @@ -1633,8 +1591,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) sizeChanged = GL_TRUE; } - //if (newMode != window->Win32.modeID) - //_glfwSetVideoModeMODE(newMode); + // TODO: Change video mode } else { diff --git a/src/x11_fullscreen.c b/src/x11_fullscreen.c index e71c2a2b..37a3ae98 100644 --- a/src/x11_fullscreen.c +++ b/src/x11_fullscreen.c @@ -323,7 +323,7 @@ struct _glfwResolution int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) { int count, k, l, r, g, b, rgba, gl; - int depth, screen; + int depth, screen = DefaultScreen(_glfwLibrary.X11.display); XVisualInfo* vislist; XVisualInfo dummy; int viscount, rgbcount, rescount; @@ -372,6 +372,8 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) } } + XFree(vislist); + rescount = 0; resarray = NULL; @@ -457,8 +459,6 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) } } - XFree(vislist); - free(resarray); free(rgbarray); diff --git a/src/x11_init.c b/src/x11_init.c index 0c529553..6de30609 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -79,7 +79,11 @@ static int keyCodeToGLFWKeyCode(int keyCode) // Note: This way we always force "NumLock = ON", which is intentional // since the returned key code should correspond to a physical // location. +#if defined(_GLFW_HAS_XKB) + keySym = XkbKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 1, 0); +#else keySym = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 1); +#endif switch (keySym) { case XK_KP_0: return GLFW_KEY_KP_0; @@ -102,7 +106,12 @@ static int keyCodeToGLFWKeyCode(int keyCode) // Now try pimary keysym for function keys (non-printable keys). These // should not be layout dependent (i.e. US layout and international // layouts should give the same result). +#if defined(_GLFW_HAS_XKB) + keySym = XkbKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 0, 0); +#else keySym = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 0); +#endif + switch (keySym) { case XK_Escape: return GLFW_KEY_ESCAPE; @@ -476,8 +485,8 @@ static void initGammaRamp(void) // 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)) + (_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 diff --git a/src/x11_time.c b/src/x11_time.c index e2203941..f1445233 100644 --- a/src/x11_time.c +++ b/src/x11_time.c @@ -30,6 +30,7 @@ #include "internal.h" +#include #include @@ -39,7 +40,7 @@ static uint64_t getRawTime(void) { -#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) +#if defined(CLOCK_MONOTONIC) if (_glfwLibrary.X11.timer.monotonic) { struct timespec ts; @@ -64,7 +65,7 @@ static uint64_t getRawTime(void) void _glfwInitTimer(void) { -#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) +#if defined(CLOCK_MONOTONIC) struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fe1df13b..daa17a31 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,12 @@ -set(STATIC_DEPS libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY}) -set(SHARED_DEPS libglfwShared ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY}) +link_libraries(glfw ${OPENGL_glu_LIBRARY}) + +if (BUILD_SHARED_LIBS) + add_definitions(-DGLFW_DLL) + link_libraries(${OPENGL_gl_LIBRARY}) +else() + link_libraries(${glfw_LIBRARIES}) +endif() include_directories(${GLFW_SOURCE_DIR}/include ${GLFW_SOURCE_DIR}/support @@ -9,63 +15,46 @@ add_executable(clipboard clipboard.c) target_link_libraries(clipboard ${STATIC_DEPS}) add_executable(defaults defaults.c) -target_link_libraries(defaults ${STATIC_DEPS}) - -add_executable(dynamic dynamic.c) -target_link_libraries(dynamic ${SHARED_DEPS}) - add_executable(events events.c) -target_link_libraries(events ${STATIC_DEPS}) - add_executable(fsaa fsaa.c getopt.c) -target_link_libraries(fsaa ${STATIC_DEPS}) - add_executable(fsfocus fsfocus.c) -target_link_libraries(fsfocus ${STATIC_DEPS}) - add_executable(gamma gamma.c getopt.c) -target_link_libraries(gamma ${STATIC_DEPS}) - add_executable(glfwinfo glfwinfo.c getopt.c) -target_link_libraries(glfwinfo ${STATIC_DEPS}) - add_executable(iconify iconify.c getopt.c) -target_link_libraries(iconify ${STATIC_DEPS}) - add_executable(joysticks joysticks.c) -target_link_libraries(joysticks ${STATIC_DEPS}) - add_executable(listmodes listmodes.c) -target_link_libraries(listmodes ${STATIC_DEPS}) - +add_executable(modes modes.c getopt.c) add_executable(peter peter.c) -target_link_libraries(peter ${STATIC_DEPS}) - add_executable(reopen reopen.c) -target_link_libraries(reopen ${STATIC_DEPS}) add_executable(accuracy WIN32 MACOSX_BUNDLE accuracy.c) -target_link_libraries(accuracy ${STATIC_DEPS}) +set_target_properties(accuracy PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Accuracy") add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c) -target_link_libraries(sharing ${STATIC_DEPS}) +set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing") add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c) -target_link_libraries(tearing ${STATIC_DEPS}) +set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing") add_executable(title WIN32 MACOSX_BUNDLE title.c) -target_link_libraries(title ${STATIC_DEPS}) +set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title") add_executable(windows WIN32 MACOSX_BUNDLE windows.c) -target_link_libraries(windows ${STATIC_DEPS}) +set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows") set(WINDOWS_BINARIES accuracy sharing tearing title windows) set(CONSOLE_BINARIES defaults events fsaa fsfocus gamma glfwinfo iconify - joysticks listmodes peter reopen) + joysticks listmodes modes peter reopen) -if(MSVC) - # Tell MSVC to use main instead of WinMain for Windows subsystem executables - set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES - LINK_FLAGS "/ENTRY:mainCRTStartup") -endif(MSVC) +if (MSVC) + # Tell MSVC to use main instead of WinMain for Windows subsystem executables + set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + LINK_FLAGS "/ENTRY:mainCRTStartup") +endif() + +if (APPLE) + set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} + MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}) +endif() diff --git a/tests/dynamic.c b/tests/dynamic.c deleted file mode 100644 index 8bc5568b..00000000 --- a/tests/dynamic.c +++ /dev/null @@ -1,91 +0,0 @@ -//======================================================================== -// Dynamic linking test -// Copyright (c) Camilla Berglund -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== -// -// This test came about as the result of bug #3060461 -// -//======================================================================== - -#define GLFW_DLL -#include - -#include -#include - -static void window_size_callback(GLFWwindow window, int width, int height) -{ - glViewport(0, 0, width, height); -} - -int main(void) -{ - GLFWwindow window; - int major, minor, rev; - glfwGetVersion(&major, &minor, &rev); - - printf("GLFW header version: %i.%i.%i\n", - GLFW_VERSION_MAJOR, - GLFW_VERSION_MINOR, - GLFW_VERSION_REVISION); - printf("GLFW library version: %i.%i.%i\n", major, minor, rev); - printf("GLFW library version string: %s\n", glfwGetVersionString()); - - if (major != GLFW_VERSION_MAJOR || - minor != GLFW_VERSION_MINOR || - rev != GLFW_VERSION_REVISION) - { - fprintf(stderr, "GLFW library version mismatch\n"); - exit(EXIT_FAILURE); - } - - if (!glfwInit()) - { - fprintf(stderr, "Failed to initialize GLFW\n"); - exit(EXIT_FAILURE); - } - - window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Dynamic Linking Test", NULL); - if (!window) - { - glfwTerminate(); - - fprintf(stderr, "Failed to open GLFW window\n"); - exit(EXIT_FAILURE); - } - - glfwSetWindowSizeCallback(window_size_callback); - glfwSwapInterval(1); - - while (glfwIsWindow(window)) - { - glClear(GL_COLOR_BUFFER_BIT); - - glfwSwapBuffers(); - glfwPollEvents(); - } - - glfwTerminate(); - exit(EXIT_SUCCESS); -} - diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 369e6a96..45cb8616 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -263,7 +263,7 @@ int main(int argc, char** argv) if (major > 3 || (major == 3 && minor >= 2)) { glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); - printf("OpenGL profile mask: 0x%08x (%s)\n", mask, get_profile_name(mask)); + printf("OpenGL profile mask: %s (0x%08x)\n", get_profile_name(mask), mask); printf("OpenGL profile parsed by GLFW: %s\n", get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE))); diff --git a/tests/modes.c b/tests/modes.c new file mode 100644 index 00000000..9c558d47 --- /dev/null +++ b/tests/modes.c @@ -0,0 +1,223 @@ +//======================================================================== +// Video mode test +// Copyright (c) Camilla Berglund +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== +// +// This test enumerates or verifies video modes +// +//======================================================================== + +#include + +#include +#include + +#include "getopt.h" + +static GLFWwindow window = NULL; + +enum Mode +{ + NO_MODE, + LIST_MODE, + TEST_MODE +}; + +static void usage(void) +{ + printf("Usage: modes -l\n"); + printf(" modes -t\n"); + printf(" modes -h\n"); +} + +static void print_mode(GLFWvidmode* mode) +{ + printf("%i x %i x %i (%i %i %i)", + mode->width, mode->height, + mode->redBits + mode->greenBits + mode->blueBits, + mode->redBits, mode->greenBits, mode->blueBits); +} + +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 list_modes(GLFWvidmode* modes, int count) +{ + int i; + GLFWvidmode mode; + + glfwGetDesktopMode(&mode); + printf("Desktop mode: "); + print_mode(&mode); + putchar('\n'); + + for (i = 0; i < count; i++) + { + printf("%3i: ", i); + print_mode(modes + i); + putchar('\n'); + } +} + +static void test_modes(GLFWvidmode* modes, int count) +{ + int i, width, height; + + glfwSetWindowSizeCallback(window_size_callback); + glfwSetWindowCloseCallback(window_close_callback); + + for (i = 0; i < count; i++) + { + glfwOpenWindowHint(GLFW_RED_BITS, modes[i].redBits); + glfwOpenWindowHint(GLFW_GREEN_BITS, modes[i].greenBits); + glfwOpenWindowHint(GLFW_BLUE_BITS, modes[i].blueBits); + + printf("Opening "); + print_mode(modes + i); + printf(" window\n"); + + window = glfwOpenWindow(modes[i].width, modes[i].height, + GLFW_FULLSCREEN, "Video Mode Test", + NULL); + if (!window) + { + printf("Failed to enter mode %i: ", i); + print_mode(modes + i); + putchar('\n'); + 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) != modes[i].redBits || + glfwGetWindowParam(window, GLFW_GREEN_BITS) != modes[i].greenBits || + glfwGetWindowParam(window, GLFW_BLUE_BITS) != modes[i].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), + modes[i].redBits, + modes[i].greenBits, + modes[i].blueBits); + } + + glfwGetWindowSize(window, &width, &height); + + if (width != modes[i].width || height != height) + { + printf("*** Size mismatch: %ix%i instead of %ix%i\n", + width, height, + modes[i].width, modes[i].height); + } + + printf("Closing window\n"); + + glfwCloseWindow(window); + glfwPollEvents(); + window = NULL; + } +} + +int main(int argc, char** argv) +{ + int ch, found, count = 0, mode = NO_MODE; + GLFWvidmode* modes = NULL; + + while ((ch = getopt(argc, argv, "lth")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + case 'l': + mode = LIST_MODE; + break; + case 't': + mode = TEST_MODE; + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + + argc -= optind; + argv += optind; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + for (;;) + { + count += 256; + modes = realloc(modes, sizeof(GLFWvidmode) * count); + + found = glfwGetVideoModes(modes, count); + if (found < count) + break; + } + + if (mode == LIST_MODE) + list_modes(modes, found); + else if (mode == TEST_MODE) + test_modes(modes, found); + + free(modes); + modes = NULL; + + exit(EXIT_SUCCESS); +} +