Merge remote-tracking branch 'upstream/master'

Syncing with upstream glfw
This commit is contained in:
Ali Sherief 2020-01-02 12:27:58 +02:00
commit 1b253fa4cd
36 changed files with 963 additions and 575 deletions

8
.gitignore vendored
View File

@ -8,16 +8,20 @@ _ReSharper*
*.dir
*.vcxproj*
*.sln
.vs/
.vs
CMakeSettings.json
Win32
x64
Debug
Release
MinSizeRel
RelWithDebInfo
*.xcodeproj
*.opensdf
# Xcode clutter
GLFW.build
GLFW.xcodeproj
# macOS clutter
.DS_Store

View File

@ -75,12 +75,14 @@ matrix:
env:
- BUILD_SHARED_LIBS=ON
- CFLAGS=-Werror
- MACOSX_DEPLOYMENT_TARGET=10.8
- os: osx
sudo: false
name: "Cocoa static library"
env:
- BUILD_SHARED_LIBS=OFF
- CFLAGS=-Werror
- MACOSX_DEPLOYMENT_TARGET=10.8
script:
- if grep -Inr '\s$' src include docs tests examples CMake *.md .gitattributes .gitignore; then
echo Trailing whitespace found, aborting;

View File

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.1)
project(GLFW VERSION 3.4.0 LANGUAGES C)
@ -37,10 +37,6 @@ cmake_dependent_option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF
cmake_dependent_option(USE_MSVC_RUNTIME_LIBRARY_DLL "Use MSVC runtime library DLL" ON
"MSVC" OFF)
if (BUILD_SHARED_LIBS)
set(_GLFW_BUILD_DLL 1)
endif()
if (BUILD_SHARED_LIBS AND UNIX)
# On Unix-like systems, shared libraries can use the soname system.
set(GLFW_LIB_NAME glfw)
@ -75,7 +71,7 @@ if (MSVC)
include(CheckIncludeFile)
check_include_file(dinput.h DINPUT_H_FOUND)
if (NOT DINPUT_H_FOUND)
message(FATAL_ERROR "DirectX 9 SDK not found")
message(FATAL_ERROR "DirectX 9 headers not found; install DirectX 9 SDK")
endif()
# Workaround for VS 2008 not shipping with stdint.h
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/vs2008")
@ -203,38 +199,32 @@ if (_GLFW_X11)
# Set up library and include paths
list(APPEND glfw_INCLUDE_DIRS "${X11_X11_INCLUDE_PATH}")
list(APPEND glfw_LIBRARIES "${X11_X11_LIB}" "${CMAKE_THREAD_LIBS_INIT}")
list(APPEND glfw_LIBRARIES "${X11_X11_LIB}")
# Check for XRandR (modern resolution switching and gamma control)
if (NOT X11_Xrandr_INCLUDE_PATH)
message(FATAL_ERROR "The RandR headers were not found")
message(FATAL_ERROR "RandR headers not found; install libxrandr development package")
endif()
# Check for Xinerama (legacy multi-monitor support)
if (NOT X11_Xinerama_INCLUDE_PATH)
message(FATAL_ERROR "The Xinerama headers were not found")
message(FATAL_ERROR "Xinerama headers not found; install libxinerama development package")
endif()
# Check for Xkb (X keyboard extension)
if (NOT X11_Xkb_INCLUDE_PATH)
message(FATAL_ERROR "The X keyboard extension headers were not found")
message(FATAL_ERROR "XKB headers not found; install X11 development package")
endif()
# Check for Xcursor (cursor creation from RGBA images)
if (NOT X11_Xcursor_INCLUDE_PATH)
message(FATAL_ERROR "The Xcursor headers were not found")
message(FATAL_ERROR "Xcursor headers not found; install libxcursor development package")
endif()
# Check for XInput (modern HID input)
if (NOT X11_Xi_INCLUDE_PATH)
message(FATAL_ERROR "The XInput headers were not found")
message(FATAL_ERROR "XInput headers not found; install libxi development package")
endif()
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}"
"${X11_Xinerama_INCLUDE_PATH}"
"${X11_Xkb_INCLUDE_PATH}"
"${X11_Xcursor_INCLUDE_PATH}"
"${X11_Xi_INCLUDE_PATH}")
endif()
#--------------------------------------------------------------------
@ -251,7 +241,7 @@ if (_GLFW_WAYLAND)
list(APPEND glfw_PKG_DEPS "wayland-egl")
list(APPEND glfw_INCLUDE_DIRS "${Wayland_INCLUDE_DIRS}")
list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
list(APPEND glfw_LIBRARIES "${Wayland_LIBRARIES}")
find_package(XKBCommon REQUIRED)
list(APPEND glfw_INCLUDE_DIRS "${XKBCOMMON_INCLUDE_DIRS}")
@ -275,7 +265,6 @@ endif()
#--------------------------------------------------------------------
if (_GLFW_OSMESA)
find_package(OSMesa REQUIRED)
list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
endif()
#--------------------------------------------------------------------
@ -286,11 +275,10 @@ if (_GLFW_COCOA)
list(APPEND glfw_LIBRARIES
"-framework Cocoa"
"-framework IOKit"
"-framework CoreFoundation"
"-framework CoreVideo")
"-framework CoreFoundation")
set(glfw_PKG_DEPS "")
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo")
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation")
endif()
#--------------------------------------------------------------------
@ -326,8 +314,6 @@ write_basic_package_version_file(src/glfw3ConfigVersion.cmake
VERSION ${GLFW_VERSION}
COMPATIBILITY SameMajorVersion)
configure_file(src/glfw_config.h.in src/glfw_config.h @ONLY)
configure_file(src/glfw3.pc.in src/glfw3.pc @ONLY)
#--------------------------------------------------------------------
@ -365,6 +351,11 @@ if (GLFW_INSTALL)
install(FILES "${GLFW_BINARY_DIR}/src/glfw3.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
if (GLFW_BUILD_DOCS)
install(DIRECTORY "${GLFW_BINARY_DIR}/docs/html"
DESTINATION "${CMAKE_INSTALL_DOCDIR}")
endif()
# Only generate this target if no higher-level project already has
if (NOT TARGET uninstall)
configure_file(CMake/cmake_uninstall.cmake.in

View File

@ -11,7 +11,7 @@ application development. It provides a simple, platform-independent API for
creating windows, contexts and surfaces, reading input, handling events, etc.
GLFW natively supports Windows, macOS and Linux and other Unix-like systems. On
Linux both X11 and Wayland is supported.
Linux both X11 and Wayland are supported.
GLFW is licensed under the [zlib/libpng
license](http://www.glfw.org/license.html).
@ -85,10 +85,11 @@ in the documentation for more information.
## Dependencies
GLFW itself depends only on the headers and libraries for your window system.
GLFW itself needs only CMake 3.1 or later and the headers and libraries for your
OS and window system.
The (experimental) Wayland backend also depends on the `extra-cmake-modules`
package, which is used to generated Wayland protocol headers.
package, which is used to generate Wayland protocol headers.
The examples and test programs depend on a number of tiny libraries. These are
located in the `deps/` directory.
@ -118,28 +119,53 @@ information on what to include when reporting a bug.
## Changelog
- Added `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR`,
`GLFW_RESIZE_ALL_CURSOR` and `GLFW_NOT_ALLOWED_CURSOR` cursor shapes (#427)
- Added `GLFW_RESIZE_EW_CURSOR` alias for `GLFW_HRESIZE_CURSOR` (#427)
- Added `GLFW_RESIZE_NS_CURSOR` alias for `GLFW_VRESIZE_CURSOR` (#427)
- Added `GLFW_POINTING_HAND_CURSOR` alias for `GLFW_HAND_CURSOR` (#427)
- Updated the minimum required CMake version to 3.1
- Disabled tests and examples by default when built as a CMake subdirectory
- Bugfix: The CMake config-file package used an absolute path and was not
relocatable (#1470)
- Bugfix: Video modes with a duplicate screen area were discarded (#1555,#1556)
- Bugfix: Compiling with -Wextra-semi caused warnings (#1440)
- Bugfix: Built-in mappings failed because some OEMs re-used VID/PID (#1583)
- [Win32] Added the `GLFW_WIN32_KEYBOARD_MENU` window hint for enabling access
to the window menu
- [Win32] Added a version info resource to the GLFW DLL
- [Win32] Bugfix: `GLFW_INCLUDE_VULKAN` plus `VK_USE_PLATFORM_WIN32_KHR` caused
symbol redefinition (#1524)
- [Win32] Bugfix: The cursor position event was emitted before its cursor enter
event (#1490)
- [Win32] Bugfix: The window hint `GLFW_MAXIMIZED` did not move or resize the
window (#1499)
- [Win32] Bugfix: Disabled cursor mode interfered with some non-client actions
- [Cocoa] Removed dependency on the CoreVideo framework
- [Cocoa] Bugfix: `glfwSetWindowSize` used a bottom-left anchor point (#1553)
- [Cocoa] Bugfix: Window remained on screen after destruction until event poll
(#1412)
- [Cocoa] Bugfix: Event processing before window creation would assert (#1543)
- [Cocoa] Bugfix: Undecorated windows could not be iconified on recent macOS
- [X11] Bugfix: The CMake files did not check for the XInput headers (#1480)
- [X11] Bugfix: Key names were not updated when the keyboard layout changed
(#1462,#1528)
- [X11] Bugfix: Decorations could not be enabled after window creation (#1566)
- [X11] Bugfix: Content scale fallback value could be inconsistent (#1578)
- [X11] Bugfix: `glfwMaximizeWindow` had no effect on hidden windows
- [X11] Bugfix: Clearing `GLFW_FLOATING` on a hidden window caused invalid read
- [X11] Bugfix: Changing `GLFW_FLOATING` on a hidden window could silently fail
- [X11] Bugfix: Disabled cursor mode was interrupted by indicator windows
- [X11] Bugfix: Monitor physical dimensions could be reported as zero mm
- [X11] Bugfix: Window position events were not emitted during resizing (#1613)
- [Wayland] Removed support for `wl_shell` (#1443)
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
- [NSGL] Removed enforcement of forward-compatible flag for core contexts
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
macOS versions (#1442)
- [NSGL] Bugfix: Workaround for swap interval on 10.14 broke on 10.12 (#1483)
## Contact
@ -212,6 +238,7 @@ skills.
- GeO4d
- Marcus Geelnard
- Charles Giessen
- Ryan C. Gordon
- Stephen Gowen
- Kovid Goyal
- Eloi Marín Gratacós
@ -292,6 +319,7 @@ skills.
- Alexandre Pretyman
- Pablo Prietz
- przemekmirek
- pthom
- Guillaume Racicot
- Philip Rideout
- Eddie Ringle

View File

@ -344,8 +344,8 @@ If you are using the dynamic library version of GLFW, add it to the project
dependencies.
If you are using the static library version of GLFW, add it and the Cocoa,
OpenGL, IOKit and CoreVideo frameworks to the project as dependencies. They can
all be found in `/System/Library/Frameworks`.
OpenGL and IOKit frameworks to the project as dependencies. They can all be
found in `/System/Library/Frameworks`.
@subsection build_link_osx With command-line on macOS
@ -359,7 +359,7 @@ the `-l` and `-framework` switches.
If you are using the dynamic GLFW library, which is named `libglfw.3.dylib`, do:
@code{.sh}
cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo
cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit
@endcode
If you are using the static library, named `libglfw3.a`, substitute `-lglfw3`

View File

@ -85,6 +85,13 @@ transparent window framebuffers. If the running X server does not support this
extension or there is no running compositing manager, the
`GLFW_TRANSPARENT_FRAMEBUFFER` framebuffer hint will have no effect.
GLFW uses both the Xcursor extension and the freedesktop cursor conventions to
provide an expanded set of standard cursor shapes. If the running X server does
not support this extension or the current cursor theme does not support the
conventions, the `GLFW_RESIZE_NWSE_CURSOR`, `GLFW_RESIZE_NESW_CURSOR` and
`GLFW_NOT_ALLOWED_CURSOR` shapes will not be available and other shapes may use
legacy images.
@section compat_wayland Wayland protocols and IPC standards

View File

@ -373,12 +373,15 @@ A cursor with a [standard shape](@ref shapes) from the current system cursor
theme can be can be created with @ref glfwCreateStandardCursor.
@code
GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR);
GLFWcursor* url_cursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR);
@endcode
These cursor objects behave in the exact same way as those created with @ref
glfwCreateCursor except that the system cursor theme provides the actual image.
A few of these shapes are not available everywhere. If a shape is unavailable,
`NULL` is returned. See @ref glfwCreateStandardCursor for details.
@subsubsection cursor_destruction Cursor destruction

View File

@ -9,6 +9,24 @@
@subsection features_34 New features in version 3.4
@subsubsection standard_cursors_34 More standard cursors
GLFW now provides the standard cursor shapes @ref GLFW_RESIZE_NWSE_CURSOR and
@ref GLFW_RESIZE_NESW_CURSOR for diagonal resizing, @ref GLFW_RESIZE_ALL_CURSOR
for omni-directional resizing and @ref GLFW_NOT_ALLOWED_CURSOR for showing an
action is not allowed.
Unlike the original set, these shapes may not be available everywhere and
creation will then fail with the new @ref GLFW_CURSOR_UNAVAILABLE error.
The cursors for horizontal and vertical resizing are now referred to as @ref
GLFW_RESIZE_EW_CURSOR and @ref GLFW_RESIZE_NS_CURSOR, and the pointing hand
cursor is now referred to as @ref GLFW_POINTING_HAND_CURSOR. The older names
are still available.
For more information see @ref cursor_standard.
@subsubsection features_34_win32_keymenu Support for keyboard access to Windows window menu
GLFW now provides the
@ -34,6 +52,12 @@ add_subdirectory(path/to/glfw)
@endcode
@subsubsection corevideo_34 CoreVideo dependency has been removed
GLFW no longer depends on the CoreVideo framework on macOS and it no longer
needs to be specified during compilation or linking.
@subsection deprecations_34 Deprecations in version 3.4
@subsection removals_34 Removals in 3.4
@ -44,6 +68,14 @@ add_subdirectory(path/to/glfw)
@subsubsection types_34 New types in version 3.4
@subsubsection constants_34 New constants in version 3.4
- @ref GLFW_POINTING_HAND_CURSOR
- @ref GLFW_RESIZE_EW_CURSOR
- @ref GLFW_RESIZE_NS_CURSOR
- @ref GLFW_RESIZE_NWSE_CURSOR
- @ref GLFW_RESIZE_NESW_CURSOR
- @ref GLFW_RESIZE_ALL_CURSOR
- @ref GLFW_NOT_ALLOWED_CURSOR
- @ref GLFW_CURSOR_UNAVAILABLE
- @ref GLFW_WIN32_KEYBOARD_MENU

View File

@ -1,7 +1,7 @@
link_libraries(glfw)
include_directories(${glfw_INCLUDE_DIRS} "${GLFW_SOURCE_DIR}/deps")
include_directories("${GLFW_SOURCE_DIR}/deps")
if (MATH_LIBRARY)
link_libraries("${MATH_LIBRARY}")
@ -11,27 +11,10 @@ if (MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
if (GLFW_USE_OSMESA)
add_definitions(-DUSE_NATIVE_OSMESA)
endif()
if (WIN32)
set(ICON glfw.rc)
elseif (APPLE)
set(ICON glfw.icns)
set_source_files_properties(glfw.icns PROPERTIES
MACOSX_PACKAGE_LOCATION "Resources")
endif()
if (${CMAKE_VERSION} VERSION_EQUAL "3.1.0" OR
${CMAKE_VERSION} VERSION_GREATER "3.1.0")
set(CMAKE_C_STANDARD 99)
else()
# Remove this fallback when removing support for CMake version less than 3.1
add_compile_options("$<$<C_COMPILER_ID:AppleClang>:-std=c99>"
"$<$<C_COMPILER_ID:Clang>:-std=c99>"
"$<$<C_COMPILER_ID:GNU>:-std=c99>")
endif()
set(GLAD_GL "${GLFW_SOURCE_DIR}/deps/glad/gl.h"
@ -51,20 +34,26 @@ add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD_GL})
add_executable(triangle-opengl WIN32 MACOSX_BUNDLE triangle-opengl.c ${ICON} ${GLAD_GL})
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}")
target_link_libraries(particles Threads::Threads)
if (RT_LIBRARY)
target_link_libraries(particles "${RT_LIBRARY}")
endif()
set(WINDOWS_BINARIES boing gears heightmap particles sharing splitview triangle-opengl wave)
set(GUI_ONLY_BINARIES boing gears heightmap particles sharing splitview
triangle-opengl wave)
set(CONSOLE_BINARIES offscreen)
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
C_STANDARD 99
FOLDER "GLFW3/Examples")
if (GLFW_USE_OSMESA)
target_compile_definitions(offscreen PRIVATE USE_NATIVE_OSMESA)
endif()
if (MSVC)
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
set_target_properties(${WINDOWS_BINARIES} PROPERTIES
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
LINK_FLAGS "/ENTRY:mainCRTStartup")
endif()
@ -78,11 +67,12 @@ if (APPLE)
set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView")
set_target_properties(wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave")
set_target_properties(${WINDOWS_BINARIES} PROPERTIES
RESOURCE glfw.icns
set_source_files_properties(glfw.icns PROPERTIES
MACOSX_PACKAGE_LOCATION "Resources")
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION}
MACOSX_BUNDLE_ICON_FILE glfw.icns
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/MacOSXBundleInfo.plist.in")
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/Info.plist.in")
endif()

View File

@ -757,6 +757,17 @@ extern "C" {
* @analysis Application programmer error. Fix the offending call.
*/
#define GLFW_NO_WINDOW_CONTEXT 0x0001000A
/*! @brief The specified cursor shape is not available.
*
* The specified standard cursor shape is not available, either because the
* current system cursor theme does not provide it or because it is not
* available on the platform.
*
* @analysis Platform or system settings limitation. Pick another
* [standard cursor shape](@ref shapes) or create a
* [custom cursor](@ref cursor_custom).
*/
#define GLFW_CURSOR_UNAVAILABLE 0x0001000B
/*! @} */
/*! @addtogroup window
@ -1039,14 +1050,15 @@ extern "C" {
/*! @defgroup shapes Standard cursor shapes
* @brief Standard system cursor shapes.
*
* See [standard cursor creation](@ref cursor_standard) for how these are used.
* These are the [standard cursor shapes](@ref cursor_standard) that can be
* requested from the window system.
*
* @ingroup input
* @{ */
/*! @brief The regular arrow cursor shape.
*
* The regular arrow cursor.
* The regular arrow cursor shape.
*/
#define GLFW_ARROW_CURSOR 0x00036001
/*! @brief The text input I-beam cursor shape.
@ -1054,26 +1066,91 @@ extern "C" {
* The text input I-beam cursor shape.
*/
#define GLFW_IBEAM_CURSOR 0x00036002
/*! @brief The crosshair shape.
/*! @brief The crosshair cursor shape.
*
* The crosshair shape.
* The crosshair cursor shape.
*/
#define GLFW_CROSSHAIR_CURSOR 0x00036003
/*! @brief The hand shape.
/*! @brief The pointing hand cursor shape.
*
* The hand shape.
* The pointing hand cursor shape.
*/
#define GLFW_HAND_CURSOR 0x00036004
/*! @brief The horizontal resize arrow shape.
#define GLFW_POINTING_HAND_CURSOR 0x00036004
/*! @brief The horizontal resize/move arrow shape.
*
* The horizontal resize arrow shape.
* The horizontal resize/move arrow shape. This is usually a horizontal
* double-headed arrow.
*/
#define GLFW_HRESIZE_CURSOR 0x00036005
/*! @brief The vertical resize arrow shape.
#define GLFW_RESIZE_EW_CURSOR 0x00036005
/*! @brief The vertical resize/move arrow shape.
*
* The vertical resize arrow shape.
* The vertical resize/move shape. This is usually a vertical double-headed
* arrow.
*/
#define GLFW_VRESIZE_CURSOR 0x00036006
#define GLFW_RESIZE_NS_CURSOR 0x00036006
/*! @brief The top-left to bottom-right diagonal resize/move arrow shape.
*
* The top-left to bottom-right diagonal resize/move shape. This is usually
* a diagonal double-headed arrow.
*
* @note @macos This shape is provided by a private system API and may fail
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
*
* @note @x11 This shape is provided by a newer standard not supported by all
* cursor themes.
*
* @note @wayland This shape is provided by a newer standard not supported by
* all cursor themes.
*/
#define GLFW_RESIZE_NWSE_CURSOR 0x00036007
/*! @brief The top-right to bottom-left diagonal resize/move arrow shape.
*
* The top-right to bottom-left diagonal resize/move shape. This is usually
* a diagonal double-headed arrow.
*
* @note @macos This shape is provided by a private system API and may fail
* with @ref GLFW_CURSOR_UNAVAILABLE in the future.
*
* @note @x11 This shape is provided by a newer standard not supported by all
* cursor themes.
*
* @note @wayland This shape is provided by a newer standard not supported by
* all cursor themes.
*/
#define GLFW_RESIZE_NESW_CURSOR 0x00036008
/*! @brief The omni-directional resize/move cursor shape.
*
* The omni-directional resize cursor/move shape. This is usually either
* a combined horizontal and vertical double-headed arrow or a grabbing hand.
*/
#define GLFW_RESIZE_ALL_CURSOR 0x00036009
/*! @brief The operation-not-allowed shape.
*
* The operation-not-allowed shape. This is usually a circle with a diagonal
* line through it.
*
* @note @x11 This shape is provided by a newer standard not supported by all
* cursor themes.
*
* @note @wayland This shape is provided by a newer standard not supported by
* all cursor themes.
*/
#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
/*! @brief Legacy name for compatibility.
*
* This is an alias for compatibility with earlier versions.
*/
#define GLFW_HRESIZE_CURSOR GLFW_RESIZE_EW_CURSOR
/*! @brief Legacy name for compatibility.
*
* This is an alias for compatibility with earlier versions.
*/
#define GLFW_VRESIZE_CURSOR GLFW_RESIZE_NS_CURSOR
/*! @brief Legacy name for compatibility.
*
* This is an alias for compatibility with earlier versions.
*/
#define GLFW_HAND_CURSOR GLFW_POINTING_HAND_CURSOR
/*! @} */
#define GLFW_CONNECTED 0x00040001
@ -2608,7 +2685,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* [High Resolution Guidelines for OS X](https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html)
* in the Mac Developer Library. The GLFW test and example programs use
* a custom `Info.plist` template for this, which can be found as
* `CMake/MacOSXBundleInfo.plist.in` in the source tree.
* `CMake/Info.plist.in` in the source tree.
*
* @remark @macos When activating frame autosaving with
* [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified
@ -4417,19 +4494,44 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
/*! @brief Creates a cursor with a standard shape.
*
* Returns a cursor with a [standard shape](@ref shapes), that can be set for
* a window with @ref glfwSetCursor.
* Returns a cursor with a standard shape, that can be set for a window with
* @ref glfwSetCursor. The images for these cursors come from the system
* cursor theme and their exact appearance will vary between platforms.
*
* Most of these shapes are guaranteed to exist on every supported platform but
* a few may not be present. See the table below for details.
*
* Cursor shape | Windows | macOS | X11 | Wayland
* ------------------------------ | ------- | ----- | ------ | -------
* @ref GLFW_ARROW_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_IBEAM_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_CROSSHAIR_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_POINTING_HAND_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_RESIZE_EW_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_RESIZE_NS_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_RESIZE_NWSE_CURSOR | Yes | Yes<sup>1</sup> | Maybe<sup>2</sup> | Maybe<sup>2</sup>
* @ref GLFW_RESIZE_NESW_CURSOR | Yes | Yes<sup>1</sup> | Maybe<sup>2</sup> | Maybe<sup>2</sup>
* @ref GLFW_RESIZE_ALL_CURSOR | Yes | Yes | Yes | Yes
* @ref GLFW_NOT_ALLOWED_CURSOR | Yes | Yes | Maybe<sup>2</sup> | Maybe<sup>2</sup>
*
* 1) This uses a private system API and may fail in the future.
*
* 2) This uses a newer standard that not all cursor themes support.
*
* If the requested shape is not available, this function emits a @ref
* GLFW_CURSOR_UNAVAILABLE error and returns `NULL`.
*
* @param[in] shape One of the [standard shapes](@ref shapes).
* @return A new cursor ready to use or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
* GLFW_INVALID_ENUM, @ref GLFW_CURSOR_UNAVAILABLE and @ref
* GLFW_PLATFORM_ERROR.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref cursor_object
* @sa @ref cursor_standard
* @sa @ref glfwCreateCursor
*
* @since Added in version 3.1.

View File

@ -1,118 +1,96 @@
set(common_HEADERS internal.h mappings.h
"${GLFW_BINARY_DIR}/src/glfw_config.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h")
set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c)
add_library(glfw "${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h"
internal.h mappings.h context.c init.c input.c monitor.c
vulkan.c window.c)
if (_GLFW_COCOA)
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
posix_thread.h nsgl_context.h egl_context.h osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_thread.c
nsgl_context.m egl_context.c osmesa_context.c)
target_sources(glfw PRIVATE cocoa_platform.h cocoa_joystick.h posix_thread.h
nsgl_context.h egl_context.h osmesa_context.h
cocoa_init.m cocoa_joystick.m cocoa_monitor.m
cocoa_window.m cocoa_time.c posix_thread.c
nsgl_context.m egl_context.c osmesa_context.c)
elseif (_GLFW_WIN32)
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h
wgl_context.h egl_context.h osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_joystick.c
win32_monitor.c win32_time.c win32_thread.c win32_window.c
wgl_context.c egl_context.c osmesa_context.c)
target_sources(glfw PRIVATE win32_platform.h win32_joystick.h wgl_context.h
egl_context.h osmesa_context.h win32_init.c
win32_joystick.c win32_monitor.c win32_time.c
win32_thread.c win32_window.c wgl_context.c
egl_context.c osmesa_context.c)
elseif (_GLFW_X11)
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h posix_time.h
posix_thread.h glx_context.h egl_context.h osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c
xkb_unicode.c posix_time.c posix_thread.c glx_context.c
egl_context.c osmesa_context.c)
target_sources(glfw PRIVATE x11_platform.h xkb_unicode.h posix_time.h
posix_thread.h glx_context.h egl_context.h
osmesa_context.h x11_init.c x11_monitor.c
x11_window.c xkb_unicode.c posix_time.c
posix_thread.c glx_context.c egl_context.c
osmesa_context.c)
elseif (_GLFW_WAYLAND)
set(glfw_HEADERS ${common_HEADERS} wl_platform.h
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c
posix_time.c posix_thread.c xkb_unicode.c
egl_context.c osmesa_context.c)
ecm_add_wayland_client_protocol(glfw_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml"
BASENAME xdg-shell)
ecm_add_wayland_client_protocol(glfw_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
BASENAME xdg-decoration)
ecm_add_wayland_client_protocol(glfw_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/viewporter/viewporter.xml"
BASENAME viewporter)
ecm_add_wayland_client_protocol(glfw_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
BASENAME relative-pointer-unstable-v1)
ecm_add_wayland_client_protocol(glfw_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
BASENAME pointer-constraints-unstable-v1)
ecm_add_wayland_client_protocol(glfw_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml"
BASENAME idle-inhibit-unstable-v1)
target_sources(glfw PRIVATE wl_platform.h posix_time.h posix_thread.h
xkb_unicode.h egl_context.h osmesa_context.h
wl_init.c wl_monitor.c wl_window.c posix_time.c
posix_thread.c xkb_unicode.c egl_context.c
osmesa_context.c)
elseif (_GLFW_OSMESA)
set(glfw_HEADERS ${common_HEADERS} null_platform.h null_joystick.h
posix_time.h posix_thread.h osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} null_init.c null_monitor.c null_window.c
null_joystick.c posix_time.c posix_thread.c osmesa_context.c)
target_sources(glfw PRIVATE null_platform.h null_joystick.h posix_time.h
posix_thread.h osmesa_context.h null_init.c
null_monitor.c null_window.c null_joystick.c
posix_time.c posix_thread.c osmesa_context.c)
endif()
if (_GLFW_X11 OR _GLFW_WAYLAND)
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
set(glfw_HEADERS ${glfw_HEADERS} linux_joystick.h)
set(glfw_SOURCES ${glfw_SOURCES} linux_joystick.c)
target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c)
else()
set(glfw_HEADERS ${glfw_HEADERS} null_joystick.h)
set(glfw_SOURCES ${glfw_SOURCES} null_joystick.c)
target_sources(glfw PRIVATE null_joystick.h null_joystick.c)
endif()
endif()
if (APPLE)
# For some reason, CMake doesn't know about .m
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
if (_GLFW_WAYLAND)
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/xdg-shell/xdg-shell.xml"
BASENAME xdg-shell)
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml"
BASENAME xdg-decoration)
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/stable/viewporter/viewporter.xml"
BASENAME viewporter)
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
BASENAME relative-pointer-unstable-v1)
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
BASENAME pointer-constraints-unstable-v1)
ecm_add_wayland_client_protocol(GLFW_WAYLAND_PROTOCOL_SOURCES
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/idle-inhibit/idle-inhibit-unstable-v1.xml"
BASENAME idle-inhibit-unstable-v1)
target_sources(glfw PRIVATE ${GLFW_WAYLAND_PROTOCOL_SOURCES})
endif()
# Make GCC and Clang warn about declarations that VS 2010 and 2012 won't accept
# for all source files that VS will build
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
if (WIN32)
set(windows_SOURCES ${glfw_SOURCES})
else()
set(windows_SOURCES ${common_SOURCES})
endif()
set_source_files_properties(${windows_SOURCES} PROPERTIES
COMPILE_FLAGS -Wdeclaration-after-statement)
if (WIN32 AND BUILD_SHARED_LIBS)
configure_file(glfw.rc.in glfw.rc @ONLY)
target_sources(glfw PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/glfw.rc")
endif()
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
configure_file(glfw_config.h.in glfw_config.h @ONLY)
target_compile_definitions(glfw PRIVATE _GLFW_USE_CONFIG_H)
target_sources(glfw PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/glfw_config.h")
set_target_properties(glfw PROPERTIES
OUTPUT_NAME ${GLFW_LIB_NAME}
VERSION ${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}
SOVERSION ${GLFW_VERSION_MAJOR}
POSITION_INDEPENDENT_CODE ON
C_STANDARD 99
C_EXTENSIONS OFF
DEFINE_SYMBOL _GLFW_BUILD_DLL
FOLDER "GLFW3")
if (${CMAKE_VERSION} VERSION_EQUAL "3.1.0" OR
${CMAKE_VERSION} VERSION_GREATER "3.1.0")
set_target_properties(glfw PROPERTIES C_STANDARD 99)
else()
# Remove this fallback when removing support for CMake version less than 3.1
target_compile_options(glfw PRIVATE
"$<$<C_COMPILER_ID:AppleClang>:-std=c99>"
"$<$<C_COMPILER_ID:Clang>:-std=c99>"
"$<$<C_COMPILER_ID:GNU>:-std=c99>")
endif()
target_compile_definitions(glfw PRIVATE _GLFW_USE_CONFIG_H)
target_include_directories(glfw PUBLIC
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
@ -120,26 +98,50 @@ target_include_directories(glfw PRIVATE
"${GLFW_SOURCE_DIR}/src"
"${GLFW_BINARY_DIR}/src"
${glfw_INCLUDE_DIRS})
target_link_libraries(glfw PRIVATE Threads::Threads ${glfw_LIBRARIES})
if (APPLE)
# For some reason CMake didn't know about .m until version 3.16
set_source_files_properties(cocoa_init.m cocoa_joystick.m cocoa_monitor.m
cocoa_window.m nsgl_context.m PROPERTIES
LANGUAGE C)
endif()
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
# Make GCC and Clang warn about declarations that VS 2010 and 2012 won't
# accept for all source files that VS will build
set_source_files_properties(context.c init.c input.c monitor.c vulkan.c
window.c win32_init.c win32_joystick.c
win32_monitor.c win32_time.c win32_thread.c
win32_window.c wgl_context.c egl_context.c
osmesa_context.c PROPERTIES
COMPILE_FLAGS -Wdeclaration-after-statement)
# Enable a reasonable set of warnings (no, -Wextra is not reasonable)
target_compile_options(glfw PRIVATE "-Wall")
endif()
if (WIN32)
target_compile_definitions(glfw PRIVATE _UNICODE)
endif()
# HACK: When building on MinGW, WINVER and UNICODE need to be defined before
# the inclusion of stddef.h (by glfw3.h), which is itself included before
# win32_platform.h. We define them here until a saner solution can be found
# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack.
target_compile_definitions(glfw PRIVATE
"$<$<BOOL:${MINGW}>:UNICODE;WINVER=0x0501>")
# Enable a reasonable set of warnings (no, -Wextra is not reasonable)
target_compile_options(glfw PRIVATE
"$<$<C_COMPILER_ID:AppleClang>:-Wall>"
"$<$<C_COMPILER_ID:Clang>:-Wall>"
"$<$<C_COMPILER_ID:GNU>:-Wall>")
if (MINGW)
target_compile_definitions(glfw PRIVATE UNICODE WINVER=0x0501)
endif()
if (BUILD_SHARED_LIBS)
if (WIN32)
if (MINGW)
# Remove the dependency on the shared version of libgcc
# NOTE: MinGW-w64 has the correct default but MinGW needs this
target_link_options(glfw PRIVATE "-static-libgcc")
target_link_libraries(glfw PRIVATE "-static-libgcc")
# Remove the lib prefix on the DLL (but not the import library)
set_target_properties(glfw PROPERTIES PREFIX "")
@ -151,11 +153,8 @@ if (BUILD_SHARED_LIBS)
set_target_properties(glfw PROPERTIES IMPORT_SUFFIX "dll.lib")
endif()
target_compile_definitions(glfw INTERFACE GLFW_DLL)
target_compile_definitions(glfw INTERFACE GLFW_DLL)
elseif (APPLE)
# Add -fno-common to work around a bug in Apple's GCC
target_compile_options(glfw PRIVATE "-fno-common")
set_target_properties(glfw PROPERTIES
INSTALL_NAME_DIR "${CMAKE_INSTALL_LIBDIR}")
endif()
@ -164,10 +163,6 @@ if (BUILD_SHARED_LIBS)
# Hide symbols not explicitly tagged for export from the shared library
target_compile_options(glfw PRIVATE "-fvisibility=hidden")
endif()
target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES})
else()
target_link_libraries(glfw INTERFACE ${glfw_LIBRARIES})
endif()
if (MSVC)

View File

@ -431,9 +431,8 @@ static GLFWbool initializeTIS(void)
// In case we are unbundled, make us a proper UI application
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
// Menu bar setup must go between sharedApplication above and
// finishLaunching below, in order to properly emulate the behavior
// of NSApplicationMain
// Menu bar setup must go between sharedApplication and finishLaunching
// in order to properly emulate the behavior of NSApplicationMain
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
{
@ -448,9 +447,9 @@ static GLFWbool initializeTIS(void)
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[NSApp stop:nil];
_glfw.ns.finishedLaunching = GLFW_TRUE;
_glfwPlatformPostEmptyEvent();
[NSApp stop:nil];
}
- (void)applicationDidHide:(NSNotification *)notification

View File

@ -331,7 +331,7 @@ void _glfwInitJoysticksNS(void)
return;
}
for (int i = 0; i < sizeof(usages) / sizeof(long); i++)
for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++)
{
const long page = kHIDPage_GenericDesktop;

View File

@ -144,7 +144,7 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode)
// Convert Core Graphics display mode to GLFW video mode
//
static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
CVDisplayLinkRef link)
double fallbackRefreshRate)
{
GLFWvidmode result;
result.width = (int) CGDisplayModeGetWidth(mode);
@ -152,11 +152,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode));
if (result.refreshRate == 0)
{
const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link);
if (!(time.flags & kCVTimeIsIndefinite))
result.refreshRate = (int) (time.timeScale / (double) time.timeValue);
}
result.refreshRate = (int) round(fallbackRefreshRate);
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
@ -238,6 +234,68 @@ static GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
return GLFW_FALSE;
}
// Returns the display refresh rate queried from the I/O registry
//
static double getFallbackRefreshRate(CGDirectDisplayID displayID)
{
double refreshRate = 60.0;
io_iterator_t it;
io_service_t service;
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
IOServiceMatching("IOFramebuffer"),
&it) != 0)
{
return refreshRate;
}
while ((service = IOIteratorNext(it)) != 0)
{
const CFNumberRef indexRef =
IORegistryEntryCreateCFProperty(service,
CFSTR("IOFramebufferOpenGLIndex"),
kCFAllocatorDefault,
kNilOptions);
if (!indexRef)
continue;
uint32_t index = 0;
CFNumberGetValue(indexRef, kCFNumberIntType, &index);
CFRelease(indexRef);
if (CGOpenGLDisplayMaskToDisplayID(1 << index) != displayID)
continue;
const CFNumberRef clockRef =
IORegistryEntryCreateCFProperty(service,
CFSTR("IOFBCurrentPixelClock"),
kCFAllocatorDefault,
kNilOptions);
const CFNumberRef countRef =
IORegistryEntryCreateCFProperty(service,
CFSTR("IOFBCurrentPixelCount"),
kCFAllocatorDefault,
kNilOptions);
if (!clockRef || !countRef)
break;
uint32_t clock = 0, count = 0;
CFNumberGetValue(clockRef, kCFNumberIntType, &clock);
CFNumberGetValue(countRef, kCFNumberIntType, &count);
CFRelease(clockRef);
CFRelease(countRef);
if (clock > 0 && count > 0)
refreshRate = clock / (double) count;
break;
}
IOObjectRelease(it);
return refreshRate;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
@ -294,6 +352,11 @@ void _glfwPollMonitorsNS(void)
free(name);
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]);
if (CGDisplayModeGetRefreshRate(mode) == 0.0)
monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(displays[i]);
CGDisplayModeRelease(mode);
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
}
@ -318,9 +381,6 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
if (_glfwCompareVideoModes(&current, best) == 0)
return;
CVDisplayLinkRef link;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
const CFIndex count = CFArrayGetCount(modes);
CGDisplayModeRef native = NULL;
@ -331,7 +391,8 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
if (!modeIsGood(dm))
continue;
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
const GLFWvidmode mode =
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
if (_glfwCompareVideoModes(best, &mode) == 0)
{
native = dm;
@ -350,7 +411,6 @@ void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
}
CFRelease(modes);
CVDisplayLinkRelease(link);
}
// Restore the previously saved (original) video mode
@ -440,9 +500,6 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
*count = 0;
CVDisplayLinkRef link;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
const CFIndex found = CFArrayGetCount(modes);
GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode));
@ -453,7 +510,8 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
if (!modeIsGood(dm))
continue;
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
const GLFWvidmode mode =
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
CFIndex j;
for (j = 0; j < *count; j++)
@ -471,7 +529,6 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
}
CFRelease(modes);
CVDisplayLinkRelease(link);
return result;
} // autoreleasepool
@ -481,15 +538,10 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
{
@autoreleasepool {
CVDisplayLinkRef link;
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
*mode = vidmodeFromCGDisplayMode(native, link);
*mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate);
CGDisplayModeRelease(native);
CVDisplayLinkRelease(link);
} // autoreleasepool
}

View File

@ -28,8 +28,6 @@
#include <dlfcn.h>
#include <Carbon/Carbon.h>
#include <CoreVideo/CVBase.h>
#include <CoreVideo/CVDisplayLink.h>
// NOTE: All of NSGL was deprecated in the 10.14 SDK
// This disables the pointless warnings for every symbol we use
@ -170,6 +168,7 @@ typedef struct _GLFWmonitorNS
CGDisplayModeRef previousMode;
uint32_t unitNumber;
id screen;
double fallbackRefreshRate;
} _GLFWmonitorNS;

View File

@ -322,12 +322,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
_glfwInputWindowFocus(window, GLFW_FALSE);
}
- (void)windowDidChangeScreen:(NSNotification *)notification
{
if (window->context.source == GLFW_NATIVE_CONTEXT_API)
_glfwUpdateDisplayLinkDisplayNSGL(window);
}
@end
@ -891,10 +885,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
@autoreleasepool {
if (!_glfw.ns.finishedLaunching)
{
[NSApp run];
_glfw.ns.finishedLaunching = GLFW_TRUE;
}
if (!createNativeWindow(window, wndconfig, fbconfig))
return GLFW_FALSE;
@ -967,13 +958,14 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
} // autoreleasepool
}
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title)
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{
@autoreleasepool {
[window->ns.object setTitle:@(title)];
NSString* string = @(title);
[window->ns.object setTitle:string];
// HACK: Set the miniwindow title explicitly as setTitle: doesn't update it
// if the window lacks NSWindowStyleMaskTitled
[window->ns.object setMiniwindowTitle:@(title)];
[window->ns.object setMiniwindowTitle:string];
} // autoreleasepool
}
@ -1385,6 +1377,9 @@ void _glfwPlatformPollEvents(void)
{
@autoreleasepool {
if (!_glfw.ns.finishedLaunching)
[NSApp run];
for (;;)
{
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
@ -1404,6 +1399,9 @@ void _glfwPlatformWaitEvents(void)
{
@autoreleasepool {
if (!_glfw.ns.finishedLaunching)
[NSApp run];
// I wanted to pass NO to dequeue:, and rely on PollEvents to
// dequeue and send. For reasons not at all clear to me, passing
// NO to dequeue: causes this method never to return.
@ -1422,6 +1420,9 @@ void _glfwPlatformWaitEventsTimeout(double timeout)
{
@autoreleasepool {
if (!_glfw.ns.finishedLaunching)
[NSApp run];
NSDate* date = [NSDate dateWithTimeIntervalSinceNow:timeout];
NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:date
@ -1439,6 +1440,9 @@ void _glfwPlatformPostEmptyEvent(void)
{
@autoreleasepool {
if (!_glfw.ns.finishedLaunching)
[NSApp run];
NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined
location:NSMakePoint(0, 0)
modifierFlags:0
@ -1603,23 +1607,49 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
@autoreleasepool {
if (shape == GLFW_ARROW_CURSOR)
cursor->ns.object = [NSCursor arrowCursor];
else if (shape == GLFW_IBEAM_CURSOR)
cursor->ns.object = [NSCursor IBeamCursor];
else if (shape == GLFW_CROSSHAIR_CURSOR)
cursor->ns.object = [NSCursor crosshairCursor];
else if (shape == GLFW_HAND_CURSOR)
cursor->ns.object = [NSCursor pointingHandCursor];
else if (shape == GLFW_HRESIZE_CURSOR)
cursor->ns.object = [NSCursor resizeLeftRightCursor];
else if (shape == GLFW_VRESIZE_CURSOR)
cursor->ns.object = [NSCursor resizeUpDownCursor];
SEL cursorSelector = NULL;
// HACK: Try to use a private message
if (shape == GLFW_RESIZE_EW_CURSOR)
cursorSelector = NSSelectorFromString(@"_windowResizeEastWestCursor");
else if (shape == GLFW_RESIZE_NS_CURSOR)
cursorSelector = NSSelectorFromString(@"_windowResizeNorthSouthCursor");
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
cursorSelector = NSSelectorFromString(@"_windowResizeNorthWestSouthEastCursor");
else if (shape == GLFW_RESIZE_NESW_CURSOR)
cursorSelector = NSSelectorFromString(@"_windowResizeNorthEastSouthWestCursor");
if (cursorSelector && [NSCursor respondsToSelector:cursorSelector])
{
id object = [NSCursor performSelector:cursorSelector];
if ([object isKindOfClass:[NSCursor class]])
cursor->ns.object = object;
}
if (!cursor->ns.object)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve standard cursor");
if (shape == GLFW_ARROW_CURSOR)
cursor->ns.object = [NSCursor arrowCursor];
else if (shape == GLFW_IBEAM_CURSOR)
cursor->ns.object = [NSCursor IBeamCursor];
else if (shape == GLFW_CROSSHAIR_CURSOR)
cursor->ns.object = [NSCursor crosshairCursor];
else if (shape == GLFW_POINTING_HAND_CURSOR)
cursor->ns.object = [NSCursor pointingHandCursor];
else if (shape == GLFW_RESIZE_EW_CURSOR)
cursor->ns.object = [NSCursor resizeLeftRightCursor];
else if (shape == GLFW_RESIZE_NS_CURSOR)
cursor->ns.object = [NSCursor resizeUpDownCursor];
else if (shape == GLFW_RESIZE_ALL_CURSOR)
cursor->ns.object = [NSCursor closedHandCursor];
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
cursor->ns.object = [NSCursor operationNotAllowedCursor];
}
if (!cursor->ns.object)
{
_glfwInputError(GLFW_CURSOR_UNAVAILABLE,
"Cocoa: Standard cursor shape unavailable");
return GLFW_FALSE;
}

View File

@ -123,23 +123,24 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
continue;
#if defined(_GLFW_X11)
XVisualInfo vi = {0};
// Only consider EGLConfigs with associated Visuals
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
if (!vi.visualid)
continue;
if (desired->transparent)
{
int count;
XVisualInfo* vis = XGetVisualInfo(_glfw.x11.display,
VisualIDMask, &vi,
&count);
if (vis)
XVisualInfo vi = {0};
// Only consider EGLConfigs with associated Visuals
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
if (!vi.visualid)
continue;
if (desired->transparent)
{
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
XFree(vis);
int count;
XVisualInfo* vis =
XGetVisualInfo(_glfw.x11.display, VisualIDMask, &vi, &count);
if (vis)
{
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
XFree(vis);
}
}
}
#endif // _GLFW_X11

30
src/glfw.rc.in Normal file
View File

@ -0,0 +1,30 @@
#include <winver.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION @GLFW_VERSION_MAJOR@,@GLFW_VERSION_MINOR@,@GLFW_VERSION_PATCH@,0
PRODUCTVERSION @GLFW_VERSION_MAJOR@,@GLFW_VERSION_MINOR@,@GLFW_VERSION_PATCH@,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0
{
BLOCK "StringFileInfo"
{
BLOCK "040904B0"
{
VALUE "CompanyName", "GLFW"
VALUE "FileDescription", "GLFW @GLFW_VERSION@ DLL"
VALUE "FileVersion", "@GLFW_VERSION@"
VALUE "OriginalFilename", "glfw3.dll"
VALUE "ProductName", "GLFW"
VALUE "ProductVersion", "@GLFW_VERSION@"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x409, 1200
}
}

View File

@ -1 +1,3 @@
include(CMakeFindDependencyMacro)
find_dependency(Threads)
include("${CMAKE_CURRENT_LIST_DIR}/glfw3Targets.cmake")

View File

@ -45,8 +45,6 @@
// Define this to 1 if building GLFW for OSMesa
#cmakedefine _GLFW_OSMESA
// Define this to 1 if building as a shared library / dynamic library / DLL
#cmakedefine _GLFW_BUILD_DLL
// Define this to 1 to use Vulkan loader linked statically into application
#cmakedefine _GLFW_VULKAN_STATIC

View File

@ -189,6 +189,8 @@ void _glfwInputError(int code, const char* format, ...)
strcpy(description, "The requested format is unavailable");
else if (code == GLFW_NO_WINDOW_CONTEXT)
strcpy(description, "The specified window has no context");
else if (code == GLFW_CURSOR_UNAVAILABLE)
strcpy(description, "The specified cursor shape is unavailable");
else
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
}

View File

@ -757,9 +757,13 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
if (shape != GLFW_ARROW_CURSOR &&
shape != GLFW_IBEAM_CURSOR &&
shape != GLFW_CROSSHAIR_CURSOR &&
shape != GLFW_HAND_CURSOR &&
shape != GLFW_HRESIZE_CURSOR &&
shape != GLFW_VRESIZE_CURSOR)
shape != GLFW_POINTING_HAND_CURSOR &&
shape != GLFW_RESIZE_EW_CURSOR &&
shape != GLFW_RESIZE_NS_CURSOR &&
shape != GLFW_RESIZE_NWSE_CURSOR &&
shape != GLFW_RESIZE_NESW_CURSOR &&
shape != GLFW_RESIZE_ALL_CURSOR &&
shape != GLFW_NOT_ALLOWED_CURSOR)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
return NULL;

View File

@ -44,10 +44,6 @@ typedef struct _GLFWcontextNSGL
{
id pixelFormat;
id object;
CVDisplayLinkRef displayLink;
atomic_int swapInterval;
int swapIntervalsPassed;
id swapIntervalCond;
} _GLFWcontextNSGL;
@ -67,5 +63,4 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextNSGL(_GLFWwindow* window);
void _glfwUpdateDisplayLinkDisplayNSGL(_GLFWwindow* window);

View File

@ -28,29 +28,8 @@
#include "internal.h"
// Display link callback for manual swap interval implementation
// This is based on a similar workaround added to SDL2
//
static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink,
const CVTimeStamp* now,
const CVTimeStamp* outputTime,
CVOptionFlags flagsIn,
CVOptionFlags* flagsOut,
void* userInfo)
{
_GLFWwindow* window = (_GLFWwindow *) userInfo;
const int interval = atomic_load(&window->context.nsgl.swapInterval);
if (interval > 0)
{
[window->context.nsgl.swapIntervalCond lock];
window->context.nsgl.swapIntervalsPassed++;
[window->context.nsgl.swapIntervalCond signal];
[window->context.nsgl.swapIntervalCond unlock];
}
return kCVReturnSuccess;
}
#include <unistd.h>
#include <math.h>
static void makeContextCurrentNSGL(_GLFWwindow* window)
{
@ -70,19 +49,28 @@ static void swapBuffersNSGL(_GLFWwindow* window)
{
@autoreleasepool {
const int interval = atomic_load(&window->context.nsgl.swapInterval);
if (interval > 0)
// HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
// windows with a non-visible occlusion state
if (!([window->ns.object occlusionState] & NSWindowOcclusionStateVisible))
{
[window->context.nsgl.swapIntervalCond lock];
do
int interval = 0;
[window->context.nsgl.object getValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
if (interval > 0)
{
[window->context.nsgl.swapIntervalCond wait];
} while (window->context.nsgl.swapIntervalsPassed % interval != 0);
window->context.nsgl.swapIntervalsPassed = 0;
[window->context.nsgl.swapIntervalCond unlock];
const double framerate = 60.0;
const uint64_t frequency = _glfwPlatformGetTimerFrequency();
const uint64_t value = _glfwPlatformGetTimerValue();
const double elapsed = value / (double) frequency;
const double period = 1.0 / framerate;
const double delay = period - fmod(elapsed, period);
usleep(floorl(delay * 1e6));
}
}
// ARP appears to be unnecessary, but this is future-proof
[window->context.nsgl.object flushBuffer];
} // autoreleasepool
@ -91,11 +79,14 @@ static void swapBuffersNSGL(_GLFWwindow* window)
static void swapIntervalNSGL(int interval)
{
@autoreleasepool {
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
atomic_store(&window->context.nsgl.swapInterval, interval);
[window->context.nsgl.swapIntervalCond lock];
window->context.nsgl.swapIntervalsPassed = 0;
[window->context.nsgl.swapIntervalCond unlock];
if (window)
{
[window->context.nsgl.object setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
}
} // autoreleasepool
}
@ -123,17 +114,6 @@ static void destroyContextNSGL(_GLFWwindow* window)
{
@autoreleasepool {
if (window->context.nsgl.displayLink)
{
if (CVDisplayLinkIsRunning(window->context.nsgl.displayLink))
CVDisplayLinkStop(window->context.nsgl.displayLink);
CVDisplayLinkRelease(window->context.nsgl.displayLink);
}
[window->context.nsgl.swapIntervalCond release];
window->context.nsgl.swapIntervalCond = nil;
[window->context.nsgl.pixelFormat release];
window->context.nsgl.pixelFormat = nil;
@ -354,17 +334,10 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
forParameter:NSOpenGLContextParameterSurfaceOpacity];
}
if (window->ns.retina)
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
GLint interval = 0;
[window->context.nsgl.object setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
[window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.retina];
[window->context.nsgl.object setView:window->ns.view];
window->context.nsgl.swapIntervalCond = [NSCondition new];
window->context.makeCurrent = makeContextCurrentNSGL;
window->context.swapBuffers = swapBuffersNSGL;
window->context.swapInterval = swapIntervalNSGL;
@ -372,26 +345,9 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
window->context.getProcAddress = getProcAddressNSGL;
window->context.destroy = destroyContextNSGL;
CVDisplayLinkCreateWithActiveCGDisplays(&window->context.nsgl.displayLink);
CVDisplayLinkSetOutputCallback(window->context.nsgl.displayLink,
&displayLinkCallback,
window);
CVDisplayLinkStart(window->context.nsgl.displayLink);
_glfwUpdateDisplayLinkDisplayNSGL(window);
return GLFW_TRUE;
}
void _glfwUpdateDisplayLinkDisplayNSGL(_GLFWwindow* window)
{
CGDirectDisplayID displayID =
[[[window->ns.object screen] deviceDescription][@"NSScreenNumber"] unsignedIntValue];
if (!displayID)
return;
CVDisplayLinkSetCurrentCGDisplay(window->context.nsgl.displayLink, displayID);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////

View File

@ -27,8 +27,11 @@
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#define _POSIX_C_SOURCE 199309L
#include "internal.h"
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
@ -41,7 +44,7 @@
//
void _glfwInitTimerPOSIX(void)
{
#if defined(CLOCK_MONOTONIC)
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
@ -64,7 +67,7 @@ void _glfwInitTimerPOSIX(void)
uint64_t _glfwPlatformGetTimerValue(void)
{
#if defined(CLOCK_MONOTONIC)
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
if (_glfw.timer.posix.monotonic)
{
struct timespec ts;

View File

@ -33,6 +33,7 @@
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <wchar.h>
// Callback for EnumDisplayMonitors in createMonitor

View File

@ -2068,14 +2068,25 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
id = OCR_IBEAM;
else if (shape == GLFW_CROSSHAIR_CURSOR)
id = OCR_CROSS;
else if (shape == GLFW_HAND_CURSOR)
else if (shape == GLFW_POINTING_HAND_CURSOR)
id = OCR_HAND;
else if (shape == GLFW_HRESIZE_CURSOR)
else if (shape == GLFW_RESIZE_EW_CURSOR)
id = OCR_SIZEWE;
else if (shape == GLFW_VRESIZE_CURSOR)
else if (shape == GLFW_RESIZE_NS_CURSOR)
id = OCR_SIZENS;
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
id = OCR_SIZENWSE;
else if (shape == GLFW_RESIZE_NESW_CURSOR)
id = OCR_SIZENESW;
else if (shape == GLFW_RESIZE_ALL_CURSOR)
id = OCR_SIZEALL;
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
id = OCR_NO;
else
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Unknown standard cursor");
return GLFW_FALSE;
}
cursor->win32.handle = LoadImageW(NULL,
MAKEINTRESOURCEW(id), IMAGE_CURSOR, 0, 0,

View File

@ -26,6 +26,8 @@
// It is fine to use C99 in this file because it will not be built with VS
//========================================================================
#define _POSIX_C_SOURCE 199309L
#include "internal.h"
#include <assert.h>
@ -38,6 +40,7 @@
#include <sys/mman.h>
#include <sys/timerfd.h>
#include <unistd.h>
#include <time.h>
#include <wayland-client.h>
@ -125,6 +128,7 @@ static void pointerHandleLeave(void* data,
_glfw.wl.serial = serial;
_glfw.wl.pointerFocus = NULL;
_glfwInputCursorEnter(window, GLFW_FALSE);
_glfw.wl.cursorPreviousName = NULL;
}
static void setCursor(_GLFWwindow* window, const char* name)
@ -196,6 +200,7 @@ static void pointerHandleMotion(void* data,
window->wl.cursorPosX = x;
window->wl.cursorPosY = y;
_glfwInputCursorPos(window, x, y);
_glfw.wl.cursorPreviousName = NULL;
return;
case topDecoration:
if (y < _GLFW_DECORATION_WIDTH)

View File

@ -770,28 +770,6 @@ static void handleEvents(int timeout)
}
}
// Translates a GLFW standard cursor to a theme cursor name
//
static char *translateCursorShape(int shape)
{
switch (shape)
{
case GLFW_ARROW_CURSOR:
return "left_ptr";
case GLFW_IBEAM_CURSOR:
return "xterm";
case GLFW_CROSSHAIR_CURSOR:
return "crosshair";
case GLFW_HAND_CURSOR:
return "grabbing";
case GLFW_HRESIZE_CURSOR:
return "sb_h_double_arrow";
case GLFW_VRESIZE_CURSOR:
return "sb_v_double_arrow";
}
return NULL;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
@ -1233,26 +1211,79 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
struct wl_cursor* standardCursor;
const char* name = NULL;
standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
translateCursorShape(shape));
if (!standardCursor)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Standard cursor \"%s\" not found",
translateCursorShape(shape));
return GLFW_FALSE;
}
// Try the XDG names first
if (shape == GLFW_ARROW_CURSOR)
name = "default";
else if (shape == GLFW_IBEAM_CURSOR)
name = "text";
else if (shape == GLFW_CROSSHAIR_CURSOR)
name = "crosshair";
else if (shape == GLFW_POINTING_HAND_CURSOR)
name = "pointer";
else if (shape == GLFW_RESIZE_EW_CURSOR)
name = "ew-resize";
else if (shape == GLFW_RESIZE_NS_CURSOR)
name = "ns-resize";
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
name = "nwse-resize";
else if (shape == GLFW_RESIZE_NESW_CURSOR)
name = "nesw-resize";
else if (shape == GLFW_RESIZE_ALL_CURSOR)
name = "all-scroll";
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
name = "not-allowed";
cursor->wl.cursor = standardCursor;
cursor->wl.currentImage = 0;
cursor->wl.cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name);
if (_glfw.wl.cursorThemeHiDPI)
{
standardCursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI,
translateCursorShape(shape));
cursor->wl.cursorHiDPI = standardCursor;
cursor->wl.cursorHiDPI =
wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, name);
}
if (!cursor->wl.cursor)
{
// Fall back to the core X11 names
if (shape == GLFW_ARROW_CURSOR)
name = "left_ptr";
else if (shape == GLFW_IBEAM_CURSOR)
name = "xterm";
else if (shape == GLFW_CROSSHAIR_CURSOR)
name = "crosshair";
else if (shape == GLFW_POINTING_HAND_CURSOR)
name = "hand2";
else if (shape == GLFW_RESIZE_EW_CURSOR)
name = "sb_h_double_arrow";
else if (shape == GLFW_RESIZE_NS_CURSOR)
name = "sb_v_double_arrow";
else if (shape == GLFW_RESIZE_ALL_CURSOR)
name = "fleur";
else
{
_glfwInputError(GLFW_CURSOR_UNAVAILABLE,
"Wayland: Standard cursor shape unavailable");
return GLFW_FALSE;
}
cursor->wl.cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme, name);
if (!cursor->wl.cursor)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Failed to create standard cursor \"%s\"",
name);
return GLFW_FALSE;
}
if (_glfw.wl.cursorThemeHiDPI)
{
if (!cursor->wl.cursorHiDPI)
{
cursor->wl.cursorHiDPI =
wl_cursor_theme_get_cursor(_glfw.wl.cursorThemeHiDPI, name);
}
}
}
return GLFW_TRUE;

View File

@ -36,6 +36,7 @@
#include <limits.h>
#include <stdio.h>
#include <locale.h>
#include <unistd.h>
// Create key code translation tables
@ -491,6 +492,12 @@ static GLFWbool initExtensions(void)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
_glfw.x11.xcursor.GetTheme = (PFN_XcursorGetTheme)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorGetTheme");
_glfw.x11.xcursor.GetDefaultSize = (PFN_XcursorGetDefaultSize)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorGetDefaultSize");
_glfw.x11.xcursor.LibraryLoadImage = (PFN_XcursorLibraryLoadImage)
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorLibraryLoadImage");
}
#if defined(__CYGWIN__)

View File

@ -85,9 +85,15 @@ typedef int (* PFN_XRRUpdateConfiguration)(XEvent*);
typedef XcursorImage* (* PFN_XcursorImageCreate)(int,int);
typedef void (* PFN_XcursorImageDestroy)(XcursorImage*);
typedef Cursor (* PFN_XcursorImageLoadCursor)(Display*,const XcursorImage*);
typedef char* (* PFN_XcursorGetTheme)(Display*);
typedef int (* PFN_XcursorGetDefaultSize)(Display*);
typedef XcursorImage* (* PFN_XcursorLibraryLoadImage)(const char*,const char*,int);
#define XcursorImageCreate _glfw.x11.xcursor.ImageCreate
#define XcursorImageDestroy _glfw.x11.xcursor.ImageDestroy
#define XcursorImageLoadCursor _glfw.x11.xcursor.ImageLoadCursor
#define XcursorGetTheme _glfw.x11.xcursor.GetTheme
#define XcursorGetDefaultSize _glfw.x11.xcursor.GetDefaultSize
#define XcursorLibraryLoadImage _glfw.x11.xcursor.LibraryLoadImage
typedef Bool (* PFN_XineramaIsActive)(Display*);
typedef Bool (* PFN_XineramaQueryExtension)(Display*,int*,int*);
@ -180,6 +186,7 @@ typedef struct _GLFWwindowX11
{
Colormap colormap;
Window handle;
Window parent;
XIC ic;
GLFWbool overrideRedirect;
@ -352,6 +359,9 @@ typedef struct _GLFWlibraryX11
PFN_XcursorImageCreate ImageCreate;
PFN_XcursorImageDestroy ImageDestroy;
PFN_XcursorImageLoadCursor ImageLoadCursor;
PFN_XcursorGetTheme GetTheme;
PFN_XcursorGetDefaultSize GetDefaultSize;
PFN_XcursorLibraryLoadImage LibraryLoadImage;
} xcursor;
struct {

View File

@ -613,46 +613,40 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
window->x11.transparent = _glfwIsVisualTransparentX11(visual);
// Create the actual window
XSetWindowAttributes wa = { 0 };
wa.colormap = window->x11.colormap;
wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
ExposureMask | FocusChangeMask | VisibilityChangeMask |
EnterWindowMask | LeaveWindowMask | PropertyChangeMask;
_glfwGrabErrorHandlerX11();
window->x11.handle = XCreateWindow(_glfw.x11.display,
_glfw.x11.root,
0, 0, // Position
width, height,
0, // Border width
depth, // Color depth
InputOutput,
visual,
CWBorderPixel | CWColormap | CWEventMask,
&wa);
_glfwReleaseErrorHandlerX11();
if (!window->x11.handle)
{
XSetWindowAttributes wa;
const unsigned long wamask = CWBorderPixel | CWColormap | CWEventMask;
wa.colormap = window->x11.colormap;
wa.border_pixel = 0;
wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
ExposureMask | FocusChangeMask | VisibilityChangeMask |
EnterWindowMask | LeaveWindowMask | PropertyChangeMask;
_glfwGrabErrorHandlerX11();
window->x11.handle = XCreateWindow(_glfw.x11.display,
_glfw.x11.root,
0, 0,
width, height,
0, // Border width
depth, // Color depth
InputOutput,
visual,
wamask,
&wa);
_glfwReleaseErrorHandlerX11();
if (!window->x11.handle)
{
_glfwInputErrorX11(GLFW_PLATFORM_ERROR,
"X11: Failed to create window");
return GLFW_FALSE;
}
XSaveContext(_glfw.x11.display,
window->x11.handle,
_glfw.x11.context,
(XPointer) window);
_glfwInputErrorX11(GLFW_PLATFORM_ERROR,
"X11: Failed to create window");
return GLFW_FALSE;
}
XSaveContext(_glfw.x11.display,
window->x11.handle,
_glfw.x11.context,
(XPointer) window);
if (!wndconfig->decorated)
_glfwPlatformSetWindowDecorated(window, GLFW_FALSE);
@ -682,7 +676,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
{
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeReplace, (unsigned char*) &states, count);
PropModeReplace, (unsigned char*) states, count);
}
}
@ -787,6 +781,13 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
NULL);
}
if (window->x11.ic)
{
unsigned long filter = 0;
if (XGetICValues(window->x11.ic, XNFilterEvents, &filter, NULL) == NULL)
XSelectInput(_glfw.x11.display, window->x11.handle, wa.event_mask | filter);
}
_glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
_glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
@ -1257,6 +1258,18 @@ static void processEvent(XEvent *event)
switch (event->type)
{
case CreateNotify:
{
window->x11.parent = event->xcreatewindow.parent;
return;
}
case ReparentNotify:
{
window->x11.parent = event->xreparent.parent;
return;
}
case KeyPress:
{
const int key = translateKey(keycode);
@ -1541,18 +1554,28 @@ static void processEvent(XEvent *event)
window->x11.height = event->xconfigure.height;
}
if (event->xconfigure.x != window->x11.xpos ||
event->xconfigure.y != window->x11.ypos)
{
if (window->x11.overrideRedirect || event->xany.send_event)
{
_glfwInputWindowPos(window,
event->xconfigure.x,
event->xconfigure.y);
int xpos = event->xconfigure.x;
int ypos = event->xconfigure.y;
window->x11.xpos = event->xconfigure.x;
window->x11.ypos = event->xconfigure.y;
}
// NOTE: ConfigureNotify events from the server are in local
// coordinates, so if we are reparented we need to translate
// the position into root (screen) coordinates
if (!event->xany.send_event && window->x11.parent != _glfw.x11.root)
{
Window dummy;
XTranslateCoordinates(_glfw.x11.display,
window->x11.parent,
_glfw.x11.root,
xpos, ypos,
&xpos, &ypos,
&dummy);
}
if (xpos != window->x11.xpos || ypos != window->x11.ypos)
{
_glfwInputWindowPos(window, xpos, ypos);
window->x11.xpos = xpos;
window->x11.ypos = ypos;
}
return;
@ -2340,18 +2363,67 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
{
if (_glfw.x11.NET_WM_STATE &&
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
if (!_glfw.x11.NET_WM_STATE ||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
!_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
{
return;
}
if (_glfwPlatformWindowVisible(window))
{
sendEventToWM(window,
_glfw.x11.NET_WM_STATE,
_NET_WM_STATE_ADD,
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,
1, 0);
XFlush(_glfw.x11.display);
_glfw.x11.NET_WM_STATE,
_NET_WM_STATE_ADD,
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,
1, 0);
}
else
{
Atom* states = NULL;
unsigned long count =
_glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.NET_WM_STATE,
XA_ATOM,
(unsigned char**) &states);
// NOTE: We don't check for failure as this property may not exist yet
// and that's fine (and we'll create it implicitly with append)
Atom missing[2] =
{
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ
};
unsigned long missingCount = 2;
for (unsigned long i = 0; i < count; i++)
{
for (unsigned long j = 0; j < missingCount; j++)
{
if (states[i] == missing[j])
{
missing[j] = missing[missingCount - 1];
missingCount--;
}
}
}
if (states)
XFree(states);
if (!missingCount)
return;
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeAppend,
(unsigned char*) missing,
missingCount);
}
XFlush(_glfw.x11.display);
}
void _glfwPlatformShowWindow(_GLFWwindow* window)
@ -2371,6 +2443,9 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{
if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION)
return;
sendEventToWM(window,
_glfw.x11.NET_WM_STATE,
_NET_WM_STATE_ADD,
@ -2567,7 +2642,7 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
if (_glfwPlatformWindowVisible(window))
{
const Atom action = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
const long action = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
sendEventToWM(window,
_glfw.x11.NET_WM_STATE,
action,
@ -2576,15 +2651,16 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
}
else
{
Atom* states;
Atom* states = NULL;
unsigned long i, count;
count = _glfwGetWindowPropertyX11(window->x11.handle,
_glfw.x11.NET_WM_STATE,
XA_ATOM,
(unsigned char**) &states);
if (!states)
return;
// NOTE: We don't check for failure as this property may not exist yet
// and that's fine (and we'll create it implicitly with append)
if (enabled)
{
@ -2594,32 +2670,36 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
break;
}
if (i == count)
{
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeAppend,
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
1);
}
if (i < count)
return;
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeAppend,
(unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
1);
}
else
else if (states)
{
for (i = 0; i < count; i++)
{
if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
{
states[i] = states[count - 1];
count--;
}
break;
}
if (i == count)
return;
states[i] = states[count - 1];
count--;
XChangeProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_STATE, XA_ATOM, 32,
PropModeReplace, (unsigned char*) &states, count);
PropModeReplace, (unsigned char*) states, count);
}
XFree(states);
if (states)
XFree(states);
}
XFlush(_glfw.x11.display);
@ -2823,29 +2903,76 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
int native = 0;
if (_glfw.x11.xcursor.handle)
{
char* theme = XcursorGetTheme(_glfw.x11.display);
if (theme)
{
const int size = XcursorGetDefaultSize(_glfw.x11.display);
const char* name = NULL;
if (shape == GLFW_ARROW_CURSOR)
native = XC_left_ptr;
else if (shape == GLFW_IBEAM_CURSOR)
native = XC_xterm;
else if (shape == GLFW_CROSSHAIR_CURSOR)
native = XC_crosshair;
else if (shape == GLFW_HAND_CURSOR)
native = XC_hand2;
else if (shape == GLFW_HRESIZE_CURSOR)
native = XC_sb_h_double_arrow;
else if (shape == GLFW_VRESIZE_CURSOR)
native = XC_sb_v_double_arrow;
else
return GLFW_FALSE;
if (shape == GLFW_ARROW_CURSOR)
name = "default";
else if (shape == GLFW_IBEAM_CURSOR)
name = "text";
else if (shape == GLFW_CROSSHAIR_CURSOR)
name = "crosshair";
else if (shape == GLFW_POINTING_HAND_CURSOR)
name = "pointer";
else if (shape == GLFW_RESIZE_EW_CURSOR)
name = "ew-resize";
else if (shape == GLFW_RESIZE_NS_CURSOR)
name = "ns-resize";
else if (shape == GLFW_RESIZE_NWSE_CURSOR)
name = "nwse-resize";
else if (shape == GLFW_RESIZE_NESW_CURSOR)
name = "nesw-resize";
else if (shape == GLFW_RESIZE_ALL_CURSOR)
name = "all-scroll";
else if (shape == GLFW_NOT_ALLOWED_CURSOR)
name = "not-allowed";
XcursorImage* image = XcursorLibraryLoadImage(name, theme, size);
if (image)
{
cursor->x11.handle = XcursorImageLoadCursor(_glfw.x11.display, image);
XcursorImageDestroy(image);
}
}
}
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
if (!cursor->x11.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to create standard cursor");
return GLFW_FALSE;
unsigned int native = 0;
if (shape == GLFW_ARROW_CURSOR)
native = XC_left_ptr;
else if (shape == GLFW_IBEAM_CURSOR)
native = XC_xterm;
else if (shape == GLFW_CROSSHAIR_CURSOR)
native = XC_crosshair;
else if (shape == GLFW_POINTING_HAND_CURSOR)
native = XC_hand2;
else if (shape == GLFW_RESIZE_EW_CURSOR)
native = XC_sb_h_double_arrow;
else if (shape == GLFW_RESIZE_NS_CURSOR)
native = XC_sb_v_double_arrow;
else if (shape == GLFW_RESIZE_ALL_CURSOR)
native = XC_fleur;
else
{
_glfwInputError(GLFW_CURSOR_UNAVAILABLE,
"X11: Standard cursor shape unavailable");
return GLFW_FALSE;
}
cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
if (!cursor->x11.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Failed to create standard cursor");
return GLFW_FALSE;
}
}
return GLFW_TRUE;

View File

@ -1,7 +1,7 @@
link_libraries(glfw)
include_directories(${glfw_INCLUDE_DIRS} "${GLFW_SOURCE_DIR}/deps")
include_directories("${GLFW_SOURCE_DIR}/deps")
if (MATH_LIBRARY)
link_libraries("${MATH_LIBRARY}")
@ -20,17 +20,6 @@ set(GETOPT "${GLFW_SOURCE_DIR}/deps/getopt.h"
set(TINYCTHREAD "${GLFW_SOURCE_DIR}/deps/tinycthread.h"
"${GLFW_SOURCE_DIR}/deps/tinycthread.c")
if (${CMAKE_VERSION} VERSION_EQUAL "3.1.0" OR
${CMAKE_VERSION} VERSION_GREATER "3.1.0")
set(CMAKE_C_STANDARD 99)
else()
# Remove this fallback when removing support for CMake version less than 3.1
add_compile_options("$<$<C_COMPILER_ID:AppleClang>:-std=c99>"
"$<$<C_COMPILER_ID:Clang>:-std=c99>"
"$<$<C_COMPILER_ID:GNU>:-std=c99>")
endif()
add_executable(clipboard clipboard.c ${GETOPT} ${GLAD_GL})
add_executable(events events.c ${GETOPT} ${GLAD_GL})
add_executable(msaa msaa.c ${GETOPT} ${GLAD_GL})
@ -50,27 +39,28 @@ add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c ${GLAD_GL})
add_executable(threads WIN32 MACOSX_BUNDLE threads.c ${TINYCTHREAD} ${GLAD_GL})
add_executable(timeout WIN32 MACOSX_BUNDLE timeout.c ${GLAD_GL})
add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD_GL})
add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${ICON} ${GLAD_VULKAN})
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GETOPT} ${GLAD_GL})
add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN})
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GLAD_GL})
target_link_libraries(empty "${CMAKE_THREAD_LIBS_INIT}")
target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}")
target_link_libraries(empty Threads::Threads)
target_link_libraries(threads Threads::Threads)
if (RT_LIBRARY)
target_link_libraries(empty "${RT_LIBRARY}")
target_link_libraries(threads "${RT_LIBRARY}")
endif()
set(WINDOWS_BINARIES empty gamma icon inputlag joysticks opacity tearing
threads timeout title triangle-vulkan windows)
set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks opacity tearing
threads timeout title triangle-vulkan windows)
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
cursor)
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
C_STANDARD 99
FOLDER "GLFW3/Tests")
if (MSVC)
# Tell MSVC to use main instead of WinMain for Windows subsystem executables
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
LINK_FLAGS "/ENTRY:mainCRTStartup")
endif()
@ -84,12 +74,11 @@ if (APPLE)
set_target_properties(threads PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Threads")
set_target_properties(timeout PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Timeout")
set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title")
set_target_properties(triangle-vulkan PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Vulkan Triangle")
set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows")
set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
set_target_properties(${GUI_ONLY_BINARIES} PROPERTIES
MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION}
MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION}
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/MacOSXBundleInfo.plist.in")
MACOSX_BUNDLE_INFO_PLIST "${GLFW_SOURCE_DIR}/CMake/Info.plist.in")
endif()

View File

@ -69,7 +69,7 @@ static int swap_interval = 1;
static int wait_events = GLFW_TRUE;
static int animate_cursor = GLFW_FALSE;
static int track_cursor = GLFW_FALSE;
static GLFWcursor* standard_cursors[6];
static GLFWcursor* standard_cursors[10];
static GLFWcursor* tracking_cursor = NULL;
static void error_callback(int error, const char* description)
@ -271,28 +271,24 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
break;
case GLFW_KEY_1:
glfwSetCursor(window, standard_cursors[0]);
break;
case GLFW_KEY_2:
glfwSetCursor(window, standard_cursors[1]);
break;
case GLFW_KEY_3:
glfwSetCursor(window, standard_cursors[2]);
break;
case GLFW_KEY_4:
glfwSetCursor(window, standard_cursors[3]);
break;
case GLFW_KEY_5:
glfwSetCursor(window, standard_cursors[4]);
break;
case GLFW_KEY_6:
glfwSetCursor(window, standard_cursors[5]);
case GLFW_KEY_7:
case GLFW_KEY_8:
case GLFW_KEY_9:
{
int index = key - GLFW_KEY_1;
if (mods & GLFW_MOD_SHIFT)
index += 9;
if (index < sizeof(standard_cursors) / sizeof(standard_cursors[0]))
glfwSetCursor(window, standard_cursors[index]);
break;
}
case GLFW_KEY_F11:
case GLFW_KEY_ENTER:
@ -358,17 +354,16 @@ int main(void)
GLFW_ARROW_CURSOR,
GLFW_IBEAM_CURSOR,
GLFW_CROSSHAIR_CURSOR,
GLFW_HAND_CURSOR,
GLFW_HRESIZE_CURSOR,
GLFW_VRESIZE_CURSOR
GLFW_POINTING_HAND_CURSOR,
GLFW_RESIZE_EW_CURSOR,
GLFW_RESIZE_NS_CURSOR,
GLFW_RESIZE_NWSE_CURSOR,
GLFW_RESIZE_NESW_CURSOR,
GLFW_RESIZE_ALL_CURSOR,
GLFW_NOT_ALLOWED_CURSOR
};
standard_cursors[i] = glfwCreateStandardCursor(shapes[i]);
if (!standard_cursors[i])
{
glfwTerminate();
exit(EXIT_FAILURE);
}
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);

View File

@ -34,8 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "getopt.h"
static GLFWwindow* windows[4];
static const char* titles[] =
{
"Red",
@ -55,20 +54,26 @@ static const struct
{ 0.98f, 0.74f, 0.04f }
};
static void usage(void)
{
printf("Usage: windows [-h] [-b] [-f] \n");
printf("Options:\n");
printf(" -b create decorated windows\n");
printf(" -f set focus on show off for all but first window\n");
printf(" -h show this help\n");
}
static void error_callback(int error, const char* description)
{
fprintf(stderr, "Error: %s\n", description);
}
static void arrange_windows(void)
{
int xbase, ybase;
glfwGetWindowPos(windows[0], &xbase, &ybase);
for (int i = 0; i < 4; i++)
{
int left, top, right, bottom;
glfwGetWindowFrameSize(windows[i], &left, &top, &right, &bottom);
glfwSetWindowPos(windows[i],
xbase + (i & 1) * (200 + left + right),
ybase + (i >> 1) * (200 + top + bottom));
}
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (action != GLFW_PRESS)
@ -87,49 +92,34 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
case GLFW_KEY_ESCAPE:
glfwSetWindowShouldClose(window, GLFW_TRUE);
break;
case GLFW_KEY_D:
{
for (int i = 0; i < 4; i++)
{
const int decorated = glfwGetWindowAttrib(windows[i], GLFW_DECORATED);
glfwSetWindowAttrib(windows[i], GLFW_DECORATED, !decorated);
}
arrange_windows();
break;
}
}
}
int main(int argc, char** argv)
{
int i, ch;
int decorated = GLFW_FALSE;
int focusOnShow = GLFW_TRUE;
int running = GLFW_TRUE;
GLFWwindow* windows[4];
while ((ch = getopt(argc, argv, "bfh")) != -1)
{
switch (ch)
{
case 'b':
decorated = GLFW_TRUE;
break;
case 'f':
focusOnShow = GLFW_FALSE;
break;
case 'h':
usage();
exit(EXIT_SUCCESS);
default:
usage();
exit(EXIT_FAILURE);
}
}
glfwSetErrorCallback(error_callback);
if (!glfwInit())
exit(EXIT_FAILURE);
glfwWindowHint(GLFW_DECORATED, decorated);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
for (i = 0; i < 4; i++)
for (int i = 0; i < 4; i++)
{
int left, top, right, bottom;
if (i)
glfwWindowHint(GLFW_FOCUS_ON_SHOW, focusOnShow);
if (i > 0)
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
windows[i] = glfwCreateWindow(200, 200, titles[i], NULL, NULL);
if (!windows[i])
@ -143,32 +133,29 @@ int main(int argc, char** argv)
glfwMakeContextCurrent(windows[i]);
gladLoadGL(glfwGetProcAddress);
glClearColor(colors[i].r, colors[i].g, colors[i].b, 1.f);
glfwGetWindowFrameSize(windows[i], &left, &top, &right, &bottom);
glfwSetWindowPos(windows[i],
100 + (i & 1) * (200 + left + right),
100 + (i >> 1) * (200 + top + bottom));
}
for (i = 0; i < 4; i++)
arrange_windows();
for (int i = 0; i < 4; i++)
glfwShowWindow(windows[i]);
while (running)
for (;;)
{
for (i = 0; i < 4; i++)
for (int i = 0; i < 4; i++)
{
glfwMakeContextCurrent(windows[i]);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(windows[i]);
if (glfwWindowShouldClose(windows[i]))
running = GLFW_FALSE;
{
glfwTerminate();
exit(EXIT_SUCCESS);
}
}
glfwWaitEvents();
}
glfwTerminate();
exit(EXIT_SUCCESS);
}