Merge branch 'master' into transparent_windows

This commit is contained in:
Cem Karan 2016-08-29 11:23:06 -04:00
commit b1f6c9046a
99 changed files with 5009 additions and 1768 deletions

View File

@ -1,35 +1,118 @@
# Contribution Guide # Contribution Guide
This file is a work in progress and you can report errors or submit patches for ## Contents
it the same as any other file.
- [Asking a question](#asking-a-question)
- [Reporting a bug](#reporting-a-bug)
- [Reporting a compile or link bug](#reporting-a-compile-or-link-bug)
- [Reporting a segfault or other crash bug](#reporting-a-segfault-or-other-crash-bug)
- [Reporting a context creation bug](#reporting-a-context-creation-bug)
- [Reporting a monitor or video mode bug](#reporting-a-monitor-or-video-mode-bug)
- [Reporting an input or event bug](#reporting-an-input-or-event-bug)
- [Reporting some other library bug](#reporting-some-other-library-bug)
- [Reporting a documentation bug](#reporting-a-documentation-bug)
- [Reporting a website bug](#reporting-a-website-bug)
- [Requesting a feature](#requesting-a-feature)
- [Contributing a bug fix](#contributing-a-bug-fix)
- [Contributing a feature](#contributing-a-feature)
## Asking a question
Questions about how to use GLFW should be asked either in the [support
section](http://discourse.glfw.org/c/support) of the forum, under the [Stack
Overflow tag](https://stackoverflow.com/questions/tagged/glfw) or [Game
Development tag](https://gamedev.stackexchange.com/questions/tagged/glfw) on
Stack Exchange or in the IRC channel `#glfw` on
[Freenode](http://freenode.net/).
Questions about the design or implementation of GLFW or about future plans
should be asked in the [dev section](http://discourse.glfw.org/c/dev) of the
forum or in the IRC channel. Please don't open a GitHub issue to discuss design
questions without first checking with a maintainer.
## Reporting a bug ## Reporting a bug
If GLFW is behaving unexpectedly, make sure you have set an error callback. If GLFW is behaving unexpectedly at run-time, start by setting an [error
GLFW will often tell you the cause of an issue via this callback. callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling).
GLFW will often tell you the cause of an error via this callback. If it
doesn't, that might be a separate bug.
If GLFW is crashing or triggering asserts, make sure that all your object If GLFW is crashing or triggering asserts, make sure that all your object
handles and other pointers are valid. handles and other pointers are valid.
Always include the __operating system name and version__ (i.e. `Windows For bugs where it makes sense, a [Short, Self Contained, Correct (Compilable),
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW, Example](http://www.sscce.org/) is absolutely invaluable. Just put it inline in
include the __GLFW release version__ (i.e. `3.1.2`), otherwise include the the body text. Note that if the bug is reproducible with one of the test
__GLFW commit ID__ (i.e. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git. programs that come with GLFW, just mention that instead.
If possible, please also include the __GLFW version string__ (`3.2.0 X11 EGL
clock_gettime /dev/js XI Xf86vm`), as described __Don't worry about adding too much information__. Unimportant information can
[here](http://www.glfw.org/docs/latest/intro.html#intro_version_string). be abbreviated or removed later, but missing information can stall bug fixing,
especially when your schedule doesn't align with that of the maintainer.
There are issue labels for both platforms and GPU manufacturers, so there is no
need to mention these in the subject line. If you do, it will be removed when
the issue is labeled.
If your bug is already reported, please add any new information you have, or if
it already has everything, give it a :+1:.
### Reporting a compile or link bug ### Reporting a compile or link bug
__Note:__ GLFW needs many system APIs to do its job. See the [Building __Note:__ GLFW needs many system APIs to do its job, which on some platforms
applications](http://www.glfw.org/docs/latest/build.html) guide for more means linking to many system libraries. If you are using GLFW as a static
information. library, that means your application needs to link to these in addition to GLFW.
In addition to the information above, always include the complete build log from __Note:__ Check the [Compiling
your compiler and linker. Issue posts are editable so it can always be GLFW](http://www.glfw.org/docs/latest/compile.html) guide and or [Building
shortened later. applications](http://www.glfw.org/docs/latest/build.html) guide for before
opening an issue of this kind. Most issues are caused by a missing package or
linker flag.
Always include the __operating system name and version__ (e.g. `Windows
7 64-bit` or `Ubuntu 15.10`) and the __compiler name and version__ (e.g. `Visual
C++ 2015 Update 2`). If you are using an official release of GLFW,
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
Please also include the __complete build log__ from your compiler and linker,
even if it's long. It can always be shortened later, if necessary.
#### Quick template
```
OS and version:
Compiler version:
Release or commit:
Build log:
```
### Reporting a segfault or other crash bug
Always include the __operating system name and version__ (e.g. `Windows
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
Please also include any __error messages__ provided to your application via the
[error
callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
the __full call stack__ of the crash, or if the crash does not occur in debug
mode, mention that instead.
#### Quick template
```
OS and version:
Release or commit:
Error messages:
Call stack:
```
### Reporting a context creation bug ### Reporting a context creation bug
@ -42,19 +125,38 @@ Install drivers from the computer manufacturer or graphics card manufacturer
[Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to [Intel](https://www-ssl.intel.com/content/www/us/en/support/detect.html)) to
fix this. fix this.
__Note:__ AMD only supports OpenGL ES on Windows via EGL. EGL support is not __Note:__ AMD only supports OpenGL ES on Windows via EGL. See the
enabled in GLFW by default. You need to [enable EGL when [GLFW\_CONTEXT\_CREATION\_API](http://www.glfw.org/docs/latest/window_guide.html#window_hints_ctx)
compiling](http://www.glfw.org/docs/latest/compile.html) GLFW to use this. hint for how to select EGL.
The `glfwinfo` tool is included in the GLFW source tree as `tests/glfwinfo.c` Please verify that context creation also fails with the `glfwinfo` tool before
and is built along with the library. It lets you request any kind of context reporting it as a bug. This tool is included in the GLFW source tree as
and framebuffer format supported by the GLFW API without having to recompile. `tests/glfwinfo.c` and is built along with the library. It has switches for all
If context creation fails in your application, please verify that it also fails GLFW context and framebuffer hints. Run `glfwinfo -h` for a complete list.
with this tool before reporting it as a bug.
In addition to the information above (OS and GLFW version), always include the Always include the __operating system name and version__ (e.g. `Windows
__GPU model and driver version__ (i.e. `GeForce GTX660 with 352.79`) when 7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
reporting this kind of bug. include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
Please also include the __GLFW version string__ (`3.2.0 X11 EGL clock_gettime
/dev/js XI Xf86vm`), as described
[here](http://www.glfw.org/docs/latest/intro.html#intro_version_string), the
__GPU model and driver version__ (e.g. `GeForce GTX660 with 352.79`), and the
__output of `glfwinfo`__ (with switches matching any hints you set in your
code) when reporting this kind of bug. If this tool doesn't run on the machine,
mention that instead.
#### Quick template
```
OS and version:
GPU and driver:
Release or commit:
Version string:
glfwinfo output:
```
### Reporting a monitor or video mode bug ### Reporting a monitor or video mode bug
@ -63,23 +165,44 @@ __Note:__ On headless systems on some platforms, no monitors are reported. This
causes glfwGetPrimaryMonitor to return `NULL`, which not all applications are causes glfwGetPrimaryMonitor to return `NULL`, which not all applications are
prepared for. prepared for.
__Note:__ Some third-party tools report more video modes than those approved of __Note:__ Some third-party tools report more video modes than are approved of
by the OS. For safety and compatbility, GLFW only reports video modes the OS by the OS. For safety and compatibility, GLFW only reports video modes the OS
wants programs to use. This is not a bug. wants programs to use. This is not a bug.
The `monitors` tool is included in the GLFW source tree as `tests/monitors.c` The `monitors` tool is included in the GLFW source tree as `tests/monitors.c`
and is built along with the library. lists all information about connected and is built along with the library. It lists all information GLFW provides
monitors made available by GLFW. about monitors it detects.
In addition to the information above (OS and GLFW version), please also include Always include the __operating system name and version__ (e.g. `Windows
the output of the `monitors` tool when reporting this kind of bug. If it 7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
doesn't work at all, please mention this. include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
Please also include any __error messages__ provided to your application via the
[error
callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
the __output of `monitors`__ when reporting this kind of bug. If this tool
doesn't run on the machine, mention this instead.
### Reporting a window event bug #### Quick template
__Note:__ While GLFW tries to provide the exact same behavior between platforms, ```
the exact ordering of related window events will sometimes differ. OS and version:
Release or commit:
Error messages:
monitors output:
```
### Reporting an input or event bug
__Note:__ The exact ordering of related window events will sometimes differ.
__Note:__ Window moving and resizing (by the user) will block the main thread on some
platforms. This is not a bug. Set a [refresh
callback](http://www.glfw.org/docs/latest/window.html#window_refresh) if you
want to keep the window contents updated during a move or size operation.
The `events` tool is included in the GLFW source tree as `tests/events.c` and is The `events` tool is included in the GLFW source tree as `tests/events.c` and is
built along with the library. It prints all information provided to every built along with the library. It prints all information provided to every
@ -87,20 +210,137 @@ callback supported by GLFW as events occur. Each event is listed with the time
and a unique number to make discussions about event logs easier. The tool has and a unique number to make discussions about event logs easier. The tool has
command-line options for creating multiple windows and full screen windows. command-line options for creating multiple windows and full screen windows.
Always include the __operating system name and version__ (e.g. `Windows
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
Please also include any __error messages__ provided to your application via the
[error
callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
if relevant, the __output of `events`__ when reporting this kind of bug. If
this tool doesn't run on the machine, mention this instead.
#### Quick template
```
OS and version:
Release or commit:
Error messages:
events output:
```
### Reporting some other library bug
Always include the __operating system name and version__ (e.g. `Windows
7 64-bit` or `Ubuntu 15.10`). If you are using an official release of GLFW,
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
Please also include any __error messages__ provided to your application via the
[error
callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling), if
relevant.
#### Quick template
```
OS and version:
Release or commit:
Error messages:
```
### Reporting a documentation bug ### Reporting a documentation bug
If you found the error in the generated documentation then it's fine to just If you found a bug in the documentation, including this file, then it's fine to
link to that webpage. You don't need to figure out which documentation source just link to that web page or mention that source file. You don't need to match
file the text comes from. the source to the output or vice versa.
### Reporting a website bug
If the bug is in the documentation (anything under `/docs/`) then please see the
section above. Bugs in the rest of the site are reported to to the [website
source repository](https://github.com/glfw/website/issues).
## Requesting a feature
Please explain why you need the feature and how you intend to use it. If you
have a specific API design in mind, please add that as well. If you have or are
planning to write code for the feature, see the section below.
If there already is a request for the feature you need, add your specific use
case unless it is already mentioned. If it is, give it a :+1:.
## Contributing a bug fix ## Contributing a bug fix
There should be text here, but there isn't. __Note:__ You must have all necessary [intellectual
property rights](https://en.wikipedia.org/wiki/Intellectual_property) to any
code you contribute. If you did not write the code yourself, you must explain
where it came from and under what license you received it. Even code using the
same license as GLFW may not be copied without attribution.
__There is no preferred patch size__. A one character fix is just as welcome as
a thousand line one, if that is the appropriate size for the fix.
In addition to the code, a complete bug fix includes:
- Change log entry in `README.md`, describing the incorrect behavior
- Credits entries for all authors of the bug fix
Bug fixes will not be rejected because they don't include all the above parts,
but please keep in mind that maintainer time is finite and that there are many
other bugs and features to work on.
If the patch fixes a bug introduced after the last release, it should not get
a change log entry.
## Contributing a feature ## Contributing a feature
This is not (yet) the text you are looking for. __Note:__ You must have all necessary rights to any code you contribute. If you
did not write the code yourself, you must explain where it came from and under
what license. Even code using the same license as GLFW may not be copied
without attribution.
__There is no preferred patch size__. A one character change is just as welcome
as one adding a thousand line one, if that is the appropriate size for the
feature.
In addition to the code, a complete feature includes:
- Change log entry in `README.md`, listing all new symbols
- News page entry, briefly describing the feature
- Guide documentation, with minimal examples, in the relevant guide
- Reference documentation, with all applicable tags
- Cross-references and mentions in appropriate places
- Credits entries for all authors of the feature
If the feature requires platform-specific code, at minimum stubs must be added
for the new platform function to all supported and experimental platforms.
If it adds a new callback, support for it must be added to `tests/event.c`.
If it adds a new monitor property, support for it must be added to
`tests/monitor.c`.
If it adds a new OpenGL, OpenGL ES or Vulkan option or extension, support
for it must be added to `tests/glfwinfo.c` and the behavior of the library when
the extension is missing documented in `docs/compat.dox`.
Features will not be rejected because they don't include all the above parts,
but please keep in mind that maintainer time is finite and that there are many
other features and bugs to work on.
Please also keep in mind that any part of the public API that has been included
in a release cannot be changed until the next _major_ version. Features can be
added and existing parts can sometimes be overloaded (in the general sense of
doing more things, not in the C++ sense), but code written to the API of one
minor release should both compile and run on subsequent minor releases.

6
.gitignore vendored
View File

@ -40,11 +40,11 @@ src/wayland-relative-pointer-unstable-v1-protocol.c
# Compiled binaries # Compiled binaries
src/libglfw.so src/libglfw.so
src/libglfw.so.3 src/libglfw.so.3
src/libglfw.so.3.2 src/libglfw.so.3.3
src/libglfw.dylib src/libglfw.dylib
src/libglfw.dylib src/libglfw.dylib
src/libglfw.3.dylib src/libglfw.3.dylib
src/libglfw.3.2.dylib src/libglfw.3.3.dylib
src/libglfw3.a src/libglfw3.a
src/glfw3.lib src/glfw3.lib
src/glfw3.dll src/glfw3.dll
@ -67,6 +67,7 @@ tests/empty
tests/events tests/events
tests/gamma tests/gamma
tests/glfwinfo tests/glfwinfo
tests/icon
tests/iconify tests/iconify
tests/joysticks tests/joysticks
tests/monitors tests/monitors
@ -75,6 +76,7 @@ tests/reopen
tests/sharing tests/sharing
tests/tearing tests/tearing
tests/threads tests/threads
tests/timeout
tests/title tests/title
tests/version tests/version
tests/vulkan tests/vulkan

View File

@ -12,6 +12,9 @@ if (WIN32)
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
"$ENV{VULKAN_SDK}/Bin" "$ENV{VULKAN_SDK}/Bin"
"$ENV{VK_SDK_PATH}/Bin") "$ENV{VK_SDK_PATH}/Bin")
find_library(VULKAN_STATIC_LIBRARY NAMES vkstatic.1 HINTS
"$ENV{VULKAN_SDK}/Bin"
"$ENV{VK_SDK_PATH}/Bin")
else() else()
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
"$ENV{VULKAN_SDK}/Bin32" "$ENV{VULKAN_SDK}/Bin32"
@ -27,5 +30,5 @@ endif()
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Vulkan DEFAULT_MSG VULKAN_LIBRARY VULKAN_INCLUDE_DIR) find_package_handle_standard_args(Vulkan DEFAULT_MSG VULKAN_LIBRARY VULKAN_INCLUDE_DIR)
mark_as_advanced(VULKAN_INCLUDE_DIR VULKAN_LIBRARY) mark_as_advanced(VULKAN_INCLUDE_DIR VULKAN_LIBRARY VULKAN_STATIC_LIBRARY)

View File

@ -11,7 +11,7 @@ if (NOT CMAKE_VERSION VERSION_LESS "3.0")
endif() endif()
set(GLFW_VERSION_MAJOR "3") set(GLFW_VERSION_MAJOR "3")
set(GLFW_VERSION_MINOR "2") set(GLFW_VERSION_MINOR "3")
set(GLFW_VERSION_PATCH "0") set(GLFW_VERSION_PATCH "0")
set(GLFW_VERSION_EXTRA "") set(GLFW_VERSION_EXTRA "")
set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}") set(GLFW_VERSION "${GLFW_VERSION_MAJOR}.${GLFW_VERSION_MINOR}")
@ -25,6 +25,7 @@ option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON)
option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON)
option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON) option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON)
option(GLFW_INSTALL "Generate installation target" ON) option(GLFW_INSTALL "Generate installation target" ON)
option(GLFW_VULKAN_STATIC "Use the Vulkan loader statically linked into application" OFF)
option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF) option(GLFW_DOCUMENT_INTERNALS "Include internals in documentation" OFF)
if (WIN32) if (WIN32)
@ -57,7 +58,11 @@ else()
set(GLFW_LIB_NAME glfw3) set(GLFW_LIB_NAME glfw3)
endif() endif()
set(CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules") if (GLFW_VULKAN_STATIC)
set(_GLFW_VULKAN_STATIC 1)
endif()
list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
find_package(Vulkan) find_package(Vulkan)
@ -90,6 +95,15 @@ if (MSVC)
endif() endif()
if (MINGW) if (MINGW)
# Workaround for legacy MinGW not providing XInput and DirectInput
include(CheckIncludeFile)
check_include_file(dinput.h DINPUT_H_FOUND)
check_include_file(xinput.h XINPUT_H_FOUND)
if (NOT DINPUT_H_FOUND OR NOT XINPUT_H_FOUND)
list(APPEND glfw_INCLUDE_DIRS "${GLFW_SOURCE_DIR}/deps/mingw")
endif()
# Enable link-time exploit mitigation features enabled by default on MSVC # Enable link-time exploit mitigation features enabled by default on MSVC
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
@ -139,6 +153,21 @@ else()
message(FATAL_ERROR "No supported platform was detected") message(FATAL_ERROR "No supported platform was detected")
endif() endif()
#--------------------------------------------------------------------
# Add Vulkan static library if requested
#--------------------------------------------------------------------
if (GLFW_VULKAN_STATIC)
if (VULKAN_FOUND AND VULKAN_STATIC_LIBRARY)
list(APPEND glfw_LIBRARIES ${VULKAN_STATIC_LIBRARY})
else()
if (BUILD_SHARED_LIBS OR GLFW_BUILD_EXAMPLES OR GLFW_BUILD_TESTS)
message(FATAL_ERROR "Vulkan loader static library not found")
else()
message(WARNING "Vulkan loader static library not found")
endif()
endif()
endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Find and add Unix math and time libraries # Find and add Unix math and time libraries
#-------------------------------------------------------------------- #--------------------------------------------------------------------
@ -244,7 +273,7 @@ endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
if (_GLFW_WAYLAND) if (_GLFW_WAYLAND)
find_package(ECM REQUIRED NO_MODULE) find_package(ECM REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH}) list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH})
find_package(Wayland REQUIRED) find_package(Wayland REQUIRED)
find_package(WaylandScanner REQUIRED) find_package(WaylandScanner REQUIRED)
@ -299,20 +328,17 @@ if (_GLFW_COCOA)
find_library(IOKIT_FRAMEWORK IOKit) find_library(IOKIT_FRAMEWORK IOKit)
find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation) find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation)
find_library(CORE_VIDEO_FRAMEWORK CoreVideo) find_library(CORE_VIDEO_FRAMEWORK CoreVideo)
find_library(CARBON_FRAMEWORK Carbon)
mark_as_advanced(COCOA_FRAMEWORK mark_as_advanced(COCOA_FRAMEWORK
IOKIT_FRAMEWORK IOKIT_FRAMEWORK
CORE_FOUNDATION_FRAMEWORK CORE_FOUNDATION_FRAMEWORK
CORE_VIDEO_FRAMEWORK CORE_VIDEO_FRAMEWORK)
CARBON_FRAMEWORK)
list(APPEND glfw_LIBRARIES "${COCOA_FRAMEWORK}" list(APPEND glfw_LIBRARIES "${COCOA_FRAMEWORK}"
"${IOKIT_FRAMEWORK}" "${IOKIT_FRAMEWORK}"
"${CORE_FOUNDATION_FRAMEWORK}" "${CORE_FOUNDATION_FRAMEWORK}"
"${CORE_VIDEO_FRAMEWORK}" "${CORE_VIDEO_FRAMEWORK}")
"${CARBON_FRAMEWORK}")
set(glfw_PKG_DEPS "") set(glfw_PKG_DEPS "")
set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo -framework Carbon") set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo")
endif() endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
Copyright (c) 2002-2006 Marcus Geelnard Copyright (c) 2002-2006 Marcus Geelnard
Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages

157
README.md
View File

@ -2,14 +2,25 @@
[![Build status](https://travis-ci.org/glfw/glfw.svg?branch=master)](https://travis-ci.org/glfw/glfw) [![Build status](https://travis-ci.org/glfw/glfw.svg?branch=master)](https://travis-ci.org/glfw/glfw)
[![Build status](https://ci.appveyor.com/api/projects/status/0kf0ct9831i5l6sp/branch/master?svg=true)](https://ci.appveyor.com/project/elmindreda/glfw) [![Build status](https://ci.appveyor.com/api/projects/status/0kf0ct9831i5l6sp/branch/master?svg=true)](https://ci.appveyor.com/project/elmindreda/glfw)
[![Coverity Scan](https://scan.coverity.com/projects/4884/badge.svg)](https://scan.coverity.com/projects/glfw-glfw)
## Introduction ## Introduction
GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
Vulkan application development. It provides a simple, platform-independent API application development. It provides a simple, platform-independent API for
for creating windows, contexts and surfaces, reading input, handling events, etc. creating windows, contexts and surfaces, reading input, handling events, etc.
Version 3.2 is _not yet described_. GLFW is licensed under the [zlib/libpng
license](https://opensource.org/licenses/Zlib).
The latest stable release is version 3.2.1.
See the [downloads](http://www.glfw.org/download.html) page for details and
files, or fetch the `latest` branch, which always points to the latest stable
release. Each release starting with 3.0 also has a corresponding [annotated
tag](https://github.com/glfw/glfw/releases) with source and binary archives.
This is a development branch for version 3.3, which is _not yet described_.
If you are new to GLFW, you may find the If you are new to GLFW, you may find the
[tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW [tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW
@ -20,37 +31,43 @@ the GLFW 3 API.
## Compiling GLFW ## Compiling GLFW
See the [Compiling GLFW](http://www.glfw.org/docs/latest/compile.html) guide in GLFW itself requires only the headers and libraries for your window system. It
the GLFW documentation. does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
GLFW supports compilation on Windows with Visual C++ 2010 and later, MinGW and
MinGW-w64, on OS X with Clang and on Linux and other Unix-like systems with GCC
and Clang. It will likely compile in other environments as well, but this is
not regularly tested.
There are also [pre-compiled Windows
binaries](http://www.glfw.org/download.html) available for all compilers
supported on that platform.
See the [compilation guide](http://www.glfw.org/docs/latest/compile.html) in the
documentation for more information.
## Using GLFW ## Using GLFW
See the See the [building application guide](http://www.glfw.org/docs/latest/build.html)
[Building programs that use GLFW](http://www.glfw.org/docs/latest/build.html) guide in the documentation for more information.
guide in the GLFW documentation.
## Reporting bugs ## System requirements
Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues). GLFW supports Windows XP and later, OS X 10.7 Lion and later, and Linux and
Please always include the name and version of the OS where the bug occurs and other Unix-like systems with the X Window System. Experimental implementations
the version of GLFW used. If you have cloned it, include the commit ID used. for the Wayland protocol and the Mir display server are available but not yet
officially supported.
If it's a build issue, please also include the build log and the name and See the [compatibility guide](http://www.glfw.org/docs/latest/compat.html)
version of your development environment. in the documentation for more information.
If it's a context creation issue, please also include the make and model of your
graphics card and the version of your driver.
This will help both us and other people experiencing the same bug.
## Dependencies ## Dependencies
GLFW itself needs only the headers and libraries for your window system. It GLFW itself depends only on the headers and libraries for your window system.
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
The examples and test programs depend on a number of tiny libraries. These are The examples and test programs depend on a number of tiny libraries. These are
located in the `deps/` directory. located in the `deps/` directory.
@ -69,94 +86,37 @@ The Vulkan example additionally requires the Vulkan SDK to be installed, or it
will not be included in the build. will not be included in the build.
The documentation is generated with [Doxygen](http://doxygen.org/). If CMake The documentation is generated with [Doxygen](http://doxygen.org/). If CMake
does not find Doxygen, the documentation will not be generated. does not find Doxygen, the documentation will not be generated when you build.
## Reporting bugs
Bugs are reported to our [issue tracker](https://github.com/glfw/glfw/issues).
Please check the [contribution
guide](https://github.com/glfw/glfw/blob/master/.github/CONTRIBUTING.md) for
information on what to include when reporting a bug.
## Changelog ## Changelog
- Added `glfwVulkanSupported`, `glfwGetRequiredInstanceExtensions`, - Bugfix: Calling `glfwMaximizeWindow` on a full screen window was not ignored
`glfwGetInstanceProcAddress`, `glfwGetPhysicalDevicePresentationSupport` and
`glfwCreateWindowSurface` for platform independent Vulkan support
- Added `glfwSetWindowMonitor` for switching between windowed and full screen
modes and updating the monitor and desired video mode of full screen windows
- Added `glfwMaximizeWindow` and `GLFW_MAXIMIZED` for window maximization
- Added `glfwFocusWindow` for giving windows input focus
- Added `glfwSetWindowSizeLimits` and `glfwSetWindowAspectRatio` for setting
absolute and relative window size limits
- Added `glfwGetKeyName` for querying the layout-specific name of printable
keys
- Added `glfwWaitEventsTimeout` for waiting for events for a set amount of time
- Added `glfwSetWindowIcon` for setting the icon of a window
- Added `glfwGetTimerValue` and `glfwGetTimerFrequency` for raw timer access
- Added `glfwSetJoystickCallback` and `GLFWjoystickfun` for joystick connection
and disconnection events
- Added `GLFW_NO_API` for creating window without contexts
- Added `GLFW_CONTEXT_NO_ERROR` context hint for `GL_KHR_no_error` support
- Added `GLFW_INCLUDE_VULKAN` for including the Vulkan header
- Added `GLFW_CONTEXT_CREATION_API`, `GLFW_NATIVE_CONTEXT_API` and
`GLFW_EGL_CONTEXT_API` for run-time context creation API selection
- Added `GLFW_TRUE` and `GLFW_FALSE` as client API independent boolean values
- Added icons to examples on Windows and OS X
- Relaxed rules for native access header macros
- Removed dependency on external OpenGL or OpenGL ES headers
- Removed `_GLFW_USE_OPENGL`, `_GLFW_USE_GLESV1`, `_GLFW_USE_GLESV2`,
`_GLFW_WGL`, `_GLFW_NSGL`, `_GLFW_GLX` and `_GLFW_EGL` configuration macros
- [Win32] Added support for Windows 8.1 per-monitor DPI
- [Win32] Replaced winmm with XInput and DirectInput for joystick input
- [Win32] Bugfix: Window creation would segfault if video mode setting required
the system to be restarted
- [Win32] Bugfix: MinGW import library lacked the `lib` prefix
- [Win32] Bugfix: Monitor connection and disconnection events were not reported
when no windows existed
- [Win32] Bugfix: Activating or deactivating displays in software did not
trigger monitor callback
- [Win32] Bugfix: No monitors were listed on headless and VMware guest systems
- [Win32] Bugfix: Pressing Ctrl+Pause would report `GLFW_KEY_UNKNOWN`
- [Win32] Bugfix: Window size events would be reported in wrong order when
restoring a full screen window
- [Cocoa] Made joystick polling more efficient
- [Cocoa] Removed support for OS X 10.6
- [Cocoa] Bugfix: Full screen windows on secondary monitors were mispositioned
- [Cocoa] Bugfix: Connecting a joystick that reports no name would segfault
- [Cocoa] Bugfix: Modifier flags cache was not updated when window became key
- [Cocoa] Bugfix: Dead key character composition did not work
- [Cocoa] Bugfix: The CGL context was not released until the autorelease pool
was drained by another function
- [X11] Bugfix: Monitor connection and disconnection events were not reported
- [X11] Bugfix: Decoding of UTF-8 text from XIM could continue past the end
- [X11] Bugfix: An XKB structure was leaked during `glfwInit`
- [X11] Bugfix: XInput2 `XI_Motion` events interfered with the Steam overlay
- [POSIX] Bugfix: An unrelated TLS key could be deleted by `glfwTerminate`
- [Linux] Made joystick polling more efficient
- [WGL] Changed extension loading to only be performed once
- [WGL] Removed dependency on external WGL headers
- [GLX] Added `glfwGetGLXWindow` to query the `GLXWindow` of a window
- [GLX] Replaced legacy drawable with `GLXWindow`
- [GLX] Removed dependency on external GLX headers
- [GLX] Bugfix: NetBSD does not provide `libGL.so.1`
- [EGL] Added `_GLFW_USE_EGLPLATFORM_H` configuration macro for controlling
whether to use an existing `EGL/eglplatform.h` header
- [EGL] Added and documented test for if the context is current on the calling
thread during buffer swap
- [EGL] Removed dependency on external EGL headers
## Contact ## Contact
The official website for GLFW is [glfw.org](http://www.glfw.org/). There you On [glfw.org](http://www.glfw.org/) you can find the latest version of GLFW, as
can find the latest version of GLFW, as well as news, documentation and other well as news, documentation and other information about the project.
information about the project.
If you have questions related to the use of GLFW, we have a If you have questions related to the use of GLFW, we have a
[support forum](http://discourse.glfw.org/), and the IRC [forum](http://discourse.glfw.org/), and the `#glfw` IRC channel on
channel `#glfw` on [Freenode](http://freenode.net/). [Freenode](http://freenode.net/).
If you have a bug to report, a patch to submit or a feature you'd like to If you have a bug to report, a patch to submit or a feature you'd like to
request, please file it in the request, please file it in the
[issue tracker](https://github.com/glfw/glfw/issues) on GitHub. [issue tracker](https://github.com/glfw/glfw/issues) on GitHub.
Finally, if you're interested in helping out with the development of GLFW or Finally, if you're interested in helping out with the development of GLFW or
porting it to your favorite platform, join us on GitHub or IRC. porting it to your favorite platform, join us on the forum, GitHub or IRC.
## Acknowledgements ## Acknowledgements
@ -199,8 +159,10 @@ skills.
- heromyth - heromyth
- Lucas Hinderberger - Lucas Hinderberger
- Paul Holden - Paul Holden
- Warren Hu
- IntellectualKitty - IntellectualKitty
- Aaron Jacobs - Aaron Jacobs
- Erik S. V. Jansson
- Toni Jovanoski - Toni Jovanoski
- Arseny Kapoulkine - Arseny Kapoulkine
- Osman Keskin - Osman Keskin
@ -240,6 +202,7 @@ skills.
- Emmanuel Gil Peyrot - Emmanuel Gil Peyrot
- Cyril Pichard - Cyril Pichard
- Pieroman - Pieroman
- Philip Rideout
- Jorge Rodriguez - Jorge Rodriguez
- Ed Ropple - Ed Ropple
- Aleksey Rybalkin - Aleksey Rybalkin
@ -254,6 +217,7 @@ skills.
- Dmitri Shuralyov - Dmitri Shuralyov
- Daniel Skorupski - Daniel Skorupski
- Bradley Smith - Bradley Smith
- Patrick Snape
- Julian Squires - Julian Squires
- Johannes Stein - Johannes Stein
- Justin Stoecker - Justin Stoecker
@ -261,10 +225,11 @@ skills.
- Nathan Sweet - Nathan Sweet
- TTK-Bandit - TTK-Bandit
- Sergey Tikhomirov - Sergey Tikhomirov
- A. Tombs - Arthur Tombs
- Ioannis Tsakpinis - Ioannis Tsakpinis
- Samuli Tuomola - Samuli Tuomola
- urraka - urraka
- Elias Vanderstuyft
- Jari Vetoniemi - Jari Vetoniemi
- Ricardo Vieira - Ricardo Vieira
- Nicholas Vitovitch - Nicholas Vitovitch

29
deps/linmath.h vendored
View File

@ -192,19 +192,20 @@ static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
vec3 u = {x, y, z}; vec3 u = {x, y, z};
if(vec3_len(u) > 1e-4) { if(vec3_len(u) > 1e-4) {
mat4x4 T, C, S;
vec3_norm(u, u); vec3_norm(u, u);
mat4x4 T;
mat4x4_from_vec3_mul_outer(T, u, u); mat4x4_from_vec3_mul_outer(T, u, u);
mat4x4 S = { S[1][2] = u[0];
{ 0, u[2], -u[1], 0}, S[2][1] = -u[0];
{-u[2], 0, u[0], 0}, S[2][0] = u[1];
{ u[1], -u[0], 0, 0}, S[0][2] = -u[1];
{ 0, 0, 0, 0} S[0][1] = u[2];
}; S[1][0] = -u[2];
mat4x4_scale(S, S, s); mat4x4_scale(S, S, s);
mat4x4 C;
mat4x4_identity(C); mat4x4_identity(C);
mat4x4_sub(C, C, T); mat4x4_sub(C, C, T);
@ -257,6 +258,7 @@ static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
} }
static inline void mat4x4_invert(mat4x4 T, mat4x4 M) static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
{ {
float idet;
float s[6]; float s[6];
float c[6]; float c[6];
s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1]; s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1];
@ -274,7 +276,7 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3]; c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3];
/* Assumes it is invertible */ /* Assumes it is invertible */
float idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] ); idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] );
T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet; T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet; T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
@ -298,10 +300,10 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M)
} }
static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M) static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M)
{ {
mat4x4_dup(R, M);
float s = 1.; float s = 1.;
vec3 h; vec3 h;
mat4x4_dup(R, M);
vec3_norm(R[2], R[2]); vec3_norm(R[2], R[2]);
s = vec3_mul_inner(R[1], R[2]); s = vec3_mul_inner(R[1], R[2]);
@ -387,14 +389,15 @@ static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
/* TODO: The negation of of can be spared by swapping the order of /* TODO: The negation of of can be spared by swapping the order of
* operands in the following cross products in the right way. */ * operands in the following cross products in the right way. */
vec3 f; vec3 f;
vec3 s;
vec3 t;
vec3_sub(f, center, eye); vec3_sub(f, center, eye);
vec3_norm(f, f); vec3_norm(f, f);
vec3 s;
vec3_mul_cross(s, f, up); vec3_mul_cross(s, f, up);
vec3_norm(s, s); vec3_norm(s, s);
vec3 t;
vec3_mul_cross(t, s, f); vec3_mul_cross(t, s, f);
m[0][0] = s[0]; m[0][0] = s[0];
@ -470,9 +473,9 @@ static inline void quat_conj(quat r, quat q)
r[3] = q[3]; r[3] = q[3];
} }
static inline void quat_rotate(quat r, float angle, vec3 axis) { static inline void quat_rotate(quat r, float angle, vec3 axis) {
int i;
vec3 v; vec3 v;
vec3_scale(v, axis, sinf(angle / 2)); vec3_scale(v, axis, sinf(angle / 2));
int i;
for(i=0; i<3; ++i) for(i=0; i<3; ++i)
r[i] = v[i]; r[i] = v[i];
r[3] = cosf(angle / 2); r[3] = cosf(angle / 2);

117
deps/mingw/_mingw_dxhelper.h vendored Normal file
View File

@ -0,0 +1,117 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER within this package.
*/
#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
#define NONAMELESSUNION 1
#endif
#if defined(NONAMELESSSTRUCT) && \
!defined(NONAMELESSUNION)
#define NONAMELESSUNION 1
#endif
#if defined(NONAMELESSUNION) && \
!defined(NONAMELESSSTRUCT)
#define NONAMELESSSTRUCT 1
#endif
#if !defined(__GNU_EXTENSION)
#if defined(__GNUC__) || defined(__GNUG__)
#define __GNU_EXTENSION __extension__
#else
#define __GNU_EXTENSION
#endif
#endif /* __extension__ */
#ifndef __ANONYMOUS_DEFINED
#define __ANONYMOUS_DEFINED
#if defined(__GNUC__) || defined(__GNUG__)
#define _ANONYMOUS_UNION __extension__
#define _ANONYMOUS_STRUCT __extension__
#else
#define _ANONYMOUS_UNION
#define _ANONYMOUS_STRUCT
#endif
#ifndef NONAMELESSUNION
#define _UNION_NAME(x)
#define _STRUCT_NAME(x)
#else /* NONAMELESSUNION */
#define _UNION_NAME(x) x
#define _STRUCT_NAME(x) x
#endif
#endif /* __ANONYMOUS_DEFINED */
#ifndef DUMMYUNIONNAME
# ifdef NONAMELESSUNION
# define DUMMYUNIONNAME u
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
# define DUMMYUNIONNAME2 u2
# define DUMMYUNIONNAME3 u3
# define DUMMYUNIONNAME4 u4
# define DUMMYUNIONNAME5 u5
# define DUMMYUNIONNAME6 u6
# define DUMMYUNIONNAME7 u7
# define DUMMYUNIONNAME8 u8
# define DUMMYUNIONNAME9 u9
# else /* NONAMELESSUNION */
# define DUMMYUNIONNAME
# define DUMMYUNIONNAME1 /* Wine uses this variant */
# define DUMMYUNIONNAME2
# define DUMMYUNIONNAME3
# define DUMMYUNIONNAME4
# define DUMMYUNIONNAME5
# define DUMMYUNIONNAME6
# define DUMMYUNIONNAME7
# define DUMMYUNIONNAME8
# define DUMMYUNIONNAME9
# endif
#endif /* DUMMYUNIONNAME */
#if !defined(DUMMYUNIONNAME1) /* MinGW does not define this one */
# ifdef NONAMELESSUNION
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
# else
# define DUMMYUNIONNAME1 /* Wine uses this variant */
# endif
#endif /* DUMMYUNIONNAME1 */
#ifndef DUMMYSTRUCTNAME
# ifdef NONAMELESSUNION
# define DUMMYSTRUCTNAME s
# define DUMMYSTRUCTNAME1 s1 /* Wine uses this variant */
# define DUMMYSTRUCTNAME2 s2
# define DUMMYSTRUCTNAME3 s3
# define DUMMYSTRUCTNAME4 s4
# define DUMMYSTRUCTNAME5 s5
# else
# define DUMMYSTRUCTNAME
# define DUMMYSTRUCTNAME1 /* Wine uses this variant */
# define DUMMYSTRUCTNAME2
# define DUMMYSTRUCTNAME3
# define DUMMYSTRUCTNAME4
# define DUMMYSTRUCTNAME5
# endif
#endif /* DUMMYSTRUCTNAME */
/* These are for compatibility with the Wine source tree */
#ifndef WINELIB_NAME_AW
# ifdef __MINGW_NAME_AW
# define WINELIB_NAME_AW __MINGW_NAME_AW
# else
# ifdef UNICODE
# define WINELIB_NAME_AW(func) func##W
# else
# define WINELIB_NAME_AW(func) func##A
# endif
# endif
#endif /* WINELIB_NAME_AW */
#ifndef DECL_WINELIB_TYPE_AW
# ifdef __MINGW_TYPEDEF_AW
# define DECL_WINELIB_TYPE_AW __MINGW_TYPEDEF_AW
# else
# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
# endif
#endif /* DECL_WINELIB_TYPE_AW */

2467
deps/mingw/dinput.h vendored Normal file

File diff suppressed because it is too large Load Diff

239
deps/mingw/xinput.h vendored Normal file
View File

@ -0,0 +1,239 @@
/*
* The Wine project - Xinput Joystick Library
* Copyright 2008 Andrew Fenn
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_XINPUT_H
#define __WINE_XINPUT_H
#include <windef.h>
/*
* Bitmasks for the joysticks buttons, determines what has
* been pressed on the joystick, these need to be mapped
* to whatever device you're using instead of an xbox 360
* joystick
*/
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
#define XINPUT_GAMEPAD_START 0x0010
#define XINPUT_GAMEPAD_BACK 0x0020
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
#define XINPUT_GAMEPAD_A 0x1000
#define XINPUT_GAMEPAD_B 0x2000
#define XINPUT_GAMEPAD_X 0x4000
#define XINPUT_GAMEPAD_Y 0x8000
/*
* Defines the flags used to determine if the user is pushing
* down on a button, not holding a button, etc
*/
#define XINPUT_KEYSTROKE_KEYDOWN 0x0001
#define XINPUT_KEYSTROKE_KEYUP 0x0002
#define XINPUT_KEYSTROKE_REPEAT 0x0004
/*
* Defines the codes which are returned by XInputGetKeystroke
*/
#define VK_PAD_A 0x5800
#define VK_PAD_B 0x5801
#define VK_PAD_X 0x5802
#define VK_PAD_Y 0x5803
#define VK_PAD_RSHOULDER 0x5804
#define VK_PAD_LSHOULDER 0x5805
#define VK_PAD_LTRIGGER 0x5806
#define VK_PAD_RTRIGGER 0x5807
#define VK_PAD_DPAD_UP 0x5810
#define VK_PAD_DPAD_DOWN 0x5811
#define VK_PAD_DPAD_LEFT 0x5812
#define VK_PAD_DPAD_RIGHT 0x5813
#define VK_PAD_START 0x5814
#define VK_PAD_BACK 0x5815
#define VK_PAD_LTHUMB_PRESS 0x5816
#define VK_PAD_RTHUMB_PRESS 0x5817
#define VK_PAD_LTHUMB_UP 0x5820
#define VK_PAD_LTHUMB_DOWN 0x5821
#define VK_PAD_LTHUMB_RIGHT 0x5822
#define VK_PAD_LTHUMB_LEFT 0x5823
#define VK_PAD_LTHUMB_UPLEFT 0x5824
#define VK_PAD_LTHUMB_UPRIGHT 0x5825
#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826
#define VK_PAD_LTHUMB_DOWNLEFT 0x5827
#define VK_PAD_RTHUMB_UP 0x5830
#define VK_PAD_RTHUMB_DOWN 0x5831
#define VK_PAD_RTHUMB_RIGHT 0x5832
#define VK_PAD_RTHUMB_LEFT 0x5833
#define VK_PAD_RTHUMB_UPLEFT 0x5834
#define VK_PAD_RTHUMB_UPRIGHT 0x5835
#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
/*
* Deadzones are for analogue joystick controls on the joypad
* which determine when input should be assumed to be in the
* middle of the pad. This is a threshold to stop a joypad
* controlling the game when the player isn't touching the
* controls.
*/
#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
/*
* Defines what type of abilities the type of joystick has
* DEVTYPE_GAMEPAD is available for all joysticks, however
* there may be more specific identifiers for other joysticks
* which are being used.
*/
#define XINPUT_DEVTYPE_GAMEPAD 0x01
#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
/*
* These are used with the XInputGetCapabilities function to
* determine the abilities to the joystick which has been
* plugged in.
*/
#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
#define XINPUT_FLAG_GAMEPAD 0x00000001
/*
* Defines the status of the battery if one is used in the
* attached joystick. The first two define if the joystick
* supports a battery. Disconnected means that the joystick
* isn't connected. Wired shows that the joystick is a wired
* joystick.
*/
#define BATTERY_DEVTYPE_GAMEPAD 0x00
#define BATTERY_DEVTYPE_HEADSET 0x01
#define BATTERY_TYPE_DISCONNECTED 0x00
#define BATTERY_TYPE_WIRED 0x01
#define BATTERY_TYPE_ALKALINE 0x02
#define BATTERY_TYPE_NIMH 0x03
#define BATTERY_TYPE_UNKNOWN 0xFF
#define BATTERY_LEVEL_EMPTY 0x00
#define BATTERY_LEVEL_LOW 0x01
#define BATTERY_LEVEL_MEDIUM 0x02
#define BATTERY_LEVEL_FULL 0x03
/*
* How many joysticks can be used with this library. Games that
* use the xinput library will not go over this number.
*/
#define XUSER_MAX_COUNT 4
#define XUSER_INDEX_ANY 0x000000FF
/*
* Defines the structure of an xbox 360 joystick.
*/
typedef struct _XINPUT_GAMEPAD {
WORD wButtons;
BYTE bLeftTrigger;
BYTE bRightTrigger;
SHORT sThumbLX;
SHORT sThumbLY;
SHORT sThumbRX;
SHORT sThumbRY;
} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
typedef struct _XINPUT_STATE {
DWORD dwPacketNumber;
XINPUT_GAMEPAD Gamepad;
} XINPUT_STATE, *PXINPUT_STATE;
/*
* Defines the structure of how much vibration is set on both the
* right and left motors in a joystick. If you're not using a 360
* joystick you will have to map these to your device.
*/
typedef struct _XINPUT_VIBRATION {
WORD wLeftMotorSpeed;
WORD wRightMotorSpeed;
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
/*
* Defines the structure for what kind of abilities the joystick has
* such abilities are things such as if the joystick has the ability
* to send and receive audio, if the joystick is in fact a driving
* wheel or perhaps if the joystick is some kind of dance pad or
* guitar.
*/
typedef struct _XINPUT_CAPABILITIES {
BYTE Type;
BYTE SubType;
WORD Flags;
XINPUT_GAMEPAD Gamepad;
XINPUT_VIBRATION Vibration;
} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
/*
* Defines the structure for a joystick input event which is
* retrieved using the function XInputGetKeystroke
*/
typedef struct _XINPUT_KEYSTROKE {
WORD VirtualKey;
WCHAR Unicode;
WORD Flags;
BYTE UserIndex;
BYTE HidCode;
} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
typedef struct _XINPUT_BATTERY_INFORMATION
{
BYTE BatteryType;
BYTE BatteryLevel;
} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
#ifdef __cplusplus
extern "C" {
#endif
void WINAPI XInputEnable(WINBOOL);
DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*);
DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*);
DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE);
DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
#ifdef __cplusplus
}
#endif
#endif /* __WINE_XINPUT_H */

2
deps/tinycthread.c vendored
View File

@ -21,7 +21,7 @@ freely, subject to the following restrictions:
distribution. distribution.
*/ */
/* 2013-01-06 Camilla Berglund <elmindreda@elmindreda.org> /* 2013-01-06 Camilla Berglund <elmindreda@glfw.org>
* *
* Added casts from time_t to DWORD to avoid warnings on VC++. * Added casts from time_t to DWORD to avoid warnings on VC++.
* Fixed time retrieval on POSIX systems. * Fixed time retrieval on POSIX systems.

View File

@ -14,7 +14,6 @@ set(glfw_DOCS_SOURCES
"${GLFW_SOURCE_DIR}/docs/window.dox" "${GLFW_SOURCE_DIR}/docs/window.dox"
"${GLFW_SOURCE_DIR}/docs/input.dox" "${GLFW_SOURCE_DIR}/docs/input.dox"
"${GLFW_SOURCE_DIR}/docs/vulkan.dox" "${GLFW_SOURCE_DIR}/docs/vulkan.dox"
"${GLFW_SOURCE_DIR}/docs/rift.dox"
"${GLFW_SOURCE_DIR}/docs/compat.dox") "${GLFW_SOURCE_DIR}/docs/compat.dox")
if (GLFW_DOCUMENT_INTERNALS) if (GLFW_DOCUMENT_INTERNALS)

View File

@ -103,7 +103,8 @@ and only for compatibility with legacy code. GLU has been deprecated and should
not be used in new code. not be used in new code.
@note GLFW does not provide any of the API headers mentioned above. They must @note GLFW does not provide any of the API headers mentioned above. They must
be provided by your development environment or your OpenGL or OpenGL ES SDK. be provided by your development environment or your OpenGL, OpenGL ES or Vulkan
SDK.
@note None of these macros may be defined during the compilation of GLFW itself. @note None of these macros may be defined during the compilation of GLFW itself.
If your build includes GLFW and you define any these in your build files, make If your build includes GLFW and you define any these in your build files, make
@ -153,7 +154,7 @@ uses OpenGL and `glu32` if it uses GLU.
This section is about using CMake to compile and link GLFW along with your This section is about using CMake to compile and link GLFW along with your
application. If you want to use an installed binary instead, see @ref application. If you want to use an installed binary instead, see @ref
build_link_cmake_module. build_link_cmake_package.
With just a few changes to your `CMakeLists.txt` you can have the GLFW source With just a few changes to your `CMakeLists.txt` you can have the GLFW source
tree built along with your application. tree built along with your application.
@ -184,59 +185,78 @@ the include directory for the GLFW header and, when applicable, the
target_link_libraries(myapp glfw) target_link_libraries(myapp glfw)
@endcode @endcode
Note that it does not include GLU, as GLFW does not use it. If your application Note that the dependencies do not include OpenGL or GLU, as GLFW loads any
needs GLU, you can find it by requiring the OpenGL package. OpenGL, OpenGL ES or Vulkan libraries it needs at runtime and does not use GLU.
If your application calls OpenGL directly, instead of using a modern
[extension loader library](@ref context_glext_auto) you can find it by requiring
the OpenGL package.
@code{.cmake} @code{.cmake}
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
@endcode @endcode
If GLU is found, the `OPENGL_GLU_FOUND` variable is true and the If OpenGL is found, the `OPENGL_FOUND` variable is true and the
`OPENGL_INCLUDE_DIR` and `OPENGL_glu_LIBRARY` cache variables can be used. `OPENGL_INCLUDE_DIR` and `OPENGL_gl_LIBRARY` cache variables can be used.
@code{.cmake} @code{.cmake}
target_include_directories(myapp ${OPENGL_INCLUDE_DIR}) target_include_directories(myapp ${OPENGL_INCLUDE_DIR})
target_link_libraries(myapp ${OPENGL_gl_LIBRARY})
@endcode
The OpenGL CMake package also looks for GLU. If GLU is found, the
`OPENGL_GLU_FOUND` variable is true and the `OPENGL_INCLUDE_DIR` and
`OPENGL_glu_LIBRARY` cache variables can be used.
@code{.cmake}
target_link_libraries(myapp ${OPENGL_glu_LIBRARY}) target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
@endcode @endcode
@note GLU has been deprecated and should not be used in new code, but some
legacy code requires it.
@subsection build_link_cmake_module With CMake and installed GLFW binaries
@subsection build_link_cmake_package With CMake and installed GLFW binaries
This section is about using CMake to link GLFW after it has been built and This section is about using CMake to link GLFW after it has been built and
installed. If you want to build it along with your application instead, see installed. If you want to build it along with your application instead, see
@ref build_link_cmake_source. @ref build_link_cmake_source.
With just a few changes to your `CMakeLists.txt`, you can locate the module and With just a few changes to your `CMakeLists.txt`, you can locate the package and
target files generated when GLFW is installed. target files generated when GLFW is installed.
@code{.cmake} @code{.cmake}
find_package(glfw3 3.2 REQUIRED) find_package(glfw3 3.3 REQUIRED)
@endcode @endcode
Once GLFW has been located, link against it with the `glfw` target. This adds Note that the dependencies do not include OpenGL or GLU, as GLFW loads any
all link-time dependencies of GLFW as it is currently configured, the include OpenGL, OpenGL ES or Vulkan libraries it needs at runtime and does not use GLU.
directory for the GLFW header and, when applicable, the If your application calls OpenGL directly, instead of using a modern
[GLFW_DLL](@ref build_macros) macro. [extension loader library](@ref context_glext_auto) you can find it by requiring
the OpenGL package.
@code{.cmake}
target_link_libraries(myapp glfw)
@endcode
Note that it does not include GLU, as GLFW does not use it. If your application
needs GLU, you can find it by requiring the OpenGL package.
@code{.cmake} @code{.cmake}
find_package(OpenGL REQUIRED) find_package(OpenGL REQUIRED)
@endcode @endcode
If GLU is found, the `OPENGL_GLU_FOUND` variable is true and the If OpenGL is found, the `OPENGL_FOUND` variable is true and the
`OPENGL_INCLUDE_DIR` and `OPENGL_glu_LIBRARY` cache variables can be used. `OPENGL_INCLUDE_DIR` and `OPENGL_gl_LIBRARY` cache variables can be used.
@code{.cmake} @code{.cmake}
target_include_directories(myapp ${OPENGL_INCLUDE_DIR}) target_include_directories(myapp ${OPENGL_INCLUDE_DIR})
target_link_libraries(myapp ${OPENGL_gl_LIBRARY})
@endcode
The OpenGL CMake package also looks for GLU. If GLU is found, the
`OPENGL_GLU_FOUND` variable is true and the `OPENGL_INCLUDE_DIR` and
`OPENGL_glu_LIBRARY` cache variables can be used.
@code{.cmake}
target_link_libraries(myapp ${OPENGL_glu_LIBRARY}) target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
@endcode @endcode
@note GLU has been deprecated and should not be used in new code, but some
legacy code requires it.
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix @subsection build_link_pkgconfig With makefiles and pkg-config on Unix
@ -268,15 +288,19 @@ You can also use the `glfw3.pc` file without installing it first, by using the
env PKG_CONFIG_PATH=path/to/glfw/src cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3` env PKG_CONFIG_PATH=path/to/glfw/src cc `pkg-config --cflags glfw3` -o myprog myprog.c `pkg-config --libs glfw3`
@endcode @endcode
The dependencies do not include GLU, as GLFW does not use it. On OS X, GLU is The dependencies do not include OpenGL or GLU, as GLFW loads any OpenGL, OpenGL
built into the OpenGL framework, so if you need GLU you don't need to do ES or Vulkan libraries it needs at runtime and does not use GLU. On OS X, GLU
is built into the OpenGL framework, so if you need GLU you don't need to do
anything extra. If you need GLU and are using Linux or BSD, you should add the anything extra. If you need GLU and are using Linux or BSD, you should add the
`glu` pkg-config module. `glu` pkg-config package.
@code{.sh} @code{.sh}
cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --libs glfw3 glu` cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --libs glfw3 glu`
@endcode @endcode
@note GLU has been deprecated and should not be used in new code, but some
legacy code requires it.
If you are using the static version of the GLFW library, make sure you don't If you are using the static version of the GLFW library, make sure you don't
link statically against GLU. link statically against GLU.

View File

@ -185,7 +185,7 @@ a non-default value will cause @ref glfwCreateWindow to fail and the
@section compat_vulkan Vulkan loader and API @section compat_vulkan Vulkan loader and API
GLFW uses the standard system-wside Vulkan loader to access the Vulkan API. GLFW uses the standard system-wide Vulkan loader to access the Vulkan API.
This should be installed by graphics drivers and Vulkan SDKs. If this is not This should be installed by graphics drivers and Vulkan SDKs. If this is not
available, @ref glfwVulkanSupported will return `GLFW_FALSE` and all other available, @ref glfwVulkanSupported will return `GLFW_FALSE` and all other
Vulkan-related functions will fail with an @ref GLFW_API_UNAVAILABLE error. Vulkan-related functions will fail with an @ref GLFW_API_UNAVAILABLE error.

View File

@ -197,6 +197,9 @@ built along with the library.
`GLFW_BUILD_DOCS` determines whether the GLFW documentation is built along with `GLFW_BUILD_DOCS` determines whether the GLFW documentation is built along with
the library. the library.
`GLFW_VULKAN_STATIC` determines whether to use the Vulkan loader linked
statically into the application.
@subsubsection compile_options_osx OS X specific CMake options @subsubsection compile_options_osx OS X specific CMake options
@ -214,9 +217,7 @@ Retina displays.
`USE_MSVC_RUNTIME_LIBRARY_DLL` determines whether to use the DLL version or the `USE_MSVC_RUNTIME_LIBRARY_DLL` determines whether to use the DLL version or the
static library version of the Visual C++ runtime library. If set to `ON`, the static library version of the Visual C++ runtime library. If set to `ON`, the
DLL version of the Visual C++ library is used. It is recommended to set this to DLL version of the Visual C++ library is used.
`ON`, as this keeps the executable smaller and benefits from security and bug
fix updates of the Visual C++ runtime.
`GLFW_USE_HYBRID_HPG` determines whether to export the `NvOptimusEnablement` and `GLFW_USE_HYBRID_HPG` determines whether to export the `NvOptimusEnablement` and
`AmdPowerXpressRequestHighPerformance` symbols, which force the use of the `AmdPowerXpressRequestHighPerformance` symbols, which force the use of the
@ -251,6 +252,10 @@ ramps and clipboard. The options are:
If you are building GLFW as a shared library / dynamic library / DLL then you If you are building GLFW as a shared library / dynamic library / DLL then you
must also define `_GLFW_BUILD_DLL`. Otherwise, you must not define it. must also define `_GLFW_BUILD_DLL`. Otherwise, you must not define it.
If you are linking the Vulkan loader statically into your application then you
must also define `_GLFW_VULKAN_STATIC`. Otherwise, GLFW will attempt to use the
external version.
For the EGL context creation API, the following options are available: For the EGL context creation API, the following options are available:
- `_GLFW_USE_EGLPLATFORM_H` to use `EGL/eglplatform.h` for native handle - `_GLFW_USE_EGLPLATFORM_H` to use `EGL/eglplatform.h` for native handle

View File

@ -5,9 +5,8 @@
@tableofcontents @tableofcontents
This guide introduces the OpenGL and OpenGL ES context related functions of This guide introduces the OpenGL and OpenGL ES context related functions of
GLFW. For details on a specific function, see the GLFW. For details on a specific function in this category, see the @ref
[reference documentation](@ref context). There are also guides for the other context. There are also guides for the other areas of the GLFW API.
areas of the GLFW API.
- @ref intro_guide - @ref intro_guide
- @ref window_guide - @ref window_guide

View File

@ -5,12 +5,13 @@
@tableofcontents @tableofcontents
This guide introduces the input related functions of GLFW. For details on This guide introduces the input related functions of GLFW. For details on
a specific function, see the [reference documentation](@ref input). There are a specific function in this category, see the @ref input. There are also guides
also guides for the other areas of GLFW. for the other areas of GLFW.
- @ref intro_guide - @ref intro_guide
- @ref window_guide - @ref window_guide
- @ref context_guide - @ref context_guide
- @ref vulkan_guide
- @ref monitor_guide - @ref monitor_guide
GLFW provides many kinds of input. While some can only be polled, like time, or GLFW provides many kinds of input. While some can only be polled, like time, or

View File

@ -111,6 +111,6 @@ which is generated from the `glfw_config.h.in` file by CMake.
Configuration macros the same style as tokens in the public interface, except Configuration macros the same style as tokens in the public interface, except
with a leading underscore. with a leading underscore.
Examples: `_GLFW_HAS_GLXGETPROCADDRESS` Examples: `_GLFW_HAS_XF86VM`
*/ */

View File

@ -4,10 +4,10 @@
@tableofcontents @tableofcontents
This guide introduces the basic concepts of GLFW and describes initialization reference This guide introduces the basic concepts of GLFW and describes initialization,
error handling and API guarantees and limitations. For a broad but shallow error handling and API guarantees and limitations. For a broad but shallow
tutorial, see @ref quick_guide instead. For details on a specific function, see the tutorial, see @ref quick_guide instead. For details on a specific function in
[reference documentation](@ref init). this category, see the @ref init.
There are also guides for the other areas of GLFW. There are also guides for the other areas of GLFW.
@ -34,7 +34,7 @@ successfully initialized, and only from the main thread.
- @ref glfwInit - @ref glfwInit
- @ref glfwTerminate - @ref glfwTerminate
Calling any other function before that time will cause a @ref Calling any other function before successful initialization will cause a @ref
GLFW_NOT_INITIALIZED error. GLFW_NOT_INITIALIZED error.
@ -50,13 +50,15 @@ if (!glfwInit())
} }
@endcode @endcode
If any part of initialization fails, all remaining bits are terminated as if If any part of initialization fails, any parts that succeeded are terminated as
@ref glfwTerminate was called. The library only needs to be initialized once if @ref glfwTerminate had been called. The library only needs to be initialized
and additional calls to an already initialized library will simply return once and additional calls to an already initialized library will simply return
`GLFW_TRUE` immediately. `GLFW_TRUE` immediately.
Once the library has been successfully initialized, it should be terminated Once the library has been successfully initialized, it should be terminated
before the application exits. before the application exits. Modern systems are very good at freeing resources
allocated by programs that simply exit, but GLFW sometimes has to change global
system settings and these might not be restored without termination.
@subsection intro_init_terminate Terminating GLFW @subsection intro_init_terminate Terminating GLFW
@ -70,7 +72,7 @@ glfwTerminate();
This will destroy any remaining window, monitor and cursor objects, restore any This will destroy any remaining window, monitor and cursor objects, restore any
modified gamma ramps, re-enable the screensaver if it had been disabled and free modified gamma ramps, re-enable the screensaver if it had been disabled and free
any resources allocated by GLFW. any other resources allocated by GLFW.
Once the library is terminated, it is as if it had never been initialized and Once the library is terminated, it is as if it had never been initialized and
you will need to initialize it again before being able to use GLFW. If the you will need to initialize it again before being able to use GLFW. If the
@ -249,11 +251,12 @@ functions may be called from any thread:
- @ref glfwGetTimerFrequency - @ref glfwGetTimerFrequency
- @ref glfwGetTimerValue - @ref glfwGetTimerValue
The regular timer may be queried from any thread, but this is not synchronized The regular timer may be used from any thread, but the reading and writing of
by GLFW with calls to @ref glfwSetTime. The following timer related functions the timer offset is not synchronized by GLFW. The following timer related
may be called from any thread: functions may be called from any thread:
- @ref glfwGetTime - @ref glfwGetTime
- @ref glfwSetTime
Library version information may be queried from any thread. The following Library version information may be queried from any thread. The following
version related functions may be called from any thread: version related functions may be called from any thread:
@ -281,9 +284,10 @@ allow calls from any thread in future releases.
@subsection compatibility Version compatibility @subsection compatibility Version compatibility
GLFW guarantees binary backward compatibility with earlier minor versions of the GLFW guarantees source and binary backward compatibility with earlier minor
API. This means that you can drop in a newer version of the GLFW DLL / shared versions of the API. This means that you can drop in a newer version of the
library / dynamic library and existing applications will continue to run. library and existing programs will continue to compile and existing binaries
will continue to run.
Once a function or constant has been added, the signature of that function or Once a function or constant has been added, the signature of that function or
value of that constant will remain unchanged until the next major version of value of that constant will remain unchanged until the next major version of

View File

@ -8,7 +8,7 @@ GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
Vulkan application development. It provides a simple, platform-independent API Vulkan application development. It provides a simple, platform-independent API
for creating windows, contexts and surfaces, reading input, handling events, etc. for creating windows, contexts and surfaces, reading input, handling events, etc.
See @ref news_32 for release highlights or the See @ref news_33 for release highlights or the
[version history](http://www.glfw.org/changelog.html) for details. [version history](http://www.glfw.org/changelog.html) for details.
@ref quick_guide is a guide for users new to GLFW. It takes you through how to @ref quick_guide is a guide for users new to GLFW. It takes you through how to
@ -34,8 +34,6 @@ use the new API.
There is a section on @ref guarantees_limitations for pointer lifetimes, There is a section on @ref guarantees_limitations for pointer lifetimes,
reentrancy, thread safety, event order and backward and forward compatibility. reentrancy, thread safety, event order and backward and forward compatibility.
@ref rift_guide fills in the gaps for how to use LibOVR with GLFW.
The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the The [FAQ](http://www.glfw.org/faq.html) answers many common questions about the
design, implementation and use of GLFW. design, implementation and use of GLFW.

View File

@ -5,12 +5,13 @@
@tableofcontents @tableofcontents
This guide introduces the monitor related functions of GLFW. For details on This guide introduces the monitor related functions of GLFW. For details on
a specific function, see the [reference documentation](@ref monitor). There are a specific function in this category, see the @ref monitor. There are also
also guides for the other areas of GLFW. guides for the other areas of GLFW.
- @ref intro_guide - @ref intro_guide
- @ref window_guide - @ref window_guide
- @ref context_guide - @ref context_guide
- @ref vulkan_guide
- @ref input_guide - @ref input_guide
@ -84,6 +85,9 @@ void monitor_callback(GLFWmonitor* monitor, int event)
} }
@endcode @endcode
If a monitor is disconnected, any windows that are full screen on it get forced
into windowed mode.
@section monitor_properties Monitor properties @section monitor_properties Monitor properties

View File

@ -2,21 +2,12 @@
@page news New features @page news New features
@section news_33 New features in 3.3
@section news_32 New features in 3.2 @section news_32 New features in 3.2
@subsection news_32_sizelimits Window size limit support
GLFW now supports setting both absolute and relative window size limits with
@ref glfwSetWindowSizeLimits and @ref glfwSetWindowAspectRatio.
@subsection news_32_keyname Localized key names
GLFW now supports querying the localized name of printable keys with @ref
glfwGetKeyName, either by key token or by scancode.
@subsection news_32_vulkan Support for Vulkan @subsection news_32_vulkan Support for Vulkan
GLFW now supports basic integration with Vulkan with @ref glfwVulkanSupported, GLFW now supports basic integration with Vulkan with @ref glfwVulkanSupported,
@ -39,20 +30,21 @@ GLFW now supports window maximization with @ref glfwMaximizeWindow and the
[GLFW_MAXIMIZED](@ref window_attribs_wnd) window hint and attribute. [GLFW_MAXIMIZED](@ref window_attribs_wnd) window hint and attribute.
@subsection news_32_icon Window icon support
GLFW now supports setting the icon of windows with @ref glfwSetWindowIcon.
@subsection news_32_focus Window input focus control @subsection news_32_focus Window input focus control
GLFW now supports giving windows input focus with @ref glfwFocusWindow. GLFW now supports giving windows input focus with @ref glfwFocusWindow.
@subsection news_32_timer Raw timer access @subsection news_32_sizelimits Window size limit support
GLFW now supports raw timer values with @ref glfwGetTimerValue and @ref GLFW now supports setting both absolute and relative window size limits with
glfwGetTimerFrequency. @ref glfwSetWindowSizeLimits and @ref glfwSetWindowAspectRatio.
@subsection news_32_keyname Localized key names
GLFW now supports querying the localized name of printable keys with @ref
glfwGetKeyName, either by key token or by scancode.
@subsection news_32_waittimeout Wait for events with timeout @subsection news_32_waittimeout Wait for events with timeout
@ -61,10 +53,47 @@ GLFW now supports waiting for events for a set amount of time with @ref
glfwWaitEventsTimeout. glfwWaitEventsTimeout.
@subsection news_32_icon Window icon support
GLFW now supports setting the icon of windows with @ref glfwSetWindowIcon.
@subsection news_32_timer Raw timer access
GLFW now supports raw timer values with @ref glfwGetTimerValue and @ref
glfwGetTimerFrequency.
@subsection news_32_joystick Joystick connection callback
GLFW now supports notifying when a joystick has been connected or disconnected
with @ref glfwSetJoystickCallback.
@subsection news_32_noapi Context-less windows
GLFW now supports creating windows without a OpenGL or OpenGL ES context with
[GLFW_NO_API](@ref window_hints_ctx).
@subsection news_32_contextapi Run-time context creation API selection @subsection news_32_contextapi Run-time context creation API selection
GLFW now supports selecting the context creation API at run-time with GLFW now supports selecting the context creation API at run-time with the
[GLFW_CONTEXT_CREATION_API](@ref window_hints_ctx). [GLFW_CONTEXT_CREATION_API](@ref window_hints_ctx) window hint value.
@subsection news_32_noerror Error-free context creation
GLFW now supports creating OpenGL and OpenGL ES contexts that do not emit errors
with the [GLFW_CONTEXT_NO_ERROR](@ref window_hints_ctx) window hint, provided
the machine supports the `GL_KHR_no_error` extension.
@subsection news_32_cmake CMake config-file package support
GLFW now supports being used as a
[config-file package](@ref build_link_cmake_package) from other projects for
easy linking with the library and its dependencies.
@section news_31 New features in 3.1 @section news_31 New features in 3.1
@ -134,13 +163,6 @@ GLFW now queries the window input focus, visibility and iconification attributes
and the cursor position directly instead of returning cached data. and the cursor position directly instead of returning cached data.
@subsection news_31_libovr Better interoperability with Oculus Rift
GLFW now provides native access functions for the OS level handles corresponding
to monitor objects, as well as the @ref rift_guide. It is also regularly
tested for compatibility with the latest version of LibOVR (0.4.4 on release).
@subsection news_31_charmods Character with modifiers callback @subsection news_31_charmods Character with modifiers callback
GLFW now provides a callback for character events with modifier key bits. The GLFW now provides a callback for character events with modifier key bits. The
@ -326,7 +348,7 @@ well as moving a window to a specific position before showing it.
@subsection news_30_undecorated Undecorated windows @subsection news_30_undecorated Undecorated windows
Windowed mode windows can now be created without decorations, i.e. things like Windowed mode windows can now be created without decorations, e.g. things like
a frame, a title bar, with the `GLFW_DECORATED` window hint. This allows for a frame, a title bar, with the `GLFW_DECORATED` window hint. This allows for
the creation of things like splash screens. the creation of things like splash screens.

View File

@ -1,199 +0,0 @@
/*!
@page rift_guide Using GLFW with LibOVR
@tableofcontents
This guide is intended to fill in the gaps between the
[Oculus PC SDK documentation](https://developer.oculus.com/documentation/) and
the rest of the GLFW documentation and is not a replacement for either. It
requires you to use [native access](@ref native) and assumes a certain level of
proficiency with LibOVR, platform specific APIs and your chosen development
environment.
While GLFW has no explicit support for LibOVR, it is tested with and tries to
interoperate well with it.
@note Because of the speed of development of the Oculus SDK, this guide may
become outdated before the next release. If this is a local copy of the
documentation, you may want to check the GLFW website for updates. This
revision of the guide is written against version 0.4.4 of the SDK.
@section rift_include Including the LibOVR and GLFW header files
Both the OpenGL LibOVR header and the GLFW native header need macros telling
them what OS you are building for. Because LibOVR only supports three major
desktop platforms, this can be solved with canonical predefined macros.
@code
#if defined(_WIN32)
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#define OVR_OS_WIN32
#elif defined(__APPLE__)
#define GLFW_EXPOSE_NATIVE_COCOA
#define GLFW_EXPOSE_NATIVE_NSGL
#define OVR_OS_MAC
#elif defined(__linux__)
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#define OVR_OS_LINUX
#endif
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>
#include <OVR_CAPI_GL.h>
@endcode
Both the GLFW and LibOVR headers by default attempt to include the standard
OpenGL `GL/gl.h` header (`OpenGL/gl.h` on OS X). If you wish to use a different
standard header or an [extension loading library](@ref context_glext_auto),
include that header before these.
@section rift_init Initializing LibOVR and GLFW
LibOVR needs to be initialized before GLFW. This means calling at least
`ovr_Initialize`, `ovrHmd_Create` and `ovrHmd_ConfigureTracking` before @ref
glfwInit. Similarly, LibOVR must be shut down after GLFW. This means calling
`ovrHmd_Destroy` and `ovr_Shutdown` after @ref glfwTerminate.
@section rift_direct Direct HMD mode
Direct HMD mode is the recommended display mode for new applications, but the
Oculus Rift runtime currently (January 2015) only supports this mode on Windows.
In direct mode the HMD is not detectable as a GLFW monitor.
@subsection rift_direct_create Creating a window and context
If the HMD is in direct mode you can use either a full screen or a windowed mode
window, but full screen is only recommended if there is a monitor that supports
the resolution of the HMD. Due to limitations in LibOVR, the size of the client
area of the window must equal the resolution of the HMD.
If the resolution of the HMD is much larger than the regular monitor, the window
may be resized by the window manager on creation. One way to avoid this is to
make it undecorated with the [GLFW_DECORATED](@ref window_hints_wnd) window
hint.
@subsection rift_direct_attach Attaching the window to the HMD
Once you have created the window and context, you need to attach the native
handle of the GLFW window to the HMD.
@code
ovrHmd_AttachToWindow(hmd, glfwGetWin32Window(window), NULL, NULL);
@endcode
@section rift_extend Extend Desktop mode
Extend desktop mode is a legacy display mode, but is still (January 2015) the
only available mode on OS X and Linux, as well as on Windows machines that for
technical reasons do not yet support direct HMD mode.
@subsection rift_extend_detect Detecting a HMD with GLFW
If the HMD is in extend desktop mode you can deduce which GLFW monitor it
corresponds to and create a full screen window on that monitor.
On Windows, the native display device name of a GLFW monitor corresponds to the
display device name of the detected HMD as stored, in the `DisplayDeviceName`
member of `ovrHmdDesc`.
On OS X, the native display ID of a GLFW monitor corresponds to the display ID
of the detected HMD, as stored in the `DisplayId` member of `ovrHmdDesc`.
At the time of writing (January 2015), the Oculus SDK does not support detecting
which monitor corresponds to the HMD in any sane fashion, but as long as the HMD
is set up and rotated properly it can be found via the screen position and
resolution provided by LibOVR. This method may instead find another monitor
that is mirroring the HMD, but this only matters if you intend to change its
video mode.
@code
int i, count;
GLFWmonitor** monitors = glfwGetMonitors(&count);
for (i = 0; i < count; i++)
{
#if defined(_WIN32)
if (strcmp(glfwGetWin32Monitor(monitors[i]), hmd->DisplayDeviceName) == 0)
return monitors[i];
#elif defined(__APPLE__)
if (glfwGetCocoaMonitor(monitors[i]) == hmd->DisplayId)
return monitors[i];
#elif defined(__linux__)
int xpos, ypos;
const GLFWvidmode* mode = glfwGetVideoMode(monitors[i]);
glfwGetMonitorPos(monitors[i], &xpos, &ypos);
if (hmd->WindowsPos.x == xpos &&
hmd->WindowsPos.y == ypos &&
hmd->Resolution.w == mode->width &&
hmd->Resolution.h == mode->height)
{
return monitors[i];
}
#endif
}
@endcode
@subsection rift_extend_create Creating a window and context
The window is created as a regular full screen window on the found monitor. It
is usually a good idea to create a
[windowed full screen](@ref window_windowed_full_screen) window, as the HMD will
very likely already be set to the correct video mode. However, in extend
desktop mode it behaves like a regular monitor and any supported video mode can
be requested.
If other monitors are mirroring the HMD and you request a different video mode,
all monitors in the mirroring set will get the new video mode.
@section rift_render Rendering to the HMD
@subsection rift_render_sdk SDK distortion rendering
If you wish to use SDK distortion rendering you will need some information from
GLFW to configure the renderer. Below are the parts of the `ovrGLConfig` union
that need to be filled with from GLFW. Note that there are other fields that
also need to be filled for `ovrHmd_ConfigureRendering` to succeed.
Before configuring SDK distortion rendering you should make your context
current.
@code
int width, height;
union ovrGLConfig config;
glfwGetFramebufferSize(window, &width, &height);
config.OGL.Header.BackBufferSize.w = width;
config.OGL.Header.BackBufferSize.h = height;
#if defined(_WIN32)
config.OGL.Window = glfwGetWin32Window(window);
#elif defined(__APPLE__)
#elif defined(__linux__)
config.OGL.Disp = glfwGetX11Display();
#endif
@endcode
When using SDK distortion rendering you should not swap the buffers yourself, as
the HMD is updated by `ovrHmd_EndFrame`.
@subsection rift_render_custom Client distortion rendering
With client distortion rendering you are in full control of the contents of the
HMD and should render and swap the buffers normally.
*/

View File

@ -18,9 +18,8 @@ The GLFW library does not need the Vulkan SDK to enable support for Vulkan.
However, any Vulkan-specific test and example programs are built only if the However, any Vulkan-specific test and example programs are built only if the
CMake files find a Vulkan SDK. CMake files find a Vulkan SDK.
For details on a specific function, see the For details on a specific function in this category, see the @ref vulkan. There
[reference documentation](@ref vulkan). There are also guides for the other are also guides for the other areas of the GLFW API.
areas of the GLFW API.
- @ref intro_guide - @ref intro_guide
- @ref window_guide - @ref window_guide
@ -39,8 +38,8 @@ before including the GLFW header.
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@endcode @endcode
If you want to include the Vulkan header from a custom location or use your own If you instead want to include the Vulkan header from a custom location or use
custom Vulkan header then you need to include them before the GLFW header. your own custom Vulkan header then do this before the GLFW header.
@code @code
#include <path/to/vulkan.h> #include <path/to/vulkan.h>

View File

@ -5,11 +5,12 @@
@tableofcontents @tableofcontents
This guide introduces the window related functions of GLFW. For details on This guide introduces the window related functions of GLFW. For details on
a specific function, see the [reference documentation](@ref window). There are a specific function in this category, see the @ref window. There are also
also guides for the other areas of GLFW. guides for the other areas of GLFW.
- @ref intro_guide - @ref intro_guide
- @ref context_guide - @ref context_guide
- @ref vulkan_guide
- @ref monitor_guide - @ref monitor_guide
- @ref input_guide - @ref input_guide
@ -79,7 +80,8 @@ Once you have a full screen window, you can change its resolution, refresh rate
and monitor with @ref glfwSetWindowMonitor. If you just need change its and monitor with @ref glfwSetWindowMonitor. If you just need change its
resolution you can also call @ref glfwSetWindowSize. In all cases, the new resolution you can also call @ref glfwSetWindowSize. In all cases, the new
video mode will be selected the same way as the video mode chosen by @ref video mode will be selected the same way as the video mode chosen by @ref
glfwCreateWindow. glfwCreateWindow. If the window has an OpenGL or OpenGL ES context, it will be
unaffected.
By default, the original video mode of the monitor will be restored and the By default, the original video mode of the monitor will be restored and the
window iconified if it loses input focus, to allow the user to switch back to window iconified if it loses input focus, to allow the user to switch back to
@ -268,15 +270,19 @@ creation API is used on a given platform may fail if you change this hint. This
can be resolved by having it load via @ref glfwGetProcAddress, which always uses can be resolved by having it load via @ref glfwGetProcAddress, which always uses
the selected API. the selected API.
@bug On some Linux systems, creating contexts via both the native and EGL APIs
in a single process will cause the application to segfault. Stick to one API or
the other on Linux for now.
`GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` specify the client `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` specify the client
API version that the created context must be compatible with. The exact API version that the created context must be compatible with. The exact
behavior of these hints depend on the requested client API. behavior of these hints depend on the requested client API.
@par @par
__OpenGL:__ `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` are not hard __OpenGL:__ `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` are
constraints, but creation will fail if the OpenGL version of the created context not hard constraints, but creation will fail if the OpenGL version of the
is less than the one requested. It is therefore perfectly safe to use the created context is less than the one requested. It is therefore perfectly safe
default of version 1.0 for legacy code and you may still get to use the default of version 1.0 for legacy code and you will still get
backwards-compatible contexts of version 3.0 and above when available. backwards-compatible contexts of version 3.0 and above when available.
@par @par
@ -285,12 +291,12 @@ version, GLFW will attempt to provide this when you ask for a version 1.0
context, which is the default for these hints. context, which is the default for these hints.
@par @par
__OpenGL ES:__ `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` are not hard __OpenGL ES:__ `GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` are
constraints, but creation will fail if the OpenGL ES version of the created not hard constraints, but creation will fail if the OpenGL ES version of the
context is less than the one requested. Additionally, OpenGL ES 1.x cannot be created context is less than the one requested. Additionally, OpenGL ES 1.x
returned if 2.0 or later was requested, and vice versa. This is because OpenGL cannot be returned if 2.0 or later was requested, and vice versa. This is
ES 3.x is backward compatible with 2.0, but OpenGL ES 2.0 is not backward because OpenGL ES 3.x is backward compatible with 2.0, but OpenGL ES 2.0 is not
compatible with 1.x. backward compatible with 1.x.
`GLFW_OPENGL_FORWARD_COMPAT` specifies whether the OpenGL context should be `GLFW_OPENGL_FORWARD_COMPAT` specifies whether the OpenGL context should be
forward-compatible, i.e. one where all functionality deprecated in the requested forward-compatible, i.e. one where all functionality deprecated in the requested
@ -645,7 +651,7 @@ As long as your source file is encoded as UTF-8, you can use any Unicode
characters directly in the source. characters directly in the source.
@code @code
glfwSetWindowTitle(window, "星を追う子ども"); glfwSetWindowTitle(window, "ラストエグザイル");
@endcode @endcode
If you are using C++11 or C11, you can use a UTF-8 string literal. If you are using C++11 or C11, you can use a UTF-8 string literal.

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// A simple particle engine with threaded physics // A simple particle engine with threaded physics
// Copyright (c) Marcus Geelnard // Copyright (c) Marcus Geelnard
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -457,7 +457,9 @@ static void draw_particles(GLFWwindow* window, double t, float dt)
{ {
struct timespec ts; struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts); clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_nsec += 100000000; ts.tv_nsec += 100 * 1000 * 1000;
ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
ts.tv_nsec %= 1000 * 1000 * 1000;
cnd_timedwait(&thread_sync.p_done, &thread_sync.particles_lock, &ts); cnd_timedwait(&thread_sync.p_done, &thread_sync.particles_lock, &ts);
} }
@ -908,7 +910,9 @@ static int physics_thread_main(void* arg)
{ {
struct timespec ts; struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts); clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_nsec += 100000000; ts.tv_nsec += 100 * 1000 * 1000;
ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
ts.tv_nsec %= 1000 * 1000 * 1000;
cnd_timedwait(&thread_sync.d_done, &thread_sync.particles_lock, &ts); cnd_timedwait(&thread_sync.d_done, &thread_sync.particles_lock, &ts);
} }

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Simple GLFW example // Simple GLFW example
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,9 +1,9 @@
/************************************************************************* /*************************************************************************
* GLFW 3.2 - www.glfw.org * GLFW 3.3 - www.glfw.org
* A library for OpenGL, window and input * A library for OpenGL, window and input
*------------------------------------------------------------------------ *------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard * Copyright (c) 2002-2006 Marcus Geelnard
* Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> * Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages * warranty. In no event will the authors be held liable for any damages
@ -115,11 +115,14 @@ extern "C" {
#define GLFW_CALLBACK_DEFINED #define GLFW_CALLBACK_DEFINED
#endif /* CALLBACK */ #endif /* CALLBACK */
/* Most Windows GLU headers need wchar_t. /* Include because most Windows GLU headers need wchar_t and
* The OS X OpenGL header blocks the definition of ptrdiff_t by glext.h. * the OS X OpenGL header blocks the definition of ptrdiff_t by glext.h.
* Include it unconditionally to avoid surprising side-effects. * Include it unconditionally to avoid surprising side-effects.
*/ */
#include <stddef.h> #include <stddef.h>
/* Include because it is needed by Vulkan and related functions.
*/
#include <stdint.h> #include <stdint.h>
/* Include the chosen client API headers. /* Include the chosen client API headers.
@ -219,7 +222,7 @@ extern "C" {
* backward-compatible. * backward-compatible.
* @ingroup init * @ingroup init
*/ */
#define GLFW_VERSION_MINOR 2 #define GLFW_VERSION_MINOR 3
/*! @brief The revision number of the GLFW library. /*! @brief The revision number of the GLFW library.
* *
* This is incremented when a bug fix release is made that does not contain any * This is incremented when a bug fix release is made that does not contain any
@ -1183,6 +1186,7 @@ typedef struct GLFWgammaramp
/*! @brief Image data. /*! @brief Image data.
* *
* @sa @ref cursor_custom * @sa @ref cursor_custom
* @sa @ref window_icon
* *
* @since Added in version 2.1. * @since Added in version 2.1.
* @glfw3 Removed format and bytes-per-pixel members. * @glfw3 Removed format and bytes-per-pixel members.
@ -1740,6 +1744,10 @@ GLFWAPI void glfwWindowHint(int hint, int value);
* screen windows, including the creation of so called _windowed full screen_ * screen windows, including the creation of so called _windowed full screen_
* or _borderless full screen_ windows, see @ref window_windowed_full_screen. * or _borderless full screen_ windows, see @ref window_windowed_full_screen.
* *
* Once you have created the window, you can switch it between windowed and
* full screen mode with @ref glfwSetWindowMonitor. If the window has an
* OpenGL or OpenGL ES context, it will be unaffected.
*
* By default, newly created windows use the placement recommended by the * By default, newly created windows use the placement recommended by the
* window system. To create the window at a specific position, make it * window system. To create the window at a specific position, make it
* initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window * initially invisible using the [GLFW_VISIBLE](@ref window_hints_wnd) window
@ -1776,9 +1784,10 @@ GLFWAPI void glfwWindowHint(int hint, int value);
* @remark @win32 Window creation will fail if the Microsoft GDI software * @remark @win32 Window creation will fail if the Microsoft GDI software
* OpenGL implementation is the only one available. * OpenGL implementation is the only one available.
* *
* @remark @win32 If the executable has an icon resource named `GLFW_ICON,` * @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it
* it will be set as the icon for the window. If no such icon is present, the * will be set as the initial icon for the window. If no such icon is present,
* `IDI_WINLOGO` icon will be used instead. * the `IDI_WINLOGO` icon will be used instead. To set a different icon, see
* @ref glfwSetWindowIcon.
* *
* @remark @win32 The context to share resources with must not be current on * @remark @win32 The context to share resources with must not be current on
* any other thread. * any other thread.
@ -1804,8 +1813,6 @@ GLFWAPI void glfwWindowHint(int hint, int value);
* a custom `Info.plist` template for this, which can be found as * a custom `Info.plist` template for this, which can be found as
* `CMake/MacOSXBundleInfo.plist.in` in the source tree. * `CMake/MacOSXBundleInfo.plist.in` in the source tree.
* *
* @remark @x11 There is no mechanism for setting the window icon yet.
*
* @remark @x11 Some window managers will not respect the placement of * @remark @x11 Some window managers will not respect the placement of
* initially hidden windows. * initially hidden windows.
* *
@ -1947,8 +1954,8 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
* returns. * returns.
* *
* @remark @osx The GLFW window has no icon, as it is not a document * @remark @osx The GLFW window has no icon, as it is not a document
* window, but the dock icon will be the same as the application bundle's icon. * window, so this function does nothing. The dock icon will be the same as
* For more information on bundles, see the * the application bundle's icon. For more information on bundles, see the
* [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/) * [Bundle Programming Guide](https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/)
* in the Mac Developer Library. * in the Mac Developer Library.
* *
@ -2298,6 +2305,9 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* window);
* *
* @param[in] window The window to maximize. * @param[in] window The window to maximize.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @par Thread Safety * @par Thread Safety
* This function may only be called from the main thread. * This function may only be called from the main thread.
* *
@ -2389,8 +2399,8 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window);
* in full screen on. * in full screen on.
* *
* @param[in] window The window to query. * @param[in] window The window to query.
* @return The monitor, or `NULL` if the window is in windowed mode or an error * @return The monitor, or `NULL` if the window is in windowed mode or an
* occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
@ -2435,7 +2445,8 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
* or video mode. * or video mode.
* @param[in] height The desired height, in screen coordinates, of the client * @param[in] height The desired height, in screen coordinates, of the client
* area or video mode. * area or video mode.
* @param[in] refreshRate The desired refresh rate, in Hz, of the video mode. * @param[in] refreshRate The desired refresh rate, in Hz, of the video mode,
* or `GLFW_DONT_CARE`.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
@ -2844,7 +2855,7 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout);
/*! @brief Posts an empty event to the event queue. /*! @brief Posts an empty event to the event queue.
* *
* This function posts an empty event from the current thread to the event * This function posts an empty event from the current thread to the event
* queue, causing @ref glfwWaitEvents to return. * queue, causing @ref glfwWaitEvents or @ref glfwWaitEventsTimeout to return.
* *
* If no windows exist, this function returns immediately. For synchronization * If no windows exist, this function returns immediately. For synchronization
* of threads in applications that do not create windows, use your threading * of threads in applications that do not create windows, use your threading
@ -2857,6 +2868,7 @@ GLFWAPI void glfwWaitEventsTimeout(double timeout);
* *
* @sa @ref events * @sa @ref events
* @sa glfwWaitEvents * @sa glfwWaitEvents
* @sa glfwWaitEventsTimeout
* *
* @since Added in version 3.1. * @since Added in version 3.1.
* *
@ -3125,10 +3137,6 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @x11 Due to the asynchronous nature of X11, it may take a moment for
* the window focus event to arrive. This means you may not be able to set the
* cursor position directly after window creation.
*
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *
* @sa @ref cursor_pos * @sa @ref cursor_pos
@ -3356,7 +3364,7 @@ GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* window, GLFWcharfun cbfun);
* @param[in] cbfun The new callback, or `NULL` to remove the currently set * @param[in] cbfun The new callback, or `NULL` to remove the currently set
* callback. * callback.
* @return The previously set callback, or `NULL` if no callback was set or an * @return The previously set callback, or `NULL` if no callback was set or an
* error occurred. * [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
@ -3535,8 +3543,10 @@ GLFWAPI int glfwJoystickPresent(int joy);
* *
* @param[in] joy The [joystick](@ref joysticks) to query. * @param[in] joy The [joystick](@ref joysticks) to query.
* @param[out] count Where to store the number of axis values in the returned * @param[out] count Where to store the number of axis values in the returned
* array. This is set to zero if an error occurred. * array. This is set to zero if the joystick is not present or an error
* @return An array of axis values, or `NULL` if the joystick is not present. * occurred.
* @return An array of axis values, or `NULL` if the joystick is not present or
* an [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
@ -3567,8 +3577,10 @@ GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count);
* *
* @param[in] joy The [joystick](@ref joysticks) to query. * @param[in] joy The [joystick](@ref joysticks) to query.
* @param[out] count Where to store the number of button states in the returned * @param[out] count Where to store the number of button states in the returned
* array. This is set to zero if an error occurred. * array. This is set to zero if the joystick is not present or an error
* @return An array of button states, or `NULL` if the joystick is not present. * occurred.
* @return An array of button states, or `NULL` if the joystick is not present
* or an [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
@ -3601,7 +3613,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count);
* *
* @param[in] joy The [joystick](@ref joysticks) to query. * @param[in] joy The [joystick](@ref joysticks) to query.
* @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick * @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
* is not present. * is not present or an [error](@ref error_handling) occurred.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR. * GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
@ -3714,8 +3726,9 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* window);
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
* @thread_safety This function may be called from any thread. Reading of the * @thread_safety This function may be called from any thread. Reading and
* internal timer offset is not atomic. * writing of the internal timer offset is not atomic, so it needs to be
* externally synchronized with calls to @ref glfwSetTime.
* *
* @sa @ref time * @sa @ref time
* *
@ -3740,8 +3753,9 @@ GLFWAPI double glfwGetTime(void);
* floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations * floor((2<sup>64</sup> - 1) / 10<sup>9</sup>) and is due to implementations
* storing nanoseconds in 64 bits. The limit may be increased in the future. * storing nanoseconds in 64 bits. The limit may be increased in the future.
* *
* @thread_safety This function may be called from any thread. Writing of the * @thread_safety This function may be called from any thread. Reading and
* internal timer offset is not atomic. * writing of the internal timer offset is not atomic, so it needs to be
* externally synchronized with calls to @ref glfwGetTime.
* *
* @sa @ref time * @sa @ref time
* *

View File

@ -1,9 +1,9 @@
/************************************************************************* /*************************************************************************
* GLFW 3.2 - www.glfw.org * GLFW 3.3 - www.glfw.org
* A library for OpenGL, window and input * A library for OpenGL, window and input
*------------------------------------------------------------------------ *------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard * Copyright (c) 2002-2006 Marcus Geelnard
* Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> * Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
* *
* This software is provided 'as-is', without any express or implied * This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages * warranty. In no event will the authors be held liable for any damages

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.2 OS X - www.glfw.org // GLFW 3.3 OS X - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -200,6 +200,97 @@ static void createKeyTables(void)
} }
} }
// Retrieve Unicode data for the current keyboard layout
//
static GLFWbool updateUnicodeDataNS(void)
{
if (_glfw.ns.inputSource)
{
CFRelease(_glfw.ns.inputSource);
_glfw.ns.inputSource = NULL;
_glfw.ns.unicodeData = nil;
}
_glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource();
if (!_glfw.ns.inputSource)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve keyboard layout input source");
return GLFW_FALSE;
}
_glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
if (!_glfw.ns.unicodeData)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve keyboard layout Unicode data");
return GLFW_FALSE;
}
return GLFW_TRUE;
}
// Load HIToolbox.framework and the TIS symbols we need from it
//
static GLFWbool initializeTIS(void)
{
// This works only because Cocoa has already loaded it properly
_glfw.ns.tis.bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
if (!_glfw.ns.tis.bundle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to load HIToolbox.framework");
return GLFW_FALSE;
}
CFStringRef* kPropertyUnicodeKeyLayoutData =
CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,
CFSTR("kTISPropertyUnicodeKeyLayoutData"));
CFStringRef* kNotifySelectedKeyboardInputSourceChanged =
CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,
CFSTR("kTISNotifySelectedKeyboardInputSourceChanged"));
_glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("TISCopyCurrentKeyboardLayoutInputSource"));
_glfw.ns.tis.GetInputSourceProperty =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("TISGetInputSourceProperty"));
_glfw.ns.tis.GetKbdType =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("LMGetKbdType"));
if (!kPropertyUnicodeKeyLayoutData ||
!kNotifySelectedKeyboardInputSourceChanged ||
!TISCopyCurrentKeyboardLayoutInputSource ||
!TISGetInputSourceProperty ||
!LMGetKbdType)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to load TIS API symbols");
return GLFW_FALSE;
}
_glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
*kPropertyUnicodeKeyLayoutData;
_glfw.ns.tis.kNotifySelectedKeyboardInputSourceChanged =
*kNotifySelectedKeyboardInputSourceChanged;
return updateUnicodeDataNS();
}
@interface GLFWLayoutListener : NSObject
@end
@implementation GLFWLayoutListener
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
{
updateUnicodeDataNS();
}
@end
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
@ -209,6 +300,13 @@ int _glfwPlatformInit(void)
{ {
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init]; _glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
_glfw.ns.listener = [[GLFWLayoutListener alloc] init];
[[NSDistributedNotificationCenter defaultCenter]
addObserver:_glfw.ns.listener
selector:@selector(selectedKeyboardInputSourceChanged:)
name:(__bridge NSString*)kTISNotifySelectedKeyboardInputSourceChanged
object:nil];
#if defined(_GLFW_USE_CHDIR) #if defined(_GLFW_USE_CHDIR)
changeToResourcesDirectory(); changeToResourcesDirectory();
#endif #endif
@ -221,23 +319,12 @@ int _glfwPlatformInit(void)
CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0); CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
// TODO: Catch kTISNotifySelectedKeyboardInputSourceChanged and update if (!initializeTIS())
_glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource();
if (!_glfw.ns.inputSource)
return GLFW_FALSE;
_glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
if (!_glfw.ns.unicodeData)
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwInitThreadLocalStoragePOSIX()) if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwInitNSGL())
return GLFW_FALSE;
_glfwInitTimerNS(); _glfwInitTimerNS();
_glfwInitJoysticksNS(); _glfwInitJoysticksNS();
@ -250,6 +337,7 @@ void _glfwPlatformTerminate(void)
{ {
CFRelease(_glfw.ns.inputSource); CFRelease(_glfw.ns.inputSource);
_glfw.ns.inputSource = NULL; _glfw.ns.inputSource = NULL;
_glfw.ns.unicodeData = nil;
} }
if (_glfw.ns.eventSource) if (_glfw.ns.eventSource)
@ -265,6 +353,18 @@ void _glfwPlatformTerminate(void)
_glfw.ns.delegate = nil; _glfw.ns.delegate = nil;
} }
if (_glfw.ns.listener)
{
[[NSDistributedNotificationCenter defaultCenter]
removeObserver:_glfw.ns.listener
name:(__bridge NSString*)kTISNotifySelectedKeyboardInputSourceChanged
object:nil];
[[NSDistributedNotificationCenter defaultCenter]
removeObserver:_glfw.ns.listener];
[_glfw.ns.listener release];
_glfw.ns.listener = nil;
}
[_glfw.ns.cursor release]; [_glfw.ns.cursor release];
_glfw.ns.cursor = nil; _glfw.ns.cursor = nil;

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.2 Cocoa - www.glfw.org // GLFW 3.3 Cocoa - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2006-2014 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -32,12 +32,13 @@
#include <IOKit/hid/IOHIDLib.h> #include <IOKit/hid/IOHIDLib.h>
#include <IOKit/hid/IOHIDKeys.h> #include <IOKit/hid/IOHIDKeys.h>
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWjoystickNS ns_js #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
_GLFWjoystickNS ns_js[GLFW_JOYSTICK_LAST + 1]
// Cocoa-specific per-joystick data // Cocoa-specific per-joystick data
// //
typedef struct _GLFWjoydeviceNS typedef struct _GLFWjoystickNS
{ {
GLFWbool present; GLFWbool present;
char name[256]; char name[256];
@ -50,17 +51,9 @@ typedef struct _GLFWjoydeviceNS
float* axes; float* axes;
unsigned char* buttons; unsigned char* buttons;
} _GLFWjoydeviceNS;
// Cocoa-specific joystick API data
//
typedef struct _GLFWjoystickNS
{
_GLFWjoydeviceNS js[GLFW_JOYSTICK_LAST + 1];
IOHIDManagerRef managerRef;
} _GLFWjoystickNS; } _GLFWjoystickNS;
void _glfwInitJoysticksNS(void); void _glfwInitJoysticksNS(void);
void _glfwTerminateJoysticksNS(void); void _glfwTerminateJoysticksNS(void);

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.2 Cocoa - www.glfw.org // GLFW 3.3 Cocoa - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net> // Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
@ -57,7 +57,7 @@ static void getElementsCFArrayHandler(const void* value, void* parameter);
// Adds an element to the specified joystick // Adds an element to the specified joystick
// //
static void addJoystickElement(_GLFWjoydeviceNS* js, static void addJoystickElement(_GLFWjoystickNS* js,
IOHIDElementRef elementRef) IOHIDElementRef elementRef)
{ {
IOHIDElementType elementType; IOHIDElementType elementType;
@ -126,14 +126,14 @@ static void getElementsCFArrayHandler(const void* value, void* parameter)
{ {
if (CFGetTypeID(value) == IOHIDElementGetTypeID()) if (CFGetTypeID(value) == IOHIDElementGetTypeID())
{ {
addJoystickElement((_GLFWjoydeviceNS*) parameter, addJoystickElement((_GLFWjoystickNS*) parameter,
(IOHIDElementRef) value); (IOHIDElementRef) value);
} }
} }
// Returns the value of the specified element of the specified joystick // Returns the value of the specified element of the specified joystick
// //
static long getElementValue(_GLFWjoydeviceNS* js, _GLFWjoyelementNS* element) static long getElementValue(_GLFWjoystickNS* js, _GLFWjoyelementNS* element)
{ {
IOReturn result = kIOReturnSuccess; IOReturn result = kIOReturnSuccess;
IOHIDValueRef valueRef; IOHIDValueRef valueRef;
@ -163,7 +163,7 @@ static long getElementValue(_GLFWjoydeviceNS* js, _GLFWjoyelementNS* element)
// Removes the specified joystick // Removes the specified joystick
// //
static void removeJoystick(_GLFWjoydeviceNS* js) static void removeJoystick(_GLFWjoystickNS* js)
{ {
int i; int i;
@ -188,14 +188,14 @@ static void removeJoystick(_GLFWjoydeviceNS* js)
free(js->axes); free(js->axes);
free(js->buttons); free(js->buttons);
memset(js, 0, sizeof(_GLFWjoydeviceNS)); memset(js, 0, sizeof(_GLFWjoystickNS));
_glfwInputJoystickChange(js - _glfw.ns_js.js, GLFW_DISCONNECTED); _glfwInputJoystickChange(js - _glfw.ns_js, GLFW_DISCONNECTED);
} }
// Polls for joystick axis events and updates GLFW state // Polls for joystick axis events and updates GLFW state
// //
static GLFWbool pollJoystickAxisEvents(_GLFWjoydeviceNS* js) static GLFWbool pollJoystickAxisEvents(_GLFWjoystickNS* js)
{ {
CFIndex i; CFIndex i;
@ -221,7 +221,7 @@ static GLFWbool pollJoystickAxisEvents(_GLFWjoydeviceNS* js)
// Polls for joystick button events and updates GLFW state // Polls for joystick button events and updates GLFW state
// //
static GLFWbool pollJoystickButtonEvents(_GLFWjoydeviceNS* js) static GLFWbool pollJoystickButtonEvents(_GLFWjoystickNS* js)
{ {
CFIndex i; CFIndex i;
int buttonIndex = 0; int buttonIndex = 0;
@ -271,25 +271,25 @@ static void matchCallback(void* context,
void* sender, void* sender,
IOHIDDeviceRef deviceRef) IOHIDDeviceRef deviceRef)
{ {
_GLFWjoydeviceNS* js; _GLFWjoystickNS* js;
int joy; int joy;
for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++)
{ {
if (_glfw.ns_js.js[joy].present && _glfw.ns_js.js[joy].deviceRef == deviceRef) if (_glfw.ns_js[joy].present && _glfw.ns_js[joy].deviceRef == deviceRef)
return; return;
} }
for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++)
{ {
if (!_glfw.ns_js.js[joy].present) if (!_glfw.ns_js[joy].present)
break; break;
} }
if (joy > GLFW_JOYSTICK_LAST) if (joy > GLFW_JOYSTICK_LAST)
return; return;
js = _glfw.ns_js.js + joy; js = _glfw.ns_js + joy;
js->present = GLFW_TRUE; js->present = GLFW_TRUE;
js->deviceRef = deviceRef; js->deviceRef = deviceRef;
@ -338,9 +338,9 @@ static void removeCallback(void* context,
for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++)
{ {
if (_glfw.ns_js.js[joy].deviceRef == deviceRef) if (_glfw.ns_js[joy].deviceRef == deviceRef)
{ {
removeJoystick(_glfw.ns_js.js + joy); removeJoystick(_glfw.ns_js + joy);
break; break;
} }
} }
@ -397,7 +397,7 @@ void _glfwInitJoysticksNS(void)
{ {
CFMutableArrayRef matchingCFArrayRef; CFMutableArrayRef matchingCFArrayRef;
_glfw.ns_js.managerRef = IOHIDManagerCreate(kCFAllocatorDefault, _glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone); kIOHIDOptionsTypeNone);
matchingCFArrayRef = CFArrayCreateMutable(kCFAllocatorDefault, matchingCFArrayRef = CFArrayCreateMutable(kCFAllocatorDefault,
@ -431,21 +431,21 @@ void _glfwInitJoysticksNS(void)
CFRelease(matchingCFDictRef); CFRelease(matchingCFDictRef);
} }
IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns_js.managerRef, IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager,
matchingCFArrayRef); matchingCFArrayRef);
CFRelease(matchingCFArrayRef); CFRelease(matchingCFArrayRef);
} }
IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns_js.managerRef, IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager,
&matchCallback, NULL); &matchCallback, NULL);
IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns_js.managerRef, IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager,
&removeCallback, NULL); &removeCallback, NULL);
IOHIDManagerScheduleWithRunLoop(_glfw.ns_js.managerRef, IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager,
CFRunLoopGetMain(), CFRunLoopGetMain(),
kCFRunLoopDefaultMode); kCFRunLoopDefaultMode);
IOHIDManagerOpen(_glfw.ns_js.managerRef, kIOHIDOptionsTypeNone); IOHIDManagerOpen(_glfw.ns.hidManager, kIOHIDOptionsTypeNone);
// Execute the run loop once in order to register any initially-attached // Execute the run loop once in order to register any initially-attached
// joysticks // joysticks
@ -460,12 +460,12 @@ void _glfwTerminateJoysticksNS(void)
for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++) for (joy = GLFW_JOYSTICK_1; joy <= GLFW_JOYSTICK_LAST; joy++)
{ {
_GLFWjoydeviceNS* js = _glfw.ns_js.js + joy; _GLFWjoystickNS* js = _glfw.ns_js + joy;
removeJoystick(js); removeJoystick(js);
} }
CFRelease(_glfw.ns_js.managerRef); CFRelease(_glfw.ns.hidManager);
_glfw.ns_js.managerRef = NULL; _glfw.ns.hidManager = NULL;
} }
@ -475,13 +475,13 @@ void _glfwTerminateJoysticksNS(void)
int _glfwPlatformJoystickPresent(int joy) int _glfwPlatformJoystickPresent(int joy)
{ {
_GLFWjoydeviceNS* js = _glfw.ns_js.js + joy; _GLFWjoystickNS* js = _glfw.ns_js + joy;
return js->present; return js->present;
} }
const float* _glfwPlatformGetJoystickAxes(int joy, int* count) const float* _glfwPlatformGetJoystickAxes(int joy, int* count)
{ {
_GLFWjoydeviceNS* js = _glfw.ns_js.js + joy; _GLFWjoystickNS* js = _glfw.ns_js + joy;
if (!pollJoystickAxisEvents(js)) if (!pollJoystickAxisEvents(js))
return NULL; return NULL;
@ -491,7 +491,7 @@ const float* _glfwPlatformGetJoystickAxes(int joy, int* count)
const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count) const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
{ {
_GLFWjoydeviceNS* js = _glfw.ns_js.js + joy; _GLFWjoystickNS* js = _glfw.ns_js + joy;
if (!pollJoystickButtonEvents(js)) if (!pollJoystickButtonEvents(js))
return NULL; return NULL;
@ -502,7 +502,7 @@ const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
const char* _glfwPlatformGetJoystickName(int joy) const char* _glfwPlatformGetJoystickName(int joy)
{ {
_GLFWjoydeviceNS* js = _glfw.ns_js.js + joy; _GLFWjoystickNS* js = _glfw.ns_js + joy;
if (!js->present) if (!js->present)
return NULL; return NULL;

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 OS X - www.glfw.org // GLFW 3.3 OS X - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -27,11 +27,9 @@
#include "internal.h" #include "internal.h"
#include <stdlib.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include <IOKit/graphics/IOGraphicsLib.h> #include <IOKit/graphics/IOGraphicsLib.h>
#include <CoreVideo/CVBase.h> #include <CoreVideo/CVBase.h>
#include <CoreVideo/CVDisplayLink.h> #include <CoreVideo/CVDisplayLink.h>
@ -66,7 +64,7 @@ static char* getDisplayName(CGDirectDisplayID displayID)
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value), size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value),
kCFStringEncodingUTF8); kCFStringEncodingUTF8);
name = calloc(size + 1, sizeof(char)); name = calloc(size + 1, 1);
CFStringGetCString(value, name, size, kCFStringEncodingUTF8); CFStringGetCString(value, name, size, kCFStringEncodingUTF8);
CFRelease(info); CFRelease(info);

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.2 OS X - www.glfw.org // GLFW 3.3 OS X - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -56,6 +56,16 @@ typedef void* id;
#define _GLFW_EGL_CONTEXT_STATE #define _GLFW_EGL_CONTEXT_STATE
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE #define _GLFW_EGL_LIBRARY_CONTEXT_STATE
// HIToolbox.framework pointer typedefs
#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
#define kTISNotifySelectedKeyboardInputSourceChanged _glfw.ns.tis.kNotifySelectedKeyboardInputSourceChanged
typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void);
#define TISCopyCurrentKeyboardLayoutInputSource _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource
typedef void* (*PFN_TISGetInputSourceProperty)(TISInputSourceRef,CFStringRef);
#define TISGetInputSourceProperty _glfw.ns.tis.GetInputSourceProperty
typedef UInt8 (*PFN_LMGetKbdType)(void);
#define LMGetKbdType _glfw.ns.tis.GetKbdType
// Cocoa-specific per-window data // Cocoa-specific per-window data
// //
@ -68,11 +78,10 @@ typedef struct _GLFWwindowNS
// The total sum of the distances the cursor has been warped // The total sum of the distances the cursor has been warped
// since the last cursor motion event was processed // since the last cursor motion event was processed
// This is kept to counteract Cocoa doing the same internally // This is kept to counteract Cocoa doing the same internally
double warpDeltaX, warpDeltaY; double cursorWarpDeltaX, cursorWarpDeltaY;
} _GLFWwindowNS; } _GLFWwindowNS;
// Cocoa-specific global data // Cocoa-specific global data
// //
typedef struct _GLFWlibraryNS typedef struct _GLFWlibraryNS
@ -82,16 +91,30 @@ typedef struct _GLFWlibraryNS
id autoreleasePool; id autoreleasePool;
id cursor; id cursor;
TISInputSourceRef inputSource; TISInputSourceRef inputSource;
IOHIDManagerRef hidManager;
id unicodeData; id unicodeData;
id listener;
char keyName[64]; char keyName[64];
short int publicKeys[256]; short int publicKeys[256];
short int nativeKeys[GLFW_KEY_LAST + 1]; short int nativeKeys[GLFW_KEY_LAST + 1];
char* clipboardString; char* clipboardString;
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
struct {
CFBundleRef bundle;
PFN_TISCopyCurrentKeyboardLayoutInputSource CopyCurrentKeyboardLayoutInputSource;
PFN_TISGetInputSourceProperty GetInputSourceProperty;
PFN_LMGetKbdType GetKbdType;
CFStringRef kPropertyUnicodeKeyLayoutData;
CFStringRef kNotifySelectedKeyboardInputSourceChanged;
} tis;
} _GLFWlibraryNS; } _GLFWlibraryNS;
// Cocoa-specific per-monitor data // Cocoa-specific per-monitor data
// //
typedef struct _GLFWmonitorNS typedef struct _GLFWmonitorNS
@ -102,7 +125,6 @@ typedef struct _GLFWmonitorNS
} _GLFWmonitorNS; } _GLFWmonitorNS;
// Cocoa-specific per-cursor data // Cocoa-specific per-cursor data
// //
typedef struct _GLFWcursorNS typedef struct _GLFWcursorNS
@ -111,7 +133,6 @@ typedef struct _GLFWcursorNS
} _GLFWcursorNS; } _GLFWcursorNS;
// Cocoa-specific global timer data // Cocoa-specific global timer data
// //
typedef struct _GLFWtimeNS typedef struct _GLFWtimeNS

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.2 OS X - www.glfw.org // GLFW 3.3 OS X - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.2 OS X - www.glfw.org // GLFW 3.3 OS X - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -85,6 +85,29 @@ static void centerCursor(_GLFWwindow *window)
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
} }
// Returns whether the cursor is in the client area of the specified window
//
static GLFWbool cursorInClientArea(_GLFWwindow* window)
{
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
return [window->ns.view mouse:pos inRect:[window->ns.view frame]];
}
// Updates the cursor image according to its cursor mode
//
static void updateCursorImage(_GLFWwindow* window)
{
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
[(NSCursor*) window->cursor->ns.object set];
else
[[NSCursor arrowCursor] set];
}
else
[(NSCursor*) _glfw.ns.cursor set];
}
// Transforms the specified y-coordinate between the CG display and NS screen // Transforms the specified y-coordinate between the CG display and NS screen
// coordinate systems // coordinate systems
// //
@ -212,11 +235,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
if (window->context.client != GLFW_NO_API) if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update]; [window->context.nsgl.object update];
if (_glfw.cursorWindow == window && if (_glfw.ns.disabledCursorWindow == window)
window->cursorMode == GLFW_CURSOR_DISABLED)
{
centerCursor(window); centerCursor(window);
}
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect]; const NSRect fbRect = [window->ns.view convertRectToBacking:contentRect];
@ -230,11 +250,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
if (window->context.client != GLFW_NO_API) if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update]; [window->context.nsgl.object update];
if (_glfw.cursorWindow == window && if (_glfw.ns.disabledCursorWindow == window)
window->cursorMode == GLFW_CURSOR_DISABLED)
{
centerCursor(window); centerCursor(window);
}
int x, y; int x, y;
_glfwPlatformGetWindowPos(window, &x, &y); _glfwPlatformGetWindowPos(window, &x, &y);
@ -259,11 +276,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)windowDidBecomeKey:(NSNotification *)notification - (void)windowDidBecomeKey:(NSNotification *)notification
{ {
if (_glfw.cursorWindow == window && if (_glfw.ns.disabledCursorWindow == window)
window->cursorMode == GLFW_CURSOR_DISABLED)
{
centerCursor(window); centerCursor(window);
}
_glfwInputWindowFocus(window, GLFW_TRUE); _glfwInputWindowFocus(window, GLFW_TRUE);
_glfwPlatformSetCursorMode(window, window->cursorMode); _glfwPlatformSetCursorMode(window, window->cursorMode);
@ -398,7 +412,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)cursorUpdate:(NSEvent *)event - (void)cursorUpdate:(NSEvent *)event
{ {
_glfwPlatformSetCursorMode(window, window->cursorMode); updateCursorImage(window);
} }
- (void)mouseDown:(NSEvent *)event - (void)mouseDown:(NSEvent *)event
@ -426,20 +440,23 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
{ {
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
{ {
_glfwInputCursorMotion(window, const double dx = [event deltaX] - window->ns.cursorWarpDeltaX;
[event deltaX] - window->ns.warpDeltaX, const double dy = [event deltaY] - window->ns.cursorWarpDeltaY;
[event deltaY] - window->ns.warpDeltaY);
_glfwInputCursorPos(window,
window->virtualCursorPosX + dx,
window->virtualCursorPosY + dy);
} }
else else
{ {
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSPoint pos = [event locationInWindow]; const NSPoint pos = [event locationInWindow];
_glfwInputCursorMotion(window, pos.x, contentRect.size.height - pos.y); _glfwInputCursorPos(window, pos.x, contentRect.size.height - pos.y);
} }
window->ns.warpDeltaX = 0; window->ns.cursorWarpDeltaX = 0;
window->ns.warpDeltaY = 0; window->ns.cursorWarpDeltaY = 0;
} }
- (void)rightMouseDown:(NSEvent *)event - (void)rightMouseDown:(NSEvent *)event
@ -611,7 +628,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType]; NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType];
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
_glfwInputCursorMotion(window, _glfwInputCursorPos(window,
[sender draggingLocation].x, [sender draggingLocation].x,
contentRect.size.height - [sender draggingLocation].y); contentRect.size.height - [sender draggingLocation].y);
@ -767,6 +784,12 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
[super sendEvent:event]; [super sendEvent:event];
} }
// No-op thread entry point
//
- (void)doNothing:(id)object
{
}
@end @end
#if defined(_GLFW_USE_MENUBAR) #if defined(_GLFW_USE_MENUBAR)
@ -892,6 +915,11 @@ static GLFWbool initializeAppKit(void)
// Implicitly create shared NSApplication instance // Implicitly create shared NSApplication instance
[GLFWApplication sharedApplication]; [GLFWApplication sharedApplication];
// Make Cocoa enter multi-threaded mode
[NSThread detachNewThreadSelector:@selector(doNothing:)
toTarget:NSApp
withObject:nil];
// In case we are unbundled, make us a proper UI application // In case we are unbundled, make us a proper UI application
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
@ -920,7 +948,7 @@ static GLFWbool initializeAppKit(void)
// Create the Cocoa window // Create the Cocoa window
// //
static GLFWbool createWindow(_GLFWwindow* window, static GLFWbool createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig) const _GLFWwndconfig* wndconfig)
{ {
window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window]; window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window];
@ -1003,13 +1031,15 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!initializeAppKit()) if (!initializeAppKit())
return GLFW_FALSE; return GLFW_FALSE;
if (!createWindow(window, wndconfig)) if (!createNativeWindow(window, wndconfig))
return GLFW_FALSE; return GLFW_FALSE;
if (ctxconfig->client != GLFW_NO_API) if (ctxconfig->client != GLFW_NO_API)
{ {
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API) if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{ {
if (!_glfwInitNSGL())
return GLFW_FALSE;
if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig)) if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -1026,6 +1056,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
_glfwPlatformFocusWindow(window); _glfwPlatformFocusWindow(window);
if (!acquireMonitor(window)) if (!acquireMonitor(window))
return GLFW_FALSE; return GLFW_FALSE;
centerCursor(window);
} }
return GLFW_TRUE; return GLFW_TRUE;
@ -1033,13 +1065,16 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
void _glfwPlatformDestroyWindow(_GLFWwindow* window) void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{ {
if (_glfw.ns.disabledCursorWindow == window)
_glfw.ns.disabledCursorWindow = NULL;
[window->ns.object orderOut:nil]; [window->ns.object orderOut:nil];
if (window->monitor) if (window->monitor)
releaseMonitor(window); releaseMonitor(window);
if (window->context.client != GLFW_NO_API) if (window->context.destroy)
window->context.destroyContext(window); window->context.destroy(window);
[window->ns.object setDelegate:nil]; [window->ns.object setDelegate:nil];
[window->ns.delegate release]; [window->ns.delegate release];
@ -1409,13 +1444,13 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{ {
_glfwPlatformSetCursorMode(window, window->cursorMode); updateCursorImage(window);
const NSRect contentRect = [window->ns.view frame]; const NSRect contentRect = [window->ns.view frame];
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream];
window->ns.warpDeltaX += x - pos.x; window->ns.cursorWarpDeltaX += x - pos.x;
window->ns.warpDeltaY += y - contentRect.size.height + pos.y; window->ns.cursorWarpDeltaY += y - contentRect.size.height + pos.y;
if (window->monitor) if (window->monitor)
{ {
@ -1435,20 +1470,26 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{ {
if (mode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
[(NSCursor*) window->cursor->ns.object set];
else
[[NSCursor arrowCursor] set];
}
else
[(NSCursor*) _glfw.ns.cursor set];
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED)
{
_glfw.ns.disabledCursorWindow = window;
_glfwPlatformGetCursorPos(window,
&_glfw.ns.restoreCursorPosX,
&_glfw.ns.restoreCursorPosY);
centerCursor(window);
CGAssociateMouseAndMouseCursorPosition(false); CGAssociateMouseAndMouseCursorPosition(false);
else }
else if (_glfw.ns.disabledCursorWindow == window)
{
_glfw.ns.disabledCursorWindow = NULL;
CGAssociateMouseAndMouseCursorPosition(true); CGAssociateMouseAndMouseCursorPosition(true);
_glfwPlatformSetCursorPos(window,
_glfw.ns.restoreCursorPosX,
_glfw.ns.restoreCursorPosY);
}
if (cursorInClientArea(window))
updateCursorImage(window);
} }
const char* _glfwPlatformGetKeyName(int key, int scancode) const char* _glfwPlatformGetKeyName(int key, int scancode)
@ -1561,16 +1602,8 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{ {
const NSPoint pos = [window->ns.object mouseLocationOutsideOfEventStream]; if (cursorInClientArea(window))
updateCursorImage(window);
if (window->cursorMode == GLFW_CURSOR_NORMAL &&
[window->ns.view mouse:pos inRect:[window->ns.view frame]])
{
if (cursor)
[(NSCursor*) cursor->ns.object set];
else
[[NSCursor arrowCursor] set];
}
} }
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 - www.glfw.org // GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -34,56 +34,6 @@
#include <stdio.h> #include <stdio.h>
// Parses the client API version string and extracts the version number
//
static GLFWbool parseVersionString(int* api, int* major, int* minor, int* rev)
{
int i;
_GLFWwindow* window;
const char* version;
const char* prefixes[] =
{
"OpenGL ES-CM ",
"OpenGL ES-CL ",
"OpenGL ES ",
NULL
};
*api = GLFW_OPENGL_API;
window = _glfwPlatformGetCurrentContext();
version = (const char*) window->context.GetString(GL_VERSION);
if (!version)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Client API version string retrieval is broken");
return GLFW_FALSE;
}
for (i = 0; prefixes[i]; i++)
{
const size_t length = strlen(prefixes[i]);
if (strncmp(version, prefixes[i], length) == 0)
{
version += length;
*api = GLFW_OPENGL_ES_API;
break;
}
}
if (!sscanf(version, "%d.%d.%d", major, minor, rev))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"No version found in client API version string");
return GLFW_FALSE;
}
return GLFW_TRUE;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -375,27 +325,79 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig) GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
{ {
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); int i;
_GLFWwindow* window;
const char* version;
const char* prefixes[] =
{
"OpenGL ES-CM ",
"OpenGL ES-CL ",
"OpenGL ES ",
NULL
};
window = _glfwPlatformGetCurrentContext();
window->context.source = ctxconfig->source;
window->context.client = GLFW_OPENGL_API;
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC) window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
glfwGetProcAddress("glGetIntegerv"); window->context.getProcAddress("glGetIntegerv");
window->context.GetString = (PFNGLGETSTRINGPROC) window->context.GetString = (PFNGLGETSTRINGPROC)
glfwGetProcAddress("glGetString"); window->context.getProcAddress("glGetString");
if (!window->context.GetIntegerv || !window->context.GetString) if (!window->context.GetIntegerv || !window->context.GetString)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken"); _glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
return GLFW_FALSE; return GLFW_FALSE;
} }
if (!parseVersionString(&window->context.client, version = (const char*) window->context.GetString(GL_VERSION);
if (!version)
{
if (ctxconfig->client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OpenGL version string retrieval is broken");
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OpenGL ES version string retrieval is broken");
}
return GLFW_FALSE;
}
for (i = 0; prefixes[i]; i++)
{
const size_t length = strlen(prefixes[i]);
if (strncmp(version, prefixes[i], length) == 0)
{
version += length;
window->context.client = GLFW_OPENGL_ES_API;
break;
}
}
if (!sscanf(version, "%d.%d.%d",
&window->context.major, &window->context.major,
&window->context.minor, &window->context.minor,
&window->context.revision)) &window->context.revision))
{ {
return GLFW_FALSE; if (window->context.client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"No version found in OpenGL version string");
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"No version found in OpenGL ES version string");
} }
window->context.source = ctxconfig->source; return GLFW_FALSE;
}
if (window->context.major < ctxconfig->major || if (window->context.major < ctxconfig->major ||
(window->context.major == ctxconfig->major && (window->context.major == ctxconfig->major &&
@ -408,10 +410,21 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
// For API consistency, we emulate the behavior of the // For API consistency, we emulate the behavior of the
// {GLX|WGL}_ARB_create_context extension and fail here // {GLX|WGL}_ARB_create_context extension and fail here
if (window->context.client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE, _glfwInputError(GLFW_VERSION_UNAVAILABLE,
"Requested client API version %i.%i, got version %i.%i", "Requested OpenGL version %i.%i, got version %i.%i",
ctxconfig->major, ctxconfig->minor, ctxconfig->major, ctxconfig->minor,
window->context.major, window->context.minor); window->context.major, window->context.minor);
}
else
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"Requested OpenGL ES version %i.%i, got version %i.%i",
ctxconfig->major, ctxconfig->minor,
window->context.major, window->context.minor);
}
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -422,7 +435,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
// users as early as possible that their build may be broken // users as early as possible that their build may be broken
window->context.GetStringi = (PFNGLGETSTRINGIPROC) window->context.GetStringi = (PFNGLGETSTRINGIPROC)
glfwGetProcAddress("glGetStringi"); window->context.getProcAddress("glGetStringi");
if (!window->context.GetStringi) if (!window->context.GetStringi)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -527,7 +540,8 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
// Clearing the front buffer to black to avoid garbage pixels left over from // Clearing the front buffer to black to avoid garbage pixels left over from
// previous uses of our bit of VRAM // previous uses of our bit of VRAM
{ {
PFNGLCLEARPROC glClear = (PFNGLCLEARPROC) glfwGetProcAddress("glClear"); PFNGLCLEARPROC glClear = (PFNGLCLEARPROC)
window->context.getProcAddress("glClear");
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
window->context.swapBuffers(window); window->context.swapBuffers(window);
} }
@ -582,11 +596,11 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
if (previous) if (previous)
{ {
if (!window || window->context.source != previous->context.source) if (!window || window->context.source != previous->context.source)
previous->context.makeContextCurrent(NULL); previous->context.makeCurrent(NULL);
} }
if (window) if (window)
window->context.makeContextCurrent(window); window->context.makeCurrent(window);
} }
GLFWAPI GLFWwindow* glfwGetCurrentContext(void) GLFWAPI GLFWwindow* glfwGetCurrentContext(void)

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 EGL - www.glfw.org // GLFW 3.3 EGL - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -28,13 +28,14 @@
#include "internal.h" #include "internal.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
// Return a description of the specified EGL error // Return a description of the specified EGL error
// //
static const char* getErrorString(EGLint error) static const char* getEGLErrorString(EGLint error)
{ {
switch (error) switch (error)
{ {
@ -75,16 +76,16 @@ static const char* getErrorString(EGLint error)
// Returns the specified attribute of the specified EGLConfig // Returns the specified attribute of the specified EGLConfig
// //
static int getConfigAttrib(EGLConfig config, int attrib) static int getEGLConfigAttrib(EGLConfig config, int attrib)
{ {
int value; int value;
eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value); eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
return value; return value;
} }
// Return a list of available and usable framebuffer configs // Return the EGLConfig most closely matching the specified hints
// //
static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig, static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* desired, const _GLFWfbconfig* desired,
EGLConfig* result) EGLConfig* result)
{ {
@ -112,16 +113,16 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
_GLFWfbconfig* u = usableConfigs + usableCount; _GLFWfbconfig* u = usableConfigs + usableCount;
// Only consider RGB(A) EGLConfigs // Only consider RGB(A) EGLConfigs
if (!(getConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER)) if (!(getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER))
continue; continue;
// Only consider window EGLConfigs // Only consider window EGLConfigs
if (!(getConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT)) if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
continue; continue;
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
// Only consider EGLConfigs with associated Visuals // Only consider EGLConfigs with associated Visuals
if (!getConfigAttrib(n, EGL_NATIVE_VISUAL_ID)) if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))
continue; continue;
#endif // _GLFW_X11 #endif // _GLFW_X11
@ -129,30 +130,30 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
{ {
if (ctxconfig->major == 1) if (ctxconfig->major == 1)
{ {
if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT)) if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES_BIT))
continue; continue;
} }
else else
{ {
if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT)) if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT))
continue; continue;
} }
} }
else if (ctxconfig->client == GLFW_OPENGL_API) else if (ctxconfig->client == GLFW_OPENGL_API)
{ {
if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT)) if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))
continue; continue;
} }
u->redBits = getConfigAttrib(n, EGL_RED_SIZE); u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);
u->greenBits = getConfigAttrib(n, EGL_GREEN_SIZE); u->greenBits = getEGLConfigAttrib(n, EGL_GREEN_SIZE);
u->blueBits = getConfigAttrib(n, EGL_BLUE_SIZE); u->blueBits = getEGLConfigAttrib(n, EGL_BLUE_SIZE);
u->alphaBits = getConfigAttrib(n, EGL_ALPHA_SIZE); u->alphaBits = getEGLConfigAttrib(n, EGL_ALPHA_SIZE);
u->depthBits = getConfigAttrib(n, EGL_DEPTH_SIZE); u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
u->stencilBits = getConfigAttrib(n, EGL_STENCIL_SIZE); u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
u->samples = getConfigAttrib(n, EGL_SAMPLES); u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
u->doublebuffer = GLFW_TRUE; u->doublebuffer = GLFW_TRUE;
u->handle = (uintptr_t) n; u->handle = (uintptr_t) n;
@ -169,7 +170,7 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
return closest != NULL; return closest != NULL;
} }
static void makeContextCurrent(_GLFWwindow* window) static void makeContextCurrentEGL(_GLFWwindow* window)
{ {
if (window) if (window)
{ {
@ -180,7 +181,7 @@ static void makeContextCurrent(_GLFWwindow* window)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to make context current: %s", "EGL: Failed to make context current: %s",
getErrorString(eglGetError())); getEGLErrorString(eglGetError()));
return; return;
} }
} }
@ -193,7 +194,7 @@ static void makeContextCurrent(_GLFWwindow* window)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to clear current context: %s", "EGL: Failed to clear current context: %s",
getErrorString(eglGetError())); getEGLErrorString(eglGetError()));
return; return;
} }
} }
@ -201,7 +202,7 @@ static void makeContextCurrent(_GLFWwindow* window)
_glfwPlatformSetCurrentContext(window); _glfwPlatformSetCurrentContext(window);
} }
static void swapBuffers(_GLFWwindow* window) static void swapBuffersEGL(_GLFWwindow* window)
{ {
if (window != _glfwPlatformGetCurrentContext()) if (window != _glfwPlatformGetCurrentContext())
{ {
@ -213,12 +214,12 @@ static void swapBuffers(_GLFWwindow* window)
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface); eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
} }
static void swapInterval(int interval) static void swapIntervalEGL(int interval)
{ {
eglSwapInterval(_glfw.egl.display, interval); eglSwapInterval(_glfw.egl.display, interval);
} }
static int extensionSupported(const char* extension) static int extensionSupportedEGL(const char* extension)
{ {
const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS); const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
if (extensions) if (extensions)
@ -230,7 +231,7 @@ static int extensionSupported(const char* extension)
return GLFW_FALSE; return GLFW_FALSE;
} }
static GLFWglproc getProcAddress(const char* procname) static GLFWglproc getProcAddressEGL(const char* procname)
{ {
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); _GLFWwindow* window = _glfwPlatformGetCurrentContext();
@ -245,7 +246,7 @@ static GLFWglproc getProcAddress(const char* procname)
return eglGetProcAddress(procname); return eglGetProcAddress(procname);
} }
static void destroyContext(_GLFWwindow* window) static void destroyContextEGL(_GLFWwindow* window)
{ {
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
// NOTE: Do not unload libGL.so.1 while the X11 display is still open, // NOTE: Do not unload libGL.so.1 while the X11 display is still open,
@ -296,6 +297,9 @@ GLFWbool _glfwInitEGL(void)
NULL NULL
}; };
if (_glfw.egl.handle)
return GLFW_TRUE;
for (i = 0; sonames[i]; i++) for (i = 0; sonames[i]; i++)
{ {
_glfw.egl.handle = _glfw_dlopen(sonames[i]); _glfw.egl.handle = _glfw_dlopen(sonames[i]);
@ -304,7 +308,12 @@ GLFWbool _glfwInitEGL(void)
} }
if (!_glfw.egl.handle) if (!_glfw.egl.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
return GLFW_FALSE; return GLFW_FALSE;
}
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
_glfw.egl.GetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC) _glfw.egl.GetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib"); _glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
@ -339,12 +348,36 @@ GLFWbool _glfwInitEGL(void)
_glfw.egl.GetProcAddress = (PFNEGLGETPROCADDRESSPROC) _glfw.egl.GetProcAddress = (PFNEGLGETPROCADDRESSPROC)
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress"); _glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
if (!_glfw.egl.GetConfigAttrib ||
!_glfw.egl.GetConfigs ||
!_glfw.egl.GetDisplay ||
!_glfw.egl.GetError ||
!_glfw.egl.Initialize ||
!_glfw.egl.Terminate ||
!_glfw.egl.BindAPI ||
!_glfw.egl.CreateContext ||
!_glfw.egl.DestroySurface ||
!_glfw.egl.DestroyContext ||
!_glfw.egl.CreateWindowSurface ||
!_glfw.egl.MakeCurrent ||
!_glfw.egl.SwapBuffers ||
!_glfw.egl.SwapInterval ||
!_glfw.egl.QueryString ||
!_glfw.egl.GetProcAddress)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to load required entry points");
_glfwTerminateEGL();
return GLFW_FALSE;
}
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY); _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
if (_glfw.egl.display == EGL_NO_DISPLAY) if (_glfw.egl.display == EGL_NO_DISPLAY)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to get EGL display: %s", "EGL: Failed to get EGL display: %s",
getErrorString(eglGetError())); getEGLErrorString(eglGetError()));
_glfwTerminateEGL(); _glfwTerminateEGL();
return GLFW_FALSE; return GLFW_FALSE;
@ -354,18 +387,18 @@ GLFWbool _glfwInitEGL(void)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to initialize EGL: %s", "EGL: Failed to initialize EGL: %s",
getErrorString(eglGetError())); getEGLErrorString(eglGetError()));
_glfwTerminateEGL(); _glfwTerminateEGL();
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfw.egl.KHR_create_context = _glfw.egl.KHR_create_context =
extensionSupported("EGL_KHR_create_context"); extensionSupportedEGL("EGL_KHR_create_context");
_glfw.egl.KHR_create_context_no_error = _glfw.egl.KHR_create_context_no_error =
extensionSupported("EGL_KHR_create_context_no_error"); extensionSupportedEGL("EGL_KHR_create_context_no_error");
_glfw.egl.KHR_gl_colorspace = _glfw.egl.KHR_gl_colorspace =
extensionSupported("EGL_KHR_gl_colorspace"); extensionSupportedEGL("EGL_KHR_gl_colorspace");
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -413,7 +446,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (ctxconfig->share) if (ctxconfig->share)
share = ctxconfig->share->context.egl.handle; share = ctxconfig->share->context.egl.handle;
if (!chooseFBConfigs(ctxconfig, fbconfig, &config)) if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
{ {
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig"); "EGL: Failed to find a suitable EGLConfig");
@ -426,7 +459,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL ES: %s", "EGL: Failed to bind OpenGL ES: %s",
getErrorString(eglGetError())); getEGLErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
} }
@ -436,7 +469,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL: %s", "EGL: Failed to bind OpenGL: %s",
getErrorString(eglGetError())); getEGLErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
} }
@ -515,7 +548,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{ {
_glfwInputError(GLFW_VERSION_UNAVAILABLE, _glfwInputError(GLFW_VERSION_UNAVAILABLE,
"EGL: Failed to create context: %s", "EGL: Failed to create context: %s",
getErrorString(eglGetError())); getEGLErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -543,7 +576,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to create window surface: %s", "EGL: Failed to create window surface: %s",
getErrorString(eglGetError())); getEGLErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -600,6 +633,11 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
for (i = 0; sonames[i]; i++) for (i = 0; sonames[i]; i++)
{ {
// HACK: Match presence of lib prefix to increase chance of finding
// a matching pair in the jungle that is Win32 EGL/GLES
if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0))
continue;
window->context.egl.client = _glfw_dlopen(sonames[i]); window->context.egl.client = _glfw_dlopen(sonames[i]);
if (window->context.egl.client) if (window->context.egl.client)
break; break;
@ -613,12 +651,12 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
} }
} }
window->context.makeContextCurrent = makeContextCurrent; window->context.makeCurrent = makeContextCurrentEGL;
window->context.swapBuffers = swapBuffers; window->context.swapBuffers = swapBuffersEGL;
window->context.swapInterval = swapInterval; window->context.swapInterval = swapIntervalEGL;
window->context.extensionSupported = extensionSupported; window->context.extensionSupported = extensionSupportedEGL;
window->context.getProcAddress = getProcAddress; window->context.getProcAddress = getProcAddressEGL;
window->context.destroyContext = destroyContext; window->context.destroy = destroyContextEGL;
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -638,7 +676,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
EGLint visualID = 0, count = 0; EGLint visualID = 0, count = 0;
const long vimask = VisualScreenMask | VisualIDMask; const long vimask = VisualScreenMask | VisualIDMask;
if (!chooseFBConfigs(ctxconfig, fbconfig, &native)) if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
{ {
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig"); "EGL: Failed to find a suitable EGLConfig");

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 EGL - www.glfw.org // GLFW 3.3 EGL - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -165,13 +165,13 @@ typedef struct _GLFWcontextEGL
} _GLFWcontextEGL; } _GLFWcontextEGL;
// EGL-specific global data // EGL-specific global data
// //
typedef struct _GLFWlibraryEGL typedef struct _GLFWlibraryEGL
{ {
EGLDisplay display; EGLDisplay display;
EGLint major, minor; EGLint major, minor;
GLFWbool prefix;
GLFWbool KHR_create_context; GLFWbool KHR_create_context;
GLFWbool KHR_create_context_no_error; GLFWbool KHR_create_context_no_error;

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.2 - www.glfw.org // GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2010-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -47,6 +47,8 @@
// Define this to 1 if building as a shared library / dynamic library / DLL // Define this to 1 if building as a shared library / dynamic library / DLL
#cmakedefine _GLFW_BUILD_DLL #cmakedefine _GLFW_BUILD_DLL
// Define this to 1 to use Vulkan loader linked statically into application
#cmakedefine _GLFW_VULKAN_STATIC
// Define this to 1 to force use of high-performance GPU on hybrid systems // Define this to 1 to force use of high-performance GPU on hybrid systems
#cmakedefine _GLFW_USE_HYBRID_HPG #cmakedefine _GLFW_USE_HYBRID_HPG

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 GLX - www.glfw.org // GLFW 3.3 GLX - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -38,16 +38,16 @@
// Returns the specified attribute of the specified GLXFBConfig // Returns the specified attribute of the specified GLXFBConfig
// //
static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib) static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
{ {
int value; int value;
glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value); glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);
return value; return value;
} }
// Return a list of available and usable framebuffer configs // Return the GLXFBConfig most closely matching the specified hints
// //
static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result) static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result)
{ {
GLXFBConfig* nativeConfigs; GLXFBConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs; _GLFWfbconfig* usableConfigs;
@ -79,41 +79,41 @@ static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result
_GLFWfbconfig* u = usableConfigs + usableCount; _GLFWfbconfig* u = usableConfigs + usableCount;
// Only consider RGBA GLXFBConfigs // Only consider RGBA GLXFBConfigs
if (!(getFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT)) if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT))
continue; continue;
// Only consider window GLXFBConfigs // Only consider window GLXFBConfigs
if (!(getFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT)) if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))
{ {
if (trustWindowBit) if (trustWindowBit)
continue; continue;
} }
u->redBits = getFBConfigAttrib(n, GLX_RED_SIZE); u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
u->greenBits = getFBConfigAttrib(n, GLX_GREEN_SIZE); u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
u->blueBits = getFBConfigAttrib(n, GLX_BLUE_SIZE); u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
u->alphaBits = getFBConfigAttrib(n, GLX_ALPHA_SIZE); u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE);
u->depthBits = getFBConfigAttrib(n, GLX_DEPTH_SIZE); u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE);
u->stencilBits = getFBConfigAttrib(n, GLX_STENCIL_SIZE); u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE);
u->accumRedBits = getFBConfigAttrib(n, GLX_ACCUM_RED_SIZE); u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE);
u->accumGreenBits = getFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE); u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE);
u->accumBlueBits = getFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE); u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE);
u->accumAlphaBits = getFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE); u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE);
u->auxBuffers = getFBConfigAttrib(n, GLX_AUX_BUFFERS); u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
if (getFBConfigAttrib(n, GLX_STEREO)) if (getGLXFBConfigAttrib(n, GLX_STEREO))
u->stereo = GLFW_TRUE; u->stereo = GLFW_TRUE;
if (getFBConfigAttrib(n, GLX_DOUBLEBUFFER)) if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER))
u->doublebuffer = GLFW_TRUE; u->doublebuffer = GLFW_TRUE;
if (_glfw.glx.ARB_multisample) if (_glfw.glx.ARB_multisample)
u->samples = getFBConfigAttrib(n, GLX_SAMPLES); u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB) if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB)
u->sRGB = getFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB);
u->handle = (uintptr_t) n; u->handle = (uintptr_t) n;
usableCount++; usableCount++;
@ -131,7 +131,7 @@ static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result
// Create the OpenGL context using legacy API // Create the OpenGL context using legacy API
// //
static GLXContext createLegacyContext(_GLFWwindow* window, static GLXContext createLegacyContextGLX(_GLFWwindow* window,
GLXFBConfig fbconfig, GLXFBConfig fbconfig,
GLXContext share) GLXContext share)
{ {
@ -142,7 +142,7 @@ static GLXContext createLegacyContext(_GLFWwindow* window,
True); True);
} }
static void makeContextCurrent(_GLFWwindow* window) static void makeContextCurrentGLX(_GLFWwindow* window)
{ {
if (window) if (window)
{ {
@ -168,12 +168,12 @@ static void makeContextCurrent(_GLFWwindow* window)
_glfwPlatformSetCurrentContext(window); _glfwPlatformSetCurrentContext(window);
} }
static void swapBuffers(_GLFWwindow* window) static void swapBuffersGLX(_GLFWwindow* window)
{ {
glXSwapBuffers(_glfw.x11.display, window->context.glx.window); glXSwapBuffers(_glfw.x11.display, window->context.glx.window);
} }
static void swapInterval(int interval) static void swapIntervalGLX(int interval)
{ {
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); _GLFWwindow* window = _glfwPlatformGetCurrentContext();
@ -192,7 +192,7 @@ static void swapInterval(int interval)
} }
} }
static int extensionSupported(const char* extension) static int extensionSupportedGLX(const char* extension)
{ {
const char* extensions = const char* extensions =
glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen); glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
@ -205,7 +205,7 @@ static int extensionSupported(const char* extension)
return GLFW_FALSE; return GLFW_FALSE;
} }
static GLFWglproc getProcAddress(const char* procname) static GLFWglproc getProcAddressGLX(const char* procname)
{ {
if (_glfw.glx.GetProcAddress) if (_glfw.glx.GetProcAddress)
return _glfw.glx.GetProcAddress((const GLubyte*) procname); return _glfw.glx.GetProcAddress((const GLubyte*) procname);
@ -217,7 +217,7 @@ static GLFWglproc getProcAddress(const char* procname)
// Destroy the OpenGL context // Destroy the OpenGL context
// //
static void destroyContext(_GLFWwindow* window) static void destroyContextGLX(_GLFWwindow* window)
{ {
if (window->context.glx.window) if (window->context.glx.window)
{ {
@ -253,6 +253,9 @@ GLFWbool _glfwInitGLX(void)
NULL NULL
}; };
if (_glfw.glx.handle)
return GLFW_TRUE;
for (i = 0; sonames[i]; i++) for (i = 0; sonames[i]; i++)
{ {
_glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL); _glfw.glx.handle = dlopen(sonames[i], RTLD_LAZY | RTLD_GLOBAL);
@ -297,6 +300,27 @@ GLFWbool _glfwInitGLX(void)
_glfw.glx.GetVisualFromFBConfig = _glfw.glx.GetVisualFromFBConfig =
dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig"); dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
if (!_glfw.glx.GetFBConfigs ||
!_glfw.glx.GetFBConfigAttrib ||
!_glfw.glx.GetClientString ||
!_glfw.glx.QueryExtension ||
!_glfw.glx.QueryVersion ||
!_glfw.glx.DestroyContext ||
!_glfw.glx.MakeCurrent ||
!_glfw.glx.SwapBuffers ||
!_glfw.glx.QueryExtensionsString ||
!_glfw.glx.CreateNewContext ||
!_glfw.glx.CreateWindow ||
!_glfw.glx.DestroyWindow ||
!_glfw.glx.GetProcAddress ||
!_glfw.glx.GetProcAddressARB ||
!_glfw.glx.GetVisualFromFBConfig)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to load required entry points");
return GLFW_FALSE;
}
if (!glXQueryExtension(_glfw.x11.display, if (!glXQueryExtension(_glfw.x11.display,
&_glfw.glx.errorBase, &_glfw.glx.errorBase,
&_glfw.glx.eventBase)) &_glfw.glx.eventBase))
@ -319,61 +343,61 @@ GLFWbool _glfwInitGLX(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
if (extensionSupported("GLX_EXT_swap_control")) if (extensionSupportedGLX("GLX_EXT_swap_control"))
{ {
_glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) _glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
getProcAddress("glXSwapIntervalEXT"); getProcAddressGLX("glXSwapIntervalEXT");
if (_glfw.glx.SwapIntervalEXT) if (_glfw.glx.SwapIntervalEXT)
_glfw.glx.EXT_swap_control = GLFW_TRUE; _glfw.glx.EXT_swap_control = GLFW_TRUE;
} }
if (extensionSupported("GLX_SGI_swap_control")) if (extensionSupportedGLX("GLX_SGI_swap_control"))
{ {
_glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) _glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
getProcAddress("glXSwapIntervalSGI"); getProcAddressGLX("glXSwapIntervalSGI");
if (_glfw.glx.SwapIntervalSGI) if (_glfw.glx.SwapIntervalSGI)
_glfw.glx.SGI_swap_control = GLFW_TRUE; _glfw.glx.SGI_swap_control = GLFW_TRUE;
} }
if (extensionSupported("GLX_MESA_swap_control")) if (extensionSupportedGLX("GLX_MESA_swap_control"))
{ {
_glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) _glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)
getProcAddress("glXSwapIntervalMESA"); getProcAddressGLX("glXSwapIntervalMESA");
if (_glfw.glx.SwapIntervalMESA) if (_glfw.glx.SwapIntervalMESA)
_glfw.glx.MESA_swap_control = GLFW_TRUE; _glfw.glx.MESA_swap_control = GLFW_TRUE;
} }
if (extensionSupported("GLX_ARB_multisample")) if (extensionSupportedGLX("GLX_ARB_multisample"))
_glfw.glx.ARB_multisample = GLFW_TRUE; _glfw.glx.ARB_multisample = GLFW_TRUE;
if (extensionSupported("GLX_ARB_framebuffer_sRGB")) if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE; _glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
if (extensionSupported("GLX_EXT_framebuffer_sRGB")) if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE; _glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
if (extensionSupported("GLX_ARB_create_context")) if (extensionSupportedGLX("GLX_ARB_create_context"))
{ {
_glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) _glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
getProcAddress("glXCreateContextAttribsARB"); getProcAddressGLX("glXCreateContextAttribsARB");
if (_glfw.glx.CreateContextAttribsARB) if (_glfw.glx.CreateContextAttribsARB)
_glfw.glx.ARB_create_context = GLFW_TRUE; _glfw.glx.ARB_create_context = GLFW_TRUE;
} }
if (extensionSupported("GLX_ARB_create_context_robustness")) if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE; _glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
if (extensionSupported("GLX_ARB_create_context_profile")) if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
_glfw.glx.ARB_create_context_profile = GLFW_TRUE; _glfw.glx.ARB_create_context_profile = GLFW_TRUE;
if (extensionSupported("GLX_EXT_create_context_es2_profile")) if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE; _glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
if (extensionSupported("GLX_ARB_context_flush_control")) if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
_glfw.glx.ARB_context_flush_control = GLFW_TRUE; _glfw.glx.ARB_context_flush_control = GLFW_TRUE;
return GLFW_TRUE; return GLFW_TRUE;
@ -413,7 +437,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
if (ctxconfig->share) if (ctxconfig->share)
share = ctxconfig->share->context.glx.handle; share = ctxconfig->share->context.glx.handle;
if (!chooseFBConfig(fbconfig, &native)) if (!chooseGLXFBConfig(fbconfig, &native))
{ {
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig"); "GLX: Failed to find a suitable GLXFBConfig");
@ -549,12 +573,15 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
ctxconfig->forward == GLFW_FALSE) ctxconfig->forward == GLFW_FALSE)
{ {
window->context.glx.handle = window->context.glx.handle =
createLegacyContext(window, native, share); createLegacyContextGLX(window, native, share);
} }
} }
} }
else else
window->context.glx.handle = createLegacyContext(window, native, share); {
window->context.glx.handle =
createLegacyContextGLX(window, native, share);
}
_glfwReleaseErrorHandlerX11(); _glfwReleaseErrorHandlerX11();
@ -572,12 +599,12 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
return GLFW_FALSE; return GLFW_FALSE;
} }
window->context.makeContextCurrent = makeContextCurrent; window->context.makeCurrent = makeContextCurrentGLX;
window->context.swapBuffers = swapBuffers; window->context.swapBuffers = swapBuffersGLX;
window->context.swapInterval = swapInterval; window->context.swapInterval = swapIntervalGLX;
window->context.extensionSupported = extensionSupported; window->context.extensionSupported = extensionSupportedGLX;
window->context.getProcAddress = getProcAddress; window->context.getProcAddress = getProcAddressGLX;
window->context.destroyContext = destroyContext; window->context.destroy = destroyContextGLX;
return GLFW_TRUE; return GLFW_TRUE;
} }
@ -593,7 +620,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
GLXFBConfig native; GLXFBConfig native;
XVisualInfo* result; XVisualInfo* result;
if (!chooseFBConfig(fbconfig, &native)) if (!chooseGLXFBConfig(fbconfig, &native))
{ {
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig"); "GLX: Failed to find a suitable GLXFBConfig");

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 GLX - www.glfw.org // GLFW 3.3 GLX - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -121,7 +121,6 @@ typedef struct _GLFWcontextGLX
} _GLFWcontextGLX; } _GLFWcontextGLX;
// GLX-specific global data // GLX-specific global data
// //
typedef struct _GLFWlibraryGLX typedef struct _GLFWlibraryGLX

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 - www.glfw.org // GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -65,9 +65,9 @@ static const char* getErrorString(int error)
case GLFW_OUT_OF_MEMORY: case GLFW_OUT_OF_MEMORY:
return "Out of memory"; return "Out of memory";
case GLFW_API_UNAVAILABLE: case GLFW_API_UNAVAILABLE:
return "The requested client API is unavailable"; return "The requested API is unavailable";
case GLFW_VERSION_UNAVAILABLE: case GLFW_VERSION_UNAVAILABLE:
return "The requested client API version is unavailable"; return "The requested API version is unavailable";
case GLFW_PLATFORM_ERROR: case GLFW_PLATFORM_ERROR:
return "A platform-specific error occurred"; return "A platform-specific error occurred";
case GLFW_FORMAT_UNAVAILABLE: case GLFW_FORMAT_UNAVAILABLE:
@ -130,8 +130,6 @@ GLFWAPI int glfwInit(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfwInitVulkan();
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount); _glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
_glfwInitialized = GLFW_TRUE; _glfwInitialized = GLFW_TRUE;

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 - www.glfw.org // GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -28,103 +28,13 @@
#include "internal.h" #include "internal.h"
#include <assert.h> #include <assert.h>
#include <float.h>
#include <stdlib.h> #include <stdlib.h>
// Internal key state used for sticky keys // Internal key state used for sticky keys
#define _GLFW_STICK 3 #define _GLFW_STICK 3
// Sets the cursor mode for the specified window
//
static void setCursorMode(_GLFWwindow* window, int newMode)
{
const int oldMode = window->cursorMode;
if (newMode != GLFW_CURSOR_NORMAL &&
newMode != GLFW_CURSOR_HIDDEN &&
newMode != GLFW_CURSOR_DISABLED)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid cursor mode %i", newMode);
return;
}
if (oldMode == newMode)
return;
window->cursorMode = newMode;
if (_glfw.cursorWindow == window)
{
if (oldMode == GLFW_CURSOR_DISABLED)
{
_glfwPlatformSetCursorPos(window,
_glfw.cursorPosX,
_glfw.cursorPosY);
}
else if (newMode == GLFW_CURSOR_DISABLED)
{
int width, height;
_glfwPlatformGetCursorPos(window,
&_glfw.cursorPosX,
&_glfw.cursorPosY);
window->cursorPosX = _glfw.cursorPosX;
window->cursorPosY = _glfw.cursorPosY;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
}
_glfwPlatformSetCursorMode(window, window->cursorMode);
}
}
// Set sticky keys mode for the specified window
//
static void setStickyKeys(_GLFWwindow* window, int enabled)
{
if (window->stickyKeys == enabled)
return;
if (!enabled)
{
int i;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
{
if (window->keys[i] == _GLFW_STICK)
window->keys[i] = GLFW_RELEASE;
}
}
window->stickyKeys = enabled;
}
// Set sticky mouse buttons mode for the specified window
//
static void setStickyMouseButtons(_GLFWwindow* window, int enabled)
{
if (window->stickyMouseButtons == enabled)
return;
if (!enabled)
{
int i;
// Release all sticky mouse buttons
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{
if (window->mouseButtons[i] == _GLFW_STICK)
window->mouseButtons[i] = GLFW_RELEASE;
}
}
window->stickyMouseButtons = enabled;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW event API ////// ////// GLFW event API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -190,22 +100,16 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods); window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
} }
void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y) void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
{ {
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)
{
if (x == 0.0 && y == 0.0)
return; return;
window->cursorPosX += x; window->virtualCursorPosX = xpos;
window->cursorPosY += y; window->virtualCursorPosY = ypos;
x = window->cursorPosX;
y = window->cursorPosY;
}
if (window->callbacks.cursorPos) if (window->callbacks.cursorPos)
window->callbacks.cursorPos((GLFWwindow*) window, x, y); window->callbacks.cursorPos((GLFWwindow*) window, xpos, ypos);
} }
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered) void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
@ -274,18 +178,76 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
switch (mode) switch (mode)
{ {
case GLFW_CURSOR: case GLFW_CURSOR:
setCursorMode(window, value); {
break; if (value != GLFW_CURSOR_NORMAL &&
case GLFW_STICKY_KEYS: value != GLFW_CURSOR_HIDDEN &&
setStickyKeys(window, value ? GLFW_TRUE : GLFW_FALSE); value != GLFW_CURSOR_DISABLED)
break; {
case GLFW_STICKY_MOUSE_BUTTONS: _glfwInputError(GLFW_INVALID_ENUM,
setStickyMouseButtons(window, value ? GLFW_TRUE : GLFW_FALSE); "Invalid cursor mode %i",
break; value);
default: return;
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode %i", mode);
break;
} }
if (window->cursorMode == value)
return;
window->cursorMode = value;
_glfwPlatformGetCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
if (_glfwPlatformWindowFocused(window))
_glfwPlatformSetCursorMode(window, value);
return;
}
case GLFW_STICKY_KEYS:
{
if (window->stickyKeys == value)
return;
if (!value)
{
int i;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
{
if (window->keys[i] == _GLFW_STICK)
window->keys[i] = GLFW_RELEASE;
}
}
window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
return;
}
case GLFW_STICKY_MOUSE_BUTTONS:
{
if (window->stickyMouseButtons == value)
return;
if (!value)
{
int i;
// Release all sticky mouse buttons
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{
if (window->mouseButtons[i] == _GLFW_STICK)
window->mouseButtons[i] = GLFW_RELEASE;
}
}
window->stickyMouseButtons = value ? GLFW_TRUE : GLFW_FALSE;
return;
}
}
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode %i", mode);
} }
GLFWAPI const char* glfwGetKeyName(int key, int scancode) GLFWAPI const char* glfwGetKeyName(int key, int scancode)
@ -301,7 +263,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
if (key < 0 || key > GLFW_KEY_LAST) if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
{ {
_glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key); _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
return GLFW_RELEASE; return GLFW_RELEASE;
@ -324,7 +286,7 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) if (button < GLFW_MOUSE_BUTTON_1 || button > GLFW_MOUSE_BUTTON_LAST)
{ {
_glfwInputError(GLFW_INVALID_ENUM, "Invalid mouse button %i", button); _glfwInputError(GLFW_INVALID_ENUM, "Invalid mouse button %i", button);
return GLFW_RELEASE; return GLFW_RELEASE;
@ -355,9 +317,9 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
{ {
if (xpos) if (xpos)
*xpos = window->cursorPosX; *xpos = window->virtualCursorPosX;
if (ypos) if (ypos)
*ypos = window->cursorPosY; *ypos = window->virtualCursorPosY;
} }
else else
_glfwPlatformGetCursorPos(window, xpos, ypos); _glfwPlatformGetCursorPos(window, xpos, ypos);
@ -370,14 +332,23 @@ GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (_glfw.cursorWindow != window) if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX ||
ypos != ypos || ypos < -DBL_MAX || ypos > DBL_MAX)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid cursor position %f %f",
xpos, ypos);
return;
}
if (!_glfwPlatformWindowFocused(window))
return; return;
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
{ {
// Only update the accumulated position if the cursor is disabled // Only update the accumulated position if the cursor is disabled
window->cursorPosX = xpos; window->virtualCursorPosX = xpos;
window->cursorPosY = ypos; window->virtualCursorPosY = ypos;
} }
else else
{ {
@ -480,9 +451,9 @@ GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPlatformSetCursor(window, cursor);
window->cursor = cursor; window->cursor = cursor;
_glfwPlatformSetCursor(window, cursor);
} }
GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun) GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
@ -638,7 +609,6 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
assert(string != NULL); assert(string != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 - www.glfw.org // GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -40,6 +40,7 @@
defined(GLFW_INCLUDE_NONE) || \ defined(GLFW_INCLUDE_NONE) || \
defined(GLFW_INCLUDE_GLEXT) || \ defined(GLFW_INCLUDE_GLEXT) || \
defined(GLFW_INCLUDE_GLU) || \ defined(GLFW_INCLUDE_GLU) || \
defined(GLFW_INCLUDE_VULKAN) || \
defined(GLFW_DLL) defined(GLFW_DLL)
#error "You must not define any header option macros when compiling GLFW" #error "You must not define any header option macros when compiling GLFW"
#endif #endif
@ -149,11 +150,16 @@ typedef struct VkExtensionProperties
} VkExtensionProperties; } VkExtensionProperties;
typedef void (APIENTRY * PFN_vkVoidFunction)(void); typedef void (APIENTRY * PFN_vkVoidFunction)(void);
#if defined(_GLFW_VULKAN_STATIC)
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance,const char*);
VkResult vkEnumerateInstanceExtensionProperties(const char*,uint32_t*,VkExtensionProperties*);
#else
typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*); typedef PFN_vkVoidFunction (APIENTRY * PFN_vkGetInstanceProcAddr)(VkInstance,const char*);
typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*); typedef VkResult (APIENTRY * PFN_vkEnumerateInstanceExtensionProperties)(const char*,uint32_t*,VkExtensionProperties*);
#define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties #define vkEnumerateInstanceExtensionProperties _glfw.vk.EnumerateInstanceExtensionProperties
#define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr #define vkGetInstanceProcAddr _glfw.vk.GetInstanceProcAddr
#endif
#if defined(_GLFW_COCOA) #if defined(_GLFW_COCOA)
#include "cocoa_platform.h" #include "cocoa_platform.h"
@ -256,7 +262,6 @@ struct _GLFWwndconfig
GLFWbool maximized; GLFWbool maximized;
}; };
/*! @brief Context configuration. /*! @brief Context configuration.
* *
* Parameters relating to the creation of the context but not directly related * Parameters relating to the creation of the context but not directly related
@ -278,7 +283,6 @@ struct _GLFWctxconfig
_GLFWwindow* share; _GLFWwindow* share;
}; };
/*! @brief Framebuffer configuration. /*! @brief Framebuffer configuration.
* *
* This describes buffers and their sizes. It also contains * This describes buffers and their sizes. It also contains
@ -307,7 +311,6 @@ struct _GLFWfbconfig
uintptr_t handle; uintptr_t handle;
}; };
/*! @brief Context structure. /*! @brief Context structure.
*/ */
struct _GLFWcontext struct _GLFWcontext
@ -324,12 +327,12 @@ struct _GLFWcontext
PFNGLGETINTEGERVPROC GetIntegerv; PFNGLGETINTEGERVPROC GetIntegerv;
PFNGLGETSTRINGPROC GetString; PFNGLGETSTRINGPROC GetString;
_GLFWmakecontextcurrentfun makeContextCurrent; _GLFWmakecontextcurrentfun makeCurrent;
_GLFWswapbuffersfun swapBuffers; _GLFWswapbuffersfun swapBuffers;
_GLFWswapintervalfun swapInterval; _GLFWswapintervalfun swapInterval;
_GLFWextensionsupportedfun extensionSupported; _GLFWextensionsupportedfun extensionSupported;
_GLFWgetprocaddressfun getProcAddress; _GLFWgetprocaddressfun getProcAddress;
_GLFWdestroycontextfun destroyContext; _GLFWdestroycontextfun destroy;
// This is defined in the context API's context.h // This is defined in the context API's context.h
_GLFW_PLATFORM_CONTEXT_STATE; _GLFW_PLATFORM_CONTEXT_STATE;
@ -337,7 +340,6 @@ struct _GLFWcontext
_GLFW_EGL_CONTEXT_STATE; _GLFW_EGL_CONTEXT_STATE;
}; };
/*! @brief Window and context structure. /*! @brief Window and context structure.
*/ */
struct _GLFWwindow struct _GLFWwindow
@ -360,13 +362,13 @@ struct _GLFWwindow
int maxwidth, maxheight; int maxwidth, maxheight;
int numer, denom; int numer, denom;
// Window input state
GLFWbool stickyKeys; GLFWbool stickyKeys;
GLFWbool stickyMouseButtons; GLFWbool stickyMouseButtons;
double cursorPosX, cursorPosY;
int cursorMode; int cursorMode;
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1]; char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
char keys[GLFW_KEY_LAST + 1]; char keys[GLFW_KEY_LAST + 1];
// Virtual cursor position when cursor is disabled
double virtualCursorPosX, virtualCursorPosY;
_GLFWcontext context; _GLFWcontext context;
@ -392,7 +394,6 @@ struct _GLFWwindow
_GLFW_PLATFORM_WINDOW_STATE; _GLFW_PLATFORM_WINDOW_STATE;
}; };
/*! @brief Monitor structure. /*! @brief Monitor structure.
*/ */
struct _GLFWmonitor struct _GLFWmonitor
@ -416,7 +417,6 @@ struct _GLFWmonitor
_GLFW_PLATFORM_MONITOR_STATE; _GLFW_PLATFORM_MONITOR_STATE;
}; };
/*! @brief Cursor structure /*! @brief Cursor structure
*/ */
struct _GLFWcursor struct _GLFWcursor
@ -438,12 +438,9 @@ struct _GLFWlibrary
int refreshRate; int refreshRate;
} hints; } hints;
double cursorPosX, cursorPosY;
_GLFWcursor* cursorListHead; _GLFWcursor* cursorListHead;
_GLFWwindow* windowListHead; _GLFWwindow* windowListHead;
_GLFWwindow* cursorWindow;
_GLFWmonitor** monitors; _GLFWmonitor** monitors;
int monitorCount; int monitorCount;
@ -455,8 +452,10 @@ struct _GLFWlibrary
void* handle; void* handle;
char** extensions; char** extensions;
uint32_t extensionCount; uint32_t extensionCount;
#if !defined(_GLFW_VULKAN_STATIC)
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties; PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr; PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
#endif
GLFWbool KHR_surface; GLFWbool KHR_surface;
GLFWbool KHR_win32_surface; GLFWbool KHR_win32_surface;
GLFWbool KHR_xlib_surface; GLFWbool KHR_xlib_surface;
@ -884,11 +883,11 @@ void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWb
/*! @brief Notifies shared code of a scroll event. /*! @brief Notifies shared code of a scroll event.
* @param[in] window The window that received the event. * @param[in] window The window that received the event.
* @param[in] x The scroll offset along the x-axis. * @param[in] xoffset The scroll offset along the x-axis.
* @param[in] y The scroll offset along the y-axis. * @param[in] yoffset The scroll offset along the y-axis.
* @ingroup event * @ingroup event
*/ */
void _glfwInputScroll(_GLFWwindow* window, double x, double y); void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
/*! @brief Notifies shared code of a mouse button click event. /*! @brief Notifies shared code of a mouse button click event.
* @param[in] window The window that received the event. * @param[in] window The window that received the event.
@ -900,13 +899,13 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
/*! @brief Notifies shared code of a cursor motion event. /*! @brief Notifies shared code of a cursor motion event.
* @param[in] window The window that received the event. * @param[in] window The window that received the event.
* @param[in] x The new x-coordinate of the cursor, relative to the left edge * @param[in] xpos The new x-coordinate of the cursor, relative to the left
* of the client area of the window. * edge of the client area of the window.
* @param[in] y The new y-coordinate of the cursor, relative to the top edge * @param[in] ypos The new y-coordinate of the cursor, relative to the top edge
* of the client area of the window. * of the client area of the window.
* @ingroup event * @ingroup event
*/ */
void _glfwInputCursorMotion(_GLFWwindow* window, double x, double y); void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
/*! @brief Notifies shared code of a cursor enter/leave event. /*! @brief Notifies shared code of a cursor enter/leave event.
* @param[in] window The window that received the event. * @param[in] window The window that received the event.
@ -1044,7 +1043,7 @@ GLFWbool _glfwIsPrintable(int key);
/*! @ingroup utility /*! @ingroup utility
*/ */
void _glfwInitVulkan(void); GLFWbool _glfwInitVulkan(void);
/*! @ingroup utility /*! @ingroup utility
*/ */

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 Linux - www.glfw.org // GLFW 3.3 Linux - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -49,7 +49,7 @@
static GLFWbool openJoystickDevice(const char* path) static GLFWbool openJoystickDevice(const char* path)
{ {
char axisCount, buttonCount; char axisCount, buttonCount;
char name[256]; char name[256] = "";
int joy, fd, version; int joy, fd, version;
_GLFWjoystickLinux* js; _GLFWjoystickLinux* js;
@ -153,7 +153,7 @@ static GLFWbool pollJoystickEvents(_GLFWjoystickLinux* js)
return js->present; return js->present;
} }
// Lexically compare joysticks, used by quicksort // Lexically compare joysticks by name; used by qsort
// //
#if defined(__linux__) #if defined(__linux__)
static int compareJoysticks(const void* fp, const void* sp) static int compareJoysticks(const void* fp, const void* sp)

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 Linux - www.glfw.org // GLFW 3.3 Linux - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
// //
@ -46,7 +46,6 @@ typedef struct _GLFWjoystickLinux
char* path; char* path;
} _GLFWjoystickLinux; } _GLFWjoystickLinux;
// Linux-specific joystick API data // Linux-specific joystick API data
// //
typedef struct _GLFWjoylistLinux typedef struct _GLFWjoylistLinux

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 Mir - www.glfw.org // GLFW 3.3 Mir - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com> // Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com>
// //
@ -183,9 +183,6 @@ int _glfwPlatformInit(void)
if (!_glfwInitThreadLocalStoragePOSIX()) if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwInitJoysticksLinux()) if (!_glfwInitJoysticksLinux())
return GLFW_FALSE; return GLFW_FALSE;

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 Mir - www.glfw.org // GLFW 3.3 Mir - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com> // Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com>
// //

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 Mir - www.glfw.org // GLFW 3.3 Mir - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com> // Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com>
// //
@ -87,7 +87,6 @@ typedef struct _GLFWwindowMir
} _GLFWwindowMir; } _GLFWwindowMir;
// Mir-specific per-monitor data // Mir-specific per-monitor data
// //
typedef struct _GLFWmonitorMir typedef struct _GLFWmonitorMir
@ -99,7 +98,6 @@ typedef struct _GLFWmonitorMir
} _GLFWmonitorMir; } _GLFWmonitorMir;
// Mir-specific global data // Mir-specific global data
// //
typedef struct _GLFWlibraryMir typedef struct _GLFWlibraryMir
@ -116,7 +114,6 @@ typedef struct _GLFWlibraryMir
} _GLFWlibraryMir; } _GLFWlibraryMir;
// Mir-specific per-cursor data // Mir-specific per-cursor data
// TODO: Only system cursors are implemented in Mir atm. Need to wait for support. // TODO: Only system cursors are implemented in Mir atm. Need to wait for support.
// //

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 Mir - www.glfw.org // GLFW 3.3 Mir - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com> // Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com>
// //
@ -201,15 +201,14 @@ static void handlePointerButton(_GLFWwindow* window,
static void handlePointerMotion(_GLFWwindow* window, static void handlePointerMotion(_GLFWwindow* window,
const MirPointerEvent* pointer_event) const MirPointerEvent* pointer_event)
{ {
int current_x = window->cursorPosX; int current_x = window->virtualCursorPosX;
int current_y = window->cursorPosY; int current_y = window->virtualCursorPosY;
int x = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_x); int x = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_x);
int y = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_y); int y = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_y);
int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll); int dx = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll);
int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll); int dy = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll);
if (current_x != x || current_y != y) _glfwInputCursorPos(window, x, y);
_glfwInputCursorMotion(window, x, y);
if (dx != 0 || dy != 0) if (dx != 0 || dy != 0)
_glfwInputScroll(window, dx, dy); _glfwInputScroll(window, dx, dy);
} }
@ -380,6 +379,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (ctxconfig->client != GLFW_NO_API) if (ctxconfig->client != GLFW_NO_API)
{ {
if (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -395,8 +396,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
window->mir.surface = NULL; window->mir.surface = NULL;
} }
if (window->context.client != GLFW_NO_API) if (window->context.destroy)
window->context.destroyContext(window); window->context.destroy(window);
} }
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 - www.glfw.org // GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -375,8 +375,8 @@ GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL); assert(monitor != NULL);
assert(count != NULL); assert(count != NULL);
*count = 0; *count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@ -454,8 +454,18 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
{ {
_GLFWmonitor* monitor = (_GLFWmonitor*) handle; _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL); assert(monitor != NULL);
assert(ramp != NULL); assert(ramp != NULL);
assert(ramp->red != NULL);
assert(ramp->green != NULL);
assert(ramp->blue != NULL);
if (ramp->size <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid gamma ramp size %i",
ramp->size);
return;
}
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.2 OS X - www.glfw.org // GLFW 3.3 OS X - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -40,7 +40,6 @@ typedef struct _GLFWcontextNSGL
} _GLFWcontextNSGL; } _GLFWcontextNSGL;
// NSGL-specific global data // NSGL-specific global data
// //
typedef struct _GLFWlibraryNSGL typedef struct _GLFWlibraryNSGL

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.2 OS X - www.glfw.org // GLFW 3.3 OS X - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2009-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -27,7 +27,7 @@
#include "internal.h" #include "internal.h"
static void makeContextCurrent(_GLFWwindow* window) static void makeContextCurrentNSGL(_GLFWwindow* window)
{ {
if (window) if (window)
[window->context.nsgl.object makeCurrentContext]; [window->context.nsgl.object makeCurrentContext];
@ -37,13 +37,13 @@ static void makeContextCurrent(_GLFWwindow* window)
_glfwPlatformSetCurrentContext(window); _glfwPlatformSetCurrentContext(window);
} }
static void swapBuffers(_GLFWwindow* window) static void swapBuffersNSGL(_GLFWwindow* window)
{ {
// ARP appears to be unnecessary, but this is future-proof // ARP appears to be unnecessary, but this is future-proof
[window->context.nsgl.object flushBuffer]; [window->context.nsgl.object flushBuffer];
} }
static void swapInterval(int interval) static void swapIntervalNSGL(int interval)
{ {
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); _GLFWwindow* window = _glfwPlatformGetCurrentContext();
@ -52,13 +52,13 @@ static void swapInterval(int interval)
forParameter:NSOpenGLCPSwapInterval]; forParameter:NSOpenGLCPSwapInterval];
} }
static int extensionSupported(const char* extension) static int extensionSupportedNSGL(const char* extension)
{ {
// There are no NSGL extensions // There are no NSGL extensions
return GLFW_FALSE; return GLFW_FALSE;
} }
static GLFWglproc getProcAddress(const char* procname) static GLFWglproc getProcAddressNSGL(const char* procname)
{ {
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault, CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,
procname, procname,
@ -74,7 +74,7 @@ static GLFWglproc getProcAddress(const char* procname)
// Destroy the OpenGL context // Destroy the OpenGL context
// //
static void destroyContext(_GLFWwindow* window) static void destroyContextNSGL(_GLFWwindow* window)
{ {
[window->context.nsgl.pixelFormat release]; [window->context.nsgl.pixelFormat release];
window->context.nsgl.pixelFormat = nil; window->context.nsgl.pixelFormat = nil;
@ -92,6 +92,9 @@ static void destroyContext(_GLFWwindow* window)
// //
GLFWbool _glfwInitNSGL(void) GLFWbool _glfwInitNSGL(void)
{ {
if (_glfw.nsgl.framework)
return GLFW_TRUE;
_glfw.nsgl.framework = _glfw.nsgl.framework =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (_glfw.nsgl.framework == NULL) if (_glfw.nsgl.framework == NULL)
@ -280,12 +283,12 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
[window->context.nsgl.object setView:window->ns.view]; [window->context.nsgl.object setView:window->ns.view];
window->context.makeContextCurrent = makeContextCurrent; window->context.makeCurrent = makeContextCurrentNSGL;
window->context.swapBuffers = swapBuffers; window->context.swapBuffers = swapBuffersNSGL;
window->context.swapInterval = swapInterval; window->context.swapInterval = swapIntervalNSGL;
window->context.extensionSupported = extensionSupported; window->context.extensionSupported = extensionSupportedNSGL;
window->context.getProcAddress = getProcAddress; window->context.getProcAddress = getProcAddressNSGL;
window->context.destroyContext = destroyContext; window->context.destroy = destroyContextNSGL;
return GLFW_TRUE; return GLFW_TRUE;
} }

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 POSIX - www.glfw.org // GLFW 3.3 POSIX - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 POSIX - www.glfw.org // GLFW 3.3 POSIX - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 POSIX - www.glfw.org // GLFW 3.3 POSIX - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 POSIX - www.glfw.org // GLFW 3.3 POSIX - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 - www.glfw.org // GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -36,20 +36,25 @@
////// GLFW internal API ////// ////// GLFW internal API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
void _glfwInitVulkan(void) GLFWbool _glfwInitVulkan(void)
{ {
VkResult err; VkResult err;
VkExtensionProperties* ep; VkExtensionProperties* ep;
uint32_t i, count; uint32_t i, count;
#if !defined(_GLFW_VULKAN_STATIC)
#if defined(_GLFW_WIN32) #if defined(_GLFW_WIN32)
const char* name = "vulkan-1.dll"; const char* name = "vulkan-1.dll";
#else #else
const char* name = "libvulkan.so.1"; const char* name = "libvulkan.so.1";
#endif #endif
if (_glfw.vk.available)
return GLFW_TRUE;
_glfw.vk.handle = _glfw_dlopen(name); _glfw.vk.handle = _glfw_dlopen(name);
if (!_glfw.vk.handle) if (!_glfw.vk.handle)
return; return GLFW_FALSE;
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) _glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr"); _glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
@ -57,7 +62,9 @@ void _glfwInitVulkan(void)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Loader does not export vkGetInstanceProcAddr"); "Vulkan: Loader does not export vkGetInstanceProcAddr");
return;
_glfwTerminateVulkan();
return GLFW_FALSE;
} }
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties) _glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
@ -66,8 +73,11 @@ void _glfwInitVulkan(void)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, _glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties"); "Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
return;
_glfwTerminateVulkan();
return GLFW_FALSE;
} }
#endif // _GLFW_VULKAN_STATIC
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
if (err) if (err)
@ -75,7 +85,9 @@ void _glfwInitVulkan(void)
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"Vulkan: Failed to query instance extension count: %s", "Vulkan: Failed to query instance extension count: %s",
_glfwGetVulkanResultString(err)); _glfwGetVulkanResultString(err));
return;
_glfwTerminateVulkan();
return GLFW_FALSE;
} }
ep = calloc(count, sizeof(VkExtensionProperties)); ep = calloc(count, sizeof(VkExtensionProperties));
@ -88,7 +100,8 @@ void _glfwInitVulkan(void)
_glfwGetVulkanResultString(err)); _glfwGetVulkanResultString(err));
free(ep); free(ep);
return; _glfwTerminateVulkan();
return GLFW_FALSE;
} }
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
@ -111,13 +124,15 @@ void _glfwInitVulkan(void)
_glfw.vk.available = GLFW_TRUE; _glfw.vk.available = GLFW_TRUE;
if (!_glfw.vk.KHR_surface) if (_glfw.vk.KHR_surface)
return; {
_glfw.vk.extensions = _glfw.vk.extensions =
_glfwPlatformGetRequiredInstanceExtensions(&_glfw.vk.extensionCount); _glfwPlatformGetRequiredInstanceExtensions(&_glfw.vk.extensionCount);
} }
return GLFW_TRUE;
}
void _glfwTerminateVulkan(void) void _glfwTerminateVulkan(void)
{ {
uint32_t i; uint32_t i;
@ -193,7 +208,7 @@ const char* _glfwGetVulkanResultString(VkResult result)
GLFWAPI int glfwVulkanSupported(void) GLFWAPI int glfwVulkanSupported(void)
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
return _glfw.vk.available; return _glfwInitVulkan();
} }
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count) GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
@ -202,9 +217,9 @@ GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfw.vk.available) if (!_glfwInitVulkan())
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");
return NULL; return NULL;
} }
@ -219,9 +234,9 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfw.vk.available) if (!_glfwInitVulkan())
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");
return NULL; return NULL;
} }
@ -238,9 +253,9 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
{ {
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE); _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (!_glfw.vk.available) if (!_glfwInitVulkan())
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -263,15 +278,15 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL); assert(window != NULL);
assert(surface != NULL); assert(surface != NULL);
*surface = VK_NULL_HANDLE; *surface = VK_NULL_HANDLE;
_GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED); _GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
if (!_glfw.vk.available) if (!_glfwInitVulkan())
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found"); _glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: API not available");
return VK_ERROR_INITIALIZATION_FAILED; return VK_ERROR_INITIALIZATION_FAILED;
} }

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 WGL - www.glfw.org // GLFW 3.3 WGL - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -55,13 +55,11 @@ static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib
// Return a list of available and usable framebuffer configs // Return a list of available and usable framebuffer configs
// //
static GLFWbool choosePixelFormat(_GLFWwindow* window, static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* desired)
const _GLFWfbconfig* desired,
int* result)
{ {
_GLFWfbconfig* usableConfigs; _GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest; const _GLFWfbconfig* closest;
int i, nativeCount, usableCount; int i, pixelFormat, nativeCount, usableCount;
if (_glfw.wgl.ARB_pixel_format) if (_glfw.wgl.ARB_pixel_format)
{ {
@ -197,7 +195,7 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window,
"WGL: The driver does not appear to support OpenGL"); "WGL: The driver does not appear to support OpenGL");
free(usableConfigs); free(usableConfigs);
return GLFW_FALSE; return 0;
} }
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount); closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
@ -207,13 +205,13 @@ static GLFWbool choosePixelFormat(_GLFWwindow* window,
"WGL: Failed to find a suitable pixel format"); "WGL: Failed to find a suitable pixel format");
free(usableConfigs); free(usableConfigs);
return GLFW_FALSE; return 0;
} }
*result = (int) closest->handle; pixelFormat = (int) closest->handle;
free(usableConfigs); free(usableConfigs);
return GLFW_TRUE; return pixelFormat;
} }
// Returns whether desktop compositing is enabled // Returns whether desktop compositing is enabled
@ -231,7 +229,7 @@ static GLFWbool isCompositionEnabled(void)
return enabled; return enabled;
} }
static void makeContextCurrent(_GLFWwindow* window) static void makeContextCurrentWGL(_GLFWwindow* window)
{ {
if (window) if (window)
{ {
@ -256,7 +254,7 @@ static void makeContextCurrent(_GLFWwindow* window)
} }
} }
static void swapBuffers(_GLFWwindow* window) static void swapBuffersWGL(_GLFWwindow* window)
{ {
// HACK: Use DwmFlush when desktop composition is enabled // HACK: Use DwmFlush when desktop composition is enabled
if (isCompositionEnabled() && !window->monitor) if (isCompositionEnabled() && !window->monitor)
@ -269,7 +267,7 @@ static void swapBuffers(_GLFWwindow* window)
SwapBuffers(window->context.wgl.dc); SwapBuffers(window->context.wgl.dc);
} }
static void swapInterval(int interval) static void swapIntervalWGL(int interval)
{ {
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); _GLFWwindow* window = _glfwPlatformGetCurrentContext();
@ -284,12 +282,10 @@ static void swapInterval(int interval)
_glfw.wgl.SwapIntervalEXT(interval); _glfw.wgl.SwapIntervalEXT(interval);
} }
static int extensionSupported(const char* extension) static int extensionSupportedWGL(const char* extension)
{ {
const char* extensions; const char* extensions;
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
if (_glfw.wgl.GetExtensionsStringEXT) if (_glfw.wgl.GetExtensionsStringEXT)
{ {
extensions = _glfw.wgl.GetExtensionsStringEXT(); extensions = _glfw.wgl.GetExtensionsStringEXT();
@ -302,7 +298,7 @@ static int extensionSupported(const char* extension)
if (_glfw.wgl.GetExtensionsStringARB) if (_glfw.wgl.GetExtensionsStringARB)
{ {
extensions = _glfw.wgl.GetExtensionsStringARB(window->context.wgl.dc); extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());
if (extensions) if (extensions)
{ {
if (_glfwStringInExtensionString(extension, extensions)) if (_glfwStringInExtensionString(extension, extensions))
@ -313,7 +309,7 @@ static int extensionSupported(const char* extension)
return GLFW_FALSE; return GLFW_FALSE;
} }
static GLFWglproc getProcAddress(const char* procname) static GLFWglproc getProcAddressWGL(const char* procname)
{ {
const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname); const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);
if (proc) if (proc)
@ -324,7 +320,7 @@ static GLFWglproc getProcAddress(const char* procname)
// Destroy the OpenGL context // Destroy the OpenGL context
// //
static void destroyContext(_GLFWwindow* window) static void destroyContextWGL(_GLFWwindow* window)
{ {
if (window->context.wgl.handle) if (window->context.wgl.handle)
{ {
@ -335,51 +331,88 @@ static void destroyContext(_GLFWwindow* window)
// Initialize WGL-specific extensions // Initialize WGL-specific extensions
// //
static void loadExtensions(void) static void loadWGLExtensions(void)
{ {
// Functions for WGL_EXT_extension_string PIXELFORMATDESCRIPTOR pfd;
// NOTE: These are needed by extensionSupported HGLRC rc;
HDC dc = GetDC(_glfw.win32.helperWindowHandle);;
_glfw.wgl.extensionsLoaded = GLFW_TRUE;
// NOTE: A dummy context has to be created for opengl32.dll to load the
// OpenGL ICD, from which we can then query WGL extensions
// NOTE: This code will accept the Microsoft GDI ICD; accelerated context
// creation failure occurs during manual pixel format enumeration
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to set pixel format for dummy context");
return;
}
rc = wglCreateContext(dc);
if (!rc)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to create dummy context");
return;
}
if (!wglMakeCurrent(dc, rc))
{
wglDeleteContext(rc);
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to make dummy context current");
return;
}
// NOTE: Functions must be loaded first as they're needed to retrieve the
// extension string that tells us whether the functions are supported
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) _glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
wglGetProcAddress("wglGetExtensionsStringEXT"); wglGetProcAddress("wglGetExtensionsStringEXT");
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) _glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
wglGetProcAddress("wglGetExtensionsStringARB"); wglGetProcAddress("wglGetExtensionsStringARB");
// Functions for WGL_ARB_create_context
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) _glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
wglGetProcAddress("wglCreateContextAttribsARB"); wglGetProcAddress("wglCreateContextAttribsARB");
// Functions for WGL_EXT_swap_control
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) _glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
wglGetProcAddress("wglSwapIntervalEXT"); wglGetProcAddress("wglSwapIntervalEXT");
// Functions for WGL_ARB_pixel_format
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) _glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
wglGetProcAddress("wglGetPixelFormatAttribivARB"); wglGetProcAddress("wglGetPixelFormatAttribivARB");
// This needs to include every extension used below except for // NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
// WGL_ARB_extensions_string and WGL_EXT_extensions_string // checked below as we are already using them
_glfw.wgl.ARB_multisample = _glfw.wgl.ARB_multisample =
extensionSupported("WGL_ARB_multisample"); extensionSupportedWGL("WGL_ARB_multisample");
_glfw.wgl.ARB_framebuffer_sRGB = _glfw.wgl.ARB_framebuffer_sRGB =
extensionSupported("WGL_ARB_framebuffer_sRGB"); extensionSupportedWGL("WGL_ARB_framebuffer_sRGB");
_glfw.wgl.EXT_framebuffer_sRGB = _glfw.wgl.EXT_framebuffer_sRGB =
extensionSupported("WGL_EXT_framebuffer_sRGB"); extensionSupportedWGL("WGL_EXT_framebuffer_sRGB");
_glfw.wgl.ARB_create_context = _glfw.wgl.ARB_create_context =
extensionSupported("WGL_ARB_create_context"); extensionSupportedWGL("WGL_ARB_create_context");
_glfw.wgl.ARB_create_context_profile = _glfw.wgl.ARB_create_context_profile =
extensionSupported("WGL_ARB_create_context_profile"); extensionSupportedWGL("WGL_ARB_create_context_profile");
_glfw.wgl.EXT_create_context_es2_profile = _glfw.wgl.EXT_create_context_es2_profile =
extensionSupported("WGL_EXT_create_context_es2_profile"); extensionSupportedWGL("WGL_EXT_create_context_es2_profile");
_glfw.wgl.ARB_create_context_robustness = _glfw.wgl.ARB_create_context_robustness =
extensionSupported("WGL_ARB_create_context_robustness"); extensionSupportedWGL("WGL_ARB_create_context_robustness");
_glfw.wgl.EXT_swap_control = _glfw.wgl.EXT_swap_control =
extensionSupported("WGL_EXT_swap_control"); extensionSupportedWGL("WGL_EXT_swap_control");
_glfw.wgl.ARB_pixel_format = _glfw.wgl.ARB_pixel_format =
extensionSupported("WGL_ARB_pixel_format"); extensionSupportedWGL("WGL_ARB_pixel_format");
_glfw.wgl.ARB_context_flush_control = _glfw.wgl.ARB_context_flush_control =
extensionSupported("WGL_ARB_context_flush_control"); extensionSupportedWGL("WGL_ARB_context_flush_control");
_glfw.wgl.extensionsLoaded = GLFW_TRUE; wglMakeCurrent(dc, NULL);
wglDeleteContext(rc);
} }
@ -391,6 +424,9 @@ static void loadExtensions(void)
// //
GLFWbool _glfwInitWGL(void) GLFWbool _glfwInitWGL(void)
{ {
if (_glfw.wgl.instance)
return GLFW_TRUE;
_glfw.wgl.instance = LoadLibraryA("opengl32.dll"); _glfw.wgl.instance = LoadLibraryA("opengl32.dll");
if (!_glfw.wgl.instance) if (!_glfw.wgl.instance)
{ {
@ -404,6 +440,8 @@ GLFWbool _glfwInitWGL(void)
GetProcAddress(_glfw.wgl.instance, "wglDeleteContext"); GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
_glfw.wgl.GetProcAddress = (WGLGETPROCADDRESS_T) _glfw.wgl.GetProcAddress = (WGLGETPROCADDRESS_T)
GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress"); GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
_glfw.wgl.GetCurrentDC = (WGLGETCURRENTDC_T)
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
_glfw.wgl.MakeCurrent = (WGLMAKECURRENT_T) _glfw.wgl.MakeCurrent = (WGLMAKECURRENT_T)
GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent"); GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
_glfw.wgl.ShareLists = (WGLSHARELISTS_T) _glfw.wgl.ShareLists = (WGLSHARELISTS_T)
@ -434,12 +472,12 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
int attribs[40]; int attribs[40];
int pixelFormat = 0; int pixelFormat;
PIXELFORMATDESCRIPTOR pfd; PIXELFORMATDESCRIPTOR pfd;
HGLRC share = NULL; HGLRC share = NULL;
if (ctxconfig->client == GLFW_NO_API) if (!_glfw.wgl.extensionsLoaded)
return GLFW_TRUE; loadWGLExtensions();
if (ctxconfig->share) if (ctxconfig->share)
share = ctxconfig->share->context.wgl.handle; share = ctxconfig->share->context.wgl.handle;
@ -452,7 +490,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
return GLFW_FALSE; return GLFW_FALSE;
} }
if (!choosePixelFormat(window, fbconfig, &pixelFormat)) pixelFormat = choosePixelFormat(window, fbconfig);
if (!pixelFormat)
return GLFW_FALSE; return GLFW_FALSE;
if (!DescribePixelFormat(window->context.wgl.dc, if (!DescribePixelFormat(window->context.wgl.dc,
@ -470,6 +509,40 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
return GLFW_FALSE; return GLFW_FALSE;
} }
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
{
if (!_glfw.wgl.ARB_create_context)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
return GLFW_FALSE;
}
}
if (ctxconfig->profile)
{
if (!_glfw.wgl.ARB_create_context_profile)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
return GLFW_FALSE;
}
}
}
else
{
if (!_glfw.wgl.ARB_create_context ||
!_glfw.wgl.ARB_create_context_profile ||
!_glfw.wgl.EXT_create_context_es2_profile)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
return GLFW_FALSE;
}
}
if (_glfw.wgl.ARB_create_context) if (_glfw.wgl.ARB_create_context)
{ {
int index = 0, mask = 0, flags = 0; int index = 0, mask = 0, flags = 0;
@ -549,9 +622,45 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
_glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc, _glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,
share, attribs); share, attribs);
if (!window->context.wgl.handle) if (!window->context.wgl.handle)
{
const DWORD error = GetLastError();
if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
{
if (ctxconfig->client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Driver does not support OpenGL version %i.%i",
ctxconfig->major,
ctxconfig->minor);
}
else
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Driver does not support OpenGL ES version %i.%i",
ctxconfig->major,
ctxconfig->minor);
}
}
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Driver does not support the requested OpenGL profile");
}
else
{
if (ctxconfig->client == GLFW_OPENGL_API)
{ {
_glfwInputError(GLFW_VERSION_UNAVAILABLE, _glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL context"); "WGL: Failed to create OpenGL context");
}
else
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL ES context");
}
}
return GLFW_FALSE; return GLFW_FALSE;
} }
} }
@ -576,114 +685,18 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
} }
} }
window->context.makeContextCurrent = makeContextCurrent; window->context.makeCurrent = makeContextCurrentWGL;
window->context.swapBuffers = swapBuffers; window->context.swapBuffers = swapBuffersWGL;
window->context.swapInterval = swapInterval; window->context.swapInterval = swapIntervalWGL;
window->context.extensionSupported = extensionSupported; window->context.extensionSupported = extensionSupportedWGL;
window->context.getProcAddress = getProcAddress; window->context.getProcAddress = getProcAddressWGL;
window->context.destroyContext = destroyContext; window->context.destroy = destroyContextWGL;
return GLFW_TRUE; return GLFW_TRUE;
} }
#undef setWGLattrib #undef setWGLattrib
// Analyzes the specified context for possible recreation
//
int _glfwAnalyzeContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
GLFWbool required = GLFW_FALSE;
if (_glfw.wgl.extensionsLoaded)
return _GLFW_RECREATION_NOT_NEEDED;
makeContextCurrent(window);
loadExtensions();
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
{
if (!_glfw.wgl.ARB_create_context)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
return _GLFW_RECREATION_IMPOSSIBLE;
}
required = GLFW_TRUE;
}
if (ctxconfig->profile)
{
if (!_glfw.wgl.ARB_create_context_profile)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
return _GLFW_RECREATION_IMPOSSIBLE;
}
required = GLFW_TRUE;
}
if (ctxconfig->release)
{
if (_glfw.wgl.ARB_context_flush_control)
required = GLFW_TRUE;
}
}
else
{
if (!_glfw.wgl.ARB_create_context ||
!_glfw.wgl.ARB_create_context_profile ||
!_glfw.wgl.EXT_create_context_es2_profile)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
return _GLFW_RECREATION_IMPOSSIBLE;
}
required = GLFW_TRUE;
}
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
if (_glfw.wgl.ARB_create_context)
required = GLFW_TRUE;
}
if (ctxconfig->debug)
{
if (_glfw.wgl.ARB_create_context)
required = GLFW_TRUE;
}
if (fbconfig->samples > 0)
{
// MSAA is not a hard constraint, so do nothing if it's not supported
if (_glfw.wgl.ARB_multisample && _glfw.wgl.ARB_pixel_format)
required = GLFW_TRUE;
}
if (fbconfig->sRGB)
{
// sRGB is not a hard constraint, so do nothing if it's not supported
if ((_glfw.wgl.ARB_framebuffer_sRGB ||
_glfw.wgl.EXT_framebuffer_sRGB) &&
_glfw.wgl.ARB_pixel_format)
{
required = GLFW_TRUE;
}
}
if (required)
return _GLFW_RECREATION_REQUIRED;
return _GLFW_RECREATION_NOT_NEEDED;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW native API ////// ////// GLFW native API //////

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 WGL - www.glfw.org // GLFW 3.3 WGL - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -73,6 +73,9 @@
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0 #define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 #define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#define ERROR_INVALID_VERSION_ARB 0x2095
#define ERROR_INVALID_PROFILE_ARB 0x2096
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int); typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*); typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void); typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
@ -82,6 +85,7 @@ typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*)
typedef HGLRC (WINAPI * WGLCREATECONTEXT_T)(HDC); typedef HGLRC (WINAPI * WGLCREATECONTEXT_T)(HDC);
typedef BOOL (WINAPI * WGLDELETECONTEXT_T)(HGLRC); typedef BOOL (WINAPI * WGLDELETECONTEXT_T)(HGLRC);
typedef PROC (WINAPI * WGLGETPROCADDRESS_T)(LPCSTR); typedef PROC (WINAPI * WGLGETPROCADDRESS_T)(LPCSTR);
typedef HDC (WINAPI * WGLGETCURRENTDC_T)(void);
typedef BOOL (WINAPI * WGLMAKECURRENT_T)(HDC,HGLRC); typedef BOOL (WINAPI * WGLMAKECURRENT_T)(HDC,HGLRC);
typedef BOOL (WINAPI * WGLSHARELISTS_T)(HGLRC,HGLRC); typedef BOOL (WINAPI * WGLSHARELISTS_T)(HGLRC,HGLRC);
@ -89,6 +93,7 @@ typedef BOOL (WINAPI * WGLSHARELISTS_T)(HGLRC,HGLRC);
#define wglCreateContext _glfw.wgl.CreateContext #define wglCreateContext _glfw.wgl.CreateContext
#define wglDeleteContext _glfw.wgl.DeleteContext #define wglDeleteContext _glfw.wgl.DeleteContext
#define wglGetProcAddress _glfw.wgl.GetProcAddress #define wglGetProcAddress _glfw.wgl.GetProcAddress
#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
#define wglMakeCurrent _glfw.wgl.MakeCurrent #define wglMakeCurrent _glfw.wgl.MakeCurrent
#define wglShareLists _glfw.wgl.ShareLists #define wglShareLists _glfw.wgl.ShareLists
@ -110,7 +115,6 @@ typedef struct _GLFWcontextWGL
} _GLFWcontextWGL; } _GLFWcontextWGL;
// WGL-specific global data // WGL-specific global data
// //
typedef struct _GLFWlibraryWGL typedef struct _GLFWlibraryWGL
@ -119,6 +123,7 @@ typedef struct _GLFWlibraryWGL
WGLCREATECONTEXT_T CreateContext; WGLCREATECONTEXT_T CreateContext;
WGLDELETECONTEXT_T DeleteContext; WGLDELETECONTEXT_T DeleteContext;
WGLGETPROCADDRESS_T GetProcAddress; WGLGETPROCADDRESS_T GetProcAddress;
WGLGETCURRENTDC_T GetCurrentDC;
WGLMAKECURRENT_T MakeCurrent; WGLMAKECURRENT_T MakeCurrent;
WGLSHARELISTS_T ShareLists; WGLSHARELISTS_T ShareLists;
@ -148,8 +153,5 @@ void _glfwTerminateWGL(void);
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig); const _GLFWfbconfig* fbconfig);
int _glfwAnalyzeContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
#endif // _glfw3_wgl_context_h_ #endif // _glfw3_wgl_context_h_

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 Win32 - www.glfw.org // GLFW 3.3 Win32 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -319,6 +319,10 @@ static HWND createHelperWindow(void)
return NULL; return NULL;
} }
// HACK: The first call to ShowWindow is ignored if the parent process
// passed along a STARTUPINFO, so clear that flag with a no-op call
ShowWindow(window, SW_HIDE);
// Register for HID device notifications // Register for HID device notifications
{ {
DEV_BROADCAST_DEVICEINTERFACE_W dbi; DEV_BROADCAST_DEVICEINTERFACE_W dbi;
@ -373,7 +377,7 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
if (!length) if (!length)
return NULL; return NULL;
target = calloc(length, sizeof(char)); target = calloc(length, 1);
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL)) if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL))
{ {
@ -415,16 +419,12 @@ int _glfwPlatformInit(void)
if (!_glfwRegisterWindowClassWin32()) if (!_glfwRegisterWindowClassWin32())
return GLFW_FALSE; return GLFW_FALSE;
_glfw.win32.helperWindow = createHelperWindow(); _glfw.win32.helperWindowHandle = createHelperWindow();
if (!_glfw.win32.helperWindow) if (!_glfw.win32.helperWindowHandle)
return GLFW_FALSE; return GLFW_FALSE;
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
if (!_glfwInitWGL())
return GLFW_FALSE;
_glfwInitEGL();
_glfwInitTimerWin32(); _glfwInitTimerWin32();
_glfwInitJoysticksWin32(); _glfwInitJoysticksWin32();
@ -433,8 +433,8 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void) void _glfwPlatformTerminate(void)
{ {
if (_glfw.win32.helperWindow) if (_glfw.win32.helperWindowHandle)
DestroyWindow(_glfw.win32.helperWindow); DestroyWindow(_glfw.win32.helperWindowHandle);
_glfwUnregisterWindowClassWin32(); _glfwUnregisterWindowClassWin32();

View File

@ -2,7 +2,7 @@
// GLFW 3.1 Win32 - www.glfw.org // GLFW 3.1 Win32 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2015 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -176,7 +176,7 @@ static int compareJoystickObjects(const void* first, const void* second)
// //
static GLFWbool supportsXInput(const GUID* guid) static GLFWbool supportsXInput(const GUID* guid)
{ {
UINT i, count; UINT i, count = 0;
RAWINPUTDEVICELIST* ridl; RAWINPUTDEVICELIST* ridl;
GLFWbool result = GLFW_FALSE; GLFWbool result = GLFW_FALSE;
@ -185,7 +185,7 @@ static GLFWbool supportsXInput(const GUID* guid)
ridl = calloc(count, sizeof(RAWINPUTDEVICELIST)); ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == -1) if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
{ {
free(ridl); free(ridl);
return GLFW_FALSE; return GLFW_FALSE;
@ -211,7 +211,7 @@ static GLFWbool supportsXInput(const GUID* guid)
continue; continue;
} }
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != guid->Data1) if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
continue; continue;
memset(name, 0, sizeof(name)); memset(name, 0, sizeof(name));

View File

@ -1,7 +1,7 @@
//======================================================================== //========================================================================
// GLFW 3.2 Win32 - www.glfw.org // GLFW 3.3 Win32 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2006-2014 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -30,7 +30,7 @@
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ #define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
_GLFWjoystickWin32 win32_js[GLFW_JOYSTICK_LAST + 1] _GLFWjoystickWin32 win32_js[GLFW_JOYSTICK_LAST + 1]
// Spoo // Joystick element (axis, button or slider)
// //
typedef struct _GLFWjoyobjectWin32 typedef struct _GLFWjoyobjectWin32
{ {

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 Win32 - www.glfw.org // GLFW 3.3 Win32 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 Win32 - www.glfw.org // GLFW 3.3 Win32 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -237,21 +237,24 @@ typedef struct _GLFWwindowWin32
GLFWbool iconified; GLFWbool iconified;
// The last received cursor position, regardless of source // The last received cursor position, regardless of source
int cursorPosX, cursorPosY; int lastCursorPosX, lastCursorPosY;
} _GLFWwindowWin32; } _GLFWwindowWin32;
// Win32-specific global data // Win32-specific global data
// //
typedef struct _GLFWlibraryWin32 typedef struct _GLFWlibraryWin32
{ {
HWND helperWindow; HWND helperWindowHandle;
DWORD foregroundLockTimeout; DWORD foregroundLockTimeout;
char* clipboardString; char* clipboardString;
char keyName[64]; char keyName[64];
short int publicKeys[512]; short int publicKeys[512];
short int nativeKeys[GLFW_KEY_LAST + 1]; short int nativeKeys[GLFW_KEY_LAST + 1];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
struct { struct {
HINSTANCE instance; HINSTANCE instance;
@ -289,7 +292,6 @@ typedef struct _GLFWlibraryWin32
} _GLFWlibraryWin32; } _GLFWlibraryWin32;
// Win32-specific per-monitor data // Win32-specific per-monitor data
// //
typedef struct _GLFWmonitorWin32 typedef struct _GLFWmonitorWin32
@ -304,7 +306,6 @@ typedef struct _GLFWmonitorWin32
} _GLFWmonitorWin32; } _GLFWmonitorWin32;
// Win32-specific per-cursor data // Win32-specific per-cursor data
// //
typedef struct _GLFWcursorWin32 typedef struct _GLFWcursorWin32
@ -313,7 +314,6 @@ typedef struct _GLFWcursorWin32
} _GLFWcursorWin32; } _GLFWcursorWin32;
// Win32-specific global timer data // Win32-specific global timer data
// //
typedef struct _GLFWtimeWin32 typedef struct _GLFWtimeWin32
@ -323,7 +323,6 @@ typedef struct _GLFWtimeWin32
} _GLFWtimeWin32; } _GLFWtimeWin32;
// Win32-specific global TLS data // Win32-specific global TLS data
// //
typedef struct _GLFWtlsWin32 typedef struct _GLFWtlsWin32

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 Win32 - www.glfw.org // GLFW 3.3 Win32 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 Win32 - www.glfw.org // GLFW 3.3 Win32 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 Win32 - www.glfw.org // GLFW 3.3 Win32 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -218,9 +218,55 @@ static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area)
} }
} }
// Centers the cursor over the window client area
//
static void centerCursor(_GLFWwindow* window)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
// Returns whether the cursor is in the client area of the specified window
//
static GLFWbool cursorInClientArea(_GLFWwindow* window)
{
RECT area;
POINT pos;
if (!GetCursorPos(&pos))
return GLFW_FALSE;
if (WindowFromPoint(pos) != window->win32.handle)
return GLFW_FALSE;
GetClientRect(window->win32.handle, &area);
ClientToScreen(window->win32.handle, (POINT*) &area.left);
ClientToScreen(window->win32.handle, (POINT*) &area.right);
return PtInRect(&area, pos);
}
// Updates the cursor image according to its cursor mode
//
static void updateCursorImage(_GLFWwindow* window)
{
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
SetCursor(window->cursor->win32.handle);
else
SetCursor(LoadCursorW(NULL, IDC_ARROW));
}
else
SetCursor(NULL);
}
// Updates the cursor clip rect // Updates the cursor clip rect
// //
static void updateClipRect(_GLFWwindow* window) static void updateClipRect(_GLFWwindow* window)
{
if (window)
{ {
RECT clipRect; RECT clipRect;
GetClientRect(window->win32.handle, &clipRect); GetClientRect(window->win32.handle, &clipRect);
@ -228,6 +274,9 @@ static void updateClipRect(_GLFWwindow* window)
ClientToScreen(window->win32.handle, (POINT*) &clipRect.right); ClientToScreen(window->win32.handle, (POINT*) &clipRect.right);
ClipCursor(&clipRect); ClipCursor(&clipRect);
} }
else
ClipCursor(NULL);
}
// Translates a GLFW standard cursor to a resource ID // Translates a GLFW standard cursor to a resource ID
// //
@ -329,6 +378,13 @@ static int translateKey(WPARAM wParam, LPARAM lParam)
return GLFW_KEY_LEFT_CONTROL; return GLFW_KEY_LEFT_CONTROL;
} }
if (wParam == VK_PROCESSKEY)
{
// IME notifies that keys have been filtered by setting the virtual
// key-code to VK_PROCESSKEY
return _GLFW_KEY_INVALID;
}
return _glfw.win32.publicKeys[HIWORD(lParam) & 0x1FF]; return _glfw.win32.publicKeys[HIWORD(lParam) & 0x1FF];
} }
@ -369,7 +425,7 @@ static void releaseMonitor(_GLFWwindow* window)
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam) WPARAM wParam, LPARAM lParam)
{ {
_GLFWwindow* window = (_GLFWwindow*) GetPropW(hWnd, L"GLFW"); _GLFWwindow* window = GetPropW(hWnd, L"GLFW");
if (!window) if (!window)
{ {
// This is the message handling for the hidden helper window // This is the message handling for the hidden helper window
@ -413,10 +469,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{ {
case WM_SETFOCUS: case WM_SETFOCUS:
{ {
_glfwInputWindowFocus(window, GLFW_TRUE);
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED); _glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
_glfwInputWindowFocus(window, GLFW_TRUE);
return 0; return 0;
} }
@ -561,18 +618,21 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
{ {
if (_glfw.cursorWindow != window) const int dx = x - window->win32.lastCursorPosX;
const int dy = y - window->win32.lastCursorPosY;
if (_glfw.win32.disabledCursorWindow != window)
break; break;
_glfwInputCursorMotion(window, _glfwInputCursorPos(window,
x - window->win32.cursorPosX, window->virtualCursorPosX + dx,
y - window->win32.cursorPosY); window->virtualCursorPosY + dy);
} }
else else
_glfwInputCursorMotion(window, x, y); _glfwInputCursorPos(window, x, y);
window->win32.cursorPosX = x; window->win32.lastCursorPosX = x;
window->win32.cursorPosY = y; window->win32.lastCursorPosY = y;
if (!window->win32.cursorTracked) if (!window->win32.cursorTracked)
{ {
@ -611,6 +671,24 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return 0; return 0;
} }
case WM_ENTERSIZEMOVE:
case WM_ENTERMENULOOP:
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
break;
}
case WM_EXITSIZEMOVE:
case WM_EXITMENULOOP:
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
break;
}
case WM_SIZE: case WM_SIZE:
{ {
const GLFWbool iconified = const GLFWbool iconified =
@ -619,11 +697,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
window->win32.iconified && window->win32.iconified &&
(wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED); (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED);
if (_glfw.cursorWindow == window) if (_glfw.win32.disabledCursorWindow == window)
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
updateClipRect(window); updateClipRect(window);
}
if (iconified) if (iconified)
_glfwInputWindowIconify(window, GLFW_TRUE); _glfwInputWindowIconify(window, GLFW_TRUE);
@ -651,11 +726,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOVE: case WM_MOVE:
{ {
if (_glfw.cursorWindow == window) if (_glfw.win32.disabledCursorWindow == window)
{
if (window->cursorMode == GLFW_CURSOR_DISABLED)
updateClipRect(window); updateClipRect(window);
}
// NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as // NOTE: This cannot use LOWORD/HIWORD recommended by MSDN, as
// those macros do not handle negative window positions correctly // those macros do not handle negative window positions correctly
@ -718,20 +790,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_SETCURSOR: case WM_SETCURSOR:
{ {
if (_glfw.cursorWindow == window && LOWORD(lParam) == HTCLIENT) if (LOWORD(lParam) == HTCLIENT)
{ {
if (window->cursorMode == GLFW_CURSOR_HIDDEN || updateCursorImage(window);
window->cursorMode == GLFW_CURSOR_DISABLED)
{
SetCursor(NULL);
return TRUE; return TRUE;
} }
else if (window->cursor)
{
SetCursor(window->cursor->win32.handle);
return TRUE;
}
}
break; break;
} }
@ -760,7 +823,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// Move the mouse to the position of the drop // Move the mouse to the position of the drop
DragQueryPoint(drop, &pt); DragQueryPoint(drop, &pt);
_glfwInputCursorMotion(window, pt.x, pt.y); _glfwInputCursorPos(window, pt.x, pt.y);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
@ -787,9 +850,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return DefWindowProcW(hWnd, uMsg, wParam, lParam); return DefWindowProcW(hWnd, uMsg, wParam, lParam);
} }
// Creates the GLFW window and rendering context // Creates the GLFW window
// //
static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) static int createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig)
{ {
int xpos, ypos, fullWidth, fullHeight; int xpos, ypos, fullWidth, fullHeight;
WCHAR* wideTitle; WCHAR* wideTitle;
@ -865,18 +929,6 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig)
return GLFW_TRUE; return GLFW_TRUE;
} }
// Destroys the GLFW window and rendering context
//
static void destroyWindow(_GLFWwindow* window)
{
if (window->win32.handle)
{
RemovePropW(window->win32.handle, L"GLFW");
DestroyWindow(window->win32.handle);
window->win32.handle = NULL;
}
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW internal API //////
@ -935,60 +987,22 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) const _GLFWfbconfig* fbconfig)
{ {
int status; if (!createNativeWindow(window, wndconfig))
if (!createWindow(window, wndconfig))
return GLFW_FALSE; return GLFW_FALSE;
if (ctxconfig->client != GLFW_NO_API) if (ctxconfig->client != GLFW_NO_API)
{ {
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API) if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{ {
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig)) if (!_glfwInitWGL())
return GLFW_FALSE;
status = _glfwAnalyzeContextWGL(window, ctxconfig, fbconfig);
if (status == _GLFW_RECREATION_IMPOSSIBLE)
return GLFW_FALSE;
if (status == _GLFW_RECREATION_REQUIRED)
{
// Some window hints require us to re-create the context using WGL
// extensions retrieved through the current context, as we cannot
// check for WGL extensions or retrieve WGL entry points before we
// have a current context (actually until we have implicitly loaded
// the vendor ICD)
// Yes, this is strange, and yes, this is the proper way on WGL
// As Windows only allows you to set the pixel format once for
// a window, we need to destroy the current window and create a new
// one to be able to use the new pixel format
// Technically, it may be possible to keep the old window around if
// we're just creating an OpenGL 3.0+ context with the same pixel
// format, but it's not worth the added code complexity
// First we clear the current context (the one we just created)
// This is usually done by glfwDestroyWindow, but as we're not doing
// full GLFW window destruction, it's duplicated here
window->context.makeContextCurrent(NULL);
// Next destroy the Win32 window and WGL context (without resetting
// or destroying the GLFW window object)
window->context.destroyContext(window);
destroyWindow(window);
// ...and then create them again, this time with better APIs
if (!createWindow(window, wndconfig))
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig)) if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
}
else else
{ {
if (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -1000,6 +1014,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
_glfwPlatformFocusWindow(window); _glfwPlatformFocusWindow(window);
if (!acquireMonitor(window)) if (!acquireMonitor(window))
return GLFW_FALSE; return GLFW_FALSE;
centerCursor(window);
} }
return GLFW_TRUE; return GLFW_TRUE;
@ -1010,10 +1026,18 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (window->monitor) if (window->monitor)
releaseMonitor(window); releaseMonitor(window);
if (window->context.client != GLFW_NO_API) if (window->context.destroy)
window->context.destroyContext(window); window->context.destroy(window);
destroyWindow(window); if (_glfw.win32.disabledCursorWindow == window)
_glfw.win32.disabledCursorWindow = NULL;
if (window->win32.handle)
{
RemovePropW(window->win32.handle, L"GLFW");
DestroyWindow(window->win32.handle);
window->win32.handle = NULL;
}
if (window->win32.bigIcon) if (window->win32.bigIcon)
DestroyIcon(window->win32.bigIcon); DestroyIcon(window->win32.bigIcon);
@ -1326,6 +1350,8 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
void _glfwPlatformPollEvents(void) void _glfwPlatformPollEvents(void)
{ {
MSG msg; MSG msg;
HWND handle;
_GLFWwindow* window;
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE))
{ {
@ -1335,7 +1361,7 @@ void _glfwPlatformPollEvents(void)
// While GLFW does not itself post WM_QUIT, other processes may post // While GLFW does not itself post WM_QUIT, other processes may post
// it to this one, for example Task Manager // it to this one, for example Task Manager
_GLFWwindow* window = _glfw.windowListHead; window = _glfw.windowListHead;
while (window) while (window)
{ {
_glfwInputWindowCloseRequest(window); _glfwInputWindowCloseRequest(window);
@ -1349,13 +1375,14 @@ void _glfwPlatformPollEvents(void)
} }
} }
if (_glfw.cursorWindow) handle = GetActiveWindow();
if (handle)
{ {
_GLFWwindow* window = _glfw.cursorWindow;
// LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix) // LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix)
// This is the only async event handling in GLFW, but it solves some // This is the only async event handling in GLFW, but it solves some
// nasty problems // nasty problems
window = GetPropW(handle, L"GLFW");
if (window)
{ {
const int mods = getAsyncKeyMods(); const int mods = getAsyncKeyMods();
@ -1371,22 +1398,23 @@ void _glfwPlatformPollEvents(void)
if (!rshiftDown && window->keys[GLFW_KEY_RIGHT_SHIFT] == 1) if (!rshiftDown && window->keys[GLFW_KEY_RIGHT_SHIFT] == 1)
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, 0, GLFW_RELEASE, mods); _glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, 0, GLFW_RELEASE, mods);
} }
}
if (window->cursorMode == GLFW_CURSOR_DISABLED) window = _glfw.win32.disabledCursorWindow;
if (window)
{ {
int width, height; int width, height;
_glfwPlatformGetWindowSize(window, &width, &height); _glfwPlatformGetWindowSize(window, &width, &height);
// NOTE: Re-center the cursor only if it has moved since the last // NOTE: Re-center the cursor only if it has moved since the last call,
// call, to avoid breaking glfwWaitEvents with WM_MOUSEMOVE // to avoid breaking glfwWaitEvents with WM_MOUSEMOVE
if (window->win32.cursorPosX != width / 2 || if (window->win32.lastCursorPosX != width / 2 ||
window->win32.cursorPosY != height / 2) window->win32.lastCursorPosY != height / 2)
{ {
_glfwPlatformSetCursorPos(window, width / 2, height / 2); _glfwPlatformSetCursorPos(window, width / 2, height / 2);
} }
} }
} }
}
void _glfwPlatformWaitEvents(void) void _glfwPlatformWaitEvents(void)
{ {
@ -1428,8 +1456,8 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
POINT pos = { (int) xpos, (int) ypos }; POINT pos = { (int) xpos, (int) ypos };
// Store the new position so it can be recognized later // Store the new position so it can be recognized later
window->win32.cursorPosX = pos.x; window->win32.lastCursorPosX = pos.x;
window->win32.cursorPosY = pos.y; window->win32.lastCursorPosY = pos.y;
ClientToScreen(window->win32.handle, &pos); ClientToScreen(window->win32.handle, &pos);
SetCursorPos(pos.x, pos.y); SetCursorPos(pos.x, pos.y);
@ -1437,28 +1465,26 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos)
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{ {
POINT pos;
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED)
updateClipRect(window);
else
ClipCursor(NULL);
if (!GetCursorPos(&pos))
return;
if (WindowFromPoint(pos) != window->win32.handle)
return;
if (mode == GLFW_CURSOR_NORMAL)
{ {
if (window->cursor) _glfw.win32.disabledCursorWindow = window;
SetCursor(window->cursor->win32.handle); _glfwPlatformGetCursorPos(window,
else &_glfw.win32.restoreCursorPosX,
SetCursor(LoadCursorW(NULL, IDC_ARROW)); &_glfw.win32.restoreCursorPosY);
centerCursor(window);
updateClipRect(window);
} }
else else if (_glfw.win32.disabledCursorWindow == window)
SetCursor(NULL); {
_glfw.win32.disabledCursorWindow = NULL;
updateClipRect(NULL);
_glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY);
}
if (cursorInClientArea(window))
updateCursorImage(window);
} }
const char* _glfwPlatformGetKeyName(int key, int scancode) const char* _glfwPlatformGetKeyName(int key, int scancode)
@ -1518,91 +1544,70 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{ {
RECT area; if (cursorInClientArea(window))
POINT pos; updateCursorImage(window);
if (_glfw.cursorWindow != window)
return;
if (window->cursorMode != GLFW_CURSOR_NORMAL)
return;
if (!GetCursorPos(&pos))
return;
if (WindowFromPoint(pos) != window->win32.handle)
return;
GetClientRect(window->win32.handle, &area);
ClientToScreen(window->win32.handle, (POINT*) &area.left);
ClientToScreen(window->win32.handle, (POINT*) &area.right);
if (!PtInRect(&area, pos))
return;
if (cursor)
SetCursor(cursor->win32.handle);
else
SetCursor(LoadCursorW(NULL, IDC_ARROW));
} }
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{ {
WCHAR* wideString; int characterCount;
HANDLE stringHandle; HANDLE object;
size_t wideSize; WCHAR* buffer;
wideString = _glfwCreateWideStringFromUTF8Win32(string); characterCount = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
if (!wideString) if (!characterCount)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-16"); "Win32: Failed to convert clipboard string to UTF-16");
return; return;
} }
wideSize = (wcslen(wideString) + 1) * sizeof(WCHAR); object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR));
if (!object)
stringHandle = GlobalAlloc(GMEM_MOVEABLE, wideSize);
if (!stringHandle)
{ {
free(wideString);
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to allocate global handle for clipboard"); "Win32: Failed to allocate global handle for clipboard");
return; return;
} }
memcpy(GlobalLock(stringHandle), wideString, wideSize); buffer = GlobalLock(object);
GlobalUnlock(stringHandle); if (!buffer)
if (!OpenClipboard(_glfw.win32.helperWindow))
{ {
GlobalFree(stringHandle); GlobalFree(object);
free(wideString);
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");
return;
}
MultiByteToWideChar(CP_UTF8, 0, string, -1, buffer, characterCount);
GlobalUnlock(object);
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
{
GlobalFree(object);
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard"); _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");
return; return;
} }
EmptyClipboard(); EmptyClipboard();
SetClipboardData(CF_UNICODETEXT, stringHandle); SetClipboardData(CF_UNICODETEXT, object);
CloseClipboard(); CloseClipboard();
free(wideString);
} }
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
{ {
HANDLE stringHandle; HANDLE object;
WCHAR* buffer;
if (!OpenClipboard(_glfw.win32.helperWindow)) if (!OpenClipboard(_glfw.win32.helperWindowHandle))
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard"); _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");
return NULL; return NULL;
} }
stringHandle = GetClipboardData(CF_UNICODETEXT); object = GetClipboardData(CF_UNICODETEXT);
if (!stringHandle) if (!object)
{ {
CloseClipboard(); CloseClipboard();
@ -1611,11 +1616,20 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
return NULL; return NULL;
} }
buffer = GlobalLock(object);
if (!buffer)
{
CloseClipboard();
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");
return NULL;
}
free(_glfw.win32.clipboardString); free(_glfw.win32.clipboardString);
_glfw.win32.clipboardString = _glfw.win32.clipboardString =
_glfwCreateUTF8FromWideStringWin32(GlobalLock(stringHandle)); _glfwCreateUTF8FromWideStringWin32(buffer);
GlobalUnlock(stringHandle); GlobalUnlock(object);
CloseClipboard(); CloseClipboard();
if (!_glfw.win32.clipboardString) if (!_glfw.win32.clipboardString)

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 - www.glfw.org // GLFW 3.3 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net> // Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
@ -42,8 +42,6 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
{ {
if (focused) if (focused)
{ {
_glfw.cursorWindow = window;
if (window->callbacks.focus) if (window->callbacks.focus)
window->callbacks.focus((GLFWwindow*) window, focused); window->callbacks.focus((GLFWwindow*) window, focused);
} }
@ -51,8 +49,6 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
{ {
int i; int i;
_glfw.cursorWindow = NULL;
if (window->callbacks.focus) if (window->callbacks.focus)
window->callbacks.focus((GLFWwindow*) window, focused); window->callbacks.focus((GLFWwindow*) window, focused);
@ -155,7 +151,8 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
if (ctxconfig.share) if (ctxconfig.share)
{ {
if (ctxconfig.share->context.client == GLFW_NO_API) if (ctxconfig.client == GLFW_NO_API ||
ctxconfig.share->context.client == GLFW_NO_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL; return NULL;
@ -206,7 +203,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
if (ctxconfig.client != GLFW_NO_API) if (ctxconfig.client != GLFW_NO_API)
{ {
window->context.makeContextCurrent(window); window->context.makeCurrent(window);
// Retrieve the actual (as opposed to requested) context attributes // Retrieve the actual (as opposed to requested) context attributes
if (!_glfwRefreshContextAttribs(&ctxconfig)) if (!_glfwRefreshContextAttribs(&ctxconfig))
@ -220,17 +217,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
glfwMakeContextCurrent((GLFWwindow*) previous); glfwMakeContextCurrent((GLFWwindow*) previous);
} }
if (window->monitor) if (!window->monitor)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
window->cursorPosX = width / 2;
window->cursorPosY = height / 2;
_glfwPlatformSetCursorPos(window, window->cursorPosX, window->cursorPosY);
}
else
{ {
if (wndconfig.visible) if (wndconfig.visible)
{ {
@ -409,10 +396,6 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
if (window == _glfwPlatformGetCurrentContext()) if (window == _glfwPlatformGetCurrentContext())
glfwMakeContextCurrent(NULL); glfwMakeContextCurrent(NULL);
// Clear the focused window pointer if this is the focused window
if (_glfw.cursorWindow == window)
_glfw.cursorWindow = NULL;
_glfwPlatformDestroyWindow(window); _glfwPlatformDestroyWindow(window);
// Unlink window from global linked list // Unlink window from global linked list
@ -532,12 +515,28 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle,
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (minwidth < 0 || minheight < 0 || if (minwidth != GLFW_DONT_CARE && minheight != GLFW_DONT_CARE)
{
if (minwidth < 0 || minheight < 0)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid window minimum size %ix%i",
minwidth, minheight);
return;
}
}
if (maxwidth != GLFW_DONT_CARE && maxheight != GLFW_DONT_CARE)
{
if (maxwidth < 0 || maxheight < 0 ||
maxwidth < minwidth || maxheight < minheight) maxwidth < minwidth || maxheight < minheight)
{ {
_glfwInputError(GLFW_INVALID_VALUE, "Invalid window size limits"); _glfwInputError(GLFW_INVALID_VALUE,
"Invalid window maximum size %ix%i",
maxwidth, maxheight);
return; return;
} }
}
window->minwidth = minwidth; window->minwidth = minwidth;
window->minheight = minheight; window->minheight = minheight;
@ -559,11 +558,16 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE)
{
if (numer <= 0 || denom <= 0) if (numer <= 0 || denom <= 0)
{ {
_glfwInputError(GLFW_INVALID_VALUE, "Invalid window aspect ratio"); _glfwInputError(GLFW_INVALID_VALUE,
"Invalid window aspect ratio %i:%i",
numer, denom);
return; return;
} }
}
window->numer = numer; window->numer = numer;
window->denom = denom; window->denom = denom;
@ -577,7 +581,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window); assert(window != NULL);
if (width) if (width)
*width = 0; *width = 0;
@ -629,7 +633,13 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow* handle)
GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle) GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle)
{ {
_GLFWwindow* window = (_GLFWwindow*) handle; _GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (window->monitor)
return;
_glfwPlatformMaximizeWindow(window); _glfwPlatformMaximizeWindow(window);
} }
@ -738,10 +748,26 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
{ {
_GLFWwindow* window = (_GLFWwindow*) wh; _GLFWwindow* window = (_GLFWwindow*) wh;
_GLFWmonitor* monitor = (_GLFWmonitor*) mh; _GLFWmonitor* monitor = (_GLFWmonitor*) mh;
assert(window); assert(window != NULL);
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
if (width <= 0 || height <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid window size %ix%i",
width, height);
return;
}
if (refreshRate < 0 && refreshRate != GLFW_DONT_CARE)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid refresh rate %i",
refreshRate);
return;
}
window->videoMode.width = width; window->videoMode.width = width;
window->videoMode.height = height; window->videoMode.height = height;
window->videoMode.refreshRate = refreshRate; window->videoMode.refreshRate = refreshRate;

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 Wayland - www.glfw.org // GLFW 3.3 Wayland - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
// //
@ -91,7 +91,7 @@ static void pointerHandleMotion(void* data,
window->wl.cursorPosY = wl_fixed_to_double(sy); window->wl.cursorPosY = wl_fixed_to_double(sy);
} }
_glfwInputCursorMotion(window, _glfwInputCursorPos(window,
wl_fixed_to_double(sx), wl_fixed_to_double(sx),
wl_fixed_to_double(sy)); wl_fixed_to_double(sy));
} }
@ -600,9 +600,6 @@ int _glfwPlatformInit(void)
if (!_glfwInitThreadLocalStoragePOSIX()) if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwInitJoysticksLinux()) if (!_glfwInitJoysticksLinux())
return GLFW_FALSE; return GLFW_FALSE;

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 Wayland - www.glfw.org // GLFW 3.3 Wayland - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
// //
@ -120,7 +120,7 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
struct wl_output *output; struct wl_output *output;
char name_str[80]; char name_str[80];
memset(name_str, 0, 80 * sizeof(char)); memset(name_str, 0, sizeof(name_str));
snprintf(name_str, 79, "wl_output@%u", name); snprintf(name_str, 79, "wl_output@%u", name);
if (version < 2) if (version < 2)

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 Wayland - www.glfw.org // GLFW 3.3 Wayland - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
// //
@ -74,7 +74,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
// //
typedef struct _GLFWvidmodeWayland _GLFWvidmodeWayland; typedef struct _GLFWvidmodeWayland _GLFWvidmodeWayland;
// Wayland-specific per-window data // Wayland-specific per-window data
// //
typedef struct _GLFWwindowWayland typedef struct _GLFWwindowWayland
@ -105,7 +104,6 @@ typedef struct _GLFWwindowWayland
} pointerLock; } pointerLock;
} _GLFWwindowWayland; } _GLFWwindowWayland;
// Wayland-specific global data // Wayland-specific global data
// //
typedef struct _GLFWlibraryWayland typedef struct _GLFWlibraryWayland
@ -149,7 +147,6 @@ typedef struct _GLFWlibraryWayland
} _GLFWlibraryWayland; } _GLFWlibraryWayland;
// Wayland-specific per-monitor data // Wayland-specific per-monitor data
// //
typedef struct _GLFWmonitorWayland typedef struct _GLFWmonitorWayland
@ -166,7 +163,6 @@ typedef struct _GLFWmonitorWayland
int scale; int scale;
} _GLFWmonitorWayland; } _GLFWmonitorWayland;
// Wayland-specific per-cursor data // Wayland-specific per-cursor data
// //
typedef struct _GLFWcursorWayland typedef struct _GLFWcursorWayland

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 Wayland - www.glfw.org // GLFW 3.3 Wayland - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
// //
@ -393,6 +393,8 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (ctxconfig->client != GLFW_NO_API) if (ctxconfig->client != GLFW_NO_API)
{ {
if (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE; return GLFW_FALSE;
} }
@ -435,8 +437,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
_glfwInputWindowFocus(window, GLFW_FALSE); _glfwInputWindowFocus(window, GLFW_FALSE);
} }
if (window->context.client != GLFW_NO_API) if (window->context.destroy)
window->context.destroyContext(window); window->context.destroy(window);
if (window->wl.native) if (window->wl.native)
wl_egl_window_destroy(window->wl.native); wl_egl_window_destroy(window->wl.native);
@ -784,9 +786,9 @@ static void handleRelativeMotion(void* data,
if (window->cursorMode != GLFW_CURSOR_DISABLED) if (window->cursorMode != GLFW_CURSOR_DISABLED)
return; return;
_glfwInputCursorMotion(window, _glfwInputCursorPos(window,
wl_fixed_to_double(dxUnaccel), window->virtualCursorPosX + wl_fixed_to_double(dxUnaccel),
wl_fixed_to_double(dyUnaccel)); window->virtualCursorPosY + wl_fixed_to_double(dyUnaccel));
} }
static const struct zwp_relative_pointer_v1_listener relativePointerListener = { static const struct zwp_relative_pointer_v1_listener relativePointerListener = {

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 X11 - www.glfw.org // GLFW 3.3 X11 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -72,9 +72,8 @@ static int translateKeyCode(int scancode)
default: break; default: break;
} }
// Now try primary keysym for function keys (non-printable keys). These // Now try primary keysym for function keys (non-printable keys)
// should not be layout dependent (i.e. US layout and international // These should not depend on the current keyboard layout
// layouts should give the same result).
keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0); keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
} }
else else
@ -766,13 +765,9 @@ int _glfwPlatformInit(void)
if (!_glfwInitThreadLocalStoragePOSIX()) if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE; return GLFW_FALSE;
if (!_glfwInitGLX())
return GLFW_FALSE;
if (!_glfwInitJoysticksLinux()) if (!_glfwInitJoysticksLinux())
return GLFW_FALSE; return GLFW_FALSE;
_glfwInitEGL();
_glfwInitTimerPOSIX(); _glfwInitTimerPOSIX();
return GLFW_TRUE; return GLFW_TRUE;

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 X11 - www.glfw.org // GLFW 3.3 X11 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 X11 - www.glfw.org // GLFW 3.3 X11 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -118,19 +118,16 @@ typedef struct _GLFWwindowX11
int xpos, ypos; int xpos, ypos;
// The last received cursor position, regardless of source // The last received cursor position, regardless of source
double cursorPosX, cursorPosY; int lastCursorPosX, lastCursorPosY;
// The last position the cursor was warped to by GLFW // The last position the cursor was warped to by GLFW
int warpPosX, warpPosY; int warpCursorPosX, warpCursorPosY;
// The information from the last KeyPress event // The information from the last KeyPress event
struct { unsigned int lastKeyCode;
unsigned int keycode; Time lastKeyTime;
Time time;
} last;
} _GLFWwindowX11; } _GLFWwindowX11;
// X11-specific global data // X11-specific global data
// //
typedef struct _GLFWlibraryX11 typedef struct _GLFWlibraryX11
@ -155,6 +152,10 @@ typedef struct _GLFWlibraryX11
short int publicKeys[256]; short int publicKeys[256];
// GLFW key to X11 keycode LUT // GLFW key to X11 keycode LUT
short int nativeKeys[GLFW_KEY_LAST + 1]; short int nativeKeys[GLFW_KEY_LAST + 1];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// Window manager atoms // Window manager atoms
Atom WM_PROTOCOLS; Atom WM_PROTOCOLS;
@ -255,7 +256,6 @@ typedef struct _GLFWlibraryX11
} _GLFWlibraryX11; } _GLFWlibraryX11;
// X11-specific per-monitor data // X11-specific per-monitor data
// //
typedef struct _GLFWmonitorX11 typedef struct _GLFWmonitorX11
@ -270,7 +270,6 @@ typedef struct _GLFWmonitorX11
} _GLFWmonitorX11; } _GLFWmonitorX11;
// X11-specific per-cursor data // X11-specific per-cursor data
// //
typedef struct _GLFWcursorX11 typedef struct _GLFWcursorX11

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 X11 - www.glfw.org // GLFW 3.3 X11 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -49,15 +49,15 @@
#define Button7 7 #define Button7 7
// Wait for data to arrive // Wait for data to arrive using select
// This avoids blocking other threads via the per-display Xlib lock that also
// covers GLX functions
// //
void selectDisplayConnection(struct timeval* timeout) static GLFWbool waitForEvent(double* timeout)
{ {
fd_set fds; fd_set fds;
int result, count;
const int fd = ConnectionNumber(_glfw.x11.display); const int fd = ConnectionNumber(_glfw.x11.display);
int count = fd + 1;
count = fd + 1;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(fd, &fds); FD_SET(fd, &fds);
@ -67,18 +67,49 @@ void selectDisplayConnection(struct timeval* timeout)
if (fd < _glfw.linux_js.inotify) if (fd < _glfw.linux_js.inotify)
count = _glfw.linux_js.inotify + 1; count = _glfw.linux_js.inotify + 1;
#endif #endif
for (;;)
// NOTE: We use select instead of an X function like XNextEvent, as the
// wait inside those are guarded by the mutex protecting the display
// struct, locking out other threads from using X (including GLX)
// NOTE: Only retry on EINTR if there is no timeout, as select is not
// required to update it for the time elapsed
// TODO: Update timeout value manually
do
{ {
result = select(count, &fds, NULL, NULL, timeout); if (timeout)
{
const long seconds = (long) *timeout;
const long microseconds = (long) ((*timeout - seconds) * 1e6);
struct timeval tv = { seconds, microseconds };
const uint64_t base = _glfwPlatformGetTimerValue();
const int result = select(count, &fds, NULL, NULL, &tv);
const int error = errno;
*timeout -= (_glfwPlatformGetTimerValue() - base) /
(double) _glfwPlatformGetTimerFrequency();
if (result > 0)
return GLFW_TRUE;
if ((result == -1 && error == EINTR) || *timeout <= 0.0)
return GLFW_FALSE;
} }
while (result == -1 && errno == EINTR && timeout == NULL); else if (select(count, &fds, NULL, NULL, NULL) != -1 || errno != EINTR)
return GLFW_TRUE;
}
}
// Waits until a VisibilityNotify event arrives for the specified window or the
// timeout period elapses (ICCCM section 4.2.2)
//
static GLFWbool waitForVisibilityNotify(_GLFWwindow* window)
{
XEvent dummy;
double timeout = 0.1;
while (!XCheckTypedWindowEvent(_glfw.x11.display,
window->x11.handle,
VisibilityNotify,
&dummy))
{
if (!waitForEvent(&timeout))
return GLFW_FALSE;
}
return GLFW_TRUE;
} }
// Returns whether the window is iconified // Returns whether the window is iconified
@ -105,6 +136,15 @@ static int getWindowState(_GLFWwindow* window)
// Returns whether the event is a selection event // Returns whether the event is a selection event
// //
static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)
{
return event->type == SelectionRequest ||
event->type == SelectionNotify ||
event->type == SelectionClear;
}
// Returns whether it is a _NET_FRAME_EXTENTS event for the specified window
//
static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer) static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer)
{ {
_GLFWwindow* window = (_GLFWwindow*) pointer; _GLFWwindow* window = (_GLFWwindow*) pointer;
@ -218,13 +258,17 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
if (window->resizable) if (window->resizable)
{ {
if (window->minwidth != GLFW_DONT_CARE && if (window->minwidth != GLFW_DONT_CARE &&
window->minheight != GLFW_DONT_CARE && window->minheight != GLFW_DONT_CARE)
window->maxwidth != GLFW_DONT_CARE &&
window->maxheight != GLFW_DONT_CARE)
{ {
hints->flags |= (PMinSize | PMaxSize); hints->flags |= PMinSize;
hints->min_width = window->minwidth; hints->min_width = window->minwidth;
hints->min_height = window->minheight; hints->min_height = window->minheight;
}
if (window->maxwidth != GLFW_DONT_CARE &&
window->maxheight != GLFW_DONT_CARE)
{
hints->flags |= PMaxSize;
hints->max_width = window->maxwidth; hints->max_width = window->maxwidth;
hints->max_height = window->maxheight; hints->max_height = window->maxheight;
} }
@ -245,6 +289,9 @@ static void updateNormalHints(_GLFWwindow* window, int width, int height)
} }
} }
hints->flags |= PWinGravity;
hints->win_gravity = StaticGravity;
XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
XFree(hints); XFree(hints);
} }
@ -387,16 +434,40 @@ static char** parseUriList(char* text, int* count)
return paths; return paths;
} }
// Centers the cursor over the window client area
//
static void centerCursor(_GLFWwindow* window)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
}
// Updates the cursor image according to its cursor mode
//
static void updateCursorImage(_GLFWwindow* window)
{
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
if (window->cursor)
{
XDefineCursor(_glfw.x11.display, window->x11.handle,
window->cursor->x11.handle);
}
else
XUndefineCursor(_glfw.x11.display, window->x11.handle);
}
else
XDefineCursor(_glfw.x11.display, window->x11.handle, _glfw.x11.cursor);
}
// Create the X11 window (and its colormap) // Create the X11 window (and its colormap)
// //
static GLFWbool createWindow(_GLFWwindow* window, static GLFWbool createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig, const _GLFWwndconfig* wndconfig,
Visual* visual, int depth) Visual* visual, int depth)
{ {
// Every window needs a colormap // Create a colormap based on the visual used by the current context
// Create one based on the visual used by the current context
// TODO: Decouple this from context creation
window->x11.colormap = XCreateColormap(_glfw.x11.display, window->x11.colormap = XCreateColormap(_glfw.x11.display,
_glfw.x11.root, _glfw.x11.root,
visual, visual,
@ -584,15 +655,6 @@ static GLFWbool createWindow(_GLFWwindow* window,
return GLFW_TRUE; return GLFW_TRUE;
} }
// Returns whether the event is a selection event
//
static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)
{
return event->type == SelectionRequest ||
event->type == SelectionNotify ||
event->type == SelectionClear;
}
// Set the specified property to the selection converted to the requested target // Set the specified property to the selection converted to the requested target
// //
static Atom writeTargetToProperty(const XSelectionRequestEvent* request) static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
@ -791,7 +853,7 @@ static void pushSelectionToManager(_GLFWwindow* window)
} }
} }
selectDisplayConnection(NULL); waitForEvent(NULL);
} }
} }
@ -933,15 +995,15 @@ static void processEvent(XEvent *event)
// HACK: Ignore duplicate key press events generated by ibus // HACK: Ignore duplicate key press events generated by ibus
// Corresponding release events are filtered out by the // Corresponding release events are filtered out by the
// GLFW key repeat logic // GLFW key repeat logic
if (window->x11.last.keycode != keycode || if (window->x11.lastKeyCode != keycode ||
window->x11.last.time != event->xkey.time) window->x11.lastKeyTime != event->xkey.time)
{ {
if (keycode) if (keycode)
_glfwInputKey(window, key, keycode, GLFW_PRESS, mods); _glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
} }
window->x11.last.keycode = keycode; window->x11.lastKeyCode = keycode;
window->x11.last.time = event->xkey.time; window->x11.lastKeyTime = event->xkey.time;
if (!filtered) if (!filtered)
{ {
@ -1152,25 +1214,28 @@ static void processEvent(XEvent *event)
const int x = event->xmotion.x; const int x = event->xmotion.x;
const int y = event->xmotion.y; const int y = event->xmotion.y;
if (x != window->x11.warpPosX || y != window->x11.warpPosY) if (x != window->x11.warpCursorPosX || y != window->x11.warpCursorPosY)
{ {
// The cursor was moved by something other than GLFW // The cursor was moved by something other than GLFW
if (window->cursorMode == GLFW_CURSOR_DISABLED) if (window->cursorMode == GLFW_CURSOR_DISABLED)
{ {
if (_glfw.cursorWindow != window) if (_glfw.x11.disabledCursorWindow != window)
return; return;
_glfwInputCursorMotion(window, const int dx = x - window->x11.lastCursorPosX;
x - window->x11.cursorPosX, const int dy = y - window->x11.lastCursorPosY;
y - window->x11.cursorPosY);
_glfwInputCursorPos(window,
window->virtualCursorPosX + dx,
window->virtualCursorPosY + dy);
} }
else else
_glfwInputCursorMotion(window, x, y); _glfwInputCursorPos(window, x, y);
} }
window->x11.cursorPosX = x; window->x11.lastCursorPosX = x;
window->x11.cursorPosY = y; window->x11.lastCursorPosY = y;
return; return;
} }
@ -1268,7 +1333,7 @@ static void processEvent(XEvent *event)
int x, y; int x, y;
_glfwPlatformGetWindowPos(window, &x, &y); _glfwPlatformGetWindowPos(window, &x, &y);
_glfwInputCursorMotion(window, absX - x, absY - y); _glfwInputCursorPos(window, absX - x, absY - y);
// Reply that we are ready to copy the dragged data // Reply that we are ready to copy the dragged data
XEvent reply; XEvent reply;
@ -1340,6 +1405,9 @@ static void processEvent(XEvent *event)
case FocusIn: case FocusIn:
{ {
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
if (event->xfocus.mode == NotifyGrab || if (event->xfocus.mode == NotifyGrab ||
event->xfocus.mode == NotifyUngrab) event->xfocus.mode == NotifyUngrab)
{ {
@ -1351,15 +1419,15 @@ static void processEvent(XEvent *event)
if (window->x11.ic) if (window->x11.ic)
XSetICFocus(window->x11.ic); XSetICFocus(window->x11.ic);
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
_glfwInputWindowFocus(window, GLFW_TRUE); _glfwInputWindowFocus(window, GLFW_TRUE);
return; return;
} }
case FocusOut: case FocusOut:
{ {
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
if (event->xfocus.mode == NotifyGrab || if (event->xfocus.mode == NotifyGrab ||
event->xfocus.mode == NotifyUngrab) event->xfocus.mode == NotifyUngrab)
{ {
@ -1371,9 +1439,6 @@ static void processEvent(XEvent *event)
if (window->x11.ic) if (window->x11.ic)
XUnsetICFocus(window->x11.ic); XUnsetICFocus(window->x11.ic);
if (window->cursorMode == GLFW_CURSOR_DISABLED)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
if (window->monitor && window->autoIconify) if (window->monitor && window->autoIconify)
_glfwPlatformIconifyWindow(window); _glfwPlatformIconifyWindow(window);
@ -1487,17 +1552,21 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
{ {
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API) if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{ {
if (!_glfwInitGLX())
return GLFW_FALSE;
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth)) if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE; return GLFW_FALSE;
} }
else else
{ {
if (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth)) if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE; return GLFW_FALSE;
} }
} }
if (!createWindow(window, wndconfig, visual, depth)) if (!createNativeWindow(window, wndconfig, visual, depth))
return GLFW_FALSE; return GLFW_FALSE;
if (ctxconfig->client != GLFW_NO_API) if (ctxconfig->client != GLFW_NO_API)
@ -1520,13 +1589,19 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
updateWindowMode(window); updateWindowMode(window);
if (!acquireMonitor(window)) if (!acquireMonitor(window))
return GLFW_FALSE; return GLFW_FALSE;
centerCursor(window);
} }
XFlush(_glfw.x11.display);
return GLFW_TRUE; return GLFW_TRUE;
} }
void _glfwPlatformDestroyWindow(_GLFWwindow* window) void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{ {
if (_glfw.x11.disabledCursorWindow == window)
_glfw.x11.disabledCursorWindow = NULL;
if (window->monitor) if (window->monitor)
releaseMonitor(window); releaseMonitor(window);
@ -1536,8 +1611,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
window->x11.ic = NULL; window->x11.ic = NULL;
} }
if (window->context.client != GLFW_NO_API) if (window->context.destroy)
window->context.destroyContext(window); window->context.destroy(window);
if (window->x11.handle) if (window->x11.handle)
{ {
@ -1640,21 +1715,11 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
{ {
Window child; Window dummy;
int x, y; int x, y;
XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root, XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root,
0, 0, &x, &y, &child); 0, 0, &x, &y, &dummy);
if (child)
{
int left, top;
XTranslateCoordinates(_glfw.x11.display, window->x11.handle, child,
0, 0, &left, &top, &child);
x -= left;
y -= top;
}
if (xpos) if (xpos)
*xpos = x; *xpos = x;
@ -1753,19 +1818,16 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
if (!_glfwPlatformWindowVisible(window) && if (!_glfwPlatformWindowVisible(window) &&
_glfw.x11.NET_REQUEST_FRAME_EXTENTS) _glfw.x11.NET_REQUEST_FRAME_EXTENTS)
{ {
uint64_t base;
XEvent event; XEvent event;
double timeout = 0.5;
// Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to // Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to
// function before the window is mapped // function before the window is mapped
sendEventToWM(window, _glfw.x11.NET_REQUEST_FRAME_EXTENTS, sendEventToWM(window, _glfw.x11.NET_REQUEST_FRAME_EXTENTS,
0, 0, 0, 0, 0); 0, 0, 0, 0, 0);
base = _glfwPlatformGetTimerValue(); // HACK: Use a timeout because earlier versions of some window managers
// (at least Unity, Fluxbox and Xfwm) failed to send the reply
// HACK: Poll with timeout for the required reply instead of blocking
// This is done because some window managers (at least Unity,
// Fluxbox and Xfwm) failed to send the required reply
// They have been fixed but broken versions are still in the wild // They have been fixed but broken versions are still in the wild
// If you are affected by this and your window manager is NOT // If you are affected by this and your window manager is NOT
// listed above, PLEASE report it to their and our issue trackers // listed above, PLEASE report it to their and our issue trackers
@ -1774,21 +1836,12 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
isFrameExtentsEvent, isFrameExtentsEvent,
(XPointer) window)) (XPointer) window))
{ {
double remaining; if (!waitForEvent(&timeout))
struct timeval timeout;
remaining = 0.5 - (_glfwPlatformGetTimerValue() - base) /
(double) _glfwPlatformGetTimerFrequency();
if (remaining <= 0.0)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue"); "X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");
return; return;
} }
timeout.tv_sec = 0;
timeout.tv_usec = (long) (remaining * 1e6);
selectDisplayConnection(&timeout);
} }
} }
@ -1838,8 +1891,11 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window)
} }
if (_glfwPlatformWindowIconified(window)) if (_glfwPlatformWindowIconified(window))
{
XMapWindow(_glfw.x11.display, window->x11.handle); XMapWindow(_glfw.x11.display, window->x11.handle);
else waitForVisibilityNotify(window);
}
else if (_glfwPlatformWindowVisible(window))
{ {
if (_glfw.x11.NET_WM_STATE && if (_glfw.x11.NET_WM_STATE &&
_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT && _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
@ -1875,8 +1931,11 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
void _glfwPlatformShowWindow(_GLFWwindow* window) void _glfwPlatformShowWindow(_GLFWwindow* window)
{ {
if (_glfwPlatformWindowVisible(window))
return;
XMapWindow(_glfw.x11.display, window->x11.handle); XMapWindow(_glfw.x11.display, window->x11.handle);
XFlush(_glfw.x11.display); waitForVisibilityNotify(window);
} }
void _glfwPlatformHideWindow(_GLFWwindow* window) void _glfwPlatformHideWindow(_GLFWwindow* window)
@ -1931,6 +1990,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
if (window->monitor) if (window->monitor)
{ {
XMapRaised(_glfw.x11.display, window->x11.handle); XMapRaised(_glfw.x11.display, window->x11.handle);
if (waitForVisibilityNotify(window))
acquireMonitor(window); acquireMonitor(window);
} }
else else
@ -2000,40 +2060,26 @@ void _glfwPlatformPollEvents(void)
processEvent(&event); processEvent(&event);
} }
_GLFWwindow* window = _glfw.cursorWindow; if (_glfw.x11.disabledCursorWindow)
if (window && window->cursorMode == GLFW_CURSOR_DISABLED) centerCursor(_glfw.x11.disabledCursorWindow);
{
int width, height; XFlush(_glfw.x11.display);
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
}
} }
void _glfwPlatformWaitEvents(void) void _glfwPlatformWaitEvents(void)
{ {
while (!XPending(_glfw.x11.display)) while (!XPending(_glfw.x11.display))
selectDisplayConnection(NULL); waitForEvent(NULL);
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
} }
void _glfwPlatformWaitEventsTimeout(double timeout) void _glfwPlatformWaitEventsTimeout(double timeout)
{ {
const double deadline = timeout + _glfwPlatformGetTimerValue() /
(double) _glfwPlatformGetTimerFrequency();
while (!XPending(_glfw.x11.display)) while (!XPending(_glfw.x11.display))
{ {
const double remaining = deadline - _glfwPlatformGetTimerValue() / if (!waitForEvent(&timeout))
(double) _glfwPlatformGetTimerFrequency(); break;
if (remaining <= 0.0)
return;
const long seconds = (long) remaining;
const long microseconds = (long) ((remaining - seconds) * 1e6);
struct timeval tv = { seconds, microseconds };
selectDisplayConnection(&tv);
} }
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
@ -2074,42 +2120,39 @@ void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{ {
// Store the new position so it can be recognized later // Store the new position so it can be recognized later
window->x11.warpPosX = (int) x; window->x11.warpCursorPosX = (int) x;
window->x11.warpPosY = (int) y; window->x11.warpCursorPosY = (int) y;
XWarpPointer(_glfw.x11.display, None, window->x11.handle, XWarpPointer(_glfw.x11.display, None, window->x11.handle,
0,0,0,0, (int) x, (int) y); 0,0,0,0, (int) x, (int) y);
XFlush(_glfw.x11.display);
} }
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{ {
if (mode == GLFW_CURSOR_DISABLED) if (mode == GLFW_CURSOR_DISABLED)
{ {
_glfw.x11.disabledCursorWindow = window;
_glfwPlatformGetCursorPos(window,
&_glfw.x11.restoreCursorPosX,
&_glfw.x11.restoreCursorPosY);
centerCursor(window);
XGrabPointer(_glfw.x11.display, window->x11.handle, True, XGrabPointer(_glfw.x11.display, window->x11.handle, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask, ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync, GrabModeAsync, GrabModeAsync,
window->x11.handle, _glfw.x11.cursor, CurrentTime); window->x11.handle, _glfw.x11.cursor, CurrentTime);
} }
else else if (_glfw.x11.disabledCursorWindow == window)
{ {
_glfw.x11.disabledCursorWindow = NULL;
XUngrabPointer(_glfw.x11.display, CurrentTime); XUngrabPointer(_glfw.x11.display, CurrentTime);
_glfwPlatformSetCursorPos(window,
_glfw.x11.restoreCursorPosX,
_glfw.x11.restoreCursorPosY);
}
if (mode == GLFW_CURSOR_NORMAL) updateCursorImage(window);
{ XFlush(_glfw.x11.display);
if (window->cursor)
{
XDefineCursor(_glfw.x11.display, window->x11.handle,
window->cursor->x11.handle);
}
else
XUndefineCursor(_glfw.x11.display, window->x11.handle);
}
else
{
XDefineCursor(_glfw.x11.display, window->x11.handle,
_glfw.x11.cursor);
}
}
} }
const char* _glfwPlatformGetKeyName(int key, int scancode) const char* _glfwPlatformGetKeyName(int key, int scancode)
@ -2175,11 +2218,7 @@ void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{ {
if (window->cursorMode == GLFW_CURSOR_NORMAL) if (window->cursorMode == GLFW_CURSOR_NORMAL)
{ {
if (cursor) updateCursorImage(window);
XDefineCursor(_glfw.x11.display, window->x11.handle, cursor->x11.handle);
else
XUndefineCursor(_glfw.x11.display, window->x11.handle);
XFlush(_glfw.x11.display); XFlush(_glfw.x11.display);
} }
} }
@ -2231,10 +2270,8 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
_glfw.x11.GLFW_SELECTION, _glfw.x11.GLFW_SELECTION,
window->x11.handle, CurrentTime); window->x11.handle, CurrentTime);
// XCheckTypedEvent is used instead of XIfEvent in order not to lock
// other threads out from the display during the entire wait period
while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event)) while (!XCheckTypedEvent(_glfw.x11.display, SelectionNotify, &event))
selectDisplayConnection(NULL); waitForEvent(NULL);
if (event.xselection.property == None) if (event.xselection.property == None)
continue; continue;

View File

@ -1,8 +1,8 @@
//======================================================================== //========================================================================
// GLFW 3.2 X11 - www.glfw.org // GLFW 3.3 X11 - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard // Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) 2006-2016 Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,5 +1,5 @@
//======================================================================== //========================================================================
// GLFW 3.2 Linux - www.glfw.org // GLFW 3.3 Linux - www.glfw.org
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com> // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
// //

View File

@ -48,7 +48,9 @@ set(CONSOLE_BINARIES clipboard events msaa gamma glfwinfo
if (VULKAN_FOUND) if (VULKAN_FOUND)
add_executable(vulkan WIN32 vulkan.c ${ICON}) add_executable(vulkan WIN32 vulkan.c ${ICON})
target_include_directories(vulkan PRIVATE "${VULKAN_INCLUDE_DIR}") target_include_directories(vulkan PRIVATE "${VULKAN_INCLUDE_DIR}")
if (NOT GLFW_VULKAN_STATIC)
target_link_libraries(vulkan "${VULKAN_LIBRARY}") target_link_libraries(vulkan "${VULKAN_LIBRARY}")
endif()
list(APPEND WINDOWS_BINARIES vulkan) list(APPEND WINDOWS_BINARIES vulkan)
endif() endif()

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Clipboard test program // Clipboard test program
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Cursor & input mode tests // Cursor & input mode tests
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -47,7 +47,7 @@
static double cursor_x; static double cursor_x;
static double cursor_y; static double cursor_y;
static int swap_interval = 1; static int swap_interval = 1;
static int wait_events = GLFW_FALSE; static int wait_events = GLFW_TRUE;
static int animate_cursor = GLFW_FALSE; static int animate_cursor = GLFW_FALSE;
static int track_cursor = GLFW_FALSE; static int track_cursor = GLFW_FALSE;
static GLFWcursor* standard_cursors[6]; static GLFWcursor* standard_cursors[6];

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Empty event test // Empty event test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Event linter (event spewer) // Event linter (event spewer)
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Gamma correction test program // Gamma correction test program
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -43,6 +43,9 @@ static GLfloat gamma_value = 1.0f;
static void usage(void) static void usage(void)
{ {
printf("Usage: gamma [-h] [-f]\n"); printf("Usage: gamma [-h] [-f]\n");
printf("Options:\n");
printf(" -f create full screen window\n");
printf(" -h show this help\n");
} }
static void set_gamma(GLFWwindow* window, float value) static void set_gamma(GLFWwindow* window, float value)
@ -75,6 +78,7 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
} }
case GLFW_KEY_KP_ADD: case GLFW_KEY_KP_ADD:
case GLFW_KEY_UP:
case GLFW_KEY_Q: case GLFW_KEY_Q:
{ {
set_gamma(window, gamma_value + STEP_SIZE); set_gamma(window, gamma_value + STEP_SIZE);
@ -82,6 +86,7 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
} }
case GLFW_KEY_KP_SUBTRACT: case GLFW_KEY_KP_SUBTRACT:
case GLFW_KEY_DOWN:
case GLFW_KEY_W: case GLFW_KEY_W:
{ {
if (gamma_value - STEP_SIZE > 0.f) if (gamma_value - STEP_SIZE > 0.f)

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Context creation and information tool // Context creation and information tool
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -357,7 +357,7 @@ static void print_version(void)
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int ch, client, context, major, minor, revision, profile; int ch, client, major, minor, revision, profile;
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits; GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE; int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE;
GLenum error; GLenum error;
@ -412,7 +412,7 @@ int main(int argc, char** argv)
if (!glfwInit()) if (!glfwInit())
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
while ((ch = getopt_long(argc, argv, "a:b:dfhlm:n:p:s:v", options, NULL)) != -1) while ((ch = getopt_long(argc, argv, "a:b:c:dfhlm:n:p:s:v", options, NULL)) != -1)
{ {
switch (ch) switch (ch)
{ {
@ -636,7 +636,6 @@ int main(int argc, char** argv)
// Report client API version // Report client API version
client = glfwGetWindowAttrib(window, GLFW_CLIENT_API); client = glfwGetWindowAttrib(window, GLFW_CLIENT_API);
context = glfwGetWindowAttrib(window, GLFW_CONTEXT_CREATION_API);
major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR); major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR); minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION); revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Window icon test program // Window icon test program
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Iconify/restore test program // Iconify/restore test program
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Joystick input test // Joystick input test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Monitor information tool // Monitor information tool
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Multisample anti-aliasing test // Multisample anti-aliasing test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Window re-opener (open/close stress test) // Window re-opener (open/close stress test)
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Context sharing test program // Context sharing test program
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Vsync enabling test // Vsync enabling test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages
@ -43,7 +43,7 @@ static double frame_rate;
static void usage(void) static void usage(void)
{ {
printf("Usage: iconify [-h] [-f]\n"); printf("Usage: tearing [-h] [-f]\n");
printf("Options:\n"); printf("Options:\n");
printf(" -f create full screen window\n"); printf(" -f create full screen window\n");
printf(" -h show this help\n"); printf(" -h show this help\n");

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Multi-threading test // Multi-threading test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Event wait timeout test // Event wait timeout test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// UTF-8 window title test // UTF-8 window title test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages

View File

@ -1,6 +1,6 @@
//======================================================================== //========================================================================
// Simple multi-window test // Simple multi-window test
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org> // Copyright (c) Camilla Berglund <elmindreda@glfw.org>
// //
// This software is provided 'as-is', without any express or implied // This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages // warranty. In no event will the authors be held liable for any damages