mirror of
https://github.com/glfw/glfw.git
synced 2026-09-24 01:28:58 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 70297aeb49 | |||
| 8eb2345347 | |||
| 97b652c584 |
+3
-4
@@ -4,7 +4,6 @@ branches:
|
|||||||
- master
|
- master
|
||||||
skip_tags: true
|
skip_tags: true
|
||||||
environment:
|
environment:
|
||||||
CFLAGS: /WX
|
|
||||||
matrix:
|
matrix:
|
||||||
- BUILD_SHARED_LIBS: ON
|
- BUILD_SHARED_LIBS: ON
|
||||||
- BUILD_SHARED_LIBS: OFF
|
- BUILD_SHARED_LIBS: OFF
|
||||||
@@ -13,11 +12,11 @@ matrix:
|
|||||||
build_script:
|
build_script:
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% ..
|
- cmake -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% ..
|
||||||
- cmake --build .
|
- cmake --build .
|
||||||
notifications:
|
notifications:
|
||||||
- provider: Email
|
- provider: Email
|
||||||
to:
|
to:
|
||||||
- ci@glfw.org
|
- ci@glfw.org
|
||||||
on_build_failure: true
|
- on_build_failure: true
|
||||||
on_build_success: false
|
- on_build_success: false
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
*.m linguist-language=Objective-C
|
|
||||||
+8
-53
@@ -8,7 +8,7 @@
|
|||||||
- [Reporting a segfault or other crash bug](#reporting-a-segfault-or-other-crash-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 context creation bug](#reporting-a-context-creation-bug)
|
||||||
- [Reporting a monitor or video mode bug](#reporting-a-monitor-or-video-mode-bug)
|
- [Reporting a monitor or video mode bug](#reporting-a-monitor-or-video-mode-bug)
|
||||||
- [Reporting a window, input or event bug](#reporting-a-window-input-or-event-bug)
|
- [Reporting an input or event bug](#reporting-an-input-or-event-bug)
|
||||||
- [Reporting some other library bug](#reporting-some-other-library-bug)
|
- [Reporting some other library bug](#reporting-some-other-library-bug)
|
||||||
- [Reporting a documentation bug](#reporting-a-documentation-bug)
|
- [Reporting a documentation bug](#reporting-a-documentation-bug)
|
||||||
- [Reporting a website bug](#reporting-a-website-bug)
|
- [Reporting a website bug](#reporting-a-website-bug)
|
||||||
@@ -42,36 +42,15 @@ 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.
|
||||||
|
|
||||||
For bugs where it makes sense, a short, self contained example is absolutely
|
For bugs where it makes sense, a [Short, Self Contained, Correct (Compilable),
|
||||||
invaluable. Just put it inline in the body text. Note that if the bug is
|
Example](http://www.sscce.org/) is absolutely invaluable. Just put it inline in
|
||||||
reproducible with one of the test programs that come with GLFW, just mention
|
the body text. Note that if the bug is reproducible with one of the test
|
||||||
that instead.
|
programs that come with GLFW, just mention that instead.
|
||||||
|
|
||||||
__Don't worry about adding too much information__. Unimportant information can
|
__Don't worry about adding too much information__. Unimportant information can
|
||||||
be abbreviated or removed later, but missing information can stall bug fixing,
|
be abbreviated or removed later, but missing information can stall bug fixing,
|
||||||
especially when your schedule doesn't align with that of the maintainer.
|
especially when your schedule doesn't align with that of the maintainer.
|
||||||
|
|
||||||
__Please provide text as text, not as images__. This includes code, error
|
|
||||||
messages and any other text. Text in images cannot be found by other users
|
|
||||||
searching for the same problem and may have to be re-typed by maintainers when
|
|
||||||
debugging.
|
|
||||||
|
|
||||||
You don't need to manually indent your code or other text to quote it with
|
|
||||||
GitHub Markdown; just surround it with triple backticks:
|
|
||||||
|
|
||||||
```
|
|
||||||
Some quoted text.
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also add syntax highlighting by appending the common file extension:
|
|
||||||
|
|
||||||
```c
|
|
||||||
int five(void)
|
|
||||||
{
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
There are issue labels for both platforms and GPU manufacturers, so there is no
|
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
|
need to mention these in the subject line. If you do, it will be removed when
|
||||||
the issue is labeled.
|
the issue is labeled.
|
||||||
@@ -160,9 +139,6 @@ Always include the __operating system name and version__ (e.g. `Windows
|
|||||||
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
||||||
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
||||||
|
|
||||||
If you are running your program in a virtual machine, please mention this and
|
|
||||||
include the __VM name and version__ (e.g. `VirtualBox 5.1`).
|
|
||||||
|
|
||||||
Please also include the __GLFW version string__ (`3.2.0 X11 EGL clock_gettime
|
Please also include the __GLFW version string__ (`3.2.0 X11 EGL clock_gettime
|
||||||
/dev/js`), as described
|
/dev/js`), as described
|
||||||
[here](http://www.glfw.org/docs/latest/intro.html#intro_version_string), the
|
[here](http://www.glfw.org/docs/latest/intro.html#intro_version_string), the
|
||||||
@@ -202,9 +178,6 @@ Always include the __operating system name and version__ (e.g. `Windows
|
|||||||
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
||||||
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
||||||
|
|
||||||
If you are running your program in a virtual machine, please mention this and
|
|
||||||
include the __VM name and version__ (e.g. `VirtualBox 5.1`).
|
|
||||||
|
|
||||||
Please also include any __error messages__ provided to your application via the
|
Please also include any __error messages__ provided to your application via the
|
||||||
[error
|
[error
|
||||||
callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
|
callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
|
||||||
@@ -222,12 +195,12 @@ monitors output:
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Reporting a window, input or event bug
|
### Reporting an input or event bug
|
||||||
|
|
||||||
__Note:__ The exact ordering of related window events will sometimes differ.
|
__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
|
__Note:__ Window moving and resizing (by the user) will block the main thread on some
|
||||||
some platforms. This is not a bug. Set a [refresh
|
platforms. This is not a bug. Set a [refresh
|
||||||
callback](http://www.glfw.org/docs/latest/window.html#window_refresh) if you
|
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.
|
want to keep the window contents updated during a move or size operation.
|
||||||
|
|
||||||
@@ -242,20 +215,12 @@ Always include the __operating system name and version__ (e.g. `Windows
|
|||||||
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
include the __GLFW release version__ (e.g. `3.1.2`), otherwise include the
|
||||||
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
__GLFW commit ID__ (e.g. `3795d78b14ef06008889cc422a1fb8d642597751`) from Git.
|
||||||
|
|
||||||
If you are running your program in a virtual machine, please mention this and
|
|
||||||
include the __VM name and version__ (e.g. `VirtualBox 5.1`).
|
|
||||||
|
|
||||||
Please also include any __error messages__ provided to your application via the
|
Please also include any __error messages__ provided to your application via the
|
||||||
[error
|
[error
|
||||||
callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
|
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
|
if relevant, the __output of `events`__ when reporting this kind of bug. If
|
||||||
this tool doesn't run on the machine, mention this instead.
|
this tool doesn't run on the machine, mention this instead.
|
||||||
|
|
||||||
__X11:__ If possible, please include what desktop environment (e.g. GNOME,
|
|
||||||
Unity, KDE) and/or window manager (e.g. Openbox, dwm, Window Maker) you are
|
|
||||||
running. If the bug is related to keyboard input, please include any input
|
|
||||||
method (e.g. ibus, SCIM) you are using.
|
|
||||||
|
|
||||||
|
|
||||||
#### Quick template
|
#### Quick template
|
||||||
|
|
||||||
@@ -336,9 +301,6 @@ other bugs and features to work on.
|
|||||||
If the patch fixes a bug introduced after the last release, it should not get
|
If the patch fixes a bug introduced after the last release, it should not get
|
||||||
a change log entry.
|
a change log entry.
|
||||||
|
|
||||||
If you haven't already, read the excellent article [How to Write a Git Commit
|
|
||||||
Message](https://chris.beams.io/posts/git-commit/).
|
|
||||||
|
|
||||||
|
|
||||||
## Contributing a feature
|
## Contributing a feature
|
||||||
|
|
||||||
@@ -347,10 +309,6 @@ 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
|
what license. Even code using the same license as GLFW may not be copied
|
||||||
without attribution.
|
without attribution.
|
||||||
|
|
||||||
__Note:__ If you haven't already implemented the feature, check first if there
|
|
||||||
already is an open issue for it and if it's already being developed in an
|
|
||||||
[experimental branch](https://github.com/glfw/glfw/branches/all).
|
|
||||||
|
|
||||||
__There is no preferred patch size__. A one character change is just as welcome
|
__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
|
as one adding a thousand line one, if that is the appropriate size for the
|
||||||
feature.
|
feature.
|
||||||
@@ -376,9 +334,6 @@ 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
|
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`.
|
the extension is missing documented in `docs/compat.dox`.
|
||||||
|
|
||||||
If you haven't already, read the excellent article [How to Write a Git Commit
|
|
||||||
Message](https://chris.beams.io/posts/git-commit/).
|
|
||||||
|
|
||||||
Features will not be rejected because they don't include all the above parts,
|
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
|
but please keep in mind that maintainer time is finite and that there are many
|
||||||
other features and bugs to work on.
|
other features and bugs to work on.
|
||||||
|
|||||||
+3
-11
@@ -8,27 +8,19 @@ os:
|
|||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
sudo: false
|
sudo: false
|
||||||
dist: trusty
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
- kubuntu-backports
|
- kubuntu-backports
|
||||||
packages:
|
packages:
|
||||||
- cmake
|
- cmake
|
||||||
- libxrandr-dev
|
|
||||||
- libxinerama-dev
|
|
||||||
- libxcursor-dev
|
|
||||||
- libxi-dev
|
|
||||||
env:
|
env:
|
||||||
global:
|
- BUILD_SHARED_LIBS=ON
|
||||||
- CFLAGS=-Werror
|
- BUILD_SHARED_LIBS=OFF
|
||||||
matrix:
|
|
||||||
- BUILD_SHARED_LIBS=ON
|
|
||||||
- BUILD_SHARED_LIBS=OFF
|
|
||||||
script:
|
script:
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} ..
|
- cmake -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} ..
|
||||||
- cmake --build .
|
- cmake --build .
|
||||||
notifications:
|
notifications:
|
||||||
email:
|
email:
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
# Usage:
|
|
||||||
# cmake -P GenerateMappings.cmake <path/to/mappings.h.in> <path/to/mappings.h>
|
|
||||||
|
|
||||||
set(source_url "https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt")
|
|
||||||
set(source_path "${CMAKE_CURRENT_BINARY_DIR}/gamecontrollerdb.txt")
|
|
||||||
set(template_path "${CMAKE_ARGV3}")
|
|
||||||
set(target_path "${CMAKE_ARGV4}")
|
|
||||||
|
|
||||||
if (NOT EXISTS "${template_path}")
|
|
||||||
message(FATAL_ERROR "Failed to find template file ${template_path}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(DOWNLOAD "${source_url}" "${source_path}"
|
|
||||||
STATUS download_status
|
|
||||||
TLS_VERIFY on)
|
|
||||||
|
|
||||||
list(GET download_status 0 status_code)
|
|
||||||
list(GET download_status 1 status_message)
|
|
||||||
|
|
||||||
if (status_code)
|
|
||||||
message(FATAL_ERROR "Failed to download ${source_url}: ${status_message}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(STRINGS "${source_path}" lines)
|
|
||||||
foreach(line ${lines})
|
|
||||||
if ("${line}" MATCHES "^[0-9a-fA-F].*$")
|
|
||||||
set(GLFW_GAMEPAD_MAPPINGS "${GLFW_GAMEPAD_MAPPINGS}\"${line}\\n\"\n")
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
configure_file("${template_path}" "${target_path}" @ONLY NEWLINE_STYLE UNIX)
|
|
||||||
file(REMOVE "${source_path}")
|
|
||||||
|
|
||||||
+27
-24
@@ -1,34 +1,37 @@
|
|||||||
# FindMir
|
# Try to find Mir on a Unix system
|
||||||
# -------
|
|
||||||
# Finds the Mir library
|
|
||||||
#
|
#
|
||||||
# This will will define the following variables::
|
# This will define:
|
||||||
#
|
#
|
||||||
# MIR_FOUND - the system has Mir
|
# MIR_FOUND - System has Mir
|
||||||
# MIR_INCLUDE_DIRS - the Mir include directory
|
# MIR_LIBRARIES - Link these to use Mir
|
||||||
# MIR_LIBRARIES - the Mir libraries
|
# MIR_INCLUDE_DIR - Include directory for Mir
|
||||||
# MIR_DEFINITIONS - the Mir definitions
|
# MIR_DEFINITIONS - Compiler switches required for using Mir
|
||||||
|
|
||||||
|
if (NOT WIN32)
|
||||||
|
|
||||||
find_package (PkgConfig)
|
find_package (PkgConfig)
|
||||||
if(PKG_CONFIG_FOUND)
|
pkg_check_modules (PKG_MIR QUIET mirclient)
|
||||||
pkg_check_modules (PC_MIR mirclient>=0.26.2 QUIET)
|
set(MIR_DEFINITIONS ${PKG_MIR_CFLAGS_OTHER})
|
||||||
|
|
||||||
find_path(MIR_INCLUDE_DIR NAMES mir_toolkit/mir_client_library.h
|
find_path(MIR_INCLUDE_DIR
|
||||||
PATHS ${PC_MIR_INCLUDE_DIRS})
|
NAMES xkbcommon/xkbcommon.h
|
||||||
|
HINTS ${PC_XKBCOMMON_INCLUDE_DIR} ${PC_XKBCOMMON_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
find_library(MIR_LIBRARY NAMES mirclient
|
find_library(MIR_LIBRARY
|
||||||
PATHS ${PC_MIR_LIBRARIES} ${PC_MIR_LIBRARY_DIRS})
|
NAMES mirclient
|
||||||
|
HINTS ${PKG_MIR_LIBRARIES} ${MIR_LIBRARY_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
set (MIR_INCLUDE_DIR ${PKG_MIR_INCLUDE_DIRS})
|
||||||
|
set (MIR_LIBRARIES ${MIR_LIBRARY})
|
||||||
|
|
||||||
include (FindPackageHandleStandardArgs)
|
include (FindPackageHandleStandardArgs)
|
||||||
find_package_handle_standard_args (MIR
|
find_package_handle_standard_args (MIR DEFAULT_MSG
|
||||||
REQUIRED_VARS MIR_LIBRARY MIR_INCLUDE_DIR)
|
MIR_LIBRARIES
|
||||||
|
MIR_INCLUDE_DIR
|
||||||
|
)
|
||||||
|
|
||||||
if (MIR_FOUND)
|
mark_as_advanced (MIR_LIBRARIES MIR_INCLUDE_DIR)
|
||||||
set(MIR_LIBRARIES ${MIR_LIBRARY})
|
|
||||||
set(MIR_INCLUDE_DIRS ${PC_MIR_INCLUDE_DIRS})
|
|
||||||
set(MIR_DEFINITIONS -DHAVE_MIR=1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
mark_as_advanced (MIR_LIBRARY MIR_INCLUDE_DIR)
|
endif ()
|
||||||
endif()
|
|
||||||
|
|||||||
@@ -8,32 +8,25 @@ if (WIN32)
|
|||||||
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
||||||
"$ENV{VULKAN_SDK}/Include"
|
"$ENV{VULKAN_SDK}/Include"
|
||||||
"$ENV{VK_SDK_PATH}/Include")
|
"$ENV{VK_SDK_PATH}/Include")
|
||||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
if (CMAKE_CL_64)
|
||||||
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
|
find_library(VULKAN_LIBRARY NAMES vulkan-1 HINTS
|
||||||
"$ENV{VULKAN_SDK}/Lib"
|
|
||||||
"$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
|
find_library(VULKAN_STATIC_LIBRARY NAMES vkstatic.1 HINTS
|
||||||
"$ENV{VULKAN_SDK}/Lib"
|
|
||||||
"$ENV{VULKAN_SDK}/Bin"
|
"$ENV{VULKAN_SDK}/Bin"
|
||||||
"$ENV{VK_SDK_PATH}/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}/Lib32"
|
|
||||||
"$ENV{VULKAN_SDK}/Bin32"
|
|
||||||
"$ENV{VK_SDK_PATH}/Bin32")
|
|
||||||
find_library(VULKAN_STATIC_LIBRARY NAMES vkstatic.1 HINTS
|
|
||||||
"$ENV{VULKAN_SDK}/Lib32"
|
|
||||||
"$ENV{VULKAN_SDK}/Bin32"
|
"$ENV{VULKAN_SDK}/Bin32"
|
||||||
"$ENV{VK_SDK_PATH}/Bin32")
|
"$ENV{VK_SDK_PATH}/Bin32")
|
||||||
endif()
|
endif()
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
set(CMAKE_FIND_FRAMEWORK NEVER)
|
|
||||||
find_library(VULKAN_LIBRARY MoltenVK)
|
find_library(VULKAN_LIBRARY MoltenVK)
|
||||||
set(CMAKE_FIND_FRAMEWORK ONLY)
|
if (VULKAN_LIBRARY)
|
||||||
find_library(VULKAN_STATIC_LIBRARY MoltenVK)
|
set(VULKAN_STATIC_LIBRARY ${VULKAN_LIBRARY})
|
||||||
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
||||||
"${VULKAN_LIBRARY}/Headers")
|
"${VULKAN_LIBRARY}/Headers")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
|
||||||
"$ENV{VULKAN_SDK}/include")
|
"$ENV{VULKAN_SDK}/include")
|
||||||
|
|||||||
+38
-40
@@ -1,8 +1,8 @@
|
|||||||
cmake_minimum_required(VERSION 2.8.12)
|
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
||||||
|
|
||||||
project(GLFW C)
|
project(GLFW C)
|
||||||
|
|
||||||
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
|
cmake_minimum_required(VERSION 2.8.12)
|
||||||
|
|
||||||
if (NOT CMAKE_VERSION VERSION_LESS "3.0")
|
if (NOT CMAKE_VERSION VERSION_LESS "3.0")
|
||||||
# Until all major package systems have moved to CMake 3,
|
# Until all major package systems have moved to CMake 3,
|
||||||
@@ -10,10 +10,6 @@ if (NOT CMAKE_VERSION VERSION_LESS "3.0")
|
|||||||
cmake_policy(SET CMP0042 OLD)
|
cmake_policy(SET CMP0042 OLD)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT CMAKE_VERSION VERSION_LESS "3.1")
|
|
||||||
cmake_policy(SET CMP0054 NEW)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(GLFW_VERSION_MAJOR "3")
|
set(GLFW_VERSION_MAJOR "3")
|
||||||
set(GLFW_VERSION_MINOR "3")
|
set(GLFW_VERSION_MINOR "3")
|
||||||
set(GLFW_VERSION_PATCH "0")
|
set(GLFW_VERSION_PATCH "0")
|
||||||
@@ -40,10 +36,14 @@ if (WIN32)
|
|||||||
option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF)
|
option(GLFW_USE_HYBRID_HPG "Force use of high-performance GPU on hybrid systems" OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
option(GLFW_USE_CHDIR "Make glfwInit chdir to Contents/Resources" ON)
|
||||||
|
option(GLFW_USE_MENUBAR "Populate the menu bar on first window creation" ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
|
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
|
||||||
option(GLFW_USE_MIR "Use Mir for window creation" OFF)
|
option(GLFW_USE_MIR "Use Mir for window creation" OFF)
|
||||||
option(GLFW_USE_EGLDEVICE "Use EGLDevice for window creation" OFF)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
@@ -164,9 +164,6 @@ elseif (GLFW_USE_MIR)
|
|||||||
elseif (GLFW_USE_OSMESA)
|
elseif (GLFW_USE_OSMESA)
|
||||||
set(_GLFW_OSMESA 1)
|
set(_GLFW_OSMESA 1)
|
||||||
message(STATUS "Using OSMesa for headless context creation")
|
message(STATUS "Using OSMesa for headless context creation")
|
||||||
elseif (GLFW_USE_EGLDEVICE)
|
|
||||||
set(_GLFW_EGLDEVICE 1)
|
|
||||||
message(STATUS "Using EGLDevice for window creation")
|
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
set(_GLFW_WIN32 1)
|
set(_GLFW_WIN32 1)
|
||||||
message(STATUS "Using Win32 for window creation")
|
message(STATUS "Using Win32 for window creation")
|
||||||
@@ -185,7 +182,7 @@ endif()
|
|||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
if (GLFW_VULKAN_STATIC)
|
if (GLFW_VULKAN_STATIC)
|
||||||
if (VULKAN_FOUND AND VULKAN_STATIC_LIBRARY)
|
if (VULKAN_FOUND AND VULKAN_STATIC_LIBRARY)
|
||||||
list(APPEND glfw_LIBRARIES "${VULKAN_STATIC_LIBRARY}" ${GLFW_VULKAN_DEPS})
|
list(APPEND glfw_LIBRARIES ${VULKAN_STATIC_LIBRARY} ${GLFW_VULKAN_DEPS})
|
||||||
if (BUILD_SHARED_LIBS)
|
if (BUILD_SHARED_LIBS)
|
||||||
message(WARNING "Linking Vulkan loader static library into GLFW")
|
message(WARNING "Linking Vulkan loader static library into GLFW")
|
||||||
endif()
|
endif()
|
||||||
@@ -249,28 +246,38 @@ if (_GLFW_X11)
|
|||||||
|
|
||||||
# Check for XRandR (modern resolution switching and gamma control)
|
# Check for XRandR (modern resolution switching and gamma control)
|
||||||
if (NOT X11_Xrandr_FOUND)
|
if (NOT X11_Xrandr_FOUND)
|
||||||
message(FATAL_ERROR "The RandR headers were not found")
|
message(FATAL_ERROR "The RandR library and headers were not found")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}")
|
||||||
|
list(APPEND glfw_LIBRARIES "${X11_Xrandr_LIB}")
|
||||||
|
list(APPEND glfw_PKG_DEPS "xrandr")
|
||||||
|
|
||||||
# Check for Xinerama (legacy multi-monitor support)
|
# Check for Xinerama (legacy multi-monitor support)
|
||||||
if (NOT X11_Xinerama_FOUND)
|
if (NOT X11_Xinerama_FOUND)
|
||||||
message(FATAL_ERROR "The Xinerama headers were not found")
|
message(FATAL_ERROR "The Xinerama library and headers were not found")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
list(APPEND glfw_INCLUDE_DIRS "${X11_Xinerama_INCLUDE_PATH}")
|
||||||
|
list(APPEND glfw_LIBRARIES "${X11_Xinerama_LIB}")
|
||||||
|
list(APPEND glfw_PKG_DEPS "xinerama")
|
||||||
|
|
||||||
# Check for Xkb (X keyboard extension)
|
# Check for Xkb (X keyboard extension)
|
||||||
if (NOT X11_Xkb_FOUND)
|
if (NOT X11_Xkb_FOUND)
|
||||||
message(FATAL_ERROR "The X keyboard extension headers were not found")
|
message(FATAL_ERROR "The X keyboard extension headers were not found")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Check for Xcursor (cursor creation from RGBA images)
|
list(APPEND glfw_INCLUDE_DIR "${X11_Xkb_INCLUDE_PATH}")
|
||||||
|
|
||||||
|
# Check for Xcursor
|
||||||
if (NOT X11_Xcursor_FOUND)
|
if (NOT X11_Xcursor_FOUND)
|
||||||
message(FATAL_ERROR "The Xcursor headers were not found")
|
message(FATAL_ERROR "The Xcursor libraries and headers were not found")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}"
|
list(APPEND glfw_INCLUDE_DIR "${X11_Xcursor_INCLUDE_PATH}")
|
||||||
"${X11_Xinerama_INCLUDE_PATH}"
|
list(APPEND glfw_LIBRARIES "${X11_Xcursor_LIB}")
|
||||||
"${X11_Xkb_INCLUDE_PATH}"
|
list(APPEND glfw_PKG_DEPS "xcursor")
|
||||||
"${X11_Xcursor_INCLUDE_PATH}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
@@ -278,7 +285,7 @@ endif()
|
|||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
if (_GLFW_WAYLAND)
|
if (_GLFW_WAYLAND)
|
||||||
find_package(ECM REQUIRED NO_MODULE)
|
find_package(ECM REQUIRED NO_MODULE)
|
||||||
list(APPEND 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)
|
||||||
@@ -295,23 +302,6 @@ if (_GLFW_WAYLAND)
|
|||||||
list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}")
|
list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
# Use EGLDevice for window creation
|
|
||||||
#--------------------------------------------------------------------
|
|
||||||
if (_GLFW_EGLDEVICE)
|
|
||||||
|
|
||||||
find_path(DRM_INCLUDE_DIR NAMES drm.h PATH_SUFFIXES drm libdrm)
|
|
||||||
if (NOT DRM_INCLUDE_DIR)
|
|
||||||
message(FATAL_ERROR "The libdrm headers were not found")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${DRM_INCLUDE_DIR}")
|
|
||||||
|
|
||||||
list(APPEND glfw_LIBRARIES "-ldrm")
|
|
||||||
list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
# Use Mir for window creation
|
# Use Mir for window creation
|
||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
@@ -319,7 +309,7 @@ if (_GLFW_MIR)
|
|||||||
find_package(Mir REQUIRED)
|
find_package(Mir REQUIRED)
|
||||||
list(APPEND glfw_PKG_DEPS "mirclient")
|
list(APPEND glfw_PKG_DEPS "mirclient")
|
||||||
|
|
||||||
list(APPEND glfw_INCLUDE_DIRS "${MIR_INCLUDE_DIRS}")
|
list(APPEND glfw_INCLUDE_DIRS "${MIR_INCLUDE_DIR}")
|
||||||
list(APPEND glfw_LIBRARIES "${MIR_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
|
list(APPEND glfw_LIBRARIES "${MIR_LIBRARIES}" "${CMAKE_THREAD_LIBS_INIT}")
|
||||||
|
|
||||||
find_package(XKBCommon REQUIRED)
|
find_package(XKBCommon REQUIRED)
|
||||||
@@ -341,6 +331,14 @@ endif()
|
|||||||
#--------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
if (_GLFW_COCOA)
|
if (_GLFW_COCOA)
|
||||||
|
|
||||||
|
if (GLFW_USE_MENUBAR)
|
||||||
|
set(_GLFW_USE_MENUBAR 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (GLFW_USE_CHDIR)
|
||||||
|
set(_GLFW_USE_CHDIR 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
list(APPEND glfw_LIBRARIES
|
list(APPEND glfw_LIBRARIES
|
||||||
"-framework Cocoa"
|
"-framework Cocoa"
|
||||||
"-framework IOKit"
|
"-framework IOKit"
|
||||||
|
|||||||
@@ -10,11 +10,6 @@ GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
|
|||||||
application development. It provides a simple, platform-independent API for
|
application development. It provides a simple, platform-independent API for
|
||||||
creating windows, contexts and surfaces, reading input, handling events, etc.
|
creating windows, contexts and surfaces, reading input, handling events, etc.
|
||||||
|
|
||||||
GLFW natively supports Windows, macOS and Linux and other Unix-like systems.
|
|
||||||
Experimental implementations for the Wayland protocol, the Mir display server
|
|
||||||
and direct rendering via EGLDevice are available but not yet officially
|
|
||||||
supported.
|
|
||||||
|
|
||||||
GLFW is licensed under the [zlib/libpng
|
GLFW is licensed under the [zlib/libpng
|
||||||
license](http://www.glfw.org/license.html).
|
license](http://www.glfw.org/license.html).
|
||||||
|
|
||||||
@@ -28,58 +23,45 @@ The [version history](http://www.glfw.org/changelog.html) lists all user-visible
|
|||||||
changes for every release.
|
changes for every release.
|
||||||
|
|
||||||
This is a development branch for version 3.3, which is _not yet described_.
|
This is a development branch for version 3.3, which is _not yet described_.
|
||||||
Pre-release documentation is available [here](http://www.glfw.org/docs/3.3/).
|
|
||||||
|
|
||||||
The `master` branch is the stable integration branch and _should_ always compile
|
|
||||||
and run on all supported platforms, although details of newly added features may
|
|
||||||
change until they have been included in a release. New features and many bug
|
|
||||||
fixes live in [other branches](https://github.com/glfw/glfw/branches/all) until
|
|
||||||
they are stable enough to merge.
|
|
||||||
|
|
||||||
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 3 useful. If
|
[tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW
|
||||||
you have used GLFW 2 in the past, there is a [transition
|
3 useful. If you have used GLFW 2 in the past, there is a
|
||||||
guide](http://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
|
[transition guide](http://www.glfw.org/docs/latest/moving.html) for moving to
|
||||||
3 API.
|
the GLFW 3 API.
|
||||||
|
|
||||||
|
|
||||||
## Compiling GLFW
|
## Compiling GLFW
|
||||||
|
|
||||||
GLFW itself requires only the headers and libraries for your window system. It
|
GLFW itself requires only the headers and libraries for your window system. It
|
||||||
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL,
|
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
|
||||||
OSMesa) or rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
|
rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
|
||||||
|
|
||||||
GLFW supports compilation on Windows with Visual C++ 2010 and later, MinGW and
|
GLFW supports compilation on Windows with Visual C++ 2010 and later, MinGW and
|
||||||
MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC
|
MinGW-w64, on macOS 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
|
and Clang. It will likely compile in other environments as well, but this is
|
||||||
not regularly tested.
|
not regularly tested.
|
||||||
|
|
||||||
There are [pre-compiled Windows binaries](http://www.glfw.org/download.html)
|
There are also [pre-compiled Windows
|
||||||
available for all supported compilers.
|
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) for
|
See the [compilation guide](http://www.glfw.org/docs/latest/compile.html) in the
|
||||||
more information about how to compile GLFW yourself.
|
documentation for more information.
|
||||||
|
|
||||||
|
|
||||||
## Using GLFW
|
## Using GLFW
|
||||||
|
|
||||||
See the [documentation](http://www.glfw.org/docs/latest/) for tutorials, guides
|
See the [building application guide](http://www.glfw.org/docs/latest/build.html)
|
||||||
and the API reference.
|
guide in the documentation for more information.
|
||||||
|
|
||||||
|
|
||||||
## Contributing to GLFW
|
|
||||||
|
|
||||||
See the [contribution
|
|
||||||
guide](https://github.com/glfw/glfw/blob/master/.github/CONTRIBUTING.md) for
|
|
||||||
more information.
|
|
||||||
|
|
||||||
|
|
||||||
## System requirements
|
## System requirements
|
||||||
|
|
||||||
GLFW supports Windows XP and later and macOS 10.7 and later. Linux and other
|
GLFW supports Windows XP and later, OS X 10.7 Lion and later, and Linux and
|
||||||
Unix-like systems running the X Window System are supported even without
|
other Unix-like systems with the X Window System. Experimental implementations
|
||||||
a desktop environment or modern extensions, although some features require
|
for the Wayland protocol and the Mir display server are available but not yet
|
||||||
a running window or clipboard manager. The OSMesa backend requires Mesa 6.3.
|
officially supported.
|
||||||
|
|
||||||
See the [compatibility guide](http://www.glfw.org/docs/latest/compat.html)
|
See the [compatibility guide](http://www.glfw.org/docs/latest/compat.html)
|
||||||
in the documentation for more information.
|
in the documentation for more information.
|
||||||
@@ -89,12 +71,6 @@ in the documentation for more information.
|
|||||||
|
|
||||||
GLFW itself depends only on the headers and libraries for your window system.
|
GLFW itself depends only on the headers and libraries for your window system.
|
||||||
|
|
||||||
The (experimental) Wayland backend also depends on the `extra-cmake-modules`
|
|
||||||
package, which is used to generated Wayland protocol headers.
|
|
||||||
|
|
||||||
The (experimental) EGLDevice backend also depends on the `libdrm-dev`
|
|
||||||
development package.
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
@@ -111,11 +87,10 @@ located in the `deps/` directory.
|
|||||||
- [Vulkan headers](https://www.khronos.org/registry/vulkan/) for Vulkan tests
|
- [Vulkan headers](https://www.khronos.org/registry/vulkan/) for Vulkan tests
|
||||||
|
|
||||||
The Vulkan example additionally requires the Vulkan SDK to be installed, or it
|
The Vulkan example additionally requires the Vulkan SDK to be installed, or it
|
||||||
will not be included in the build. On macOS you need to provide the path to the
|
will not be included in the build.
|
||||||
MoltenVK SDK manually as it has no standard installation location.
|
|
||||||
|
|
||||||
The documentation is generated with [Doxygen](http://doxygen.org/) if CMake can
|
The documentation is generated with [Doxygen](http://doxygen.org/). If CMake
|
||||||
find that tool.
|
does not find Doxygen, the documentation will not be generated when you build.
|
||||||
|
|
||||||
|
|
||||||
## Reporting bugs
|
## Reporting bugs
|
||||||
@@ -128,99 +103,24 @@ information on what to include when reporting a bug.
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
- Added `glfwGetError` function for querying the last error code and its
|
|
||||||
description (#970)
|
|
||||||
- Added `glfwUpdateGamepadMappings` function for importing gamepad mappings in
|
|
||||||
SDL\_GameControllerDB format (#900)
|
|
||||||
- Added `glfwJoystickIsGamepad` function for querying whether a joystick has
|
|
||||||
a gamepad mapping (#900)
|
|
||||||
- Added `glfwGetJoystickGUID` function for querying the SDL compatible GUID of
|
|
||||||
a joystick (#900)
|
|
||||||
- Added `glfwGetGamepadName` function for querying the name provided by the
|
|
||||||
gamepad mapping (#900)
|
|
||||||
- Added `glfwGetGamepadState` function, `GLFW_GAMEPAD_*` and `GLFWgamepadstate`
|
|
||||||
for retrieving gamepad input state (#900)
|
|
||||||
- Added `glfwRequestWindowAttention` function for requesting attention from the
|
|
||||||
user (#732,#988)
|
|
||||||
- Added `glfwGetKeyScancode` function that allows retrieving platform dependent
|
- Added `glfwGetKeyScancode` function that allows retrieving platform dependent
|
||||||
scancodes for keys (#830)
|
scancodes for keys (#830)
|
||||||
- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
|
- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
|
||||||
receiving window maximization events (#778)
|
receiving window maximization events (#778)
|
||||||
- Added `glfwSetWindowAttrib` function for changing window attributes (#537)
|
- Added `glfwSetWindowAttrib` function for changing window attributes (#537)
|
||||||
- Added `glfwGetJoystickHats` function for querying joystick hats
|
- Added headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#281,#850)
|
||||||
(#889,#906,#934)
|
|
||||||
- Added `glfwInitHint` and `glfwInitHintString` for setting initialization hints
|
|
||||||
- Added `glfwGetX11SelectionString` and `glfwSetX11SelectionString`
|
|
||||||
functions for accessing X11 primary selection (#894,#1056)
|
|
||||||
- Added headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#850)
|
|
||||||
- Added definition of `GLAPIENTRY` to public header
|
- Added definition of `GLAPIENTRY` to public header
|
||||||
- Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering
|
|
||||||
(#749,#842)
|
|
||||||
- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
|
|
||||||
- Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint
|
- Added macOS specific `GLFW_COCOA_RETINA_FRAMEBUFFER` window hint
|
||||||
- Added macOS specific `GLFW_COCOA_FRAME_AUTOSAVE` window hint (#195)
|
|
||||||
- Added macOS specific `GLFW_COCOA_GRAPHICS_SWITCHING` window hint (#377,#935)
|
|
||||||
- Added macOS specific `GLFW_COCOA_CHDIR_RESOURCES` init hint
|
|
||||||
- Added macOS specific `GLFW_COCOA_MENUBAR` init hint
|
|
||||||
- Added X11 specific `GLFW_X11_WM_CLASS_NAME` and `GLFW_X11_WM_CLASS_CLASS` init
|
|
||||||
hints (#893)
|
|
||||||
- Added `GLFW_INCLUDE_ES32` for including the OpenGL ES 3.2 header
|
|
||||||
- Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with
|
|
||||||
[OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
|
|
||||||
- Added `GenerateMappings.cmake` script for updating gamepad mappings
|
|
||||||
- Removed `GLFW_USE_RETINA` compile-time option
|
- Removed `GLFW_USE_RETINA` compile-time option
|
||||||
- Removed `GLFW_USE_CHDIR` compile-time option
|
|
||||||
- Removed `GLFW_USE_MENUBAR` compile-time option
|
|
||||||
- Bugfix: Calling `glfwMaximizeWindow` on a full screen window was not ignored
|
- Bugfix: Calling `glfwMaximizeWindow` on a full screen window was not ignored
|
||||||
- Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding
|
- Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding
|
||||||
OpenGL and OpenGL ES header macros
|
OpenGL and OpenGL ES header macros
|
||||||
- Bugfix: `glfwGetInstanceProcAddress` returned `NULL` for
|
- Bugfix: `glfwGetInstanceProcAddress` returned `NULL` for
|
||||||
`vkGetInstanceProcAddr` when `_GLFW_VULKAN_STATIC` was enabled
|
`vkGetInstanceProcAddr` when `_GLFW_VULKAN_STATIC` was enabled
|
||||||
- Bugfix: Invalid library paths were used in test and example CMake files (#930)
|
|
||||||
- Bugfix: The scancode for synthetic key release events was always zero
|
|
||||||
- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
|
|
||||||
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
|
|
||||||
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
|
|
||||||
- [Win32] Bugfix: Undecorated windows could not be iconified by the user (#861)
|
- [Win32] Bugfix: Undecorated windows could not be iconified by the user (#861)
|
||||||
- [Win32] Bugfix: Deadzone logic could underflow with some controllers (#910)
|
- [Win32] Bugfix: Deadzone logic could underflow with some controllers (#910)
|
||||||
- [Win32] Bugfix: Bitness test in `FindVulkan.cmake` was VS specific (#928)
|
|
||||||
- [Win32] Bugfix: `glfwVulkanSupported` emitted an error on systems with
|
|
||||||
a loader but no ICD (#916)
|
|
||||||
- [Win32] Bugfix: Non-iconified full sreeen windows did not prevent screen
|
|
||||||
blanking or password enabled screensavers (#851)
|
|
||||||
- [Win32] Bugfix: Mouse capture logic lost secondary release messages (#954)
|
|
||||||
- [Win32] Bugfix: The 32-bit Vulkan loader library static was not searched for
|
|
||||||
- [Win32] Bugfix: Vulkan libraries have a new path as of SDK 1.0.42.0 (#956)
|
|
||||||
- [Win32] Bugfix: Monitors with no display devices were not enumerated (#960)
|
|
||||||
- [Win32] Bugfix: Monitor events were not emitted (#784)
|
|
||||||
- [Win32] Bugfix: The Cygwin DLL was installed to the wrong directory (#1035)
|
|
||||||
- [Win32] Bugfix: Normalization of axis data via XInput was incorrect (#1045)
|
|
||||||
- [Win32] Bugfix: `glfw3native.h` would undefine a foreign `APIENTRY` (#1062)
|
|
||||||
- [Win32] Bugfix: Disabled cursor mode prevented use of caption buttons
|
|
||||||
(#650,#1071)
|
|
||||||
- [Win32] Bugfix: Returned key names did not match other platforms (#943)
|
|
||||||
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
|
|
||||||
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
|
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
|
||||||
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
|
- [Cocoa] Added support for Vulkan window surface creation via MoltenVK (#870)
|
||||||
- [X11] Bugfix: Dynamic X11 library loading did not use full sonames (#941)
|
|
||||||
- [X11] Bugfix: Window creation on 64-bit would read past top of stack (#951)
|
|
||||||
- [X11] Bugfix: XDND support had multiple non-conformance issues (#968)
|
|
||||||
- [X11] Bugfix: The RandR monitor path was disabled despite working RandR (#972)
|
|
||||||
- [X11] Bugfix: IM-duplicated key events would leak at low polling rates (#747)
|
|
||||||
- [X11] Bugfix: Gamma ramp setting via RandR did not validate ramp size
|
|
||||||
- [X11] Bugfix: Key name string encoding depended on current locale (#981,#983)
|
|
||||||
- [X11] Bugfix: Incremental reading of selections was not supported (#275)
|
|
||||||
- [X11] Bugfix: Selection I/O reported but did not support `COMPOUND_TEXT`
|
|
||||||
- [X11] Bugfix: Latin-1 text read from selections was not converted to UTF-8
|
|
||||||
- [Linux] Added experimental support for direct rendering via EGLDevice (#786)
|
|
||||||
- [Linux] Moved to evdev for joystick input (#906,#1005)
|
|
||||||
- [Linux] Bugfix: Event processing did not detect joystick disconnection (#932)
|
|
||||||
- [Linux] Bugfix: The joystick device path could be truncated (#1025)
|
|
||||||
- [Linux] Bugfix: `glfwInit` would fail if inotify creation failed (#833)
|
|
||||||
- [Linux] Bugfix: `strdup` was used without any required feature macro (#1055)
|
|
||||||
- [Cocoa] Added support for Vulkan window surface creation via
|
|
||||||
[MoltenVK](https://moltengl.com/moltenvk/) (#870)
|
|
||||||
- [Cocoa] Added support for loading a `MainMenu.nib` when available
|
|
||||||
- [Cocoa] Bugfix: Disabling window aspect ratio would assert (#852)
|
- [Cocoa] Bugfix: Disabling window aspect ratio would assert (#852)
|
||||||
- [Cocoa] Bugfix: Window creation failed to set first responder (#876,#883)
|
- [Cocoa] Bugfix: Window creation failed to set first responder (#876,#883)
|
||||||
- [Cocoa] Bugfix: Removed use of deprecated `CGDisplayIOServicePort` function
|
- [Cocoa] Bugfix: Removed use of deprecated `CGDisplayIOServicePort` function
|
||||||
@@ -228,25 +128,7 @@ information on what to include when reporting a bug.
|
|||||||
- [Cocoa] Bugfix: Disabled use of deprecated `CGDisplayModeCopyPixelEncoding`
|
- [Cocoa] Bugfix: Disabled use of deprecated `CGDisplayModeCopyPixelEncoding`
|
||||||
function on macOS 10.12+
|
function on macOS 10.12+
|
||||||
- [Cocoa] Bugfix: Running in AppSandbox would emit warnings (#816,#882)
|
- [Cocoa] Bugfix: Running in AppSandbox would emit warnings (#816,#882)
|
||||||
- [Cocoa] Bugfix: Windows created after the first were not cascaded (#195)
|
|
||||||
- [Cocoa] Bugfix: Leaving video mode with `glfwSetWindowMonitor` would set
|
|
||||||
incorrect position and size (#748)
|
|
||||||
- [Cocoa] Bugfix: Iconified full screen windows could not be restored (#848)
|
|
||||||
- [Cocoa] Bugfix: Value range was ignored for joystick hats and buttons (#888)
|
|
||||||
- [Cocoa] Bugfix: Full screen framebuffer was incorrectly sized for some video
|
|
||||||
modes (#682)
|
|
||||||
- [Cocoa] Bugfix: A string object for IME was updated non-idiomatically (#1050)
|
|
||||||
- [Cocoa] Bugfix: A hidden or disabled cursor would become visible when a user
|
|
||||||
notification was shown (#971,#1028)
|
|
||||||
- [Cocoa] Bugfix: Some characters did not repeat due to Press and Hold (#1010)
|
|
||||||
- [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts
|
|
||||||
- [WGL] Added support for `WGL_ARB_create_context_no_error`
|
|
||||||
- [GLX] Added support for `GLX_ARB_create_context_no_error`
|
|
||||||
- [GLX] Bugfix: Context creation could segfault if no GLXFBConfigs were
|
|
||||||
available (#1040)
|
|
||||||
- [EGL] Added support for `EGL_KHR_get_all_proc_addresses` (#871)
|
- [EGL] Added support for `EGL_KHR_get_all_proc_addresses` (#871)
|
||||||
- [EGL] Added support for `EGL_KHR_context_flush_control`
|
|
||||||
- [EGL] Bugfix: The test for `EGL_RGB_BUFFER` was invalid
|
|
||||||
|
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
@@ -272,27 +154,19 @@ GLFW exists because people around the world donated their time and lent their
|
|||||||
skills.
|
skills.
|
||||||
|
|
||||||
- Bobyshev Alexander
|
- Bobyshev Alexander
|
||||||
|
- artblanc
|
||||||
|
- arturo
|
||||||
- Matt Arsenault
|
- Matt Arsenault
|
||||||
- David Avedissian
|
|
||||||
- Keith Bauer
|
- Keith Bauer
|
||||||
- John Bartholomew
|
- John Bartholomew
|
||||||
- Niklas Behrens
|
- Niklas Behrens
|
||||||
- Niklas Bergström
|
- Niklas Bergström
|
||||||
- Denis Bernard
|
|
||||||
- Doug Binks
|
- Doug Binks
|
||||||
- blanco
|
- blanco
|
||||||
- Kyle Brenneman
|
- Kyle Brenneman
|
||||||
- Rok Breulj
|
|
||||||
- Martin Capitanio
|
- Martin Capitanio
|
||||||
- David Carlier
|
|
||||||
- Arturo Castro
|
|
||||||
- Chi-kwan Chan
|
- Chi-kwan Chan
|
||||||
- Kamal Chandra
|
|
||||||
- Ian Clarkson
|
|
||||||
- Michał Cichoń
|
|
||||||
- Lambert Clara
|
- Lambert Clara
|
||||||
- Yaron Cohen-Tal
|
|
||||||
- Omar Cornut
|
|
||||||
- Andrew Corrigan
|
- Andrew Corrigan
|
||||||
- Noel Cower
|
- Noel Cower
|
||||||
- Jason Daly
|
- Jason Daly
|
||||||
@@ -304,10 +178,7 @@ skills.
|
|||||||
- Mario Dorn
|
- Mario Dorn
|
||||||
- Jonathan Dummer
|
- Jonathan Dummer
|
||||||
- Ralph Eastwood
|
- Ralph Eastwood
|
||||||
- Fredrik Ehnbom
|
|
||||||
- Robin Eklind
|
|
||||||
- Siavash Eliasi
|
- Siavash Eliasi
|
||||||
- Felipe Ferreira
|
|
||||||
- Michael Fogleman
|
- Michael Fogleman
|
||||||
- Gerald Franz
|
- Gerald Franz
|
||||||
- Mário Freitas
|
- Mário Freitas
|
||||||
@@ -315,7 +186,6 @@ skills.
|
|||||||
- Marcus Geelnard
|
- Marcus Geelnard
|
||||||
- Eloi Marín Gratacós
|
- Eloi Marín Gratacós
|
||||||
- Stefan Gustavson
|
- Stefan Gustavson
|
||||||
- Jonathan Hale
|
|
||||||
- Sylvain Hellegouarch
|
- Sylvain Hellegouarch
|
||||||
- Matthew Henry
|
- Matthew Henry
|
||||||
- heromyth
|
- heromyth
|
||||||
@@ -328,79 +198,63 @@ skills.
|
|||||||
- Toni Jovanoski
|
- Toni Jovanoski
|
||||||
- Arseny Kapoulkine
|
- Arseny Kapoulkine
|
||||||
- Osman Keskin
|
- Osman Keskin
|
||||||
- Josh Kilmer
|
|
||||||
- Cameron King
|
- Cameron King
|
||||||
- Peter Knut
|
- Peter Knut
|
||||||
- Christoph Kubisch
|
- Christoph Kubisch
|
||||||
- Yuri Kunde Schlesner
|
|
||||||
- Konstantin Käfer
|
|
||||||
- Eric Larson
|
- Eric Larson
|
||||||
- Robin Leffmann
|
- Robin Leffmann
|
||||||
- Glenn Lewis
|
- Glenn Lewis
|
||||||
- Shane Liesegang
|
- Shane Liesegang
|
||||||
- Eyal Lotem
|
- Eyal Lotem
|
||||||
|
- Дмитри Малышев
|
||||||
|
- Martins Mozeiko
|
||||||
- Tristam MacDonald
|
- Tristam MacDonald
|
||||||
- Hans Mackowiak
|
- Hans Mackowiak
|
||||||
- Дмитри Малышев
|
|
||||||
- Zbigniew Mandziejewicz
|
- Zbigniew Mandziejewicz
|
||||||
- Célestin Marot
|
|
||||||
- Kyle McDonald
|
- Kyle McDonald
|
||||||
- David Medlock
|
- David Medlock
|
||||||
- Bryce Mehring
|
- Bryce Mehring
|
||||||
- Jonathan Mercier
|
- Jonathan Mercier
|
||||||
- Marcel Metz
|
- Marcel Metz
|
||||||
- Liam Middlebrook
|
|
||||||
- Jonathan Miller
|
- Jonathan Miller
|
||||||
- Kenneth Miller
|
- Kenneth Miller
|
||||||
- Bruce Mitchener
|
- Bruce Mitchener
|
||||||
- Jack Moffitt
|
- Jack Moffitt
|
||||||
- Jeff Molofee
|
- Jeff Molofee
|
||||||
- Pierre Morel
|
|
||||||
- Jon Morton
|
- Jon Morton
|
||||||
- Pierre Moulon
|
- Pierre Moulon
|
||||||
- Martins Mozeiko
|
|
||||||
- Julian Møller
|
- Julian Møller
|
||||||
- ndogxj
|
|
||||||
- Kristian Nielsen
|
|
||||||
- Kamil Nowakowski
|
- Kamil Nowakowski
|
||||||
- Denis Ovod
|
|
||||||
- Ozzy
|
- Ozzy
|
||||||
- Andri Pálsson
|
- Andri Pálsson
|
||||||
- Peoro
|
- Peoro
|
||||||
- Braden Pellett
|
- Braden Pellett
|
||||||
- Arturo J. Pérez
|
- Arturo J. Pérez
|
||||||
- Anthony Pesch
|
|
||||||
- Orson Peters
|
- Orson Peters
|
||||||
- Emmanuel Gil Peyrot
|
- Emmanuel Gil Peyrot
|
||||||
- Cyril Pichard
|
- Cyril Pichard
|
||||||
- Keith Pitt
|
- Pieroman
|
||||||
- Stanislav Podgorskiy
|
|
||||||
- Alexandre Pretyman
|
|
||||||
- Philip Rideout
|
- Philip Rideout
|
||||||
- Eddie Ringle
|
|
||||||
- Jorge Rodriguez
|
- Jorge Rodriguez
|
||||||
- Ed Ropple
|
- Ed Ropple
|
||||||
- Aleksey Rybalkin
|
- Aleksey Rybalkin
|
||||||
- Riku Salminen
|
- Riku Salminen
|
||||||
- Brandon Schaefer
|
- Brandon Schaefer
|
||||||
- Sebastian Schuberth
|
- Sebastian Schuberth
|
||||||
- Christian Sdunek
|
|
||||||
- Matt Sealey
|
- Matt Sealey
|
||||||
|
- SephiRok
|
||||||
- Steve Sexton
|
- Steve Sexton
|
||||||
- Arkady Shapkin
|
- Systemcluster
|
||||||
- Yoshiki Shibukawa
|
- Yoshiki Shibukawa
|
||||||
- Dmitri Shuralyov
|
- Dmitri Shuralyov
|
||||||
- Daniel Skorupski
|
- Daniel Skorupski
|
||||||
- Bradley Smith
|
- Bradley Smith
|
||||||
- Patrick Snape
|
- Patrick Snape
|
||||||
- Erlend Sogge Heggen
|
|
||||||
- Julian Squires
|
- Julian Squires
|
||||||
- Johannes Stein
|
- Johannes Stein
|
||||||
- Pontus Stenetorp
|
|
||||||
- Michael Stocker
|
- Michael Stocker
|
||||||
- Justin Stoecker
|
- Justin Stoecker
|
||||||
- Elviss Strazdins
|
- Elviss Strazdins
|
||||||
- Paul Sultana
|
|
||||||
- Nathan Sweet
|
- Nathan Sweet
|
||||||
- TTK-Bandit
|
- TTK-Bandit
|
||||||
- Sergey Tikhomirov
|
- Sergey Tikhomirov
|
||||||
@@ -410,7 +264,6 @@ skills.
|
|||||||
- Matthew Turner
|
- Matthew Turner
|
||||||
- urraka
|
- urraka
|
||||||
- Elias Vanderstuyft
|
- Elias Vanderstuyft
|
||||||
- Stef Velzel
|
|
||||||
- Jari Vetoniemi
|
- Jari Vetoniemi
|
||||||
- Ricardo Vieira
|
- Ricardo Vieira
|
||||||
- Nicholas Vitovitch
|
- Nicholas Vitovitch
|
||||||
@@ -420,8 +273,7 @@ skills.
|
|||||||
- Xo Wang
|
- Xo Wang
|
||||||
- Jay Weisskopf
|
- Jay Weisskopf
|
||||||
- Frank Wille
|
- Frank Wille
|
||||||
- Ryogo Yoshimura
|
- yuriks
|
||||||
- Andrey Zholos
|
|
||||||
- Santi Zupancic
|
- Santi Zupancic
|
||||||
- Jonas Ådahl
|
- Jonas Ådahl
|
||||||
- Lasse Öörni
|
- Lasse Öörni
|
||||||
|
|||||||
Vendored
+1
-1
@@ -192,7 +192,7 @@ 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 = {{0}};
|
mat4x4 T, C, S;
|
||||||
|
|
||||||
vec3_norm(u, u);
|
vec3_norm(u, u);
|
||||||
mat4x4_from_vec3_mul_outer(T, u, u);
|
mat4x4_from_vec3_mul_outer(T, u, u);
|
||||||
|
|||||||
Vendored
+1033
-2663
File diff suppressed because it is too large
Load Diff
Vendored
+9
-31
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Nuklear - v1.32.0 - public domain
|
* Nuklear - v1.17 - public domain
|
||||||
* no warrenty implied; use at your own risk.
|
* no warrenty implied; use at your own risk.
|
||||||
* authored from 2015-2017 by Micha Mettke
|
* authored from 2015-2016 by Micha Mettke
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* ==============================================================
|
* ==============================================================
|
||||||
@@ -24,7 +24,7 @@ NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atl
|
|||||||
NK_API void nk_glfw3_font_stash_end(void);
|
NK_API void nk_glfw3_font_stash_end(void);
|
||||||
|
|
||||||
NK_API void nk_glfw3_new_frame(void);
|
NK_API void nk_glfw3_new_frame(void);
|
||||||
NK_API void nk_glfw3_render(enum nk_anti_aliasing);
|
NK_API void nk_glfw3_render(enum nk_anti_aliasing , int max_vertex_buffer, int max_element_buffer);
|
||||||
NK_API void nk_glfw3_shutdown(void);
|
NK_API void nk_glfw3_shutdown(void);
|
||||||
|
|
||||||
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
||||||
@@ -44,12 +44,6 @@ NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xof
|
|||||||
#ifndef NK_GLFW_TEXT_MAX
|
#ifndef NK_GLFW_TEXT_MAX
|
||||||
#define NK_GLFW_TEXT_MAX 256
|
#define NK_GLFW_TEXT_MAX 256
|
||||||
#endif
|
#endif
|
||||||
#ifndef NK_GLFW_DOUBLE_CLICK_LO
|
|
||||||
#define NK_GLFW_DOUBLE_CLICK_LO 0.02
|
|
||||||
#endif
|
|
||||||
#ifndef NK_GLFW_DOUBLE_CLICK_HI
|
|
||||||
#define NK_GLFW_DOUBLE_CLICK_HI 0.2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct nk_glfw_device {
|
struct nk_glfw_device {
|
||||||
struct nk_buffer cmds;
|
struct nk_buffer cmds;
|
||||||
@@ -73,8 +67,7 @@ static struct nk_glfw {
|
|||||||
struct nk_vec2 fb_scale;
|
struct nk_vec2 fb_scale;
|
||||||
unsigned int text[NK_GLFW_TEXT_MAX];
|
unsigned int text[NK_GLFW_TEXT_MAX];
|
||||||
int text_len;
|
int text_len;
|
||||||
struct nk_vec2 scroll;
|
float scroll;
|
||||||
double last_button_click;
|
|
||||||
} glfw;
|
} glfw;
|
||||||
|
|
||||||
NK_INTERN void
|
NK_INTERN void
|
||||||
@@ -90,7 +83,7 @@ nk_glfw3_device_upload_atlas(const void *image, int width, int height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NK_API void
|
NK_API void
|
||||||
nk_glfw3_render(enum nk_anti_aliasing AA)
|
nk_glfw3_render(enum nk_anti_aliasing AA, int max_vertex_buffer, int max_element_buffer)
|
||||||
{
|
{
|
||||||
/* setup global state */
|
/* setup global state */
|
||||||
struct nk_glfw_device *dev = &glfw.ogl;
|
struct nk_glfw_device *dev = &glfw.ogl;
|
||||||
@@ -207,22 +200,7 @@ NK_API void
|
|||||||
nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
|
nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
|
||||||
{
|
{
|
||||||
(void)win; (void)xoff;
|
(void)win; (void)xoff;
|
||||||
glfw.scroll.x += (float)xoff;
|
glfw.scroll += (float)yoff;
|
||||||
glfw.scroll.y += (float)yoff;
|
|
||||||
}
|
|
||||||
|
|
||||||
NK_API void
|
|
||||||
nk_glfw3_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
|
||||||
{
|
|
||||||
double x, y;
|
|
||||||
if (button != GLFW_MOUSE_BUTTON_LEFT) return;
|
|
||||||
glfwGetCursorPos(window, &x, &y);
|
|
||||||
if (action == GLFW_PRESS) {
|
|
||||||
double dt = glfwGetTime() - glfw.last_button_click;
|
|
||||||
if (dt > NK_GLFW_DOUBLE_CLICK_LO && dt < NK_GLFW_DOUBLE_CLICK_HI)
|
|
||||||
nk_input_button(&glfw.ctx, NK_BUTTON_DOUBLE, (int)x, (int)y, nk_true);
|
|
||||||
glfw.last_button_click = glfwGetTime();
|
|
||||||
} else nk_input_button(&glfw.ctx, NK_BUTTON_DOUBLE, (int)x, (int)y, nk_false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NK_INTERN void
|
NK_INTERN void
|
||||||
@@ -254,8 +232,8 @@ nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
|
|||||||
if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
|
if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
|
||||||
glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
|
glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
|
||||||
glfwSetCharCallback(win, nk_glfw3_char_callback);
|
glfwSetCharCallback(win, nk_glfw3_char_callback);
|
||||||
glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nk_init_default(&glfw.ctx, 0);
|
nk_init_default(&glfw.ctx, 0);
|
||||||
glfw.ctx.clip.copy = nk_glfw3_clipbard_copy;
|
glfw.ctx.clip.copy = nk_glfw3_clipbard_copy;
|
||||||
glfw.ctx.clip.paste = nk_glfw3_clipbard_paste;
|
glfw.ctx.clip.paste = nk_glfw3_clipbard_paste;
|
||||||
@@ -324,7 +302,7 @@ nk_glfw3_new_frame(void)
|
|||||||
if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
|
if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
|
||||||
glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
|
glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
|
||||||
nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
|
nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
|
||||||
nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS);
|
nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_P) == GLFW_PRESS);
|
||||||
nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
|
nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
|
||||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
|
nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
|
||||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
|
nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
|
||||||
@@ -355,7 +333,7 @@ nk_glfw3_new_frame(void)
|
|||||||
nk_input_scroll(ctx, glfw.scroll);
|
nk_input_scroll(ctx, glfw.scroll);
|
||||||
nk_input_end(&glfw.ctx);
|
nk_input_end(&glfw.ctx);
|
||||||
glfw.text_len = 0;
|
glfw.text_len = 0;
|
||||||
glfw.scroll = nk_vec2(0,0);
|
glfw.scroll = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NK_API
|
NK_API
|
||||||
|
|||||||
Vendored
+1
-1
@@ -53,7 +53,7 @@ extern "C"
|
|||||||
#define VKAPI_PTR VKAPI_CALL
|
#define VKAPI_PTR VKAPI_CALL
|
||||||
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
|
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
|
||||||
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
|
#error "Vulkan isn't supported for the 'armeabi' NDK ABI"
|
||||||
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
|
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && __ARM_32BIT_STATE
|
||||||
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
|
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
|
||||||
// calling convention, i.e. float parameters are passed in registers. This
|
// calling convention, i.e. float parameters are passed in registers. This
|
||||||
// is true even if the rest of the application passes floats on the stack,
|
// is true even if the rest of the application passes floats on the stack,
|
||||||
|
|||||||
Vendored
+7
-647
@@ -6,7 +6,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Copyright (c) 2015-2017 The Khronos Group Inc.
|
** Copyright (c) 2015-2016 The Khronos Group Inc.
|
||||||
**
|
**
|
||||||
** Licensed under the Apache License, Version 2.0 (the "License");
|
** Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
** you may not use this file except in compliance with the License.
|
** you may not use this file except in compliance with the License.
|
||||||
@@ -43,7 +43,7 @@ extern "C" {
|
|||||||
#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
|
#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
|
||||||
#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
|
#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
|
||||||
// Version of this file
|
// Version of this file
|
||||||
#define VK_HEADER_VERSION 39
|
#define VK_HEADER_VERSION 26
|
||||||
|
|
||||||
|
|
||||||
#define VK_NULL_HANDLE 0
|
#define VK_NULL_HANDLE 0
|
||||||
@@ -145,7 +145,6 @@ typedef enum VkResult {
|
|||||||
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
|
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
|
||||||
VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
|
VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
|
||||||
VK_ERROR_INVALID_SHADER_NV = -1000012000,
|
VK_ERROR_INVALID_SHADER_NV = -1000012000,
|
||||||
VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000,
|
|
||||||
VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL,
|
VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL,
|
||||||
VK_RESULT_END_RANGE = VK_INCOMPLETE,
|
VK_RESULT_END_RANGE = VK_INCOMPLETE,
|
||||||
VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FRAGMENTED_POOL + 1),
|
VK_RESULT_RANGE_SIZE = (VK_INCOMPLETE - VK_ERROR_FRAGMENTED_POOL + 1),
|
||||||
@@ -226,28 +225,6 @@ typedef enum VkStructureType {
|
|||||||
VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
|
VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
|
||||||
VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001,
|
VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001,
|
||||||
VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000,
|
VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000,
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = 1000059000,
|
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = 1000059001,
|
|
||||||
VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = 1000059002,
|
|
||||||
VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = 1000059003,
|
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = 1000059004,
|
|
||||||
VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = 1000059005,
|
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = 1000059006,
|
|
||||||
VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = 1000059007,
|
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = 1000059008,
|
|
||||||
VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000,
|
|
||||||
VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000,
|
|
||||||
VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000,
|
|
||||||
VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001,
|
|
||||||
VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX = 1000086002,
|
|
||||||
VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX = 1000086003,
|
|
||||||
VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX = 1000086004,
|
|
||||||
VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX = 1000086005,
|
|
||||||
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = 1000090000,
|
|
||||||
VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000,
|
|
||||||
VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001,
|
|
||||||
VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002,
|
|
||||||
VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003,
|
|
||||||
VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
|
||||||
VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
|
VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
|
||||||
VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
|
VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
|
||||||
@@ -856,8 +833,6 @@ typedef enum VkFormatFeatureFlagBits {
|
|||||||
VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800,
|
VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800,
|
||||||
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000,
|
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000,
|
||||||
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000,
|
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG = 0x00002000,
|
||||||
VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR = 0x00004000,
|
|
||||||
VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR = 0x00008000,
|
|
||||||
VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
VK_FORMAT_FEATURE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
||||||
} VkFormatFeatureFlagBits;
|
} VkFormatFeatureFlagBits;
|
||||||
typedef VkFlags VkFormatFeatureFlags;
|
typedef VkFlags VkFormatFeatureFlags;
|
||||||
@@ -881,7 +856,6 @@ typedef enum VkImageCreateFlagBits {
|
|||||||
VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
|
VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
|
||||||
VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008,
|
VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008,
|
||||||
VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010,
|
VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010,
|
||||||
VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = 0x00000020,
|
|
||||||
VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
||||||
} VkImageCreateFlagBits;
|
} VkImageCreateFlagBits;
|
||||||
typedef VkFlags VkImageCreateFlags;
|
typedef VkFlags VkImageCreateFlags;
|
||||||
@@ -943,7 +917,6 @@ typedef enum VkPipelineStageFlagBits {
|
|||||||
VK_PIPELINE_STAGE_HOST_BIT = 0x00004000,
|
VK_PIPELINE_STAGE_HOST_BIT = 0x00004000,
|
||||||
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000,
|
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000,
|
||||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000,
|
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000,
|
||||||
VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000,
|
|
||||||
VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
||||||
} VkPipelineStageFlagBits;
|
} VkPipelineStageFlagBits;
|
||||||
typedef VkFlags VkPipelineStageFlags;
|
typedef VkFlags VkPipelineStageFlags;
|
||||||
@@ -1118,8 +1091,6 @@ typedef enum VkAccessFlagBits {
|
|||||||
VK_ACCESS_HOST_WRITE_BIT = 0x00004000,
|
VK_ACCESS_HOST_WRITE_BIT = 0x00004000,
|
||||||
VK_ACCESS_MEMORY_READ_BIT = 0x00008000,
|
VK_ACCESS_MEMORY_READ_BIT = 0x00008000,
|
||||||
VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000,
|
VK_ACCESS_MEMORY_WRITE_BIT = 0x00010000,
|
||||||
VK_ACCESS_COMMAND_PROCESS_READ_BIT_NVX = 0x00020000,
|
|
||||||
VK_ACCESS_COMMAND_PROCESS_WRITE_BIT_NVX = 0x00040000,
|
|
||||||
VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
VK_ACCESS_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
||||||
} VkAccessFlagBits;
|
} VkAccessFlagBits;
|
||||||
typedef VkFlags VkAccessFlags;
|
typedef VkFlags VkAccessFlags;
|
||||||
@@ -3225,18 +3196,6 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
|
|||||||
|
|
||||||
typedef enum VkColorSpaceKHR {
|
typedef enum VkColorSpaceKHR {
|
||||||
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0,
|
VK_COLOR_SPACE_SRGB_NONLINEAR_KHR = 0,
|
||||||
VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT = 1000104001,
|
|
||||||
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT = 1000104002,
|
|
||||||
VK_COLOR_SPACE_SCRGB_LINEAR_EXT = 1000104003,
|
|
||||||
VK_COLOR_SPACE_SCRGB_NONLINEAR_EXT = 1000104004,
|
|
||||||
VK_COLOR_SPACE_DCI_P3_LINEAR_EXT = 1000104005,
|
|
||||||
VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT = 1000104006,
|
|
||||||
VK_COLOR_SPACE_BT709_LINEAR_EXT = 1000104007,
|
|
||||||
VK_COLOR_SPACE_BT709_NONLINEAR_EXT = 1000104008,
|
|
||||||
VK_COLOR_SPACE_BT2020_LINEAR_EXT = 1000104009,
|
|
||||||
VK_COLOR_SPACE_BT2020_NONLINEAR_EXT = 1000104010,
|
|
||||||
VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT = 1000104011,
|
|
||||||
VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT = 1000104012,
|
|
||||||
VK_COLOR_SPACE_BEGIN_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
|
VK_COLOR_SPACE_BEGIN_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
|
||||||
VK_COLOR_SPACE_END_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
|
VK_COLOR_SPACE_END_RANGE_KHR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
|
||||||
VK_COLOR_SPACE_RANGE_SIZE_KHR = (VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + 1),
|
VK_COLOR_SPACE_RANGE_SIZE_KHR = (VK_COLOR_SPACE_SRGB_NONLINEAR_KHR - VK_COLOR_SPACE_SRGB_NONLINEAR_KHR + 1),
|
||||||
@@ -3772,140 +3731,10 @@ VKAPI_ATTR VkBool32 VKAPI_CALL vkGetPhysicalDeviceWin32PresentationSupportKHR(
|
|||||||
#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge"
|
#define VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME "VK_KHR_sampler_mirror_clamp_to_edge"
|
||||||
|
|
||||||
|
|
||||||
#define VK_KHR_get_physical_device_properties2 1
|
|
||||||
#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_SPEC_VERSION 1
|
|
||||||
#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME "VK_KHR_get_physical_device_properties2"
|
|
||||||
|
|
||||||
typedef struct VkPhysicalDeviceFeatures2KHR {
|
|
||||||
VkStructureType sType;
|
|
||||||
void* pNext;
|
|
||||||
VkPhysicalDeviceFeatures features;
|
|
||||||
} VkPhysicalDeviceFeatures2KHR;
|
|
||||||
|
|
||||||
typedef struct VkPhysicalDeviceProperties2KHR {
|
|
||||||
VkStructureType sType;
|
|
||||||
void* pNext;
|
|
||||||
VkPhysicalDeviceProperties properties;
|
|
||||||
} VkPhysicalDeviceProperties2KHR;
|
|
||||||
|
|
||||||
typedef struct VkFormatProperties2KHR {
|
|
||||||
VkStructureType sType;
|
|
||||||
void* pNext;
|
|
||||||
VkFormatProperties formatProperties;
|
|
||||||
} VkFormatProperties2KHR;
|
|
||||||
|
|
||||||
typedef struct VkImageFormatProperties2KHR {
|
|
||||||
VkStructureType sType;
|
|
||||||
void* pNext;
|
|
||||||
VkImageFormatProperties imageFormatProperties;
|
|
||||||
} VkImageFormatProperties2KHR;
|
|
||||||
|
|
||||||
typedef struct VkPhysicalDeviceImageFormatInfo2KHR {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkFormat format;
|
|
||||||
VkImageType type;
|
|
||||||
VkImageTiling tiling;
|
|
||||||
VkImageUsageFlags usage;
|
|
||||||
VkImageCreateFlags flags;
|
|
||||||
} VkPhysicalDeviceImageFormatInfo2KHR;
|
|
||||||
|
|
||||||
typedef struct VkQueueFamilyProperties2KHR {
|
|
||||||
VkStructureType sType;
|
|
||||||
void* pNext;
|
|
||||||
VkQueueFamilyProperties queueFamilyProperties;
|
|
||||||
} VkQueueFamilyProperties2KHR;
|
|
||||||
|
|
||||||
typedef struct VkPhysicalDeviceMemoryProperties2KHR {
|
|
||||||
VkStructureType sType;
|
|
||||||
void* pNext;
|
|
||||||
VkPhysicalDeviceMemoryProperties memoryProperties;
|
|
||||||
} VkPhysicalDeviceMemoryProperties2KHR;
|
|
||||||
|
|
||||||
typedef struct VkSparseImageFormatProperties2KHR {
|
|
||||||
VkStructureType sType;
|
|
||||||
void* pNext;
|
|
||||||
VkSparseImageFormatProperties properties;
|
|
||||||
} VkSparseImageFormatProperties2KHR;
|
|
||||||
|
|
||||||
typedef struct VkPhysicalDeviceSparseImageFormatInfo2KHR {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkFormat format;
|
|
||||||
VkImageType type;
|
|
||||||
VkSampleCountFlagBits samples;
|
|
||||||
VkImageUsageFlags usage;
|
|
||||||
VkImageTiling tiling;
|
|
||||||
} VkPhysicalDeviceSparseImageFormatInfo2KHR;
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFeatures2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures2KHR* pFeatures);
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2KHR* pProperties);
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceFormatProperties2KHR)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties2KHR* pFormatProperties);
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo, VkImageFormatProperties2KHR* pImageFormatProperties);
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR)(VkPhysicalDevice physicalDevice, uint32_t* pQueueFamilyPropertyCount, VkQueueFamilyProperties2KHR* pQueueFamilyProperties);
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceMemoryProperties2KHR)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties);
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceSparseImageFormatProperties2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo, uint32_t* pPropertyCount, VkSparseImageFormatProperties2KHR* pProperties);
|
|
||||||
|
|
||||||
#ifndef VK_NO_PROTOTYPES
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures2KHR(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
VkPhysicalDeviceFeatures2KHR* pFeatures);
|
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceProperties2KHR(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
VkPhysicalDeviceProperties2KHR* pProperties);
|
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties2KHR(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
VkFormat format,
|
|
||||||
VkFormatProperties2KHR* pFormatProperties);
|
|
||||||
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceImageFormatProperties2KHR(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
const VkPhysicalDeviceImageFormatInfo2KHR* pImageFormatInfo,
|
|
||||||
VkImageFormatProperties2KHR* pImageFormatProperties);
|
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceQueueFamilyProperties2KHR(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
uint32_t* pQueueFamilyPropertyCount,
|
|
||||||
VkQueueFamilyProperties2KHR* pQueueFamilyProperties);
|
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties2KHR(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
VkPhysicalDeviceMemoryProperties2KHR* pMemoryProperties);
|
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceSparseImageFormatProperties2KHR(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo,
|
|
||||||
uint32_t* pPropertyCount,
|
|
||||||
VkSparseImageFormatProperties2KHR* pProperties);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VK_KHR_shader_draw_parameters 1
|
|
||||||
#define VK_KHR_SHADER_DRAW_PARAMETERS_SPEC_VERSION 1
|
|
||||||
#define VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME "VK_KHR_shader_draw_parameters"
|
|
||||||
|
|
||||||
|
|
||||||
#define VK_KHR_maintenance1 1
|
|
||||||
#define VK_KHR_MAINTENANCE1_SPEC_VERSION 1
|
|
||||||
#define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1"
|
|
||||||
|
|
||||||
typedef VkFlags VkCommandPoolTrimFlagsKHR;
|
|
||||||
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlagsKHR flags);
|
|
||||||
|
|
||||||
#ifndef VK_NO_PROTOTYPES
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkTrimCommandPoolKHR(
|
|
||||||
VkDevice device,
|
|
||||||
VkCommandPool commandPool,
|
|
||||||
VkCommandPoolTrimFlagsKHR flags);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VK_EXT_debug_report 1
|
#define VK_EXT_debug_report 1
|
||||||
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
|
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
|
||||||
|
|
||||||
#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 4
|
#define VK_EXT_DEBUG_REPORT_SPEC_VERSION 3
|
||||||
#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report"
|
#define VK_EXT_DEBUG_REPORT_EXTENSION_NAME "VK_EXT_debug_report"
|
||||||
#define VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT
|
#define VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT
|
||||||
|
|
||||||
@@ -3940,13 +3769,9 @@ typedef enum VkDebugReportObjectTypeEXT {
|
|||||||
VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26,
|
VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT = 26,
|
||||||
VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27,
|
VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT = 27,
|
||||||
VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = 28,
|
VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT = 28,
|
||||||
VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_KHR_EXT = 29,
|
|
||||||
VK_DEBUG_REPORT_OBJECT_TYPE_DISPLAY_MODE_KHR_EXT = 30,
|
|
||||||
VK_DEBUG_REPORT_OBJECT_TYPE_OBJECT_TABLE_NVX_EXT = 31,
|
|
||||||
VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT = 32,
|
|
||||||
VK_DEBUG_REPORT_OBJECT_TYPE_BEGIN_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
|
VK_DEBUG_REPORT_OBJECT_TYPE_BEGIN_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
|
||||||
VK_DEBUG_REPORT_OBJECT_TYPE_END_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT,
|
VK_DEBUG_REPORT_OBJECT_TYPE_END_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
|
||||||
VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT = (VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_EXT - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT + 1),
|
VK_DEBUG_REPORT_OBJECT_TYPE_RANGE_SIZE_EXT = (VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT - VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT + 1),
|
||||||
VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
|
VK_DEBUG_REPORT_OBJECT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
|
||||||
} VkDebugReportObjectTypeEXT;
|
} VkDebugReportObjectTypeEXT;
|
||||||
|
|
||||||
@@ -4147,8 +3972,8 @@ typedef struct VkDedicatedAllocationMemoryAllocateInfoNV {
|
|||||||
|
|
||||||
|
|
||||||
#define VK_AMD_draw_indirect_count 1
|
#define VK_AMD_draw_indirect_count 1
|
||||||
#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
|
#define VK_AMD_EXTENSION_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
|
||||||
#define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count"
|
#define VK_AMD_EXTENSION_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count"
|
||||||
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
|
typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
|
||||||
typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
|
typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
|
||||||
@@ -4173,21 +3998,6 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawIndexedIndirectCountAMD(
|
|||||||
uint32_t stride);
|
uint32_t stride);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VK_AMD_negative_viewport_height 1
|
|
||||||
#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION 1
|
|
||||||
#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME "VK_AMD_negative_viewport_height"
|
|
||||||
|
|
||||||
|
|
||||||
#define VK_AMD_gpu_shader_half_float 1
|
|
||||||
#define VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION 1
|
|
||||||
#define VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME "VK_AMD_gpu_shader_half_float"
|
|
||||||
|
|
||||||
|
|
||||||
#define VK_AMD_shader_ballot 1
|
|
||||||
#define VK_AMD_SHADER_BALLOT_SPEC_VERSION 1
|
|
||||||
#define VK_AMD_SHADER_BALLOT_EXTENSION_NAME "VK_AMD_shader_ballot"
|
|
||||||
|
|
||||||
|
|
||||||
#define VK_IMG_format_pvrtc 1
|
#define VK_IMG_format_pvrtc 1
|
||||||
#define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1
|
#define VK_IMG_FORMAT_PVRTC_SPEC_VERSION 1
|
||||||
#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc"
|
#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc"
|
||||||
@@ -4306,456 +4116,6 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
|
|||||||
|
|
||||||
#endif /* VK_USE_PLATFORM_WIN32_KHR */
|
#endif /* VK_USE_PLATFORM_WIN32_KHR */
|
||||||
|
|
||||||
#define VK_EXT_validation_flags 1
|
|
||||||
#define VK_EXT_VALIDATION_FLAGS_SPEC_VERSION 1
|
|
||||||
#define VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME "VK_EXT_validation_flags"
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum VkValidationCheckEXT {
|
|
||||||
VK_VALIDATION_CHECK_ALL_EXT = 0,
|
|
||||||
VK_VALIDATION_CHECK_BEGIN_RANGE_EXT = VK_VALIDATION_CHECK_ALL_EXT,
|
|
||||||
VK_VALIDATION_CHECK_END_RANGE_EXT = VK_VALIDATION_CHECK_ALL_EXT,
|
|
||||||
VK_VALIDATION_CHECK_RANGE_SIZE_EXT = (VK_VALIDATION_CHECK_ALL_EXT - VK_VALIDATION_CHECK_ALL_EXT + 1),
|
|
||||||
VK_VALIDATION_CHECK_MAX_ENUM_EXT = 0x7FFFFFFF
|
|
||||||
} VkValidationCheckEXT;
|
|
||||||
|
|
||||||
typedef struct VkValidationFlagsEXT {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
uint32_t disabledValidationCheckCount;
|
|
||||||
VkValidationCheckEXT* pDisabledValidationChecks;
|
|
||||||
} VkValidationFlagsEXT;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef VK_USE_PLATFORM_VI_NN
|
|
||||||
#define VK_NN_vi_surface 1
|
|
||||||
#define VK_NN_VI_SURFACE_SPEC_VERSION 1
|
|
||||||
#define VK_NN_VI_SURFACE_EXTENSION_NAME "VK_NN_vi_surface"
|
|
||||||
|
|
||||||
typedef VkFlags VkViSurfaceCreateFlagsNN;
|
|
||||||
|
|
||||||
typedef struct VkViSurfaceCreateInfoNN {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkViSurfaceCreateFlagsNN flags;
|
|
||||||
void* window;
|
|
||||||
} VkViSurfaceCreateInfoNN;
|
|
||||||
|
|
||||||
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateViSurfaceNN)(VkInstance instance, const VkViSurfaceCreateInfoNN* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
|
|
||||||
|
|
||||||
#ifndef VK_NO_PROTOTYPES
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateViSurfaceNN(
|
|
||||||
VkInstance instance,
|
|
||||||
const VkViSurfaceCreateInfoNN* pCreateInfo,
|
|
||||||
const VkAllocationCallbacks* pAllocator,
|
|
||||||
VkSurfaceKHR* pSurface);
|
|
||||||
#endif
|
|
||||||
#endif /* VK_USE_PLATFORM_VI_NN */
|
|
||||||
|
|
||||||
#define VK_EXT_shader_subgroup_ballot 1
|
|
||||||
#define VK_EXT_SHADER_SUBGROUP_BALLOT_SPEC_VERSION 1
|
|
||||||
#define VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME "VK_EXT_shader_subgroup_ballot"
|
|
||||||
|
|
||||||
|
|
||||||
#define VK_EXT_shader_subgroup_vote 1
|
|
||||||
#define VK_EXT_SHADER_SUBGROUP_VOTE_SPEC_VERSION 1
|
|
||||||
#define VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME "VK_EXT_shader_subgroup_vote"
|
|
||||||
|
|
||||||
|
|
||||||
#define VK_NVX_device_generated_commands 1
|
|
||||||
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkObjectTableNVX)
|
|
||||||
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkIndirectCommandsLayoutNVX)
|
|
||||||
|
|
||||||
#define VK_NVX_DEVICE_GENERATED_COMMANDS_SPEC_VERSION 1
|
|
||||||
#define VK_NVX_DEVICE_GENERATED_COMMANDS_EXTENSION_NAME "VK_NVX_device_generated_commands"
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum VkIndirectCommandsTokenTypeNVX {
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_PIPELINE_NVX = 0,
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_DESCRIPTOR_SET_NVX = 1,
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_INDEX_BUFFER_NVX = 2,
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_VERTEX_BUFFER_NVX = 3,
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_PUSH_CONSTANT_NVX = 4,
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_DRAW_INDEXED_NVX = 5,
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_DRAW_NVX = 6,
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_DISPATCH_NVX = 7,
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_TYPE_BEGIN_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_PIPELINE_NVX,
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_TYPE_END_RANGE_NVX = VK_INDIRECT_COMMANDS_TOKEN_DISPATCH_NVX,
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_TYPE_RANGE_SIZE_NVX = (VK_INDIRECT_COMMANDS_TOKEN_DISPATCH_NVX - VK_INDIRECT_COMMANDS_TOKEN_PIPELINE_NVX + 1),
|
|
||||||
VK_INDIRECT_COMMANDS_TOKEN_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF
|
|
||||||
} VkIndirectCommandsTokenTypeNVX;
|
|
||||||
|
|
||||||
typedef enum VkObjectEntryTypeNVX {
|
|
||||||
VK_OBJECT_ENTRY_DESCRIPTOR_SET_NVX = 0,
|
|
||||||
VK_OBJECT_ENTRY_PIPELINE_NVX = 1,
|
|
||||||
VK_OBJECT_ENTRY_INDEX_BUFFER_NVX = 2,
|
|
||||||
VK_OBJECT_ENTRY_VERTEX_BUFFER_NVX = 3,
|
|
||||||
VK_OBJECT_ENTRY_PUSH_CONSTANT_NVX = 4,
|
|
||||||
VK_OBJECT_ENTRY_TYPE_BEGIN_RANGE_NVX = VK_OBJECT_ENTRY_DESCRIPTOR_SET_NVX,
|
|
||||||
VK_OBJECT_ENTRY_TYPE_END_RANGE_NVX = VK_OBJECT_ENTRY_PUSH_CONSTANT_NVX,
|
|
||||||
VK_OBJECT_ENTRY_TYPE_RANGE_SIZE_NVX = (VK_OBJECT_ENTRY_PUSH_CONSTANT_NVX - VK_OBJECT_ENTRY_DESCRIPTOR_SET_NVX + 1),
|
|
||||||
VK_OBJECT_ENTRY_TYPE_MAX_ENUM_NVX = 0x7FFFFFFF
|
|
||||||
} VkObjectEntryTypeNVX;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum VkIndirectCommandsLayoutUsageFlagBitsNVX {
|
|
||||||
VK_INDIRECT_COMMANDS_LAYOUT_USAGE_UNORDERED_SEQUENCES_BIT_NVX = 0x00000001,
|
|
||||||
VK_INDIRECT_COMMANDS_LAYOUT_USAGE_SPARSE_SEQUENCES_BIT_NVX = 0x00000002,
|
|
||||||
VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EMPTY_EXECUTIONS_BIT_NVX = 0x00000004,
|
|
||||||
VK_INDIRECT_COMMANDS_LAYOUT_USAGE_INDEXED_SEQUENCES_BIT_NVX = 0x00000008,
|
|
||||||
VK_INDIRECT_COMMANDS_LAYOUT_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF
|
|
||||||
} VkIndirectCommandsLayoutUsageFlagBitsNVX;
|
|
||||||
typedef VkFlags VkIndirectCommandsLayoutUsageFlagsNVX;
|
|
||||||
|
|
||||||
typedef enum VkObjectEntryUsageFlagBitsNVX {
|
|
||||||
VK_OBJECT_ENTRY_USAGE_GRAPHICS_BIT_NVX = 0x00000001,
|
|
||||||
VK_OBJECT_ENTRY_USAGE_COMPUTE_BIT_NVX = 0x00000002,
|
|
||||||
VK_OBJECT_ENTRY_USAGE_FLAG_BITS_MAX_ENUM_NVX = 0x7FFFFFFF
|
|
||||||
} VkObjectEntryUsageFlagBitsNVX;
|
|
||||||
typedef VkFlags VkObjectEntryUsageFlagsNVX;
|
|
||||||
|
|
||||||
typedef struct VkDeviceGeneratedCommandsFeaturesNVX {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkBool32 computeBindingPointSupport;
|
|
||||||
} VkDeviceGeneratedCommandsFeaturesNVX;
|
|
||||||
|
|
||||||
typedef struct VkDeviceGeneratedCommandsLimitsNVX {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
uint32_t maxIndirectCommandsLayoutTokenCount;
|
|
||||||
uint32_t maxObjectEntryCounts;
|
|
||||||
uint32_t minSequenceCountBufferOffsetAlignment;
|
|
||||||
uint32_t minSequenceIndexBufferOffsetAlignment;
|
|
||||||
uint32_t minCommandsTokenBufferOffsetAlignment;
|
|
||||||
} VkDeviceGeneratedCommandsLimitsNVX;
|
|
||||||
|
|
||||||
typedef struct VkIndirectCommandsTokenNVX {
|
|
||||||
VkIndirectCommandsTokenTypeNVX tokenType;
|
|
||||||
VkBuffer buffer;
|
|
||||||
VkDeviceSize offset;
|
|
||||||
} VkIndirectCommandsTokenNVX;
|
|
||||||
|
|
||||||
typedef struct VkIndirectCommandsLayoutTokenNVX {
|
|
||||||
VkIndirectCommandsTokenTypeNVX tokenType;
|
|
||||||
uint32_t bindingUnit;
|
|
||||||
uint32_t dynamicCount;
|
|
||||||
uint32_t divisor;
|
|
||||||
} VkIndirectCommandsLayoutTokenNVX;
|
|
||||||
|
|
||||||
typedef struct VkIndirectCommandsLayoutCreateInfoNVX {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkPipelineBindPoint pipelineBindPoint;
|
|
||||||
VkIndirectCommandsLayoutUsageFlagsNVX flags;
|
|
||||||
uint32_t tokenCount;
|
|
||||||
const VkIndirectCommandsLayoutTokenNVX* pTokens;
|
|
||||||
} VkIndirectCommandsLayoutCreateInfoNVX;
|
|
||||||
|
|
||||||
typedef struct VkCmdProcessCommandsInfoNVX {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkObjectTableNVX objectTable;
|
|
||||||
VkIndirectCommandsLayoutNVX indirectCommandsLayout;
|
|
||||||
uint32_t indirectCommandsTokenCount;
|
|
||||||
const VkIndirectCommandsTokenNVX* pIndirectCommandsTokens;
|
|
||||||
uint32_t maxSequencesCount;
|
|
||||||
VkCommandBuffer targetCommandBuffer;
|
|
||||||
VkBuffer sequencesCountBuffer;
|
|
||||||
VkDeviceSize sequencesCountOffset;
|
|
||||||
VkBuffer sequencesIndexBuffer;
|
|
||||||
VkDeviceSize sequencesIndexOffset;
|
|
||||||
} VkCmdProcessCommandsInfoNVX;
|
|
||||||
|
|
||||||
typedef struct VkCmdReserveSpaceForCommandsInfoNVX {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkObjectTableNVX objectTable;
|
|
||||||
VkIndirectCommandsLayoutNVX indirectCommandsLayout;
|
|
||||||
uint32_t maxSequencesCount;
|
|
||||||
} VkCmdReserveSpaceForCommandsInfoNVX;
|
|
||||||
|
|
||||||
typedef struct VkObjectTableCreateInfoNVX {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
uint32_t objectCount;
|
|
||||||
const VkObjectEntryTypeNVX* pObjectEntryTypes;
|
|
||||||
const uint32_t* pObjectEntryCounts;
|
|
||||||
const VkObjectEntryUsageFlagsNVX* pObjectEntryUsageFlags;
|
|
||||||
uint32_t maxUniformBuffersPerDescriptor;
|
|
||||||
uint32_t maxStorageBuffersPerDescriptor;
|
|
||||||
uint32_t maxStorageImagesPerDescriptor;
|
|
||||||
uint32_t maxSampledImagesPerDescriptor;
|
|
||||||
uint32_t maxPipelineLayouts;
|
|
||||||
} VkObjectTableCreateInfoNVX;
|
|
||||||
|
|
||||||
typedef struct VkObjectTableEntryNVX {
|
|
||||||
VkObjectEntryTypeNVX type;
|
|
||||||
VkObjectEntryUsageFlagsNVX flags;
|
|
||||||
} VkObjectTableEntryNVX;
|
|
||||||
|
|
||||||
typedef struct VkObjectTablePipelineEntryNVX {
|
|
||||||
VkObjectEntryTypeNVX type;
|
|
||||||
VkObjectEntryUsageFlagsNVX flags;
|
|
||||||
VkPipeline pipeline;
|
|
||||||
} VkObjectTablePipelineEntryNVX;
|
|
||||||
|
|
||||||
typedef struct VkObjectTableDescriptorSetEntryNVX {
|
|
||||||
VkObjectEntryTypeNVX type;
|
|
||||||
VkObjectEntryUsageFlagsNVX flags;
|
|
||||||
VkPipelineLayout pipelineLayout;
|
|
||||||
VkDescriptorSet descriptorSet;
|
|
||||||
} VkObjectTableDescriptorSetEntryNVX;
|
|
||||||
|
|
||||||
typedef struct VkObjectTableVertexBufferEntryNVX {
|
|
||||||
VkObjectEntryTypeNVX type;
|
|
||||||
VkObjectEntryUsageFlagsNVX flags;
|
|
||||||
VkBuffer buffer;
|
|
||||||
} VkObjectTableVertexBufferEntryNVX;
|
|
||||||
|
|
||||||
typedef struct VkObjectTableIndexBufferEntryNVX {
|
|
||||||
VkObjectEntryTypeNVX type;
|
|
||||||
VkObjectEntryUsageFlagsNVX flags;
|
|
||||||
VkBuffer buffer;
|
|
||||||
VkIndexType indexType;
|
|
||||||
} VkObjectTableIndexBufferEntryNVX;
|
|
||||||
|
|
||||||
typedef struct VkObjectTablePushConstantEntryNVX {
|
|
||||||
VkObjectEntryTypeNVX type;
|
|
||||||
VkObjectEntryUsageFlagsNVX flags;
|
|
||||||
VkPipelineLayout pipelineLayout;
|
|
||||||
VkShaderStageFlags stageFlags;
|
|
||||||
} VkObjectTablePushConstantEntryNVX;
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkCmdProcessCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo);
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkCmdReserveSpaceForCommandsNVX)(VkCommandBuffer commandBuffer, const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo);
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateIndirectCommandsLayoutNVX)(VkDevice device, const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout);
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkDestroyIndirectCommandsLayoutNVX)(VkDevice device, VkIndirectCommandsLayoutNVX indirectCommandsLayout, const VkAllocationCallbacks* pAllocator);
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkCreateObjectTableNVX)(VkDevice device, const VkObjectTableCreateInfoNVX* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkObjectTableNVX* pObjectTable);
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkDestroyObjectTableNVX)(VkDevice device, VkObjectTableNVX objectTable, const VkAllocationCallbacks* pAllocator);
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkRegisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectTableEntryNVX* const* ppObjectTableEntries, const uint32_t* pObjectIndices);
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkUnregisterObjectsNVX)(VkDevice device, VkObjectTableNVX objectTable, uint32_t objectCount, const VkObjectEntryTypeNVX* pObjectEntryTypes, const uint32_t* pObjectIndices);
|
|
||||||
typedef void (VKAPI_PTR *PFN_vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX)(VkPhysicalDevice physicalDevice, VkDeviceGeneratedCommandsFeaturesNVX* pFeatures, VkDeviceGeneratedCommandsLimitsNVX* pLimits);
|
|
||||||
|
|
||||||
#ifndef VK_NO_PROTOTYPES
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkCmdProcessCommandsNVX(
|
|
||||||
VkCommandBuffer commandBuffer,
|
|
||||||
const VkCmdProcessCommandsInfoNVX* pProcessCommandsInfo);
|
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkCmdReserveSpaceForCommandsNVX(
|
|
||||||
VkCommandBuffer commandBuffer,
|
|
||||||
const VkCmdReserveSpaceForCommandsInfoNVX* pReserveSpaceInfo);
|
|
||||||
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateIndirectCommandsLayoutNVX(
|
|
||||||
VkDevice device,
|
|
||||||
const VkIndirectCommandsLayoutCreateInfoNVX* pCreateInfo,
|
|
||||||
const VkAllocationCallbacks* pAllocator,
|
|
||||||
VkIndirectCommandsLayoutNVX* pIndirectCommandsLayout);
|
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkDestroyIndirectCommandsLayoutNVX(
|
|
||||||
VkDevice device,
|
|
||||||
VkIndirectCommandsLayoutNVX indirectCommandsLayout,
|
|
||||||
const VkAllocationCallbacks* pAllocator);
|
|
||||||
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkCreateObjectTableNVX(
|
|
||||||
VkDevice device,
|
|
||||||
const VkObjectTableCreateInfoNVX* pCreateInfo,
|
|
||||||
const VkAllocationCallbacks* pAllocator,
|
|
||||||
VkObjectTableNVX* pObjectTable);
|
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkDestroyObjectTableNVX(
|
|
||||||
VkDevice device,
|
|
||||||
VkObjectTableNVX objectTable,
|
|
||||||
const VkAllocationCallbacks* pAllocator);
|
|
||||||
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkRegisterObjectsNVX(
|
|
||||||
VkDevice device,
|
|
||||||
VkObjectTableNVX objectTable,
|
|
||||||
uint32_t objectCount,
|
|
||||||
const VkObjectTableEntryNVX* const* ppObjectTableEntries,
|
|
||||||
const uint32_t* pObjectIndices);
|
|
||||||
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkUnregisterObjectsNVX(
|
|
||||||
VkDevice device,
|
|
||||||
VkObjectTableNVX objectTable,
|
|
||||||
uint32_t objectCount,
|
|
||||||
const VkObjectEntryTypeNVX* pObjectEntryTypes,
|
|
||||||
const uint32_t* pObjectIndices);
|
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceGeneratedCommandsPropertiesNVX(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
VkDeviceGeneratedCommandsFeaturesNVX* pFeatures,
|
|
||||||
VkDeviceGeneratedCommandsLimitsNVX* pLimits);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VK_EXT_direct_mode_display 1
|
|
||||||
#define VK_EXT_DIRECT_MODE_DISPLAY_SPEC_VERSION 1
|
|
||||||
#define VK_EXT_DIRECT_MODE_DISPLAY_EXTENSION_NAME "VK_EXT_direct_mode_display"
|
|
||||||
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkReleaseDisplayEXT)(VkPhysicalDevice physicalDevice, VkDisplayKHR display);
|
|
||||||
|
|
||||||
#ifndef VK_NO_PROTOTYPES
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkReleaseDisplayEXT(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
VkDisplayKHR display);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
|
||||||
#define VK_EXT_acquire_xlib_display 1
|
|
||||||
#include <X11/extensions/Xrandr.h>
|
|
||||||
|
|
||||||
#define VK_EXT_ACQUIRE_XLIB_DISPLAY_SPEC_VERSION 1
|
|
||||||
#define VK_EXT_ACQUIRE_XLIB_DISPLAY_EXTENSION_NAME "VK_EXT_acquire_xlib_display"
|
|
||||||
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkAcquireXlibDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, VkDisplayKHR display);
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkGetRandROutputDisplayEXT)(VkPhysicalDevice physicalDevice, Display* dpy, RROutput rrOutput, VkDisplayKHR* pDisplay);
|
|
||||||
|
|
||||||
#ifndef VK_NO_PROTOTYPES
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireXlibDisplayEXT(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
Display* dpy,
|
|
||||||
VkDisplayKHR display);
|
|
||||||
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetRandROutputDisplayEXT(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
Display* dpy,
|
|
||||||
RROutput rrOutput,
|
|
||||||
VkDisplayKHR* pDisplay);
|
|
||||||
#endif
|
|
||||||
#endif /* VK_USE_PLATFORM_XLIB_XRANDR_EXT */
|
|
||||||
|
|
||||||
#define VK_EXT_display_surface_counter 1
|
|
||||||
#define VK_EXT_DISPLAY_SURFACE_COUNTER_SPEC_VERSION 1
|
|
||||||
#define VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME "VK_EXT_display_surface_counter"
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum VkSurfaceCounterFlagBitsEXT {
|
|
||||||
VK_SURFACE_COUNTER_VBLANK_EXT = 0x00000001,
|
|
||||||
VK_SURFACE_COUNTER_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
|
|
||||||
} VkSurfaceCounterFlagBitsEXT;
|
|
||||||
typedef VkFlags VkSurfaceCounterFlagsEXT;
|
|
||||||
|
|
||||||
typedef struct VkSurfaceCapabilities2EXT {
|
|
||||||
VkStructureType sType;
|
|
||||||
void* pNext;
|
|
||||||
uint32_t minImageCount;
|
|
||||||
uint32_t maxImageCount;
|
|
||||||
VkExtent2D currentExtent;
|
|
||||||
VkExtent2D minImageExtent;
|
|
||||||
VkExtent2D maxImageExtent;
|
|
||||||
uint32_t maxImageArrayLayers;
|
|
||||||
VkSurfaceTransformFlagsKHR supportedTransforms;
|
|
||||||
VkSurfaceTransformFlagBitsKHR currentTransform;
|
|
||||||
VkCompositeAlphaFlagsKHR supportedCompositeAlpha;
|
|
||||||
VkImageUsageFlags supportedUsageFlags;
|
|
||||||
VkSurfaceCounterFlagsEXT supportedSurfaceCounters;
|
|
||||||
} VkSurfaceCapabilities2EXT;
|
|
||||||
|
|
||||||
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT)(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilities2EXT* pSurfaceCapabilities);
|
|
||||||
|
|
||||||
#ifndef VK_NO_PROTOTYPES
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2EXT(
|
|
||||||
VkPhysicalDevice physicalDevice,
|
|
||||||
VkSurfaceKHR surface,
|
|
||||||
VkSurfaceCapabilities2EXT* pSurfaceCapabilities);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VK_EXT_display_control 1
|
|
||||||
#define VK_EXT_DISPLAY_CONTROL_SPEC_VERSION 1
|
|
||||||
#define VK_EXT_DISPLAY_CONTROL_EXTENSION_NAME "VK_EXT_display_control"
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum VkDisplayPowerStateEXT {
|
|
||||||
VK_DISPLAY_POWER_STATE_OFF_EXT = 0,
|
|
||||||
VK_DISPLAY_POWER_STATE_SUSPEND_EXT = 1,
|
|
||||||
VK_DISPLAY_POWER_STATE_ON_EXT = 2,
|
|
||||||
VK_DISPLAY_POWER_STATE_BEGIN_RANGE_EXT = VK_DISPLAY_POWER_STATE_OFF_EXT,
|
|
||||||
VK_DISPLAY_POWER_STATE_END_RANGE_EXT = VK_DISPLAY_POWER_STATE_ON_EXT,
|
|
||||||
VK_DISPLAY_POWER_STATE_RANGE_SIZE_EXT = (VK_DISPLAY_POWER_STATE_ON_EXT - VK_DISPLAY_POWER_STATE_OFF_EXT + 1),
|
|
||||||
VK_DISPLAY_POWER_STATE_MAX_ENUM_EXT = 0x7FFFFFFF
|
|
||||||
} VkDisplayPowerStateEXT;
|
|
||||||
|
|
||||||
typedef enum VkDeviceEventTypeEXT {
|
|
||||||
VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT = 0,
|
|
||||||
VK_DEVICE_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT,
|
|
||||||
VK_DEVICE_EVENT_TYPE_END_RANGE_EXT = VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT,
|
|
||||||
VK_DEVICE_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT - VK_DEVICE_EVENT_TYPE_DISPLAY_HOTPLUG_EXT + 1),
|
|
||||||
VK_DEVICE_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
|
|
||||||
} VkDeviceEventTypeEXT;
|
|
||||||
|
|
||||||
typedef enum VkDisplayEventTypeEXT {
|
|
||||||
VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT = 0,
|
|
||||||
VK_DISPLAY_EVENT_TYPE_BEGIN_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT,
|
|
||||||
VK_DISPLAY_EVENT_TYPE_END_RANGE_EXT = VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT,
|
|
||||||
VK_DISPLAY_EVENT_TYPE_RANGE_SIZE_EXT = (VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT - VK_DISPLAY_EVENT_TYPE_FIRST_PIXEL_OUT_EXT + 1),
|
|
||||||
VK_DISPLAY_EVENT_TYPE_MAX_ENUM_EXT = 0x7FFFFFFF
|
|
||||||
} VkDisplayEventTypeEXT;
|
|
||||||
|
|
||||||
typedef struct VkDisplayPowerInfoEXT {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkDisplayPowerStateEXT powerState;
|
|
||||||
} VkDisplayPowerInfoEXT;
|
|
||||||
|
|
||||||
typedef struct VkDeviceEventInfoEXT {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkDeviceEventTypeEXT deviceEvent;
|
|
||||||
} VkDeviceEventInfoEXT;
|
|
||||||
|
|
||||||
typedef struct VkDisplayEventInfoEXT {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkDisplayEventTypeEXT displayEvent;
|
|
||||||
} VkDisplayEventInfoEXT;
|
|
||||||
|
|
||||||
typedef struct VkSwapchainCounterCreateInfoEXT {
|
|
||||||
VkStructureType sType;
|
|
||||||
const void* pNext;
|
|
||||||
VkSurfaceCounterFlagsEXT surfaceCounters;
|
|
||||||
} VkSwapchainCounterCreateInfoEXT;
|
|
||||||
|
|
||||||
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkDisplayPowerControlEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayPowerInfoEXT* pDisplayPowerInfo);
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkRegisterDeviceEventEXT)(VkDevice device, const VkDeviceEventInfoEXT* pDeviceEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence);
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkRegisterDisplayEventEXT)(VkDevice device, VkDisplayKHR display, const VkDisplayEventInfoEXT* pDisplayEventInfo, const VkAllocationCallbacks* pAllocator, VkFence* pFence);
|
|
||||||
typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainCounterEXT)(VkDevice device, VkSwapchainKHR swapchain, VkSurfaceCounterFlagBitsEXT counter, uint64_t* pCounterValue);
|
|
||||||
|
|
||||||
#ifndef VK_NO_PROTOTYPES
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkDisplayPowerControlEXT(
|
|
||||||
VkDevice device,
|
|
||||||
VkDisplayKHR display,
|
|
||||||
const VkDisplayPowerInfoEXT* pDisplayPowerInfo);
|
|
||||||
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDeviceEventEXT(
|
|
||||||
VkDevice device,
|
|
||||||
const VkDeviceEventInfoEXT* pDeviceEventInfo,
|
|
||||||
const VkAllocationCallbacks* pAllocator,
|
|
||||||
VkFence* pFence);
|
|
||||||
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkRegisterDisplayEventEXT(
|
|
||||||
VkDevice device,
|
|
||||||
VkDisplayKHR display,
|
|
||||||
const VkDisplayEventInfoEXT* pDisplayEventInfo,
|
|
||||||
const VkAllocationCallbacks* pAllocator,
|
|
||||||
VkFence* pFence);
|
|
||||||
|
|
||||||
VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainCounterEXT(
|
|
||||||
VkDevice device,
|
|
||||||
VkSwapchainKHR swapchain,
|
|
||||||
VkSurfaceCounterFlagBitsEXT counter,
|
|
||||||
uint64_t* pCounterValue);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VK_EXT_swapchain_colorspace 1
|
|
||||||
#define VK_SWAPCHAIN_COLOR_SPACE_SPEC_VERSION 1
|
|
||||||
#define VK_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME "VK_EXT_swapchain_colorspace"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+2
-3
@@ -14,12 +14,11 @@ 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/metal.dox"
|
||||||
"${GLFW_SOURCE_DIR}/docs/compat.dox")
|
"${GLFW_SOURCE_DIR}/docs/compat.dox")
|
||||||
|
|
||||||
if (GLFW_DOCUMENT_INTERNALS)
|
if (GLFW_DOCUMENT_INTERNALS)
|
||||||
list(APPEND glfw_DOCS_SOURCES
|
list(APPEND glfw_DOCS_SOURCES "${GLFW_SOURCE_DIR}/src/internal.h")
|
||||||
"${GLFW_SOURCE_DIR}/docs/internal.dox"
|
|
||||||
"${GLFW_SOURCE_DIR}/src/internal.h")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
foreach(arg ${glfw_DOCS_SOURCES})
|
foreach(arg ${glfw_DOCS_SOURCES})
|
||||||
|
|||||||
+2
-3
@@ -204,8 +204,7 @@ ALIASES = "thread_safety=@par Thread safety\n" \
|
|||||||
"x11=__X11:__" \
|
"x11=__X11:__" \
|
||||||
"wayland=__Wayland:__" \
|
"wayland=__Wayland:__" \
|
||||||
"win32=__Windows:__" \
|
"win32=__Windows:__" \
|
||||||
"macos=__macOS:__" \
|
"macos=__macOS:__"
|
||||||
"linux=__Linux:__"
|
|
||||||
|
|
||||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||||
# A mapping has the form "name=value". For example adding
|
# A mapping has the form "name=value". For example adding
|
||||||
@@ -476,7 +475,7 @@ SORT_MEMBER_DOCS = NO
|
|||||||
# by member name. If set to NO (the default) the members will appear in
|
# by member name. If set to NO (the default) the members will appear in
|
||||||
# declaration order.
|
# declaration order.
|
||||||
|
|
||||||
SORT_BRIEF_DOCS = NO
|
SORT_BRIEF_DOCS = YES
|
||||||
|
|
||||||
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
|
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
|
||||||
# will sort the (brief and detailed) documentation of class members so that
|
# will sort the (brief and detailed) documentation of class members so that
|
||||||
|
|||||||
+17
-46
@@ -15,27 +15,27 @@ specific compiler of your chosen development environment. The compilation
|
|||||||
and linking process should be explained in your C programming material and in
|
and linking process should be explained in your C programming material and in
|
||||||
the documentation for your development environment.
|
the documentation for your development environment.
|
||||||
|
|
||||||
|
|
||||||
@section build_include Including the GLFW header file
|
@section build_include Including the GLFW header file
|
||||||
|
|
||||||
You should include the GLFW header in the source files where you use OpenGL or
|
In the source files of your application where you use OpenGL or GLFW, you should
|
||||||
GLFW.
|
include the GLFW header file, i.e.:
|
||||||
|
|
||||||
@code
|
@code
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
This header declares the GLFW API and by default also includes the OpenGL header
|
The GLFW header declares the GLFW API and by default also includes the OpenGL
|
||||||
from your development environment. See below for how to control this.
|
header of your development environment, which in turn defines all the constants,
|
||||||
|
types and function prototypes of the OpenGL API.
|
||||||
|
|
||||||
The GLFW header also defines any platform-specific macros needed by your OpenGL
|
The GLFW header also defines everything necessary for your OpenGL header to
|
||||||
header, so it can be included without needing any window system headers.
|
function. For example, under Windows you are normally required to include
|
||||||
|
`windows.h` before the OpenGL header, which would pollute your code namespace
|
||||||
|
with the entire Win32 API.
|
||||||
|
|
||||||
For example, under Windows you are normally required to include `windows.h`
|
Instead, the GLFW header takes care of this for you, not by including
|
||||||
before the OpenGL header, which would bring in the whole Win32 API. The GLFW
|
`windows.h`, but by duplicating only the very few necessary parts of it. It
|
||||||
header duplicates the small number of macros needed.
|
does this only when needed, so if `windows.h` _is_ included, the GLFW header
|
||||||
|
|
||||||
It does this only when needed, so if `windows.h` _is_ included, the GLFW header
|
|
||||||
does not try to redefine those symbols. The reverse is not true, i.e.
|
does not try to redefine those symbols. The reverse is not true, i.e.
|
||||||
`windows.h` cannot cope if any of its symbols have already been defined.
|
`windows.h` cannot cope if any of its symbols have already been defined.
|
||||||
|
|
||||||
@@ -49,21 +49,8 @@ In other words:
|
|||||||
|
|
||||||
If you are using an OpenGL extension loading library such as
|
If you are using an OpenGL extension loading library such as
|
||||||
[glad](https://github.com/Dav1dde/glad), the extension loader header should
|
[glad](https://github.com/Dav1dde/glad), the extension loader header should
|
||||||
be included _before_ the GLFW one.
|
either be included _before_ the GLFW one, or the @ref GLFW_INCLUDE_NONE macro
|
||||||
|
(described below) should be defined.
|
||||||
@code
|
|
||||||
#include <glad/glad.h>
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Alternatively the @ref GLFW_INCLUDE_NONE macro (described below) can be used to
|
|
||||||
prevent the GLFW header from including the OpenGL header.
|
|
||||||
|
|
||||||
@code
|
|
||||||
#define GLFW_INCLUDE_NONE
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <glad/glad.h>
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
|
|
||||||
@subsection build_macros GLFW header option macros
|
@subsection build_macros GLFW header option macros
|
||||||
@@ -99,10 +86,6 @@ __GLFW_INCLUDE_ES3__ makes the GLFW header include the OpenGL ES 3.0
|
|||||||
__GLFW_INCLUDE_ES31__ makes the GLFW header include the OpenGL ES 3.1
|
__GLFW_INCLUDE_ES31__ makes the GLFW header include the OpenGL ES 3.1
|
||||||
`GLES3/gl31.h` header instead of the regular OpenGL header.
|
`GLES3/gl31.h` header instead of the regular OpenGL header.
|
||||||
|
|
||||||
@anchor GLFW_INCLUDE_ES32
|
|
||||||
__GLFW_INCLUDE_ES31__ makes the GLFW header include the OpenGL ES 3.2
|
|
||||||
`GLES3/gl32.h` header instead of the regular OpenGL header.
|
|
||||||
|
|
||||||
@anchor GLFW_INCLUDE_NONE
|
@anchor GLFW_INCLUDE_NONE
|
||||||
__GLFW_INCLUDE_NONE__ makes the GLFW header not include any OpenGL or OpenGL ES
|
__GLFW_INCLUDE_NONE__ makes the GLFW header not include any OpenGL or OpenGL ES
|
||||||
API header. This is useful in combination with an extension loading library.
|
API header. This is useful in combination with an extension loading library.
|
||||||
@@ -239,8 +222,7 @@ target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
@note GLU has been deprecated and should not be used in new code, but some
|
@note GLU has been deprecated and should not be used in new code, but some
|
||||||
legacy code requires it. See the [section on GLU](@ref moving_glu) in the
|
legacy code requires it.
|
||||||
transition guide for suggested replacements.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_cmake_package With CMake and installed GLFW binaries
|
@subsection build_link_cmake_package With CMake and installed GLFW binaries
|
||||||
@@ -256,15 +238,6 @@ target files generated when GLFW is installed.
|
|||||||
find_package(glfw3 3.3 REQUIRED)
|
find_package(glfw3 3.3 REQUIRED)
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Once GLFW has been added to the project, link against it with the `glfw` target.
|
|
||||||
This adds all link-time dependencies of GLFW as it is currently configured,
|
|
||||||
the include directory for the GLFW header and, when applicable, the @ref
|
|
||||||
GLFW_DLL macro.
|
|
||||||
|
|
||||||
@code{.cmake}
|
|
||||||
target_link_libraries(myapp glfw)
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Note that the dependencies do not include OpenGL or GLU, as GLFW loads any
|
Note that the dependencies do not include OpenGL or GLU, as GLFW loads any
|
||||||
OpenGL, OpenGL ES or Vulkan libraries it needs at runtime and does not use GLU.
|
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
|
If your application calls OpenGL directly, instead of using a modern
|
||||||
@@ -292,8 +265,7 @@ target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
@note GLU has been deprecated and should not be used in new code, but some
|
@note GLU has been deprecated and should not be used in new code, but some
|
||||||
legacy code requires it. See the [section on GLU](@ref moving_glu) in the
|
legacy code requires it.
|
||||||
transition guide for suggested replacements.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
|
@subsection build_link_pkgconfig With makefiles and pkg-config on Unix
|
||||||
@@ -337,8 +309,7 @@ cc `pkg-config --cflags glfw3 glu` -o myprog myprog.c `pkg-config --libs glfw3 g
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
@note GLU has been deprecated and should not be used in new code, but some
|
@note GLU has been deprecated and should not be used in new code, but some
|
||||||
legacy code requires it. See the [section on GLU](@ref moving_glu) in the
|
legacy code requires it.
|
||||||
transition guide for suggested replacements.
|
|
||||||
|
|
||||||
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.
|
||||||
|
|||||||
+9
-14
@@ -76,10 +76,6 @@ GLFW uses the Xkb extension and detectable auto-repeat to provide keyboard
|
|||||||
input. If the running X server does not support this extension, a non-Xkb
|
input. If the running X server does not support this extension, a non-Xkb
|
||||||
fallback path is used.
|
fallback path is used.
|
||||||
|
|
||||||
GLFW uses the XInput2 extension to provide raw, non-accelerated mouse motion
|
|
||||||
when the cursor is disabled. If the running X server does not support this
|
|
||||||
extension, regular accelerated mouse motion will be used.
|
|
||||||
|
|
||||||
|
|
||||||
@section compat_glx GLX extensions
|
@section compat_glx GLX extensions
|
||||||
|
|
||||||
@@ -164,21 +160,21 @@ extensions to provide support for sRGB framebuffers. Where both of these
|
|||||||
extension are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
|
extension are unavailable, the `GLFW_SRGB_CAPABLE` hint will have no effect.
|
||||||
|
|
||||||
|
|
||||||
@section compat_osx OpenGL on macOS
|
@section compat_osx OpenGL 3.2 and later on macOS
|
||||||
|
|
||||||
Support for OpenGL 3.2 and above was introduced with OS X 10.7 and even then
|
Support for OpenGL 3.2 and above was introduced with OS X 10.7 and even then
|
||||||
only forward-compatible, core profile contexts are supported. Support for
|
only forward-compatible, core profile contexts are supported. Support for
|
||||||
OpenGL 4.1 was introduced with OS X 10.9, also limited to forward-compatible,
|
OpenGL 4.1 was introduced with OS X 10.9, also limited to forward-compatible,
|
||||||
core profile contexts. There is also still no mechanism for requesting debug
|
core profile contexts. There is also still no mechanism for requesting debug
|
||||||
contexts or no-error contexts. Versions of Mac OS X earlier than 10.7 support
|
contexts. Versions of Mac OS X earlier than 10.7 support at most OpenGL
|
||||||
at most OpenGL version 2.1.
|
version 2.1.
|
||||||
|
|
||||||
Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and
|
Because of this, on OS X 10.7 and later, the `GLFW_CONTEXT_VERSION_MAJOR` and
|
||||||
`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if
|
`GLFW_CONTEXT_VERSION_MINOR` hints will cause @ref glfwCreateWindow to fail if
|
||||||
given version 3.0 or 3.1. The `GLFW_OPENGL_FORWARD_COMPAT` hint must be set to
|
given version 3.0 or 3.1, the `GLFW_OPENGL_FORWARD_COMPAT` hint must be set to
|
||||||
`GLFW_TRUE` and the `GLFW_OPENGL_PROFILE` hint must be set to
|
`GLFW_TRUE` and the `GLFW_OPENGL_PROFILE` hint must be set to
|
||||||
`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts. The
|
`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts and the
|
||||||
`GLFW_OPENGL_DEBUG_CONTEXT` and `GLFW_CONTEXT_NO_ERROR` hints are ignored.
|
`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored.
|
||||||
|
|
||||||
Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and
|
Also, on Mac OS X 10.6 and below, the `GLFW_CONTEXT_VERSION_MAJOR` and
|
||||||
`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1,
|
`GLFW_CONTEXT_VERSION_MINOR` hints will fail if given a version above 2.1,
|
||||||
@@ -191,10 +187,9 @@ a non-default value will cause @ref glfwCreateWindow to fail and the
|
|||||||
|
|
||||||
By default, GLFW uses the standard system-wide Vulkan loader to access the
|
By default, GLFW uses the standard system-wide Vulkan loader to access the
|
||||||
Vulkan API on all platforms except macOS. This is installed by both graphics
|
Vulkan API on all platforms except macOS. This is installed by both graphics
|
||||||
drivers and Vulkan SDKs. If either the loader or at least one minimally
|
drivers and Vulkan SDKs. If the loader is not found, @ref glfwVulkanSupported
|
||||||
functional ICD is missing, @ref glfwVulkanSupported will return `GLFW_FALSE` and
|
will return `GLFW_FALSE` and all other Vulkan-related functions will fail with
|
||||||
all other Vulkan-related functions will fail with an @ref GLFW_API_UNAVAILABLE
|
an @ref GLFW_API_UNAVAILABLE error.
|
||||||
error.
|
|
||||||
|
|
||||||
|
|
||||||
@section compat_wsi Vulkan WSI extensions
|
@section compat_wsi Vulkan WSI extensions
|
||||||
|
|||||||
+19
-7
@@ -219,6 +219,17 @@ __GLFW_VULKAN_STATIC__ determines whether to use the Vulkan loader linked
|
|||||||
statically into the application.
|
statically into the application.
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection compile_options_osx macOS specific CMake options
|
||||||
|
|
||||||
|
@anchor GLFW_USE_CHDIR
|
||||||
|
__GLFW_USE_CHDIR__ determines whether @ref glfwInit changes the current
|
||||||
|
directory of bundled applications to the `Contents/Resources` directory.
|
||||||
|
|
||||||
|
@anchor GLFW_USE_MENUBAR
|
||||||
|
__GLFW_USE_MENUBAR__ determines whether the first call to @ref glfwCreateWindow
|
||||||
|
sets up a minimal menu bar.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection compile_options_win32 Windows specific CMake options
|
@subsubsection compile_options_win32 Windows specific CMake options
|
||||||
|
|
||||||
@anchor USE_MSVC_RUNTIME_LIBRARY_DLL
|
@anchor USE_MSVC_RUNTIME_LIBRARY_DLL
|
||||||
@@ -257,7 +268,6 @@ ramps and clipboard. The options are:
|
|||||||
- @b _GLFW_WAYLAND to use the Wayland API (experimental and incomplete)
|
- @b _GLFW_WAYLAND to use the Wayland API (experimental and incomplete)
|
||||||
- @b _GLFW_MIR to use the Mir API (experimental and incomplete)
|
- @b _GLFW_MIR to use the Mir API (experimental and incomplete)
|
||||||
- @b _GLFW_OSMESA to use the OSMesa API (headless and non-interactive)
|
- @b _GLFW_OSMESA to use the OSMesa API (headless and non-interactive)
|
||||||
- @b _GLFW_EGLDEVICE to use the EGLDevice API (experimental and incomplete)
|
|
||||||
|
|
||||||
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 @b _GLFW_BUILD_DLL. Otherwise, you must not define it.
|
must also define @b _GLFW_BUILD_DLL. Otherwise, you must not define it.
|
||||||
@@ -266,17 +276,19 @@ If you are linking the Vulkan loader statically into your application then you
|
|||||||
must also define @b _GLFW_VULKAN_STATIC. Otherwise, GLFW will attempt to use the
|
must also define @b _GLFW_VULKAN_STATIC. Otherwise, GLFW will attempt to use the
|
||||||
external version.
|
external version.
|
||||||
|
|
||||||
If you are using a custom name for the Vulkan, EGL, GLX, OSMesa, OpenGL, GLESv1
|
|
||||||
or GLESv2 library, you can override the default names by defining those you need
|
|
||||||
of @b _GLFW_VULKAN_LIBRARY, @b _GLFW_EGL_LIBRARY, @b _GLFW_GLX_LIBRARY, @b
|
|
||||||
_GLFW_OSMESA_LIBRARY, @b _GLFW_OPENGL_LIBRARY, @b _GLFW_GLESV1_LIBRARY and @b
|
|
||||||
_GLFW_GLESV2_LIBRARY. Otherwise, GLFW will use the built-in default names.
|
|
||||||
|
|
||||||
For the EGL context creation API, the following options are available:
|
For the EGL context creation API, the following options are available:
|
||||||
|
|
||||||
- @b _GLFW_USE_EGLPLATFORM_H to use `EGL/eglplatform.h` for native handle
|
- @b _GLFW_USE_EGLPLATFORM_H to use `EGL/eglplatform.h` for native handle
|
||||||
definitions (fallback)
|
definitions (fallback)
|
||||||
|
|
||||||
|
If you are using the Cocoa window creation API, the following options are
|
||||||
|
available:
|
||||||
|
|
||||||
|
- @b _GLFW_USE_CHDIR to `chdir` to the `Resources` subdirectory of the
|
||||||
|
application bundle during @ref glfwInit (recommended)
|
||||||
|
- @b _GLFW_USE_MENUBAR to create and populate the menu bar when the first window
|
||||||
|
is created (recommended)
|
||||||
|
|
||||||
@note None of the @ref build_macros may be defined during the compilation of
|
@note None of the @ref build_macros may be defined during the compilation of
|
||||||
GLFW. If you define any of these in your build files, make sure they are not
|
GLFW. If you define any of these in your build files, make sure they are not
|
||||||
applied to the GLFW sources.
|
applied to the GLFW sources.
|
||||||
|
|||||||
+4
-3
@@ -84,9 +84,10 @@ objects are recommended for rendering with such contexts.
|
|||||||
You should still [process events](@ref events) as long as you have at least one
|
You should still [process events](@ref events) as long as you have at least one
|
||||||
window, even if none of them are visible.
|
window, even if none of them are visible.
|
||||||
|
|
||||||
@macos The first time a window is created the menu bar is created. This is not
|
@macos The first time a window is created the menu bar is populated with
|
||||||
desirable for example when writing a command-line only application. Menu bar
|
common commands like Hide, Quit and About. This is not desirable for example
|
||||||
creation can be disabled with the @ref GLFW_COCOA_MENUBAR init hint.
|
when writing a command-line only application. The menu bar setup can be
|
||||||
|
disabled with a [compile-time option](@ref compile_options_osx).
|
||||||
|
|
||||||
|
|
||||||
@subsection context_less Windows without contexts
|
@subsection context_less Windows without contexts
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-27
@@ -76,17 +76,8 @@
|
|||||||
border:2px solid desaturate(darken(@base-color, 10%), 20%);
|
border:2px solid desaturate(darken(@base-color, 10%), 20%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sm-dox,.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted,.sm-dox ul a:hover {
|
|
||||||
background:none;
|
|
||||||
text-shadow:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sm-dox ul a:hover {
|
#navrow1,#navrow2,#navrow3,#navrow4,.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code {
|
||||||
background:@header-footer-link-color;
|
|
||||||
text-shadow:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main-nav,#navrow1,#navrow2,#navrow3,#navrow4,.tablist a,.tablist a:visited,.tablist a:hover,.tablist li,.tablist li.current a,.memdoc,dl.reflist dd,div.toc li,.ah,span.lineno,span.lineno a,span.lineno a:hover,.note code,.pre code,.post code,.invariant code,.warning code,.attention code,.deprecated code,.bug code,.todo code,.test code,.doxtable code {
|
|
||||||
background:none;
|
background:none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,13 +183,6 @@ address.footer {
|
|||||||
background:@header-footer-link-color;
|
background:@header-footer-link-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
#main-nav {
|
|
||||||
max-width:960px;
|
|
||||||
min-width:800px;
|
|
||||||
margin:0 auto;
|
|
||||||
font-size:13px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navrow1,#navrow2,#navrow3,#navrow4 {
|
#navrow1,#navrow2,#navrow3,#navrow4 {
|
||||||
max-width:920px;
|
max-width:920px;
|
||||||
min-width:800px;
|
min-width:800px;
|
||||||
@@ -206,15 +190,6 @@ address.footer {
|
|||||||
font-size:13px;
|
font-size:13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.memtitle {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.memproto,.memname {
|
|
||||||
font-weight:bold;
|
|
||||||
text-shadow:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tablist {
|
.tablist {
|
||||||
height:36px;
|
height:36px;
|
||||||
display:block;
|
display:block;
|
||||||
@@ -247,7 +222,6 @@ table.doxtable th,dl.reflist dt {
|
|||||||
background:linear-gradient(to bottom,@table-background-color2 0%,@table-background-color1 100%);
|
background:linear-gradient(to bottom,@table-background-color2 0%,@table-background-color1 100%);
|
||||||
box-shadow:inset 0 0 32px @table-background-color1;
|
box-shadow:inset 0 0 32px @table-background-color1;
|
||||||
text-shadow:0 -1px 1px darken(@table-background-color1, 15%);
|
text-shadow:0 -1px 1px darken(@table-background-color1, 15%);
|
||||||
text-align:left;
|
|
||||||
color:@table-text-color;
|
color:@table-text-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ $extrastylesheet
|
|||||||
<ul class="glfwnavbar">
|
<ul class="glfwnavbar">
|
||||||
<li><a href="http://www.glfw.org/documentation.html">Documentation</a></li>
|
<li><a href="http://www.glfw.org/documentation.html">Documentation</a></li>
|
||||||
<li><a href="http://www.glfw.org/download.html">Download</a></li>
|
<li><a href="http://www.glfw.org/download.html">Download</a></li>
|
||||||
|
<li><a href="http://www.glfw.org/media.html">Media</a></li>
|
||||||
<li><a href="http://www.glfw.org/community.html">Community</a></li>
|
<li><a href="http://www.glfw.org/community.html">Community</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+23
-238
@@ -145,9 +145,7 @@ per-window state arrays that can be polled with @ref glfwGetKey.
|
|||||||
@code
|
@code
|
||||||
int state = glfwGetKey(window, GLFW_KEY_E);
|
int state = glfwGetKey(window, GLFW_KEY_E);
|
||||||
if (state == GLFW_PRESS)
|
if (state == GLFW_PRESS)
|
||||||
{
|
|
||||||
activate_airship();
|
activate_airship();
|
||||||
}
|
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
|
The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
|
||||||
@@ -155,7 +153,6 @@ The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
|
|||||||
This function only returns cached key event state. It does not poll the
|
This function only returns cached key event state. It does not poll the
|
||||||
system for the current physical state of the key.
|
system for the current physical state of the key.
|
||||||
|
|
||||||
@anchor GLFW_STICKY_KEYS
|
|
||||||
Whenever you poll state, you risk missing the state change you are looking for.
|
Whenever you poll state, you risk missing the state change you are looking for.
|
||||||
If a pressed key is released again before you poll its state, you will have
|
If a pressed key is released again before you poll its state, you will have
|
||||||
missed the key press. The recommended solution for this is to use a
|
missed the key press. The recommended solution for this is to use a
|
||||||
@@ -181,10 +178,12 @@ GLFW supports text input in the form of a stream of
|
|||||||
operating system text input system. Unlike key input, text input obeys keyboard
|
operating system text input system. Unlike key input, text input obeys keyboard
|
||||||
layouts and modifier keys and supports composing characters using
|
layouts and modifier keys and supports composing characters using
|
||||||
[dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can
|
[dead keys](https://en.wikipedia.org/wiki/Dead_key). Once received, you can
|
||||||
encode the code points into UTF-8 or any other encoding you prefer.
|
encode the code points into
|
||||||
|
[UTF-8](https://en.wikipedia.org/wiki/UTF-8) or any other encoding you prefer.
|
||||||
|
|
||||||
Because an `unsigned int` is 32 bits long on all platforms supported by GLFW,
|
Because an `unsigned int` is 32 bits long on all platforms supported by GLFW,
|
||||||
you can treat the code point argument as native endian UTF-32.
|
you can treat the code point argument as native endian
|
||||||
|
[UTF-32](https://en.wikipedia.org/wiki/UTF-32).
|
||||||
|
|
||||||
There are two callbacks for receiving Unicode code points. If you wish to
|
There are two callbacks for receiving Unicode code points. If you wish to
|
||||||
offer regular text input, set a character callback.
|
offer regular text input, set a character callback.
|
||||||
@@ -272,9 +271,8 @@ glfwGetCursorPos(window, &xpos, &ypos);
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
@subsection cursor_mode Cursor mode
|
@subsection cursor_mode Cursor modes
|
||||||
|
|
||||||
@anchor GLFW_CURSOR
|
|
||||||
The `GLFW_CURSOR` input mode provides several cursor modes for special forms of
|
The `GLFW_CURSOR` input mode provides several cursor modes for special forms of
|
||||||
mouse motion input. By default, the cursor mode is `GLFW_CURSOR_NORMAL`,
|
mouse motion input. By default, the cursor mode is `GLFW_CURSOR_NORMAL`,
|
||||||
meaning the regular arrow cursor (or another cursor set with @ref glfwSetCursor)
|
meaning the regular arrow cursor (or another cursor set with @ref glfwSetCursor)
|
||||||
@@ -344,8 +342,8 @@ If cursor creation fails, `NULL` will be returned, so it is necessary to check
|
|||||||
the return value.
|
the return value.
|
||||||
|
|
||||||
The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits
|
The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits
|
||||||
per channel with the red channel first. The pixels are arranged canonically as
|
per channel. The pixels are arranged canonically as sequential rows, starting
|
||||||
sequential rows, starting from the top-left corner.
|
from the top-left corner.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection cursor_standard Standard cursor creation
|
@subsubsection cursor_standard Standard cursor creation
|
||||||
@@ -369,10 +367,8 @@ When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor.
|
|||||||
glfwDestroyCursor(cursor);
|
glfwDestroyCursor(cursor);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Cursor destruction always succeeds. If the cursor is current for any window,
|
Cursor destruction always succeeds. All cursors remaining when @ref
|
||||||
that window will revert to the default cursor. This does not affect the cursor
|
glfwTerminate is called are destroyed as well.
|
||||||
mode. All remaining cursors remaining are destroyed when @ref glfwTerminate is
|
|
||||||
called.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection cursor_set Cursor setting
|
@subsubsection cursor_set Cursor setting
|
||||||
@@ -389,14 +385,14 @@ to `GLFW_CURSOR_NORMAL`.
|
|||||||
|
|
||||||
A single cursor may be set for any number of windows.
|
A single cursor may be set for any number of windows.
|
||||||
|
|
||||||
To revert to the default cursor, set the cursor of that window to `NULL`.
|
To remove a cursor from a window, set the cursor of that window to `NULL`.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
glfwSetCursor(window, NULL);
|
glfwSetCursor(window, NULL);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
When a cursor is destroyed, any window that has it set will revert to the
|
When a cursor is destroyed, it is removed from any window where it is set. This
|
||||||
default cursor. This does not affect the cursor mode.
|
does not affect the cursor modes of those windows.
|
||||||
|
|
||||||
|
|
||||||
@subsection cursor_enter Cursor enter/leave events
|
@subsection cursor_enter Cursor enter/leave events
|
||||||
@@ -453,9 +449,7 @@ per-window state arrays that can be polled with @ref glfwGetMouseButton.
|
|||||||
@code
|
@code
|
||||||
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
|
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
|
||||||
if (state == GLFW_PRESS)
|
if (state == GLFW_PRESS)
|
||||||
{
|
|
||||||
upgrade_cow();
|
upgrade_cow();
|
||||||
}
|
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
|
The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
|
||||||
@@ -463,7 +457,6 @@ The returned state is one of `GLFW_PRESS` or `GLFW_RELEASE`.
|
|||||||
This function only returns cached mouse button event state. It does not poll
|
This function only returns cached mouse button event state. It does not poll
|
||||||
the system for the current state of the mouse button.
|
the system for the current state of the mouse button.
|
||||||
|
|
||||||
@anchor GLFW_STICKY_MOUSE_BUTTONS
|
|
||||||
Whenever you poll state, you risk missing the state change you are looking for.
|
Whenever you poll state, you risk missing the state change you are looking for.
|
||||||
If a pressed mouse button is released again before you poll its state, you will have
|
If a pressed mouse button is released again before you poll its state, you will have
|
||||||
missed the button press. The recommended solution for this is to use a
|
missed the button press. The recommended solution for this is to use a
|
||||||
@@ -508,24 +501,21 @@ A simple mouse wheel, being vertical, provides offsets along the Y-axis.
|
|||||||
|
|
||||||
The joystick functions expose connected joysticks and controllers, with both
|
The joystick functions expose connected joysticks and controllers, with both
|
||||||
referred to as joysticks. It supports up to sixteen joysticks, ranging from
|
referred to as joysticks. It supports up to sixteen joysticks, ranging from
|
||||||
`GLFW_JOYSTICK_1`, `GLFW_JOYSTICK_2` up to and including `GLFW_JOYSTICK_16` or
|
`GLFW_JOYSTICK_1`, `GLFW_JOYSTICK_2` up to `GLFW_JOYSTICK_LAST`. You can test
|
||||||
`GLFW_JOYSTICK_LAST`. You can test whether a [joystick](@ref joysticks) is
|
whether a [joystick](@ref joysticks) is present with @ref glfwJoystickPresent.
|
||||||
present with @ref glfwJoystickPresent.
|
|
||||||
|
|
||||||
@code
|
@code
|
||||||
int present = glfwJoystickPresent(GLFW_JOYSTICK_1);
|
int present = glfwJoystickPresent(GLFW_JOYSTICK_1);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
When GLFW is initialized, detected joysticks are added to to the beginning of
|
When GLFW is initialized, detected joysticks are added to to the beginning of
|
||||||
the array. Once a joystick is detected, it keeps its assigned ID until it is
|
the array, starting with `GLFW_JOYSTICK_1`. Once a joystick is detected, it
|
||||||
disconnected or the library is terminated, so as joysticks are connected and
|
keeps its assigned index until it is disconnected, so as joysticks are connected
|
||||||
disconnected, there may appear gaps in the IDs.
|
and disconnected, they will become spread out.
|
||||||
|
|
||||||
Joystick axis, button and hat state is updated when polled and does not require
|
Joystick state is updated as needed when a joystick function is called and does
|
||||||
a window to be created or events to be processed. However, if you want joystick
|
not require a window to be created or @ref glfwPollEvents or @ref glfwWaitEvents
|
||||||
connection and disconnection events reliably delivered to the
|
to be called.
|
||||||
[joystick callback](@ref joystick_event) then you must
|
|
||||||
[process events](@ref events).
|
|
||||||
|
|
||||||
To see all the properties of all connected joysticks in real-time, run the
|
To see all the properties of all connected joysticks in real-time, run the
|
||||||
`joysticks` test program.
|
`joysticks` test program.
|
||||||
@@ -539,7 +529,7 @@ returned array.
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
int count;
|
int count;
|
||||||
const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_5, &count);
|
const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &count);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Each element in the returned array is a value between -1.0 and 1.0.
|
Each element in the returned array is a value between -1.0 and 1.0.
|
||||||
@@ -553,55 +543,11 @@ returned array.
|
|||||||
|
|
||||||
@code
|
@code
|
||||||
int count;
|
int count;
|
||||||
const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_3, &count);
|
const unsigned char* axes = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &count);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`.
|
Each element in the returned array is either `GLFW_PRESS` or `GLFW_RELEASE`.
|
||||||
|
|
||||||
For backward compatibility with earlier versions that did not have @ref
|
|
||||||
glfwGetJoystickHats, the button array by default also includes all hats. See
|
|
||||||
the reference documentation for @ref glfwGetJoystickButtons for details.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection joystick_hat Joystick hat states
|
|
||||||
|
|
||||||
The states of all hats are returned by @ref glfwGetJoystickHats. See the
|
|
||||||
reference documentation for the lifetime of the returned array.
|
|
||||||
|
|
||||||
@code
|
|
||||||
int count;
|
|
||||||
const unsigned char* hats = glfwGetJoystickHats(GLFW_JOYSTICK_7, &count);
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Each element in the returned array is one of the following:
|
|
||||||
|
|
||||||
Name | Value
|
|
||||||
--------------------- | --------------------------------
|
|
||||||
`GLFW_HAT_CENTERED` | 0
|
|
||||||
`GLFW_HAT_UP` | 1
|
|
||||||
`GLFW_HAT_RIGHT` | 2
|
|
||||||
`GLFW_HAT_DOWN` | 4
|
|
||||||
`GLFW_HAT_LEFT` | 8
|
|
||||||
`GLFW_HAT_RIGHT_UP` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP`
|
|
||||||
`GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN`
|
|
||||||
`GLFW_HAT_LEFT_UP` | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP`
|
|
||||||
`GLFW_HAT_LEFT_DOWN` | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN`
|
|
||||||
|
|
||||||
The diagonal directions are bitwise combinations of the primary (up, right, down
|
|
||||||
and left) directions and you can test for these individually by ANDing it with
|
|
||||||
the corresponding direction.
|
|
||||||
|
|
||||||
@code
|
|
||||||
if (hats[2] & GLFW_HAT_RIGHT)
|
|
||||||
{
|
|
||||||
// State of hat 2 could be right-up, right or right-down
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
For backward compatibility with earlier versions that did not have @ref
|
|
||||||
glfwGetJoystickHats, all hats are by default also included in the button array.
|
|
||||||
See the reference documentation for @ref glfwGetJoystickButtons for details.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection joystick_name Joystick name
|
@subsection joystick_name Joystick name
|
||||||
|
|
||||||
@@ -610,7 +556,7 @@ glfwGetJoystickName. See the reference documentation for the lifetime of the
|
|||||||
returned string.
|
returned string.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
const char* name = glfwGetJoystickName(GLFW_JOYSTICK_4);
|
const char* name = glfwGetJoystickName(GLFW_JOYSTICK_1);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Joystick names are not guaranteed to be unique. Two joysticks of the same model
|
Joystick names are not guaranteed to be unique. Two joysticks of the same model
|
||||||
@@ -644,165 +590,6 @@ void joystick_callback(int jid, int event)
|
|||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
For joystick connection and disconnection events to be delivered on all
|
|
||||||
platforms, you need to call one of the [event processing](@ref events)
|
|
||||||
functions. Joystick disconnection may also be detected and the callback
|
|
||||||
called by joystick functions. The function will then return whatever it
|
|
||||||
returns for a disconnected joystick.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection gamepad Gamepad input
|
|
||||||
|
|
||||||
The joystick functions provide unlabeled axes, buttons and hats, with no
|
|
||||||
indication of where they are located on the device. Their order may also vary
|
|
||||||
between platforms even with the same device.
|
|
||||||
|
|
||||||
To solve this problem the SDL community crowdsourced the
|
|
||||||
[SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) project,
|
|
||||||
a database of mappings from many different devices to an Xbox-like gamepad.
|
|
||||||
|
|
||||||
GLFW supports this mapping format and contains a copy of the mappings
|
|
||||||
available at the time of release. See @ref gamepad_mapping for how to update
|
|
||||||
this at runtime. Mappings will be assigned to joysticks automatically any time
|
|
||||||
a joystick is connected or the mappings are updated.
|
|
||||||
|
|
||||||
You can check whether a joystick is both present and has a gamepad mapping with
|
|
||||||
@ref glfwJoystickIsGamepad.
|
|
||||||
|
|
||||||
@code
|
|
||||||
if (glfwJoystickIsGamepad(GLFW_JOYSTICK_2))
|
|
||||||
{
|
|
||||||
// Use as gamepad
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
If you are only interested in gamepad input you can use this function instead of
|
|
||||||
@ref glfwJoystickPresent.
|
|
||||||
|
|
||||||
You can query the human-readable name provided by the gamepad mapping with @ref
|
|
||||||
glfwGetGamepadName. This may or may not be the same as the
|
|
||||||
[joystick name](@ref joystick_name).
|
|
||||||
|
|
||||||
@code
|
|
||||||
const char* name = glfwGetGamepadName(GLFW_JOYSTICK_7);
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
To retrieve the gamepad state of a joystick, call @ref glfwGetGamepadState.
|
|
||||||
|
|
||||||
@code
|
|
||||||
GLFWgamepadstate state;
|
|
||||||
|
|
||||||
if (glfwGetGamepadState(GLFW_JOYSTICK_3, &state))
|
|
||||||
{
|
|
||||||
if (state.buttons[GLFW_GAMEPAD_BUTTON_A])
|
|
||||||
{
|
|
||||||
input_jump();
|
|
||||||
}
|
|
||||||
|
|
||||||
input_speed(state.axes[GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER]);
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
The @ref GLFWgamepadstate struct has two arrays; one for button states and one
|
|
||||||
for axis states. The values for each button and axis are the same as for the
|
|
||||||
@ref glfwGetJoystickButtons and @ref glfwGetJoystickAxes functions, i.e.
|
|
||||||
`GLFW_PRESS` or `GLFW_RELEASE` for buttons and -1.0 to 1.0 inclusive for axes.
|
|
||||||
|
|
||||||
The sizes of the arrays and the positions within each array are fixed.
|
|
||||||
|
|
||||||
The [button indices](@ref gamepad_buttons) are `GLFW_GAMEPAD_BUTTON_A`,
|
|
||||||
`GLFW_GAMEPAD_BUTTON_B`, `GLFW_GAMEPAD_BUTTON_X`, `GLFW_GAMEPAD_BUTTON_Y`,
|
|
||||||
`GLFW_GAMEPAD_BUTTON_LEFT_BUMPER`, `GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER`,
|
|
||||||
`GLFW_GAMEPAD_BUTTON_BACK`, `GLFW_GAMEPAD_BUTTON_START`,
|
|
||||||
`GLFW_GAMEPAD_BUTTON_GUIDE`, `GLFW_GAMEPAD_BUTTON_LEFT_THUMB`,
|
|
||||||
`GLFW_GAMEPAD_BUTTON_RIGHT_THUMB`, `GLFW_GAMEPAD_BUTTON_DPAD_UP`,
|
|
||||||
`GLFW_GAMEPAD_BUTTON_DPAD_RIGHT`, `GLFW_GAMEPAD_BUTTON_DPAD_DOWN` and
|
|
||||||
`GLFW_GAMEPAD_BUTTON_DPAD_LEFT`.
|
|
||||||
|
|
||||||
For those who prefer, there are also the `GLFW_GAMEPAD_BUTTON_CROSS`,
|
|
||||||
`GLFW_GAMEPAD_BUTTON_CIRCLE`, `GLFW_GAMEPAD_BUTTON_SQUARE` and
|
|
||||||
`GLFW_GAMEPAD_BUTTON_TRIANGLE` aliases for the A, B, X and Y button indices.
|
|
||||||
|
|
||||||
The [axis indices](@ref gamepad_axes) are `GLFW_GAMEPAD_AXIS_LEFT_X`,
|
|
||||||
`GLFW_GAMEPAD_AXIS_LEFT_Y`, `GLFW_GAMEPAD_AXIS_RIGHT_X`,
|
|
||||||
`GLFW_GAMEPAD_AXIS_RIGHT_Y`, `GLFW_GAMEPAD_AXIS_LEFT_TRIGGER` and
|
|
||||||
`GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER`.
|
|
||||||
|
|
||||||
The `GLFW_GAMEPAD_BUTTON_LAST` and `GLFW_GAMEPAD_AXIS_LAST` constants equal
|
|
||||||
the largest available index for each array.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection gamepad_mapping Gamepad mappings
|
|
||||||
|
|
||||||
GLFW contains a copy of the mappings available in
|
|
||||||
[SDL_GameControllerDB](https://github.com/gabomdq/SDL_GameControllerDB) at the
|
|
||||||
time of release. Newer ones can be added at runtime with @ref
|
|
||||||
glfwUpdateGamepadMappings.
|
|
||||||
|
|
||||||
@code
|
|
||||||
const char* mappings = load_file_contents("gamecontrollerdb.txt");
|
|
||||||
|
|
||||||
glfwUpdateGamepadMappings(mappings);
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
This function supports everything from single lines up to and including the
|
|
||||||
unmodified contents of the whole `gamecontrollerdb.txt` file.
|
|
||||||
|
|
||||||
Below is a description of the mapping format. Please keep in mind that __this
|
|
||||||
description is not authoritative__. The format is defined by the SDL and
|
|
||||||
SDL_GameControllerDB projects and their documentation and code takes precedence.
|
|
||||||
|
|
||||||
Each mapping is a single line of comma-separated values describing the GUID,
|
|
||||||
name and layout of the gamepad. Lines that do not begin with a hexadecimal
|
|
||||||
digit are ignored.
|
|
||||||
|
|
||||||
The first value is always the gamepad GUID, a 32 character long hexadecimal
|
|
||||||
string that typically identifies its make, model, revision and the type of
|
|
||||||
connection to the computer. When this information is not available, the GUID is
|
|
||||||
generated using the gamepad name. GLFW uses the SDL 2.0.5+ GUID format but can
|
|
||||||
convert from the older formats.
|
|
||||||
|
|
||||||
The second value is always the human-readable name of the gamepad.
|
|
||||||
|
|
||||||
All subsequent values are in the form `<field>:<value>` and describe the layout
|
|
||||||
of the mapping. These fields may not all be present and may occur in any order.
|
|
||||||
|
|
||||||
The button fields are `a`, `b`, `c`, `d`, `back`, `start`, `guide`, `dpup`,
|
|
||||||
`dpright`, `dpdown`, `dpleft`, `leftshoulder`, `rightshoulder`, `leftstick` and
|
|
||||||
`rightstick`.
|
|
||||||
|
|
||||||
The axis fields are `leftx`, `lefty`, `rightx`, `righty`, `lefttrigger` and
|
|
||||||
`righttrigger`.
|
|
||||||
|
|
||||||
The value of an axis or button field can be a joystick button, a joystick axis,
|
|
||||||
a hat bitmask or empty. Joystick buttons are specified as `bN`, for example
|
|
||||||
`b2` for the third button. Joystick axes are specified as `aN`, for example
|
|
||||||
`a7` for the eighth button. Joystick hat bit masks are specified as `hN.N`, for
|
|
||||||
example `h0.8` for left on the first hat. More than one bit may be set in the
|
|
||||||
mask.
|
|
||||||
|
|
||||||
The hat bit mask match the [hat states](@ref hat_state) in the joystick
|
|
||||||
functions.
|
|
||||||
|
|
||||||
There is also the special `platform` field that specifies which platform the
|
|
||||||
mapping is valid for. Possible values are `Windows`, `Mac OS X` and `Linux`.
|
|
||||||
Mappings without this field will always be considered valid.
|
|
||||||
|
|
||||||
Below is an example of what a gamepad mapping might look like. It is the
|
|
||||||
one built into GLFW for Xbox controllers accessed via the XInput API on Windows.
|
|
||||||
This example has been broken into several lines to fit on the page, but real
|
|
||||||
gamepad mappings must be a single line.
|
|
||||||
|
|
||||||
@code{.unparsed}
|
|
||||||
78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,
|
|
||||||
b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,
|
|
||||||
rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,
|
|
||||||
righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@note GLFW does not yet support the range and inversion modifiers `+`, `-` and
|
|
||||||
`~` that were recently added to SDL.
|
|
||||||
|
|
||||||
|
|
||||||
@section time Time input
|
@section time Time input
|
||||||
|
|
||||||
@@ -849,9 +636,7 @@ reference documentation for the lifetime of the returned string.
|
|||||||
@code
|
@code
|
||||||
const char* text = glfwGetClipboardString(window);
|
const char* text = glfwGetClipboardString(window);
|
||||||
if (text)
|
if (text)
|
||||||
{
|
|
||||||
insert_text(text);
|
insert_text(text);
|
||||||
}
|
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
If the clipboard is empty or if its contents could not be converted, `NULL` is
|
If the clipboard is empty or if its contents could not be converted, `NULL` is
|
||||||
|
|||||||
+54
-149
@@ -30,10 +30,7 @@ successfully initialized, and only from the main thread.
|
|||||||
|
|
||||||
- @ref glfwGetVersion
|
- @ref glfwGetVersion
|
||||||
- @ref glfwGetVersionString
|
- @ref glfwGetVersionString
|
||||||
- @ref glfwGetError
|
|
||||||
- @ref glfwSetErrorCallback
|
- @ref glfwSetErrorCallback
|
||||||
- @ref glfwInitHint
|
|
||||||
- @ref glfwInitHintString
|
|
||||||
- @ref glfwInit
|
- @ref glfwInit
|
||||||
- @ref glfwTerminate
|
- @ref glfwTerminate
|
||||||
|
|
||||||
@@ -64,66 +61,6 @@ allocated by programs that simply exit, but GLFW sometimes has to change global
|
|||||||
system settings and these might not be restored without termination.
|
system settings and these might not be restored without termination.
|
||||||
|
|
||||||
|
|
||||||
@subsection init_hints Initialization hints
|
|
||||||
|
|
||||||
Initialization hints are set before @ref glfwInit and affect how the library
|
|
||||||
behaves until termination. Integer type hints are set with @ref glfwInitHint
|
|
||||||
and string type hints with @ref glfwInitHintString.
|
|
||||||
|
|
||||||
@code
|
|
||||||
glfwInitHint(GLFW_JOYSTICK_HAT_BUTTONS, GLFW_FALSE);
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
The values you set hints to are never reset by GLFW, but they only take effect
|
|
||||||
during initialization. Once GLFW has been initialized, any values you set will
|
|
||||||
be ignored until the library is terminated and initialized again.
|
|
||||||
|
|
||||||
Some hints are platform specific. These may be set on any platform but they
|
|
||||||
will only affect their specific platform. Other platforms will simply ignore
|
|
||||||
them. Setting these hints requires no platform specific headers or functions.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection init_hints_shared Shared init hints
|
|
||||||
|
|
||||||
@anchor GLFW_JOYSTICK_HAT_BUTTONS
|
|
||||||
__GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
|
|
||||||
buttons, for compatibility with earlier versions of GLFW that did not have @ref
|
|
||||||
glfwGetJoystickHats. Set this with @ref glfwInitHint.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection init_hints_osx macOS specific init hints
|
|
||||||
|
|
||||||
@anchor GLFW_COCOA_CHDIR_RESOURCES
|
|
||||||
__GLFW_COCOA_CHDIR_RESOURCES__ specifies whether to set the current directory to
|
|
||||||
the application to the `Contents/Resources` subdirectory of the application's
|
|
||||||
bundle, if present. Set this with @ref glfwInitHint.
|
|
||||||
|
|
||||||
@anchor GLFW_COCOA_MENUBAR
|
|
||||||
__GLFW_COCOA_MENUBAR__ specifies whether to create a basic menu bar, either from
|
|
||||||
a nib or manually, when the first window is created, which is when AppKit is
|
|
||||||
initialized. Set this with @ref glfwInitHint.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection init_hints_x11 X11 specific init hints
|
|
||||||
|
|
||||||
@anchor GLFW_X11_WM_CLASS_NAME
|
|
||||||
@anchor GLFW_X11_WM_CLASS_CLASS
|
|
||||||
__GLFW_X11_WM_CLASS_NAME__ and __GLFW_X11_WM_CLASS_CLASS__ specifies the desired
|
|
||||||
ASCII encoded name and class parts of the ICCCM `WM_CLASS` hint for all windows.
|
|
||||||
Set this with @ref glfwInitHintString.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection init_hints_values Supported and default values
|
|
||||||
|
|
||||||
Initialization hint | Default value | Supported values
|
|
||||||
------------------------------- | ------------- | ----------------
|
|
||||||
@ref GLFW_JOYSTICK_HAT_BUTTONS | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
|
||||||
@ref GLFW_COCOA_CHDIR_RESOURCES | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
|
||||||
@ref GLFW_COCOA_MENUBAR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
|
||||||
@ref GLFW_X11_WM_CLASS_NAME | `""` | An ASCII encoded `WM_CLASS` name
|
|
||||||
@ref GLFW_X11_WM_CLASS_CLASS | `""` | An ASCII encoded `WM_CLASS` class
|
|
||||||
|
|
||||||
|
|
||||||
@subsection intro_init_terminate Terminating GLFW
|
@subsection intro_init_terminate Terminating GLFW
|
||||||
|
|
||||||
Before your application exits, you should terminate the GLFW library if it has
|
Before your application exits, you should terminate the GLFW library if it has
|
||||||
@@ -146,76 +83,41 @@ immediately.
|
|||||||
@section error_handling Error handling
|
@section error_handling Error handling
|
||||||
|
|
||||||
Some GLFW functions have return values that indicate an error, but this is often
|
Some GLFW functions have return values that indicate an error, but this is often
|
||||||
not very helpful when trying to figure out what happened or why it occurred.
|
not very helpful when trying to figure out _why_ the error occurred. Some
|
||||||
Other functions have no return value reserved for errors, so error notification
|
functions also return otherwise valid values on error. Finally, far from all
|
||||||
needs a separate channel. Finally, far from all GLFW functions have return
|
GLFW functions have return values.
|
||||||
values.
|
|
||||||
|
|
||||||
The last [error code](@ref errors) for the calling thread can be queried at any
|
This is where the error callback comes in. This callback is called whenever an
|
||||||
time with @ref glfwGetError.
|
error occurs. It is set with @ref glfwSetErrorCallback, a function that may be
|
||||||
|
called regardless of whether GLFW is initialized.
|
||||||
@code
|
|
||||||
int code = glfwGetError(NULL);
|
|
||||||
|
|
||||||
if (code != GLFW_NO_ERROR)
|
|
||||||
handle_error(code);
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
If no error has occurred since the last call, @ref GLFW_NO_ERROR (zero) is
|
|
||||||
returned. The error is cleared before the function returns.
|
|
||||||
|
|
||||||
The error code indicates the general category of the error. Some error codes,
|
|
||||||
such as @ref GLFW_NOT_INITIALIZED has only a single meaning, whereas others like
|
|
||||||
@ref GLFW_PLATFORM_ERROR are used for many different errors.
|
|
||||||
|
|
||||||
GLFW often has more information about an error than its general category. You
|
|
||||||
can retrieve a UTF-8 encoded human-readable description along with the error
|
|
||||||
code. If no error has occurred since the last call, the description is set to
|
|
||||||
`NULL`.
|
|
||||||
|
|
||||||
@code
|
|
||||||
const char* description;
|
|
||||||
int code = glfwGetError(&description);
|
|
||||||
|
|
||||||
if (description)
|
|
||||||
display_error_message(code, description);
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
The retrieved description string is only valid until the next error occurs.
|
|
||||||
This means you must make a copy of it if you want to keep it.
|
|
||||||
|
|
||||||
You can also set an error callback, which will be called each time an error
|
|
||||||
occurs. It is set with @ref glfwSetErrorCallback.
|
|
||||||
|
|
||||||
@code
|
@code
|
||||||
glfwSetErrorCallback(error_callback);
|
glfwSetErrorCallback(error_callback);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The error callback receives the same error code and human-readable description
|
The error callback receives a human-readable description of the error and (when
|
||||||
returned by @ref glfwGetError.
|
possible) its cause. The description encoded as UTF-8. The callback is also
|
||||||
|
provided with an [error code](@ref errors).
|
||||||
|
|
||||||
@code
|
@code
|
||||||
void error_callback(int code, const char* description)
|
void error_callback(int error, const char* description)
|
||||||
{
|
{
|
||||||
display_error_message(code, description);
|
puts(description);
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The error callback is called after the error is stored, so calling @ref
|
The error code indicates the general category of the error. Some error codes,
|
||||||
glfwGetError from within the error callback returns the same values as the
|
such as @ref GLFW_NOT_INITIALIZED has only a single meaning, whereas others like
|
||||||
callback argument.
|
@ref GLFW_PLATFORM_ERROR are used for many different errors.
|
||||||
|
|
||||||
The description string passed to the callback is only valid until the error
|
The description string is only valid until the error callback returns, as it may
|
||||||
callback returns. This means you must make a copy of it if you want to keep it.
|
have been generated specifically for that error. This lets GLFW provide much
|
||||||
|
more specific error descriptions but means you must make a copy if you want to
|
||||||
|
keep the description string.
|
||||||
|
|
||||||
__Reported errors are never fatal.__ As long as GLFW was successfully
|
@note Relying on erroneous behavior is not forward compatible. In other words,
|
||||||
initialized, it will remain initialized and in a safe state until terminated
|
do not rely on a currently invalid call to generate a specific error, as that
|
||||||
regardless of how many errors occur. If an error occurs during initialization
|
same call may in future versions generate a different error or become valid.
|
||||||
that causes @ref glfwInit to fail, any part of the library that was initialized
|
|
||||||
will be safely terminated.
|
|
||||||
|
|
||||||
Do not rely on a currently invalid call to generate a specific error, as in the
|
|
||||||
future that same call may generate a different error or become valid.
|
|
||||||
|
|
||||||
|
|
||||||
@section coordinate_systems Coordinate systems
|
@section coordinate_systems Coordinate systems
|
||||||
@@ -286,10 +188,14 @@ releases.
|
|||||||
|
|
||||||
@subsection reentrancy Reentrancy
|
@subsection reentrancy Reentrancy
|
||||||
|
|
||||||
GLFW event processing and object destruction are not reentrant. This means that
|
GLFW event processing and object creation and destruction are not reentrant.
|
||||||
the following functions must not be called from any callback function:
|
This means that the following functions must not be called from any callback
|
||||||
|
function:
|
||||||
|
|
||||||
|
- @ref glfwCreateWindow
|
||||||
- @ref glfwDestroyWindow
|
- @ref glfwDestroyWindow
|
||||||
|
- @ref glfwCreateCursor
|
||||||
|
- @ref glfwCreateStandardCursor
|
||||||
- @ref glfwDestroyCursor
|
- @ref glfwDestroyCursor
|
||||||
- @ref glfwPollEvents
|
- @ref glfwPollEvents
|
||||||
- @ref glfwWaitEvents
|
- @ref glfwWaitEvents
|
||||||
@@ -302,39 +208,35 @@ functions not on this list will not be made non-reentrant.
|
|||||||
|
|
||||||
@subsection thread_safety Thread safety
|
@subsection thread_safety Thread safety
|
||||||
|
|
||||||
Most GLFW functions must only be called from the main thread (the thread that
|
Most GLFW functions must only be called from the main thread, but some may be
|
||||||
calls main), but some may be called from any thread once the library has been
|
called from any thread. However, no GLFW function may be called from any thread
|
||||||
initialized. Before initialization the whole library is thread-unsafe.
|
but the main thread until GLFW has been successfully initialized, including
|
||||||
|
functions that may called before initialization.
|
||||||
|
|
||||||
The reference documentation for every GLFW function states whether it is limited
|
The reference documentation for every GLFW function states whether it is limited
|
||||||
to the main thread.
|
to the main thread.
|
||||||
|
|
||||||
Initialization, termination, event processing and the creation and
|
Initialization and termination, event processing and the creation and
|
||||||
destruction of windows, cursors and OpenGL and OpenGL ES contexts are all
|
destruction of windows, contexts and cursors are all limited to the main thread
|
||||||
restricted to the main thread due to limitations of one or several platforms.
|
due to limitations of one or several platforms.
|
||||||
|
|
||||||
Because event processing must be performed on the main thread, all callbacks
|
Because event processing must be performed on the main thread, all callbacks
|
||||||
except for the error callback will only be called on that thread. The error
|
except for the error callback will only be called on that thread. The error
|
||||||
callback may be called on any thread, as any GLFW function may generate errors.
|
callback may be called on any thread, as any GLFW function may generate errors.
|
||||||
|
|
||||||
The error code and description may be queried from any thread.
|
The posting of empty events may be done from any thread. The window user
|
||||||
|
pointer and close flag may also be accessed and modified from any thread, but
|
||||||
- @ref glfwGetError
|
this is not synchronized by GLFW. The following window related functions may
|
||||||
|
be called from any thread:
|
||||||
Empty events may be posted from any thread.
|
|
||||||
|
|
||||||
- @ref glfwPostEmptyEvent
|
- @ref glfwPostEmptyEvent
|
||||||
|
|
||||||
The window user pointer and close flag may be read and written from any thread,
|
|
||||||
but this is not synchronized by GLFW.
|
|
||||||
|
|
||||||
- @ref glfwGetWindowUserPointer
|
- @ref glfwGetWindowUserPointer
|
||||||
- @ref glfwSetWindowUserPointer
|
- @ref glfwSetWindowUserPointer
|
||||||
- @ref glfwWindowShouldClose
|
- @ref glfwWindowShouldClose
|
||||||
- @ref glfwSetWindowShouldClose
|
- @ref glfwSetWindowShouldClose
|
||||||
|
|
||||||
These functions for working with OpenGL and OpenGL ES contexts may be called
|
Rendering may be done on any thread. The following context related functions
|
||||||
from any thread, but the window object is not synchronized by GLFW.
|
may be called from any thread:
|
||||||
|
|
||||||
- @ref glfwMakeContextCurrent
|
- @ref glfwMakeContextCurrent
|
||||||
- @ref glfwGetCurrentContext
|
- @ref glfwGetCurrentContext
|
||||||
@@ -343,23 +245,27 @@ from any thread, but the window object is not synchronized by GLFW.
|
|||||||
- @ref glfwExtensionSupported
|
- @ref glfwExtensionSupported
|
||||||
- @ref glfwGetProcAddress
|
- @ref glfwGetProcAddress
|
||||||
|
|
||||||
The raw timer functions may be called from any thread.
|
The raw timer may be queried from any thread. The following raw timer related
|
||||||
|
functions may be called from any thread:
|
||||||
|
|
||||||
- @ref glfwGetTimerFrequency
|
- @ref glfwGetTimerFrequency
|
||||||
- @ref glfwGetTimerValue
|
- @ref glfwGetTimerValue
|
||||||
|
|
||||||
The regular timer may be used from any thread, but reading and writing the timer
|
The regular timer may be used from any thread, but the reading and writing of
|
||||||
offset is not synchronized by GLFW.
|
the timer offset is not synchronized by GLFW. The following timer related
|
||||||
|
functions may be called from any thread:
|
||||||
|
|
||||||
- @ref glfwGetTime
|
- @ref glfwGetTime
|
||||||
- @ref glfwSetTime
|
- @ref glfwSetTime
|
||||||
|
|
||||||
Library version information may be queried from any thread.
|
Library version information may be queried from any thread. The following
|
||||||
|
version related functions may be called from any thread:
|
||||||
|
|
||||||
- @ref glfwGetVersion
|
- @ref glfwGetVersion
|
||||||
- @ref glfwGetVersionString
|
- @ref glfwGetVersionString
|
||||||
|
|
||||||
All Vulkan related functions may be called from any thread.
|
Vulkan objects may be created and information queried from any thread. The
|
||||||
|
following Vulkan related functions may be called from any thread:
|
||||||
|
|
||||||
- @ref glfwVulkanSupported
|
- @ref glfwVulkanSupported
|
||||||
- @ref glfwGetRequiredInstanceExtensions
|
- @ref glfwGetRequiredInstanceExtensions
|
||||||
@@ -367,9 +273,9 @@ All Vulkan related functions may be called from any thread.
|
|||||||
- @ref glfwGetPhysicalDevicePresentationSupport
|
- @ref glfwGetPhysicalDevicePresentationSupport
|
||||||
- @ref glfwCreateWindowSurface
|
- @ref glfwCreateWindowSurface
|
||||||
|
|
||||||
GLFW uses synchronization objects internally only to manage the per-thread
|
GLFW uses no synchronization objects internally except for thread-local storage
|
||||||
context and error states. Additional synchronization is left to the
|
to keep track of the current context for each thread. Synchronization is left
|
||||||
application.
|
to the application.
|
||||||
|
|
||||||
Functions that may currently be called from any thread will always remain so,
|
Functions that may currently be called from any thread will always remain so,
|
||||||
but functions that are currently limited to the main thread may be updated to
|
but functions that are currently limited to the main thread may be updated to
|
||||||
@@ -391,9 +297,8 @@ Undocumented behavior, i.e. behavior that is not described in the documentation,
|
|||||||
may change at any time until it is documented.
|
may change at any time until it is documented.
|
||||||
|
|
||||||
If the reference documentation and the implementation differ, the reference
|
If the reference documentation and the implementation differ, the reference
|
||||||
documentation will almost always take precedence and the implementation will be
|
documentation is correct and the implementation will be fixed in the next
|
||||||
fixed in the next release. The reference documentation will also take
|
release.
|
||||||
precedence over anything stated in a guide.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection event_order Event order
|
@subsection event_order Event order
|
||||||
|
|||||||
+3
-1
@@ -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_33 for 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,6 +34,8 @@ 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.
|
||||||
|
|
||||||
|
The @ref metal shows how to use Metal with GLFW on OS X.
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/*!
|
||||||
|
|
||||||
|
@page metal Metal guide
|
||||||
|
|
||||||
|
@tableofcontents
|
||||||
|
|
||||||
|
*/
|
||||||
+2
-2
@@ -195,8 +195,8 @@ glfwSetGammaRamp(monitor, &ramp);
|
|||||||
The gamma ramp data is copied before the function returns, so there is no need
|
The gamma ramp data is copied before the function returns, so there is no need
|
||||||
to keep it around once the ramp has been set.
|
to keep it around once the ramp has been set.
|
||||||
|
|
||||||
It is recommended that your gamma ramp have the same size as the current gamma
|
@note It is recommended to use gamma ramps of size 256, as that is the size
|
||||||
ramp for that monitor.
|
supported by all graphics cards on all platforms.
|
||||||
|
|
||||||
The current gamma ramp for a monitor is returned by @ref glfwGetGammaRamp. See
|
The current gamma ramp for a monitor is returned by @ref glfwGetGammaRamp. See
|
||||||
the reference documentation for the lifetime of the returned structure.
|
the reference documentation for the lifetime of the returned structure.
|
||||||
|
|||||||
@@ -447,13 +447,6 @@ defining @ref GLFW_INCLUDE_GLU before the inclusion of the GLFW header.
|
|||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
There are many libraries that offer replacements for the functionality offered
|
|
||||||
by GLU. For the matrix helper functions, see math libraries like
|
|
||||||
[GLM](https://github.com/g-truc/glm) (for C++),
|
|
||||||
[linmath.h](https://github.com/datenwolf/linmath.h) (for C) and others. For the
|
|
||||||
tessellation functions, see for example
|
|
||||||
[libtess2](https://github.com/memononen/libtess2).
|
|
||||||
|
|
||||||
|
|
||||||
@section moving_tables Name change tables
|
@section moving_tables Name change tables
|
||||||
|
|
||||||
|
|||||||
+11
-99
@@ -1,50 +1,19 @@
|
|||||||
/*!
|
/*!
|
||||||
|
|
||||||
@page news Release notes
|
@page news New features
|
||||||
|
|
||||||
@section news_33 Release notes for 3.3
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_geterror Error query
|
|
||||||
|
|
||||||
GLFW now supports querying the last error code for the calling thread and its
|
|
||||||
human-readable description with @ref glfwGetError.
|
|
||||||
|
|
||||||
@see @ref error_handling
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_gamepad SDL_GameControllerDB support and gamepad input
|
|
||||||
|
|
||||||
GLFW now supports remapping of gamepads and controllers to a 360-like controller
|
|
||||||
layout with @ref glfwJoystickIsGamepad, @ref glfwGetJoystickGUID, @ref
|
|
||||||
glfwGetGamepadName, @ref glfwGetGamepadState and @ref glfwUpdateGamepadMappings,
|
|
||||||
and the input state struct @ref GLFWgamepadstate.
|
|
||||||
|
|
||||||
@sa @ref gamepad
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_attention User attention request
|
|
||||||
|
|
||||||
GLFW now supports requesting user attention to a specific window (on macOS to
|
|
||||||
the application as a whole) with @ref glfwRequestWindowAttention.
|
|
||||||
|
|
||||||
@see @ref window_attention
|
|
||||||
|
|
||||||
|
@section news_33 New features in 3.3
|
||||||
|
|
||||||
@subsection news_33_maximize Window maximization callback
|
@subsection news_33_maximize Window maximization callback
|
||||||
|
|
||||||
GLFW now supports notifying the application that the window has been maximized
|
GLFW now supports window maximization notifications with @ref
|
||||||
@ref glfwSetWindowMaximizeCallback.
|
glfwSetWindowMaximizeCallback.
|
||||||
|
|
||||||
@see @ref window_maximize
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_keyscancode Platform-specific key scancode query
|
@subsection news_33_keyscancode Platform-specific key scancode query
|
||||||
|
|
||||||
GLFW now supports querying the platform dependent scancode of any physical key
|
GLFW now supports querying the platform dependent scancode of any key with
|
||||||
with @ref glfwGetKeyScancode.
|
@ref glfwGetKeyScancode.
|
||||||
|
|
||||||
@see @ref input_key
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_setwindowattrib Support for updating window attributes
|
@subsection news_33_setwindowattrib Support for updating window attributes
|
||||||
@@ -55,77 +24,20 @@ GLFW now supports changing the [GLFW_DECORATED](@ref GLFW_DECORATED_attrib),
|
|||||||
[GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) attributes for existing
|
[GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_attrib) attributes for existing
|
||||||
windows with @ref glfwSetWindowAttrib.
|
windows with @ref glfwSetWindowAttrib.
|
||||||
|
|
||||||
@see @ref window_attribs
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_inithint Support for initialization hints
|
|
||||||
|
|
||||||
GLFW now supports setting library initialization hints with @ref glfwInitHint
|
|
||||||
or @ref glfwInitHintString. These must be set before initialization to take
|
|
||||||
effect.
|
|
||||||
|
|
||||||
@see @ref init_hints
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_platformhints Support for platform specific hints
|
|
||||||
|
|
||||||
GLFW now supports platform specific init and window hints to control system
|
|
||||||
features that are only available on a single platform.
|
|
||||||
|
|
||||||
@see @ref init_hints_osx
|
|
||||||
@see @ref window_hints_osx
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_joyhats Support for joystick hats
|
|
||||||
|
|
||||||
GLFW now supports querying the hats (or POVs or D-pads) of a joystick with @ref
|
|
||||||
glfwGetJoystickHats. Hats are by default also exposed as buttons, but this can
|
|
||||||
be disabled with the @ref GLFW_JOYSTICK_HAT_BUTTONS init hint.
|
|
||||||
|
|
||||||
@see @ref joystick_hat
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_centercursor Cursor centering window hint
|
|
||||||
|
|
||||||
GLFW now supports controlling whether the cursor is centered over newly created
|
|
||||||
full screen windows with the [GLFW_CENTER_CURSOR](@ref GLFW_CENTER_CURSOR_hint)
|
|
||||||
window hint. It is enabled by default.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_rawmotion Support for raw mouse motion
|
|
||||||
|
|
||||||
GLFW now uses raw (unscaled and unaccelerated) mouse motion in disabled cursor
|
|
||||||
mode on platforms where this is available, specifically Windows and X11.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_moltenvk Support for Vulkan on macOS via MoltenVK
|
@subsection news_33_moltenvk Support for Vulkan on macOS via MoltenVK
|
||||||
|
|
||||||
GLFW now supports the `VK_MVK_macos_surface` window surface creation extension
|
GLFW now supports the `VK_MVK_macos_surface` window surface creation extension
|
||||||
provided by [MoltenVK](https://moltengl.com/moltenvk/).
|
provided by [MoltenVK](https://moltengl.com/moltenvk/).
|
||||||
|
|
||||||
@see @ref vulkan_guide
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_osmesa OSMesa backend for headless software rendering
|
@subsection news_33_osmesa OSMesa backend for headless software rendering
|
||||||
|
|
||||||
GLFW now supports creating offscreen OpenGL contexts using
|
GLFW now supports headless context creation and software rendering via OSMesa,
|
||||||
[OSMesa](https://www.mesa3d.org/osmesa.html) by setting
|
intended for automated testing. This backend does not provide input.
|
||||||
[GLFW_CONTEXT_CREATION_API](@ref GLFW_CONTEXT_CREATION_API_hint) to
|
|
||||||
`GLFW_OSMESA_CONTEXT_API`.
|
|
||||||
|
|
||||||
There is also a new null backend that uses OSMesa as its native context
|
|
||||||
creation API, intended for automated testing. This backend does not provide
|
|
||||||
input.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_primary X11 primary selection access
|
@section news_32 New features in 3.2
|
||||||
|
|
||||||
GLFW now supports querying and setting the X11 primary selection via the native
|
|
||||||
access functions @ref glfwGetX11SelectionString and @ref
|
|
||||||
glfwSetX11SelectionString.
|
|
||||||
|
|
||||||
|
|
||||||
@section news_32 Release notes for 3.2
|
|
||||||
|
|
||||||
|
|
||||||
@subsection news_32_vulkan Support for Vulkan
|
@subsection news_32_vulkan Support for Vulkan
|
||||||
@@ -216,7 +128,7 @@ GLFW now supports being used as a
|
|||||||
easy linking with the library and its dependencies.
|
easy linking with the library and its dependencies.
|
||||||
|
|
||||||
|
|
||||||
@section news_31 Release notes for 3.1
|
@section news_31 New features in 3.1
|
||||||
|
|
||||||
These are the release highlights. For a full list of changes see the
|
These are the release highlights. For a full list of changes see the
|
||||||
[version history](http://www.glfw.org/changelog.html).
|
[version history](http://www.glfw.org/changelog.html).
|
||||||
@@ -327,7 +239,7 @@ GLFW now has an _experimental_ Mir display server backend that can be selected
|
|||||||
on Linux with a CMake option.
|
on Linux with a CMake option.
|
||||||
|
|
||||||
|
|
||||||
@section news_30 Release notes for 3.0
|
@section news_30 New features in 3.0
|
||||||
|
|
||||||
These are the release highlights. For a full list of changes see the
|
These are the release highlights. For a full list of changes see the
|
||||||
[version history](http://www.glfw.org/changelog.html).
|
[version history](http://www.glfw.org/changelog.html).
|
||||||
|
|||||||
+15
-19
@@ -20,11 +20,6 @@ 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.
|
||||||
|
|
||||||
@macos Because MoltenVK is typically not installed system-wide, you will need to
|
|
||||||
point CMake to it using the `CMAKE_FRAMEWORK_PATH` variable when configuring the
|
|
||||||
GLFW source tree. Set this variable to the `MoltenVK/macOS` subdirectory of the
|
|
||||||
SDK, either on the command-line or in the CMake GUI.
|
|
||||||
|
|
||||||
For details on a specific function in this category, see the @ref vulkan. There
|
For details on a specific function in this category, see the @ref vulkan. There
|
||||||
are also guides for the other areas of the GLFW API.
|
are also guides for the other areas of the GLFW API.
|
||||||
|
|
||||||
@@ -39,18 +34,19 @@ are also guides for the other areas of the GLFW API.
|
|||||||
|
|
||||||
By default, GLFW will look for the Vulkan loader on demand at runtime via its
|
By default, GLFW will look for the Vulkan loader on demand at runtime via its
|
||||||
standard name (`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other
|
standard name (`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other
|
||||||
Unix-like systems and `libMoltenVK.dylib` on macOS). This means that GLFW does
|
Unix-like systems). This means that GLFW does not need to be linked against the
|
||||||
not need to be linked against the loader. However, it also means that if you
|
loader. However, it also means that if you are using the static library form of
|
||||||
are using the static library form of the Vulkan loader GLFW will either fail to
|
the Vulkan loader GLFW will either fail to find it or (worse) use the wrong one.
|
||||||
find it or (worse) use the wrong one.
|
|
||||||
|
|
||||||
The @ref GLFW_VULKAN_STATIC CMake option makes GLFW link directly against the
|
The @ref GLFW_VULKAN_STATIC CMake option makes GLFW link directly against the
|
||||||
static library form. Not linking against the Vulkan loader will then be
|
static form. Not linking against the Vulkan loader will then be a compile-time
|
||||||
a compile-time error.
|
error.
|
||||||
|
|
||||||
@macos When using the static library form of MoltenVK (i.e. `MetalVK.framework`
|
@macos MoltenVK only provides the static library form of the Vulkan loader, but
|
||||||
and not `libMoltenVK.dylib`) you must also link against its dependencies: the
|
GLFW is able to find it without @ref GLFW_VULKAN_STATIC as long as it is linked
|
||||||
`Cocoa`, `Metal` and `QuartzCore` system frameworks and the `libc++` library.
|
into any of the binaries already loaded into the process. As it is a static
|
||||||
|
library, you must also link against its dependencies: the `Cocoa`, `Metal` and
|
||||||
|
`QuartzCore` frameworks and the `libc++` library.
|
||||||
|
|
||||||
|
|
||||||
@section vulkan_include Including the Vulkan and GLFW header files
|
@section vulkan_include Including the Vulkan and GLFW header files
|
||||||
@@ -85,7 +81,7 @@ section. The canonical desktop loader library exports all Vulkan core and
|
|||||||
Khronos extension functions, allowing them to be called directly.
|
Khronos extension functions, allowing them to be called directly.
|
||||||
|
|
||||||
If you are loading the Vulkan loader dynamically instead of linking directly
|
If you are loading the Vulkan loader dynamically instead of linking directly
|
||||||
against it, you can check for the availability of a loader and ICD with @ref
|
against it, you can check for the availability of a loader with @ref
|
||||||
glfwVulkanSupported.
|
glfwVulkanSupported.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
@@ -95,11 +91,11 @@ if (glfwVulkanSupported())
|
|||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
This function returns `GLFW_TRUE` if the Vulkan loader and any minimally
|
This function returns `GLFW_TRUE` if the Vulkan loader was found. This check is
|
||||||
functional ICD was found.
|
performed by @ref glfwInit.
|
||||||
|
|
||||||
If if one or both were not found, calling any other Vulkan related GLFW function
|
If no loader was found, calling any other Vulkan related GLFW function will
|
||||||
will generate a @ref GLFW_API_UNAVAILABLE error.
|
generate a @ref GLFW_API_UNAVAILABLE error.
|
||||||
|
|
||||||
|
|
||||||
@subsection vulkan_proc Querying Vulkan function pointers
|
@subsection vulkan_proc Querying Vulkan function pointers
|
||||||
|
|||||||
+34
-109
@@ -89,9 +89,6 @@ the desktop. This behavior can be disabled with the
|
|||||||
[GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_hint) window hint, for example if you
|
[GLFW_AUTO_ICONIFY](@ref GLFW_AUTO_ICONIFY_hint) window hint, for example if you
|
||||||
wish to simultaneously cover multiple windows with full screen windows.
|
wish to simultaneously cover multiple windows with full screen windows.
|
||||||
|
|
||||||
If a monitor is disconnected, any window that is full screen on that monitor
|
|
||||||
will be forced into windowed mode. See @ref monitor_event for more information.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection window_windowed_full_screen "Windowed full screen" windows
|
@subsubsection window_windowed_full_screen "Windowed full screen" windows
|
||||||
|
|
||||||
@@ -182,48 +179,38 @@ context, but are ignored when requesting an OpenGL ES context:
|
|||||||
@anchor GLFW_RESIZABLE_hint
|
@anchor GLFW_RESIZABLE_hint
|
||||||
__GLFW_RESIZABLE__ specifies whether the windowed mode window will be resizable
|
__GLFW_RESIZABLE__ specifies whether the windowed mode window will be resizable
|
||||||
_by the user_. The window will still be resizable using the @ref
|
_by the user_. The window will still be resizable using the @ref
|
||||||
glfwSetWindowSize function. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
glfwSetWindowSize function. This hint is ignored for full screen and
|
||||||
This hint is ignored for full screen and undecorated windows.
|
undecorated windows.
|
||||||
|
|
||||||
@anchor GLFW_VISIBLE_hint
|
@anchor GLFW_VISIBLE_hint
|
||||||
__GLFW_VISIBLE__ specifies whether the windowed mode window will be initially
|
__GLFW_VISIBLE__ specifies whether the windowed mode window will be initially
|
||||||
visible. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This hint is
|
visible. This hint is ignored for full screen windows.
|
||||||
ignored for full screen windows.
|
|
||||||
|
|
||||||
@anchor GLFW_DECORATED_hint
|
@anchor GLFW_DECORATED_hint
|
||||||
__GLFW_DECORATED__ specifies whether the windowed mode window will have window
|
__GLFW_DECORATED__ specifies whether the windowed mode window will have window
|
||||||
decorations such as a border, a close widget, etc. An undecorated window will
|
decorations such as a border, a close widget, etc. An undecorated window will
|
||||||
not be resizable by the user but will still allow the user to generate close
|
not be resizable by the user but will still allow the user to generate close
|
||||||
events on some platforms. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
events on some platforms. This hint is ignored for full screen windows.
|
||||||
This hint is ignored for full screen windows.
|
|
||||||
|
|
||||||
@anchor GLFW_FOCUSED_hint
|
@anchor GLFW_FOCUSED_hint
|
||||||
__GLFW_FOCUSED__ specifies whether the windowed mode window will be given input
|
__GLFW_FOCUSED__ specifies whether the windowed mode window will be given input
|
||||||
focus when created. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This
|
focus when created. This hint is ignored for full screen and initially hidden
|
||||||
hint is ignored for full screen and initially hidden windows.
|
windows.
|
||||||
|
|
||||||
@anchor GLFW_AUTO_ICONIFY_hint
|
@anchor GLFW_AUTO_ICONIFY_hint
|
||||||
__GLFW_AUTO_ICONIFY__ specifies whether the full screen window will
|
__GLFW_AUTO_ICONIFY__ specifies whether the full screen window will
|
||||||
automatically iconify and restore the previous video mode on input focus loss.
|
automatically iconify and restore the previous video mode on input focus loss.
|
||||||
Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This hint is ignored for
|
This hint is ignored for windowed mode windows.
|
||||||
windowed mode windows.
|
|
||||||
|
|
||||||
@anchor GLFW_FLOATING_hint
|
@anchor GLFW_FLOATING_hint
|
||||||
__GLFW_FLOATING__ specifies whether the windowed mode window will be floating
|
__GLFW_FLOATING__ specifies whether the windowed mode window will be floating
|
||||||
above other regular windows, also called topmost or always-on-top. This is
|
above other regular windows, also called topmost or always-on-top. This is
|
||||||
intended primarily for debugging purposes and cannot be used to implement proper
|
intended primarily for debugging purposes and cannot be used to implement proper
|
||||||
full screen windows. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This
|
full screen windows. This hint is ignored for full screen windows.
|
||||||
hint is ignored for full screen windows.
|
|
||||||
|
|
||||||
@anchor GLFW_MAXIMIZED_hint
|
@anchor GLFW_MAXIMIZED_hint
|
||||||
__GLFW_MAXIMIZED__ specifies whether the windowed mode window will be maximized
|
__GLFW_MAXIMIZED__ specifies whether the windowed mode window will be maximized
|
||||||
when created. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This hint is
|
when created. This hint is ignored for full screen windows.
|
||||||
ignored for full screen windows.
|
|
||||||
|
|
||||||
@anchor GLFW_CENTER_CURSOR_hint
|
|
||||||
__GLFW_CENTER_CURSOR__ specifies whether the cursor should be centered over
|
|
||||||
newly created full screen windows. Possible values are `GLFW_TRUE` and
|
|
||||||
`GLFW_FALSE`. This hint is ignored for windowed mode windows.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection window_hints_fb Framebuffer related hints
|
@subsubsection window_hints_fb Framebuffer related hints
|
||||||
@@ -261,8 +248,8 @@ Auxiliary buffers are a legacy OpenGL feature and should not be used in new
|
|||||||
code.
|
code.
|
||||||
|
|
||||||
@anchor GLFW_STEREO
|
@anchor GLFW_STEREO
|
||||||
__GLFW_STEREO__ specifies whether to use OpenGL stereoscopic rendering.
|
__GLFW_STEREO__ specifies whether to use OpenGL stereoscopic rendering. This is
|
||||||
Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This is a hard constraint.
|
a hard constraint.
|
||||||
|
|
||||||
@anchor GLFW_SAMPLES
|
@anchor GLFW_SAMPLES
|
||||||
__GLFW_SAMPLES__ specifies the desired number of samples to use for
|
__GLFW_SAMPLES__ specifies the desired number of samples to use for
|
||||||
@@ -271,21 +258,14 @@ the application has no preference.
|
|||||||
|
|
||||||
@anchor GLFW_SRGB_CAPABLE
|
@anchor GLFW_SRGB_CAPABLE
|
||||||
__GLFW_SRGB_CAPABLE__ specifies whether the framebuffer should be sRGB capable.
|
__GLFW_SRGB_CAPABLE__ specifies whether the framebuffer should be sRGB capable.
|
||||||
Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
If supported, a created OpenGL context will support the `GL_FRAMEBUFFER_SRGB`
|
||||||
|
enable, also called `GL_FRAMEBUFFER_SRGB_EXT`) for controlling sRGB rendering
|
||||||
@par
|
and a created OpenGL ES context will always have sRGB rendering enabled.
|
||||||
__OpenGL:__ If enabled and supported by the system, the `GL_FRAMEBUFFER_SRGB`
|
|
||||||
enable will control sRGB rendering. By default, sRGB rendering will be
|
|
||||||
disabled.
|
|
||||||
|
|
||||||
@par
|
|
||||||
__OpenGL ES:__ If enabled and supported by the system, the context will always
|
|
||||||
have sRGB rendering enabled.
|
|
||||||
|
|
||||||
@anchor GLFW_DOUBLEBUFFER
|
@anchor GLFW_DOUBLEBUFFER
|
||||||
__GLFW_DOUBLEBUFFER__ specifies whether the framebuffer should be double
|
__GLFW_DOUBLEBUFFER__ specifies whether the framebuffer should be double
|
||||||
buffered. You nearly always want to use double buffering. This is a hard
|
buffered. You nearly always want to use double buffering. This is a hard
|
||||||
constraint. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
|
constraint.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection window_hints_mtr Monitor related hints
|
@subsubsection window_hints_mtr Monitor related hints
|
||||||
@@ -305,9 +285,9 @@ This is a hard constraint.
|
|||||||
|
|
||||||
@anchor GLFW_CONTEXT_CREATION_API_hint
|
@anchor GLFW_CONTEXT_CREATION_API_hint
|
||||||
__GLFW_CONTEXT_CREATION_API__ specifies which context creation API to use to
|
__GLFW_CONTEXT_CREATION_API__ specifies which context creation API to use to
|
||||||
create the context. Possible values are `GLFW_NATIVE_CONTEXT_API`,
|
create the context. Possible values are `GLFW_NATIVE_CONTEXT_API` and
|
||||||
`GLFW_EGL_CONTEXT_API` and `GLFW_OSMESA_CONTEXT_API`. This is a hard
|
`GLFW_EGL_CONTEXT_API`. This is a hard constraint. If no client API is
|
||||||
constraint. If no client API is requested, this hint is ignored.
|
requested, this hint is ignored.
|
||||||
|
|
||||||
@par
|
@par
|
||||||
@macos The EGL API is not available on this platform and requests to use it
|
@macos The EGL API is not available on this platform and requests to use it
|
||||||
@@ -317,12 +297,6 @@ will fail.
|
|||||||
__Wayland, Mir:__ The EGL API _is_ the native context creation API, so this hint
|
__Wayland, Mir:__ The EGL API _is_ the native context creation API, so this hint
|
||||||
will have no effect.
|
will have no effect.
|
||||||
|
|
||||||
@par
|
|
||||||
__OSMesa:__ As its name implies, an OpenGL context created with OSMesa does not
|
|
||||||
update the window contents when its buffers are swapped. Use OpenGL functions
|
|
||||||
or the OSMesa native access functions @ref glfwGetOSMesaColorBuffer and @ref
|
|
||||||
glfwGetOSMesaDepthBuffer to retrieve the framebuffer contents.
|
|
||||||
|
|
||||||
@note An OpenGL extension loader library that assumes it knows which context
|
@note An OpenGL extension loader library that assumes it knows which context
|
||||||
creation API is used on a given platform may fail if you change this hint. This
|
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
|
||||||
@@ -338,9 +312,6 @@ __GLFW_CONTEXT_VERSION_MAJOR__ and __GLFW_CONTEXT_VERSION_MINOR__ specify the
|
|||||||
client API version that the created context must be compatible with. The exact
|
client 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.
|
||||||
|
|
||||||
@note Do not confuse these hints with `GLFW_VERSION_MAJOR` and
|
|
||||||
`GLFW_VERSION_MINOR`, which provide the API version of the GLFW header.
|
|
||||||
|
|
||||||
@par
|
@par
|
||||||
__OpenGL:__ These hints are not hard constraints, but creation will fail if the
|
__OpenGL:__ These hints are not hard constraints, but creation will fail if the
|
||||||
OpenGL version of the created context is less than the one requested. It is
|
OpenGL version of the created context is less than the one requested. It is
|
||||||
@@ -380,8 +351,7 @@ Forward-compatibility is described in detail in the
|
|||||||
@anchor GLFW_OPENGL_DEBUG_CONTEXT_hint
|
@anchor GLFW_OPENGL_DEBUG_CONTEXT_hint
|
||||||
__GLFW_OPENGL_DEBUG_CONTEXT__ specifies whether to create a debug OpenGL
|
__GLFW_OPENGL_DEBUG_CONTEXT__ specifies whether to create a debug OpenGL
|
||||||
context, which may have additional error and performance issue reporting
|
context, which may have additional error and performance issue reporting
|
||||||
functionality. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If OpenGL ES
|
functionality. If OpenGL ES is requested, this hint is ignored.
|
||||||
is requested, this hint is ignored.
|
|
||||||
|
|
||||||
@anchor GLFW_OPENGL_PROFILE_hint
|
@anchor GLFW_OPENGL_PROFILE_hint
|
||||||
__GLFW_OPENGL_PROFILE__ specifies which OpenGL profile to create the context
|
__GLFW_OPENGL_PROFILE__ specifies which OpenGL profile to create the context
|
||||||
@@ -418,44 +388,28 @@ extension.
|
|||||||
|
|
||||||
@anchor GLFW_CONTEXT_NO_ERROR_hint
|
@anchor GLFW_CONTEXT_NO_ERROR_hint
|
||||||
__GLFW_CONTEXT_NO_ERROR__ specifies whether errors should be generated by the
|
__GLFW_CONTEXT_NO_ERROR__ specifies whether errors should be generated by the
|
||||||
context. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If enabled,
|
context. If enabled, situations that would have generated errors instead cause
|
||||||
situations that would have generated errors instead cause undefined behavior.
|
undefined behavior.
|
||||||
|
|
||||||
@par
|
@par
|
||||||
The no error mode for OpenGL and OpenGL ES is described in detail by the
|
The no error mode for OpenGL and OpenGL ES is described in detail by the
|
||||||
[GL_KHR_no_error](https://www.opengl.org/registry/specs/KHR/no_error.txt)
|
[GL_KHR_no_error](https://www.opengl.org/registry/specs/KHR/no_error.txt)
|
||||||
extension.
|
extension.
|
||||||
|
|
||||||
|
@note This hint is experimental in its current state. There are currently
|
||||||
|
(October 2015) no corresponding WGL or GLX extensions. That makes this hint
|
||||||
|
a [hard constraint](@ref window_hints_hard) for those backends, as creation will
|
||||||
|
fail if unsupported context flags are requested. Once the extensions are
|
||||||
|
available, they will be required and creation of `GL_KHR_no_error` contexts may
|
||||||
|
fail on early drivers where this flag is supported without those extensions
|
||||||
|
being listed.
|
||||||
|
|
||||||
@subsubsection window_hints_osx macOS specific window hints
|
|
||||||
|
@subsubsection window_hints_osx macOS specific hints
|
||||||
|
|
||||||
@anchor GLFW_COCOA_RETINA_FRAMEBUFFER_hint
|
@anchor GLFW_COCOA_RETINA_FRAMEBUFFER_hint
|
||||||
__GLFW_COCOA_RETINA_FRAMEBUFFER__ specifies whether to use full resolution
|
__GLFW_COCOA_RETINA_FRAMEBUFFER__ specifies whether to use full resolution
|
||||||
framebuffers on Retina displays. Possible values are `GLFW_TRUE` and
|
framebuffers on Retina displays. This is ignored on other platforms.
|
||||||
`GLFW_FALSE`. This is ignored on other platforms.
|
|
||||||
|
|
||||||
@anchor GLFW_COCOA_FRAME_AUTOSAVE_hint
|
|
||||||
__GLFW_COCOA_FRAME_AUTOSAVE__ specifies whether to activate frame autosaving
|
|
||||||
using the window title specified at window creation. Possible values are
|
|
||||||
`GLFW_TRUE` and `GLFW_FALSE`. This is ignored on other platforms.
|
|
||||||
|
|
||||||
@anchor GLFW_COCOA_GRAPHICS_SWITCHING_hint
|
|
||||||
__GLFW_COCOA_GRAPHICS_SWITCHING__ specifies whether to in Automatic Graphics
|
|
||||||
Switching, i.e. to allow the system to choose the integrated GPU for the OpenGL
|
|
||||||
context and move it between GPUs if necessary or whether to force it to always
|
|
||||||
run on the discrete GPU. This only affects systems with both integrated and
|
|
||||||
discrete GPUs. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This is
|
|
||||||
ignored on other platforms.
|
|
||||||
|
|
||||||
@par
|
|
||||||
Simpler programs and tools may want to enable this to save power, while games
|
|
||||||
and other applications performing advanced rendering will want to leave it
|
|
||||||
disabled.
|
|
||||||
|
|
||||||
@par
|
|
||||||
A bundled application that wishes to participate in Automatic Graphics Switching
|
|
||||||
should also declare this in its `Info.plist` by setting the
|
|
||||||
`NSSupportsAutomaticGraphicsSwitching` key to `true`.
|
|
||||||
|
|
||||||
|
|
||||||
@subsubsection window_hints_values Supported and default values
|
@subsubsection window_hints_values Supported and default values
|
||||||
@@ -469,7 +423,6 @@ GLFW_FOCUSED | `GLFW_TRUE` | `GLFW_TRUE` or `GL
|
|||||||
GLFW_AUTO_ICONIFY | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_AUTO_ICONIFY | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_FLOATING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_FLOATING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_MAXIMIZED | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_MAXIMIZED | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
|
||||||
GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
@@ -487,7 +440,7 @@ GLFW_STEREO | `GLFW_FALSE` | `GLFW_TRUE` or `GL
|
|||||||
GLFW_SRGB_CAPABLE | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_SRGB_CAPABLE | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_DOUBLEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_DOUBLEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_CLIENT_API | `GLFW_OPENGL_API` | `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API`
|
GLFW_CLIENT_API | `GLFW_OPENGL_API` | `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API`
|
||||||
GLFW_CONTEXT_CREATION_API | `GLFW_NATIVE_CONTEXT_API` | `GLFW_NATIVE_CONTEXT_API`, `GLFW_EGL_CONTEXT_API` or `GLFW_OSMESA_CONTEXT_API`
|
GLFW_CONTEXT_CREATION_API | `GLFW_NATIVE_CONTEXT_API` | `GLFW_NATIVE_CONTEXT_API` or `GLFW_EGL_CONTEXT_API`
|
||||||
GLFW_CONTEXT_VERSION_MAJOR | 1 | Any valid major version number of the chosen client API
|
GLFW_CONTEXT_VERSION_MAJOR | 1 | Any valid major version number of the chosen client API
|
||||||
GLFW_CONTEXT_VERSION_MINOR | 0 | Any valid minor version number of the chosen client API
|
GLFW_CONTEXT_VERSION_MINOR | 0 | Any valid minor version number of the chosen client API
|
||||||
GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET`
|
GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET`
|
||||||
@@ -496,8 +449,6 @@ GLFW_OPENGL_FORWARD_COMPAT | `GLFW_FALSE` | `GLFW_TRUE` or `GL
|
|||||||
GLFW_OPENGL_DEBUG_CONTEXT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_OPENGL_DEBUG_CONTEXT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_OPENGL_PROFILE | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE`
|
GLFW_OPENGL_PROFILE | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE`
|
||||||
GLFW_COCOA_RETINA_FRAMEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_COCOA_RETINA_FRAMEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_COCOA_FRAME_AUTOSAVE | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
|
||||||
GLFW_COCOA_GRAPHICS_SWITCHING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
|
||||||
|
|
||||||
|
|
||||||
@section window_events Window event processing
|
@section window_events Window event processing
|
||||||
@@ -777,10 +728,6 @@ images[1] = load_icon("my_icon_small.png");
|
|||||||
glfwSetWindowIcon(window, 2, images);
|
glfwSetWindowIcon(window, 2, images);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
The image data is 32-bit, little-endian, non-premultiplied RGBA, i.e. eight bits
|
|
||||||
per channel with the red channel first. The pixels are arranged canonically as
|
|
||||||
sequential rows, starting from the top-left corner.
|
|
||||||
|
|
||||||
To revert to the default window icon, pass in an empty image array.
|
To revert to the default window icon, pass in an empty image array.
|
||||||
|
|
||||||
@code
|
@code
|
||||||
@@ -980,10 +927,6 @@ glfwFocusWindow.
|
|||||||
glfwFocusWindow(window);
|
glfwFocusWindow(window);
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
Keep in mind that it can be very disruptive to the user when a window is forced
|
|
||||||
to the top. For a less disruptive way of getting the user's attention, see
|
|
||||||
[attention requests](@ref window_attention).
|
|
||||||
|
|
||||||
If you wish to be notified when a window gains or loses input focus, whether by
|
If you wish to be notified when a window gains or loses input focus, whether by
|
||||||
the user, system or your own code, set a focus callback.
|
the user, system or your own code, set a focus callback.
|
||||||
|
|
||||||
@@ -1022,20 +965,6 @@ glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE);
|
|||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
@subsection window_attention Window attention request
|
|
||||||
|
|
||||||
If you wish to notify the user of an event without interrupting, you can request
|
|
||||||
attention with @ref glfwRequestWindowAttention.
|
|
||||||
|
|
||||||
@code
|
|
||||||
glfwRequestWindowAttention(window);
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
The system will highlight the specified window, or on platforms where this is
|
|
||||||
not supported, the application as a whole. Once the user has given it
|
|
||||||
attention, the system will automatically end the request.
|
|
||||||
|
|
||||||
|
|
||||||
@subsection window_refresh Window damage and refresh
|
@subsection window_refresh Window damage and refresh
|
||||||
|
|
||||||
If you wish to be notified when the contents of a window is damaged and needs
|
If you wish to be notified when the contents of a window is damaged and needs
|
||||||
@@ -1139,8 +1068,8 @@ either `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API`.
|
|||||||
|
|
||||||
@anchor GLFW_CONTEXT_CREATION_API_attrib
|
@anchor GLFW_CONTEXT_CREATION_API_attrib
|
||||||
__GLFW_CONTEXT_CREATION_API__ indicates the context creation API used to create
|
__GLFW_CONTEXT_CREATION_API__ indicates the context creation API used to create
|
||||||
the window's context; either `GLFW_NATIVE_CONTEXT_API`, `GLFW_EGL_CONTEXT_API`
|
the window's context; either `GLFW_NATIVE_CONTEXT_API` or
|
||||||
or `GLFW_OSMESA_CONTEXT_API`.
|
`GLFW_EGL_CONTEXT_API`.
|
||||||
|
|
||||||
@anchor GLFW_CONTEXT_VERSION_MAJOR_attrib
|
@anchor GLFW_CONTEXT_VERSION_MAJOR_attrib
|
||||||
@anchor GLFW_CONTEXT_VERSION_MINOR_attrib
|
@anchor GLFW_CONTEXT_VERSION_MINOR_attrib
|
||||||
@@ -1149,10 +1078,6 @@ __GLFW_CONTEXT_VERSION_MAJOR__, __GLFW_CONTEXT_VERSION_MINOR__ and
|
|||||||
__GLFW_CONTEXT_REVISION__ indicate the client API version of the window's
|
__GLFW_CONTEXT_REVISION__ indicate the client API version of the window's
|
||||||
context.
|
context.
|
||||||
|
|
||||||
@note Do not confuse these attributes with `GLFW_VERSION_MAJOR`,
|
|
||||||
`GLFW_VERSION_MINOR` and `GLFW_VERSION_REVISION` which provide the API version
|
|
||||||
of the GLFW header.
|
|
||||||
|
|
||||||
@anchor GLFW_OPENGL_FORWARD_COMPAT_attrib
|
@anchor GLFW_OPENGL_FORWARD_COMPAT_attrib
|
||||||
__GLFW_OPENGL_FORWARD_COMPAT__ is `GLFW_TRUE` if the window's context is an
|
__GLFW_OPENGL_FORWARD_COMPAT__ is `GLFW_TRUE` if the window's context is an
|
||||||
OpenGL forward-compatible one, or `GLFW_FALSE` otherwise.
|
OpenGL forward-compatible one, or `GLFW_FALSE` otherwise.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ link_libraries(glfw)
|
|||||||
|
|
||||||
include_directories(${glfw_INCLUDE_DIRS} "${GLFW_SOURCE_DIR}/deps")
|
include_directories(${glfw_INCLUDE_DIRS} "${GLFW_SOURCE_DIR}/deps")
|
||||||
|
|
||||||
if (MATH_LIBRARY)
|
if (BUILD_SHARED_LIBS)
|
||||||
link_libraries("${MATH_LIBRARY}")
|
link_libraries("${MATH_LIBRARY}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -39,9 +39,13 @@ add_executable(simple WIN32 MACOSX_BUNDLE simple.c ${ICON} ${GLAD})
|
|||||||
add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD})
|
add_executable(splitview WIN32 MACOSX_BUNDLE splitview.c ${ICON} ${GLAD})
|
||||||
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD})
|
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD})
|
||||||
|
|
||||||
target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}")
|
target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}" "${RT_LIBRARY}")
|
||||||
if (RT_LIBRARY)
|
|
||||||
target_link_libraries(particles "${RT_LIBRARY}")
|
if (APPLE)
|
||||||
|
add_executable(metal MACOSX_BUNDLE metal.m ${ICON})
|
||||||
|
target_compile_options(metal PUBLIC "-fobjc-arc")
|
||||||
|
target_link_libraries(metal "-framework Metal" "-framework QuartzCore")
|
||||||
|
set_target_properties(metal PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Metal")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave)
|
set(WINDOWS_BINARIES boing gears heightmap particles simple splitview wave)
|
||||||
@@ -60,6 +64,7 @@ if (APPLE)
|
|||||||
set_target_properties(boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing")
|
set_target_properties(boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing")
|
||||||
set_target_properties(gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears")
|
set_target_properties(gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears")
|
||||||
set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap")
|
set_target_properties(heightmap PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Heightmap")
|
||||||
|
set_target_properties(metal PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Metal")
|
||||||
set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles")
|
set_target_properties(particles PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Particles")
|
||||||
set_target_properties(simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple")
|
set_target_properties(simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple")
|
||||||
set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView")
|
set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView")
|
||||||
|
|||||||
@@ -0,0 +1,162 @@
|
|||||||
|
//========================================================================
|
||||||
|
// Simple GLFW+Metal example
|
||||||
|
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
//! [code]
|
||||||
|
|
||||||
|
#define GLFW_INCLUDE_NONE
|
||||||
|
#import <GLFW/glfw3.h>
|
||||||
|
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||||
|
#import <GLFW/glfw3native.h>
|
||||||
|
|
||||||
|
#import <Metal/Metal.h>
|
||||||
|
#import <QuartzCore/QuartzCore.h>
|
||||||
|
#import <simd/simd.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static void error_callback(int error, const char* description)
|
||||||
|
{
|
||||||
|
fputs(description, stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||||
|
{
|
||||||
|
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||||
|
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
|
||||||
|
if (!device)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
|
if (!glfwInit())
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
|
GLFWwindow* window = glfwCreateWindow(640, 480, "Metal Example", NULL, NULL);
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
NSWindow* nswin = glfwGetCocoaWindow(window);
|
||||||
|
CAMetalLayer* layer = [CAMetalLayer layer];
|
||||||
|
layer.device = device;
|
||||||
|
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||||
|
nswin.contentView.layer = layer;
|
||||||
|
nswin.contentView.wantsLayer = YES;
|
||||||
|
|
||||||
|
MTLCompileOptions* compileOptions = [MTLCompileOptions new];
|
||||||
|
compileOptions.languageVersion = MTLLanguageVersion1_1;
|
||||||
|
NSError* compileError;
|
||||||
|
id<MTLLibrary> lib = [device newLibraryWithSource:
|
||||||
|
@"#include <metal_stdlib>\n"
|
||||||
|
"using namespace metal;\n"
|
||||||
|
"vertex float4 v_simple(\n"
|
||||||
|
" constant float4* in [[buffer(0)]],\n"
|
||||||
|
" uint vid [[vertex_id]])\n"
|
||||||
|
"{\n"
|
||||||
|
" return in[vid];\n"
|
||||||
|
"}\n"
|
||||||
|
"fragment float4 f_simple(\n"
|
||||||
|
" float4 in [[stage_in]])\n"
|
||||||
|
"{\n"
|
||||||
|
" return float4(1, 0, 0, 1);\n"
|
||||||
|
"}\n"
|
||||||
|
options:compileOptions error:&compileError];
|
||||||
|
if (!lib)
|
||||||
|
{
|
||||||
|
NSLog(@"can't create library: %@", compileError);
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
id<MTLFunction> vs = [lib newFunctionWithName:@"v_simple"];
|
||||||
|
assert(vs);
|
||||||
|
id<MTLFunction> fs = [lib newFunctionWithName:@"f_simple"];
|
||||||
|
assert(fs);
|
||||||
|
|
||||||
|
id<MTLCommandQueue> cq = [device newCommandQueue];
|
||||||
|
assert(cq);
|
||||||
|
|
||||||
|
MTLRenderPipelineDescriptor* rpd = [MTLRenderPipelineDescriptor new];
|
||||||
|
rpd.vertexFunction = vs;
|
||||||
|
rpd.fragmentFunction = fs;
|
||||||
|
rpd.colorAttachments[0].pixelFormat = layer.pixelFormat;
|
||||||
|
id<MTLRenderPipelineState> rps = [device newRenderPipelineStateWithDescriptor:rpd error:NULL];
|
||||||
|
assert(rps);
|
||||||
|
|
||||||
|
glfwSetKeyCallback(window, key_callback);
|
||||||
|
|
||||||
|
while (!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
float ratio;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
ratio = width / (float) height;
|
||||||
|
|
||||||
|
layer.drawableSize = CGSizeMake(width, height);
|
||||||
|
id<CAMetalDrawable> drawable = [layer nextDrawable];
|
||||||
|
assert(drawable);
|
||||||
|
|
||||||
|
id<MTLCommandBuffer> cb = [cq commandBuffer];
|
||||||
|
|
||||||
|
MTLRenderPassDescriptor* rpd = [MTLRenderPassDescriptor new];
|
||||||
|
MTLRenderPassColorAttachmentDescriptor* cd = rpd.colorAttachments[0];
|
||||||
|
cd.texture = drawable.texture;
|
||||||
|
cd.loadAction = MTLLoadActionClear;
|
||||||
|
cd.clearColor = MTLClearColorMake(1.0, 1.0, 1.0, 1.0);
|
||||||
|
cd.storeAction = MTLStoreActionStore;
|
||||||
|
id<MTLRenderCommandEncoder> rce = [cb renderCommandEncoderWithDescriptor:rpd];
|
||||||
|
|
||||||
|
[rce setRenderPipelineState:rps];
|
||||||
|
[rce setVertexBytes:(vector_float4[]){
|
||||||
|
{ 0, 0, 0, 1 },
|
||||||
|
{ -1, 1, 0, 1 },
|
||||||
|
{ 1, 1, 0, 1 },
|
||||||
|
} length:3 * sizeof(vector_float4) atIndex:0];
|
||||||
|
[rce drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];
|
||||||
|
|
||||||
|
[rce endEncoding];
|
||||||
|
[cb presentDrawable:drawable];
|
||||||
|
[cb commit];
|
||||||
|
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
|
||||||
|
glfwTerminate();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! [code]
|
||||||
@@ -87,8 +87,6 @@ int main(void)
|
|||||||
|
|
||||||
glfwSetErrorCallback(error_callback);
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE);
|
|
||||||
|
|
||||||
if (!glfwInit())
|
if (!glfwInit())
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
|||||||
+110
-662
File diff suppressed because it is too large
Load Diff
@@ -45,7 +45,6 @@ extern "C" {
|
|||||||
* more information.
|
* more information.
|
||||||
*/
|
*/
|
||||||
/*! @defgroup native Native access
|
/*! @defgroup native Native access
|
||||||
* @brief Functions related to accessing native handles.
|
|
||||||
*
|
*
|
||||||
* **By using the native access functions you assert that you know what you're
|
* **By using the native access functions you assert that you know what you're
|
||||||
* doing and how to fix problems caused by using them. If you don't, you
|
* doing and how to fix problems caused by using them. If you don't, you
|
||||||
@@ -86,10 +85,7 @@ extern "C" {
|
|||||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||||
// example to allow applications to correctly declare a GL_ARB_debug_output
|
// example to allow applications to correctly declare a GL_ARB_debug_output
|
||||||
// callback) but windows.h assumes no one will define APIENTRY before it does
|
// callback) but windows.h assumes no one will define APIENTRY before it does
|
||||||
#if defined(GLFW_APIENTRY_DEFINED)
|
#undef APIENTRY
|
||||||
#undef APIENTRY
|
|
||||||
#undef GLFW_APIENTRY_DEFINED
|
|
||||||
#endif
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
|
#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
@@ -292,56 +288,6 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
|||||||
* @ingroup native
|
* @ingroup native
|
||||||
*/
|
*/
|
||||||
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
||||||
|
|
||||||
/*! @brief Sets the current primary selection to the specified string.
|
|
||||||
*
|
|
||||||
* @param[in] string A UTF-8 encoded string.
|
|
||||||
*
|
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
|
||||||
* GLFW_PLATFORM_ERROR.
|
|
||||||
*
|
|
||||||
* @pointer_lifetime The specified string is copied before this function
|
|
||||||
* returns.
|
|
||||||
*
|
|
||||||
* @thread_safety This function must only be called from the main thread.
|
|
||||||
*
|
|
||||||
* @sa @ref clipboard
|
|
||||||
* @sa glfwGetX11SelectionString
|
|
||||||
* @sa glfwSetClipboardString
|
|
||||||
*
|
|
||||||
* @since Added in version 3.3.
|
|
||||||
*
|
|
||||||
* @ingroup native
|
|
||||||
*/
|
|
||||||
GLFWAPI void glfwSetX11SelectionString(const char* string);
|
|
||||||
|
|
||||||
/*! @brief Returns the contents of the current primary selection as a string.
|
|
||||||
*
|
|
||||||
* If the selection is empty or if its contents cannot be converted, `NULL`
|
|
||||||
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
|
|
||||||
*
|
|
||||||
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
|
|
||||||
* if an [error](@ref error_handling) occurred.
|
|
||||||
*
|
|
||||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
|
||||||
* GLFW_PLATFORM_ERROR.
|
|
||||||
*
|
|
||||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
|
||||||
* should not free it yourself. It is valid until the next call to @ref
|
|
||||||
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
|
|
||||||
* library is terminated.
|
|
||||||
*
|
|
||||||
* @thread_safety This function must only be called from the main thread.
|
|
||||||
*
|
|
||||||
* @sa @ref clipboard
|
|
||||||
* @sa glfwSetX11SelectionString
|
|
||||||
* @sa glfwGetClipboardString
|
|
||||||
*
|
|
||||||
* @since Added in version 3.3.
|
|
||||||
*
|
|
||||||
* @ingroup native
|
|
||||||
*/
|
|
||||||
GLFWAPI const char* glfwGetX11SelectionString(void);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||||
@@ -447,9 +393,9 @@ GLFWAPI MirConnection* glfwGetMirDisplay(void);
|
|||||||
*/
|
*/
|
||||||
GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
|
GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
|
||||||
|
|
||||||
/*! @brief Returns the `MirWindow*` of the specified window.
|
/*! @brief Returns the `MirSurface*` of the specified window.
|
||||||
*
|
*
|
||||||
* @return The `MirWindow*` of the specified window, or `NULL` if an
|
* @return The `MirSurface*` of the specified window, or `NULL` if an
|
||||||
* [error](@ref error_handling) occurred.
|
* [error](@ref error_handling) occurred.
|
||||||
*
|
*
|
||||||
* @thread_safety This function may be called from any thread. Access is not
|
* @thread_safety This function may be called from any thread. Access is not
|
||||||
@@ -459,7 +405,7 @@ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
|
|||||||
*
|
*
|
||||||
* @ingroup native
|
* @ingroup native
|
||||||
*/
|
*/
|
||||||
GLFWAPI MirWindow* glfwGetMirWindow(GLFWwindow* window);
|
GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||||
|
|||||||
+30
-62
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
set(common_HEADERS internal.h mappings.h
|
set(common_HEADERS internal.h
|
||||||
"${GLFW_BINARY_DIR}/src/glfw_config.h"
|
"${GLFW_BINARY_DIR}/src/glfw_config.h"
|
||||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
|
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.h"
|
||||||
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h")
|
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3native.h")
|
||||||
@@ -7,64 +7,50 @@ set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c)
|
|||||||
|
|
||||||
if (_GLFW_COCOA)
|
if (_GLFW_COCOA)
|
||||||
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
|
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
|
||||||
posix_thread.h nsgl_context.h egl_context.h osmesa_context.h)
|
posix_tls.h nsgl_context.h)
|
||||||
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m
|
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m
|
||||||
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_thread.c
|
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_tls.c
|
||||||
nsgl_context.m egl_context.c osmesa_context.c)
|
nsgl_context.m)
|
||||||
elseif (_GLFW_WIN32)
|
elseif (_GLFW_WIN32)
|
||||||
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h
|
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h
|
||||||
wgl_context.h egl_context.h osmesa_context.h)
|
wgl_context.h egl_context.h)
|
||||||
set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_joystick.c
|
set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_joystick.c
|
||||||
win32_monitor.c win32_time.c win32_thread.c win32_window.c
|
win32_monitor.c win32_time.c win32_tls.c win32_window.c
|
||||||
wgl_context.c egl_context.c osmesa_context.c)
|
wgl_context.c egl_context.c)
|
||||||
elseif (_GLFW_X11)
|
elseif (_GLFW_X11)
|
||||||
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h posix_time.h
|
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h
|
||||||
posix_thread.h glx_context.h egl_context.h osmesa_context.h)
|
linux_joystick.h posix_time.h posix_tls.h glx_context.h
|
||||||
|
egl_context.h)
|
||||||
set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c
|
set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c
|
||||||
xkb_unicode.c posix_time.c posix_thread.c glx_context.c
|
xkb_unicode.c linux_joystick.c posix_time.c posix_tls.c
|
||||||
egl_context.c osmesa_context.c)
|
glx_context.c egl_context.c)
|
||||||
|
|
||||||
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
|
||||||
set(glfw_HEADERS ${glfw_HEADERS} linux_joystick.h)
|
|
||||||
set(glfw_SOURCES ${glfw_SOURCES} linux_joystick.c)
|
|
||||||
else()
|
|
||||||
set(glfw_HEADERS ${glfw_HEADERS} null_joystick.h)
|
|
||||||
set(glfw_SOURCES ${glfw_SOURCES} null_joystick.c)
|
|
||||||
endif()
|
|
||||||
elseif (_GLFW_WAYLAND)
|
elseif (_GLFW_WAYLAND)
|
||||||
set(glfw_HEADERS ${common_HEADERS} wl_platform.h linux_joystick.h
|
set(glfw_HEADERS ${common_HEADERS} wl_platform.h linux_joystick.h
|
||||||
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
|
posix_time.h posix_tls.h xkb_unicode.h egl_context.h)
|
||||||
osmesa_context.h)
|
|
||||||
set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c
|
set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c
|
||||||
linux_joystick.c posix_time.c posix_thread.c xkb_unicode.c
|
linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c
|
||||||
egl_context.c osmesa_context.c)
|
egl_context.c)
|
||||||
|
|
||||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||||
PROTOCOL
|
PROTOCOL
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml"
|
${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/relative-pointer/relative-pointer-unstable-v1.xml
|
||||||
BASENAME relative-pointer-unstable-v1)
|
BASENAME relative-pointer-unstable-v1)
|
||||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||||
PROTOCOL
|
PROTOCOL
|
||||||
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
|
${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml
|
||||||
BASENAME pointer-constraints-unstable-v1)
|
BASENAME pointer-constraints-unstable-v1)
|
||||||
elseif(_GLFW_EGLDEVICE)
|
|
||||||
set(glfw_HEADERS ${common_HEADERS} egldevice_platform.h linux_joystick.h
|
|
||||||
posix_time.h posix_thread.h xkb_unicode.h egl_context.h)
|
|
||||||
set(glfw_SOURCES ${common_SOURCES} egldevice_init.c egldevice_monitor.c egldevice_window.c
|
|
||||||
linux_joystick.c posix_time.c posix_thread.c xkb_unicode.c
|
|
||||||
egl_context.c)
|
|
||||||
elseif (_GLFW_MIR)
|
elseif (_GLFW_MIR)
|
||||||
set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h
|
set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h
|
||||||
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
|
posix_time.h posix_tls.h xkb_unicode.h egl_context.h)
|
||||||
osmesa_context.h)
|
|
||||||
set(glfw_SOURCES ${common_SOURCES} mir_init.c mir_monitor.c mir_window.c
|
set(glfw_SOURCES ${common_SOURCES} mir_init.c mir_monitor.c mir_window.c
|
||||||
linux_joystick.c posix_time.c posix_thread.c xkb_unicode.c
|
linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c
|
||||||
egl_context.c osmesa_context.c)
|
egl_context.c)
|
||||||
elseif (_GLFW_OSMESA)
|
elseif (_GLFW_OSMESA)
|
||||||
set(glfw_HEADERS ${common_HEADERS} null_platform.h null_joystick.h
|
set(glfw_HEADERS ${common_HEADERS} osmesa_platform.h
|
||||||
posix_time.h posix_thread.h osmesa_context.h)
|
posix_time.h posix_tls.h osmesa_context.h)
|
||||||
set(glfw_SOURCES ${common_SOURCES} null_init.c null_monitor.c null_window.c
|
set(glfw_SOURCES ${common_SOURCES} osmesa_init.c osmesa_monitor.c
|
||||||
null_joystick.c posix_time.c posix_thread.c osmesa_context.c)
|
osmesa_window.c posix_time.c posix_tls.c
|
||||||
|
osmesa_context.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
@@ -72,18 +58,6 @@ if (APPLE)
|
|||||||
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
|
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Make GCC and Clang warn about declarations that VS 2010 and 2012 won't accept
|
|
||||||
# for all source files that VS will build
|
|
||||||
if (${CMAKE_C_COMPILER_ID} STREQUAL GNU OR ${CMAKE_C_COMPILER_ID} STREQUAL Clang)
|
|
||||||
if (WIN32)
|
|
||||||
set(windows_SOURCES ${glfw_SOURCES})
|
|
||||||
else()
|
|
||||||
set(windows_SOURCES ${common_SOURCES})
|
|
||||||
endif()
|
|
||||||
set_source_files_properties(${windows_SOURCES} PROPERTIES
|
|
||||||
COMPILE_FLAGS -Wdeclaration-after-statement)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
|
add_library(glfw ${glfw_SOURCES} ${glfw_HEADERS})
|
||||||
set_target_properties(glfw PROPERTIES
|
set_target_properties(glfw PROPERTIES
|
||||||
OUTPUT_NAME ${GLFW_LIB_NAME}
|
OUTPUT_NAME ${GLFW_LIB_NAME}
|
||||||
@@ -92,12 +66,10 @@ set_target_properties(glfw PROPERTIES
|
|||||||
POSITION_INDEPENDENT_CODE ON
|
POSITION_INDEPENDENT_CODE ON
|
||||||
FOLDER "GLFW3")
|
FOLDER "GLFW3")
|
||||||
|
|
||||||
target_compile_definitions(glfw PRIVATE
|
target_compile_definitions(glfw PRIVATE -D_GLFW_USE_CONFIG_H)
|
||||||
_GLFW_USE_CONFIG_H
|
|
||||||
$<$<BOOL:${UNIX}>:_POSIX_C_SOURCE=200809L>)
|
|
||||||
target_include_directories(glfw PUBLIC
|
target_include_directories(glfw PUBLIC
|
||||||
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
|
$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>
|
||||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>")
|
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)
|
||||||
target_include_directories(glfw PRIVATE
|
target_include_directories(glfw PRIVATE
|
||||||
"${GLFW_SOURCE_DIR}/src"
|
"${GLFW_SOURCE_DIR}/src"
|
||||||
"${GLFW_BINARY_DIR}/src"
|
"${GLFW_BINARY_DIR}/src"
|
||||||
@@ -138,7 +110,7 @@ if (BUILD_SHARED_LIBS)
|
|||||||
target_compile_options(glfw PRIVATE "-fvisibility=hidden")
|
target_compile_options(glfw PRIVATE "-fvisibility=hidden")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_compile_definitions(glfw INTERFACE GLFW_DLL)
|
target_compile_definitions(glfw INTERFACE -DGLFW_DLL)
|
||||||
target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES})
|
target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES})
|
||||||
else()
|
else()
|
||||||
target_link_libraries(glfw INTERFACE ${glfw_LIBRARIES})
|
target_link_libraries(glfw INTERFACE ${glfw_LIBRARIES})
|
||||||
@@ -149,10 +121,6 @@ if (MSVC)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (GLFW_INSTALL)
|
if (GLFW_INSTALL)
|
||||||
install(TARGETS glfw
|
install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX})
|
||||||
EXPORT glfwTargets
|
|
||||||
RUNTIME DESTINATION "bin"
|
|
||||||
ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
|
|
||||||
LIBRARY DESTINATION "lib${LIB_SUFFIX}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
+24
-9
@@ -28,6 +28,8 @@
|
|||||||
#include <sys/param.h> // For MAXPATHLEN
|
#include <sys/param.h> // For MAXPATHLEN
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_GLFW_USE_CHDIR)
|
||||||
|
|
||||||
// Change to our application bundle's resources directory, if present
|
// Change to our application bundle's resources directory, if present
|
||||||
//
|
//
|
||||||
static void changeToResourcesDirectory(void)
|
static void changeToResourcesDirectory(void)
|
||||||
@@ -64,6 +66,8 @@ static void changeToResourcesDirectory(void)
|
|||||||
chdir(resourcesPath);
|
chdir(resourcesPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* _GLFW_USE_CHDIR */
|
||||||
|
|
||||||
// Create key code translation tables
|
// Create key code translation tables
|
||||||
//
|
//
|
||||||
static void createKeyTables(void)
|
static void createKeyTables(void)
|
||||||
@@ -215,9 +219,8 @@ static GLFWbool updateUnicodeDataNS(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.ns.unicodeData =
|
_glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource,
|
||||||
TISGetInputSourceProperty(_glfw.ns.inputSource,
|
kTISPropertyUnicodeKeyLayoutData);
|
||||||
kTISPropertyUnicodeKeyLayoutData);
|
|
||||||
if (!_glfw.ns.unicodeData)
|
if (!_glfw.ns.unicodeData)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@@ -233,8 +236,7 @@ static GLFWbool updateUnicodeDataNS(void)
|
|||||||
static GLFWbool initializeTIS(void)
|
static GLFWbool initializeTIS(void)
|
||||||
{
|
{
|
||||||
// This works only because Cocoa has already loaded it properly
|
// This works only because Cocoa has already loaded it properly
|
||||||
_glfw.ns.tis.bundle =
|
_glfw.ns.tis.bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
|
||||||
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
|
|
||||||
if (!_glfw.ns.tis.bundle)
|
if (!_glfw.ns.tis.bundle)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@@ -292,9 +294,6 @@ int _glfwPlatformInit(void)
|
|||||||
{
|
{
|
||||||
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
|
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
if (_glfw.hints.init.ns.chdir)
|
|
||||||
changeToResourcesDirectory();
|
|
||||||
|
|
||||||
_glfw.ns.listener = [[GLFWLayoutListener alloc] init];
|
_glfw.ns.listener = [[GLFWLayoutListener alloc] init];
|
||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
addObserver:_glfw.ns.listener
|
addObserver:_glfw.ns.listener
|
||||||
@@ -302,6 +301,10 @@ int _glfwPlatformInit(void)
|
|||||||
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
||||||
object:nil];
|
object:nil];
|
||||||
|
|
||||||
|
#if defined(_GLFW_USE_CHDIR)
|
||||||
|
changeToResourcesDirectory();
|
||||||
|
#endif
|
||||||
|
|
||||||
createKeyTables();
|
createKeyTables();
|
||||||
|
|
||||||
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||||
@@ -313,10 +316,12 @@ int _glfwPlatformInit(void)
|
|||||||
if (!initializeTIS())
|
if (!initializeTIS())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
_glfwInitTimerNS();
|
_glfwInitTimerNS();
|
||||||
_glfwInitJoysticksNS();
|
_glfwInitJoysticksNS();
|
||||||
|
|
||||||
_glfwPollMonitorsNS();
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,10 +359,14 @@ void _glfwPlatformTerminate(void)
|
|||||||
_glfw.ns.listener = nil;
|
_glfw.ns.listener = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[_glfw.ns.cursor release];
|
||||||
|
_glfw.ns.cursor = nil;
|
||||||
|
|
||||||
free(_glfw.ns.clipboardString);
|
free(_glfw.ns.clipboardString);
|
||||||
|
|
||||||
_glfwTerminateNSGL();
|
_glfwTerminateNSGL();
|
||||||
_glfwTerminateJoysticksNS();
|
_glfwTerminateJoysticksNS();
|
||||||
|
_glfwTerminateThreadLocalStoragePOSIX();
|
||||||
|
|
||||||
[_glfw.ns.autoreleasePool release];
|
[_glfw.ns.autoreleasePool release];
|
||||||
_glfw.ns.autoreleasePool = nil;
|
_glfw.ns.autoreleasePool = nil;
|
||||||
@@ -366,6 +375,12 @@ void _glfwPlatformTerminate(void)
|
|||||||
const char* _glfwPlatformGetVersionString(void)
|
const char* _glfwPlatformGetVersionString(void)
|
||||||
{
|
{
|
||||||
return _GLFW_VERSION_NUMBER " Cocoa NSGL"
|
return _GLFW_VERSION_NUMBER " Cocoa NSGL"
|
||||||
|
#if defined(_GLFW_USE_CHDIR)
|
||||||
|
" chdir"
|
||||||
|
#endif
|
||||||
|
#if defined(_GLFW_USE_MENUBAR)
|
||||||
|
" menubar"
|
||||||
|
#endif
|
||||||
#if defined(_GLFW_BUILD_DLL)
|
#if defined(_GLFW_BUILD_DLL)
|
||||||
" dynamic"
|
" dynamic"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+17
-7
@@ -24,27 +24,37 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_cocoa_joystick_h_
|
||||||
|
#define _glfw3_cocoa_joystick_h_
|
||||||
|
|
||||||
#include <IOKit/IOKitLib.h>
|
#include <IOKit/IOKitLib.h>
|
||||||
#include <IOKit/IOCFPlugIn.h>
|
#include <IOKit/IOCFPlugIn.h>
|
||||||
#include <IOKit/hid/IOHIDLib.h>
|
#include <IOKit/hid/IOHIDLib.h>
|
||||||
#include <IOKit/hid/IOHIDKeys.h>
|
#include <IOKit/hid/IOHIDKeys.h>
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
|
||||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
|
_GLFWjoystickNS ns_js[GLFW_JOYSTICK_LAST + 1]
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X"
|
|
||||||
|
|
||||||
// Cocoa-specific per-joystick data
|
// Cocoa-specific per-joystick data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWjoystickNS
|
typedef struct _GLFWjoystickNS
|
||||||
{
|
{
|
||||||
IOHIDDeviceRef device;
|
GLFWbool present;
|
||||||
CFMutableArrayRef axes;
|
char name[256];
|
||||||
CFMutableArrayRef buttons;
|
|
||||||
CFMutableArrayRef hats;
|
IOHIDDeviceRef deviceRef;
|
||||||
|
|
||||||
|
CFMutableArrayRef axisElements;
|
||||||
|
CFMutableArrayRef buttonElements;
|
||||||
|
CFMutableArrayRef hatElements;
|
||||||
|
|
||||||
|
float* axes;
|
||||||
|
unsigned char* buttons;
|
||||||
} _GLFWjoystickNS;
|
} _GLFWjoystickNS;
|
||||||
|
|
||||||
|
|
||||||
void _glfwInitJoysticksNS(void);
|
void _glfwInitJoysticksNS(void);
|
||||||
void _glfwTerminateJoysticksNS(void);
|
void _glfwTerminateJoysticksNS(void);
|
||||||
|
|
||||||
|
#endif // _glfw3_cocoa_joystick_h_
|
||||||
|
|||||||
+358
-309
@@ -42,167 +42,42 @@
|
|||||||
//
|
//
|
||||||
typedef struct _GLFWjoyelementNS
|
typedef struct _GLFWjoyelementNS
|
||||||
{
|
{
|
||||||
IOHIDElementRef native;
|
IOHIDElementRef elementRef;
|
||||||
uint32_t usage;
|
|
||||||
int index;
|
long min;
|
||||||
long minimum;
|
long max;
|
||||||
long maximum;
|
|
||||||
|
long minReport;
|
||||||
|
long maxReport;
|
||||||
|
|
||||||
} _GLFWjoyelementNS;
|
} _GLFWjoyelementNS;
|
||||||
|
|
||||||
|
|
||||||
// Returns the value of the specified element of the specified joystick
|
static void getElementsCFArrayHandler(const void* value, void* parameter);
|
||||||
//
|
|
||||||
static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
|
|
||||||
{
|
|
||||||
IOHIDValueRef valueRef;
|
|
||||||
long value = 0;
|
|
||||||
|
|
||||||
if (js->ns.device)
|
// Adds an element to the specified joystick
|
||||||
|
//
|
||||||
|
static void addJoystickElement(_GLFWjoystickNS* js,
|
||||||
|
IOHIDElementRef elementRef)
|
||||||
|
{
|
||||||
|
IOHIDElementType elementType;
|
||||||
|
long usagePage, usage;
|
||||||
|
CFMutableArrayRef elementsArray = NULL;
|
||||||
|
|
||||||
|
elementType = IOHIDElementGetType(elementRef);
|
||||||
|
usagePage = IOHIDElementGetUsagePage(elementRef);
|
||||||
|
usage = IOHIDElementGetUsage(elementRef);
|
||||||
|
|
||||||
|
if ((elementType != kIOHIDElementTypeInput_Axis) &&
|
||||||
|
(elementType != kIOHIDElementTypeInput_Button) &&
|
||||||
|
(elementType != kIOHIDElementTypeInput_Misc))
|
||||||
{
|
{
|
||||||
if (IOHIDDeviceGetValue(js->ns.device,
|
|
||||||
element->native,
|
|
||||||
&valueRef) == kIOReturnSuccess)
|
|
||||||
{
|
|
||||||
value = IOHIDValueGetIntegerValue(valueRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Comparison function for matching the SDL element order
|
|
||||||
//
|
|
||||||
static CFComparisonResult compareElements(const void* fp,
|
|
||||||
const void* sp,
|
|
||||||
void* user)
|
|
||||||
{
|
|
||||||
const _GLFWjoyelementNS* fe = fp;
|
|
||||||
const _GLFWjoyelementNS* se = sp;
|
|
||||||
if (fe->usage < se->usage)
|
|
||||||
return kCFCompareLessThan;
|
|
||||||
if (fe->usage > se->usage)
|
|
||||||
return kCFCompareGreaterThan;
|
|
||||||
if (fe->index < se->index)
|
|
||||||
return kCFCompareLessThan;
|
|
||||||
if (fe->index > se->index)
|
|
||||||
return kCFCompareGreaterThan;
|
|
||||||
return kCFCompareEqualTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes the specified joystick
|
|
||||||
//
|
|
||||||
static void closeJoystick(_GLFWjoystick* js)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!js->present)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
|
||||||
free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
|
|
||||||
CFRelease(js->ns.axes);
|
|
||||||
|
|
||||||
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
|
||||||
free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
|
|
||||||
CFRelease(js->ns.buttons);
|
|
||||||
|
|
||||||
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
|
||||||
free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
|
|
||||||
CFRelease(js->ns.hats);
|
|
||||||
|
|
||||||
_glfwFreeJoystick(js);
|
|
||||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callback for user-initiated joystick addition
|
|
||||||
//
|
|
||||||
static void matchCallback(void* context,
|
|
||||||
IOReturn result,
|
|
||||||
void* sender,
|
|
||||||
IOHIDDeviceRef device)
|
|
||||||
{
|
|
||||||
int jid;
|
|
||||||
char name[256];
|
|
||||||
char guid[33];
|
|
||||||
CFIndex i;
|
|
||||||
CFTypeRef property;
|
|
||||||
uint32_t vendor = 0, product = 0, version = 0;
|
|
||||||
_GLFWjoystick* js;
|
|
||||||
CFMutableArrayRef axes, buttons, hats;
|
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
{
|
|
||||||
if (_glfw.joysticks[jid].ns.device == device)
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
axes = CFArrayCreateMutable(NULL, 0, NULL);
|
switch (usagePage)
|
||||||
buttons = CFArrayCreateMutable(NULL, 0, NULL);
|
|
||||||
hats = CFArrayCreateMutable(NULL, 0, NULL);
|
|
||||||
|
|
||||||
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
|
|
||||||
if (property)
|
|
||||||
{
|
{
|
||||||
CFStringGetCString(property,
|
case kHIDPage_GenericDesktop:
|
||||||
name,
|
|
||||||
sizeof(name),
|
|
||||||
kCFStringEncodingUTF8);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
strncpy(name, "Unknown", sizeof(name));
|
|
||||||
|
|
||||||
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey));
|
|
||||||
if (property)
|
|
||||||
CFNumberGetValue(property, kCFNumberSInt32Type, &vendor);
|
|
||||||
|
|
||||||
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey));
|
|
||||||
if (property)
|
|
||||||
CFNumberGetValue(property, kCFNumberSInt32Type, &product);
|
|
||||||
|
|
||||||
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVersionNumberKey));
|
|
||||||
if (property)
|
|
||||||
CFNumberGetValue(property, kCFNumberSInt32Type, &version);
|
|
||||||
|
|
||||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
|
||||||
if (vendor && product)
|
|
||||||
{
|
|
||||||
sprintf(guid, "03000000%02x%02x0000%02x%02x0000%02x%02x0000",
|
|
||||||
(uint8_t) vendor, (uint8_t) (vendor >> 8),
|
|
||||||
(uint8_t) product, (uint8_t) (product >> 8),
|
|
||||||
(uint8_t) version, (uint8_t) (version >> 8));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
|
||||||
name[0], name[1], name[2], name[3],
|
|
||||||
name[4], name[5], name[6], name[7],
|
|
||||||
name[8], name[9], name[10]);
|
|
||||||
}
|
|
||||||
|
|
||||||
CFArrayRef elements =
|
|
||||||
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
|
|
||||||
|
|
||||||
for (i = 0; i < CFArrayGetCount(elements); i++)
|
|
||||||
{
|
|
||||||
IOHIDElementRef native = (IOHIDElementRef)
|
|
||||||
CFArrayGetValueAtIndex(elements, i);
|
|
||||||
if (CFGetTypeID(native) != IOHIDElementGetTypeID())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const IOHIDElementType type = IOHIDElementGetType(native);
|
|
||||||
if ((type != kIOHIDElementTypeInput_Axis) &&
|
|
||||||
(type != kIOHIDElementTypeInput_Button) &&
|
|
||||||
(type != kIOHIDElementTypeInput_Misc))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
CFMutableArrayRef target = NULL;
|
|
||||||
|
|
||||||
const uint32_t usage = IOHIDElementGetUsage(native);
|
|
||||||
const uint32_t page = IOHIDElementGetUsagePage(native);
|
|
||||||
if (page == kHIDPage_GenericDesktop)
|
|
||||||
{
|
{
|
||||||
switch (usage)
|
switch (usage)
|
||||||
{
|
{
|
||||||
@@ -215,48 +90,241 @@ static void matchCallback(void* context,
|
|||||||
case kHIDUsage_GD_Slider:
|
case kHIDUsage_GD_Slider:
|
||||||
case kHIDUsage_GD_Dial:
|
case kHIDUsage_GD_Dial:
|
||||||
case kHIDUsage_GD_Wheel:
|
case kHIDUsage_GD_Wheel:
|
||||||
target = axes;
|
elementsArray = js->axisElements;
|
||||||
break;
|
break;
|
||||||
case kHIDUsage_GD_Hatswitch:
|
case kHIDUsage_GD_Hatswitch:
|
||||||
target = hats;
|
elementsArray = js->hatElements;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if (page == kHIDPage_Button)
|
|
||||||
target = buttons;
|
|
||||||
|
|
||||||
if (target)
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kHIDPage_Button:
|
||||||
|
elementsArray = js->buttonElements;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementsArray)
|
||||||
|
{
|
||||||
|
_GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS));
|
||||||
|
|
||||||
|
CFArrayAppendValue(elementsArray, element);
|
||||||
|
|
||||||
|
element->elementRef = elementRef;
|
||||||
|
|
||||||
|
element->minReport = IOHIDElementGetLogicalMin(elementRef);
|
||||||
|
element->maxReport = IOHIDElementGetLogicalMax(elementRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds an element to the specified joystick
|
||||||
|
//
|
||||||
|
static void getElementsCFArrayHandler(const void* value, void* parameter)
|
||||||
|
{
|
||||||
|
if (CFGetTypeID(value) == IOHIDElementGetTypeID())
|
||||||
|
{
|
||||||
|
addJoystickElement((_GLFWjoystickNS*) parameter,
|
||||||
|
(IOHIDElementRef) value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the value of the specified element of the specified joystick
|
||||||
|
//
|
||||||
|
static long getElementValue(_GLFWjoystickNS* js, _GLFWjoyelementNS* element)
|
||||||
|
{
|
||||||
|
IOReturn result = kIOReturnSuccess;
|
||||||
|
IOHIDValueRef valueRef;
|
||||||
|
long value = 0;
|
||||||
|
|
||||||
|
if (js && element && js->deviceRef)
|
||||||
|
{
|
||||||
|
result = IOHIDDeviceGetValue(js->deviceRef,
|
||||||
|
element->elementRef,
|
||||||
|
&valueRef);
|
||||||
|
|
||||||
|
if (kIOReturnSuccess == result)
|
||||||
{
|
{
|
||||||
_GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS));
|
value = IOHIDValueGetIntegerValue(valueRef);
|
||||||
element->native = native;
|
|
||||||
element->usage = usage;
|
// Record min and max for auto calibration
|
||||||
element->index = (int) CFArrayGetCount(target);
|
if (value < element->minReport)
|
||||||
element->minimum = IOHIDElementGetLogicalMin(native);
|
element->minReport = value;
|
||||||
element->maximum = IOHIDElementGetLogicalMax(native);
|
if (value > element->maxReport)
|
||||||
CFArrayAppendValue(target, element);
|
element->maxReport = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CFRelease(elements);
|
// Auto user scale
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)),
|
// Removes the specified joystick
|
||||||
compareElements, NULL);
|
//
|
||||||
CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)),
|
static void removeJoystick(_GLFWjoystickNS* js)
|
||||||
compareElements, NULL);
|
{
|
||||||
CFArraySortValues(hats, CFRangeMake(0, CFArrayGetCount(hats)),
|
int i;
|
||||||
compareElements, NULL);
|
|
||||||
|
|
||||||
js = _glfwAllocJoystick(name, guid,
|
if (!js->present)
|
||||||
CFArrayGetCount(axes),
|
return;
|
||||||
CFArrayGetCount(buttons),
|
|
||||||
CFArrayGetCount(hats));
|
|
||||||
|
|
||||||
js->ns.device = device;
|
for (i = 0; i < CFArrayGetCount(js->axisElements); i++)
|
||||||
js->ns.axes = axes;
|
free((void*) CFArrayGetValueAtIndex(js->axisElements, i));
|
||||||
js->ns.buttons = buttons;
|
CFArrayRemoveAllValues(js->axisElements);
|
||||||
js->ns.hats = hats;
|
CFRelease(js->axisElements);
|
||||||
|
|
||||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
for (i = 0; i < CFArrayGetCount(js->buttonElements); i++)
|
||||||
|
free((void*) CFArrayGetValueAtIndex(js->buttonElements, i));
|
||||||
|
CFArrayRemoveAllValues(js->buttonElements);
|
||||||
|
CFRelease(js->buttonElements);
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(js->hatElements); i++)
|
||||||
|
free((void*) CFArrayGetValueAtIndex(js->hatElements, i));
|
||||||
|
CFArrayRemoveAllValues(js->hatElements);
|
||||||
|
CFRelease(js->hatElements);
|
||||||
|
|
||||||
|
free(js->axes);
|
||||||
|
free(js->buttons);
|
||||||
|
|
||||||
|
memset(js, 0, sizeof(_GLFWjoystickNS));
|
||||||
|
|
||||||
|
_glfwInputJoystickChange(js - _glfw.ns_js, GLFW_DISCONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Polls for joystick axis events and updates GLFW state
|
||||||
|
//
|
||||||
|
static GLFWbool pollJoystickAxisEvents(_GLFWjoystickNS* js)
|
||||||
|
{
|
||||||
|
CFIndex i;
|
||||||
|
|
||||||
|
if (!js->present)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(js->axisElements); i++)
|
||||||
|
{
|
||||||
|
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
|
||||||
|
CFArrayGetValueAtIndex(js->axisElements, i);
|
||||||
|
|
||||||
|
long value = getElementValue(js, axis);
|
||||||
|
long readScale = axis->maxReport - axis->minReport;
|
||||||
|
|
||||||
|
if (readScale == 0)
|
||||||
|
js->axes[i] = value;
|
||||||
|
else
|
||||||
|
js->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Polls for joystick button events and updates GLFW state
|
||||||
|
//
|
||||||
|
static GLFWbool pollJoystickButtonEvents(_GLFWjoystickNS* js)
|
||||||
|
{
|
||||||
|
CFIndex i;
|
||||||
|
int buttonIndex = 0;
|
||||||
|
|
||||||
|
if (!js->present)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(js->buttonElements); i++)
|
||||||
|
{
|
||||||
|
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
|
||||||
|
CFArrayGetValueAtIndex(js->buttonElements, i);
|
||||||
|
|
||||||
|
if (getElementValue(js, button))
|
||||||
|
js->buttons[buttonIndex++] = GLFW_PRESS;
|
||||||
|
else
|
||||||
|
js->buttons[buttonIndex++] = GLFW_RELEASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < CFArrayGetCount(js->hatElements); i++)
|
||||||
|
{
|
||||||
|
_GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)
|
||||||
|
CFArrayGetValueAtIndex(js->hatElements, i);
|
||||||
|
|
||||||
|
// Bit fields of button presses for each direction, including nil
|
||||||
|
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
|
||||||
|
|
||||||
|
long j, value = getElementValue(js, hat);
|
||||||
|
if (value < 0 || value > 8)
|
||||||
|
value = 8;
|
||||||
|
|
||||||
|
for (j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
if (directions[value] & (1 << j))
|
||||||
|
js->buttons[buttonIndex++] = GLFW_PRESS;
|
||||||
|
else
|
||||||
|
js->buttons[buttonIndex++] = GLFW_RELEASE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback for user-initiated joystick addition
|
||||||
|
//
|
||||||
|
static void matchCallback(void* context,
|
||||||
|
IOReturn result,
|
||||||
|
void* sender,
|
||||||
|
IOHIDDeviceRef deviceRef)
|
||||||
|
{
|
||||||
|
_GLFWjoystickNS* js;
|
||||||
|
int jid;
|
||||||
|
|
||||||
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (_glfw.ns_js[jid].present && _glfw.ns_js[jid].deviceRef == deviceRef)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (!_glfw.ns_js[jid].present)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jid > GLFW_JOYSTICK_LAST)
|
||||||
|
return;
|
||||||
|
|
||||||
|
js = _glfw.ns_js + jid;
|
||||||
|
js->present = GLFW_TRUE;
|
||||||
|
js->deviceRef = deviceRef;
|
||||||
|
|
||||||
|
CFStringRef name = IOHIDDeviceGetProperty(deviceRef,
|
||||||
|
CFSTR(kIOHIDProductKey));
|
||||||
|
if (name)
|
||||||
|
{
|
||||||
|
CFStringGetCString(name,
|
||||||
|
js->name,
|
||||||
|
sizeof(js->name),
|
||||||
|
kCFStringEncodingUTF8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strncpy(js->name, "Unknown", sizeof(js->name));
|
||||||
|
|
||||||
|
js->axisElements = CFArrayCreateMutable(NULL, 0, NULL);
|
||||||
|
js->buttonElements = CFArrayCreateMutable(NULL, 0, NULL);
|
||||||
|
js->hatElements = CFArrayCreateMutable(NULL, 0, NULL);
|
||||||
|
|
||||||
|
CFArrayRef arrayRef = IOHIDDeviceCopyMatchingElements(deviceRef,
|
||||||
|
NULL,
|
||||||
|
kIOHIDOptionsTypeNone);
|
||||||
|
CFRange range = { 0, CFArrayGetCount(arrayRef) };
|
||||||
|
CFArrayApplyFunction(arrayRef,
|
||||||
|
range,
|
||||||
|
getElementsCFArrayHandler,
|
||||||
|
(void*) js);
|
||||||
|
|
||||||
|
CFRelease(arrayRef);
|
||||||
|
|
||||||
|
js->axes = calloc(CFArrayGetCount(js->axisElements), sizeof(float));
|
||||||
|
js->buttons = calloc(CFArrayGetCount(js->buttonElements) +
|
||||||
|
CFArrayGetCount(js->hatElements) * 4, 1);
|
||||||
|
|
||||||
|
_glfwInputJoystickChange(jid, GLFW_CONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback for user-initiated joystick removal
|
// Callback for user-initiated joystick removal
|
||||||
@@ -264,20 +332,60 @@ static void matchCallback(void* context,
|
|||||||
static void removeCallback(void* context,
|
static void removeCallback(void* context,
|
||||||
IOReturn result,
|
IOReturn result,
|
||||||
void* sender,
|
void* sender,
|
||||||
IOHIDDeviceRef device)
|
IOHIDDeviceRef deviceRef)
|
||||||
{
|
{
|
||||||
int jid;
|
int jid;
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
{
|
{
|
||||||
if (_glfw.joysticks[jid].ns.device == device)
|
if (_glfw.ns_js[jid].deviceRef == deviceRef)
|
||||||
{
|
{
|
||||||
closeJoystick(_glfw.joysticks + jid);
|
removeJoystick(_glfw.ns_js + jid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates a dictionary to match against devices with the specified usage page
|
||||||
|
// and usage
|
||||||
|
//
|
||||||
|
static CFMutableDictionaryRef createMatchingDictionary(long usagePage,
|
||||||
|
long usage)
|
||||||
|
{
|
||||||
|
CFMutableDictionaryRef result =
|
||||||
|
CFDictionaryCreateMutable(kCFAllocatorDefault,
|
||||||
|
0,
|
||||||
|
&kCFTypeDictionaryKeyCallBacks,
|
||||||
|
&kCFTypeDictionaryValueCallBacks);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault,
|
||||||
|
kCFNumberLongType,
|
||||||
|
&usagePage);
|
||||||
|
if (pageRef)
|
||||||
|
{
|
||||||
|
CFDictionarySetValue(result,
|
||||||
|
CFSTR(kIOHIDDeviceUsagePageKey),
|
||||||
|
pageRef);
|
||||||
|
CFRelease(pageRef);
|
||||||
|
|
||||||
|
CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault,
|
||||||
|
kCFNumberLongType,
|
||||||
|
&usage);
|
||||||
|
if (usageRef)
|
||||||
|
{
|
||||||
|
CFDictionarySetValue(result,
|
||||||
|
CFSTR(kIOHIDDeviceUsageKey),
|
||||||
|
usageRef);
|
||||||
|
CFRelease(usageRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
@@ -287,73 +395,56 @@ static void removeCallback(void* context,
|
|||||||
//
|
//
|
||||||
void _glfwInitJoysticksNS(void)
|
void _glfwInitJoysticksNS(void)
|
||||||
{
|
{
|
||||||
CFMutableArrayRef matching;
|
CFMutableArrayRef matchingCFArrayRef;
|
||||||
const long usages[] =
|
|
||||||
{
|
|
||||||
kHIDUsage_GD_Joystick,
|
|
||||||
kHIDUsage_GD_GamePad,
|
|
||||||
kHIDUsage_GD_MultiAxisController
|
|
||||||
};
|
|
||||||
|
|
||||||
_glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
|
_glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
|
||||||
kIOHIDOptionsTypeNone);
|
kIOHIDOptionsTypeNone);
|
||||||
|
|
||||||
matching = CFArrayCreateMutable(kCFAllocatorDefault,
|
matchingCFArrayRef = CFArrayCreateMutable(kCFAllocatorDefault,
|
||||||
0,
|
0,
|
||||||
&kCFTypeArrayCallBacks);
|
&kCFTypeArrayCallBacks);
|
||||||
if (!matching)
|
if (matchingCFArrayRef)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array");
|
CFDictionaryRef matchingCFDictRef =
|
||||||
return;
|
createMatchingDictionary(kHIDPage_GenericDesktop,
|
||||||
}
|
kHIDUsage_GD_Joystick);
|
||||||
|
if (matchingCFDictRef)
|
||||||
for (int i = 0; i < sizeof(usages) / sizeof(long); i++)
|
|
||||||
{
|
|
||||||
const long page = kHIDPage_GenericDesktop;
|
|
||||||
|
|
||||||
CFMutableDictionaryRef dict =
|
|
||||||
CFDictionaryCreateMutable(kCFAllocatorDefault,
|
|
||||||
0,
|
|
||||||
&kCFTypeDictionaryKeyCallBacks,
|
|
||||||
&kCFTypeDictionaryValueCallBacks);
|
|
||||||
if (!dict)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault,
|
|
||||||
kCFNumberLongType,
|
|
||||||
&page);
|
|
||||||
CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault,
|
|
||||||
kCFNumberLongType,
|
|
||||||
&usages[i]);
|
|
||||||
if (pageRef && usageRef)
|
|
||||||
{
|
{
|
||||||
CFDictionarySetValue(dict,
|
CFArrayAppendValue(matchingCFArrayRef, matchingCFDictRef);
|
||||||
CFSTR(kIOHIDDeviceUsagePageKey),
|
CFRelease(matchingCFDictRef);
|
||||||
pageRef);
|
|
||||||
CFDictionarySetValue(dict,
|
|
||||||
CFSTR(kIOHIDDeviceUsageKey),
|
|
||||||
usageRef);
|
|
||||||
CFArrayAppendValue(matching, dict);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pageRef)
|
matchingCFDictRef = createMatchingDictionary(kHIDPage_GenericDesktop,
|
||||||
CFRelease(pageRef);
|
kHIDUsage_GD_GamePad);
|
||||||
if (usageRef)
|
if (matchingCFDictRef)
|
||||||
CFRelease(usageRef);
|
{
|
||||||
|
CFArrayAppendValue(matchingCFArrayRef, matchingCFDictRef);
|
||||||
|
CFRelease(matchingCFDictRef);
|
||||||
|
}
|
||||||
|
|
||||||
CFRelease(dict);
|
matchingCFDictRef =
|
||||||
|
createMatchingDictionary(kHIDPage_GenericDesktop,
|
||||||
|
kHIDUsage_GD_MultiAxisController);
|
||||||
|
if (matchingCFDictRef)
|
||||||
|
{
|
||||||
|
CFArrayAppendValue(matchingCFArrayRef, matchingCFDictRef);
|
||||||
|
CFRelease(matchingCFDictRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager,
|
||||||
|
matchingCFArrayRef);
|
||||||
|
CFRelease(matchingCFArrayRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager, matching);
|
|
||||||
CFRelease(matching);
|
|
||||||
|
|
||||||
IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager,
|
IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager,
|
||||||
&matchCallback, NULL);
|
&matchCallback, NULL);
|
||||||
IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager,
|
IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager,
|
||||||
&removeCallback, NULL);
|
&removeCallback, NULL);
|
||||||
|
|
||||||
IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager,
|
IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager,
|
||||||
CFRunLoopGetMain(),
|
CFRunLoopGetMain(),
|
||||||
kCFRunLoopDefaultMode);
|
kCFRunLoopDefaultMode);
|
||||||
|
|
||||||
IOHIDManagerOpen(_glfw.ns.hidManager, 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
|
||||||
@@ -367,8 +458,11 @@ void _glfwTerminateJoysticksNS(void)
|
|||||||
{
|
{
|
||||||
int jid;
|
int jid;
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
closeJoystick(_glfw.joysticks + jid);
|
{
|
||||||
|
_GLFWjoystickNS* js = _glfw.ns_js + jid;
|
||||||
|
removeJoystick(js);
|
||||||
|
}
|
||||||
|
|
||||||
CFRelease(_glfw.ns.hidManager);
|
CFRelease(_glfw.ns.hidManager);
|
||||||
_glfw.ns.hidManager = NULL;
|
_glfw.ns.hidManager = NULL;
|
||||||
@@ -379,84 +473,39 @@ void _glfwTerminateJoysticksNS(void)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
int _glfwPlatformJoystickPresent(int jid)
|
||||||
{
|
{
|
||||||
if (mode & _GLFW_POLL_AXES)
|
_GLFWjoystickNS* js = _glfw.ns_js + jid;
|
||||||
{
|
|
||||||
CFIndex i;
|
|
||||||
|
|
||||||
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
|
||||||
{
|
|
||||||
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
|
|
||||||
CFArrayGetValueAtIndex(js->ns.axes, i);
|
|
||||||
|
|
||||||
const long raw = getElementValue(js, axis);
|
|
||||||
// Perform auto calibration
|
|
||||||
if (raw < axis->minimum)
|
|
||||||
axis->minimum = raw;
|
|
||||||
if (raw > axis->maximum)
|
|
||||||
axis->maximum = raw;
|
|
||||||
|
|
||||||
const long delta = axis->maximum - axis->minimum;
|
|
||||||
if (delta == 0)
|
|
||||||
_glfwInputJoystickAxis(js, i, 0.f);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const float value = (2.f * (raw - axis->minimum) / delta) - 1.f;
|
|
||||||
_glfwInputJoystickAxis(js, i, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode & _GLFW_POLL_BUTTONS)
|
|
||||||
{
|
|
||||||
CFIndex i;
|
|
||||||
|
|
||||||
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
|
||||||
{
|
|
||||||
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
|
|
||||||
CFArrayGetValueAtIndex(js->ns.buttons, i);
|
|
||||||
const char value = getElementValue(js, button) - button->minimum;
|
|
||||||
_glfwInputJoystickButton(js, i, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
|
||||||
{
|
|
||||||
const int states[9] =
|
|
||||||
{
|
|
||||||
GLFW_HAT_UP,
|
|
||||||
GLFW_HAT_RIGHT_UP,
|
|
||||||
GLFW_HAT_RIGHT,
|
|
||||||
GLFW_HAT_RIGHT_DOWN,
|
|
||||||
GLFW_HAT_DOWN,
|
|
||||||
GLFW_HAT_LEFT_DOWN,
|
|
||||||
GLFW_HAT_LEFT,
|
|
||||||
GLFW_HAT_LEFT_UP,
|
|
||||||
GLFW_HAT_CENTERED
|
|
||||||
};
|
|
||||||
|
|
||||||
_GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)
|
|
||||||
CFArrayGetValueAtIndex(js->ns.hats, i);
|
|
||||||
long state = getElementValue(js, hat) - hat->minimum;
|
|
||||||
if (state < 0 || state > 8)
|
|
||||||
state = 8;
|
|
||||||
|
|
||||||
_glfwInputJoystickHat(js, i, states[state]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return js->present;
|
return js->present;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
const float* _glfwPlatformGetJoystickAxes(int jid, int* count)
|
||||||
{
|
{
|
||||||
if ((strncmp(guid + 4, "000000000000", 12) == 0) &&
|
_GLFWjoystickNS* js = _glfw.ns_js + jid;
|
||||||
(strncmp(guid + 20, "000000000000", 12) == 0))
|
if (!pollJoystickAxisEvents(js))
|
||||||
{
|
return NULL;
|
||||||
char original[33];
|
|
||||||
strcpy(original, guid);
|
*count = (int) CFArrayGetCount(js->axisElements);
|
||||||
sprintf(guid, "03000000%.4s0000%.4s000000000000",
|
return js->axes;
|
||||||
original, original + 16);
|
}
|
||||||
}
|
|
||||||
|
const unsigned char* _glfwPlatformGetJoystickButtons(int jid, int* count)
|
||||||
|
{
|
||||||
|
_GLFWjoystickNS* js = _glfw.ns_js + jid;
|
||||||
|
if (!pollJoystickButtonEvents(js))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*count = (int) CFArrayGetCount(js->buttonElements) +
|
||||||
|
(int) CFArrayGetCount(js->hatElements) * 4;
|
||||||
|
return js->buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetJoystickName(int jid)
|
||||||
|
{
|
||||||
|
_GLFWjoystickNS* js = _glfw.ns_js + jid;
|
||||||
|
if (!js->present)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return js->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+60
-84
@@ -48,14 +48,14 @@ static char* getDisplayName(CGDirectDisplayID displayID)
|
|||||||
IOServiceMatching("IODisplayConnect"),
|
IOServiceMatching("IODisplayConnect"),
|
||||||
&it) != 0)
|
&it) != 0)
|
||||||
{
|
{
|
||||||
// This may happen if a desktop Mac is running headless
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
return NULL;
|
"Cocoa: Failed to get display service port iterator");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((service = IOIteratorNext(it)) != 0)
|
while ((service = IOIteratorNext(it)) != 0)
|
||||||
{
|
{
|
||||||
info = IODisplayCreateInfoDictionary(service,
|
info = IODisplayCreateInfoDictionary(service, kIODisplayOnlyPreferredName);
|
||||||
kIODisplayOnlyPreferredName);
|
|
||||||
|
|
||||||
CFNumberRef vendorIDRef =
|
CFNumberRef vendorIDRef =
|
||||||
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
|
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
|
||||||
@@ -99,6 +99,8 @@ static char* getDisplayName(CGDirectDisplayID displayID)
|
|||||||
(const void**) &nameRef))
|
(const void**) &nameRef))
|
||||||
{
|
{
|
||||||
// This may happen if a desktop Mac is running headless
|
// This may happen if a desktop Mac is running headless
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Cocoa: Failed to retrieve display name");
|
||||||
CFRelease(info);
|
CFRelease(info);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -126,7 +128,7 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode)
|
|||||||
if (flags & kDisplayModeStretchedFlag)
|
if (flags & kDisplayModeStretchedFlag)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
|
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101200
|
||||||
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
|
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
|
||||||
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
|
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
|
||||||
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
|
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
|
||||||
@@ -157,7 +159,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
|
|||||||
result.refreshRate = (int) (time.timeScale / (double) time.timeValue);
|
result.refreshRate = (int) (time.timeScale / (double) time.timeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
|
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101200
|
||||||
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
|
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
|
||||||
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
|
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
|
||||||
{
|
{
|
||||||
@@ -173,7 +175,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
|
|||||||
result.blueBits = 8;
|
result.blueBits = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
|
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101200
|
||||||
CFRelease(format);
|
CFRelease(format);
|
||||||
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
|
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
|
||||||
return result;
|
return result;
|
||||||
@@ -186,13 +188,7 @@ static CGDisplayFadeReservationToken beginFadeReservation(void)
|
|||||||
CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
|
CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
|
||||||
|
|
||||||
if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
|
if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
|
||||||
{
|
CGDisplayFade(token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
|
||||||
CGDisplayFade(token, 0.3,
|
|
||||||
kCGDisplayBlendNormal,
|
|
||||||
kCGDisplayBlendSolidColor,
|
|
||||||
0.0, 0.0, 0.0,
|
|
||||||
TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@@ -203,11 +199,7 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
|
|||||||
{
|
{
|
||||||
if (token != kCGDisplayFadeReservationInvalidToken)
|
if (token != kCGDisplayFadeReservationInvalidToken)
|
||||||
{
|
{
|
||||||
CGDisplayFade(token, 0.5,
|
CGDisplayFade(token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
|
||||||
kCGDisplayBlendSolidColor,
|
|
||||||
kCGDisplayBlendNormal,
|
|
||||||
0.0, 0.0, 0.0,
|
|
||||||
FALSE);
|
|
||||||
CGReleaseDisplayFadeReservation(token);
|
CGReleaseDisplayFadeReservation(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,71 +209,6 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Poll for changes in the set of connected monitors
|
|
||||||
//
|
|
||||||
void _glfwPollMonitorsNS(void)
|
|
||||||
{
|
|
||||||
uint32_t i, j, displayCount, disconnectedCount;
|
|
||||||
CGDirectDisplayID* displays;
|
|
||||||
_GLFWmonitor** disconnected = NULL;
|
|
||||||
|
|
||||||
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
|
||||||
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
|
||||||
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
|
||||||
|
|
||||||
disconnectedCount = _glfw.monitorCount;
|
|
||||||
if (disconnectedCount)
|
|
||||||
{
|
|
||||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
|
||||||
memcpy(disconnected,
|
|
||||||
_glfw.monitors,
|
|
||||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < displayCount; i++)
|
|
||||||
{
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
|
||||||
|
|
||||||
if (CGDisplayIsAsleep(displays[i]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (j = 0; j < disconnectedCount; j++)
|
|
||||||
{
|
|
||||||
// HACK: Compare unit numbers instead of display IDs to work around
|
|
||||||
// display replacement on machines with automatic graphics
|
|
||||||
// switching
|
|
||||||
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
|
|
||||||
{
|
|
||||||
disconnected[j] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const CGSize size = CGDisplayScreenSize(displays[i]);
|
|
||||||
char* name = getDisplayName(displays[i]);
|
|
||||||
if (!name)
|
|
||||||
name = strdup("Unknown");
|
|
||||||
|
|
||||||
monitor = _glfwAllocMonitor(name, size.width, size.height);
|
|
||||||
monitor->ns.displayID = displays[i];
|
|
||||||
monitor->ns.unitNumber = unitNumber;
|
|
||||||
|
|
||||||
free(name);
|
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < disconnectedCount; i++)
|
|
||||||
{
|
|
||||||
if (disconnected[i])
|
|
||||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(disconnected);
|
|
||||||
free(displays);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the current video mode
|
// Change the current video mode
|
||||||
//
|
//
|
||||||
GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||||
@@ -361,6 +288,55 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||||
|
{
|
||||||
|
uint32_t i, found = 0, displayCount;
|
||||||
|
_GLFWmonitor** monitors;
|
||||||
|
CGDirectDisplayID* displays;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
||||||
|
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||||
|
monitors = calloc(displayCount, sizeof(_GLFWmonitor*));
|
||||||
|
|
||||||
|
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
||||||
|
|
||||||
|
for (i = 0; i < displayCount; i++)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor;
|
||||||
|
|
||||||
|
if (CGDisplayIsAsleep(displays[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const CGSize size = CGDisplayScreenSize(displays[i]);
|
||||||
|
char* name = getDisplayName(displays[i]);
|
||||||
|
if (!name)
|
||||||
|
name = strdup("Unknown");
|
||||||
|
|
||||||
|
monitor = _glfwAllocMonitor(name, size.width, size.height);
|
||||||
|
monitor->ns.displayID = displays[i];
|
||||||
|
monitor->ns.unitNumber = CGDisplayUnitNumber(displays[i]);
|
||||||
|
|
||||||
|
free(name);
|
||||||
|
|
||||||
|
found++;
|
||||||
|
monitors[found - 1] = monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(displays);
|
||||||
|
|
||||||
|
*count = found;
|
||||||
|
return monitors;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
||||||
|
{
|
||||||
|
// HACK: Compare unit numbers instead of display IDs to work around display
|
||||||
|
// replacement on machines with automatic graphics switching
|
||||||
|
return first->ns.unitNumber == second->ns.unitNumber;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
|
const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
|
||||||
|
|||||||
+12
-12
@@ -24,6 +24,9 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_cocoa_platform_h_
|
||||||
|
#define _glfw3_cocoa_platform_h_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
@@ -48,25 +51,23 @@ typedef struct VkMacOSSurfaceCreateInfoMVK
|
|||||||
|
|
||||||
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
|
|
||||||
#include "posix_thread.h"
|
#include "posix_tls.h"
|
||||||
#include "cocoa_joystick.h"
|
#include "cocoa_joystick.h"
|
||||||
#include "nsgl_context.h"
|
#include "nsgl_context.h"
|
||||||
#include "egl_context.h"
|
|
||||||
#include "osmesa_context.h"
|
|
||||||
|
|
||||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||||
#define _glfw_dlclose(handle) dlclose(handle)
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->ns.view)
|
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNS ns
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns
|
||||||
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerNS ns
|
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeNS ns_time
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns
|
||||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns
|
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns
|
||||||
|
|
||||||
|
#define _GLFW_EGL_CONTEXT_STATE
|
||||||
|
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE
|
||||||
|
|
||||||
// HIToolbox.framework pointer typedefs
|
// HIToolbox.framework pointer typedefs
|
||||||
#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
|
#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
|
||||||
typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void);
|
typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void);
|
||||||
@@ -102,7 +103,7 @@ typedef struct _GLFWlibraryNS
|
|||||||
CGEventSourceRef eventSource;
|
CGEventSourceRef eventSource;
|
||||||
id delegate;
|
id delegate;
|
||||||
id autoreleasePool;
|
id autoreleasePool;
|
||||||
GLFWbool cursorHidden;
|
id cursor;
|
||||||
TISInputSourceRef inputSource;
|
TISInputSourceRef inputSource;
|
||||||
IOHIDManagerRef hidManager;
|
IOHIDManagerRef hidManager;
|
||||||
id unicodeData;
|
id unicodeData;
|
||||||
@@ -112,7 +113,6 @@ typedef struct _GLFWlibraryNS
|
|||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
char* clipboardString;
|
char* clipboardString;
|
||||||
CGPoint cascadePoint;
|
|
||||||
// Where to place the cursor when re-enabled
|
// Where to place the cursor when re-enabled
|
||||||
double restoreCursorPosX, restoreCursorPosY;
|
double restoreCursorPosX, restoreCursorPosY;
|
||||||
// The window whose disabled cursor mode is active
|
// The window whose disabled cursor mode is active
|
||||||
@@ -148,16 +148,16 @@ typedef struct _GLFWcursorNS
|
|||||||
|
|
||||||
// Cocoa-specific global timer data
|
// Cocoa-specific global timer data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWtimerNS
|
typedef struct _GLFWtimeNS
|
||||||
{
|
{
|
||||||
uint64_t frequency;
|
uint64_t frequency;
|
||||||
|
|
||||||
} _GLFWtimerNS;
|
} _GLFWtimeNS;
|
||||||
|
|
||||||
|
|
||||||
void _glfwInitTimerNS(void);
|
void _glfwInitTimerNS(void);
|
||||||
|
|
||||||
void _glfwPollMonitorsNS(void);
|
|
||||||
GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||||
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
#endif // _glfw3_cocoa_platform_h_
|
||||||
|
|||||||
+2
-2
@@ -40,7 +40,7 @@ void _glfwInitTimerNS(void)
|
|||||||
mach_timebase_info_data_t info;
|
mach_timebase_info_data_t info;
|
||||||
mach_timebase_info(&info);
|
mach_timebase_info(&info);
|
||||||
|
|
||||||
_glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer;
|
_glfw.ns_time.frequency = (info.denom * 1e9) / info.numer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -55,6 +55,6 @@ uint64_t _glfwPlatformGetTimerValue(void)
|
|||||||
|
|
||||||
uint64_t _glfwPlatformGetTimerFrequency(void)
|
uint64_t _glfwPlatformGetTimerFrequency(void)
|
||||||
{
|
{
|
||||||
return _glfw.timer.ns.frequency;
|
return _glfw.ns_time.frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+95
-160
@@ -50,6 +50,29 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the specified standard cursor
|
||||||
|
//
|
||||||
|
static NSCursor* getStandardCursor(int shape)
|
||||||
|
{
|
||||||
|
switch (shape)
|
||||||
|
{
|
||||||
|
case GLFW_ARROW_CURSOR:
|
||||||
|
return [NSCursor arrowCursor];
|
||||||
|
case GLFW_IBEAM_CURSOR:
|
||||||
|
return [NSCursor IBeamCursor];
|
||||||
|
case GLFW_CROSSHAIR_CURSOR:
|
||||||
|
return [NSCursor crosshairCursor];
|
||||||
|
case GLFW_HAND_CURSOR:
|
||||||
|
return [NSCursor pointingHandCursor];
|
||||||
|
case GLFW_HRESIZE_CURSOR:
|
||||||
|
return [NSCursor resizeLeftRightCursor];
|
||||||
|
case GLFW_VRESIZE_CURSOR:
|
||||||
|
return [NSCursor resizeUpDownCursor];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the style mask corresponding to the window settings
|
// Returns the style mask corresponding to the window settings
|
||||||
//
|
//
|
||||||
static NSUInteger getStyleMask(_GLFWwindow* window)
|
static NSUInteger getStyleMask(_GLFWwindow* window)
|
||||||
@@ -88,43 +111,19 @@ static GLFWbool cursorInClientArea(_GLFWwindow* window)
|
|||||||
return [window->ns.view mouse:pos inRect:[window->ns.view frame]];
|
return [window->ns.view mouse:pos inRect:[window->ns.view frame]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hides the cursor if not already hidden
|
|
||||||
//
|
|
||||||
static void hideCursor(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
if (!_glfw.ns.cursorHidden)
|
|
||||||
{
|
|
||||||
[NSCursor hide];
|
|
||||||
_glfw.ns.cursorHidden = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shows the cursor if not already shown
|
|
||||||
//
|
|
||||||
static void showCursor(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
if (_glfw.ns.cursorHidden)
|
|
||||||
{
|
|
||||||
[NSCursor unhide];
|
|
||||||
_glfw.ns.cursorHidden = GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updates the cursor image according to its cursor mode
|
// Updates the cursor image according to its cursor mode
|
||||||
//
|
//
|
||||||
static void updateCursorImage(_GLFWwindow* window)
|
static void updateCursorImage(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window->cursorMode == GLFW_CURSOR_NORMAL)
|
if (window->cursorMode == GLFW_CURSOR_NORMAL)
|
||||||
{
|
{
|
||||||
showCursor(window);
|
|
||||||
|
|
||||||
if (window->cursor)
|
if (window->cursor)
|
||||||
[(NSCursor*) window->cursor->ns.object set];
|
[(NSCursor*) window->cursor->ns.object set];
|
||||||
else
|
else
|
||||||
[[NSCursor arrowCursor] set];
|
[[NSCursor arrowCursor] set];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
hideCursor(window);
|
[(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
|
||||||
@@ -148,7 +147,7 @@ static GLFWbool acquireMonitor(_GLFWwindow* window)
|
|||||||
|
|
||||||
[window->ns.object setFrame:frame display:YES];
|
[window->ns.object setFrame:frame display:YES];
|
||||||
|
|
||||||
_glfwInputMonitorWindow(window->monitor, window);
|
_glfwInputMonitorWindowChange(window->monitor, window);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +158,7 @@ static void releaseMonitor(_GLFWwindow* window)
|
|||||||
if (window->monitor->window != window)
|
if (window->monitor->window != window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_glfwInputMonitorWindow(window->monitor, NULL);
|
_glfwInputMonitorWindowChange(window->monitor, NULL);
|
||||||
_glfwRestoreVideoModeNS(window->monitor);
|
_glfwRestoreVideoModeNS(window->monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,15 +340,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
|
|
||||||
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
|
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
|
||||||
{
|
{
|
||||||
_GLFWwindow* window;
|
_glfwInputMonitorChange();
|
||||||
|
|
||||||
for (window = _glfw.windowListHead; window; window = window->next)
|
|
||||||
{
|
|
||||||
if (window->context.client != GLFW_NO_API)
|
|
||||||
[window->context.nsgl.object update];
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwPollMonitorsNS();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
@@ -387,6 +378,20 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
|
|
||||||
@implementation GLFWContentView
|
@implementation GLFWContentView
|
||||||
|
|
||||||
|
+ (void)initialize
|
||||||
|
{
|
||||||
|
if (self == [GLFWContentView class])
|
||||||
|
{
|
||||||
|
if (_glfw.ns.cursor == nil)
|
||||||
|
{
|
||||||
|
NSImage* data = [[NSImage alloc] initWithSize:NSMakeSize(16, 16)];
|
||||||
|
_glfw.ns.cursor = [[NSCursor alloc] initWithImage:data
|
||||||
|
hotSpot:NSZeroPoint];
|
||||||
|
[data release];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow
|
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
@@ -433,10 +438,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
|
|
||||||
- (id)makeBackingLayer
|
- (id)makeBackingLayer
|
||||||
{
|
{
|
||||||
if (window->ns.layer)
|
return window->ns.layer;
|
||||||
return window->ns.layer;
|
|
||||||
|
|
||||||
return [super makeBackingLayer];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)cursorUpdate:(NSEvent *)event
|
- (void)cursorUpdate:(NSEvent *)event
|
||||||
@@ -532,17 +534,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
|
|
||||||
- (void)mouseExited:(NSEvent *)event
|
- (void)mouseExited:(NSEvent *)event
|
||||||
{
|
{
|
||||||
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
|
||||||
showCursor(window);
|
|
||||||
|
|
||||||
_glfwInputCursorEnter(window, GLFW_FALSE);
|
_glfwInputCursorEnter(window, GLFW_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)mouseEntered:(NSEvent *)event
|
- (void)mouseEntered:(NSEvent *)event
|
||||||
{
|
{
|
||||||
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
|
||||||
hideCursor(window);
|
|
||||||
|
|
||||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,11 +710,10 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
selectedRange:(NSRange)selectedRange
|
selectedRange:(NSRange)selectedRange
|
||||||
replacementRange:(NSRange)replacementRange
|
replacementRange:(NSRange)replacementRange
|
||||||
{
|
{
|
||||||
[markedText release];
|
|
||||||
if ([string isKindOfClass:[NSAttributedString class]])
|
if ([string isKindOfClass:[NSAttributedString class]])
|
||||||
markedText = [[NSMutableAttributedString alloc] initWithAttributedString:string];
|
[markedText initWithAttributedString:string];
|
||||||
else
|
else
|
||||||
markedText = [[NSMutableAttributedString alloc] initWithString:string];
|
[markedText initWithString:string];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)unmarkText
|
- (void)unmarkText
|
||||||
@@ -797,11 +792,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)canBecomeMainWindow
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
@@ -810,10 +800,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
@interface GLFWApplication : NSApplication
|
@interface GLFWApplication : NSApplication
|
||||||
{
|
|
||||||
NSArray* nibObjects;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GLFWApplication
|
@implementation GLFWApplication
|
||||||
@@ -838,58 +824,53 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
- (void)doNothing:(id)object
|
- (void)doNothing:(id)object
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)loadMainMenu
|
|
||||||
{
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 100800
|
|
||||||
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
|
|
||||||
owner:NSApp
|
|
||||||
topLevelObjects:&nibObjects];
|
|
||||||
#else
|
|
||||||
[[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:NSApp];
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
// Set up the menu bar (manually)
|
#if defined(_GLFW_USE_MENUBAR)
|
||||||
// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
|
|
||||||
// could go away at any moment, lots of stuff that really should be
|
// Try to figure out what the calling application is called
|
||||||
// localize(d|able), etc. Add a nib to save us this horror.
|
|
||||||
//
|
//
|
||||||
static void createMenuBar(void)
|
static NSString* findAppName(void)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
NSString* appName = nil;
|
NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
|
||||||
NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
|
|
||||||
NSString* nameKeys[] =
|
// Keys to search for as potential application names
|
||||||
|
NSString* GLFWNameKeys[] =
|
||||||
{
|
{
|
||||||
@"CFBundleDisplayName",
|
@"CFBundleDisplayName",
|
||||||
@"CFBundleName",
|
@"CFBundleName",
|
||||||
@"CFBundleExecutable",
|
@"CFBundleExecutable",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Try to figure out what the calling application is called
|
for (i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++)
|
||||||
|
|
||||||
for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
|
|
||||||
{
|
{
|
||||||
id name = [bundleInfo objectForKey:nameKeys[i]];
|
id name = [infoDictionary objectForKey:GLFWNameKeys[i]];
|
||||||
if (name &&
|
if (name &&
|
||||||
[name isKindOfClass:[NSString class]] &&
|
[name isKindOfClass:[NSString class]] &&
|
||||||
![name isEqualToString:@""])
|
![name isEqualToString:@""])
|
||||||
{
|
{
|
||||||
appName = name;
|
return name;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!appName)
|
char** progname = _NSGetProgname();
|
||||||
{
|
if (progname && *progname)
|
||||||
char** progname = _NSGetProgname();
|
return [NSString stringWithUTF8String:*progname];
|
||||||
if (progname && *progname)
|
|
||||||
appName = [NSString stringWithUTF8String:*progname];
|
// Really shouldn't get here
|
||||||
else
|
return @"GLFW Application";
|
||||||
appName = @"GLFW Application";
|
}
|
||||||
}
|
|
||||||
|
// Set up the menu bar (manually)
|
||||||
|
// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
|
||||||
|
// could go away at any moment, lots of stuff that really should be
|
||||||
|
// localize(d|able), etc. Loading a nib would save us this horror, but that
|
||||||
|
// doesn't seem like a good thing to require of GLFW users.
|
||||||
|
//
|
||||||
|
static void createMenuBar(void)
|
||||||
|
{
|
||||||
|
NSString* appName = findAppName();
|
||||||
|
|
||||||
NSMenu* bar = [[NSMenu alloc] init];
|
NSMenu* bar = [[NSMenu alloc] init];
|
||||||
[NSApp setMainMenu:bar];
|
[NSApp setMainMenu:bar];
|
||||||
@@ -956,6 +937,8 @@ static void createMenuBar(void)
|
|||||||
[NSApp performSelector:setAppleMenuSelector withObject:appMenu];
|
[NSApp performSelector:setAppleMenuSelector withObject:appMenu];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* _GLFW_USE_MENUBAR */
|
||||||
|
|
||||||
// Initialize the Cocoa Application Kit
|
// Initialize the Cocoa Application Kit
|
||||||
//
|
//
|
||||||
static GLFWbool initializeAppKit(void)
|
static GLFWbool initializeAppKit(void)
|
||||||
@@ -971,20 +954,15 @@ static GLFWbool initializeAppKit(void)
|
|||||||
toTarget:NSApp
|
toTarget:NSApp
|
||||||
withObject:nil];
|
withObject:nil];
|
||||||
|
|
||||||
if (_glfw.hints.init.ns.menubar)
|
// In case we are unbundled, make us a proper UI application
|
||||||
{
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
// In case we are unbundled, make us a proper UI application
|
|
||||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
|
||||||
|
|
||||||
// Menu bar setup must go between sharedApplication above and
|
#if defined(_GLFW_USE_MENUBAR)
|
||||||
// finishLaunching below, in order to properly emulate the behavior
|
// Menu bar setup must go between sharedApplication above and
|
||||||
// of NSApplicationMain
|
// finishLaunching below, in order to properly emulate the behavior
|
||||||
|
// of NSApplicationMain
|
||||||
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
|
createMenuBar();
|
||||||
[NSApp loadMainMenu];
|
#endif
|
||||||
else
|
|
||||||
createMenuBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
// There can only be one application delegate, but we allocate it the
|
// There can only be one application delegate, but we allocate it the
|
||||||
// first time a window is created to keep all window code in this file
|
// first time a window is created to keep all window code in this file
|
||||||
@@ -999,13 +977,6 @@ static GLFWbool initializeAppKit(void)
|
|||||||
[NSApp setDelegate:_glfw.ns.delegate];
|
[NSApp setDelegate:_glfw.ns.delegate];
|
||||||
[NSApp run];
|
[NSApp run];
|
||||||
|
|
||||||
// Press and Hold prevents some keys from emitting repeated characters
|
|
||||||
NSDictionary* defaults =
|
|
||||||
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO],
|
|
||||||
@"ApplePressAndHoldEnabled",
|
|
||||||
nil];
|
|
||||||
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1054,17 +1025,9 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
[window->ns.object center];
|
[window->ns.object center];
|
||||||
_glfw.ns.cascadePoint =
|
|
||||||
NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint:
|
|
||||||
NSPointFromCGPoint(_glfw.ns.cascadePoint)]);
|
|
||||||
|
|
||||||
if (wndconfig->resizable)
|
if (wndconfig->resizable)
|
||||||
{
|
[window->ns.object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||||
const NSWindowCollectionBehavior behavior =
|
|
||||||
NSWindowCollectionBehaviorFullScreenPrimary |
|
|
||||||
NSWindowCollectionBehaviorManaged;
|
|
||||||
[window->ns.object setCollectionBehavior:behavior];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wndconfig->floating)
|
if (wndconfig->floating)
|
||||||
[window->ns.object setLevel:NSFloatingWindowLevel];
|
[window->ns.object setLevel:NSFloatingWindowLevel];
|
||||||
@@ -1073,9 +1036,6 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
[window->ns.object zoom:nil];
|
[window->ns.object zoom:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wndconfig->ns.frame)
|
|
||||||
[window->ns.object setFrameAutosaveName:[NSString stringWithUTF8String:wndconfig->title]];
|
|
||||||
|
|
||||||
window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];
|
window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];
|
||||||
|
|
||||||
if (wndconfig->ns.retina)
|
if (wndconfig->ns.retina)
|
||||||
@@ -1116,19 +1076,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
|
if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
else
|
||||||
{
|
{
|
||||||
if (!_glfwInitEGL())
|
_glfwInputError(GLFW_API_UNAVAILABLE, "Cocoa: EGL not available");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwInitOSMesa())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1139,8 +1090,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
if (!acquireMonitor(window))
|
if (!acquireMonitor(window))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (wndconfig->centerCursor)
|
centerCursor(window);
|
||||||
centerCursor(window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@@ -1306,11 +1256,6 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
|
|||||||
[window->ns.object orderOut:nil];
|
[window->ns.object orderOut:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
[NSApp requestUserAttention:NSInformationalRequest];
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
// Make us the active application
|
// Make us the active application
|
||||||
@@ -1354,10 +1299,6 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|||||||
|
|
||||||
_glfwInputWindowMonitorChange(window, monitor);
|
_glfwInputWindowMonitorChange(window, monitor);
|
||||||
|
|
||||||
// HACK: Allow the state cached in Cocoa to catch up to reality
|
|
||||||
// TODO: Solve this in a less terrible way
|
|
||||||
_glfwPlatformPollEvents();
|
|
||||||
|
|
||||||
const NSUInteger styleMask = getStyleMask(window);
|
const NSUInteger styleMask = getStyleMask(window);
|
||||||
[window->ns.object setStyleMask:styleMask];
|
[window->ns.object setStyleMask:styleMask];
|
||||||
[window->ns.object makeFirstResponder:window->ns.view];
|
[window->ns.object makeFirstResponder:window->ns.view];
|
||||||
@@ -1584,8 +1525,14 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
updateCursorImage(window);
|
updateCursorImage(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetKeyName(int key, int scancode)
|
||||||
{
|
{
|
||||||
|
if (key != GLFW_KEY_UNKNOWN)
|
||||||
|
scancode = _glfw.ns.scancodes[key];
|
||||||
|
|
||||||
|
if (!_glfwIsPrintable(_glfw.ns.keycodes[scancode]))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
UInt32 deadKeyState = 0;
|
UInt32 deadKeyState = 0;
|
||||||
UniChar characters[8];
|
UniChar characters[8];
|
||||||
UniCharCount characterCount = 0;
|
UniCharCount characterCount = 0;
|
||||||
@@ -1673,19 +1620,7 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
|||||||
if (!initializeAppKit())
|
if (!initializeAppKit())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (shape == GLFW_ARROW_CURSOR)
|
cursor->ns.object = getStandardCursor(shape);
|
||||||
cursor->ns.object = [NSCursor arrowCursor];
|
|
||||||
else if (shape == GLFW_IBEAM_CURSOR)
|
|
||||||
cursor->ns.object = [NSCursor IBeamCursor];
|
|
||||||
else if (shape == GLFW_CROSSHAIR_CURSOR)
|
|
||||||
cursor->ns.object = [NSCursor crosshairCursor];
|
|
||||||
else if (shape == GLFW_HAND_CURSOR)
|
|
||||||
cursor->ns.object = [NSCursor pointingHandCursor];
|
|
||||||
else if (shape == GLFW_HRESIZE_CURSOR)
|
|
||||||
cursor->ns.object = [NSCursor resizeLeftRightCursor];
|
|
||||||
else if (shape == GLFW_VRESIZE_CURSOR)
|
|
||||||
cursor->ns.object = [NSCursor resizeUpDownCursor];
|
|
||||||
|
|
||||||
if (!cursor->ns.object)
|
if (!cursor->ns.object)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
|||||||
+13
-13
@@ -41,11 +41,10 @@
|
|||||||
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||||
{
|
{
|
||||||
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
|
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
|
||||||
ctxconfig->source != GLFW_EGL_CONTEXT_API &&
|
ctxconfig->source != GLFW_EGL_CONTEXT_API)
|
||||||
ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
"Invalid context creation API 0x%08X",
|
"Invalid context creation API %i",
|
||||||
ctxconfig->source);
|
ctxconfig->source);
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
@@ -55,7 +54,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
|||||||
ctxconfig->client != GLFW_OPENGL_ES_API)
|
ctxconfig->client != GLFW_OPENGL_ES_API)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
"Invalid client API 0x%08X",
|
"Invalid client API %i",
|
||||||
ctxconfig->client);
|
ctxconfig->client);
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
@@ -85,7 +84,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
|||||||
ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)
|
ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
"Invalid OpenGL profile 0x%08X",
|
"Invalid OpenGL profile %i",
|
||||||
ctxconfig->profile);
|
ctxconfig->profile);
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
@@ -134,7 +133,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
|||||||
ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)
|
ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
"Invalid context robustness mode 0x%08X",
|
"Invalid context robustness mode %i",
|
||||||
ctxconfig->robustness);
|
ctxconfig->robustness);
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
@@ -146,7 +145,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
|||||||
ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)
|
ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
"Invalid context release behavior 0x%08X",
|
"Invalid context release behavior %i",
|
||||||
ctxconfig->release);
|
ctxconfig->release);
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
@@ -331,7 +330,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
window = _glfwPlatformGetCurrentContext();
|
||||||
|
|
||||||
window->context.source = ctxconfig->source;
|
window->context.source = ctxconfig->source;
|
||||||
window->context.client = GLFW_OPENGL_API;
|
window->context.client = GLFW_OPENGL_API;
|
||||||
@@ -578,7 +577,7 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
|
|||||||
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
|
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
_GLFWwindow* previous = _glfwPlatformGetTls(&_glfw.contextSlot);
|
_GLFWwindow* previous = _glfwPlatformGetCurrentContext();
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
@@ -601,7 +600,7 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
|
|||||||
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
|
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
return _glfwPlatformGetTls(&_glfw.contextSlot);
|
return (GLFWwindow*) _glfwPlatformGetCurrentContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
|
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
|
||||||
@@ -626,7 +625,7 @@ GLFWAPI void glfwSwapInterval(int interval)
|
|||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
window = _glfwPlatformGetCurrentContext();
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||||
@@ -639,11 +638,12 @@ GLFWAPI void glfwSwapInterval(int interval)
|
|||||||
GLFWAPI int glfwExtensionSupported(const char* extension)
|
GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window;
|
_GLFWwindow* window;
|
||||||
|
|
||||||
assert(extension != NULL);
|
assert(extension != NULL);
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||||
|
|
||||||
window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
window = _glfwPlatformGetCurrentContext();
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||||
@@ -708,7 +708,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
|
|||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
window = _glfwPlatformGetCurrentContext();
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||||
|
|||||||
+41
-77
@@ -113,21 +113,13 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
_GLFWfbconfig* u = usableConfigs + usableCount;
|
_GLFWfbconfig* u = usableConfigs + usableCount;
|
||||||
|
|
||||||
// Only consider RGB(A) EGLConfigs
|
// Only consider RGB(A) EGLConfigs
|
||||||
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
|
if (!(getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) & EGL_RGB_BUFFER))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#if defined(_GLFW_EGLDEVICE)
|
|
||||||
// Only consider stream EGLConfigs
|
|
||||||
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_STREAM_BIT_KHR))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
#else
|
|
||||||
// Only consider window EGLConfigs
|
// Only consider window EGLConfigs
|
||||||
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
|
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_GLFW_X11)
|
#if defined(_GLFW_X11)
|
||||||
// Only consider EGLConfigs with associated Visuals
|
// Only consider EGLConfigs with associated Visuals
|
||||||
if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))
|
if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))
|
||||||
@@ -207,12 +199,12 @@ static void makeContextCurrentEGL(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
_glfwPlatformSetCurrentContext(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void swapBuffersEGL(_GLFWwindow* window)
|
static void swapBuffersEGL(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window != _glfwPlatformGetTls(&_glfw.contextSlot))
|
if (window != _glfwPlatformGetCurrentContext())
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"EGL: The context must be current on the calling thread when swapping buffers");
|
"EGL: The context must be current on the calling thread when swapping buffers");
|
||||||
@@ -241,7 +233,7 @@ static int extensionSupportedEGL(const char* extension)
|
|||||||
|
|
||||||
static GLFWglproc getProcAddressEGL(const char* procname)
|
static GLFWglproc getProcAddressEGL(const char* procname)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||||
|
|
||||||
if (window->context.egl.client)
|
if (window->context.egl.client)
|
||||||
{
|
{
|
||||||
@@ -294,15 +286,11 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
int i;
|
int i;
|
||||||
const char* sonames[] =
|
const char* sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_EGL_LIBRARY)
|
#if defined(_GLFW_WIN32)
|
||||||
_GLFW_EGL_LIBRARY,
|
|
||||||
#elif defined(_GLFW_WIN32)
|
|
||||||
"libEGL.dll",
|
"libEGL.dll",
|
||||||
"EGL.dll",
|
"EGL.dll",
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
"libEGL.dylib",
|
"libEGL.dylib",
|
||||||
#elif defined(__CYGWIN__)
|
|
||||||
"libEGL-1.so",
|
|
||||||
#else
|
#else
|
||||||
"libEGL.so.1",
|
"libEGL.so.1",
|
||||||
#endif
|
#endif
|
||||||
@@ -384,9 +372,6 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For EGLDevice backend the display gets initialized
|
|
||||||
// in _glfwPlatformInit()
|
|
||||||
#if !defined(_GLFW_EGLDEVICE)
|
|
||||||
_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)
|
||||||
{
|
{
|
||||||
@@ -407,7 +392,6 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
_glfw.egl.KHR_create_context =
|
_glfw.egl.KHR_create_context =
|
||||||
extensionSupportedEGL("EGL_KHR_create_context");
|
extensionSupportedEGL("EGL_KHR_create_context");
|
||||||
@@ -417,8 +401,6 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
extensionSupportedEGL("EGL_KHR_gl_colorspace");
|
extensionSupportedEGL("EGL_KHR_gl_colorspace");
|
||||||
_glfw.egl.KHR_get_all_proc_addresses =
|
_glfw.egl.KHR_get_all_proc_addresses =
|
||||||
extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
|
extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
|
||||||
_glfw.egl.KHR_context_flush_control =
|
|
||||||
extensionSupportedEGL("EGL_KHR_context_flush_control");
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
@@ -440,11 +422,11 @@ void _glfwTerminateEGL(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define setAttrib(a, v) \
|
#define setEGLattrib(attribName, attribValue) \
|
||||||
{ \
|
{ \
|
||||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
attribs[index++] = attribName; \
|
||||||
attribs[index++] = a; \
|
attribs[index++] = attribValue; \
|
||||||
attribs[index++] = v; \
|
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the OpenGL or OpenGL ES context
|
// Create the OpenGL or OpenGL ES context
|
||||||
@@ -456,7 +438,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
EGLint attribs[40];
|
EGLint attribs[40];
|
||||||
EGLConfig config;
|
EGLConfig config;
|
||||||
EGLContext share = NULL;
|
EGLContext share = NULL;
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
if (!_glfw.egl.display)
|
if (!_glfw.egl.display)
|
||||||
{
|
{
|
||||||
@@ -497,7 +478,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
|
|
||||||
if (_glfw.egl.KHR_create_context)
|
if (_glfw.egl.KHR_create_context)
|
||||||
{
|
{
|
||||||
int mask = 0, flags = 0;
|
int index = 0, mask = 0, flags = 0;
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
{
|
{
|
||||||
@@ -508,6 +489,12 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
|
mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
|
||||||
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
||||||
mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
|
mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
|
||||||
|
|
||||||
|
if (_glfw.egl.KHR_create_context_no_error)
|
||||||
|
{
|
||||||
|
if (ctxconfig->noerror)
|
||||||
|
flags |= EGL_CONTEXT_OPENGL_NO_ERROR_KHR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxconfig->debug)
|
if (ctxconfig->debug)
|
||||||
@@ -517,57 +504,44 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||||
{
|
{
|
||||||
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
||||||
EGL_NO_RESET_NOTIFICATION_KHR);
|
EGL_NO_RESET_NOTIFICATION_KHR);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
{
|
{
|
||||||
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
|
||||||
EGL_LOSE_CONTEXT_ON_RESET_KHR);
|
EGL_LOSE_CONTEXT_ON_RESET_KHR);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
|
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxconfig->noerror)
|
|
||||||
{
|
|
||||||
if (_glfw.egl.KHR_create_context_no_error)
|
|
||||||
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
{
|
{
|
||||||
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
|
setEGLattrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
|
||||||
setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
|
setEGLattrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
|
setEGLattrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
|
||||||
|
|
||||||
if (flags)
|
if (flags)
|
||||||
setAttrib(EGL_CONTEXT_FLAGS_KHR, flags);
|
setEGLattrib(EGL_CONTEXT_FLAGS_KHR, flags);
|
||||||
|
|
||||||
|
setEGLattrib(EGL_NONE, EGL_NONE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
setAttrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
|
setEGLattrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
|
||||||
|
|
||||||
|
setEGLattrib(EGL_NONE, EGL_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.egl.KHR_context_flush_control)
|
// Context release behaviors (GL_KHR_context_flush_control) are not yet
|
||||||
{
|
// supported on EGL but are not a hard constraint, so ignore and continue
|
||||||
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
|
||||||
{
|
|
||||||
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
|
|
||||||
EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
|
|
||||||
}
|
|
||||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
|
||||||
{
|
|
||||||
setAttrib(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
|
|
||||||
EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setAttrib(EGL_NONE, EGL_NONE);
|
|
||||||
|
|
||||||
window->context.egl.handle = eglCreateContext(_glfw.egl.display,
|
window->context.egl.handle = eglCreateContext(_glfw.egl.display,
|
||||||
config, share, attribs);
|
config, share, attribs);
|
||||||
@@ -587,15 +561,14 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
if (fbconfig->sRGB)
|
if (fbconfig->sRGB)
|
||||||
{
|
{
|
||||||
if (_glfw.egl.KHR_gl_colorspace)
|
if (_glfw.egl.KHR_gl_colorspace)
|
||||||
setAttrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
|
{
|
||||||
|
setEGLattrib(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setAttrib(EGL_NONE, EGL_NONE);
|
setEGLattrib(EGL_NONE, EGL_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The surface for EGLDevice backened is created in _glfwPlatformCreateWindow
|
|
||||||
//
|
|
||||||
#if !defined (_GLFW_EGLDEVICE)
|
|
||||||
window->context.egl.surface =
|
window->context.egl.surface =
|
||||||
eglCreateWindowSurface(_glfw.egl.display,
|
eglCreateWindowSurface(_glfw.egl.display,
|
||||||
config,
|
config,
|
||||||
@@ -608,7 +581,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
getEGLErrorString(eglGetError()));
|
getEGLErrorString(eglGetError()));
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
window->context.egl.config = config;
|
window->context.egl.config = config;
|
||||||
|
|
||||||
@@ -619,9 +591,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
const char** sonames;
|
const char** sonames;
|
||||||
const char* es1sonames[] =
|
const char* es1sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_GLESV1_LIBRARY)
|
#if defined(_GLFW_WIN32)
|
||||||
_GLFW_GLESV1_LIBRARY,
|
|
||||||
#elif defined(_GLFW_WIN32)
|
|
||||||
"GLESv1_CM.dll",
|
"GLESv1_CM.dll",
|
||||||
"libGLES_CM.dll",
|
"libGLES_CM.dll",
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
@@ -634,15 +604,11 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
};
|
};
|
||||||
const char* es2sonames[] =
|
const char* es2sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_GLESV2_LIBRARY)
|
#if defined(_GLFW_WIN32)
|
||||||
_GLFW_GLESV2_LIBRARY,
|
|
||||||
#elif defined(_GLFW_WIN32)
|
|
||||||
"GLESv2.dll",
|
"GLESv2.dll",
|
||||||
"libGLESv2.dll",
|
"libGLESv2.dll",
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
"libGLESv2.dylib",
|
"libGLESv2.dylib",
|
||||||
#elif defined(__CYGWIN__)
|
|
||||||
"libGLESv2-2.so",
|
|
||||||
#else
|
#else
|
||||||
"libGLESv2.so.2",
|
"libGLESv2.so.2",
|
||||||
#endif
|
#endif
|
||||||
@@ -650,9 +616,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
};
|
};
|
||||||
const char* glsonames[] =
|
const char* glsonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_OPENGL_LIBRARY)
|
#if defined(_GLFW_WIN32)
|
||||||
_GLFW_OPENGL_LIBRARY,
|
|
||||||
#elif defined(_GLFW_WIN32)
|
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
#else
|
#else
|
||||||
"libGL.so.1",
|
"libGL.so.1",
|
||||||
@@ -700,7 +664,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef setAttrib
|
#undef setEGLattrib
|
||||||
|
|
||||||
// Returns the Visual and depth of the chosen EGLConfig
|
// Returns the Visual and depth of the chosen EGLConfig
|
||||||
//
|
//
|
||||||
|
|||||||
+4
-15
@@ -25,16 +25,15 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_egl_context_h_
|
||||||
|
#define _glfw3_egl_context_h_
|
||||||
|
|
||||||
#if defined(_GLFW_USE_EGLPLATFORM_H)
|
#if defined(_GLFW_USE_EGLPLATFORM_H)
|
||||||
#include <EGL/eglplatform.h>
|
#include <EGL/eglplatform.h>
|
||||||
#elif defined(_GLFW_WIN32)
|
#elif defined(_GLFW_WIN32)
|
||||||
#define EGLAPIENTRY __stdcall
|
#define EGLAPIENTRY __stdcall
|
||||||
typedef HDC EGLNativeDisplayType;
|
typedef HDC EGLNativeDisplayType;
|
||||||
typedef HWND EGLNativeWindowType;
|
typedef HWND EGLNativeWindowType;
|
||||||
#elif defined(_GLFW_COCOA)
|
|
||||||
#define EGLAPIENTRY
|
|
||||||
typedef void* EGLNativeDisplayType;
|
|
||||||
typedef id EGLNativeWindowType;
|
|
||||||
#elif defined(_GLFW_X11)
|
#elif defined(_GLFW_X11)
|
||||||
#define EGLAPIENTRY
|
#define EGLAPIENTRY
|
||||||
typedef Display* EGLNativeDisplayType;
|
typedef Display* EGLNativeDisplayType;
|
||||||
@@ -47,10 +46,6 @@ typedef struct wl_egl_window* EGLNativeWindowType;
|
|||||||
#define EGLAPIENTRY
|
#define EGLAPIENTRY
|
||||||
typedef MirEGLNativeDisplayType EGLNativeDisplayType;
|
typedef MirEGLNativeDisplayType EGLNativeDisplayType;
|
||||||
typedef MirEGLNativeWindowType EGLNativeWindowType;
|
typedef MirEGLNativeWindowType EGLNativeWindowType;
|
||||||
#elif defined(_GLFW_EGLDEVICE)
|
|
||||||
#define EGLAPIENTRY
|
|
||||||
typedef void* EGLNativeDisplayType;
|
|
||||||
typedef int EGLNativeWindowType;
|
|
||||||
#else
|
#else
|
||||||
#error "No supported EGL platform selected"
|
#error "No supported EGL platform selected"
|
||||||
#endif
|
#endif
|
||||||
@@ -88,8 +83,6 @@ typedef int EGLNativeWindowType;
|
|||||||
#define EGL_OPENGL_ES_API 0x30a0
|
#define EGL_OPENGL_ES_API 0x30a0
|
||||||
#define EGL_OPENGL_API 0x30a2
|
#define EGL_OPENGL_API 0x30a2
|
||||||
#define EGL_NONE 0x3038
|
#define EGL_NONE 0x3038
|
||||||
#define EGL_WIDTH 0x3057
|
|
||||||
#define EGL_HEIGHT 0x3056
|
|
||||||
#define EGL_EXTENSIONS 0x3055
|
#define EGL_EXTENSIONS 0x3055
|
||||||
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
|
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
|
||||||
#define EGL_NATIVE_VISUAL_ID 0x302e
|
#define EGL_NATIVE_VISUAL_ID 0x302e
|
||||||
@@ -113,9 +106,6 @@ typedef int EGLNativeWindowType;
|
|||||||
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3
|
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3
|
||||||
#define EGL_GL_COLORSPACE_KHR 0x309d
|
#define EGL_GL_COLORSPACE_KHR 0x309d
|
||||||
#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
|
#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
|
||||||
#define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097
|
|
||||||
#define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0
|
|
||||||
#define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098
|
|
||||||
|
|
||||||
typedef int EGLint;
|
typedef int EGLint;
|
||||||
typedef unsigned int EGLBoolean;
|
typedef unsigned int EGLBoolean;
|
||||||
@@ -124,7 +114,6 @@ typedef void* EGLConfig;
|
|||||||
typedef void* EGLContext;
|
typedef void* EGLContext;
|
||||||
typedef void* EGLDisplay;
|
typedef void* EGLDisplay;
|
||||||
typedef void* EGLSurface;
|
typedef void* EGLSurface;
|
||||||
typedef intptr_t EGLAttrib;
|
|
||||||
|
|
||||||
// EGL function pointer typedefs
|
// EGL function pointer typedefs
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
|
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
|
||||||
@@ -188,7 +177,6 @@ typedef struct _GLFWlibraryEGL
|
|||||||
GLFWbool KHR_create_context_no_error;
|
GLFWbool KHR_create_context_no_error;
|
||||||
GLFWbool KHR_gl_colorspace;
|
GLFWbool KHR_gl_colorspace;
|
||||||
GLFWbool KHR_get_all_proc_addresses;
|
GLFWbool KHR_get_all_proc_addresses;
|
||||||
GLFWbool KHR_context_flush_control;
|
|
||||||
|
|
||||||
void* handle;
|
void* handle;
|
||||||
|
|
||||||
@@ -223,3 +211,4 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
|||||||
Visual** visual, int* depth);
|
Visual** visual, int* depth);
|
||||||
#endif /*_GLFW_X11*/
|
#endif /*_GLFW_X11*/
|
||||||
|
|
||||||
|
#endif // _glfw3_egl_context_h_
|
||||||
|
|||||||
@@ -1,284 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 EGLDevice - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#include <linux/limits.h>
|
|
||||||
|
|
||||||
static GLFWbool initializeExtensions(void)
|
|
||||||
{
|
|
||||||
_glfw.egldevice.QueryDevicesEXT =
|
|
||||||
(PFNEGLQUERYDEVICESEXTPROC)
|
|
||||||
eglGetProcAddress("eglQueryDevicesEXT");
|
|
||||||
_glfw.egldevice.QueryDeviceStringEXT =
|
|
||||||
(PFNEGLQUERYDEVICESTRINGEXTPROC)
|
|
||||||
eglGetProcAddress("eglQueryDeviceStringEXT");
|
|
||||||
_glfw.egldevice.GetPlatformDisplayEXT =
|
|
||||||
(PFNEGLGETPLATFORMDISPLAYEXTPROC)
|
|
||||||
eglGetProcAddress("eglGetPlatformDisplayEXT");
|
|
||||||
_glfw.egldevice.GetOutputLayersEXT =
|
|
||||||
(PFNEGLGETOUTPUTLAYERSEXTPROC)
|
|
||||||
eglGetProcAddress("eglGetOutputLayersEXT");
|
|
||||||
_glfw.egldevice.CreateStreamKHR =
|
|
||||||
(PFNEGLCREATESTREAMKHRPROC)
|
|
||||||
eglGetProcAddress("eglCreateStreamKHR");
|
|
||||||
_glfw.egldevice.DestroyStreamKHR =
|
|
||||||
(PFNEGLDESTROYSTREAMKHRPROC)
|
|
||||||
eglGetProcAddress("eglDestroyStreamKHR");
|
|
||||||
_glfw.egldevice.StreamConsumerOutputEXT =
|
|
||||||
(PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)
|
|
||||||
eglGetProcAddress("eglStreamConsumerOutputEXT");
|
|
||||||
_glfw.egldevice.CreateStreamProducerSurfaceKHR =
|
|
||||||
(PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)
|
|
||||||
eglGetProcAddress("eglCreateStreamProducerSurfaceKHR");
|
|
||||||
|
|
||||||
if(!_glfw.egldevice.QueryDevicesEXT ||
|
|
||||||
!_glfw.egldevice.QueryDeviceStringEXT ||
|
|
||||||
!_glfw.egldevice.GetPlatformDisplayEXT ||
|
|
||||||
!_glfw.egldevice.GetOutputLayersEXT ||
|
|
||||||
!_glfw.egldevice.CreateStreamKHR ||
|
|
||||||
!_glfw.egldevice.DestroyStreamKHR ||
|
|
||||||
!_glfw.egldevice.StreamConsumerOutputEXT ||
|
|
||||||
!_glfw.egldevice.CreateStreamProducerSurfaceKHR)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Failed to find required EGL extension functions");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static EGLDeviceEXT getEGLDevice(void)
|
|
||||||
{
|
|
||||||
int i, num_devs;
|
|
||||||
EGLDeviceEXT* egl_devs, eglDevice;
|
|
||||||
const char *clientExtensionString;
|
|
||||||
|
|
||||||
eglDevice = EGL_NO_DEVICE_EXT;
|
|
||||||
clientExtensionString = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
|
||||||
if (!_glfwStringInExtensionString("EGL_EXT_device_base",
|
|
||||||
clientExtensionString) &&
|
|
||||||
(!_glfwStringInExtensionString("EGL_EXT_device_enumeration",
|
|
||||||
clientExtensionString) ||
|
|
||||||
!_glfwStringInExtensionString("EGL_EXT_device_query",
|
|
||||||
clientExtensionString)))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: EGL_EXT_device base extensions not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!eglQueryDevicesEXT(0, NULL, &num_devs))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Falied to query EGLDevice");
|
|
||||||
}
|
|
||||||
if (num_devs < 1)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: No devices found");
|
|
||||||
}
|
|
||||||
|
|
||||||
egl_devs = calloc(sizeof(EGLDeviceEXT), num_devs);
|
|
||||||
if (egl_devs == NULL)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Unable to allocate memory for device storage");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select suitable device
|
|
||||||
if (!eglQueryDevicesEXT(num_devs, egl_devs, &num_devs))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Failed to query EGL devices");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i <= num_devs; i++)
|
|
||||||
{
|
|
||||||
const char* deviceExtensionString;
|
|
||||||
|
|
||||||
deviceExtensionString = eglQueryDeviceStringEXT(egl_devs[i], EGL_EXTENSIONS);
|
|
||||||
if (_glfwStringInExtensionString("EGL_EXT_device_drm",
|
|
||||||
deviceExtensionString))
|
|
||||||
{
|
|
||||||
eglDevice = egl_devs[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(egl_devs);
|
|
||||||
|
|
||||||
if (eglDevice == EGL_NO_DEVICE_EXT)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Missing required extension EGL_EXT_device_drm");
|
|
||||||
}
|
|
||||||
return eglDevice;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int getDRMFd(EGLDeviceEXT eglDevice)
|
|
||||||
{
|
|
||||||
int drm_fd;
|
|
||||||
const char* drmName;
|
|
||||||
|
|
||||||
drmName = eglQueryDeviceStringEXT(eglDevice, EGL_DRM_DEVICE_FILE_EXT);
|
|
||||||
if (!drmName || (strnlen(drmName, PATH_MAX) == 0))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Couldn't obtain device file from 0x%p",
|
|
||||||
(void*)(uintptr_t)eglDevice);
|
|
||||||
}
|
|
||||||
|
|
||||||
drm_fd = drmOpen(drmName, NULL);
|
|
||||||
if (drm_fd < 0)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Couldn't open device file '%s'", drmName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return drm_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GLFWbool initEGLDisplay(EGLDeviceEXT egl_dev, int drm_fd)
|
|
||||||
{
|
|
||||||
const char* displayExtensionString;
|
|
||||||
EGLint displayAttribs[] = {
|
|
||||||
EGL_DRM_MASTER_FD_EXT,
|
|
||||||
drm_fd,
|
|
||||||
EGL_NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
_glfw.egl.display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT,
|
|
||||||
(void*)egl_dev,
|
|
||||||
displayAttribs);
|
|
||||||
if (_glfw.egl.display == EGL_NO_DISPLAY)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Couldn't obtain EGLDisplay for device");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Failed to initialize EGL");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for stream_consumer_egloutput + output_drm support
|
|
||||||
displayExtensionString = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
|
|
||||||
if (!_glfwStringInExtensionString("EGL_EXT_output_base",
|
|
||||||
displayExtensionString))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Missing required extension EGL_EXT_output_base");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_glfwStringInExtensionString("EGL_EXT_output_drm",
|
|
||||||
displayExtensionString))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Missing required extension EGL_EXT_output_drm");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_glfwStringInExtensionString("EGL_KHR_stream",
|
|
||||||
displayExtensionString))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Missing required extension EGL_KHR_stream");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_glfwStringInExtensionString("EGL_KHR_stream_producer_eglsurface",
|
|
||||||
displayExtensionString))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Missing required extension EGL_KHR_stream_producer_eglsurface");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
if (!_glfwStringInExtensionString("EGL_EXT_stream_consumer_egloutput",
|
|
||||||
displayExtensionString))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Missing required extension EGL_EXT_stream_consumer_egloutput");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int _glfwPlatformInit(void)
|
|
||||||
{
|
|
||||||
EGLDeviceEXT egl_dev;
|
|
||||||
int drm_fd;
|
|
||||||
|
|
||||||
// Initialize EGL
|
|
||||||
if (!_glfwInitEGL())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
// Initialize global data and extension function pointers
|
|
||||||
if (!initializeExtensions())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
// Query and Obtain EGLDevice
|
|
||||||
egl_dev = getEGLDevice();
|
|
||||||
|
|
||||||
// Obtain and open DRM device file
|
|
||||||
drm_fd = getDRMFd(egl_dev);
|
|
||||||
|
|
||||||
// Store for use later
|
|
||||||
_glfw.egldevice.drmFd = drm_fd;
|
|
||||||
|
|
||||||
// Obtain EGLDisplay
|
|
||||||
if (!initEGLDisplay(egl_dev, drm_fd))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
_glfwInitTimerPOSIX();
|
|
||||||
|
|
||||||
_glfwPollMonitorsEGLDevice();
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformTerminate(void)
|
|
||||||
{
|
|
||||||
_glfwTerminateEGL();
|
|
||||||
_glfwTerminateJoysticksLinux();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* _glfwPlatformGetVersionString(void)
|
|
||||||
{
|
|
||||||
return _GLFW_VERSION_NUMBER "EGLDevice EGL"
|
|
||||||
#if defined(_GLFW_BUILD_DLL)
|
|
||||||
" shared"
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 EGLDevice - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
static GLFWbool pickConnector(_GLFWmonitor* monitor, int drm_fd, drmModeRes* res_info)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
// Getting suitable connector, encoder and crtc
|
|
||||||
for (i = 0; i < res_info->count_connectors; i++)
|
|
||||||
{
|
|
||||||
monitor->egldevice.connId = res_info->connectors[i];
|
|
||||||
|
|
||||||
drmModeConnector* conn_info;
|
|
||||||
|
|
||||||
conn_info =
|
|
||||||
drmModeGetConnector(drm_fd, monitor->egldevice.connId);
|
|
||||||
if (!conn_info)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Unable to obtain info for connector (%d)",
|
|
||||||
monitor->egldevice.connId);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
if (conn_info->connection == DRM_MODE_CONNECTED &&
|
|
||||||
conn_info->count_modes > 0 &&
|
|
||||||
conn_info->count_encoders > 0)
|
|
||||||
{
|
|
||||||
monitor->egldevice.encId = conn_info->encoders[0];
|
|
||||||
|
|
||||||
drmModeEncoder* enc_info;
|
|
||||||
|
|
||||||
enc_info =
|
|
||||||
drmModeGetEncoder(drm_fd, monitor->egldevice.encId);
|
|
||||||
if (!enc_info) {
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Unable to query DRM-KMS information for connector index %d", i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select the modesize
|
|
||||||
monitor->currentMode.width = (int)conn_info->modes[0].hdisplay;
|
|
||||||
monitor->currentMode.height = (int)conn_info->modes[0].vdisplay;
|
|
||||||
monitor->currentMode.refreshRate = (int)conn_info->modes[0].vrefresh;
|
|
||||||
monitor->modeCount = (int)conn_info->count_modes;
|
|
||||||
monitor->name = conn_info->modes[0].name;
|
|
||||||
|
|
||||||
for (j = 0; j < res_info->count_crtcs; j++)
|
|
||||||
{
|
|
||||||
if ((enc_info->possible_crtcs & (1 << j)) == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
monitor->egldevice.crtcId = res_info->crtcs[j];
|
|
||||||
monitor->egldevice.crtcIndex = j;
|
|
||||||
|
|
||||||
if (res_info->crtcs[i] == enc_info->crtc_id)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (monitor->egldevice.crtcId == 0)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Unable to select suitable CRTC");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
drmModeFreeEncoder(enc_info);
|
|
||||||
}
|
|
||||||
drmModeFreeConnector(conn_info);
|
|
||||||
}
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GLFWbool initDRMResources(_GLFWmonitor* monitor, int drm_fd)
|
|
||||||
{
|
|
||||||
drmModeRes* res_info;
|
|
||||||
|
|
||||||
res_info = drmModeGetResources(drm_fd);
|
|
||||||
if (!res_info)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Couldn't obtain DRM-KMS resources");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!pickConnector(monitor, drm_fd, res_info))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
drmModeFreeResources(res_info);
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
/////////// GLFW platform API //////////////
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void _glfwPollMonitorsEGLDevice(void)
|
|
||||||
{
|
|
||||||
_GLFWmonitor* monitor = _glfwAllocMonitor("Monitor", 0, 0);
|
|
||||||
|
|
||||||
// Obtain DRM resource info
|
|
||||||
if (!initDRMResources(monitor, _glfw.egldevice.drmFd))
|
|
||||||
{
|
|
||||||
_glfwFreeMonitor(monitor);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_FIRST);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetMonitorPos not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetVideoModes not implemented");
|
|
||||||
*found = 0;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetVideoMode not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetGammaRamp not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetGammaRamp not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 EGLDevice - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <xf86drm.h>
|
|
||||||
#include <xf86drmMode.h>
|
|
||||||
#include <drm_fourcc.h>
|
|
||||||
|
|
||||||
#include "posix_time.h"
|
|
||||||
#include "linux_joystick.h"
|
|
||||||
#include "posix_thread.h"
|
|
||||||
#include "egl_context.h"
|
|
||||||
#include "osmesa_context.h"
|
|
||||||
|
|
||||||
#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT) 0)
|
|
||||||
#define EGL_DRM_DEVICE_FILE_EXT 0x3233
|
|
||||||
#define EGL_PLATFORM_DEVICE_EXT 0x313f
|
|
||||||
#define EGL_DRM_MASTER_FD_EXT 0x333c
|
|
||||||
#define EGL_STREAM_FIFO_LENGTH_KHR 0x31fc
|
|
||||||
#define EGL_DRM_CRTC_EXT 0x3234
|
|
||||||
#define EGL_NO_STREAM_KHR ((EGLStreamKHR) 0)
|
|
||||||
#define EGL_STREAM_BIT_KHR 0x0800
|
|
||||||
|
|
||||||
typedef void* EGLOutputLayerEXT;
|
|
||||||
typedef void* EGLStreamKHR;
|
|
||||||
typedef void* EGLDeviceEXT;
|
|
||||||
|
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLQUERYDEVICESEXTPROC)(EGLint,EGLDeviceEXT*,EGLint*);
|
|
||||||
typedef const char *(EGLAPIENTRY * PFNEGLQUERYDEVICESTRINGEXTPROC)(EGLDeviceEXT,EGLint);
|
|
||||||
typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);
|
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLGETOUTPUTLAYERSEXTPROC)(EGLDisplay,const EGLAttrib*,EGLOutputLayerEXT*,EGLint,EGLint*);
|
|
||||||
typedef EGLStreamKHR (EGLAPIENTRY * PFNEGLCREATESTREAMKHRPROC)(EGLDisplay,const EGLint*);
|
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLDESTROYSTREAMKHRPROC)(EGLDisplay,EGLStreamKHR);
|
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)(EGLDisplay,EGLStreamKHR,EGLOutputLayerEXT);
|
|
||||||
typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay,EGLConfig,EGLStreamKHR,const EGLint*);
|
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMATTRIBKHRPROC)(EGLDisplay,EGLStreamKHR,EGLenum,EGLint);
|
|
||||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC)(EGLDisplay,EGLStreamKHR,const EGLAttrib*);
|
|
||||||
#define eglQueryDevicesEXT _glfw.egldevice.QueryDevicesEXT
|
|
||||||
#define eglQueryDeviceStringEXT _glfw.egldevice.QueryDeviceStringEXT
|
|
||||||
#define eglGetPlatformDisplayEXT _glfw.egldevice.GetPlatformDisplayEXT
|
|
||||||
#define eglGetOutputLayersEXT _glfw.egldevice.GetOutputLayersEXT
|
|
||||||
#define eglCreateStreamKHR _glfw.egldevice.CreateStreamKHR
|
|
||||||
#define eglDestroyStreamKHR _glfw.egldevice.DestroyStreamKHR
|
|
||||||
#define eglStreamConsumerOutputEXT _glfw.egldevice.StreamConsumerOutputEXT
|
|
||||||
#define eglCreateStreamProducerSurfaceKHR _glfw.egldevice.CreateStreamProducerSurfaceKHR
|
|
||||||
#define eglStreamAttribKHR _glfw.egldevice.StreamAttribKHR
|
|
||||||
#define eglStreamConsumerAcquireAttribKHR _glfw.egldevice.StreamConsumerAcquireAttribKHR
|
|
||||||
|
|
||||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
|
||||||
#define _glfw_dlclose(handle) dlclose(handle)
|
|
||||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType)window->egldevice.handle)
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowEGLDevice egldevice
|
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryEGLDevice egldevice
|
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorEGLDevice egldevice
|
|
||||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorEGLDevice egldevice
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE
|
|
||||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
|
||||||
|
|
||||||
// EGLDevice-specific per-window data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWwindowEGLDevice
|
|
||||||
{
|
|
||||||
int xsurfsize, ysurfsize;
|
|
||||||
int xoffset, yoffset;
|
|
||||||
int fifo;
|
|
||||||
|
|
||||||
uint32_t planeId;
|
|
||||||
|
|
||||||
EGLDisplay handle;
|
|
||||||
EGLOutputLayerEXT eglLayer;
|
|
||||||
EGLStreamKHR eglStream;
|
|
||||||
} _GLFWwindowEGLDevice;
|
|
||||||
|
|
||||||
// EGLDevice-specific global data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWlibraryEGLDevice
|
|
||||||
{
|
|
||||||
int drmFd;
|
|
||||||
|
|
||||||
PFNEGLQUERYDEVICESEXTPROC QueryDevicesEXT;
|
|
||||||
PFNEGLQUERYDEVICESTRINGEXTPROC QueryDeviceStringEXT;
|
|
||||||
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;
|
|
||||||
PFNEGLGETOUTPUTLAYERSEXTPROC GetOutputLayersEXT;
|
|
||||||
PFNEGLCREATESTREAMKHRPROC CreateStreamKHR;
|
|
||||||
PFNEGLDESTROYSTREAMKHRPROC DestroyStreamKHR;
|
|
||||||
PFNEGLSTREAMCONSUMEROUTPUTEXTPROC StreamConsumerOutputEXT;
|
|
||||||
PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC CreateStreamProducerSurfaceKHR;
|
|
||||||
PFNEGLSTREAMATTRIBKHRPROC StreamAttribKHR;
|
|
||||||
PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC StreamConsumerAcquireAttribKHR;
|
|
||||||
} _GLFWlibraryEGLDevice;
|
|
||||||
|
|
||||||
// EGLDevice-specific per-monitor data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWmonitorEGLDevice
|
|
||||||
{
|
|
||||||
int crtcIndex;
|
|
||||||
uint32_t connId, encId, crtcId;
|
|
||||||
} _GLFWmonitorEGLDevice;
|
|
||||||
|
|
||||||
// EGLDevice-specific per-cursor data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWcursorEGLDevice
|
|
||||||
{
|
|
||||||
} _GLFWcursorEGLDevice;
|
|
||||||
|
|
||||||
void _glfwPollMonitorsEGLDevice(void);
|
|
||||||
|
|
||||||
@@ -1,430 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 EGLDevice - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
//////// GLFW platform API /////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|
||||||
const _GLFWwndconfig* wndconfig,
|
|
||||||
const _GLFWctxconfig* ctxconfig,
|
|
||||||
const _GLFWfbconfig* fbconfig)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
EGLAttrib layerAttribs[] = { EGL_NONE, EGL_NONE, EGL_NONE };
|
|
||||||
EGLint streamAttribs[] = { EGL_STREAM_FIFO_LENGTH_KHR,
|
|
||||||
window->egldevice.fifo, EGL_NONE };
|
|
||||||
EGLint surfaceAttribs[] = { EGL_WIDTH, 0, EGL_HEIGHT, 0, EGL_NONE };
|
|
||||||
|
|
||||||
if (window->monitor)
|
|
||||||
monitor = window->monitor;
|
|
||||||
else
|
|
||||||
monitor = _glfw.monitors[0];
|
|
||||||
|
|
||||||
window->egldevice.xsurfsize = wndconfig->width;
|
|
||||||
window->egldevice.ysurfsize = wndconfig->height;
|
|
||||||
|
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
// Get the layer for this crtc/plane
|
|
||||||
layerAttribs[0] = EGL_DRM_CRTC_EXT;
|
|
||||||
layerAttribs[1] = (EGLAttrib)monitor->egldevice.crtcId;
|
|
||||||
|
|
||||||
if (!eglGetOutputLayersEXT(_glfw.egl.display, layerAttribs,
|
|
||||||
&window->egldevice.eglLayer,
|
|
||||||
1, &n) || !n)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Unable to obtain EGLOutputLayer");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a stream and connect to the output
|
|
||||||
window->egldevice.eglStream =
|
|
||||||
eglCreateStreamKHR(_glfw.egl.display, streamAttribs);
|
|
||||||
if (window->egldevice.eglStream == EGL_NO_STREAM_KHR)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Unable to create stream (error 0x%x)",
|
|
||||||
eglGetError());
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
if (!eglStreamConsumerOutputEXT(_glfw.egl.display,
|
|
||||||
window->egldevice.eglStream,
|
|
||||||
window->egldevice.eglLayer))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Unable to connect stream (error 0x%x)",
|
|
||||||
eglGetError());
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a surface to feed the stream
|
|
||||||
surfaceAttribs[1] = window->egldevice.xsurfsize;
|
|
||||||
surfaceAttribs[3] = window->egldevice.ysurfsize;
|
|
||||||
window->context.egl.surface =
|
|
||||||
eglCreateStreamProducerSurfaceKHR(_glfw.egl.display,
|
|
||||||
window->context.egl.config,
|
|
||||||
window->egldevice.eglStream,
|
|
||||||
surfaceAttribs);
|
|
||||||
if (window->context.egl.surface == EGL_NO_SURFACE)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Unable to create rendering surface (error 0x%x)", eglGetError());
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
if (window->context.client != GLFW_NO_API)
|
|
||||||
window->context.destroy(window);
|
|
||||||
|
|
||||||
if (window->egldevice.eglStream != EGL_NO_STREAM_KHR)
|
|
||||||
eglDestroyStreamKHR(_glfw.egl.display, window->egldevice.eglStream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetWindowTitle is not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
|
||||||
int count, const GLFWimage* images)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetWindowIcon is not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
|
||||||
{
|
|
||||||
if (xpos)
|
|
||||||
*xpos = window->egldevice.xoffset;
|
|
||||||
if (ypos)
|
|
||||||
*ypos = window->egldevice.yoffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
|
||||||
{
|
|
||||||
window->egldevice.xoffset = xpos;
|
|
||||||
window->egldevice.yoffset = ypos;
|
|
||||||
|
|
||||||
drmModeRes* res_info;
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
|
|
||||||
if (window->monitor)
|
|
||||||
monitor = window->monitor;
|
|
||||||
else
|
|
||||||
monitor = _glfw.monitors[0];
|
|
||||||
|
|
||||||
res_info = drmModeGetResources(_glfw.egldevice.drmFd);
|
|
||||||
if (drmModeSetCrtc(_glfw.egldevice.drmFd,
|
|
||||||
res_info->crtcs[monitor->egldevice.crtcIndex],
|
|
||||||
-1, window->egldevice.xoffset, window->egldevice.yoffset,
|
|
||||||
&res_info->connectors[monitor->egldevice.crtcIndex], 1, NULL))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: Setting window pos failed");
|
|
||||||
}
|
|
||||||
drmModeFreeResources(res_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
|
||||||
{
|
|
||||||
if (width)
|
|
||||||
*width = window->egldevice.xsurfsize;
|
|
||||||
if (height)
|
|
||||||
*height = window->egldevice.ysurfsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetWindowSize not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
|
||||||
int minwidth, int minheight,
|
|
||||||
int maxwidth, int maxheight)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetWindowSizeLimits not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetWindowAspectRatio not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
|
||||||
{
|
|
||||||
_glfwPlatformGetWindowSize(window, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
|
||||||
int* left, int* top,
|
|
||||||
int* right, int* bottom)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetWindowFrameSize not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformIconifyWindow not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformRestoreWindow not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformMaximizeWindow not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetWindowResizable not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetWindowDecorated not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetWindowFloating not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformRequestWindowAttention not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformUnhideWindow not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformHideWindow not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|
||||||
_GLFWmonitor* monitor,
|
|
||||||
int xpos, int ypos,
|
|
||||||
int width, int height,
|
|
||||||
int refreshRate)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetWindowMonitor not implemented");
|
|
||||||
}
|
|
||||||
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformWindowFocused not implemented");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformWindowIconified not implemented");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformWindowVisible not implemented");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformWindowMaximized not implemented");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformPollEvents(void)
|
|
||||||
{
|
|
||||||
_glfwDetectJoystickConnectionLinux();
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformWaitEvents(void)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformWaitEvents not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformWaitEventsTimeout(double timeout)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformWaitEventsTimeout not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformPostEmptyEvent(void)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformPostEmptyEvent not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetCursorPos not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetCursorPos not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetCursorMode not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* _glfwPlatformGetKeyName(int key, int scancode)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetKeyName not supported");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|
||||||
const GLFWimage* image,
|
|
||||||
int xhot, int yhot)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformCreateCursor not supported");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformCreateStandardCursor not supported");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetCursor not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformSetClipboardString not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetClipboardString not supported");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetScancodeName not supported");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformGetKeyScancode(int key)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetKeyScancode not supported");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetRequiredInstanceExtensions not supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|
||||||
VkPhysicalDevice device,
|
|
||||||
uint32_t queuefamily)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformGetPhysicalDevicePresentationSupport not supported");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
|
||||||
_GLFWwindow* window,
|
|
||||||
const VkAllocationCallbacks* allocator,
|
|
||||||
VkSurfaceKHR* surface)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"EGLDevice: _glfwPlatformCreateWindowSurface not supported");
|
|
||||||
return VK_ERROR_INITIALIZATION_FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -46,8 +46,6 @@
|
|||||||
#cmakedefine _GLFW_MIR
|
#cmakedefine _GLFW_MIR
|
||||||
// Define this to 1 if building GLFW for OSMesa
|
// Define this to 1 if building GLFW for OSMesa
|
||||||
#cmakedefine _GLFW_OSMESA
|
#cmakedefine _GLFW_OSMESA
|
||||||
// Define this to 1 if building GLFW for EGLDevice
|
|
||||||
#cmakedefine _GLFW_EGLDEVICE
|
|
||||||
|
|
||||||
// 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
|
||||||
@@ -57,3 +55,8 @@
|
|||||||
// 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
|
||||||
|
|
||||||
|
// Define this to 1 if glfwInit should change the current directory
|
||||||
|
#cmakedefine _GLFW_USE_CHDIR
|
||||||
|
// Define this to 1 if glfwCreateWindow should populate the menu bar
|
||||||
|
#cmakedefine _GLFW_USE_MENUBAR
|
||||||
|
|
||||||
|
|||||||
+25
-34
@@ -59,12 +59,12 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
|
|||||||
// HACK: This is a (hopefully temporary) workaround for Chromium
|
// HACK: This is a (hopefully temporary) workaround for Chromium
|
||||||
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
|
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
|
||||||
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
|
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
|
||||||
if (vendor && strcmp(vendor, "Chromium") == 0)
|
if (strcmp(vendor, "Chromium") == 0)
|
||||||
trustWindowBit = GLFW_FALSE;
|
trustWindowBit = GLFW_FALSE;
|
||||||
|
|
||||||
nativeConfigs =
|
nativeConfigs =
|
||||||
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
|
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
|
||||||
if (!nativeConfigs || !nativeCount)
|
if (!nativeCount)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
|
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@@ -165,7 +165,7 @@ static void makeContextCurrentGLX(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
_glfwPlatformSetCurrentContext(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void swapBuffersGLX(_GLFWwindow* window)
|
static void swapBuffersGLX(_GLFWwindow* window)
|
||||||
@@ -175,7 +175,7 @@ static void swapBuffersGLX(_GLFWwindow* window)
|
|||||||
|
|
||||||
static void swapIntervalGLX(int interval)
|
static void swapIntervalGLX(int interval)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||||
|
|
||||||
if (_glfw.glx.EXT_swap_control)
|
if (_glfw.glx.EXT_swap_control)
|
||||||
{
|
{
|
||||||
@@ -244,9 +244,7 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
int i;
|
int i;
|
||||||
const char* sonames[] =
|
const char* sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_GLX_LIBRARY)
|
#if defined(__CYGWIN__)
|
||||||
_GLFW_GLX_LIBRARY,
|
|
||||||
#elif defined(__CYGWIN__)
|
|
||||||
"libGL-1.so",
|
"libGL-1.so",
|
||||||
#else
|
#else
|
||||||
"libGL.so.1",
|
"libGL.so.1",
|
||||||
@@ -399,9 +397,6 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
if (extensionSupportedGLX("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 (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
|
|
||||||
_glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
|
|
||||||
|
|
||||||
if (extensionSupportedGLX("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;
|
||||||
|
|
||||||
@@ -422,11 +417,11 @@ void _glfwTerminateGLX(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define setAttrib(a, v) \
|
#define setGLXattrib(attribName, attribValue) \
|
||||||
{ \
|
{ \
|
||||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
attribs[index++] = attribName; \
|
||||||
attribs[index++] = a; \
|
attribs[index++] = attribValue; \
|
||||||
attribs[index++] = v; \
|
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the OpenGL or OpenGL ES context
|
// Create the OpenGL or OpenGL ES context
|
||||||
@@ -503,6 +498,8 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
|
|
||||||
if (ctxconfig->debug)
|
if (ctxconfig->debug)
|
||||||
flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
|
flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
|
||||||
|
if (ctxconfig->noerror)
|
||||||
|
flags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;
|
||||||
|
|
||||||
if (ctxconfig->robustness)
|
if (ctxconfig->robustness)
|
||||||
{
|
{
|
||||||
@@ -510,13 +507,13 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||||
{
|
{
|
||||||
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
GLX_NO_RESET_NOTIFICATION_ARB);
|
GLX_NO_RESET_NOTIFICATION_ARB);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
{
|
{
|
||||||
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
GLX_LOSE_CONTEXT_ON_RESET_ARB);
|
GLX_LOSE_CONTEXT_ON_RESET_ARB);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
||||||
@@ -529,39 +526,33 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||||
{
|
{
|
||||||
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||||
{
|
{
|
||||||
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxconfig->noerror)
|
|
||||||
{
|
|
||||||
if (_glfw.glx.ARB_create_context_no_error)
|
|
||||||
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Only request an explicitly versioned context when necessary, as
|
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||||
// explicitly requesting version 1.0 does not always return the
|
// explicitly requesting version 1.0 does not always return the
|
||||||
// highest version supported by the driver
|
// highest version supported by the driver
|
||||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
{
|
{
|
||||||
setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
||||||
setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
|
setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
|
||||||
|
|
||||||
if (flags)
|
if (flags)
|
||||||
setAttrib(GLX_CONTEXT_FLAGS_ARB, flags);
|
setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags);
|
||||||
|
|
||||||
setAttrib(None, None);
|
setGLXattrib(None, None);
|
||||||
|
|
||||||
window->context.glx.handle =
|
window->context.glx.handle =
|
||||||
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
|
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
|
||||||
@@ -618,7 +609,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef setAttrib
|
#undef setGLXattrib
|
||||||
|
|
||||||
// Returns the Visual and depth of the chosen GLXFBConfig
|
// Returns the Visual and depth of the chosen GLXFBConfig
|
||||||
//
|
//
|
||||||
|
|||||||
+4
-2
@@ -25,6 +25,9 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_glx_context_h_
|
||||||
|
#define _glfw3_glx_context_h_
|
||||||
|
|
||||||
#define GLX_VENDOR 1
|
#define GLX_VENDOR 1
|
||||||
#define GLX_RGBA_BIT 0x00000001
|
#define GLX_RGBA_BIT 0x00000001
|
||||||
#define GLX_WINDOW_BIT 0x00000001
|
#define GLX_WINDOW_BIT 0x00000001
|
||||||
@@ -64,7 +67,6 @@
|
|||||||
#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
|
#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
|
||||||
#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
|
#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
|
||||||
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
|
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
|
||||||
#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
|
|
||||||
|
|
||||||
typedef XID GLXWindow;
|
typedef XID GLXWindow;
|
||||||
typedef XID GLXDrawable;
|
typedef XID GLXDrawable;
|
||||||
@@ -163,7 +165,6 @@ typedef struct _GLFWlibraryGLX
|
|||||||
GLFWbool ARB_create_context_profile;
|
GLFWbool ARB_create_context_profile;
|
||||||
GLFWbool ARB_create_context_robustness;
|
GLFWbool ARB_create_context_robustness;
|
||||||
GLFWbool EXT_create_context_es2_profile;
|
GLFWbool EXT_create_context_es2_profile;
|
||||||
GLFWbool ARB_create_context_no_error;
|
|
||||||
GLFWbool ARB_context_flush_control;
|
GLFWbool ARB_context_flush_control;
|
||||||
|
|
||||||
} _GLFWlibraryGLX;
|
} _GLFWlibraryGLX;
|
||||||
@@ -179,3 +180,4 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
|
|||||||
const _GLFWfbconfig* fbconfig,
|
const _GLFWfbconfig* fbconfig,
|
||||||
Visual** visual, int* depth);
|
Visual** visual, int* depth);
|
||||||
|
|
||||||
|
#endif // _glfw3_glx_context_h_
|
||||||
|
|||||||
+83
-202
@@ -26,45 +26,33 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "mappings.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
|
|
||||||
// The global variables below comprise all global data in GLFW.
|
// The three global variables below comprise all global data in GLFW.
|
||||||
// Any other global variable is a bug.
|
// Any other global variable is a bug.
|
||||||
|
|
||||||
// Global state shared between compilation units of GLFW
|
// Global state shared between compilation units of GLFW
|
||||||
|
// These are documented in internal.h
|
||||||
//
|
//
|
||||||
_GLFWlibrary _glfw = { GLFW_FALSE };
|
GLFWbool _glfwInitialized = GLFW_FALSE;
|
||||||
|
_GLFWlibrary _glfw;
|
||||||
|
|
||||||
// These are outside of _glfw so they can be used before initialization and
|
// This is outside of _glfw so it can be initialized and usable before
|
||||||
// after termination
|
// glfwInit is called, which lets that function report errors
|
||||||
//
|
//
|
||||||
static _GLFWerror _glfwMainThreadError;
|
static GLFWerrorfun _glfwErrorCallback = NULL;
|
||||||
static GLFWerrorfun _glfwErrorCallback;
|
|
||||||
static _GLFWinitconfig _glfwInitHints =
|
|
||||||
{
|
|
||||||
GLFW_TRUE, // hat buttons
|
|
||||||
{
|
|
||||||
GLFW_TRUE, // macOS menu bar
|
|
||||||
GLFW_TRUE // macOS bundle chdir
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"", // X11 WM_CLASS name
|
|
||||||
"" // X11 WM_CLASS class
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns a generic string representation of the specified error
|
// Returns a generic string representation of the specified error
|
||||||
//
|
//
|
||||||
static const char* getErrorString(int code)
|
static const char* getErrorString(int error)
|
||||||
{
|
{
|
||||||
switch (code)
|
switch (error)
|
||||||
{
|
{
|
||||||
case GLFW_NOT_INITIALIZED:
|
case GLFW_NOT_INITIALIZED:
|
||||||
return "The GLFW library is not initialized";
|
return "The GLFW library is not initialized";
|
||||||
@@ -81,7 +69,7 @@ static const char* getErrorString(int code)
|
|||||||
case GLFW_VERSION_UNAVAILABLE:
|
case GLFW_VERSION_UNAVAILABLE:
|
||||||
return "The requested API version is unavailable";
|
return "The requested API version is unavailable";
|
||||||
case GLFW_PLATFORM_ERROR:
|
case GLFW_PLATFORM_ERROR:
|
||||||
return "An undocumented platform-specific error occurred";
|
return "A platform-specific error occurred";
|
||||||
case GLFW_FORMAT_UNAVAILABLE:
|
case GLFW_FORMAT_UNAVAILABLE:
|
||||||
return "The requested format is unavailable";
|
return "The requested format is unavailable";
|
||||||
case GLFW_NO_WINDOW_CONTEXT:
|
case GLFW_NO_WINDOW_CONTEXT:
|
||||||
@@ -91,12 +79,75 @@ static const char* getErrorString(int code)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Terminate the library
|
|
||||||
//
|
//////////////////////////////////////////////////////////////////////////
|
||||||
static void terminate(void)
|
////// GLFW event API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void _glfwInputError(int error, const char* format, ...)
|
||||||
|
{
|
||||||
|
if (_glfwErrorCallback)
|
||||||
|
{
|
||||||
|
char buffer[8192];
|
||||||
|
const char* description;
|
||||||
|
|
||||||
|
if (format)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
va_list vl;
|
||||||
|
|
||||||
|
va_start(vl, format);
|
||||||
|
count = vsnprintf(buffer, sizeof(buffer), format, vl);
|
||||||
|
va_end(vl);
|
||||||
|
|
||||||
|
if (count < 0)
|
||||||
|
buffer[sizeof(buffer) - 1] = '\0';
|
||||||
|
|
||||||
|
description = buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
description = getErrorString(error);
|
||||||
|
|
||||||
|
_glfwErrorCallback(error, description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW public API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWAPI int glfwInit(void)
|
||||||
|
{
|
||||||
|
if (_glfwInitialized)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
memset(&_glfw, 0, sizeof(_glfw));
|
||||||
|
|
||||||
|
if (!_glfwPlatformInit())
|
||||||
|
{
|
||||||
|
_glfwPlatformTerminate();
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
||||||
|
_glfwInitialized = GLFW_TRUE;
|
||||||
|
|
||||||
|
_glfw.timerOffset = _glfwPlatformGetTimerValue();
|
||||||
|
|
||||||
|
// Not all window hints have zero as their default value
|
||||||
|
glfwDefaultWindowHints();
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWAPI void glfwTerminate(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!_glfwInitialized)
|
||||||
|
return;
|
||||||
|
|
||||||
memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks));
|
memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks));
|
||||||
|
|
||||||
while (_glfw.windowListHead)
|
while (_glfw.windowListHead)
|
||||||
@@ -110,174 +161,28 @@ static void terminate(void)
|
|||||||
_GLFWmonitor* monitor = _glfw.monitors[i];
|
_GLFWmonitor* monitor = _glfw.monitors[i];
|
||||||
if (monitor->originalRamp.size)
|
if (monitor->originalRamp.size)
|
||||||
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
|
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
|
||||||
_glfwFreeMonitor(monitor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(_glfw.monitors);
|
_glfwTerminateVulkan();
|
||||||
|
|
||||||
|
_glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount);
|
||||||
_glfw.monitors = NULL;
|
_glfw.monitors = NULL;
|
||||||
_glfw.monitorCount = 0;
|
_glfw.monitorCount = 0;
|
||||||
|
|
||||||
free(_glfw.mappings);
|
|
||||||
_glfw.mappings = NULL;
|
|
||||||
_glfw.mappingCount = 0;
|
|
||||||
|
|
||||||
_glfwTerminateVulkan();
|
|
||||||
_glfwPlatformTerminate();
|
_glfwPlatformTerminate();
|
||||||
|
|
||||||
_glfw.initialized = GLFW_FALSE;
|
|
||||||
|
|
||||||
while (_glfw.errorListHead)
|
|
||||||
{
|
|
||||||
_GLFWerror* error = _glfw.errorListHead;
|
|
||||||
_glfw.errorListHead = error->next;
|
|
||||||
free(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwPlatformDestroyTls(&_glfw.contextSlot);
|
|
||||||
_glfwPlatformDestroyTls(&_glfw.errorSlot);
|
|
||||||
_glfwPlatformDestroyMutex(&_glfw.errorLock);
|
|
||||||
|
|
||||||
memset(&_glfw, 0, sizeof(_glfw));
|
memset(&_glfw, 0, sizeof(_glfw));
|
||||||
}
|
_glfwInitialized = GLFW_FALSE;
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW event API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void _glfwInputError(int code, const char* format, ...)
|
|
||||||
{
|
|
||||||
_GLFWerror* error;
|
|
||||||
char description[_GLFW_MESSAGE_SIZE];
|
|
||||||
|
|
||||||
if (format)
|
|
||||||
{
|
|
||||||
int count;
|
|
||||||
va_list vl;
|
|
||||||
|
|
||||||
va_start(vl, format);
|
|
||||||
count = vsnprintf(description, sizeof(description), format, vl);
|
|
||||||
va_end(vl);
|
|
||||||
|
|
||||||
if (count < 0)
|
|
||||||
description[sizeof(description) - 1] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
strcpy(description, getErrorString(code));
|
|
||||||
|
|
||||||
if (_glfw.initialized)
|
|
||||||
{
|
|
||||||
error = _glfwPlatformGetTls(&_glfw.errorSlot);
|
|
||||||
if (!error)
|
|
||||||
{
|
|
||||||
error = calloc(1, sizeof(_GLFWerror));
|
|
||||||
_glfwPlatformSetTls(&_glfw.errorSlot, error);
|
|
||||||
_glfwPlatformLockMutex(&_glfw.errorLock);
|
|
||||||
error->next = _glfw.errorListHead;
|
|
||||||
_glfw.errorListHead = error;
|
|
||||||
_glfwPlatformUnlockMutex(&_glfw.errorLock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
error = &_glfwMainThreadError;
|
|
||||||
|
|
||||||
error->code = code;
|
|
||||||
strcpy(error->description, description);
|
|
||||||
|
|
||||||
if (_glfwErrorCallback)
|
|
||||||
_glfwErrorCallback(code, description);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW public API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWAPI int glfwInit(void)
|
|
||||||
{
|
|
||||||
if (_glfw.initialized)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
|
|
||||||
memset(&_glfw, 0, sizeof(_glfw));
|
|
||||||
_glfw.hints.init = _glfwInitHints;
|
|
||||||
|
|
||||||
if (!_glfwPlatformInit())
|
|
||||||
{
|
|
||||||
terminate();
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_glfwPlatformCreateMutex(&_glfw.errorLock))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwPlatformCreateTls(&_glfw.errorSlot))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwPlatformCreateTls(&_glfw.contextSlot))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
|
|
||||||
|
|
||||||
_glfw.initialized = GLFW_TRUE;
|
|
||||||
_glfw.timer.offset = _glfwPlatformGetTimerValue();
|
|
||||||
|
|
||||||
glfwDefaultWindowHints();
|
|
||||||
glfwUpdateGamepadMappings(_glfwDefaultMappings);
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI void glfwTerminate(void)
|
|
||||||
{
|
|
||||||
if (!_glfw.initialized)
|
|
||||||
return;
|
|
||||||
|
|
||||||
terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI void glfwInitHint(int hint, int value)
|
|
||||||
{
|
|
||||||
switch (hint)
|
|
||||||
{
|
|
||||||
case GLFW_JOYSTICK_HAT_BUTTONS:
|
|
||||||
_glfwInitHints.hatButtons = value;
|
|
||||||
return;
|
|
||||||
case GLFW_COCOA_CHDIR_RESOURCES:
|
|
||||||
_glfwInitHints.ns.chdir = value;
|
|
||||||
return;
|
|
||||||
case GLFW_COCOA_MENUBAR:
|
|
||||||
_glfwInitHints.ns.menubar = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
|
||||||
"Invalid integer type init hint 0x%08X", hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI void glfwInitHintString(int hint, const char* value)
|
|
||||||
{
|
|
||||||
assert(value != NULL);
|
|
||||||
|
|
||||||
switch (hint)
|
|
||||||
{
|
|
||||||
case GLFW_X11_WM_CLASS_NAME:
|
|
||||||
strncpy(_glfwInitHints.x11.className, value,
|
|
||||||
sizeof(_glfwInitHints.x11.className) - 1);
|
|
||||||
break;
|
|
||||||
case GLFW_X11_WM_CLASS_CLASS:
|
|
||||||
strncpy(_glfwInitHints.x11.classClass, value,
|
|
||||||
sizeof(_glfwInitHints.x11.classClass) - 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
|
||||||
"Invalid string type init hint 0x%08X", hint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
|
||||||
{
|
{
|
||||||
if (major != NULL)
|
if (major != NULL)
|
||||||
*major = GLFW_VERSION_MAJOR;
|
*major = GLFW_VERSION_MAJOR;
|
||||||
|
|
||||||
if (minor != NULL)
|
if (minor != NULL)
|
||||||
*minor = GLFW_VERSION_MINOR;
|
*minor = GLFW_VERSION_MINOR;
|
||||||
|
|
||||||
if (rev != NULL)
|
if (rev != NULL)
|
||||||
*rev = GLFW_VERSION_REVISION;
|
*rev = GLFW_VERSION_REVISION;
|
||||||
}
|
}
|
||||||
@@ -287,30 +192,6 @@ GLFWAPI const char* glfwGetVersionString(void)
|
|||||||
return _glfwPlatformGetVersionString();
|
return _glfwPlatformGetVersionString();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI int glfwGetError(const char** description)
|
|
||||||
{
|
|
||||||
_GLFWerror* error;
|
|
||||||
int code = GLFW_NO_ERROR;
|
|
||||||
|
|
||||||
if (description)
|
|
||||||
*description = NULL;
|
|
||||||
|
|
||||||
if (_glfw.initialized)
|
|
||||||
error = _glfwPlatformGetTls(&_glfw.errorSlot);
|
|
||||||
else
|
|
||||||
error = &_glfwMainThreadError;
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
{
|
|
||||||
code = error->code;
|
|
||||||
error->code = GLFW_NO_ERROR;
|
|
||||||
if (description && code)
|
|
||||||
*description = error->description;
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
|
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
|
||||||
{
|
{
|
||||||
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
|
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
|
||||||
|
|||||||
+87
-566
@@ -29,144 +29,11 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
// Internal key state used for sticky keys
|
// Internal key state used for sticky keys
|
||||||
#define _GLFW_STICK 3
|
#define _GLFW_STICK 3
|
||||||
|
|
||||||
// Internal constants for gamepad mapping source types
|
|
||||||
#define _GLFW_JOYSTICK_AXIS 1
|
|
||||||
#define _GLFW_JOYSTICK_BUTTON 2
|
|
||||||
#define _GLFW_JOYSTICK_HATBIT 3
|
|
||||||
|
|
||||||
// Finds a mapping based on joystick GUID
|
|
||||||
//
|
|
||||||
static _GLFWmapping* findMapping(const char* guid)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < _glfw.mappingCount; i++)
|
|
||||||
{
|
|
||||||
if (strcmp(_glfw.mappings[i].guid, guid) == 0)
|
|
||||||
return _glfw.mappings + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parses an SDL_GameControllerDB line and adds it to the mapping list
|
|
||||||
//
|
|
||||||
static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
|
||||||
{
|
|
||||||
const char* c = string;
|
|
||||||
size_t i, length;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
const char* name;
|
|
||||||
_GLFWmapelement* element;
|
|
||||||
} fields[] =
|
|
||||||
{
|
|
||||||
{ "platform", NULL },
|
|
||||||
{ "a", mapping->buttons + GLFW_GAMEPAD_BUTTON_A },
|
|
||||||
{ "b", mapping->buttons + GLFW_GAMEPAD_BUTTON_B },
|
|
||||||
{ "x", mapping->buttons + GLFW_GAMEPAD_BUTTON_X },
|
|
||||||
{ "y", mapping->buttons + GLFW_GAMEPAD_BUTTON_Y },
|
|
||||||
{ "back", mapping->buttons + GLFW_GAMEPAD_BUTTON_BACK },
|
|
||||||
{ "start", mapping->buttons + GLFW_GAMEPAD_BUTTON_START },
|
|
||||||
{ "guide", mapping->buttons + GLFW_GAMEPAD_BUTTON_GUIDE },
|
|
||||||
{ "leftshoulder", mapping->buttons + GLFW_GAMEPAD_BUTTON_LEFT_BUMPER },
|
|
||||||
{ "rightshoulder", mapping->buttons + GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER },
|
|
||||||
{ "leftstick", mapping->buttons + GLFW_GAMEPAD_BUTTON_LEFT_THUMB },
|
|
||||||
{ "rightstick", mapping->buttons + GLFW_GAMEPAD_BUTTON_RIGHT_THUMB },
|
|
||||||
{ "dpup", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_UP },
|
|
||||||
{ "dpright", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_RIGHT },
|
|
||||||
{ "dpdown", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_DOWN },
|
|
||||||
{ "dpleft", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_LEFT },
|
|
||||||
{ "lefttrigger", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_TRIGGER },
|
|
||||||
{ "righttrigger", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER },
|
|
||||||
{ "leftx", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_X },
|
|
||||||
{ "lefty", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_Y },
|
|
||||||
{ "rightx", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_X },
|
|
||||||
{ "righty", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_Y }
|
|
||||||
};
|
|
||||||
|
|
||||||
length = strcspn(c, ",");
|
|
||||||
if (length != 32 || c[length] != ',')
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(mapping->guid, c, length);
|
|
||||||
c += length + 1;
|
|
||||||
|
|
||||||
length = strcspn(c, ",");
|
|
||||||
if (length >= sizeof(mapping->name) || c[length] != ',')
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(mapping->name, c, length);
|
|
||||||
c += length + 1;
|
|
||||||
|
|
||||||
while (*c)
|
|
||||||
{
|
|
||||||
for (i = 0; i < sizeof(fields) / sizeof(fields[0]); i++)
|
|
||||||
{
|
|
||||||
length = strlen(fields[i].name);
|
|
||||||
if (strncmp(c, fields[i].name, length) != 0 || c[length] != ':')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
c += length + 1;
|
|
||||||
|
|
||||||
if (fields[i].element)
|
|
||||||
{
|
|
||||||
if (*c == 'a')
|
|
||||||
fields[i].element->type = _GLFW_JOYSTICK_AXIS;
|
|
||||||
else if (*c == 'b')
|
|
||||||
fields[i].element->type = _GLFW_JOYSTICK_BUTTON;
|
|
||||||
else if (*c == 'h')
|
|
||||||
fields[i].element->type = _GLFW_JOYSTICK_HATBIT;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (fields[i].element->type == _GLFW_JOYSTICK_HATBIT)
|
|
||||||
{
|
|
||||||
const unsigned int hat = strtoul(c + 1, (char**) &c, 10);
|
|
||||||
const unsigned int bit = strtoul(c + 1, (char**) &c, 10);
|
|
||||||
fields[i].element->value = (hat << 4) | bit;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
fields[i].element->value = (uint8_t) strtoul(c + 1, (char**) &c, 10);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = strlen(_GLFW_PLATFORM_MAPPING_NAME);
|
|
||||||
if (strncmp(c, _GLFW_PLATFORM_MAPPING_NAME, length) != 0)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
c += strcspn(c, ",");
|
|
||||||
c += strspn(c, ",");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 32; i++)
|
|
||||||
{
|
|
||||||
if (mapping->guid[i] >= 'A' && mapping->guid[i] <= 'F')
|
|
||||||
mapping->guid[i] += 'a' - 'A';
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwPlatformUpdateGamepadGUID(mapping->guid);
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW event API //////
|
////// GLFW event API //////
|
||||||
@@ -223,6 +90,7 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
|
|||||||
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
|
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Register mouse button action
|
||||||
if (action == GLFW_RELEASE && window->stickyMouseButtons)
|
if (action == GLFW_RELEASE && window->stickyMouseButtons)
|
||||||
window->mouseButtons[button] = _GLFW_STICK;
|
window->mouseButtons[button] = _GLFW_STICK;
|
||||||
else
|
else
|
||||||
@@ -256,82 +124,22 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
|
|||||||
window->callbacks.drop((GLFWwindow*) window, count, paths);
|
window->callbacks.drop((GLFWwindow*) window, count, paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwInputJoystick(_GLFWjoystick* js, int event)
|
void _glfwInputJoystickChange(int jid, int event)
|
||||||
{
|
{
|
||||||
const int jid = (int) (js - _glfw.joysticks);
|
|
||||||
|
|
||||||
if (_glfw.callbacks.joystick)
|
if (_glfw.callbacks.joystick)
|
||||||
_glfw.callbacks.joystick(jid, event);
|
_glfw.callbacks.joystick(jid, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
|
|
||||||
{
|
|
||||||
js->axes[axis] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value)
|
|
||||||
{
|
|
||||||
js->buttons[button] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
|
|
||||||
{
|
|
||||||
const int base = js->buttonCount + hat * 4;
|
|
||||||
|
|
||||||
js->buttons[base + 0] = (value & 0x01) ? GLFW_PRESS : GLFW_RELEASE;
|
|
||||||
js->buttons[base + 1] = (value & 0x02) ? GLFW_PRESS : GLFW_RELEASE;
|
|
||||||
js->buttons[base + 2] = (value & 0x04) ? GLFW_PRESS : GLFW_RELEASE;
|
|
||||||
js->buttons[base + 3] = (value & 0x08) ? GLFW_PRESS : GLFW_RELEASE;
|
|
||||||
|
|
||||||
js->hats[hat] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
_GLFWjoystick* _glfwAllocJoystick(const char* name,
|
GLFWbool _glfwIsPrintable(int key)
|
||||||
const char* guid,
|
|
||||||
int axisCount,
|
|
||||||
int buttonCount,
|
|
||||||
int hatCount)
|
|
||||||
{
|
{
|
||||||
int jid;
|
return (key >= GLFW_KEY_APOSTROPHE && key <= GLFW_KEY_WORLD_2) ||
|
||||||
_GLFWjoystick* js;
|
(key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD) ||
|
||||||
|
key == GLFW_KEY_KP_EQUAL;
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
{
|
|
||||||
if (!_glfw.joysticks[jid].present)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jid > GLFW_JOYSTICK_LAST)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
|
||||||
js->present = GLFW_TRUE;
|
|
||||||
js->name = strdup(name);
|
|
||||||
js->axes = calloc(axisCount, sizeof(float));
|
|
||||||
js->buttons = calloc(buttonCount + hatCount * 4, 1);
|
|
||||||
js->hats = calloc(hatCount, 1);
|
|
||||||
js->axisCount = axisCount;
|
|
||||||
js->buttonCount = buttonCount;
|
|
||||||
js->hatCount = hatCount;
|
|
||||||
js->mapping = findMapping(guid);
|
|
||||||
|
|
||||||
strcpy(js->guid, guid);
|
|
||||||
|
|
||||||
return js;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwFreeJoystick(_GLFWjoystick* js)
|
|
||||||
{
|
|
||||||
free(js->name);
|
|
||||||
free(js->axes);
|
|
||||||
free(js->buttons);
|
|
||||||
free(js->hats);
|
|
||||||
memset(js, 0, sizeof(_GLFWjoystick));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -354,10 +162,10 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
|
|||||||
return window->stickyKeys;
|
return window->stickyKeys;
|
||||||
case GLFW_STICKY_MOUSE_BUTTONS:
|
case GLFW_STICKY_MOUSE_BUTTONS:
|
||||||
return window->stickyMouseButtons;
|
return window->stickyMouseButtons;
|
||||||
|
default:
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode %i", mode);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||||
@@ -367,91 +175,85 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
|||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
if (mode == GLFW_CURSOR)
|
switch (mode)
|
||||||
{
|
{
|
||||||
if (value != GLFW_CURSOR_NORMAL &&
|
case GLFW_CURSOR:
|
||||||
value != GLFW_CURSOR_HIDDEN &&
|
|
||||||
value != GLFW_CURSOR_DISABLED)
|
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM,
|
if (value != GLFW_CURSOR_NORMAL &&
|
||||||
"Invalid cursor mode 0x%08X",
|
value != GLFW_CURSOR_HIDDEN &&
|
||||||
value);
|
value != GLFW_CURSOR_DISABLED)
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->cursorMode == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
window->cursorMode = value;
|
|
||||||
|
|
||||||
_glfwPlatformGetCursorPos(window,
|
|
||||||
&window->virtualCursorPosX,
|
|
||||||
&window->virtualCursorPosY);
|
|
||||||
|
|
||||||
if (_glfwPlatformWindowFocused(window))
|
|
||||||
_glfwPlatformSetCursorMode(window, value);
|
|
||||||
}
|
|
||||||
else if (mode == GLFW_STICKY_KEYS)
|
|
||||||
{
|
|
||||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
|
||||||
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)
|
_glfwInputError(GLFW_INVALID_ENUM,
|
||||||
window->keys[i] = GLFW_RELEASE;
|
"Invalid cursor mode %i",
|
||||||
|
value);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
|
if (window->cursorMode == value)
|
||||||
}
|
return;
|
||||||
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
|
|
||||||
{
|
window->cursorMode = value;
|
||||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
|
||||||
if (window->stickyMouseButtons == value)
|
_glfwPlatformGetCursorPos(window,
|
||||||
|
&window->virtualCursorPosX,
|
||||||
|
&window->virtualCursorPosY);
|
||||||
|
|
||||||
|
if (_glfwPlatformWindowFocused(window))
|
||||||
|
_glfwPlatformSetCursorMode(window, value);
|
||||||
|
|
||||||
return;
|
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;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
_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)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
return _glfwPlatformGetKeyName(key, scancode);
|
||||||
if (key != GLFW_KEY_UNKNOWN)
|
|
||||||
{
|
|
||||||
if (key != GLFW_KEY_KP_EQUAL &&
|
|
||||||
(key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) &&
|
|
||||||
(key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_WORLD_2))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
scancode = _glfwPlatformGetKeyScancode(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _glfwPlatformGetScancodeName(scancode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI int glfwGetKeyScancode(int key)
|
GLFWAPI int glfwGetKeyScancode(int key)
|
||||||
@@ -602,7 +404,7 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
|
|||||||
shape != GLFW_HRESIZE_CURSOR &&
|
shape != GLFW_HRESIZE_CURSOR &&
|
||||||
shape != GLFW_VRESIZE_CURSOR)
|
shape != GLFW_VRESIZE_CURSOR)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor %i", shape);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -753,165 +555,60 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
|
|||||||
|
|
||||||
GLFWAPI int glfwJoystickPresent(int jid)
|
GLFWAPI int glfwJoystickPresent(int jid)
|
||||||
{
|
{
|
||||||
_GLFWjoystick* js;
|
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||||
|
|
||||||
assert(jid >= GLFW_JOYSTICK_1);
|
|
||||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
|
||||||
|
|
||||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", jid);
|
||||||
return GLFW_FALSE;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
return _glfwPlatformJoystickPresent(jid);
|
||||||
if (!js->present)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
|
GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
|
||||||
{
|
{
|
||||||
_GLFWjoystick* js;
|
|
||||||
|
|
||||||
assert(jid >= GLFW_JOYSTICK_1);
|
|
||||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
|
||||||
assert(count != NULL);
|
assert(count != NULL);
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", jid);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
return _glfwPlatformGetJoystickAxes(jid, count);
|
||||||
if (!js->present)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
*count = js->axisCount;
|
|
||||||
return js->axes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count)
|
GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count)
|
||||||
{
|
{
|
||||||
_GLFWjoystick* js;
|
|
||||||
|
|
||||||
assert(jid >= GLFW_JOYSTICK_1);
|
|
||||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
|
||||||
assert(count != NULL);
|
assert(count != NULL);
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", jid);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
return _glfwPlatformGetJoystickButtons(jid, count);
|
||||||
if (!js->present)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (_glfw.hints.init.hatButtons)
|
|
||||||
*count = js->buttonCount + js->hatCount * 4;
|
|
||||||
else
|
|
||||||
*count = js->buttonCount;
|
|
||||||
|
|
||||||
return js->buttons;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count)
|
|
||||||
{
|
|
||||||
_GLFWjoystick* js;
|
|
||||||
|
|
||||||
assert(jid >= GLFW_JOYSTICK_1);
|
|
||||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
|
||||||
assert(count != NULL);
|
|
||||||
|
|
||||||
*count = 0;
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
|
|
||||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
|
||||||
if (!js->present)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
*count = js->hatCount;
|
|
||||||
return js->hats;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI const char* glfwGetJoystickName(int jid)
|
GLFWAPI const char* glfwGetJoystickName(int jid)
|
||||||
{
|
{
|
||||||
_GLFWjoystick* js;
|
|
||||||
|
|
||||||
assert(jid >= GLFW_JOYSTICK_1);
|
|
||||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", jid);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
return _glfwPlatformGetJoystickName(jid);
|
||||||
if (!js->present)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return js->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI const char* glfwGetJoystickGUID(int jid)
|
|
||||||
{
|
|
||||||
_GLFWjoystick* js;
|
|
||||||
|
|
||||||
assert(jid >= GLFW_JOYSTICK_1);
|
|
||||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
|
|
||||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
|
||||||
if (!js->present)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return js->guid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
|
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
|
||||||
@@ -921,182 +618,6 @@ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
|
|||||||
return cbfun;
|
return cbfun;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI int glfwUpdateGamepadMappings(const char* string)
|
|
||||||
{
|
|
||||||
int jid;
|
|
||||||
const char* c = string;
|
|
||||||
|
|
||||||
assert(string != NULL);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
|
||||||
|
|
||||||
while (*c)
|
|
||||||
{
|
|
||||||
if (isxdigit(*c))
|
|
||||||
{
|
|
||||||
char line[1024];
|
|
||||||
|
|
||||||
const size_t length = strcspn(c, "\r\n");
|
|
||||||
if (length < sizeof(line))
|
|
||||||
{
|
|
||||||
_GLFWmapping mapping = {{0}};
|
|
||||||
|
|
||||||
memcpy(line, c, length);
|
|
||||||
line[length] = '\0';
|
|
||||||
|
|
||||||
if (parseMapping(&mapping, line))
|
|
||||||
{
|
|
||||||
_GLFWmapping* previous = findMapping(mapping.guid);
|
|
||||||
if (previous)
|
|
||||||
*previous = mapping;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_glfw.mappingCount++;
|
|
||||||
_glfw.mappings =
|
|
||||||
realloc(_glfw.mappings,
|
|
||||||
sizeof(_GLFWmapping) * _glfw.mappingCount);
|
|
||||||
_glfw.mappings[_glfw.mappingCount - 1] = mapping;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c += length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
c += strcspn(c, "\r\n");
|
|
||||||
c += strspn(c, "\r\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
{
|
|
||||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
|
||||||
if (js->present)
|
|
||||||
js->mapping = findMapping(js->guid);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI int glfwJoystickIsGamepad(int jid)
|
|
||||||
{
|
|
||||||
_GLFWjoystick* js;
|
|
||||||
|
|
||||||
assert(jid >= GLFW_JOYSTICK_1);
|
|
||||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
|
||||||
|
|
||||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
|
||||||
if (!js->present)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
return js->mapping != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI const char* glfwGetGamepadName(int jid)
|
|
||||||
{
|
|
||||||
_GLFWjoystick* js;
|
|
||||||
|
|
||||||
assert(jid >= GLFW_JOYSTICK_1);
|
|
||||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
|
||||||
|
|
||||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
|
||||||
if (!js->present)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!js->mapping)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return js->mapping->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
_GLFWjoystick* js;
|
|
||||||
|
|
||||||
assert(jid >= GLFW_JOYSTICK_1);
|
|
||||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
|
||||||
assert(state != NULL);
|
|
||||||
|
|
||||||
memset(state, 0, sizeof(GLFWgamepadstate));
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
|
||||||
|
|
||||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
js = _glfw.joysticks + jid;
|
|
||||||
if (!js->present)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
if (!js->mapping)
|
|
||||||
return GLFW_FALSE;
|
|
||||||
|
|
||||||
for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
|
|
||||||
{
|
|
||||||
if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_AXIS)
|
|
||||||
{
|
|
||||||
if (fabs(js->axes[js->mapping->buttons[i].value]) > 0.5)
|
|
||||||
state->buttons[i] = GLFW_PRESS;
|
|
||||||
}
|
|
||||||
else if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_HATBIT)
|
|
||||||
{
|
|
||||||
const unsigned int hat = js->mapping->buttons[i].value >> 4;
|
|
||||||
const unsigned int bit = js->mapping->buttons[i].value & 0xf;
|
|
||||||
if (js->hats[hat] & bit)
|
|
||||||
state->buttons[i] = GLFW_PRESS;
|
|
||||||
}
|
|
||||||
else if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_BUTTON)
|
|
||||||
state->buttons[i] = js->buttons[js->mapping->buttons[i].value];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++)
|
|
||||||
{
|
|
||||||
if (js->mapping->axes[i].type == _GLFW_JOYSTICK_AXIS)
|
|
||||||
state->axes[i] = js->axes[js->mapping->axes[i].value];
|
|
||||||
else if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_HATBIT)
|
|
||||||
{
|
|
||||||
const unsigned int hat = js->mapping->buttons[i].value >> 4;
|
|
||||||
const unsigned int bit = js->mapping->buttons[i].value & 0xf;
|
|
||||||
if (js->hats[hat] & bit)
|
|
||||||
state->axes[i] = 1.f;
|
|
||||||
}
|
|
||||||
else if (js->mapping->buttons[i].type == _GLFW_JOYSTICK_BUTTON)
|
|
||||||
state->axes[i] = (float) js->buttons[js->mapping->axes[i].value];
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
@@ -1119,7 +640,7 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
|
|||||||
GLFWAPI double glfwGetTime(void)
|
GLFWAPI double glfwGetTime(void)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(0.0);
|
_GLFW_REQUIRE_INIT_OR_RETURN(0.0);
|
||||||
return (double) (_glfwPlatformGetTimerValue() - _glfw.timer.offset) /
|
return (double) (_glfwPlatformGetTimerValue() - _glfw.timerOffset) /
|
||||||
_glfwPlatformGetTimerFrequency();
|
_glfwPlatformGetTimerFrequency();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1133,7 +654,7 @@ GLFWAPI void glfwSetTime(double time)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.timer.offset = _glfwPlatformGetTimerValue() -
|
_glfw.timerOffset = _glfwPlatformGetTimerValue() -
|
||||||
(uint64_t) (time * _glfwPlatformGetTimerFrequency());
|
(uint64_t) (time * _glfwPlatformGetTimerFrequency());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+308
-223
@@ -25,6 +25,10 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_internal_h_
|
||||||
|
#define _glfw3_internal_h_
|
||||||
|
|
||||||
|
|
||||||
#if defined(_GLFW_USE_CONFIG_H)
|
#if defined(_GLFW_USE_CONFIG_H)
|
||||||
#include "glfw_config.h"
|
#include "glfw_config.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -33,8 +37,6 @@
|
|||||||
defined(GLFW_INCLUDE_ES1) || \
|
defined(GLFW_INCLUDE_ES1) || \
|
||||||
defined(GLFW_INCLUDE_ES2) || \
|
defined(GLFW_INCLUDE_ES2) || \
|
||||||
defined(GLFW_INCLUDE_ES3) || \
|
defined(GLFW_INCLUDE_ES3) || \
|
||||||
defined(GLFW_INCLUDE_ES31) || \
|
|
||||||
defined(GLFW_INCLUDE_ES32) || \
|
|
||||||
defined(GLFW_INCLUDE_NONE) || \
|
defined(GLFW_INCLUDE_NONE) || \
|
||||||
defined(GLFW_INCLUDE_GLEXT) || \
|
defined(GLFW_INCLUDE_GLEXT) || \
|
||||||
defined(GLFW_INCLUDE_GLU) || \
|
defined(GLFW_INCLUDE_GLU) || \
|
||||||
@@ -46,20 +48,8 @@
|
|||||||
#define GLFW_INCLUDE_NONE
|
#define GLFW_INCLUDE_NONE
|
||||||
#include "../include/GLFW/glfw3.h"
|
#include "../include/GLFW/glfw3.h"
|
||||||
|
|
||||||
#define _GLFW_INSERT_FIRST 0
|
|
||||||
#define _GLFW_INSERT_LAST 1
|
|
||||||
|
|
||||||
#define _GLFW_POLL_PRESENCE 0
|
|
||||||
#define _GLFW_POLL_AXES 1
|
|
||||||
#define _GLFW_POLL_BUTTONS 2
|
|
||||||
#define _GLFW_POLL_ALL (_GLFW_POLL_AXES | _GLFW_POLL_BUTTONS)
|
|
||||||
|
|
||||||
#define _GLFW_MESSAGE_SIZE 1024
|
|
||||||
|
|
||||||
typedef int GLFWbool;
|
typedef int GLFWbool;
|
||||||
|
|
||||||
typedef struct _GLFWerror _GLFWerror;
|
|
||||||
typedef struct _GLFWinitconfig _GLFWinitconfig;
|
|
||||||
typedef struct _GLFWwndconfig _GLFWwndconfig;
|
typedef struct _GLFWwndconfig _GLFWwndconfig;
|
||||||
typedef struct _GLFWctxconfig _GLFWctxconfig;
|
typedef struct _GLFWctxconfig _GLFWctxconfig;
|
||||||
typedef struct _GLFWfbconfig _GLFWfbconfig;
|
typedef struct _GLFWfbconfig _GLFWfbconfig;
|
||||||
@@ -68,11 +58,6 @@ typedef struct _GLFWwindow _GLFWwindow;
|
|||||||
typedef struct _GLFWlibrary _GLFWlibrary;
|
typedef struct _GLFWlibrary _GLFWlibrary;
|
||||||
typedef struct _GLFWmonitor _GLFWmonitor;
|
typedef struct _GLFWmonitor _GLFWmonitor;
|
||||||
typedef struct _GLFWcursor _GLFWcursor;
|
typedef struct _GLFWcursor _GLFWcursor;
|
||||||
typedef struct _GLFWmapelement _GLFWmapelement;
|
|
||||||
typedef struct _GLFWmapping _GLFWmapping;
|
|
||||||
typedef struct _GLFWjoystick _GLFWjoystick;
|
|
||||||
typedef struct _GLFWtls _GLFWtls;
|
|
||||||
typedef struct _GLFWmutex _GLFWmutex;
|
|
||||||
|
|
||||||
typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*);
|
typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*);
|
||||||
typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*);
|
typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*);
|
||||||
@@ -189,9 +174,7 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
|||||||
#elif defined(_GLFW_MIR)
|
#elif defined(_GLFW_MIR)
|
||||||
#include "mir_platform.h"
|
#include "mir_platform.h"
|
||||||
#elif defined(_GLFW_OSMESA)
|
#elif defined(_GLFW_OSMESA)
|
||||||
#include "null_platform.h"
|
#include "osmesa_platform.h"
|
||||||
#elif defined(_GLFW_EGLDEVICE)
|
|
||||||
#include "egldevice_platform.h"
|
|
||||||
#else
|
#else
|
||||||
#error "No supported window creation API selected"
|
#error "No supported window creation API selected"
|
||||||
#endif
|
#endif
|
||||||
@@ -237,13 +220,13 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
|||||||
|
|
||||||
// Checks for whether the library has been initialized
|
// Checks for whether the library has been initialized
|
||||||
#define _GLFW_REQUIRE_INIT() \
|
#define _GLFW_REQUIRE_INIT() \
|
||||||
if (!_glfw.initialized) \
|
if (!_glfwInitialized) \
|
||||||
{ \
|
{ \
|
||||||
_glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
|
_glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
#define _GLFW_REQUIRE_INIT_OR_RETURN(x) \
|
#define _GLFW_REQUIRE_INIT_OR_RETURN(x) \
|
||||||
if (!_glfw.initialized) \
|
if (!_glfwInitialized) \
|
||||||
{ \
|
{ \
|
||||||
_glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
|
_glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
|
||||||
return x; \
|
return x; \
|
||||||
@@ -263,30 +246,6 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
|||||||
// Platform-independent structures
|
// Platform-independent structures
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
struct _GLFWerror
|
|
||||||
{
|
|
||||||
_GLFWerror* next;
|
|
||||||
int code;
|
|
||||||
char description[_GLFW_MESSAGE_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief Initialization configuration.
|
|
||||||
*
|
|
||||||
* Parameters relating to the initialization of the library.
|
|
||||||
*/
|
|
||||||
struct _GLFWinitconfig
|
|
||||||
{
|
|
||||||
GLFWbool hatButtons;
|
|
||||||
struct {
|
|
||||||
GLFWbool menubar;
|
|
||||||
GLFWbool chdir;
|
|
||||||
} ns;
|
|
||||||
struct {
|
|
||||||
char className[256];
|
|
||||||
char classClass[256];
|
|
||||||
} x11;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief Window configuration.
|
/*! @brief Window configuration.
|
||||||
*
|
*
|
||||||
* Parameters relating to the creation of the window but not directly related
|
* Parameters relating to the creation of the window but not directly related
|
||||||
@@ -305,10 +264,8 @@ struct _GLFWwndconfig
|
|||||||
GLFWbool autoIconify;
|
GLFWbool autoIconify;
|
||||||
GLFWbool floating;
|
GLFWbool floating;
|
||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
GLFWbool centerCursor;
|
|
||||||
struct {
|
struct {
|
||||||
GLFWbool retina;
|
GLFWbool retina;
|
||||||
GLFWbool frame;
|
|
||||||
} ns;
|
} ns;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -331,9 +288,6 @@ struct _GLFWctxconfig
|
|||||||
int robustness;
|
int robustness;
|
||||||
int release;
|
int release;
|
||||||
_GLFWwindow* share;
|
_GLFWwindow* share;
|
||||||
struct {
|
|
||||||
GLFWbool offline;
|
|
||||||
} nsgl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! @brief Framebuffer configuration.
|
/*! @brief Framebuffer configuration.
|
||||||
@@ -391,8 +345,6 @@ struct _GLFWcontext
|
|||||||
_GLFW_PLATFORM_CONTEXT_STATE;
|
_GLFW_PLATFORM_CONTEXT_STATE;
|
||||||
// This is defined in egl_context.h
|
// This is defined in egl_context.h
|
||||||
_GLFW_EGL_CONTEXT_STATE;
|
_GLFW_EGL_CONTEXT_STATE;
|
||||||
// This is defined in osmesa_context.h
|
|
||||||
_GLFW_OSMESA_CONTEXT_STATE;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! @brief Window and context structure.
|
/*! @brief Window and context structure.
|
||||||
@@ -482,93 +434,25 @@ struct _GLFWcursor
|
|||||||
_GLFW_PLATFORM_CURSOR_STATE;
|
_GLFW_PLATFORM_CURSOR_STATE;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! @brief Gamepad mapping element structure
|
|
||||||
*/
|
|
||||||
struct _GLFWmapelement
|
|
||||||
{
|
|
||||||
uint8_t type;
|
|
||||||
uint8_t value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief Gamepad mapping structure
|
|
||||||
*/
|
|
||||||
struct _GLFWmapping
|
|
||||||
{
|
|
||||||
char name[128];
|
|
||||||
char guid[33];
|
|
||||||
_GLFWmapelement buttons[15];
|
|
||||||
_GLFWmapelement axes[6];
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief Joystick structure
|
|
||||||
*/
|
|
||||||
struct _GLFWjoystick
|
|
||||||
{
|
|
||||||
GLFWbool present;
|
|
||||||
float* axes;
|
|
||||||
int axisCount;
|
|
||||||
unsigned char* buttons;
|
|
||||||
int buttonCount;
|
|
||||||
unsigned char* hats;
|
|
||||||
int hatCount;
|
|
||||||
char* name;
|
|
||||||
char guid[33];
|
|
||||||
_GLFWmapping* mapping;
|
|
||||||
|
|
||||||
// This is defined in the joystick API's joystick.h
|
|
||||||
_GLFW_PLATFORM_JOYSTICK_STATE;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief Thread local storage structure.
|
|
||||||
*/
|
|
||||||
struct _GLFWtls
|
|
||||||
{
|
|
||||||
// This is defined in the platform's thread.h
|
|
||||||
_GLFW_PLATFORM_TLS_STATE;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief Mutex structure.
|
|
||||||
*/
|
|
||||||
struct _GLFWmutex
|
|
||||||
{
|
|
||||||
// This is defined in the platform's thread.h
|
|
||||||
_GLFW_PLATFORM_MUTEX_STATE;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! @brief Library global data.
|
/*! @brief Library global data.
|
||||||
*/
|
*/
|
||||||
struct _GLFWlibrary
|
struct _GLFWlibrary
|
||||||
{
|
{
|
||||||
GLFWbool initialized;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
_GLFWinitconfig init;
|
|
||||||
_GLFWfbconfig framebuffer;
|
_GLFWfbconfig framebuffer;
|
||||||
_GLFWwndconfig window;
|
_GLFWwndconfig window;
|
||||||
_GLFWctxconfig context;
|
_GLFWctxconfig context;
|
||||||
int refreshRate;
|
int refreshRate;
|
||||||
} hints;
|
} hints;
|
||||||
|
|
||||||
_GLFWerror* errorListHead;
|
|
||||||
_GLFWcursor* cursorListHead;
|
_GLFWcursor* cursorListHead;
|
||||||
|
|
||||||
_GLFWwindow* windowListHead;
|
_GLFWwindow* windowListHead;
|
||||||
|
|
||||||
_GLFWmonitor** monitors;
|
_GLFWmonitor** monitors;
|
||||||
int monitorCount;
|
int monitorCount;
|
||||||
|
|
||||||
_GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1];
|
uint64_t timerOffset;
|
||||||
_GLFWmapping* mappings;
|
|
||||||
int mappingCount;
|
|
||||||
|
|
||||||
_GLFWtls errorSlot;
|
|
||||||
_GLFWtls contextSlot;
|
|
||||||
_GLFWmutex errorLock;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint64_t offset;
|
|
||||||
// This is defined in the platform's time.h
|
|
||||||
_GLFW_PLATFORM_LIBRARY_TIMER_STATE;
|
|
||||||
} timer;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
GLFWbool available;
|
GLFWbool available;
|
||||||
@@ -602,12 +486,14 @@ struct _GLFWlibrary
|
|||||||
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
|
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
|
||||||
// This is defined in the context API's context.h
|
// This is defined in the context API's context.h
|
||||||
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE;
|
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE;
|
||||||
|
// This is defined in the platform's time.h
|
||||||
|
_GLFW_PLATFORM_LIBRARY_TIME_STATE;
|
||||||
// This is defined in the platform's joystick.h
|
// This is defined in the platform's joystick.h
|
||||||
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
|
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
|
||||||
|
// This is defined in the platform's tls.h
|
||||||
|
_GLFW_PLATFORM_LIBRARY_TLS_STATE;
|
||||||
// This is defined in egl_context.h
|
// This is defined in egl_context.h
|
||||||
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
|
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
|
||||||
// This is defined in osmesa_context.h
|
|
||||||
_GLFW_OSMESA_LIBRARY_CONTEXT_STATE;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -615,7 +501,13 @@ struct _GLFWlibrary
|
|||||||
// Global state shared between compilation units of GLFW
|
// Global state shared between compilation units of GLFW
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
/*! @brief All global data shared between compilation units.
|
/*! @brief Flag indicating whether GLFW has been successfully initialized.
|
||||||
|
*/
|
||||||
|
extern GLFWbool _glfwInitialized;
|
||||||
|
|
||||||
|
/*! @brief All global data protected by @ref _glfwInitialized.
|
||||||
|
* This should only be touched after a call to @ref glfwInit that has not been
|
||||||
|
* followed by a call to @ref glfwTerminate.
|
||||||
*/
|
*/
|
||||||
extern _GLFWlibrary _glfw;
|
extern _GLFWlibrary _glfw;
|
||||||
|
|
||||||
@@ -624,96 +516,332 @@ extern _GLFWlibrary _glfw;
|
|||||||
// Platform API functions
|
// Platform API functions
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
/*! @addtogroup platform @{ */
|
/*! @brief Initializes the platform-specific part of the library.
|
||||||
|
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an error occurred.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
int _glfwPlatformInit(void);
|
int _glfwPlatformInit(void);
|
||||||
|
|
||||||
|
/*! @brief Terminates the platform-specific part of the library.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformTerminate(void);
|
void _glfwPlatformTerminate(void);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetVersionString
|
||||||
|
* @ingroup platform
|
||||||
|
*
|
||||||
|
* @note The returned string must be available for the duration of the program.
|
||||||
|
*
|
||||||
|
* @note The returned string must not change for the duration of the program.
|
||||||
|
*/
|
||||||
const char* _glfwPlatformGetVersionString(void);
|
const char* _glfwPlatformGetVersionString(void);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetCursorPos
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos);
|
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos);
|
||||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
|
||||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
|
|
||||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
|
|
||||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
|
|
||||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
|
|
||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode);
|
/*! @copydoc glfwSetCursorPos
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||||
|
|
||||||
|
/*! @brief Sets the specified cursor mode of the specified window.
|
||||||
|
* @param[in] window The window whose cursor mode to set.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetKeyName
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
const char* _glfwPlatformGetKeyName(int key, int scancode);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetKeyScancode
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
int _glfwPlatformGetKeyScancode(int key);
|
int _glfwPlatformGetKeyScancode(int key);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetMonitors
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
_GLFWmonitor** _glfwPlatformGetMonitors(int* count);
|
||||||
|
|
||||||
|
/*! @brief Checks whether two monitor objects represent the same monitor.
|
||||||
|
*
|
||||||
|
* @param[in] first The first monitor.
|
||||||
|
* @param[in] second The second monitor.
|
||||||
|
* @return @c GLFW_TRUE if the monitor objects represent the same monitor, or
|
||||||
|
* @c GLFW_FALSE otherwise.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetMonitorPos
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetVideoModes
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
|
||||||
|
|
||||||
|
/*! @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetGammaRamp
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||||
|
|
||||||
|
/*! @copydoc glfwSetGammaRamp
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||||
|
|
||||||
|
/*! @copydoc glfwSetClipboardString
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string);
|
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetClipboardString
|
||||||
|
* @ingroup platform
|
||||||
|
*
|
||||||
|
* @note The returned string must be valid until the next call to @ref
|
||||||
|
* _glfwPlatformGetClipboardString or @ref _glfwPlatformSetClipboardString.
|
||||||
|
*/
|
||||||
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window);
|
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window);
|
||||||
|
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
|
/*! @copydoc glfwJoystickPresent
|
||||||
void _glfwPlatformUpdateGamepadGUID(char* guid);
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
int _glfwPlatformJoystickPresent(int jid);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetJoystickAxes
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
const float* _glfwPlatformGetJoystickAxes(int jid, int* count);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetJoystickButtons
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
const unsigned char* _glfwPlatformGetJoystickButtons(int jid, int* count);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetJoystickName
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
const char* _glfwPlatformGetJoystickName(int jid);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetTimerValue
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
uint64_t _glfwPlatformGetTimerValue(void);
|
uint64_t _glfwPlatformGetTimerValue(void);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetTimerFrequency
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
uint64_t _glfwPlatformGetTimerFrequency(void);
|
uint64_t _glfwPlatformGetTimerFrequency(void);
|
||||||
|
|
||||||
|
/*! @ingroup platform
|
||||||
|
*/
|
||||||
int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||||
const _GLFWwndconfig* wndconfig,
|
const _GLFWwndconfig* wndconfig,
|
||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
|
||||||
|
/*! @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window);
|
void _glfwPlatformDestroyWindow(_GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @copydoc glfwSetWindowTitle
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
|
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
|
||||||
|
|
||||||
|
/*! @copydoc glfwSetWindowIcon
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count, const GLFWimage* images);
|
void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count, const GLFWimage* images);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetWindowPos
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos);
|
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos);
|
||||||
|
|
||||||
|
/*! @copydoc glfwSetWindowPos
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetWindowSize
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height);
|
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height);
|
||||||
|
|
||||||
|
/*! @copydoc glfwSetWindowSize
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
|
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
|
||||||
|
|
||||||
|
/*! @copydoc glfwSetWindowSizeLimits
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
|
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
|
||||||
|
|
||||||
|
/*! @copydoc glfwSetWindowAspectRatio
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
|
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetFramebufferSize
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
|
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetWindowFrameSize
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
|
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
|
||||||
|
|
||||||
|
/*! @copydoc glfwIconifyWindow
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
|
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @copydoc glfwRestoreWindow
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
|
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @copydoc glfwMaximizeWindow
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
|
void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @copydoc glfwShowWindow
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformShowWindow(_GLFWwindow* window);
|
void _glfwPlatformShowWindow(_GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @copydoc glfwHideWindow
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformHideWindow(_GLFWwindow* window);
|
void _glfwPlatformHideWindow(_GLFWwindow* window);
|
||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window);
|
|
||||||
|
/*! @copydoc glfwFocusWindow
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformFocusWindow(_GLFWwindow* window);
|
void _glfwPlatformFocusWindow(_GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @copydoc glfwSetWindowMonitor
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
|
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
|
||||||
|
|
||||||
|
/*! @brief Returns whether the window is focused.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
int _glfwPlatformWindowFocused(_GLFWwindow* window);
|
int _glfwPlatformWindowFocused(_GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @brief Returns whether the window is iconified.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
int _glfwPlatformWindowIconified(_GLFWwindow* window);
|
int _glfwPlatformWindowIconified(_GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @brief Returns whether the window is visible.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
int _glfwPlatformWindowVisible(_GLFWwindow* window);
|
int _glfwPlatformWindowVisible(_GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @brief Returns whether the window is maximized.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
|
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @brief Sets whether the window is resizable by the user.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
||||||
|
|
||||||
|
/*! @brief Sets whether the window is decorated.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
||||||
|
|
||||||
|
/*! @brief Sets whether the window is floating.
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
||||||
|
|
||||||
|
/*! @copydoc glfwPollEvents
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformPollEvents(void);
|
void _glfwPlatformPollEvents(void);
|
||||||
|
|
||||||
|
/*! @copydoc glfwWaitEvents
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformWaitEvents(void);
|
void _glfwPlatformWaitEvents(void);
|
||||||
|
|
||||||
|
/*! @copydoc glfwWaitEventsTimeout
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformWaitEventsTimeout(double timeout);
|
void _glfwPlatformWaitEventsTimeout(double timeout);
|
||||||
|
|
||||||
|
/*! @copydoc glfwPostEmptyEvent
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformPostEmptyEvent(void);
|
void _glfwPlatformPostEmptyEvent(void);
|
||||||
|
|
||||||
|
/*! @ingroup platform
|
||||||
|
*/
|
||||||
|
void _glfwPlatformSetCurrentContext(_GLFWwindow* context);
|
||||||
|
|
||||||
|
/*! @copydoc glfwGetCurrentContext
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
_GLFWwindow* _glfwPlatformGetCurrentContext(void);
|
||||||
|
|
||||||
|
/*! @copydoc glfwCreateCursor
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
int _glfwPlatformCreateCursor(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
|
||||||
|
|
||||||
|
/*! @copydoc glfwCreateStandardCursor
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
|
||||||
|
|
||||||
|
/*! @copydoc glfwDestroyCursor
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
|
||||||
|
|
||||||
|
/*! @copydoc glfwSetCursor
|
||||||
|
* @ingroup platform
|
||||||
|
*/
|
||||||
|
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
|
||||||
|
|
||||||
|
/*! @ingroup platform
|
||||||
|
*/
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
|
||||||
|
|
||||||
|
/*! @ingroup platform
|
||||||
|
*/
|
||||||
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
|
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
|
||||||
|
|
||||||
|
/*! @ingroup platform
|
||||||
|
*/
|
||||||
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
|
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
|
||||||
|
|
||||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
|
|
||||||
void _glfwPlatformDestroyTls(_GLFWtls* tls);
|
|
||||||
void* _glfwPlatformGetTls(_GLFWtls* tls);
|
|
||||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value);
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex);
|
|
||||||
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex);
|
|
||||||
void _glfwPlatformLockMutex(_GLFWmutex* mutex);
|
|
||||||
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
|
|
||||||
|
|
||||||
/*! @} */
|
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Event API functions
|
// Event API functions
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
/*! @brief Notifies shared code that a window has lost or received input focus.
|
/*! @brief Notifies shared code of a window focus event.
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @param[in] focused `GLFW_TRUE` if the window received focus, or `GLFW_FALSE`
|
* @param[in] focused `GLFW_TRUE` if the window received focus, or `GLFW_FALSE`
|
||||||
* if it lost focus.
|
* if it lost focus.
|
||||||
@@ -721,7 +849,7 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
|
|||||||
*/
|
*/
|
||||||
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
|
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
|
||||||
|
|
||||||
/*! @brief Notifies shared code that a window has moved.
|
/*! @brief Notifies shared code of a window movement event.
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @param[in] xpos The new x-coordinate of the client area of the window.
|
* @param[in] xpos The new x-coordinate of the client area of the window.
|
||||||
* @param[in] ypos The new y-coordinate of the client area of the window.
|
* @param[in] ypos The new y-coordinate of the client area of the window.
|
||||||
@@ -729,7 +857,7 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
|
|||||||
*/
|
*/
|
||||||
void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
||||||
|
|
||||||
/*! @brief Notifies shared code that a window has been resized.
|
/*! @brief Notifies shared code of a window resize event.
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @param[in] width The new width of the client area of the window.
|
* @param[in] width The new width of the client area of the window.
|
||||||
* @param[in] height The new height of the client area of the window.
|
* @param[in] height The new height of the client area of the window.
|
||||||
@@ -737,7 +865,7 @@ void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
|||||||
*/
|
*/
|
||||||
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
|
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
|
||||||
|
|
||||||
/*! @brief Notifies shared code that a window framebuffer has been resized.
|
/*! @brief Notifies shared code of a framebuffer resize event.
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @param[in] width The new width, in pixels, of the framebuffer.
|
* @param[in] width The new width, in pixels, of the framebuffer.
|
||||||
* @param[in] height The new height, in pixels, of the framebuffer.
|
* @param[in] height The new height, in pixels, of the framebuffer.
|
||||||
@@ -745,7 +873,7 @@ void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
|
|||||||
*/
|
*/
|
||||||
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
|
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
|
||||||
|
|
||||||
/*! @brief Notifies shared code that a window has been iconified or restored.
|
/*! @brief Notifies shared code of a window iconification event.
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @param[in] iconified `GLFW_TRUE` if the window was iconified, or
|
* @param[in] iconified `GLFW_TRUE` if the window was iconified, or
|
||||||
* `GLFW_FALSE` if it was restored.
|
* `GLFW_FALSE` if it was restored.
|
||||||
@@ -753,7 +881,7 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
|
|||||||
*/
|
*/
|
||||||
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);
|
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);
|
||||||
|
|
||||||
/*! @brief Notifies shared code that a window has been maximized or restored.
|
/*! @brief Notifies shared code of a window maximization event.
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @param[in] maximized `GLFW_TRUE` if the window was maximized, or
|
* @param[in] maximized `GLFW_TRUE` if the window was maximized, or
|
||||||
* `GLFW_FALSE` if it was restored.
|
* `GLFW_FALSE` if it was restored.
|
||||||
@@ -761,22 +889,17 @@ void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);
|
|||||||
*/
|
*/
|
||||||
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized);
|
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized);
|
||||||
|
|
||||||
/*! @brief Notifies shared code that a window's contents needs updating.
|
/*! @brief Notifies shared code of a window damage event.
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
*/
|
*/
|
||||||
void _glfwInputWindowDamage(_GLFWwindow* window);
|
void _glfwInputWindowDamage(_GLFWwindow* window);
|
||||||
|
|
||||||
/*! @brief Notifies shared code that the user wishes to close a window.
|
/*! @brief Notifies shared code of a window close request event
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @ingroup event
|
* @ingroup event
|
||||||
*/
|
*/
|
||||||
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
|
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
|
||||||
|
|
||||||
/*! @brief Notifies shared code that a window has changed its desired monitor.
|
|
||||||
* @param[in] window The window that received the event.
|
|
||||||
* @param[in] monitor The new desired monitor, or `NULL`.
|
|
||||||
* @ingroup event
|
|
||||||
*/
|
|
||||||
void _glfwInputWindowMonitorChange(_GLFWwindow* window, _GLFWmonitor* monitor);
|
void _glfwInputWindowMonitorChange(_GLFWwindow* window, _GLFWmonitor* monitor);
|
||||||
|
|
||||||
/*! @brief Notifies shared code of a physical key event.
|
/*! @brief Notifies shared code of a physical key event.
|
||||||
@@ -811,7 +934,6 @@ void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset);
|
|||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @param[in] button The button that was pressed or released.
|
* @param[in] button The button that was pressed or released.
|
||||||
* @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE.
|
* @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE.
|
||||||
* @param[in] mods The modifiers pressed when the event was generated.
|
|
||||||
* @ingroup event
|
* @ingroup event
|
||||||
*/
|
*/
|
||||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
||||||
@@ -834,35 +956,27 @@ void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
|||||||
*/
|
*/
|
||||||
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered);
|
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered);
|
||||||
|
|
||||||
/*! @brief Notifies shared code of a monitor connection or disconnection.
|
/*! @ingroup event
|
||||||
* @param[in] monitor The monitor that was connected or disconnected.
|
|
||||||
* @param[in] action One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
|
|
||||||
* @param[in] placement `_GLFW_INSERT_FIRST` or `_GLFW_INSERT_LAST`.
|
|
||||||
* @ingroup event
|
|
||||||
*/
|
*/
|
||||||
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
|
void _glfwInputMonitorChange(void);
|
||||||
|
|
||||||
/*! @brief Notifies shared code that a full screen window has acquired or
|
/*! @ingroup event
|
||||||
* released a monitor.
|
|
||||||
* @param[in] monitor The monitor that was acquired or released.
|
|
||||||
* @param[in] window The window that acquired the monitor, or `NULL`.
|
|
||||||
* @ingroup event
|
|
||||||
*/
|
*/
|
||||||
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
|
void _glfwInputMonitorWindowChange(_GLFWmonitor* monitor, _GLFWwindow* window);
|
||||||
|
|
||||||
/*! @brief Notifies shared code of an error.
|
/*! @brief Notifies shared code of an error.
|
||||||
* @param[in] code The error code most suitable for the error.
|
* @param[in] error The error code most suitable for the error.
|
||||||
* @param[in] format The `printf` style format string of the error
|
* @param[in] format The `printf` style format string of the error
|
||||||
* description.
|
* description.
|
||||||
* @ingroup event
|
* @ingroup event
|
||||||
*/
|
*/
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
void _glfwInputError(int code, const char* format, ...) __attribute__((format(printf, 2, 3)));
|
void _glfwInputError(int error, const char* format, ...) __attribute__((format(printf, 2, 3)));
|
||||||
#else
|
#else
|
||||||
void _glfwInputError(int code, const char* format, ...);
|
void _glfwInputError(int error, const char* format, ...);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! @brief Notifies shared code of files or directories dropped on a window.
|
/*! @brief Notifies dropped object over window.
|
||||||
* @param[in] window The window that received the event.
|
* @param[in] window The window that received the event.
|
||||||
* @param[in] count The number of dropped objects.
|
* @param[in] count The number of dropped objects.
|
||||||
* @param[in] names The names of the dropped objects.
|
* @param[in] names The names of the dropped objects.
|
||||||
@@ -870,41 +984,19 @@ void _glfwInputError(int code, const char* format, ...);
|
|||||||
*/
|
*/
|
||||||
void _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
|
void _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
|
||||||
|
|
||||||
/*! @brief Notifies shared code of a joystick connection or disconnection.
|
/*! @brief Notifies shared code of a joystick connection/disconnection event.
|
||||||
* @param[in] js The joystick that was connected or disconnected.
|
* @param[in] jid The joystick that was connected or disconnected.
|
||||||
* @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
|
* @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
|
||||||
* @ingroup event
|
* @ingroup event
|
||||||
*/
|
*/
|
||||||
void _glfwInputJoystick(_GLFWjoystick* js, int event);
|
void _glfwInputJoystickChange(int jid, int event);
|
||||||
|
|
||||||
/*! @brief Notifies shared code of the new value of a joystick axis.
|
|
||||||
* @param[in] js The joystick whose axis to update.
|
|
||||||
* @param[in] axis The index of the axis to update.
|
|
||||||
* @param[in] value The new value of the axis.
|
|
||||||
*/
|
|
||||||
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value);
|
|
||||||
|
|
||||||
/*! @brief Notifies shared code of the new value of a joystick button.
|
|
||||||
* @param[in] js The joystick whose button to update.
|
|
||||||
* @param[in] button The index of the button to update.
|
|
||||||
* @param[in] value The new value of the button.
|
|
||||||
*/
|
|
||||||
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value);
|
|
||||||
|
|
||||||
/*! @brief Notifies shared code of the new value of a joystick hat.
|
|
||||||
* @param[in] js The joystick whose hat to update.
|
|
||||||
* @param[in] button The index of the hat to update.
|
|
||||||
* @param[in] value The new value of the hat.
|
|
||||||
*/
|
|
||||||
void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value);
|
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Utility functions
|
// Utility functions
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
/*! @brief Chooses the video mode most closely matching the desired one.
|
/*! @ingroup utility
|
||||||
* @ingroup utility
|
|
||||||
*/
|
*/
|
||||||
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
|
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
|
||||||
const GLFWvidmode* desired);
|
const GLFWvidmode* desired);
|
||||||
@@ -959,13 +1051,11 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig);
|
|||||||
*/
|
*/
|
||||||
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
|
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
|
||||||
|
|
||||||
/*! @brief Allocates red, green and blue value arrays of the specified size.
|
/*! @ingroup utility
|
||||||
* @ingroup utility
|
|
||||||
*/
|
*/
|
||||||
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size);
|
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size);
|
||||||
|
|
||||||
/*! @brief Frees the red, green and blue value arrays and clears the struct.
|
/*! @ingroup utility
|
||||||
* @ingroup utility
|
|
||||||
*/
|
*/
|
||||||
void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
|
void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
|
||||||
|
|
||||||
@@ -984,19 +1074,13 @@ _GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM);
|
|||||||
*/
|
*/
|
||||||
void _glfwFreeMonitor(_GLFWmonitor* monitor);
|
void _glfwFreeMonitor(_GLFWmonitor* monitor);
|
||||||
|
|
||||||
/*! @brief Returns an available joystick object with arrays and name allocated.
|
/*! @ingroup utility
|
||||||
* @ingroup utility
|
|
||||||
*/
|
*/
|
||||||
_GLFWjoystick* _glfwAllocJoystick(const char* name,
|
void _glfwFreeMonitors(_GLFWmonitor** monitors, int count);
|
||||||
const char* guid,
|
|
||||||
int axisCount,
|
|
||||||
int buttonCount,
|
|
||||||
int hatCount);
|
|
||||||
|
|
||||||
/*! @brief Frees arrays and name and flags the joystick object as unused.
|
/*! @ingroup utility
|
||||||
* @ingroup utility
|
*/
|
||||||
*/
|
GLFWbool _glfwIsPrintable(int key);
|
||||||
void _glfwFreeJoystick(_GLFWjoystick* js);
|
|
||||||
|
|
||||||
/*! @ingroup utility
|
/*! @ingroup utility
|
||||||
*/
|
*/
|
||||||
@@ -1010,3 +1094,4 @@ void _glfwTerminateVulkan(void);
|
|||||||
*/
|
*/
|
||||||
const char* _glfwGetVulkanResultString(VkResult result);
|
const char* _glfwGetVulkanResultString(VkResult result);
|
||||||
|
|
||||||
|
#endif // _glfw3_internal_h_
|
||||||
|
|||||||
+179
-268
@@ -27,6 +27,9 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
#include <linux/joystick.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
@@ -37,220 +40,129 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif // __linux__
|
||||||
|
|
||||||
// Apply an EV_KEY event to the specified joystick
|
|
||||||
//
|
|
||||||
static void handleKeyEvent(_GLFWjoystick* js, int code, int value)
|
|
||||||
{
|
|
||||||
_glfwInputJoystickButton(js,
|
|
||||||
js->linjs.keyMap[code - BTN_MISC],
|
|
||||||
value ? GLFW_PRESS : GLFW_RELEASE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply an EV_ABS event to the specified joystick
|
|
||||||
//
|
|
||||||
static void handleAbsEvent(_GLFWjoystick* js, int code, int value)
|
|
||||||
{
|
|
||||||
const int index = js->linjs.absMap[code];
|
|
||||||
|
|
||||||
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
|
|
||||||
{
|
|
||||||
static const char stateMap[3][3] =
|
|
||||||
{
|
|
||||||
{ GLFW_HAT_CENTERED, GLFW_HAT_UP, GLFW_HAT_DOWN },
|
|
||||||
{ GLFW_HAT_LEFT, GLFW_HAT_LEFT_UP, GLFW_HAT_LEFT_DOWN },
|
|
||||||
{ GLFW_HAT_RIGHT, GLFW_HAT_RIGHT_UP, GLFW_HAT_RIGHT_DOWN },
|
|
||||||
};
|
|
||||||
|
|
||||||
const int hat = (code - ABS_HAT0X) / 2;
|
|
||||||
const int axis = (code - ABS_HAT0X) % 2;
|
|
||||||
int* state = js->linjs.hats[hat];
|
|
||||||
|
|
||||||
// NOTE: Looking at several input drivers, it seems all hat events use
|
|
||||||
// -1 for left / up, 0 for centered and 1 for right / down
|
|
||||||
if (value == 0)
|
|
||||||
state[axis] = 0;
|
|
||||||
else if (value < 0)
|
|
||||||
state[axis] = 1;
|
|
||||||
else if (value > 0)
|
|
||||||
state[axis] = 2;
|
|
||||||
|
|
||||||
_glfwInputJoystickHat(js, index, stateMap[state[0]][state[1]]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const struct input_absinfo* info = &js->linjs.absInfo[code];
|
|
||||||
float normalized = value;
|
|
||||||
|
|
||||||
const int range = info->maximum - info->minimum;
|
|
||||||
if (range)
|
|
||||||
{
|
|
||||||
// Normalize to 0.0 -> 1.0
|
|
||||||
normalized = (normalized - info->minimum) / range;
|
|
||||||
// Normalize to -1.0 -> 1.0
|
|
||||||
normalized = normalized * 2.0f - 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputJoystickAxis(js, index, normalized);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poll state of absolute axes
|
|
||||||
//
|
|
||||||
static void pollAbsState(_GLFWjoystick* js)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
|
|
||||||
for (code = 0; code < ABS_CNT; code++)
|
|
||||||
{
|
|
||||||
if (js->linjs.absMap[code] < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
struct input_absinfo* info = &js->linjs.absInfo[code];
|
|
||||||
|
|
||||||
if (ioctl(js->linjs.fd, EVIOCGABS(code), info) < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
handleAbsEvent(js, code, info->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define isBitSet(bit, arr) (arr[(bit) / 8] & (1 << ((bit) % 8)))
|
|
||||||
|
|
||||||
// Attempt to open the specified joystick device
|
// Attempt to open the specified joystick device
|
||||||
//
|
//
|
||||||
|
#if defined(__linux__)
|
||||||
static GLFWbool openJoystickDevice(const char* path)
|
static GLFWbool openJoystickDevice(const char* path)
|
||||||
{
|
{
|
||||||
int jid, code;
|
char axisCount, buttonCount;
|
||||||
char name[256] = "";
|
char name[256] = "";
|
||||||
char guid[33] = "";
|
int jid, fd, version;
|
||||||
char evBits[(EV_CNT + 7) / 8] = {0};
|
_GLFWjoystickLinux* js;
|
||||||
char keyBits[(KEY_CNT + 7) / 8] = {0};
|
|
||||||
char absBits[(ABS_CNT + 7) / 8] = {0};
|
|
||||||
int axisCount = 0, buttonCount = 0, hatCount = 0;
|
|
||||||
struct input_id id;
|
|
||||||
_GLFWjoystickLinux linjs = {0};
|
|
||||||
_GLFWjoystick* js = NULL;
|
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
{
|
{
|
||||||
if (!_glfw.joysticks[jid].present)
|
if (!_glfw.linux_js.js[jid].present)
|
||||||
continue;
|
continue;
|
||||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
|
||||||
|
if (strcmp(_glfw.linux_js.js[jid].path, path) == 0)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
if (linjs.fd == -1)
|
{
|
||||||
|
if (!_glfw.linux_js.js[jid].present)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jid > GLFW_JOYSTICK_LAST)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
|
fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
|
if (fd == -1)
|
||||||
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
|
return GLFW_FALSE;
|
||||||
ioctl(linjs.fd, EVIOCGID, &id) < 0)
|
|
||||||
|
// Verify that the joystick driver version is at least 1.0
|
||||||
|
ioctl(fd, JSIOCGVERSION, &version);
|
||||||
|
if (version < 0x010000)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
// It's an old 0.x interface (we don't support it)
|
||||||
"Linux: Failed to query input device: %s",
|
close(fd);
|
||||||
strerror(errno));
|
|
||||||
close(linjs.fd);
|
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure this device supports the events expected of a joystick
|
if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0)
|
||||||
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
|
|
||||||
{
|
|
||||||
close(linjs.fd);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
|
|
||||||
strncpy(name, "Unknown", sizeof(name));
|
strncpy(name, "Unknown", sizeof(name));
|
||||||
|
|
||||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
js = _glfw.linux_js.js + jid;
|
||||||
if (id.vendor && id.product && id.version)
|
js->present = GLFW_TRUE;
|
||||||
{
|
js->name = strdup(name);
|
||||||
sprintf(guid, "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000",
|
js->path = strdup(path);
|
||||||
id.bustype & 0xff, id.bustype >> 8,
|
js->fd = fd;
|
||||||
id.vendor & 0xff, id.vendor >> 8,
|
|
||||||
id.product & 0xff, id.product >> 8,
|
|
||||||
id.version & 0xff, id.version >> 8);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(guid, "%02x%02x0000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
|
||||||
id.bustype & 0xff, id.bustype >> 8,
|
|
||||||
name[0], name[1], name[2], name[3],
|
|
||||||
name[4], name[5], name[6], name[7],
|
|
||||||
name[8], name[9], name[10]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (code = BTN_MISC; code < KEY_CNT; code++)
|
ioctl(fd, JSIOCGAXES, &axisCount);
|
||||||
{
|
js->axisCount = (int) axisCount;
|
||||||
if (!isBitSet(code, keyBits))
|
js->axes = calloc(axisCount, sizeof(float));
|
||||||
continue;
|
|
||||||
|
|
||||||
linjs.keyMap[code - BTN_MISC] = buttonCount;
|
ioctl(fd, JSIOCGBUTTONS, &buttonCount);
|
||||||
buttonCount++;
|
js->buttonCount = (int) buttonCount;
|
||||||
}
|
js->buttons = calloc(buttonCount, 1);
|
||||||
|
|
||||||
for (code = 0; code < ABS_CNT; code++)
|
_glfwInputJoystickChange(jid, GLFW_CONNECTED);
|
||||||
{
|
|
||||||
linjs.absMap[code] = -1;
|
|
||||||
if (!isBitSet(code, absBits))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
|
|
||||||
{
|
|
||||||
linjs.absMap[code] = hatCount;
|
|
||||||
hatCount++;
|
|
||||||
// Skip the Y axis
|
|
||||||
code++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ioctl(linjs.fd, EVIOCGABS(code), &linjs.absInfo[code]) < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
linjs.absMap[code] = axisCount;
|
|
||||||
axisCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
js = _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
|
|
||||||
if (!js)
|
|
||||||
{
|
|
||||||
close(linjs.fd);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(linjs.path, path, sizeof(linjs.path));
|
|
||||||
memcpy(&js->linjs, &linjs, sizeof(linjs));
|
|
||||||
|
|
||||||
pollAbsState(js);
|
|
||||||
|
|
||||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
#endif // __linux__
|
||||||
|
|
||||||
#undef isBitSet
|
// Polls for and processes events the specified joystick
|
||||||
|
|
||||||
// Frees all resources associated with the specified joystick
|
|
||||||
//
|
//
|
||||||
static void closeJoystick(_GLFWjoystick* js)
|
static GLFWbool pollJoystickEvents(_GLFWjoystickLinux* js)
|
||||||
{
|
{
|
||||||
close(js->linjs.fd);
|
#if defined(__linux__)
|
||||||
_glfwFreeJoystick(js);
|
_glfwPollJoystickEvents();
|
||||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
|
||||||
|
if (!js->present)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
// Read all queued events (non-blocking)
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
struct js_event e;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if (read(js->fd, &e, sizeof(e)) < 0)
|
||||||
|
{
|
||||||
|
// Reset the joystick slot if the device was disconnected
|
||||||
|
if (errno == ENODEV)
|
||||||
|
{
|
||||||
|
free(js->axes);
|
||||||
|
free(js->buttons);
|
||||||
|
free(js->name);
|
||||||
|
free(js->path);
|
||||||
|
|
||||||
|
memset(js, 0, sizeof(_GLFWjoystickLinux));
|
||||||
|
|
||||||
|
_glfwInputJoystickChange(js - _glfw.linux_js.js,
|
||||||
|
GLFW_DISCONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the initial-state bit
|
||||||
|
e.type &= ~JS_EVENT_INIT;
|
||||||
|
|
||||||
|
if (e.type == JS_EVENT_AXIS)
|
||||||
|
js->axes[e.number] = (float) e.value / 32767.0f;
|
||||||
|
else if (e.type == JS_EVENT_BUTTON)
|
||||||
|
js->buttons[e.number] = e.value ? GLFW_PRESS : GLFW_RELEASE;
|
||||||
|
}
|
||||||
|
#endif // __linux__
|
||||||
|
return js->present;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lexically compare joysticks by name; used by qsort
|
// Lexically compare joysticks by name; used by qsort
|
||||||
//
|
//
|
||||||
|
#if defined(__linux__)
|
||||||
static int compareJoysticks(const void* fp, const void* sp)
|
static int compareJoysticks(const void* fp, const void* sp)
|
||||||
{
|
{
|
||||||
const _GLFWjoystick* fj = fp;
|
const _GLFWjoystickLinux* fj = fp;
|
||||||
const _GLFWjoystick* sj = sp;
|
const _GLFWjoystickLinux* sj = sp;
|
||||||
return strcmp(fj->linjs.path, sj->linjs.path);
|
return strcmp(fj->path, sj->path);
|
||||||
}
|
}
|
||||||
|
#endif // __linux__
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@@ -261,24 +173,36 @@ static int compareJoysticks(const void* fp, const void* sp)
|
|||||||
//
|
//
|
||||||
GLFWbool _glfwInitJoysticksLinux(void)
|
GLFWbool _glfwInitJoysticksLinux(void)
|
||||||
{
|
{
|
||||||
|
#if defined(__linux__)
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
const char* dirname = "/dev/input";
|
const char* dirname = "/dev/input";
|
||||||
|
|
||||||
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
_glfw.linux_js.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||||
if (_glfw.linjs.inotify > 0)
|
if (_glfw.linux_js.inotify == -1)
|
||||||
{
|
{
|
||||||
// HACK: Register for IN_ATTRIB to get notified when udev is done
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
// This works well in practice but the true way is libudev
|
"Linux: Failed to initialize inotify: %s",
|
||||||
|
strerror(errno));
|
||||||
_glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify,
|
return GLFW_FALSE;
|
||||||
dirname,
|
|
||||||
IN_CREATE | IN_ATTRIB | IN_DELETE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Continue without device connection notifications if inotify fails
|
// HACK: Register for IN_ATTRIB as well to get notified when udev is done
|
||||||
|
// This works well in practice but the true way is libudev
|
||||||
|
|
||||||
if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)
|
_glfw.linux_js.watch = inotify_add_watch(_glfw.linux_js.inotify,
|
||||||
|
dirname,
|
||||||
|
IN_CREATE | IN_ATTRIB);
|
||||||
|
if (_glfw.linux_js.watch == -1)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Linux: Failed to watch for joystick connections in %s: %s",
|
||||||
|
dirname,
|
||||||
|
strerror(errno));
|
||||||
|
// Continue without device connection notifications
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regcomp(&_glfw.linux_js.regex, "^js[0-9]\\+$", 0) != 0)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@@ -291,15 +215,13 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
|||||||
|
|
||||||
while ((entry = readdir(dir)))
|
while ((entry = readdir(dir)))
|
||||||
{
|
{
|
||||||
|
char path[20];
|
||||||
regmatch_t match;
|
regmatch_t match;
|
||||||
|
|
||||||
if (regexec(&_glfw.linjs.regex, entry->d_name, 1, &match, 0) != 0)
|
if (regexec(&_glfw.linux_js.regex, entry->d_name, 1, &match, 0) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
char path[PATH_MAX];
|
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
|
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
|
||||||
|
|
||||||
if (openJoystickDevice(path))
|
if (openJoystickDevice(path))
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -307,10 +229,17 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
|||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Linux: Failed to open joystick device directory %s: %s",
|
||||||
|
dirname,
|
||||||
|
strerror(errno));
|
||||||
|
// Continue with no joysticks detected
|
||||||
|
}
|
||||||
|
|
||||||
// Continue with no joysticks if enumeration fails
|
qsort(_glfw.linux_js.js, count, sizeof(_GLFWjoystickLinux), compareJoysticks);
|
||||||
|
#endif // __linux__
|
||||||
|
|
||||||
qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,65 +247,56 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
|||||||
//
|
//
|
||||||
void _glfwTerminateJoysticksLinux(void)
|
void _glfwTerminateJoysticksLinux(void)
|
||||||
{
|
{
|
||||||
int jid;
|
#if defined(__linux__)
|
||||||
|
int i;
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
for (i = 0; i <= GLFW_JOYSTICK_LAST; i++)
|
||||||
{
|
{
|
||||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
if (_glfw.linux_js.js[i].present)
|
||||||
if (js->present)
|
{
|
||||||
closeJoystick(js);
|
close(_glfw.linux_js.js[i].fd);
|
||||||
|
free(_glfw.linux_js.js[i].axes);
|
||||||
|
free(_glfw.linux_js.js[i].buttons);
|
||||||
|
free(_glfw.linux_js.js[i].name);
|
||||||
|
free(_glfw.linux_js.js[i].path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
regfree(&_glfw.linjs.regex);
|
regfree(&_glfw.linux_js.regex);
|
||||||
|
|
||||||
if (_glfw.linjs.inotify > 0)
|
if (_glfw.linux_js.inotify > 0)
|
||||||
{
|
{
|
||||||
if (_glfw.linjs.watch > 0)
|
if (_glfw.linux_js.watch > 0)
|
||||||
inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
|
inotify_rm_watch(_glfw.linux_js.inotify, _glfw.linux_js.watch);
|
||||||
|
|
||||||
close(_glfw.linjs.inotify);
|
close(_glfw.linux_js.inotify);
|
||||||
}
|
}
|
||||||
|
#endif // __linux__
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwDetectJoystickConnectionLinux(void)
|
void _glfwPollJoystickEvents(void)
|
||||||
{
|
{
|
||||||
|
#if defined(__linux__)
|
||||||
ssize_t offset = 0;
|
ssize_t offset = 0;
|
||||||
char buffer[16384];
|
char buffer[16384];
|
||||||
|
|
||||||
if (_glfw.linjs.inotify <= 0)
|
const ssize_t size = read(_glfw.linux_js.inotify, buffer, sizeof(buffer));
|
||||||
return;
|
|
||||||
|
|
||||||
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
|
|
||||||
|
|
||||||
while (size > offset)
|
while (size > offset)
|
||||||
{
|
{
|
||||||
regmatch_t match;
|
regmatch_t match;
|
||||||
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
|
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
|
||||||
|
|
||||||
offset += sizeof(struct inotify_event) + e->len;
|
if (regexec(&_glfw.linux_js.regex, e->name, 1, &match, 0) == 0)
|
||||||
|
|
||||||
if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
char path[PATH_MAX];
|
|
||||||
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
|
|
||||||
|
|
||||||
if (e->mask & (IN_CREATE | IN_ATTRIB))
|
|
||||||
openJoystickDevice(path);
|
|
||||||
else if (e->mask & IN_DELETE)
|
|
||||||
{
|
{
|
||||||
int jid;
|
char path[20];
|
||||||
|
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
openJoystickDevice(path);
|
||||||
{
|
|
||||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
|
||||||
{
|
|
||||||
closeJoystick(_glfw.joysticks + jid);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
offset += sizeof(struct inotify_event) + e->len;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -384,47 +304,38 @@ void _glfwDetectJoystickConnectionLinux(void)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
int _glfwPlatformJoystickPresent(int jid)
|
||||||
{
|
{
|
||||||
// Read all queued events (non-blocking)
|
_GLFWjoystickLinux* js = _glfw.linux_js.js + jid;
|
||||||
for (;;)
|
return pollJoystickEvents(js);
|
||||||
{
|
|
||||||
struct input_event e;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
if (read(js->linjs.fd, &e, sizeof(e)) < 0)
|
|
||||||
{
|
|
||||||
// Reset the joystick slot if the device was disconnected
|
|
||||||
if (errno == ENODEV)
|
|
||||||
closeJoystick(js);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.type == EV_SYN)
|
|
||||||
{
|
|
||||||
if (e.code == SYN_DROPPED)
|
|
||||||
_glfw.linjs.dropped = GLFW_TRUE;
|
|
||||||
else if (e.code == SYN_REPORT)
|
|
||||||
{
|
|
||||||
_glfw.linjs.dropped = GLFW_FALSE;
|
|
||||||
pollAbsState(js);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.linjs.dropped)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (e.type == EV_KEY)
|
|
||||||
handleKeyEvent(js, e.code, e.value);
|
|
||||||
else if (e.type == EV_ABS)
|
|
||||||
handleAbsEvent(js, e.code, e.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return js->present;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
const float* _glfwPlatformGetJoystickAxes(int jid, int* count)
|
||||||
{
|
{
|
||||||
|
_GLFWjoystickLinux* js = _glfw.linux_js.js + jid;
|
||||||
|
if (!pollJoystickEvents(js))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*count = js->axisCount;
|
||||||
|
return js->axes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char* _glfwPlatformGetJoystickButtons(int jid, int* count)
|
||||||
|
{
|
||||||
|
_GLFWjoystickLinux* js = _glfw.linux_js.js + jid;
|
||||||
|
if (!pollJoystickEvents(js))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*count = js->buttonCount;
|
||||||
|
return js->buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetJoystickName(int jid)
|
||||||
|
{
|
||||||
|
_GLFWjoystickLinux* js = _glfw.linux_js.js + jid;
|
||||||
|
if (!pollJoystickEvents(js))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return js->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+24
-18
@@ -24,39 +24,45 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#include <linux/input.h>
|
#ifndef _glfw3_linux_joystick_h_
|
||||||
#include <linux/limits.h>
|
#define _glfw3_linux_joystick_h_
|
||||||
|
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWjoylistLinux linux_js
|
||||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_MAPPING_NAME "Linux"
|
|
||||||
|
|
||||||
// Linux-specific joystick data
|
// Linux-specific joystick data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWjoystickLinux
|
typedef struct _GLFWjoystickLinux
|
||||||
{
|
{
|
||||||
int fd;
|
GLFWbool present;
|
||||||
char path[PATH_MAX];
|
int fd;
|
||||||
int keyMap[KEY_CNT - BTN_MISC];
|
float* axes;
|
||||||
int absMap[ABS_CNT];
|
int axisCount;
|
||||||
struct input_absinfo absInfo[ABS_CNT];
|
unsigned char* buttons;
|
||||||
int hats[4][2];
|
int buttonCount;
|
||||||
|
char* name;
|
||||||
|
char* path;
|
||||||
} _GLFWjoystickLinux;
|
} _GLFWjoystickLinux;
|
||||||
|
|
||||||
// Linux-specific joystick API data
|
// Linux-specific joystick API data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWlibraryLinux
|
typedef struct _GLFWjoylistLinux
|
||||||
{
|
{
|
||||||
int inotify;
|
_GLFWjoystickLinux js[GLFW_JOYSTICK_LAST + 1];
|
||||||
int watch;
|
|
||||||
regex_t regex;
|
#if defined(__linux__)
|
||||||
GLFWbool dropped;
|
int inotify;
|
||||||
} _GLFWlibraryLinux;
|
int watch;
|
||||||
|
regex_t regex;
|
||||||
|
#endif /*__linux__*/
|
||||||
|
} _GLFWjoylistLinux;
|
||||||
|
|
||||||
|
|
||||||
GLFWbool _glfwInitJoysticksLinux(void);
|
GLFWbool _glfwInitJoysticksLinux(void);
|
||||||
void _glfwTerminateJoysticksLinux(void);
|
void _glfwTerminateJoysticksLinux(void);
|
||||||
void _glfwDetectJoystickConnectionLinux(void);
|
|
||||||
|
|
||||||
|
void _glfwPollJoystickEvents(void);
|
||||||
|
|
||||||
|
#endif // _glfw3_linux_joystick_h_
|
||||||
|
|||||||
-241
@@ -1,241 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
// As mappings.h.in, this file is used by CMake to produce the mappings.h
|
|
||||||
// header file. If you are adding a GLFW specific gamepad mapping, this is
|
|
||||||
// where to put it.
|
|
||||||
//========================================================================
|
|
||||||
// As mappings.h, this provides all pre-defined gamepad mappings, including
|
|
||||||
// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
|
|
||||||
// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
|
|
||||||
// This file can be re-generated from mappings.h.in and the upstream
|
|
||||||
// gamecontrollerdb.txt with the GenerateMappings.cmake script.
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
// All gamepad mappings not labeled GLFW are copied from the
|
|
||||||
// SDL_GameControllerDB project under the following license:
|
|
||||||
//
|
|
||||||
// Simple DirectMedia Layer
|
|
||||||
// Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the
|
|
||||||
// use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
// misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
|
|
||||||
const char* _glfwDefaultMappings =
|
|
||||||
"8f0e1200000000000000504944564944,Acme,platform:Windows,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
|
|
||||||
"341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,\n"
|
|
||||||
"ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,\n"
|
|
||||||
"6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,\n"
|
|
||||||
"0d0f6e00000000000000504944564944,HORIPAD 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,\n"
|
|
||||||
"88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,\n"
|
|
||||||
"4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,\n"
|
|
||||||
"25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,\n"
|
|
||||||
"4c05c405000000000000504944564944,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows,\n"
|
|
||||||
"4c05cc09000000000000504944564944,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows,\n"
|
|
||||||
"4c05a00b000000000000504944564944,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows,\n"
|
|
||||||
"6d0418c2000000000000504944564944,Logitech RumblePad 2 USB,platform:Windows,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
|
||||||
"36280100000000000000504944564944,OUYA Controller,platform:Windows,a:b0,b:b3,y:b2,x:b1,start:b14,guide:b15,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpleft:b10,dpdown:b9,dpright:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b12,righttrigger:b13,\n"
|
|
||||||
"4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows,\n"
|
|
||||||
"00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows,\n"
|
|
||||||
"28040140000000000000504944564944,GamePad Pro USB,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,\n"
|
|
||||||
"ff113133000000000000504944564944,SVEN X-PAD,platform:Windows,a:b2,b:b3,y:b1,x:b0,start:b5,back:b4,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b8,righttrigger:b9,\n"
|
|
||||||
"8f0e0300000000000000504944564944,Piranha xtreme,platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
|
|
||||||
"8f0e0d31000000000000504944564944,Multilaser JS071 USB,platform:Windows,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
|
|
||||||
"10080300000000000000504944564944,PS2 USB,platform:Windows,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
|
|
||||||
"79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,y:b1,x:b0,start:b4,guide:b10,back:b5,leftstick:b8,rightstick:b9,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows,\n"
|
|
||||||
"4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,platform:Windows,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
|
||||||
"6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
|
|
||||||
"83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Windows,\n"
|
|
||||||
"10080100000000000000504944564944,PS1 USB,platform:Windows,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
|
|
||||||
"49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,platform:Windows,\n"
|
|
||||||
"4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"79004318000000000000504944564944,Mayflash GameCube Controller Adapter,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b0,start:b9,guide:b0,leftshoulder:b4,rightshoulder:b7,leftstick:b0,rightstick:b0,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
|
|
||||||
"79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,y:b3,x:b4,start:b11,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,platform:Windows,\n"
|
|
||||||
"63252305000000000000504944564944,USB Vibration Joystick (BM),platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
|
||||||
"20380900000000000000504944564944,8Bitdo NES30 PRO Wireless,platform:Windows,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"02200090000000000000504944564944,8Bitdo NES30 PRO USB,platform:Windows,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"ff113133000000000000504944564944,Gembird JPD-DualForce,platform:Windows,a:b2,b:b3,x:b0,y:b1,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,leftstick:b10,rightstick:b11,\n"
|
|
||||||
"341a0108000000000000504944564944,EXEQ RF USB Gamepad 8206,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,leftstick:b8,rightstick:b7,back:b8,start:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows,\n"
|
|
||||||
"c0111352000000000000504944564944,Battalife Joystick,platform:Windows,x:b4,a:b6,b:b7,y:b5,back:b2,start:b3,leftshoulder:b0,rightshoulder:b1,leftx:a0,lefty:a1,\n"
|
|
||||||
"100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,platform:Windows,\n"
|
|
||||||
"79000600000000000000504944564944,NGS Phantom,a:b2,b:b3,y:b1,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
|
||||||
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,\n"
|
|
||||||
"6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,\n"
|
|
||||||
"6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,\n"
|
|
||||||
"6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,\n"
|
|
||||||
"6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,\n"
|
|
||||||
"4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,\n"
|
|
||||||
"4c05000000000000c405000000000000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Mac OS X,\n"
|
|
||||||
"4c05000000000000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Mac OS X,\n"
|
|
||||||
"5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,\n"
|
|
||||||
"891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Mac OS X,\n"
|
|
||||||
"4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Mac OS X,\n"
|
|
||||||
"8f0e0000000000000300000000000000,Piranha xtreme,platform:Mac OS X,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
|
|
||||||
"0d0f0000000000004d00000000000000,HORI Gem Pad 3,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
|
|
||||||
"79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,\n"
|
|
||||||
"4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,platform:Mac OS X,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
|
||||||
"AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,\n"
|
|
||||||
"050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,y:b9,x:b10,start:b6,guide:b8,back:b7,dpup:b2,dpleft:b0,dpdown:b3,dpright:b1,leftx:a0,lefty:a1,lefttrigger:b12,righttrigger:,leftshoulder:b11,platform:Mac OS X,\n"
|
|
||||||
"83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X,\n"
|
|
||||||
"bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X,\n"
|
|
||||||
"79000000000000001100000000000000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a3,lefty:a4,platform:Mac OS X,\n"
|
|
||||||
"5e04000000000000dd02000000000000,Xbox One Wired Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"5e04000000000000ea02000000000000,Xbox Wireless Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"5e04000000000000e002000000000000,Xbox Wireless Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b10,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,x:b18,y:b17,back:b7,guide:b8,start:b6,leftstick:b23,rightstick:b24,leftshoulder:b19,rightshoulder:b20,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b21,righttrigger:b22,platform:Mac OS X,\n"
|
|
||||||
"79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,x:b0,y:b12,back:b32,start:b36,leftstick:b40,rightstick:b44,leftshoulder:b16,rightshoulder:b20,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a4,rightx:a8,righty:a12,lefttrigger:b24,righttrigger:b28,platform:Mac OS X,\n"
|
|
||||||
"2509000000000000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,\n"
|
|
||||||
"351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X,\n"
|
|
||||||
"b4040000000000000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,x:b3,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X,\n"
|
|
||||||
"81170000000000007e05000000000000,Sega Saturn,x:b0,a:b2,b:b4,y:b6,start:b13,dpleft:b15,dpdown:b16,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,lefttrigger:b10,rightshoulder:b9,righttrigger:a4,righttrigger:b11,leftx:a0,lefty:a2,platform:Mac OS X,\n"
|
|
||||||
"10280000000000000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X,\n"
|
|
||||||
"d814000000000000cecf000000000000,MC Cthulhu,platform:Mac OS X,leftx:,lefty:,rightx:,righty:,lefttrigger:b6,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,righttrigger:b7,\n"
|
|
||||||
"0d0f0000000000006600000000000000,HORIPAD FPS PLUS 4,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:a4,\n"
|
|
||||||
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,\n"
|
|
||||||
"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,\n"
|
|
||||||
"030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,\n"
|
|
||||||
"030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
|
||||||
"030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,\n"
|
|
||||||
"030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
|
||||||
"030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,\n"
|
|
||||||
"030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
|
||||||
"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,\n"
|
|
||||||
"030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
|
|
||||||
"050000004c050000c405000000010000,Sony DualShock 4 BT,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,\n"
|
|
||||||
"030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
|
|
||||||
"050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
|
|
||||||
"030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
|
|
||||||
"030000006f0e00003001000001010000,EA Sports PS3 Controller,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
|
|
||||||
"03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
|
||||||
"030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
|
||||||
"030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
|
||||||
"030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
|
||||||
"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,y:b0,x:b3,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux,\n"
|
|
||||||
"03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Linux,\n"
|
|
||||||
"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,y:b3,x:b1,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Linux,\n"
|
|
||||||
"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,\n"
|
|
||||||
"030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick ,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
|
|
||||||
"030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick ,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
|
|
||||||
"030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,\n"
|
|
||||||
"030000006d04000016c2000010010000,Logitech Logitech Dual Action,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
|
||||||
"03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Linux,\n"
|
|
||||||
"030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,y:b4,x:b3,start:b8,guide:b5,back:b2,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b9,righttrigger:b10,platform:Linux,\n"
|
|
||||||
"030000006d04000018c2000010010000,Logitech Logitech RumblePad 2 USB,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
|
||||||
"05000000d6200000ad0d000001000000,Moga Pro,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,\n"
|
|
||||||
"030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,platform:Linux,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
|
|
||||||
"030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,platform:Linux,a:b1,b:b2,x:b0,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,\n"
|
|
||||||
"0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Linux,\n"
|
|
||||||
"0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Linux,\n"
|
|
||||||
"030000006f0e00001f01000000010000,Generic X-Box pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"03000000280400000140000000010000,Gravis GamePad Pro USB ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,\n"
|
|
||||||
"030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"030000005e0400008502000000010000,Microsoft X-Box pad (Japan),platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
|
|
||||||
"03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,platform:Linux,a:b2,b:b1,y:b0,x:b3,start:b8,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,\n"
|
|
||||||
"030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,\n"
|
|
||||||
"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Linux,\n"
|
|
||||||
"03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,\n"
|
|
||||||
"060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux,\n"
|
|
||||||
"050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux,\n"
|
|
||||||
"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick ,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a3,rightx:a1,righty:a4,\n"
|
|
||||||
"03000000666600000488000000010000,Super Joy Box 5 Pro,platform:Linux,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,\n"
|
|
||||||
"05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,\n"
|
|
||||||
"05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,\n"
|
|
||||||
"030000008916000001fd000024010000,Razer Onza Classic Edition,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"030000005e040000d102000001010000,Microsoft X-Box One pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"030000005e040000dd02000003020000,Microsoft X-Box One pad v2,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux,\n"
|
|
||||||
"03000000790000001100000010010000,RetroLink Saturn Classic Controller,platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,\n"
|
|
||||||
"050000007e0500003003000001000000,Nintendo Wii U Pro Controller,platform:Linux,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,\n"
|
|
||||||
"030000005e0400008e02000004010000,Microsoft X-Box 360 pad,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
|
|
||||||
"030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,\n"
|
|
||||||
"030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7\n"
|
|
||||||
"03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
|
||||||
"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b7,back:b6,guide:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,lefttrigger:a5,righttrigger:a4,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
|
||||||
"03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,\n"
|
|
||||||
"030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"030000006f0e00001304000000010000,Generic X-Box pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:a0,rightstick:a3,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux,\n"
|
|
||||||
"03000000bd12000015d0000010010000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux,\n"
|
|
||||||
"03000000790000001100000010010000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux,\n"
|
|
||||||
"03000000c9110000f055000011010000,HJC Game GAMEPAD,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b2,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:h0.2,righttrigger:b7,b:b1,platform:Linux,\n"
|
|
||||||
"03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux,\n"
|
|
||||||
"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:,leftstick:,rightstick:,leftshoulder:,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,rightshoulder:b7,dpup:b12,platform:Linux,\n"
|
|
||||||
"030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,platform:Linux,x:b0,a:b2,b:b3,y:b1,back:b10,guide:b12,start:b11,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
|
||||||
"030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,platform:Linux,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux,\n"
|
|
||||||
"030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,platform:Linux,a:b0,b:b2,x:b1,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,\n"
|
|
||||||
"05000000102800000900000000010000,8Bitdo SFC30 GamePad,platform:Linux,x:b4,a:b1,b:b0,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,\n"
|
|
||||||
"03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,leftx:a0,lefty:a1,\n"
|
|
||||||
"030000000d0f00000d00000000010000,hori,platform:Linux,a:b0,b:b6,y:b2,x:b1,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,start:b9,guide:b10,back:b8,leftshoulder:b3,rightshoulder:b7,leftx:b4,lefty:b5,\n"
|
|
||||||
"03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,\n"
|
|
||||||
"03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,platform:Linux,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,\n"
|
|
||||||
"03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),platform:Linux,a:b3,b:b4,y:b1,x:b0,start:b7,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,\n"
|
|
||||||
"05000000010000000100000003000000,Nintendo Wiimote,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
|
|
||||||
"030000005e0400008e02000062230000,Microsoft X-Box 360 pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,y:b1,x:b0,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,platform:Linux,\n"
|
|
||||||
"030000006f0e00000103000000020000,Logic3 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"05000000380700006652000025010000,Mad Catz C.T.R.L.R ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
|
||||||
"030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
|
||||||
"03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:a2,righttrigger:a5,\n"
|
|
||||||
"05000000a00500003232000001000000,8Bitdo Zero GamePad,platform:Linux,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,\n"
|
|
||||||
"030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,platform:Linux,\n"
|
|
||||||
"03000000100800000300000010010000,USB Gamepad,platform:Linux,a:b2,b:b1,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
|
|
||||||
"05000000ac0500003232000001000000,VR-BOX,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
|
|
||||||
"03000000780000000600000010010000,Microntek USB Joystick,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1,\n"
|
|
||||||
|
|
||||||
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n";
|
|
||||||
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
// As mappings.h.in, this file is used by CMake to produce the mappings.h
|
|
||||||
// header file. If you are adding a GLFW specific gamepad mapping, this is
|
|
||||||
// where to put it.
|
|
||||||
//========================================================================
|
|
||||||
// As mappings.h, this provides all pre-defined gamepad mappings, including
|
|
||||||
// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
|
|
||||||
// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
|
|
||||||
// This file can be re-generated from mappings.h.in and the upstream
|
|
||||||
// gamecontrollerdb.txt with the GenerateMappings.cmake script.
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
// All gamepad mappings not labeled GLFW are copied from the
|
|
||||||
// SDL_GameControllerDB project under the following license:
|
|
||||||
//
|
|
||||||
// Simple DirectMedia Layer
|
|
||||||
// Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the
|
|
||||||
// use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
// misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
|
|
||||||
const char* _glfwDefaultMappings =
|
|
||||||
@GLFW_GAMEPAD_MAPPINGS@
|
|
||||||
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
|
||||||
"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n";
|
|
||||||
|
|
||||||
+12
-4
@@ -1,7 +1,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.3 Mir - www.glfw.org
|
// GLFW 3.3 Mir - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2014-2017 Brandon Schaefer <brandon.schaefer@canonical.com>
|
// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com>
|
||||||
//
|
//
|
||||||
// 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
|
||||||
@@ -51,7 +51,6 @@ static void createKeyTables(void)
|
|||||||
_glfw.mir.keycodes[KEY_8] = GLFW_KEY_8;
|
_glfw.mir.keycodes[KEY_8] = GLFW_KEY_8;
|
||||||
_glfw.mir.keycodes[KEY_9] = GLFW_KEY_9;
|
_glfw.mir.keycodes[KEY_9] = GLFW_KEY_9;
|
||||||
_glfw.mir.keycodes[KEY_0] = GLFW_KEY_0;
|
_glfw.mir.keycodes[KEY_0] = GLFW_KEY_0;
|
||||||
_glfw.mir.keycodes[KEY_SPACE] = GLFW_KEY_SPACE;
|
|
||||||
_glfw.mir.keycodes[KEY_MINUS] = GLFW_KEY_MINUS;
|
_glfw.mir.keycodes[KEY_MINUS] = GLFW_KEY_MINUS;
|
||||||
_glfw.mir.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL;
|
_glfw.mir.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL;
|
||||||
_glfw.mir.keycodes[KEY_Q] = GLFW_KEY_Q;
|
_glfw.mir.keycodes[KEY_Q] = GLFW_KEY_Q;
|
||||||
@@ -190,11 +189,18 @@ int _glfwPlatformInit(void)
|
|||||||
|
|
||||||
createKeyTables();
|
createKeyTables();
|
||||||
|
|
||||||
|
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!_glfwInitJoysticksLinux())
|
if (!_glfwInitJoysticksLinux())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
_glfwInitTimerPOSIX();
|
_glfwInitTimerPOSIX();
|
||||||
|
|
||||||
|
// Need the default conf for when we set a NULL cursor
|
||||||
|
_glfw.mir.defaultConf = mir_cursor_configuration_from_name(mir_default_cursor_name);
|
||||||
|
_glfw.mir.disabledConf = mir_cursor_configuration_from_name(mir_disabled_cursor_name);
|
||||||
|
|
||||||
_glfw.mir.eventQueue = calloc(1, sizeof(EventQueue));
|
_glfw.mir.eventQueue = calloc(1, sizeof(EventQueue));
|
||||||
_glfwInitEventQueueMir(_glfw.mir.eventQueue);
|
_glfwInitEventQueueMir(_glfw.mir.eventQueue);
|
||||||
|
|
||||||
@@ -207,7 +213,6 @@ int _glfwPlatformInit(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwPollMonitorsMir();
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,6 +220,7 @@ void _glfwPlatformTerminate(void)
|
|||||||
{
|
{
|
||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
_glfwTerminateJoysticksLinux();
|
_glfwTerminateJoysticksLinux();
|
||||||
|
_glfwTerminateThreadLocalStoragePOSIX();
|
||||||
|
|
||||||
_glfwDeleteEventQueueMir(_glfw.mir.eventQueue);
|
_glfwDeleteEventQueueMir(_glfw.mir.eventQueue);
|
||||||
|
|
||||||
@@ -231,7 +237,9 @@ const char* _glfwPlatformGetVersionString(void)
|
|||||||
#else
|
#else
|
||||||
" gettimeofday"
|
" gettimeofday"
|
||||||
#endif
|
#endif
|
||||||
" evdev"
|
#if defined(__linux__)
|
||||||
|
" /dev/js"
|
||||||
|
#endif
|
||||||
#if defined(_GLFW_BUILD_DLL)
|
#if defined(_GLFW_BUILD_DLL)
|
||||||
" shared"
|
" shared"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+47
-70
@@ -1,7 +1,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.3 Mir - www.glfw.org
|
// GLFW 3.3 Mir - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2014-2017 Brandon Schaefer <brandon.schaefer@canonical.com>
|
// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com>
|
||||||
//
|
//
|
||||||
// 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,55 +30,53 @@
|
|||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Poll for changes in the set of connected monitors
|
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||||
//
|
|
||||||
void _glfwPollMonitorsMir(void)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i, found = 0;
|
||||||
MirDisplayConfig* displayConfig =
|
_GLFWmonitor** monitors = NULL;
|
||||||
mir_connection_create_display_configuration(_glfw.mir.connection);
|
MirDisplayConfiguration* displayConfig =
|
||||||
|
mir_connection_create_display_config(_glfw.mir.connection);
|
||||||
|
|
||||||
int numOutputs = mir_display_config_get_num_outputs(displayConfig);
|
*count = 0;
|
||||||
|
|
||||||
for (i = 0; i < numOutputs; i++)
|
for (i = 0; i < displayConfig->num_outputs; i++)
|
||||||
{
|
{
|
||||||
const MirOutput* output = mir_display_config_get_output(displayConfig, i);
|
const MirDisplayOutput* out = displayConfig->outputs + i;
|
||||||
MirOutputConnectionState state = mir_output_get_connection_state(output);
|
|
||||||
bool enabled = mir_output_is_enabled(output);
|
|
||||||
|
|
||||||
if (enabled && state == mir_output_connection_state_connected)
|
if (out->used &&
|
||||||
|
out->connected &&
|
||||||
|
out->num_modes &&
|
||||||
|
out->current_mode < out->num_modes)
|
||||||
{
|
{
|
||||||
int widthMM = mir_output_get_physical_width_mm(output);
|
found++;
|
||||||
int heightMM = mir_output_get_physical_height_mm(output);
|
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found);
|
||||||
int x = mir_output_get_position_x(output);
|
monitors[i] = _glfwAllocMonitor("Unknown",
|
||||||
int y = mir_output_get_position_y(output);
|
out->physical_width_mm,
|
||||||
int id = mir_output_get_id(output);
|
out->physical_height_mm);
|
||||||
size_t currentMode = mir_output_get_current_mode_index(output);
|
|
||||||
const char* name = mir_output_type_name(mir_output_get_type(output));
|
|
||||||
|
|
||||||
_GLFWmonitor* monitor = _glfwAllocMonitor(name,
|
monitors[i]->mir.x = out->position_x;
|
||||||
widthMM,
|
monitors[i]->mir.y = out->position_y;
|
||||||
heightMM);
|
monitors[i]->mir.outputId = out->output_id;
|
||||||
monitor->mir.x = x;
|
monitors[i]->mir.curMode = out->current_mode;
|
||||||
monitor->mir.y = y;
|
|
||||||
monitor->mir.outputId = id;
|
|
||||||
monitor->mir.curMode = currentMode;
|
|
||||||
monitor->modes = _glfwPlatformGetVideoModes(monitor, &monitor->modeCount);
|
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
monitors[i]->modes = _glfwPlatformGetVideoModes(monitors[i],
|
||||||
|
&monitors[i]->modeCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mir_display_config_release(displayConfig);
|
mir_display_config_destroy(displayConfig);
|
||||||
|
|
||||||
|
*count = found;
|
||||||
|
return monitors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
||||||
//////////////////////////////////////////////////////////////////////////
|
{
|
||||||
////// GLFW platform API //////
|
return first->mir.outputId == second->mir.outputId;
|
||||||
//////////////////////////////////////////////////////////////////////////
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
@@ -88,7 +86,7 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
|||||||
*ypos = monitor->mir.y;
|
*ypos = monitor->mir.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FillInRGBBitsFromPixelFormat(GLFWvidmode* mode, const MirPixelFormat pf)
|
void FillInRGBBitsFromPixelFormat(GLFWvidmode* mode, const MirPixelFormat pf)
|
||||||
{
|
{
|
||||||
switch (pf)
|
switch (pf)
|
||||||
{
|
{
|
||||||
@@ -125,52 +123,30 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
GLFWvidmode* modes = NULL;
|
GLFWvidmode* modes = NULL;
|
||||||
MirDisplayConfig* displayConfig =
|
MirDisplayConfiguration* displayConfig =
|
||||||
mir_connection_create_display_configuration(_glfw.mir.connection);
|
mir_connection_create_display_config(_glfw.mir.connection);
|
||||||
|
|
||||||
int numOutputs = mir_display_config_get_num_outputs(displayConfig);
|
for (i = 0; i < displayConfig->num_outputs; i++)
|
||||||
|
|
||||||
for (i = 0; i < numOutputs; i++)
|
|
||||||
{
|
{
|
||||||
const MirOutput* output = mir_display_config_get_output(displayConfig, i);
|
const MirDisplayOutput* out = displayConfig->outputs + i;
|
||||||
int id = mir_output_get_id(output);
|
if (out->output_id != monitor->mir.outputId)
|
||||||
|
|
||||||
if (id != monitor->mir.outputId)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MirOutputConnectionState state = mir_output_get_connection_state(output);
|
modes = calloc(out->num_modes, sizeof(GLFWvidmode));
|
||||||
bool enabled = mir_output_is_enabled(output);
|
|
||||||
|
|
||||||
// We must have been disconnected
|
for (*found = 0; *found < out->num_modes; (*found)++)
|
||||||
if (!enabled || state != mir_output_connection_state_connected)
|
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
modes[*found].width = out->modes[*found].horizontal_resolution;
|
||||||
"Mir: Monitor no longer connected");
|
modes[*found].height = out->modes[*found].vertical_resolution;
|
||||||
return NULL;
|
modes[*found].refreshRate = out->modes[*found].refresh_rate;
|
||||||
}
|
|
||||||
|
|
||||||
int numModes = mir_output_get_num_modes(output);
|
FillInRGBBitsFromPixelFormat(&modes[*found], out->output_formats[*found]);
|
||||||
modes = calloc(numModes, sizeof(GLFWvidmode));
|
|
||||||
|
|
||||||
for (*found = 0; *found < numModes; (*found)++)
|
|
||||||
{
|
|
||||||
const MirOutputMode* mode = mir_output_get_mode(output, *found);
|
|
||||||
int width = mir_output_mode_get_width(mode);
|
|
||||||
int height = mir_output_mode_get_height(mode);
|
|
||||||
double refreshRate = mir_output_mode_get_refresh_rate(mode);
|
|
||||||
MirPixelFormat currentFormat = mir_output_get_current_pixel_format(output);
|
|
||||||
|
|
||||||
modes[*found].width = width;
|
|
||||||
modes[*found].height = height;
|
|
||||||
modes[*found].refreshRate = refreshRate;
|
|
||||||
|
|
||||||
FillInRGBBitsFromPixelFormat(&modes[*found], currentFormat);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mir_display_config_release(displayConfig);
|
mir_display_config_destroy(displayConfig);
|
||||||
|
|
||||||
return modes;
|
return modes;
|
||||||
}
|
}
|
||||||
@@ -203,3 +179,4 @@ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* handle)
|
|||||||
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
_GLFW_REQUIRE_INIT_OR_RETURN(0);
|
||||||
return monitor->mir.outputId;
|
return monitor->mir.outputId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-17
@@ -1,7 +1,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.3 Mir - www.glfw.org
|
// GLFW 3.3 Mir - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2014-2017 Brandon Schaefer <brandon.schaefer@canonical.com>
|
// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com>
|
||||||
//
|
//
|
||||||
// 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
|
||||||
@@ -24,38 +24,40 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_mir_platform_h_
|
||||||
|
#define _glfw3_mir_platform_h_
|
||||||
|
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#include <mir_toolkit/mir_client_library.h>
|
#include <mir_toolkit/mir_client_library.h>
|
||||||
|
|
||||||
typedef VkFlags VkMirWindowCreateFlagsKHR;
|
typedef VkFlags VkMirSurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
typedef struct VkMirWindowCreateInfoKHR
|
typedef struct VkMirSurfaceCreateInfoKHR
|
||||||
{
|
{
|
||||||
VkStructureType sType;
|
VkStructureType sType;
|
||||||
const void* pNext;
|
const void* pNext;
|
||||||
VkMirWindowCreateFlagsKHR flags;
|
VkMirSurfaceCreateFlagsKHR flags;
|
||||||
MirConnection* connection;
|
MirConnection* connection;
|
||||||
MirWindow* mirWindow;
|
MirSurface* mirSurface;
|
||||||
} VkMirWindowCreateInfoKHR;
|
} VkMirSurfaceCreateInfoKHR;
|
||||||
|
|
||||||
typedef VkResult (APIENTRY *PFN_vkCreateMirWindowKHR)(VkInstance,const VkMirWindowCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
typedef VkResult (APIENTRY *PFN_vkCreateMirSurfaceKHR)(VkInstance,const VkMirSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice,uint32_t,MirConnection*);
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(VkPhysicalDevice,uint32_t,MirConnection*);
|
||||||
|
|
||||||
#include "posix_thread.h"
|
#include "posix_tls.h"
|
||||||
#include "posix_time.h"
|
#include "posix_time.h"
|
||||||
#include "linux_joystick.h"
|
#include "linux_joystick.h"
|
||||||
#include "xkb_unicode.h"
|
#include "xkb_unicode.h"
|
||||||
#include "egl_context.h"
|
#include "egl_context.h"
|
||||||
#include "osmesa_context.h"
|
|
||||||
|
|
||||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||||
#define _glfw_dlclose(handle) dlclose(handle)
|
#define _glfw_dlclose(handle) dlclose(handle)
|
||||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
|
|
||||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->mir.nativeWindow)
|
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->mir.window)
|
||||||
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display)
|
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.mir.display)
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowMir mir
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowMir mir
|
||||||
@@ -78,10 +80,10 @@ typedef struct EventQueue
|
|||||||
//
|
//
|
||||||
typedef struct _GLFWwindowMir
|
typedef struct _GLFWwindowMir
|
||||||
{
|
{
|
||||||
MirWindow* window;
|
MirSurface* surface;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
MirEGLNativeWindowType nativeWindow;
|
MirEGLNativeWindowType window;
|
||||||
_GLFWcursor* currentCursor;
|
_GLFWcursor* currentCursor;
|
||||||
|
|
||||||
} _GLFWwindowMir;
|
} _GLFWwindowMir;
|
||||||
@@ -103,16 +105,18 @@ typedef struct _GLFWlibraryMir
|
|||||||
{
|
{
|
||||||
MirConnection* connection;
|
MirConnection* connection;
|
||||||
MirEGLNativeDisplayType display;
|
MirEGLNativeDisplayType display;
|
||||||
|
MirCursorConfiguration* defaultConf;
|
||||||
|
MirCursorConfiguration* disabledConf;
|
||||||
EventQueue* eventQueue;
|
EventQueue* eventQueue;
|
||||||
|
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
|
|
||||||
pthread_mutex_t eventMutex;
|
pthread_mutex_t eventMutex;
|
||||||
pthread_cond_t eventCond;
|
pthread_cond_t eventCond;
|
||||||
|
|
||||||
// The window whose disabled cursor mode is active
|
// The window whose disabled cursor mode is active
|
||||||
_GLFWwindow* disabledCursorWindow;
|
_GLFWwindow* disabledCursorWindow;
|
||||||
|
|
||||||
} _GLFWlibraryMir;
|
} _GLFWlibraryMir;
|
||||||
|
|
||||||
@@ -123,11 +127,10 @@ typedef struct _GLFWcursorMir
|
|||||||
{
|
{
|
||||||
MirCursorConfiguration* conf;
|
MirCursorConfiguration* conf;
|
||||||
MirBufferStream* customCursor;
|
MirBufferStream* customCursor;
|
||||||
char const* cursorName; // only needed for system cursors
|
|
||||||
} _GLFWcursorMir;
|
} _GLFWcursorMir;
|
||||||
|
|
||||||
|
|
||||||
extern void _glfwPollMonitorsMir(void);
|
|
||||||
extern void _glfwInitEventQueueMir(EventQueue* queue);
|
extern void _glfwInitEventQueueMir(EventQueue* queue);
|
||||||
extern void _glfwDeleteEventQueueMir(EventQueue* queue);
|
extern void _glfwDeleteEventQueueMir(EventQueue* queue);
|
||||||
|
|
||||||
|
#endif // _glfw3_mir_platform_h_
|
||||||
|
|||||||
+137
-148
@@ -1,7 +1,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.3 Mir - www.glfw.org
|
// GLFW 3.3 Mir - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2014-2017 Brandon Schaefer <brandon.schaefer@canonical.com>
|
// Copyright (c) 2014-2015 Brandon Schaefer <brandon.schaefer@canonical.com>
|
||||||
//
|
//
|
||||||
// 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
|
||||||
@@ -89,6 +89,9 @@ static EventNode* dequeueEvent(EventQueue* queue)
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME Soon to be changed upstream mir! So we can use an egl config to figure out
|
||||||
|
the best pixel format!
|
||||||
|
*/
|
||||||
static MirPixelFormat findValidPixelFormat(void)
|
static MirPixelFormat findValidPixelFormat(void)
|
||||||
{
|
{
|
||||||
unsigned int i, validFormats, mirPixelFormats = 32;
|
unsigned int i, validFormats, mirPixelFormats = 32;
|
||||||
@@ -280,14 +283,14 @@ static void handleEvent(const MirEvent* event, _GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addNewEvent(MirWindow* window, const MirEvent* event, void* context)
|
static void addNewEvent(MirSurface* surface, const MirEvent* event, void* context)
|
||||||
{
|
{
|
||||||
enqueueEvent(event, context);
|
enqueueEvent(event, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLFWbool createWindow(_GLFWwindow* window)
|
static GLFWbool createSurface(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
MirWindowSpec* spec;
|
MirSurfaceSpec* spec;
|
||||||
MirBufferUsage buffer_usage = mir_buffer_usage_hardware;
|
MirBufferUsage buffer_usage = mir_buffer_usage_hardware;
|
||||||
MirPixelFormat pixel_format = findValidPixelFormat();
|
MirPixelFormat pixel_format = findValidPixelFormat();
|
||||||
|
|
||||||
@@ -298,39 +301,40 @@ static GLFWbool createWindow(_GLFWwindow* window)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
spec = mir_create_normal_window_spec(_glfw.mir.connection,
|
spec = mir_connection_create_spec_for_normal_surface(_glfw.mir.connection,
|
||||||
window->mir.width,
|
window->mir.width,
|
||||||
window->mir.height);
|
window->mir.height,
|
||||||
|
pixel_format);
|
||||||
|
|
||||||
mir_window_spec_set_pixel_format(spec, pixel_format);
|
mir_surface_spec_set_buffer_usage(spec, buffer_usage);
|
||||||
mir_window_spec_set_buffer_usage(spec, buffer_usage);
|
mir_surface_spec_set_name(spec, "MirSurface");
|
||||||
|
|
||||||
window->mir.window = mir_create_window_sync(spec);
|
window->mir.surface = mir_surface_create_sync(spec);
|
||||||
mir_window_spec_release(spec);
|
mir_surface_spec_release(spec);
|
||||||
|
|
||||||
if (!mir_window_is_valid(window->mir.window))
|
if (!mir_surface_is_valid(window->mir.surface))
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Mir: Unable to create window: %s",
|
"Mir: Unable to create surface: %s",
|
||||||
mir_window_get_error_message(window->mir.window));
|
mir_surface_get_error_message(window->mir.surface));
|
||||||
|
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mir_window_set_event_handler(window->mir.window, addNewEvent, window);
|
mir_surface_set_event_handler(window->mir.surface, addNewEvent, window);
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setWindowConfinement(_GLFWwindow* window, MirPointerConfinementState state)
|
static void setSurfaceConfinement(_GLFWwindow* window, MirPointerConfinementState state)
|
||||||
{
|
{
|
||||||
MirWindowSpec* spec;
|
MirSurfaceSpec* spec;
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
|
||||||
mir_window_spec_set_pointer_confinement(spec, state);
|
mir_surface_spec_set_pointer_confinement(spec, state);
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
mir_surface_apply_spec(window->mir.surface, spec);
|
||||||
mir_window_spec_release(spec);
|
mir_surface_spec_release(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@@ -377,12 +381,12 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
GLFWvidmode mode;
|
GLFWvidmode mode;
|
||||||
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
||||||
|
|
||||||
mir_window_set_state(window->mir.window, mir_window_state_fullscreen);
|
mir_surface_set_state(window->mir.surface, mir_surface_state_fullscreen);
|
||||||
|
|
||||||
if (wndconfig->width > mode.width || wndconfig->height > mode.height)
|
if (wndconfig->width > mode.width || wndconfig->height > mode.height)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Mir: Requested window size too large: %ix%i",
|
"Mir: Requested surface size too large: %ix%i",
|
||||||
wndconfig->width, wndconfig->height);
|
wndconfig->width, wndconfig->height);
|
||||||
|
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@@ -393,29 +397,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
window->mir.height = wndconfig->height;
|
window->mir.height = wndconfig->height;
|
||||||
window->mir.currentCursor = NULL;
|
window->mir.currentCursor = NULL;
|
||||||
|
|
||||||
if (!createWindow(window))
|
if (!createSurface(window))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
window->mir.nativeWindow = mir_buffer_stream_get_egl_native_window(
|
window->mir.window = mir_buffer_stream_get_egl_native_window(
|
||||||
mir_window_get_buffer_stream(window->mir.window));
|
mir_surface_get_buffer_stream(window->mir.surface));
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
{
|
{
|
||||||
if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||
|
if (!_glfwInitEGL())
|
||||||
ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
return GLFW_FALSE;
|
||||||
{
|
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||||
if (!_glfwInitEGL())
|
return GLFW_FALSE;
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwInitOSMesa())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@@ -426,10 +419,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
if (_glfw.mir.disabledCursorWindow == window)
|
if (_glfw.mir.disabledCursorWindow == window)
|
||||||
_glfw.mir.disabledCursorWindow = NULL;
|
_glfw.mir.disabledCursorWindow = NULL;
|
||||||
|
|
||||||
if (mir_window_is_valid(window->mir.window))
|
if (mir_surface_is_valid(window->mir.surface))
|
||||||
{
|
{
|
||||||
mir_window_release_sync(window->mir.window);
|
mir_surface_release_sync(window->mir.surface);
|
||||||
window->mir.window= NULL;
|
window->mir.surface = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->context.destroy)
|
if (window->context.destroy)
|
||||||
@@ -438,12 +431,14 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||||
{
|
{
|
||||||
MirWindowSpec* spec;
|
MirSurfaceSpec* spec;
|
||||||
|
const char* e_title = title ? title : "";
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
|
||||||
mir_window_spec_set_name(spec, title);
|
mir_surface_spec_set_name(spec, e_title);
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
mir_surface_apply_spec(window->mir.surface, spec);
|
||||||
|
mir_surface_spec_release(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||||
@@ -455,30 +450,22 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
|||||||
|
|
||||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||||
{
|
{
|
||||||
MirWindowSpec* spec;
|
MirSurfaceSpec* spec;
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
|
||||||
mir_window_spec_set_width (spec, width);
|
mir_surface_spec_set_width (spec, width);
|
||||||
mir_window_spec_set_height(spec, height);
|
mir_surface_spec_set_height(spec, height);
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
mir_surface_apply_spec(window->mir.surface, spec);
|
||||||
mir_window_spec_release(spec);
|
mir_surface_spec_release(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||||
int minwidth, int minheight,
|
int minwidth, int minheight,
|
||||||
int maxwidth, int maxheight)
|
int maxwidth, int maxheight)
|
||||||
{
|
{
|
||||||
MirWindowSpec* spec;
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_max_width (spec, maxwidth);
|
|
||||||
mir_window_spec_set_max_height(spec, maxheight);
|
|
||||||
mir_window_spec_set_min_width (spec, minwidth);
|
|
||||||
mir_window_spec_set_min_height(spec, minheight);
|
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
|
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
|
||||||
@@ -517,63 +504,57 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
|||||||
|
|
||||||
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
MirWindowSpec* spec;
|
MirSurfaceSpec* spec;
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
|
||||||
mir_window_spec_set_state(spec, mir_window_state_minimized);
|
mir_surface_spec_set_state(spec, mir_surface_state_minimized);
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
mir_surface_apply_spec(window->mir.surface, spec);
|
||||||
mir_window_spec_release(spec);
|
mir_surface_spec_release(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
MirWindowSpec* spec;
|
MirSurfaceSpec* spec;
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
|
||||||
mir_window_spec_set_state(spec, mir_window_state_restored);
|
mir_surface_spec_set_state(spec, mir_surface_state_restored);
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
mir_surface_apply_spec(window->mir.surface, spec);
|
||||||
mir_window_spec_release(spec);
|
mir_surface_spec_release(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
MirWindowSpec* spec;
|
MirSurfaceSpec* spec;
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
|
||||||
mir_window_spec_set_state(spec, mir_window_state_maximized);
|
mir_surface_spec_set_state(spec, mir_surface_state_maximized);
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
mir_surface_apply_spec(window->mir.surface, spec);
|
||||||
mir_window_spec_release(spec);
|
mir_surface_spec_release(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
MirWindowSpec* spec;
|
MirSurfaceSpec* spec;
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
|
||||||
mir_window_spec_set_state(spec, mir_window_state_hidden);
|
mir_surface_spec_set_state(spec, mir_surface_state_hidden);
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
mir_surface_apply_spec(window->mir.surface, spec);
|
||||||
mir_window_spec_release(spec);
|
mir_surface_spec_release(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
MirWindowSpec* spec;
|
MirSurfaceSpec* spec;
|
||||||
|
|
||||||
spec = mir_create_window_spec(_glfw.mir.connection);
|
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
|
||||||
mir_window_spec_set_state(spec, mir_window_state_restored);
|
mir_surface_spec_set_state(spec, mir_surface_state_restored);
|
||||||
|
|
||||||
mir_window_apply_spec(window->mir.window, spec);
|
mir_surface_apply_spec(window->mir.surface, spec);
|
||||||
mir_window_spec_release(spec);
|
mir_surface_spec_release(spec);
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||||
@@ -594,7 +575,7 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|||||||
|
|
||||||
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return mir_window_get_focus_state(window->mir.window) == mir_window_focus_state_focused;
|
return mir_surface_get_focus(window->mir.surface) == mir_surface_focused;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
||||||
@@ -606,12 +587,12 @@ int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
|||||||
|
|
||||||
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return mir_window_get_visibility(window->mir.window) == mir_window_visibility_exposed;
|
return mir_surface_get_visibility(window->mir.surface) == mir_surface_visibility_exposed;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
return mir_window_get_state(window->mir.window) == mir_window_state_maximized;
|
return mir_surface_get_state(window->mir.surface) == mir_surface_state_maximized;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
@@ -647,7 +628,7 @@ void _glfwPlatformWaitEvents(void)
|
|||||||
{
|
{
|
||||||
pthread_mutex_lock(&_glfw.mir.eventMutex);
|
pthread_mutex_lock(&_glfw.mir.eventMutex);
|
||||||
|
|
||||||
while (emptyEventQueue(_glfw.mir.eventQueue))
|
if (emptyEventQueue(_glfw.mir.eventQueue))
|
||||||
pthread_cond_wait(&_glfw.mir.eventCond, &_glfw.mir.eventMutex);
|
pthread_cond_wait(&_glfw.mir.eventCond, &_glfw.mir.eventMutex);
|
||||||
|
|
||||||
pthread_mutex_unlock(&_glfw.mir.eventMutex);
|
pthread_mutex_unlock(&_glfw.mir.eventMutex);
|
||||||
@@ -690,40 +671,54 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
|||||||
int xhot, int yhot)
|
int xhot, int yhot)
|
||||||
{
|
{
|
||||||
MirBufferStream* stream;
|
MirBufferStream* stream;
|
||||||
|
MirPixelFormat pixel_format = findValidPixelFormat();
|
||||||
|
|
||||||
int i_w = image->width;
|
int i_w = image->width;
|
||||||
int i_h = image->height;
|
int i_h = image->height;
|
||||||
|
|
||||||
|
if (pixel_format == mir_pixel_format_invalid)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Mir: Unable to find a correct pixel format");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
stream = mir_connection_create_buffer_stream_sync(_glfw.mir.connection,
|
stream = mir_connection_create_buffer_stream_sync(_glfw.mir.connection,
|
||||||
i_w, i_h,
|
i_w, i_h,
|
||||||
mir_pixel_format_argb_8888,
|
pixel_format,
|
||||||
mir_buffer_usage_software);
|
mir_buffer_usage_software);
|
||||||
|
|
||||||
cursor->mir.conf = mir_cursor_configuration_from_buffer_stream(stream, xhot, yhot);
|
cursor->mir.conf = mir_cursor_configuration_from_buffer_stream(stream, xhot, yhot);
|
||||||
|
|
||||||
|
char* dest;
|
||||||
|
unsigned char *pixels;
|
||||||
|
int i, r_stride, bytes_per_pixel, bytes_per_row;
|
||||||
|
|
||||||
MirGraphicsRegion region;
|
MirGraphicsRegion region;
|
||||||
mir_buffer_stream_get_graphics_region(stream, ®ion);
|
mir_buffer_stream_get_graphics_region(stream, ®ion);
|
||||||
|
|
||||||
unsigned char* pixels = image->pixels;
|
// FIXME Figure this out based on the current_pf
|
||||||
char* dest = region.vaddr;
|
bytes_per_pixel = 4;
|
||||||
int i;
|
bytes_per_row = bytes_per_pixel * i_w;
|
||||||
|
|
||||||
for (i = 0; i < i_w * i_h; i++, pixels += 4)
|
dest = region.vaddr;
|
||||||
|
pixels = image->pixels;
|
||||||
|
|
||||||
|
r_stride = region.stride;
|
||||||
|
|
||||||
|
for (i = 0; i < i_h; i++)
|
||||||
{
|
{
|
||||||
unsigned int alpha = pixels[3];
|
memcpy(dest, pixels, bytes_per_row);
|
||||||
*dest++ = (char)(pixels[2] * alpha / 255);
|
dest += r_stride;
|
||||||
*dest++ = (char)(pixels[1] * alpha / 255);
|
pixels += r_stride;
|
||||||
*dest++ = (char)(pixels[0] * alpha / 255);
|
|
||||||
*dest++ = (char)alpha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mir_buffer_stream_swap_buffers_sync(stream);
|
|
||||||
cursor->mir.customCursor = stream;
|
cursor->mir.customCursor = stream;
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* getSystemCursorName(int shape)
|
const char* getSystemCursorName(int shape)
|
||||||
{
|
{
|
||||||
switch (shape)
|
switch (shape)
|
||||||
{
|
{
|
||||||
@@ -746,11 +741,17 @@ static const char* getSystemCursorName(int shape)
|
|||||||
|
|
||||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||||
{
|
{
|
||||||
cursor->mir.conf = NULL;
|
const char* cursor_name = getSystemCursorName(shape);
|
||||||
cursor->mir.customCursor = NULL;
|
|
||||||
cursor->mir.cursorName = getSystemCursorName(shape);
|
|
||||||
|
|
||||||
return cursor->mir.cursorName != NULL;
|
if (cursor_name)
|
||||||
|
{
|
||||||
|
cursor->mir.conf = mir_cursor_configuration_from_name(cursor_name);
|
||||||
|
cursor->mir.customCursor = NULL;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||||
@@ -761,32 +762,21 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
|||||||
mir_buffer_stream_release_sync(cursor->mir.customCursor);
|
mir_buffer_stream_release_sync(cursor->mir.customCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setCursorNameForWindow(MirWindow* window, char const* name)
|
|
||||||
{
|
|
||||||
MirWindowSpec* spec = mir_create_window_spec(_glfw.mir.connection);
|
|
||||||
mir_window_spec_set_cursor_name(spec, name);
|
|
||||||
mir_window_apply_spec(window, spec);
|
|
||||||
mir_window_spec_release(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||||
{
|
{
|
||||||
if (cursor)
|
if (cursor && cursor->mir.conf)
|
||||||
{
|
{
|
||||||
window->mir.currentCursor = cursor;
|
window->mir.currentCursor = cursor;
|
||||||
|
|
||||||
if (cursor->mir.cursorName)
|
mir_wait_for(mir_surface_configure_cursor(window->mir.surface, cursor->mir.conf));
|
||||||
|
if (cursor->mir.customCursor)
|
||||||
{
|
{
|
||||||
setCursorNameForWindow(window->mir.window, cursor->mir.cursorName);
|
mir_buffer_stream_swap_buffers_sync(cursor->mir.customCursor);
|
||||||
}
|
|
||||||
else if (cursor->mir.conf)
|
|
||||||
{
|
|
||||||
mir_window_configure_cursor(window->mir.window, cursor->mir.conf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setCursorNameForWindow(window->mir.window, mir_default_cursor_name);
|
mir_wait_for(mir_surface_configure_cursor(window->mir.surface, _glfw.mir.defaultConf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -807,8 +797,8 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
if (mode == GLFW_CURSOR_DISABLED)
|
if (mode == GLFW_CURSOR_DISABLED)
|
||||||
{
|
{
|
||||||
_glfw.mir.disabledCursorWindow = window;
|
_glfw.mir.disabledCursorWindow = window;
|
||||||
setWindowConfinement(window, mir_pointer_confined_to_window);
|
setSurfaceConfinement(window, mir_pointer_confined_to_surface);
|
||||||
setCursorNameForWindow(window->mir.window, mir_disabled_cursor_name);
|
mir_wait_for(mir_surface_configure_cursor(window->mir.surface, _glfw.mir.disabledConf));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -816,7 +806,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
if (_glfw.mir.disabledCursorWindow == window)
|
if (_glfw.mir.disabledCursorWindow == window)
|
||||||
{
|
{
|
||||||
_glfw.mir.disabledCursorWindow = NULL;
|
_glfw.mir.disabledCursorWindow = NULL;
|
||||||
setWindowConfinement(window, mir_pointer_unconfined);
|
setSurfaceConfinement(window, mir_pointer_unconfined);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_NORMAL)
|
if (window->cursorMode == GLFW_CURSOR_NORMAL)
|
||||||
@@ -825,12 +815,12 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
}
|
}
|
||||||
else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
else if (window->cursorMode == GLFW_CURSOR_HIDDEN)
|
||||||
{
|
{
|
||||||
setCursorNameForWindow(window->mir.window, mir_disabled_cursor_name);
|
mir_wait_for(mir_surface_configure_cursor(window->mir.surface, _glfw.mir.disabledConf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetKeyName(int key, int scancode)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
||||||
@@ -869,8 +859,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|||||||
VkPhysicalDevice device,
|
VkPhysicalDevice device,
|
||||||
uint32_t queuefamily)
|
uint32_t queuefamily)
|
||||||
{
|
{
|
||||||
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
|
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR =
|
||||||
vkGetPhysicalDeviceMirPresentationSupportKHR =
|
|
||||||
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
|
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
|
||||||
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
|
||||||
if (!vkGetPhysicalDeviceMirPresentationSupportKHR)
|
if (!vkGetPhysicalDeviceMirPresentationSupportKHR)
|
||||||
@@ -891,12 +880,12 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
|||||||
VkSurfaceKHR* surface)
|
VkSurfaceKHR* surface)
|
||||||
{
|
{
|
||||||
VkResult err;
|
VkResult err;
|
||||||
VkMirWindowCreateInfoKHR sci;
|
VkMirSurfaceCreateInfoKHR sci;
|
||||||
PFN_vkCreateMirWindowKHR vkCreateMirWindowKHR;
|
PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR;
|
||||||
|
|
||||||
vkCreateMirWindowKHR = (PFN_vkCreateMirWindowKHR)
|
vkCreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR)
|
||||||
vkGetInstanceProcAddr(instance, "vkCreateMirWindowKHR");
|
vkGetInstanceProcAddr(instance, "vkCreateMirSurfaceKHR");
|
||||||
if (!vkCreateMirWindowKHR)
|
if (!vkCreateMirSurfaceKHR)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
"Mir: Vulkan instance missing VK_KHR_mir_surface extension");
|
"Mir: Vulkan instance missing VK_KHR_mir_surface extension");
|
||||||
@@ -906,9 +895,9 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
|||||||
memset(&sci, 0, sizeof(sci));
|
memset(&sci, 0, sizeof(sci));
|
||||||
sci.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
|
sci.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
|
||||||
sci.connection = _glfw.mir.connection;
|
sci.connection = _glfw.mir.connection;
|
||||||
sci.mirWindow = window->mir.window;
|
sci.mirSurface = window->mir.surface;
|
||||||
|
|
||||||
err = vkCreateMirWindowKHR(instance, &sci, allocator, surface);
|
err = vkCreateMirSurfaceKHR(instance, &sci, allocator, surface);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@@ -930,10 +919,10 @@ GLFWAPI MirConnection* glfwGetMirDisplay(void)
|
|||||||
return _glfw.mir.connection;
|
return _glfw.mir.connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI MirWindow* glfwGetMirWindow(GLFWwindow* handle)
|
GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* handle)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
return window->mir.window;
|
return window->mir.surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+74
-36
@@ -86,49 +86,83 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
|
|||||||
////// GLFW event API //////
|
////// GLFW event API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
|
void _glfwInputMonitorChange(void)
|
||||||
{
|
{
|
||||||
if (action == GLFW_CONNECTED)
|
int i, j, monitorCount = _glfw.monitorCount;
|
||||||
{
|
_GLFWmonitor** monitors = _glfw.monitors;
|
||||||
_glfw.monitorCount++;
|
|
||||||
_glfw.monitors =
|
|
||||||
realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount);
|
|
||||||
|
|
||||||
if (placement == _GLFW_INSERT_FIRST)
|
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
|
||||||
{
|
|
||||||
memmove(_glfw.monitors + 1,
|
|
||||||
_glfw.monitors,
|
|
||||||
(_glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
|
|
||||||
_glfw.monitors[0] = monitor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_glfw.monitors[_glfw.monitorCount - 1] = monitor;
|
|
||||||
}
|
|
||||||
else if (action == GLFW_DISCONNECTED)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < _glfw.monitorCount; i++)
|
// Re-use still connected monitor objects
|
||||||
|
|
||||||
|
for (i = 0; i < _glfw.monitorCount; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < monitorCount; j++)
|
||||||
{
|
{
|
||||||
if (_glfw.monitors[i] == monitor)
|
if (_glfwPlatformIsSameMonitor(_glfw.monitors[i], monitors[j]))
|
||||||
{
|
{
|
||||||
_glfw.monitorCount--;
|
_glfwFreeMonitor(_glfw.monitors[i]);
|
||||||
memmove(_glfw.monitors + i,
|
_glfw.monitors[i] = monitors[j];
|
||||||
_glfw.monitors + i + 1,
|
|
||||||
(_glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.callbacks.monitor)
|
// Find and report disconnected monitors (not in the new list)
|
||||||
_glfw.callbacks.monitor((GLFWmonitor*) monitor, action);
|
|
||||||
|
|
||||||
if (action == GLFW_DISCONNECTED)
|
for (i = 0; i < monitorCount; i++)
|
||||||
_glfwFreeMonitor(monitor);
|
{
|
||||||
|
_GLFWwindow* window;
|
||||||
|
|
||||||
|
for (j = 0; j < _glfw.monitorCount; j++)
|
||||||
|
{
|
||||||
|
if (monitors[i] == _glfw.monitors[j])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j < _glfw.monitorCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (window = _glfw.windowListHead; window; window = window->next)
|
||||||
|
{
|
||||||
|
if (window->monitor == monitors[i])
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||||
|
_glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_glfw.callbacks.monitor)
|
||||||
|
_glfw.callbacks.monitor((GLFWmonitor*) monitors[i], GLFW_DISCONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find and report newly connected monitors (not in the old list)
|
||||||
|
// Re-used monitor objects are then removed from the old list to avoid
|
||||||
|
// having them destroyed at the end of this function
|
||||||
|
|
||||||
|
for (i = 0; i < _glfw.monitorCount; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < monitorCount; j++)
|
||||||
|
{
|
||||||
|
if (_glfw.monitors[i] == monitors[j])
|
||||||
|
{
|
||||||
|
monitors[j] = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j < monitorCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (_glfw.callbacks.monitor)
|
||||||
|
_glfw.callbacks.monitor((GLFWmonitor*) _glfw.monitors[i], GLFW_CONNECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwFreeMonitors(monitors, monitorCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
|
void _glfwInputMonitorWindowChange(_GLFWmonitor* monitor, _GLFWwindow* window)
|
||||||
{
|
{
|
||||||
monitor->window = window;
|
monitor->window = window;
|
||||||
}
|
}
|
||||||
@@ -180,6 +214,16 @@ void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
|
|||||||
memset(ramp, 0, sizeof(GLFWgammaramp));
|
memset(ramp, 0, sizeof(GLFWgammaramp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwFreeMonitors(_GLFWmonitor** monitors, int count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
_glfwFreeMonitor(monitors[i]);
|
||||||
|
|
||||||
|
free(monitors);
|
||||||
|
}
|
||||||
|
|
||||||
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
|
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
|
||||||
const GLFWvidmode* desired)
|
const GLFWvidmode* desired)
|
||||||
{
|
{
|
||||||
@@ -262,7 +306,6 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)
|
|||||||
GLFWAPI GLFWmonitor** glfwGetMonitors(int* count)
|
GLFWAPI GLFWmonitor** glfwGetMonitors(int* count)
|
||||||
{
|
{
|
||||||
assert(count != NULL);
|
assert(count != NULL);
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
@@ -363,10 +406,6 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
|||||||
int i;
|
int i;
|
||||||
unsigned short values[256];
|
unsigned short values[256];
|
||||||
GLFWgammaramp ramp;
|
GLFWgammaramp ramp;
|
||||||
assert(handle != NULL);
|
|
||||||
assert(gamma == gamma);
|
|
||||||
assert(gamma >= 0.f);
|
|
||||||
assert(gamma <= FLT_MAX);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
@@ -418,7 +457,6 @@ 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->size > 0);
|
|
||||||
assert(ramp->red != NULL);
|
assert(ramp->red != NULL);
|
||||||
assert(ramp->green != NULL);
|
assert(ramp->green != NULL);
|
||||||
assert(ramp->blue != NULL);
|
assert(ramp->blue != NULL);
|
||||||
|
|||||||
@@ -24,6 +24,9 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_nsgl_context_h_
|
||||||
|
#define _glfw3_nsgl_context_h_
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
|
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
|
||||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
|
||||||
|
|
||||||
@@ -54,3 +57,4 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
||||||
|
|
||||||
|
#endif // _glfw3_nsgl_context_h_
|
||||||
|
|||||||
+29
-49
@@ -34,7 +34,7 @@ static void makeContextCurrentNSGL(_GLFWwindow* window)
|
|||||||
else
|
else
|
||||||
[NSOpenGLContext clearCurrentContext];
|
[NSOpenGLContext clearCurrentContext];
|
||||||
|
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
_glfwPlatformSetCurrentContext(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void swapBuffersNSGL(_GLFWwindow* window)
|
static void swapBuffersNSGL(_GLFWwindow* window)
|
||||||
@@ -45,7 +45,7 @@ static void swapBuffersNSGL(_GLFWwindow* window)
|
|||||||
|
|
||||||
static void swapIntervalNSGL(int interval)
|
static void swapIntervalNSGL(int interval)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||||
|
|
||||||
GLint sync = interval;
|
GLint sync = interval;
|
||||||
[window->context.nsgl.object setValues:&sync
|
[window->context.nsgl.object setValues:&sync
|
||||||
@@ -119,6 +119,8 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
|
unsigned int attributeCount = 0;
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
@@ -143,59 +145,37 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context robustness modes (GL_KHR_robustness) are not yet supported by
|
// Context robustness modes (GL_KHR_robustness) are not yet supported on
|
||||||
// macOS but are not a hard constraint, so ignore and continue
|
// macOS but are not a hard constraint, so ignore and continue
|
||||||
|
|
||||||
// Context release behaviors (GL_KHR_context_flush_control) are not yet
|
// Context release behaviors (GL_KHR_context_flush_control) are not yet
|
||||||
// supported by macOS but are not a hard constraint, so ignore and continue
|
// supported on macOS but are not a hard constraint, so ignore and continue
|
||||||
|
|
||||||
// Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not
|
#define ADD_ATTR(x) { attributes[attributeCount++] = x; }
|
||||||
// a hard constraint, so ignore and continue
|
#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); }
|
||||||
|
|
||||||
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
|
// Arbitrary array size here
|
||||||
// are not a hard constraint, so ignore and continue
|
NSOpenGLPixelFormatAttribute attributes[40];
|
||||||
|
|
||||||
#define addAttrib(a) \
|
ADD_ATTR(NSOpenGLPFAAccelerated);
|
||||||
{ \
|
ADD_ATTR(NSOpenGLPFAClosestPolicy);
|
||||||
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
|
||||||
attribs[index++] = a; \
|
|
||||||
}
|
|
||||||
#define setAttrib(a, v) { addAttrib(a); addAttrib(v); }
|
|
||||||
|
|
||||||
NSOpenGLPixelFormatAttribute attribs[40];
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
addAttrib(NSOpenGLPFAAccelerated);
|
|
||||||
addAttrib(NSOpenGLPFAClosestPolicy);
|
|
||||||
|
|
||||||
if (ctxconfig->nsgl.offline)
|
|
||||||
{
|
|
||||||
addAttrib(NSOpenGLPFAAllowOfflineRenderers);
|
|
||||||
// NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
|
|
||||||
// Info.plist for unbundled applications
|
|
||||||
// HACK: This assumes that NSOpenGLPixelFormat will remain
|
|
||||||
// a straightforward wrapper of its CGL counterpart
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 100800
|
|
||||||
addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching);
|
|
||||||
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
||||||
if (ctxconfig->major >= 4)
|
if (ctxconfig->major >= 4)
|
||||||
{
|
{
|
||||||
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
|
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
||||||
if (ctxconfig->major >= 3)
|
if (ctxconfig->major >= 3)
|
||||||
{
|
{
|
||||||
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxconfig->major <= 2)
|
if (ctxconfig->major <= 2)
|
||||||
{
|
{
|
||||||
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
|
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
|
||||||
setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
|
ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
|
||||||
|
|
||||||
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
|
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
|
||||||
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
|
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
|
||||||
@@ -207,7 +187,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
fbconfig->accumBlueBits +
|
fbconfig->accumBlueBits +
|
||||||
fbconfig->accumAlphaBits;
|
fbconfig->accumAlphaBits;
|
||||||
|
|
||||||
setAttrib(NSOpenGLPFAAccumSize, accumBits);
|
ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,17 +205,17 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
else if (colorBits < 15)
|
else if (colorBits < 15)
|
||||||
colorBits = 15;
|
colorBits = 15;
|
||||||
|
|
||||||
setAttrib(NSOpenGLPFAColorSize, colorBits);
|
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fbconfig->alphaBits != GLFW_DONT_CARE)
|
if (fbconfig->alphaBits != GLFW_DONT_CARE)
|
||||||
setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
|
ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
|
||||||
|
|
||||||
if (fbconfig->depthBits != GLFW_DONT_CARE)
|
if (fbconfig->depthBits != GLFW_DONT_CARE)
|
||||||
setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits);
|
ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits);
|
||||||
|
|
||||||
if (fbconfig->stencilBits != GLFW_DONT_CARE)
|
if (fbconfig->stencilBits != GLFW_DONT_CARE)
|
||||||
setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
|
ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
|
||||||
|
|
||||||
if (fbconfig->stereo)
|
if (fbconfig->stereo)
|
||||||
{
|
{
|
||||||
@@ -244,36 +224,36 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
"NSGL: Stereo rendering is deprecated");
|
"NSGL: Stereo rendering is deprecated");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
#else
|
#else
|
||||||
addAttrib(NSOpenGLPFAStereo);
|
ADD_ATTR(NSOpenGLPFAStereo);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fbconfig->doublebuffer)
|
if (fbconfig->doublebuffer)
|
||||||
addAttrib(NSOpenGLPFADoubleBuffer);
|
ADD_ATTR(NSOpenGLPFADoubleBuffer);
|
||||||
|
|
||||||
if (fbconfig->samples != GLFW_DONT_CARE)
|
if (fbconfig->samples != GLFW_DONT_CARE)
|
||||||
{
|
{
|
||||||
if (fbconfig->samples == 0)
|
if (fbconfig->samples == 0)
|
||||||
{
|
{
|
||||||
setAttrib(NSOpenGLPFASampleBuffers, 0);
|
ADD_ATTR2(NSOpenGLPFASampleBuffers, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setAttrib(NSOpenGLPFASampleBuffers, 1);
|
ADD_ATTR2(NSOpenGLPFASampleBuffers, 1);
|
||||||
setAttrib(NSOpenGLPFASamples, fbconfig->samples);
|
ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
|
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
|
||||||
// framebuffer, so there's no need (and no way) to request it
|
// framebuffer, so there's no need (and no way) to request it
|
||||||
|
|
||||||
addAttrib(0);
|
ADD_ATTR(0);
|
||||||
|
|
||||||
#undef addAttrib
|
#undef ADD_ATTR
|
||||||
#undef setAttrib
|
#undef ADD_ATTR2
|
||||||
|
|
||||||
window->context.nsgl.pixelFormat =
|
window->context.nsgl.pixelFormat =
|
||||||
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
|
[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
|
||||||
if (window->context.nsgl.pixelFormat == nil)
|
if (window->context.nsgl.pixelFormat == nil)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_JOYSTICK_STATE int nulljs
|
|
||||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs
|
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_MAPPING_NAME ""
|
|
||||||
|
|
||||||
+16
-19
@@ -36,26 +36,25 @@ static void makeContextCurrentOSMesa(_GLFWwindow* window)
|
|||||||
{
|
{
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
int width, height;
|
|
||||||
_glfwPlatformGetFramebufferSize(window, &width, &height);
|
|
||||||
|
|
||||||
// Check to see if we need to allocate a new buffer
|
// Check to see if we need to allocate a new buffer
|
||||||
if ((window->context.osmesa.buffer == NULL) ||
|
if ((window->context.osmesa.buffer == NULL) ||
|
||||||
(width != window->context.osmesa.width) ||
|
(window->osmesa.width != window->context.osmesa.width) ||
|
||||||
(height != window->context.osmesa.height))
|
(window->osmesa.height != window->context.osmesa.height))
|
||||||
{
|
{
|
||||||
free(window->context.osmesa.buffer);
|
free(window->context.osmesa.buffer);
|
||||||
|
|
||||||
// Allocate the new buffer (width * height * 8-bit RGBA)
|
// Allocate the new buffer (width * height * 8-bit RGBA)
|
||||||
window->context.osmesa.buffer = calloc(4, width * height);
|
window->context.osmesa.buffer =
|
||||||
window->context.osmesa.width = width;
|
calloc(4, window->osmesa.width * window->osmesa.height);
|
||||||
window->context.osmesa.height = height;
|
|
||||||
|
window->context.osmesa.width = window->osmesa.width;
|
||||||
|
window->context.osmesa.height = window->osmesa.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!OSMesaMakeCurrent(window->context.osmesa.handle,
|
if (!OSMesaMakeCurrent(window->context.osmesa.handle,
|
||||||
window->context.osmesa.buffer,
|
window->context.osmesa.buffer,
|
||||||
GL_UNSIGNED_BYTE,
|
GL_UNSIGNED_BYTE,
|
||||||
width, height))
|
window->osmesa.width, window->osmesa.height))
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"OSMesa: Failed to make context current");
|
"OSMesa: Failed to make context current");
|
||||||
@@ -63,7 +62,7 @@ static void makeContextCurrentOSMesa(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
_glfwPlatformSetCurrentContext(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLFWglproc getProcAddressOSMesa(const char* procname)
|
static GLFWglproc getProcAddressOSMesa(const char* procname)
|
||||||
@@ -113,9 +112,7 @@ GLFWbool _glfwInitOSMesa(void)
|
|||||||
int i;
|
int i;
|
||||||
const char* sonames[] =
|
const char* sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_OSMESA_LIBRARY)
|
#if defined(_WIN32)
|
||||||
_GLFW_OSMESA_LIBRARY,
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
"libOSMesa.dll",
|
"libOSMesa.dll",
|
||||||
"OSMesa.dll",
|
"OSMesa.dll",
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
@@ -186,11 +183,11 @@ void _glfwTerminateOSMesa(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define setAttrib(a, v) \
|
#define setAttrib(attribName, attribValue) \
|
||||||
{ \
|
{ \
|
||||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
attribs[index++] = attribName; \
|
||||||
attribs[index++] = a; \
|
attribs[index++] = attribValue; \
|
||||||
attribs[index++] = v; \
|
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||||
|
|||||||
+10
-6
@@ -25,6 +25,9 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_osmesa_context_h_
|
||||||
|
#define _glfw3_osmesa_context_h_
|
||||||
|
|
||||||
#define OSMESA_RGBA 0x1908
|
#define OSMESA_RGBA 0x1908
|
||||||
#define OSMESA_FORMAT 0x22
|
#define OSMESA_FORMAT 0x22
|
||||||
#define OSMESA_DEPTH_BITS 0x30
|
#define OSMESA_DEPTH_BITS 0x30
|
||||||
@@ -54,18 +57,18 @@ typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*);
|
|||||||
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
|
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
|
||||||
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
|
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
|
||||||
|
|
||||||
#define _GLFW_OSMESA_CONTEXT_STATE _GLFWcontextOSMesa osmesa
|
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextOSMesa osmesa
|
||||||
#define _GLFW_OSMESA_LIBRARY_CONTEXT_STATE _GLFWlibraryOSMesa osmesa
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryOSMesa osmesa
|
||||||
|
|
||||||
|
|
||||||
// OSMesa-specific per-context data
|
// OSMesa-specific per-context data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWcontextOSMesa
|
typedef struct _GLFWcontextOSMesa
|
||||||
{
|
{
|
||||||
OSMesaContext handle;
|
OSMesaContext handle;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
void* buffer;
|
void* buffer;
|
||||||
|
|
||||||
} _GLFWcontextOSMesa;
|
} _GLFWcontextOSMesa;
|
||||||
|
|
||||||
@@ -92,3 +95,4 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
|
||||||
|
#endif // _glfw3_osmesa_context_h_
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.3 - www.glfw.org
|
// GLFW 3.3 OSMesa - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2016 Google Inc.
|
// Copyright (c) 2016 Google Inc.
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||||
@@ -34,6 +34,9 @@
|
|||||||
|
|
||||||
int _glfwPlatformInit(void)
|
int _glfwPlatformInit(void)
|
||||||
{
|
{
|
||||||
|
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
_glfwInitTimerPOSIX();
|
_glfwInitTimerPOSIX();
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
@@ -41,10 +44,11 @@ int _glfwPlatformInit(void)
|
|||||||
void _glfwPlatformTerminate(void)
|
void _glfwPlatformTerminate(void)
|
||||||
{
|
{
|
||||||
_glfwTerminateOSMesa();
|
_glfwTerminateOSMesa();
|
||||||
|
_glfwTerminateThreadLocalStoragePOSIX();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetVersionString(void)
|
const char* _glfwPlatformGetVersionString(void)
|
||||||
{
|
{
|
||||||
return _GLFW_VERSION_NUMBER " null OSMesa";
|
return _GLFW_VERSION_NUMBER " none OSMesa";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.3 - www.glfw.org
|
// GLFW 3.3 OSMesa - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2016 Google Inc.
|
// Copyright (c) 2016 Google Inc.
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||||
@@ -32,6 +32,18 @@
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||||
|
{
|
||||||
|
// OSMesa is headless, so no monitors
|
||||||
|
*count = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.3 - www.glfw.org
|
// GLFW 3.3 OSMesa - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2016 Google Inc.
|
// Copyright (c) 2016 Google Inc.
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||||
@@ -25,22 +25,23 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_osmesa_platform_h_
|
||||||
|
#define _glfw3_osmesa_platform_h_
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowNull null
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowOSMesa osmesa
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE
|
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE
|
#define _GLFW_PLATFORM_MONITOR_STATE
|
||||||
#define _GLFW_PLATFORM_CURSOR_STATE
|
#define _GLFW_PLATFORM_CURSOR_STATE
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE
|
||||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
|
||||||
#define _GLFW_EGL_CONTEXT_STATE
|
#define _GLFW_EGL_CONTEXT_STATE
|
||||||
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE
|
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE
|
||||||
|
|
||||||
#include "osmesa_context.h"
|
#include "osmesa_context.h"
|
||||||
#include "posix_time.h"
|
#include "posix_time.h"
|
||||||
#include "posix_thread.h"
|
#include "posix_tls.h"
|
||||||
#include "null_joystick.h"
|
|
||||||
|
|
||||||
#if defined(_GLFW_WIN32)
|
#if defined(_GLFW_WIN32)
|
||||||
#define _glfw_dlopen(name) LoadLibraryA(name)
|
#define _glfw_dlopen(name) LoadLibraryA(name)
|
||||||
@@ -52,11 +53,13 @@
|
|||||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Null-specific per-window data
|
// OSMesa-specific per-window data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWwindowNull
|
typedef struct _GLFWwindowOSMesa
|
||||||
{
|
{
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
} _GLFWwindowNull;
|
} _GLFWwindowOSMesa;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // _glfw3_osmesa_platform_h_
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.3 - www.glfw.org
|
// GLFW 3.3 OSMesa - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Copyright (c) 2016 Google Inc.
|
// Copyright (c) 2016 Google Inc.
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||||
@@ -31,8 +31,8 @@
|
|||||||
static int createNativeWindow(_GLFWwindow* window,
|
static int createNativeWindow(_GLFWwindow* window,
|
||||||
const _GLFWwndconfig* wndconfig)
|
const _GLFWwndconfig* wndconfig)
|
||||||
{
|
{
|
||||||
window->null.width = wndconfig->width;
|
window->osmesa.width = wndconfig->width;
|
||||||
window->null.height = wndconfig->height;
|
window->osmesa.height = wndconfig->height;
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
@@ -52,8 +52,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
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)
|
||||||
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
{
|
||||||
if (!_glfwInitOSMesa())
|
if (!_glfwInitOSMesa())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@@ -62,7 +61,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available");
|
_glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: EGL not available");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,15 +103,15 @@ void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
|||||||
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
||||||
{
|
{
|
||||||
if (width)
|
if (width)
|
||||||
*width = window->null.width;
|
*width = window->osmesa.width;
|
||||||
if (height)
|
if (height)
|
||||||
*height = window->null.height;
|
*height = window->osmesa.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||||
{
|
{
|
||||||
window->null.width = width;
|
window->osmesa.width = width;
|
||||||
window->null.height = height;
|
window->osmesa.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||||
@@ -128,15 +127,19 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d)
|
|||||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
||||||
{
|
{
|
||||||
if (width)
|
if (width)
|
||||||
*width = window->null.width;
|
*width = window->osmesa.width;
|
||||||
if (height)
|
if (height)
|
||||||
*height = window->null.height;
|
*height = window->osmesa.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||||
int* left, int* top,
|
int* left, int* top,
|
||||||
int* right, int* bottom)
|
int* right, int* bottom)
|
||||||
{
|
{
|
||||||
|
if (right)
|
||||||
|
*right = window->osmesa.width;
|
||||||
|
if (bottom)
|
||||||
|
*top = window->osmesa.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
||||||
@@ -172,11 +175,6 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
|
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -232,6 +230,10 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||||
const GLFWimage* image,
|
const GLFWimage* image,
|
||||||
int xhot, int yhot)
|
int xhot, int yhot)
|
||||||
@@ -261,7 +263,7 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetKeyName(int key, int scancode)
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -271,6 +273,26 @@ int _glfwPlatformGetKeyScancode(int key)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformJoystickPresent(int joy)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float* _glfwPlatformGetJoystickAxes(int joy, int* count)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetJoystickName(int joy)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
//========================================================================
|
|
||||||
// GLFW 3.3 POSIX - www.glfw.org
|
|
||||||
//------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied
|
|
||||||
// warranty. In no event will the authors be held liable for any damages
|
|
||||||
// arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it
|
|
||||||
// freely, subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
// claim that you wrote the original software. If you use this software
|
|
||||||
// in a product, an acknowledgment in the product documentation would
|
|
||||||
// be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such, and must not
|
|
||||||
// be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source
|
|
||||||
// distribution.
|
|
||||||
//
|
|
||||||
//========================================================================
|
|
||||||
|
|
||||||
#include "internal.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
////// GLFW platform API //////
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
|
|
||||||
{
|
|
||||||
assert(tls->posix.allocated == GLFW_FALSE);
|
|
||||||
|
|
||||||
if (pthread_key_create(&tls->posix.key, NULL) != 0)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"POSIX: Failed to create context TLS");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
tls->posix.allocated = GLFW_TRUE;
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
|
||||||
{
|
|
||||||
if (tls->posix.allocated)
|
|
||||||
pthread_key_delete(tls->posix.key);
|
|
||||||
memset(tls, 0, sizeof(_GLFWtls));
|
|
||||||
}
|
|
||||||
|
|
||||||
void* _glfwPlatformGetTls(_GLFWtls* tls)
|
|
||||||
{
|
|
||||||
assert(tls->posix.allocated == GLFW_TRUE);
|
|
||||||
return pthread_getspecific(tls->posix.key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
|
|
||||||
{
|
|
||||||
assert(tls->posix.allocated == GLFW_TRUE);
|
|
||||||
pthread_setspecific(tls->posix.key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
assert(mutex->posix.allocated == GLFW_FALSE);
|
|
||||||
|
|
||||||
if (pthread_mutex_init(&mutex->posix.handle, NULL) != 0)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR, "POSIX: Failed to create mutex");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mutex->posix.allocated = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
if (mutex->posix.allocated)
|
|
||||||
pthread_mutex_destroy(&mutex->posix.handle);
|
|
||||||
memset(mutex, 0, sizeof(_GLFWmutex));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
assert(mutex->posix.allocated == GLFW_TRUE);
|
|
||||||
pthread_mutex_lock(&mutex->posix.handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
assert(mutex->posix.allocated == GLFW_TRUE);
|
|
||||||
pthread_mutex_unlock(&mutex->posix.handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
+6
-6
@@ -44,14 +44,14 @@ void _glfwInitTimerPOSIX(void)
|
|||||||
|
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||||
{
|
{
|
||||||
_glfw.timer.posix.monotonic = GLFW_TRUE;
|
_glfw.posix_time.monotonic = GLFW_TRUE;
|
||||||
_glfw.timer.posix.frequency = 1000000000;
|
_glfw.posix_time.frequency = 1000000000;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
_glfw.timer.posix.monotonic = GLFW_FALSE;
|
_glfw.posix_time.monotonic = GLFW_FALSE;
|
||||||
_glfw.timer.posix.frequency = 1000000;
|
_glfw.posix_time.frequency = 1000000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ void _glfwInitTimerPOSIX(void)
|
|||||||
uint64_t _glfwPlatformGetTimerValue(void)
|
uint64_t _glfwPlatformGetTimerValue(void)
|
||||||
{
|
{
|
||||||
#if defined(CLOCK_MONOTONIC)
|
#if defined(CLOCK_MONOTONIC)
|
||||||
if (_glfw.timer.posix.monotonic)
|
if (_glfw.posix_time.monotonic)
|
||||||
{
|
{
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
@@ -80,6 +80,6 @@ uint64_t _glfwPlatformGetTimerValue(void)
|
|||||||
|
|
||||||
uint64_t _glfwPlatformGetTimerFrequency(void)
|
uint64_t _glfwPlatformGetTimerFrequency(void)
|
||||||
{
|
{
|
||||||
return _glfw.timer.posix.frequency;
|
return _glfw.posix_time.frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -25,20 +25,24 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix
|
#ifndef _glfw3_posix_time_h_
|
||||||
|
#define _glfw3_posix_time_h_
|
||||||
|
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimePOSIX posix_time
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
// POSIX-specific global timer data
|
// POSIX-specific global timer data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWtimerPOSIX
|
typedef struct _GLFWtimePOSIX
|
||||||
{
|
{
|
||||||
GLFWbool monotonic;
|
GLFWbool monotonic;
|
||||||
uint64_t frequency;
|
uint64_t frequency;
|
||||||
|
|
||||||
} _GLFWtimerPOSIX;
|
} _GLFWtimePOSIX;
|
||||||
|
|
||||||
|
|
||||||
void _glfwInitTimerPOSIX(void);
|
void _glfwInitTimerPOSIX(void);
|
||||||
|
|
||||||
|
#endif // _glfw3_posix_time_h_
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.3 - www.glfw.org
|
// GLFW 3.3 POSIX - www.glfw.org
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
// Copyright (c) 2006-2016 Camilla Löwy <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
|
||||||
@@ -27,16 +28,41 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWbool _glfwInitThreadLocalStoragePOSIX(void)
|
||||||
|
{
|
||||||
|
if (pthread_key_create(&_glfw.posix_tls.context, NULL) != 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"POSIX: Failed to create context TLS");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.posix_tls.allocated = GLFW_TRUE;
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwTerminateThreadLocalStoragePOSIX(void)
|
||||||
|
{
|
||||||
|
if (_glfw.posix_tls.allocated)
|
||||||
|
pthread_key_delete(_glfw.posix_tls.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
void _glfwPlatformSetCurrentContext(_GLFWwindow* context)
|
||||||
{
|
{
|
||||||
return GLFW_FALSE;
|
pthread_setspecific(_glfw.posix_tls.context, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
|
||||||
{
|
{
|
||||||
|
return pthread_getspecific(_glfw.posix_tls.context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,27 +25,25 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_posix_tls_h_
|
||||||
|
#define _glfw3_posix_tls_h_
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsPOSIX posix
|
#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsPOSIX posix_tls
|
||||||
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexPOSIX posix
|
|
||||||
|
|
||||||
|
|
||||||
// POSIX-specific thread local storage data
|
// POSIX-specific global TLS data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWtlsPOSIX
|
typedef struct _GLFWtlsPOSIX
|
||||||
{
|
{
|
||||||
GLFWbool allocated;
|
GLFWbool allocated;
|
||||||
pthread_key_t key;
|
pthread_key_t context;
|
||||||
|
|
||||||
} _GLFWtlsPOSIX;
|
} _GLFWtlsPOSIX;
|
||||||
|
|
||||||
// POSIX-specific mutex data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWmutexPOSIX
|
|
||||||
{
|
|
||||||
GLFWbool allocated;
|
|
||||||
pthread_mutex_t handle;
|
|
||||||
|
|
||||||
} _GLFWmutexPOSIX;
|
GLFWbool _glfwInitThreadLocalStoragePOSIX(void);
|
||||||
|
void _glfwTerminateThreadLocalStoragePOSIX(void);
|
||||||
|
|
||||||
|
#endif // _glfw3_posix_tls_h_
|
||||||
+15
-19
@@ -49,12 +49,11 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
|
|
||||||
#if !defined(_GLFW_VULKAN_STATIC)
|
#if !defined(_GLFW_VULKAN_STATIC)
|
||||||
#if defined(_GLFW_VULKAN_LIBRARY)
|
#if defined(_GLFW_WIN32)
|
||||||
_glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY);
|
|
||||||
#elif defined(_GLFW_WIN32)
|
|
||||||
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
|
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
_glfw.vk.handle = _glfw_dlopen("libMoltenVK.dylib");
|
// NULL maps to RTLD_DEFAULT, which searches all loaded binaries
|
||||||
|
_glfw.vk.handle = _glfw_dlopen(NULL);
|
||||||
#else
|
#else
|
||||||
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
|
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
|
||||||
#endif
|
#endif
|
||||||
@@ -70,8 +69,16 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
||||||
if (!_glfw.vk.GetInstanceProcAddr)
|
if (!_glfw.vk.GetInstanceProcAddr)
|
||||||
{
|
{
|
||||||
|
#if defined(_GLFW_COCOA)
|
||||||
|
if (mode == _GLFW_REQUIRE_LOADER)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
|
"Vulkan: vkGetInstanceProcAddr not found in process");
|
||||||
|
}
|
||||||
|
#else
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||||
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
||||||
|
#endif
|
||||||
|
|
||||||
_glfwTerminateVulkan();
|
_glfwTerminateVulkan();
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@@ -92,13 +99,9 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
// NOTE: This happens on systems with a loader but without any Vulkan ICD
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
if (mode == _GLFW_REQUIRE_LOADER)
|
"Vulkan: Failed to query instance extension count: %s",
|
||||||
{
|
_glfwGetVulkanResultString(err));
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
|
||||||
"Vulkan: Failed to query instance extension count: %s",
|
|
||||||
_glfwGetVulkanResultString(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwTerminateVulkan();
|
_glfwTerminateVulkan();
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
@@ -109,7 +112,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
|
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Vulkan: Failed to query instance extensions: %s",
|
"Vulkan: Failed to query instance extensions: %s",
|
||||||
_glfwGetVulkanResultString(err));
|
_glfwGetVulkanResultString(err));
|
||||||
|
|
||||||
@@ -227,8 +230,6 @@ GLFWAPI int glfwVulkanSupported(void)
|
|||||||
|
|
||||||
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
|
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
|
||||||
{
|
{
|
||||||
assert(count != NULL);
|
|
||||||
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
@@ -247,7 +248,6 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
|
|||||||
const char* procname)
|
const char* procname)
|
||||||
{
|
{
|
||||||
GLFWvkproc proc;
|
GLFWvkproc proc;
|
||||||
assert(procname != NULL);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
@@ -273,9 +273,6 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|||||||
VkPhysicalDevice device,
|
VkPhysicalDevice device,
|
||||||
uint32_t queuefamily)
|
uint32_t queuefamily)
|
||||||
{
|
{
|
||||||
assert(instance != VK_NULL_HANDLE);
|
|
||||||
assert(device != VK_NULL_HANDLE);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||||
|
|
||||||
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
||||||
@@ -299,7 +296,6 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
|
|||||||
VkSurfaceKHR* surface)
|
VkSurfaceKHR* surface)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
assert(instance != VK_NULL_HANDLE);
|
|
||||||
assert(window != NULL);
|
assert(window != NULL);
|
||||||
assert(surface != NULL);
|
assert(surface != NULL);
|
||||||
|
|
||||||
|
|||||||
+62
-90
@@ -44,8 +44,9 @@ static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib
|
|||||||
pixelFormat,
|
pixelFormat,
|
||||||
0, 1, &attrib, &value))
|
0, 1, &attrib, &value))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"WGL: Failed to retrieve pixel format attribute");
|
"WGL: Failed to retrieve pixel format attribute %i",
|
||||||
|
attrib);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,9 +55,7 @@ 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 int choosePixelFormat(_GLFWwindow* window,
|
static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* desired)
|
||||||
const _GLFWctxconfig* ctxconfig,
|
|
||||||
const _GLFWfbconfig* fbconfig)
|
|
||||||
{
|
{
|
||||||
_GLFWfbconfig* usableConfigs;
|
_GLFWfbconfig* usableConfigs;
|
||||||
const _GLFWfbconfig* closest;
|
const _GLFWfbconfig* closest;
|
||||||
@@ -129,25 +128,11 @@ static int choosePixelFormat(_GLFWwindow* window,
|
|||||||
if (_glfw.wgl.ARB_multisample)
|
if (_glfw.wgl.ARB_multisample)
|
||||||
u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB);
|
u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB);
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
if (_glfw.wgl.ARB_framebuffer_sRGB ||
|
||||||
|
_glfw.wgl.EXT_framebuffer_sRGB)
|
||||||
{
|
{
|
||||||
if (_glfw.wgl.ARB_framebuffer_sRGB ||
|
if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
|
||||||
_glfw.wgl.EXT_framebuffer_sRGB)
|
u->sRGB = GLFW_TRUE;
|
||||||
{
|
|
||||||
if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
|
|
||||||
u->sRGB = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_glfw.wgl.EXT_colorspace)
|
|
||||||
{
|
|
||||||
if (getPixelFormatAttrib(window, n, WGL_COLORSPACE_EXT) ==
|
|
||||||
WGL_COLORSPACE_SRGB_EXT)
|
|
||||||
{
|
|
||||||
u->sRGB = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -213,7 +198,7 @@ static int choosePixelFormat(_GLFWwindow* window,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
|
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
|
||||||
if (!closest)
|
if (!closest)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
@@ -233,15 +218,15 @@ static int choosePixelFormat(_GLFWwindow* window,
|
|||||||
//
|
//
|
||||||
static GLFWbool isCompositionEnabled(void)
|
static GLFWbool isCompositionEnabled(void)
|
||||||
{
|
{
|
||||||
if (_glfw.win32.dwmapi.instance)
|
BOOL enabled;
|
||||||
{
|
|
||||||
BOOL enabled;
|
|
||||||
|
|
||||||
if (DwmIsCompositionEnabled(&enabled) == S_OK)
|
if (!_glfw_DwmIsCompositionEnabled)
|
||||||
return enabled;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void makeContextCurrentWGL(_GLFWwindow* window)
|
static void makeContextCurrentWGL(_GLFWwindow* window)
|
||||||
@@ -249,23 +234,23 @@ static void makeContextCurrentWGL(_GLFWwindow* window)
|
|||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
|
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
_glfwPlatformSetCurrentContext(window);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"WGL: Failed to make context current");
|
"WGL: Failed to make context current");
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
|
_glfwPlatformSetCurrentContext(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!wglMakeCurrent(NULL, NULL))
|
if (!wglMakeCurrent(NULL, NULL))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"WGL: Failed to clear current context");
|
"WGL: Failed to clear current context");
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
|
_glfwPlatformSetCurrentContext(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +261,7 @@ static void swapBuffersWGL(_GLFWwindow* window)
|
|||||||
{
|
{
|
||||||
int count = abs(window->context.wgl.interval);
|
int count = abs(window->context.wgl.interval);
|
||||||
while (count--)
|
while (count--)
|
||||||
DwmFlush();
|
_glfw_DwmFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapBuffers(window->context.wgl.dc);
|
SwapBuffers(window->context.wgl.dc);
|
||||||
@@ -284,7 +269,7 @@ static void swapBuffersWGL(_GLFWwindow* window)
|
|||||||
|
|
||||||
static void swapIntervalWGL(int interval)
|
static void swapIntervalWGL(int interval)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||||
|
|
||||||
window->context.wgl.interval = interval;
|
window->context.wgl.interval = interval;
|
||||||
|
|
||||||
@@ -368,24 +353,25 @@ static void loadWGLExtensions(void)
|
|||||||
|
|
||||||
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
|
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"WGL: Failed to set pixel format for dummy context");
|
"WGL: Failed to set pixel format for dummy context");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = wglCreateContext(dc);
|
rc = wglCreateContext(dc);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"WGL: Failed to create dummy context");
|
"WGL: Failed to create dummy context");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wglMakeCurrent(dc, rc))
|
if (!wglMakeCurrent(dc, rc))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"WGL: Failed to make dummy context current");
|
|
||||||
wglDeleteContext(rc);
|
wglDeleteContext(rc);
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"WGL: Failed to make dummy context current");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,12 +404,8 @@ static void loadWGLExtensions(void)
|
|||||||
extensionSupportedWGL("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 =
|
||||||
extensionSupportedWGL("WGL_ARB_create_context_robustness");
|
extensionSupportedWGL("WGL_ARB_create_context_robustness");
|
||||||
_glfw.wgl.ARB_create_context_no_error =
|
|
||||||
extensionSupportedWGL("WGL_ARB_create_context_no_error");
|
|
||||||
_glfw.wgl.EXT_swap_control =
|
_glfw.wgl.EXT_swap_control =
|
||||||
extensionSupportedWGL("WGL_EXT_swap_control");
|
extensionSupportedWGL("WGL_EXT_swap_control");
|
||||||
_glfw.wgl.EXT_colorspace =
|
|
||||||
extensionSupportedWGL("WGL_EXT_colorspace");
|
|
||||||
_glfw.wgl.ARB_pixel_format =
|
_glfw.wgl.ARB_pixel_format =
|
||||||
extensionSupportedWGL("WGL_ARB_pixel_format");
|
extensionSupportedWGL("WGL_ARB_pixel_format");
|
||||||
_glfw.wgl.ARB_context_flush_control =
|
_glfw.wgl.ARB_context_flush_control =
|
||||||
@@ -448,8 +430,7 @@ GLFWbool _glfwInitWGL(void)
|
|||||||
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
|
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
|
||||||
if (!_glfw.wgl.instance)
|
if (!_glfw.wgl.instance)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to load opengl32.dll");
|
||||||
"WGL: Failed to load opengl32.dll");
|
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,11 +458,11 @@ void _glfwTerminateWGL(void)
|
|||||||
FreeLibrary(_glfw.wgl.instance);
|
FreeLibrary(_glfw.wgl.instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define setAttrib(a, v) \
|
#define setWGLattrib(attribName, attribValue) \
|
||||||
{ \
|
{ \
|
||||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
attribs[index++] = attribName; \
|
||||||
attribs[index++] = a; \
|
attribs[index++] = attribValue; \
|
||||||
attribs[index++] = v; \
|
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the OpenGL or OpenGL ES context
|
// Create the OpenGL or OpenGL ES context
|
||||||
@@ -509,22 +490,22 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig);
|
pixelFormat = choosePixelFormat(window, fbconfig);
|
||||||
if (!pixelFormat)
|
if (!pixelFormat)
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||||
pixelFormat, sizeof(pfd), &pfd))
|
pixelFormat, sizeof(pfd), &pfd))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"WGL: Failed to retrieve PFD for selected pixel format");
|
"WGL: Failed to retrieve PFD for selected pixel format");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
|
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"WGL: Failed to set selected pixel format");
|
"WGL: Failed to set selected pixel format");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,6 +562,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
|
|
||||||
if (ctxconfig->debug)
|
if (ctxconfig->debug)
|
||||||
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
||||||
|
if (ctxconfig->noerror)
|
||||||
|
flags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;
|
||||||
|
|
||||||
if (ctxconfig->robustness)
|
if (ctxconfig->robustness)
|
||||||
{
|
{
|
||||||
@@ -588,13 +571,13 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||||
{
|
{
|
||||||
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
WGL_NO_RESET_NOTIFICATION_ARB);
|
WGL_NO_RESET_NOTIFICATION_ARB);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||||
{
|
{
|
||||||
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||||
WGL_LOSE_CONTEXT_ON_RESET_ARB);
|
WGL_LOSE_CONTEXT_ON_RESET_ARB);
|
||||||
}
|
}
|
||||||
|
|
||||||
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
||||||
@@ -607,39 +590,33 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||||
{
|
{
|
||||||
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
||||||
}
|
}
|
||||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||||
{
|
{
|
||||||
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||||
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxconfig->noerror)
|
|
||||||
{
|
|
||||||
if (_glfw.wgl.ARB_create_context_no_error)
|
|
||||||
setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Only request an explicitly versioned context when necessary, as
|
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||||
// explicitly requesting version 1.0 does not always return the
|
// explicitly requesting version 1.0 does not always return the
|
||||||
// highest version supported by the driver
|
// highest version supported by the driver
|
||||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||||
{
|
{
|
||||||
setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
setWGLattrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
||||||
setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
setWGLattrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags)
|
if (flags)
|
||||||
setAttrib(WGL_CONTEXT_FLAGS_ARB, flags);
|
setWGLattrib(WGL_CONTEXT_FLAGS_ARB, flags);
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
|
setWGLattrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
|
||||||
|
|
||||||
setAttrib(0, 0);
|
setWGLattrib(0, 0);
|
||||||
|
|
||||||
window->context.wgl.handle =
|
window->context.wgl.handle =
|
||||||
_glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,
|
_glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,
|
||||||
@@ -670,11 +647,6 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
"WGL: Driver does not support the requested OpenGL profile");
|
"WGL: Driver does not support the requested OpenGL profile");
|
||||||
}
|
}
|
||||||
else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB))
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_INVALID_VALUE,
|
|
||||||
"WGL: The share context is not compatible with the requested context");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||||
@@ -697,8 +669,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
|
window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
|
||||||
if (!window->context.wgl.handle)
|
if (!window->context.wgl.handle)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
|
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||||
"WGL: Failed to create OpenGL context");
|
"WGL: Failed to create OpenGL context");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -706,8 +678,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (!wglShareLists(share, window->context.wgl.handle))
|
if (!wglShareLists(share, window->context.wgl.handle))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"WGL: Failed to enable sharing with specified OpenGL context");
|
"WGL: Failed to enable sharing with specified OpenGL context");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -723,7 +695,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef setAttrib
|
#undef setWGLattrib
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
+5
-6
@@ -25,6 +25,10 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_wgl_context_h_
|
||||||
|
#define _glfw3_wgl_context_h_
|
||||||
|
|
||||||
|
|
||||||
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
|
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
|
||||||
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
||||||
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
|
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
|
||||||
@@ -68,13 +72,9 @@
|
|||||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
|
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
|
||||||
#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 WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
|
|
||||||
#define WGL_COLORSPACE_EXT 0x309d
|
|
||||||
#define WGL_COLORSPACE_SRGB_EXT 0x3089
|
|
||||||
|
|
||||||
#define ERROR_INVALID_VERSION_ARB 0x2095
|
#define ERROR_INVALID_VERSION_ARB 0x2095
|
||||||
#define ERROR_INVALID_PROFILE_ARB 0x2096
|
#define ERROR_INVALID_PROFILE_ARB 0x2096
|
||||||
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
|
|
||||||
|
|
||||||
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*);
|
||||||
@@ -135,7 +135,6 @@ typedef struct _GLFWlibraryWGL
|
|||||||
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
|
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
|
||||||
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
||||||
GLFWbool EXT_swap_control;
|
GLFWbool EXT_swap_control;
|
||||||
GLFWbool EXT_colorspace;
|
|
||||||
GLFWbool ARB_multisample;
|
GLFWbool ARB_multisample;
|
||||||
GLFWbool ARB_framebuffer_sRGB;
|
GLFWbool ARB_framebuffer_sRGB;
|
||||||
GLFWbool EXT_framebuffer_sRGB;
|
GLFWbool EXT_framebuffer_sRGB;
|
||||||
@@ -144,7 +143,6 @@ typedef struct _GLFWlibraryWGL
|
|||||||
GLFWbool ARB_create_context_profile;
|
GLFWbool ARB_create_context_profile;
|
||||||
GLFWbool EXT_create_context_es2_profile;
|
GLFWbool EXT_create_context_es2_profile;
|
||||||
GLFWbool ARB_create_context_robustness;
|
GLFWbool ARB_create_context_robustness;
|
||||||
GLFWbool ARB_create_context_no_error;
|
|
||||||
GLFWbool ARB_context_flush_control;
|
GLFWbool ARB_context_flush_control;
|
||||||
|
|
||||||
} _GLFWlibraryWGL;
|
} _GLFWlibraryWGL;
|
||||||
@@ -156,3 +154,4 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
|
|
||||||
|
#endif // _glfw3_wgl_context_h_
|
||||||
|
|||||||
+28
-118
@@ -30,10 +30,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
static const GUID _glfw_GUID_DEVINTERFACE_HID =
|
#include <initguid.h>
|
||||||
{0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
|
DEFINE_GUID(GUID_DEVINTERFACE_HID,0x4d1e55b2,0xf16f,0x11cf,0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30);
|
||||||
|
|
||||||
#define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID
|
|
||||||
|
|
||||||
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
|
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
|
||||||
|
|
||||||
@@ -69,19 +67,17 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");
|
_glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");
|
||||||
if (!_glfw.win32.winmm.instance)
|
if (!_glfw.win32.winmm.instance)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to load winmm.dll");
|
||||||
"Win32: Failed to load winmm.dll");
|
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.win32.winmm.GetTime = (PFN_timeGetTime)
|
_glfw.win32.winmm.timeGetTime = (PFN_timeGetTime)
|
||||||
GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime");
|
GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime");
|
||||||
|
|
||||||
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
|
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
|
||||||
if (!_glfw.win32.user32.instance)
|
if (!_glfw.win32.user32.instance)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to load user32.dll");
|
||||||
"Win32: Failed to load user32.dll");
|
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +89,7 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
||||||
if (_glfw.win32.dinput8.instance)
|
if (_glfw.win32.dinput8.instance)
|
||||||
{
|
{
|
||||||
_glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
|
_glfw.win32.dinput8.DirectInput8Create = (PFN_DirectInput8Create)
|
||||||
GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create");
|
GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,9 +110,9 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfw.win32.xinput.instance = LoadLibraryA(names[i]);
|
_glfw.win32.xinput.instance = LoadLibraryA(names[i]);
|
||||||
if (_glfw.win32.xinput.instance)
|
if (_glfw.win32.xinput.instance)
|
||||||
{
|
{
|
||||||
_glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
|
_glfw.win32.xinput.XInputGetCapabilities = (PFN_XInputGetCapabilities)
|
||||||
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");
|
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");
|
||||||
_glfw.win32.xinput.GetState = (PFN_XInputGetState)
|
_glfw.win32.xinput.XInputGetState = (PFN_XInputGetState)
|
||||||
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");
|
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -127,9 +123,9 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
|
_glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
|
||||||
if (_glfw.win32.dwmapi.instance)
|
if (_glfw.win32.dwmapi.instance)
|
||||||
{
|
{
|
||||||
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
|
_glfw.win32.dwmapi.DwmIsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
|
||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
||||||
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
|
_glfw.win32.dwmapi.DwmFlush = (PFN_DwmFlush)
|
||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,16 +307,16 @@ static HWND createHelperWindow(void)
|
|||||||
MSG msg;
|
MSG msg;
|
||||||
HWND window = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
|
HWND window = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
|
||||||
_GLFW_WNDCLASSNAME,
|
_GLFW_WNDCLASSNAME,
|
||||||
L"GLFW message window",
|
L"GLFW helper window",
|
||||||
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
||||||
0, 0, 1, 1,
|
0, 0, 1, 1,
|
||||||
NULL, NULL,
|
HWND_MESSAGE, NULL,
|
||||||
GetModuleHandleW(NULL),
|
GetModuleHandleW(NULL),
|
||||||
NULL);
|
NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to create helper window");
|
"Win32: Failed to create helper window");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,22 +356,16 @@ static HWND createHelperWindow(void)
|
|||||||
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
|
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
|
||||||
{
|
{
|
||||||
WCHAR* target;
|
WCHAR* target;
|
||||||
int count;
|
int length;
|
||||||
|
|
||||||
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
|
length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
|
||||||
if (!count)
|
if (!length)
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to convert string from UTF-8");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
target = calloc(count, sizeof(WCHAR));
|
target = calloc(length, sizeof(WCHAR));
|
||||||
|
|
||||||
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
|
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, length))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to convert string from UTF-8");
|
|
||||||
free(target);
|
free(target);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -388,22 +378,16 @@ WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
|
|||||||
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
||||||
{
|
{
|
||||||
char* target;
|
char* target;
|
||||||
int size;
|
int length;
|
||||||
|
|
||||||
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
|
length = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
|
||||||
if (!size)
|
if (!length)
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to convert string to UTF-8");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
target = calloc(size, 1);
|
target = calloc(length, 1);
|
||||||
|
|
||||||
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
|
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to convert string to UTF-8");
|
|
||||||
free(target);
|
free(target);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -411,81 +395,6 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reports the specified error, appending information about the last Win32 error
|
|
||||||
//
|
|
||||||
void _glfwInputErrorWin32(int error, const char* description)
|
|
||||||
{
|
|
||||||
WCHAR buffer[_GLFW_MESSAGE_SIZE] = L"";
|
|
||||||
char message[_GLFW_MESSAGE_SIZE] = "";
|
|
||||||
|
|
||||||
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
|
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS |
|
|
||||||
FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
|
||||||
NULL,
|
|
||||||
GetLastError() & 0xffff,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
buffer,
|
|
||||||
sizeof(buffer),
|
|
||||||
NULL);
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL);
|
|
||||||
|
|
||||||
_glfwInputError(error, "%s: %s", description, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Updates key names according to the current keyboard layout
|
|
||||||
//
|
|
||||||
void _glfwUpdateKeyNamesWin32(void)
|
|
||||||
{
|
|
||||||
int key;
|
|
||||||
BYTE state[256] = {0};
|
|
||||||
|
|
||||||
memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
|
|
||||||
|
|
||||||
for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++)
|
|
||||||
{
|
|
||||||
UINT vk;
|
|
||||||
int scancode, length;
|
|
||||||
WCHAR chars[16];
|
|
||||||
|
|
||||||
scancode = _glfw.win32.scancodes[key];
|
|
||||||
if (scancode == -1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
|
|
||||||
{
|
|
||||||
const UINT vks[] = {
|
|
||||||
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
|
|
||||||
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
|
|
||||||
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
|
|
||||||
VK_MULTIPLY, VK_SUBTRACT, VK_ADD
|
|
||||||
};
|
|
||||||
|
|
||||||
vk = vks[key - GLFW_KEY_KP_0];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
|
|
||||||
|
|
||||||
length = ToUnicode(vk, scancode, state,
|
|
||||||
chars, sizeof(chars) / sizeof(WCHAR),
|
|
||||||
0);
|
|
||||||
|
|
||||||
if (length == -1)
|
|
||||||
{
|
|
||||||
length = ToUnicode(vk, scancode, state,
|
|
||||||
chars, sizeof(chars) / sizeof(WCHAR),
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length < 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
|
|
||||||
_glfw.win32.keynames[key],
|
|
||||||
sizeof(_glfw.win32.keynames[key]),
|
|
||||||
NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@@ -493,6 +402,9 @@ void _glfwUpdateKeyNamesWin32(void)
|
|||||||
|
|
||||||
int _glfwPlatformInit(void)
|
int _glfwPlatformInit(void)
|
||||||
{
|
{
|
||||||
|
if (!_glfwInitThreadLocalStorageWin32())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
// To make SetForegroundWindow work as we want, we need to fiddle
|
// To make SetForegroundWindow work as we want, we need to fiddle
|
||||||
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
|
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
|
||||||
// as possible in the hope of still being the foreground process)
|
// as possible in the hope of still being the foreground process)
|
||||||
@@ -505,7 +417,6 @@ int _glfwPlatformInit(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
createKeyTables();
|
createKeyTables();
|
||||||
_glfwUpdateKeyNamesWin32();
|
|
||||||
|
|
||||||
if (_glfw_SetProcessDpiAwareness)
|
if (_glfw_SetProcessDpiAwareness)
|
||||||
_glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
_glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||||
@@ -522,7 +433,6 @@ int _glfwPlatformInit(void)
|
|||||||
_glfwInitTimerWin32();
|
_glfwInitTimerWin32();
|
||||||
_glfwInitJoysticksWin32();
|
_glfwInitJoysticksWin32();
|
||||||
|
|
||||||
_glfwPollMonitorsWin32();
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,12 +449,12 @@ void _glfwPlatformTerminate(void)
|
|||||||
SPIF_SENDCHANGE);
|
SPIF_SENDCHANGE);
|
||||||
|
|
||||||
free(_glfw.win32.clipboardString);
|
free(_glfw.win32.clipboardString);
|
||||||
free(_glfw.win32.rawInput);
|
|
||||||
|
|
||||||
_glfwTerminateWGL();
|
_glfwTerminateWGL();
|
||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
|
|
||||||
_glfwTerminateJoysticksWin32();
|
_glfwTerminateJoysticksWin32();
|
||||||
|
_glfwTerminateThreadLocalStorageWin32();
|
||||||
|
|
||||||
freeLibraries();
|
freeLibraries();
|
||||||
}
|
}
|
||||||
|
|||||||
+296
-285
@@ -1,5 +1,5 @@
|
|||||||
//========================================================================
|
//========================================================================
|
||||||
// GLFW 3.3 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-2016 Camilla Löwy <elmindreda@glfw.org>
|
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||||
@@ -27,9 +27,13 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <initguid.h>
|
||||||
|
|
||||||
|
#define _GLFW_PRESENCE_ONLY 1
|
||||||
|
#define _GLFW_UPDATE_STATE 2
|
||||||
|
|
||||||
#define _GLFW_TYPE_AXIS 0
|
#define _GLFW_TYPE_AXIS 0
|
||||||
#define _GLFW_TYPE_SLIDER 1
|
#define _GLFW_TYPE_SLIDER 1
|
||||||
#define _GLFW_TYPE_BUTTON 2
|
#define _GLFW_TYPE_BUTTON 2
|
||||||
@@ -48,39 +52,18 @@ typedef struct _GLFWobjenumWin32
|
|||||||
int povCount;
|
int povCount;
|
||||||
} _GLFWobjenumWin32;
|
} _GLFWobjenumWin32;
|
||||||
|
|
||||||
// Define local copies of the necessary GUIDs
|
// Define only the necessary GUIDs (it's bad enough that we're exporting these)
|
||||||
//
|
//
|
||||||
static const GUID _glfw_IID_IDirectInput8W =
|
DEFINE_GUID(IID_IDirectInput8W,0xbf798031,0x483a,0x4da2,0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00);
|
||||||
{0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
|
DEFINE_GUID(GUID_XAxis,0xa36d02e0,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);
|
||||||
static const GUID _glfw_GUID_XAxis =
|
DEFINE_GUID(GUID_YAxis,0xa36d02e1,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);
|
||||||
{0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
DEFINE_GUID(GUID_ZAxis,0xa36d02e2,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);
|
||||||
static const GUID _glfw_GUID_YAxis =
|
DEFINE_GUID(GUID_RxAxis,0xa36d02f4,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);
|
||||||
{0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
DEFINE_GUID(GUID_RyAxis,0xa36d02f5,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);
|
||||||
static const GUID _glfw_GUID_ZAxis =
|
DEFINE_GUID(GUID_RzAxis,0xa36d02e3,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);
|
||||||
{0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
DEFINE_GUID(GUID_Slider,0xa36d02e4,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);
|
||||||
static const GUID _glfw_GUID_RxAxis =
|
DEFINE_GUID(GUID_Button,0xa36d02f0,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);
|
||||||
{0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
DEFINE_GUID(GUID_POV,0xa36d02f2,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00);
|
||||||
static const GUID _glfw_GUID_RyAxis =
|
|
||||||
{0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_RzAxis =
|
|
||||||
{0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_Slider =
|
|
||||||
{0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_Button =
|
|
||||||
{0xa36d02f0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
static const GUID _glfw_GUID_POV =
|
|
||||||
{0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
|
||||||
|
|
||||||
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
|
|
||||||
#define GUID_XAxis _glfw_GUID_XAxis
|
|
||||||
#define GUID_YAxis _glfw_GUID_YAxis
|
|
||||||
#define GUID_ZAxis _glfw_GUID_ZAxis
|
|
||||||
#define GUID_RxAxis _glfw_GUID_RxAxis
|
|
||||||
#define GUID_RyAxis _glfw_GUID_RyAxis
|
|
||||||
#define GUID_RzAxis _glfw_GUID_RzAxis
|
|
||||||
#define GUID_Slider _glfw_GUID_Slider
|
|
||||||
#define GUID_Button _glfw_GUID_Button
|
|
||||||
#define GUID_POV _glfw_GUID_POV
|
|
||||||
|
|
||||||
// Object data array for our clone of c_dfDIJoystick
|
// Object data array for our clone of c_dfDIJoystick
|
||||||
// Generated with https://github.com/elmindreda/c_dfDIJoystick2
|
// Generated with https://github.com/elmindreda/c_dfDIJoystick2
|
||||||
@@ -166,9 +149,9 @@ static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic)
|
|||||||
case XINPUT_DEVSUBTYPE_GAMEPAD:
|
case XINPUT_DEVSUBTYPE_GAMEPAD:
|
||||||
{
|
{
|
||||||
if (xic->Flags & XINPUT_CAPS_WIRELESS)
|
if (xic->Flags & XINPUT_CAPS_WIRELESS)
|
||||||
return "Wireless Xbox Controller";
|
return "Wireless Xbox 360 Controller";
|
||||||
else
|
else
|
||||||
return "Xbox Controller";
|
return "Xbox 360 Controller";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,20 +238,25 @@ static GLFWbool supportsXInput(const GUID* guid)
|
|||||||
|
|
||||||
// Frees all resources associated with the specified joystick
|
// Frees all resources associated with the specified joystick
|
||||||
//
|
//
|
||||||
static void closeJoystick(_GLFWjoystick* js)
|
static void closeJoystick(_GLFWjoystickWin32* js)
|
||||||
{
|
{
|
||||||
if (js->win32.device)
|
if (js->device)
|
||||||
{
|
{
|
||||||
IDirectInputDevice8_Unacquire(js->win32.device);
|
IDirectInputDevice8_Unacquire(js->device);
|
||||||
IDirectInputDevice8_Release(js->win32.device);
|
IDirectInputDevice8_Release(js->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwFreeJoystick(js);
|
free(js->name);
|
||||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
free(js->axes);
|
||||||
|
free(js->buttons);
|
||||||
|
free(js->objects);
|
||||||
|
memset(js, 0, sizeof(_GLFWjoystickWin32));
|
||||||
|
|
||||||
|
_glfwInputJoystickChange((int) (js - _glfw.win32_js), GLFW_DISCONNECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DirectInput device object enumeration callback
|
// DirectInput device object enumeration callback
|
||||||
// Insights gleaned from SDL
|
// Insights gleaned from SDL2
|
||||||
//
|
//
|
||||||
static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,
|
static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,
|
||||||
void* user)
|
void* user)
|
||||||
@@ -349,20 +337,23 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
|||||||
DIPROPDWORD dipd;
|
DIPROPDWORD dipd;
|
||||||
IDirectInputDevice8* device;
|
IDirectInputDevice8* device;
|
||||||
_GLFWobjenumWin32 data;
|
_GLFWobjenumWin32 data;
|
||||||
_GLFWjoystick* js;
|
_GLFWjoystickWin32* js;
|
||||||
char guid[33];
|
|
||||||
char name[256];
|
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
{
|
{
|
||||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
if (memcmp(&_glfw.win32_js[jid].guid, &di->guidInstance, sizeof(GUID)) == 0)
|
||||||
if (js->present)
|
return DIENUM_CONTINUE;
|
||||||
{
|
|
||||||
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (!_glfw.win32_js[jid].present)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jid > GLFW_JOYSTICK_LAST)
|
||||||
|
return DIENUM_STOP;
|
||||||
|
|
||||||
if (supportsXInput(&di->guidProduct))
|
if (supportsXInput(&di->guidProduct))
|
||||||
return DIENUM_CONTINUE;
|
return DIENUM_CONTINUE;
|
||||||
|
|
||||||
@@ -435,54 +426,226 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
|||||||
sizeof(_GLFWjoyobjectWin32),
|
sizeof(_GLFWjoyobjectWin32),
|
||||||
compareJoystickObjects);
|
compareJoystickObjects);
|
||||||
|
|
||||||
if (!WideCharToMultiByte(CP_UTF8, 0,
|
js = _glfw.win32_js + jid;
|
||||||
di->tszInstanceName, -1,
|
js->device = device;
|
||||||
name, sizeof(name),
|
js->guid = di->guidInstance;
|
||||||
NULL, NULL))
|
js->axisCount = data.axisCount + data.sliderCount;
|
||||||
{
|
js->axes = calloc(js->axisCount, sizeof(float));
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
js->buttonCount += data.buttonCount + data.povCount * 4;
|
||||||
"Win32: Failed to convert joystick name to UTF-8");
|
js->buttons = calloc(js->buttonCount, 1);
|
||||||
|
js->objects = data.objects;
|
||||||
|
js->objectCount = data.objectCount;
|
||||||
|
js->name = _glfwCreateUTF8FromWideStringWin32(di->tszInstanceName);
|
||||||
|
js->present = GLFW_TRUE;
|
||||||
|
|
||||||
IDirectInputDevice8_Release(device);
|
_glfwInputJoystickChange(jid, GLFW_CONNECTED);
|
||||||
free(data.objects);
|
return DIENUM_CONTINUE;
|
||||||
return DIENUM_STOP;
|
}
|
||||||
|
|
||||||
|
// Attempt to open the specified joystick device
|
||||||
|
// TODO: Pack state arrays for non-gamepad devices
|
||||||
|
//
|
||||||
|
static GLFWbool openXinputDevice(DWORD index)
|
||||||
|
{
|
||||||
|
int jid;
|
||||||
|
XINPUT_CAPABILITIES xic;
|
||||||
|
_GLFWjoystickWin32* js;
|
||||||
|
|
||||||
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
|
{
|
||||||
|
if (_glfw.win32_js[jid].present &&
|
||||||
|
_glfw.win32_js[jid].device == NULL &&
|
||||||
|
_glfw.win32_js[jid].index == index)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
|
|
||||||
{
|
{
|
||||||
sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
|
if (!_glfw.win32_js[jid].present)
|
||||||
(uint8_t) di->guidProduct.Data1,
|
break;
|
||||||
(uint8_t) (di->guidProduct.Data1 >> 8),
|
}
|
||||||
(uint8_t) (di->guidProduct.Data1 >> 16),
|
|
||||||
(uint8_t) (di->guidProduct.Data1 >> 24));
|
if (jid > GLFW_JOYSTICK_LAST)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
if (_glfw_XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
js = _glfw.win32_js + jid;
|
||||||
|
js->axisCount = 6;
|
||||||
|
js->axes = calloc(js->axisCount, sizeof(float));
|
||||||
|
js->buttonCount = 14;
|
||||||
|
js->buttons = calloc(js->buttonCount, 1);
|
||||||
|
js->present = GLFW_TRUE;
|
||||||
|
js->name = strdup(getDeviceDescription(&xic));
|
||||||
|
js->index = index;
|
||||||
|
|
||||||
|
_glfwInputJoystickChange(jid, GLFW_CONNECTED);
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Polls for and processes events the specified joystick
|
||||||
|
//
|
||||||
|
static GLFWbool pollJoystickState(_GLFWjoystickWin32* js, int mode)
|
||||||
|
{
|
||||||
|
if (!js->present)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
if (js->device)
|
||||||
|
{
|
||||||
|
int i, j, ai = 0, bi = 0;
|
||||||
|
HRESULT result;
|
||||||
|
DIJOYSTATE state;
|
||||||
|
|
||||||
|
IDirectInputDevice8_Poll(js->device);
|
||||||
|
result = IDirectInputDevice8_GetDeviceState(js->device,
|
||||||
|
sizeof(state),
|
||||||
|
&state);
|
||||||
|
if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
|
||||||
|
{
|
||||||
|
IDirectInputDevice8_Acquire(js->device);
|
||||||
|
IDirectInputDevice8_Poll(js->device);
|
||||||
|
result = IDirectInputDevice8_GetDeviceState(js->device,
|
||||||
|
sizeof(state),
|
||||||
|
&state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(result))
|
||||||
|
{
|
||||||
|
closeJoystick(js);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == _GLFW_PRESENCE_ONLY)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
for (i = 0; i < js->objectCount; i++)
|
||||||
|
{
|
||||||
|
const void* data = (char*) &state + js->objects[i].offset;
|
||||||
|
|
||||||
|
switch (js->objects[i].type)
|
||||||
|
{
|
||||||
|
case _GLFW_TYPE_AXIS:
|
||||||
|
case _GLFW_TYPE_SLIDER:
|
||||||
|
{
|
||||||
|
js->axes[ai++] = (*((LONG*) data) + 0.5f) / 32767.5f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case _GLFW_TYPE_BUTTON:
|
||||||
|
{
|
||||||
|
if (*((BYTE*) data) & 0x80)
|
||||||
|
js->buttons[bi++] = GLFW_PRESS;
|
||||||
|
else
|
||||||
|
js->buttons[bi++] = GLFW_RELEASE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case _GLFW_TYPE_POV:
|
||||||
|
{
|
||||||
|
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
|
||||||
|
// Screams of horror are appropriate at this point
|
||||||
|
int value = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
|
||||||
|
if (value < 0 || value > 8)
|
||||||
|
value = 8;
|
||||||
|
|
||||||
|
for (j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
if (directions[value] & (1 << j))
|
||||||
|
js->buttons[bi++] = GLFW_PRESS;
|
||||||
|
else
|
||||||
|
js->buttons[bi++] = GLFW_RELEASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
int i;
|
||||||
name[0], name[1], name[2], name[3],
|
DWORD result;
|
||||||
name[4], name[5], name[6], name[7],
|
XINPUT_STATE xis;
|
||||||
name[8], name[9], name[10]);
|
const WORD buttons[14] =
|
||||||
|
{
|
||||||
|
XINPUT_GAMEPAD_A,
|
||||||
|
XINPUT_GAMEPAD_B,
|
||||||
|
XINPUT_GAMEPAD_X,
|
||||||
|
XINPUT_GAMEPAD_Y,
|
||||||
|
XINPUT_GAMEPAD_LEFT_SHOULDER,
|
||||||
|
XINPUT_GAMEPAD_RIGHT_SHOULDER,
|
||||||
|
XINPUT_GAMEPAD_BACK,
|
||||||
|
XINPUT_GAMEPAD_START,
|
||||||
|
XINPUT_GAMEPAD_LEFT_THUMB,
|
||||||
|
XINPUT_GAMEPAD_RIGHT_THUMB,
|
||||||
|
XINPUT_GAMEPAD_DPAD_UP,
|
||||||
|
XINPUT_GAMEPAD_DPAD_RIGHT,
|
||||||
|
XINPUT_GAMEPAD_DPAD_DOWN,
|
||||||
|
XINPUT_GAMEPAD_DPAD_LEFT
|
||||||
|
};
|
||||||
|
|
||||||
|
result = _glfw_XInputGetState(js->index, &xis);
|
||||||
|
if (result != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
if (result == ERROR_DEVICE_NOT_CONNECTED)
|
||||||
|
closeJoystick(js);
|
||||||
|
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == _GLFW_PRESENCE_ONLY)
|
||||||
|
return GLFW_TRUE;
|
||||||
|
|
||||||
|
if ((float) xis.Gamepad.sThumbLX * xis.Gamepad.sThumbLX +
|
||||||
|
(float) xis.Gamepad.sThumbLY * xis.Gamepad.sThumbLY >
|
||||||
|
(float) XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE *
|
||||||
|
XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
|
||||||
|
{
|
||||||
|
js->axes[0] = (xis.Gamepad.sThumbLX + 0.5f) / 32767.f;
|
||||||
|
js->axes[1] = (xis.Gamepad.sThumbLY + 0.5f) / 32767.f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
js->axes[0] = 0.f;
|
||||||
|
js->axes[1] = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((float) xis.Gamepad.sThumbRX * xis.Gamepad.sThumbRX +
|
||||||
|
(float) xis.Gamepad.sThumbRY * xis.Gamepad.sThumbRY >
|
||||||
|
(float) XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE *
|
||||||
|
XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
|
||||||
|
{
|
||||||
|
js->axes[2] = (xis.Gamepad.sThumbRX + 0.5f) / 32767.f;
|
||||||
|
js->axes[3] = (xis.Gamepad.sThumbRY + 0.5f) / 32767.f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
js->axes[2] = 0.f;
|
||||||
|
js->axes[3] = 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xis.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
|
||||||
|
js->axes[4] = xis.Gamepad.bLeftTrigger / 127.5f - 1.f;
|
||||||
|
else
|
||||||
|
js->axes[4] = -1.f;
|
||||||
|
|
||||||
|
if (xis.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD)
|
||||||
|
js->axes[5] = xis.Gamepad.bRightTrigger / 127.5f - 1.f;
|
||||||
|
else
|
||||||
|
js->axes[5] = -1.f;
|
||||||
|
|
||||||
|
for (i = 0; i < 14; i++)
|
||||||
|
js->buttons[i] = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
|
||||||
|
|
||||||
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
js = _glfwAllocJoystick(name, guid,
|
|
||||||
data.axisCount + data.sliderCount,
|
|
||||||
data.buttonCount,
|
|
||||||
data.povCount);
|
|
||||||
if (!js)
|
|
||||||
{
|
|
||||||
IDirectInputDevice8_Release(device);
|
|
||||||
free(data.objects);
|
|
||||||
return DIENUM_STOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
js->win32.device = device;
|
|
||||||
js->win32.guid = di->guidInstance;
|
|
||||||
js->win32.objects = data.objects;
|
|
||||||
js->win32.objectCount = data.objectCount;
|
|
||||||
|
|
||||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -496,11 +659,11 @@ void _glfwInitJoysticksWin32(void)
|
|||||||
{
|
{
|
||||||
if (_glfw.win32.dinput8.instance)
|
if (_glfw.win32.dinput8.instance)
|
||||||
{
|
{
|
||||||
if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
|
if (FAILED(_glfw_DirectInput8Create(GetModuleHandle(NULL),
|
||||||
DIRECTINPUT_VERSION,
|
DIRECTINPUT_VERSION,
|
||||||
&IID_IDirectInput8W,
|
&IID_IDirectInput8W,
|
||||||
(void**) &_glfw.win32.dinput8.api,
|
(void**) &_glfw.win32.dinput8.api,
|
||||||
NULL)))
|
NULL)))
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to create interface");
|
"Win32: Failed to create interface");
|
||||||
@@ -517,7 +680,7 @@ void _glfwTerminateJoysticksWin32(void)
|
|||||||
int jid;
|
int jid;
|
||||||
|
|
||||||
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
closeJoystick(_glfw.joysticks + jid);
|
closeJoystick(_glfw.win32_js + jid);
|
||||||
|
|
||||||
if (_glfw.win32.dinput8.api)
|
if (_glfw.win32.dinput8.api)
|
||||||
IDirectInput8_Release(_glfw.win32.dinput8.api);
|
IDirectInput8_Release(_glfw.win32.dinput8.api);
|
||||||
@@ -529,43 +692,10 @@ void _glfwDetectJoystickConnectionWin32(void)
|
|||||||
{
|
{
|
||||||
if (_glfw.win32.xinput.instance)
|
if (_glfw.win32.xinput.instance)
|
||||||
{
|
{
|
||||||
DWORD index;
|
DWORD i;
|
||||||
|
|
||||||
for (index = 0; index < XUSER_MAX_COUNT; index++)
|
for (i = 0; i < XUSER_MAX_COUNT; i++)
|
||||||
{
|
openXinputDevice(i);
|
||||||
int jid;
|
|
||||||
char guid[33];
|
|
||||||
XINPUT_CAPABILITIES xic;
|
|
||||||
_GLFWjoystick* js;
|
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
|
||||||
{
|
|
||||||
if (_glfw.joysticks[jid].present &&
|
|
||||||
_glfw.joysticks[jid].win32.device == NULL &&
|
|
||||||
_glfw.joysticks[jid].win32.index == index)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jid <= GLFW_JOYSTICK_LAST)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
|
||||||
sprintf(guid, "78696e707574%02x000000000000000000",
|
|
||||||
xic.SubType & 0xff);
|
|
||||||
|
|
||||||
js = _glfwAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1);
|
|
||||||
if (!js)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
js->win32.index = index;
|
|
||||||
|
|
||||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.win32.dinput8.api)
|
if (_glfw.win32.dinput8.api)
|
||||||
@@ -589,12 +719,8 @@ void _glfwDetectJoystickDisconnectionWin32(void)
|
|||||||
{
|
{
|
||||||
int jid;
|
int jid;
|
||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
{
|
pollJoystickState(_glfw.win32_js + jid, _GLFW_PRESENCE_ONLY);
|
||||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
|
||||||
if (js->present)
|
|
||||||
_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -602,153 +728,38 @@ void _glfwDetectJoystickDisconnectionWin32(void)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
int _glfwPlatformJoystickPresent(int jid)
|
||||||
{
|
{
|
||||||
if (js->win32.device)
|
_GLFWjoystickWin32* js = _glfw.win32_js + jid;
|
||||||
{
|
return pollJoystickState(js, _GLFW_PRESENCE_ONLY);
|
||||||
int i, ai = 0, bi = 0, pi = 0;
|
|
||||||
HRESULT result;
|
|
||||||
DIJOYSTATE state;
|
|
||||||
|
|
||||||
IDirectInputDevice8_Poll(js->win32.device);
|
|
||||||
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
|
|
||||||
sizeof(state),
|
|
||||||
&state);
|
|
||||||
if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
|
|
||||||
{
|
|
||||||
IDirectInputDevice8_Acquire(js->win32.device);
|
|
||||||
IDirectInputDevice8_Poll(js->win32.device);
|
|
||||||
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
|
|
||||||
sizeof(state),
|
|
||||||
&state);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(result))
|
|
||||||
{
|
|
||||||
closeJoystick(js);
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == _GLFW_POLL_PRESENCE)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
|
|
||||||
for (i = 0; i < js->win32.objectCount; i++)
|
|
||||||
{
|
|
||||||
const void* data = (char*) &state + js->win32.objects[i].offset;
|
|
||||||
|
|
||||||
switch (js->win32.objects[i].type)
|
|
||||||
{
|
|
||||||
case _GLFW_TYPE_AXIS:
|
|
||||||
case _GLFW_TYPE_SLIDER:
|
|
||||||
{
|
|
||||||
const float value = (*((LONG*) data) + 0.5f) / 32767.5f;
|
|
||||||
_glfwInputJoystickAxis(js, ai, value);
|
|
||||||
ai++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case _GLFW_TYPE_BUTTON:
|
|
||||||
{
|
|
||||||
const char value = (*((BYTE*) data) & 0x80) != 0;
|
|
||||||
_glfwInputJoystickButton(js, bi, value);
|
|
||||||
bi++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case _GLFW_TYPE_POV:
|
|
||||||
{
|
|
||||||
const int states[9] =
|
|
||||||
{
|
|
||||||
GLFW_HAT_UP,
|
|
||||||
GLFW_HAT_RIGHT_UP,
|
|
||||||
GLFW_HAT_RIGHT,
|
|
||||||
GLFW_HAT_RIGHT_DOWN,
|
|
||||||
GLFW_HAT_DOWN,
|
|
||||||
GLFW_HAT_LEFT_DOWN,
|
|
||||||
GLFW_HAT_LEFT,
|
|
||||||
GLFW_HAT_LEFT_UP,
|
|
||||||
GLFW_HAT_CENTERED
|
|
||||||
};
|
|
||||||
|
|
||||||
// Screams of horror are appropriate at this point
|
|
||||||
int state = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
|
|
||||||
if (state < 0 || state > 8)
|
|
||||||
state = 8;
|
|
||||||
|
|
||||||
_glfwInputJoystickHat(js, pi, states[state]);
|
|
||||||
pi++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int i, dpad = 0;
|
|
||||||
DWORD result;
|
|
||||||
XINPUT_STATE xis;
|
|
||||||
const WORD buttons[10] =
|
|
||||||
{
|
|
||||||
XINPUT_GAMEPAD_A,
|
|
||||||
XINPUT_GAMEPAD_B,
|
|
||||||
XINPUT_GAMEPAD_X,
|
|
||||||
XINPUT_GAMEPAD_Y,
|
|
||||||
XINPUT_GAMEPAD_LEFT_SHOULDER,
|
|
||||||
XINPUT_GAMEPAD_RIGHT_SHOULDER,
|
|
||||||
XINPUT_GAMEPAD_BACK,
|
|
||||||
XINPUT_GAMEPAD_START,
|
|
||||||
XINPUT_GAMEPAD_LEFT_THUMB,
|
|
||||||
XINPUT_GAMEPAD_RIGHT_THUMB
|
|
||||||
};
|
|
||||||
|
|
||||||
result = XInputGetState(js->win32.index, &xis);
|
|
||||||
if (result != ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
if (result == ERROR_DEVICE_NOT_CONNECTED)
|
|
||||||
closeJoystick(js);
|
|
||||||
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == _GLFW_POLL_PRESENCE)
|
|
||||||
return GLFW_TRUE;
|
|
||||||
|
|
||||||
_glfwInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f);
|
|
||||||
_glfwInputJoystickAxis(js, 1, (xis.Gamepad.sThumbLY + 0.5f) / 32767.5f);
|
|
||||||
_glfwInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f);
|
|
||||||
_glfwInputJoystickAxis(js, 3, (xis.Gamepad.sThumbRY + 0.5f) / 32767.5f);
|
|
||||||
_glfwInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f);
|
|
||||||
_glfwInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f);
|
|
||||||
|
|
||||||
for (i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
|
|
||||||
_glfwInputJoystickButton(js, i, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
|
|
||||||
dpad |= GLFW_HAT_UP;
|
|
||||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
|
|
||||||
dpad |= GLFW_HAT_RIGHT;
|
|
||||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
|
|
||||||
dpad |= GLFW_HAT_DOWN;
|
|
||||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
|
|
||||||
dpad |= GLFW_HAT_LEFT;
|
|
||||||
|
|
||||||
_glfwInputJoystickHat(js, 0, dpad);
|
|
||||||
}
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
const float* _glfwPlatformGetJoystickAxes(int jid, int* count)
|
||||||
{
|
{
|
||||||
if (strcmp(guid + 20, "504944564944") == 0)
|
_GLFWjoystickWin32* js = _glfw.win32_js + jid;
|
||||||
{
|
if (!pollJoystickState(js, _GLFW_UPDATE_STATE))
|
||||||
char original[33];
|
return NULL;
|
||||||
strcpy(original, guid);
|
|
||||||
sprintf(guid, "03000000%.4s0000%.4s000000000000",
|
*count = js->axisCount;
|
||||||
original, original + 4);
|
return js->axes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unsigned char* _glfwPlatformGetJoystickButtons(int jid, int* count)
|
||||||
|
{
|
||||||
|
_GLFWjoystickWin32* js = _glfw.win32_js + jid;
|
||||||
|
if (!pollJoystickState(js, _GLFW_UPDATE_STATE))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*count = js->buttonCount;
|
||||||
|
return js->buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* _glfwPlatformGetJoystickName(int jid)
|
||||||
|
{
|
||||||
|
_GLFWjoystickWin32* js = _glfw.win32_js + jid;
|
||||||
|
if (!pollJoystickState(js, _GLFW_PRESENCE_ONLY))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return js->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-3
@@ -24,10 +24,11 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32
|
#ifndef _glfw3_win32_joystick_h_
|
||||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int dummy
|
#define _glfw3_win32_joystick_h_
|
||||||
|
|
||||||
#define _GLFW_PLATFORM_MAPPING_NAME "Windows"
|
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
|
||||||
|
_GLFWjoystickWin32 win32_js[GLFW_JOYSTICK_LAST + 1]
|
||||||
|
|
||||||
// Joystick element (axis, button or slider)
|
// Joystick element (axis, button or slider)
|
||||||
//
|
//
|
||||||
@@ -41,8 +42,14 @@ typedef struct _GLFWjoyobjectWin32
|
|||||||
//
|
//
|
||||||
typedef struct _GLFWjoystickWin32
|
typedef struct _GLFWjoystickWin32
|
||||||
{
|
{
|
||||||
|
GLFWbool present;
|
||||||
|
float* axes;
|
||||||
|
int axisCount;
|
||||||
|
unsigned char* buttons;
|
||||||
|
int buttonCount;
|
||||||
_GLFWjoyobjectWin32* objects;
|
_GLFWjoyobjectWin32* objects;
|
||||||
int objectCount;
|
int objectCount;
|
||||||
|
char* name;
|
||||||
IDirectInputDevice8W* device;
|
IDirectInputDevice8W* device;
|
||||||
DWORD index;
|
DWORD index;
|
||||||
GUID guid;
|
GUID guid;
|
||||||
@@ -54,3 +61,4 @@ void _glfwTerminateJoysticksWin32(void);
|
|||||||
void _glfwDetectJoystickConnectionWin32(void);
|
void _glfwDetectJoystickConnectionWin32(void);
|
||||||
void _glfwDetectJoystickDisconnectionWin32(void);
|
void _glfwDetectJoystickDisconnectionWin32(void);
|
||||||
|
|
||||||
|
#endif // _glfw3_win32_joystick_h_
|
||||||
|
|||||||
+107
-182
@@ -33,27 +33,6 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
|
|
||||||
// Callback for EnumDisplayMonitors in createMonitor
|
|
||||||
//
|
|
||||||
static BOOL CALLBACK monitorCallback(HMONITOR handle,
|
|
||||||
HDC dc,
|
|
||||||
RECT* rect,
|
|
||||||
LPARAM data)
|
|
||||||
{
|
|
||||||
MONITORINFOEXW mi;
|
|
||||||
ZeroMemory(&mi, sizeof(mi));
|
|
||||||
mi.cbSize = sizeof(mi);
|
|
||||||
|
|
||||||
if (GetMonitorInfoW(handle, (MONITORINFO*) &mi))
|
|
||||||
{
|
|
||||||
_GLFWmonitor* monitor = (_GLFWmonitor*) data;
|
|
||||||
if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0)
|
|
||||||
monitor->win32.handle = handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create monitor from an adapter and (optionally) a display
|
// Create monitor from an adapter and (optionally) a display
|
||||||
//
|
//
|
||||||
static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
|
static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
|
||||||
@@ -62,15 +41,17 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
|
|||||||
_GLFWmonitor* monitor;
|
_GLFWmonitor* monitor;
|
||||||
char* name;
|
char* name;
|
||||||
HDC dc;
|
HDC dc;
|
||||||
DEVMODEW dm;
|
|
||||||
RECT rect;
|
|
||||||
|
|
||||||
if (display)
|
if (display)
|
||||||
name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
|
name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
|
||||||
else
|
else
|
||||||
name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);
|
name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);
|
||||||
if (!name)
|
if (!name)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to convert string to UTF-8");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
|
dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
|
||||||
|
|
||||||
@@ -101,16 +82,6 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
|
|||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZeroMemory(&dm, sizeof(dm));
|
|
||||||
dm.dmSize = sizeof(dm);
|
|
||||||
EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm);
|
|
||||||
|
|
||||||
rect.left = dm.dmPosition.x;
|
|
||||||
rect.top = dm.dmPosition.y;
|
|
||||||
rect.right = dm.dmPosition.x + dm.dmPelsWidth;
|
|
||||||
rect.bottom = dm.dmPosition.y + dm.dmPelsHeight;
|
|
||||||
|
|
||||||
EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor);
|
|
||||||
return monitor;
|
return monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,116 +90,6 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Poll for changes in the set of connected monitors
|
|
||||||
//
|
|
||||||
void _glfwPollMonitorsWin32(void)
|
|
||||||
{
|
|
||||||
int i, disconnectedCount;
|
|
||||||
_GLFWmonitor** disconnected = NULL;
|
|
||||||
DWORD adapterIndex, displayIndex;
|
|
||||||
DISPLAY_DEVICEW adapter, display;
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
|
|
||||||
disconnectedCount = _glfw.monitorCount;
|
|
||||||
if (disconnectedCount)
|
|
||||||
{
|
|
||||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
|
||||||
memcpy(disconnected,
|
|
||||||
_glfw.monitors,
|
|
||||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (adapterIndex = 0; ; adapterIndex++)
|
|
||||||
{
|
|
||||||
int type = _GLFW_INSERT_LAST;
|
|
||||||
|
|
||||||
ZeroMemory(&adapter, sizeof(adapter));
|
|
||||||
adapter.cb = sizeof(adapter);
|
|
||||||
|
|
||||||
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
|
||||||
type = _GLFW_INSERT_FIRST;
|
|
||||||
|
|
||||||
for (displayIndex = 0; ; displayIndex++)
|
|
||||||
{
|
|
||||||
ZeroMemory(&display, sizeof(display));
|
|
||||||
display.cb = sizeof(display);
|
|
||||||
|
|
||||||
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (i = 0; i < disconnectedCount; i++)
|
|
||||||
{
|
|
||||||
if (disconnected[i] &&
|
|
||||||
wcscmp(disconnected[i]->win32.displayName,
|
|
||||||
display.DeviceName) == 0)
|
|
||||||
{
|
|
||||||
disconnected[i] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < disconnectedCount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
monitor = createMonitor(&adapter, &display);
|
|
||||||
if (!monitor)
|
|
||||||
{
|
|
||||||
free(disconnected);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
|
||||||
|
|
||||||
type = _GLFW_INSERT_LAST;
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK: If an active adapter does not have any display devices
|
|
||||||
// (as sometimes happens), add it directly as a monitor
|
|
||||||
if (displayIndex == 0)
|
|
||||||
{
|
|
||||||
for (i = 0; i < disconnectedCount; i++)
|
|
||||||
{
|
|
||||||
if (disconnected[i] &&
|
|
||||||
wcscmp(disconnected[i]->win32.adapterName,
|
|
||||||
adapter.DeviceName) == 0)
|
|
||||||
{
|
|
||||||
disconnected[i] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < disconnectedCount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
monitor = createMonitor(&adapter, NULL);
|
|
||||||
if (!monitor)
|
|
||||||
{
|
|
||||||
free(disconnected);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < disconnectedCount; i++)
|
|
||||||
{
|
|
||||||
if (disconnected[i])
|
|
||||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(disconnected);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the current video mode
|
// Change the current video mode
|
||||||
//
|
//
|
||||||
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||||
@@ -236,7 +97,6 @@ GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desire
|
|||||||
GLFWvidmode current;
|
GLFWvidmode current;
|
||||||
const GLFWvidmode* best;
|
const GLFWvidmode* best;
|
||||||
DEVMODEW dm;
|
DEVMODEW dm;
|
||||||
LONG result;
|
|
||||||
|
|
||||||
best = _glfwChooseVideoMode(monitor, desired);
|
best = _glfwChooseVideoMode(monitor, desired);
|
||||||
_glfwPlatformGetVideoMode(monitor, ¤t);
|
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||||
@@ -244,7 +104,7 @@ GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desire
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
|
|
||||||
ZeroMemory(&dm, sizeof(dm));
|
ZeroMemory(&dm, sizeof(dm));
|
||||||
dm.dmSize = sizeof(dm);
|
dm.dmSize = sizeof(DEVMODEW);
|
||||||
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
|
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
|
||||||
DM_DISPLAYFREQUENCY;
|
DM_DISPLAYFREQUENCY;
|
||||||
dm.dmPelsWidth = best->width;
|
dm.dmPelsWidth = best->width;
|
||||||
@@ -255,34 +115,13 @@ GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desire
|
|||||||
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
|
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
|
||||||
dm.dmBitsPerPel = 32;
|
dm.dmBitsPerPel = 32;
|
||||||
|
|
||||||
result = ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
||||||
&dm,
|
&dm,
|
||||||
NULL,
|
NULL,
|
||||||
CDS_FULLSCREEN,
|
CDS_FULLSCREEN,
|
||||||
NULL);
|
NULL) != DISP_CHANGE_SUCCESSFUL)
|
||||||
if (result != DISP_CHANGE_SUCCESSFUL)
|
|
||||||
{
|
{
|
||||||
const char* description = "Unknown error";
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to set video mode");
|
||||||
|
|
||||||
if (result == DISP_CHANGE_BADDUALVIEW)
|
|
||||||
description = "The system uses DualView";
|
|
||||||
else if (result == DISP_CHANGE_BADFLAGS)
|
|
||||||
description = "Invalid flags";
|
|
||||||
else if (result == DISP_CHANGE_BADMODE)
|
|
||||||
description = "Graphics mode not supported";
|
|
||||||
else if (result == DISP_CHANGE_BADPARAM)
|
|
||||||
description = "Invalid parameter";
|
|
||||||
else if (result == DISP_CHANGE_FAILED)
|
|
||||||
description = "Graphics mode failed";
|
|
||||||
else if (result == DISP_CHANGE_NOTUPDATED)
|
|
||||||
description = "Failed to write to registry";
|
|
||||||
else if (result == DISP_CHANGE_RESTART)
|
|
||||||
description = "Computer restart required";
|
|
||||||
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to set video mode: %s",
|
|
||||||
description);
|
|
||||||
|
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,21 +146,106 @@ void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||||
|
{
|
||||||
|
int found = 0;
|
||||||
|
DWORD adapterIndex, displayIndex, primaryIndex = 0;
|
||||||
|
DISPLAY_DEVICEW adapter, display;
|
||||||
|
GLFWbool hasDisplays = GLFW_FALSE;
|
||||||
|
_GLFWmonitor** monitors = NULL;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
// HACK: Check if any active adapters have connected displays
|
||||||
|
// If not, this is a headless system or a VMware guest
|
||||||
|
|
||||||
|
for (adapterIndex = 0; ; adapterIndex++)
|
||||||
|
{
|
||||||
|
ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));
|
||||||
|
adapter.cb = sizeof(DISPLAY_DEVICEW);
|
||||||
|
|
||||||
|
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
|
||||||
|
display.cb = sizeof(DISPLAY_DEVICEW);
|
||||||
|
|
||||||
|
if (EnumDisplayDevicesW(adapter.DeviceName, 0, &display, 0))
|
||||||
|
{
|
||||||
|
hasDisplays = GLFW_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (adapterIndex = 0; ; adapterIndex++)
|
||||||
|
{
|
||||||
|
ZeroMemory(&adapter, sizeof(DISPLAY_DEVICEW));
|
||||||
|
adapter.cb = sizeof(DISPLAY_DEVICEW);
|
||||||
|
|
||||||
|
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
||||||
|
primaryIndex = found;
|
||||||
|
|
||||||
|
if (hasDisplays)
|
||||||
|
{
|
||||||
|
for (displayIndex = 0; ; displayIndex++)
|
||||||
|
{
|
||||||
|
ZeroMemory(&display, sizeof(DISPLAY_DEVICEW));
|
||||||
|
display.cb = sizeof(DISPLAY_DEVICEW);
|
||||||
|
|
||||||
|
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
|
||||||
|
break;
|
||||||
|
|
||||||
|
found++;
|
||||||
|
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found);
|
||||||
|
monitors[found - 1] = createMonitor(&adapter, &display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
found++;
|
||||||
|
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found);
|
||||||
|
monitors[found - 1] = createMonitor(&adapter, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFW_SWAP_POINTERS(monitors[0], monitors[primaryIndex]);
|
||||||
|
|
||||||
|
*count = found;
|
||||||
|
return monitors;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
||||||
|
{
|
||||||
|
if (wcslen(first->win32.displayName))
|
||||||
|
return wcscmp(first->win32.displayName, second->win32.displayName) == 0;
|
||||||
|
else
|
||||||
|
return wcscmp(first->win32.adapterName, second->win32.adapterName) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
DEVMODEW dm;
|
DEVMODEW settings;
|
||||||
ZeroMemory(&dm, sizeof(dm));
|
ZeroMemory(&settings, sizeof(DEVMODEW));
|
||||||
dm.dmSize = sizeof(dm);
|
settings.dmSize = sizeof(DEVMODEW);
|
||||||
|
|
||||||
EnumDisplaySettingsExW(monitor->win32.adapterName,
|
EnumDisplaySettingsExW(monitor->win32.adapterName,
|
||||||
ENUM_CURRENT_SETTINGS,
|
ENUM_CURRENT_SETTINGS,
|
||||||
&dm,
|
&settings,
|
||||||
EDS_ROTATEDMODE);
|
EDS_ROTATEDMODE);
|
||||||
|
|
||||||
if (xpos)
|
if (xpos)
|
||||||
*xpos = dm.dmPosition.x;
|
*xpos = settings.dmPosition.x;
|
||||||
if (ypos)
|
if (ypos)
|
||||||
*ypos = dm.dmPosition.y;
|
*ypos = settings.dmPosition.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||||
@@ -337,8 +261,8 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
|||||||
GLFWvidmode mode;
|
GLFWvidmode mode;
|
||||||
DEVMODEW dm;
|
DEVMODEW dm;
|
||||||
|
|
||||||
ZeroMemory(&dm, sizeof(dm));
|
ZeroMemory(&dm, sizeof(DEVMODEW));
|
||||||
dm.dmSize = sizeof(dm);
|
dm.dmSize = sizeof(DEVMODEW);
|
||||||
|
|
||||||
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
|
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
|
||||||
break;
|
break;
|
||||||
@@ -404,8 +328,9 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
|||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||||
{
|
{
|
||||||
DEVMODEW dm;
|
DEVMODEW dm;
|
||||||
ZeroMemory(&dm, sizeof(dm));
|
|
||||||
dm.dmSize = sizeof(dm);
|
ZeroMemory(&dm, sizeof(DEVMODEW));
|
||||||
|
dm.dmSize = sizeof(DEVMODEW);
|
||||||
|
|
||||||
EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
|
EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
|
||||||
|
|
||||||
|
|||||||
+27
-38
@@ -25,6 +25,9 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_win32_platform_h_
|
||||||
|
#define _glfw3_win32_platform_h_
|
||||||
|
|
||||||
// We don't need all the fancy stuff
|
// We don't need all the fancy stuff
|
||||||
#ifndef NOMINMAX
|
#ifndef NOMINMAX
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
@@ -63,6 +66,7 @@
|
|||||||
|
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <mmsystem.h>
|
||||||
#include <dinput.h>
|
#include <dinput.h>
|
||||||
#include <xinput.h>
|
#include <xinput.h>
|
||||||
#include <dbt.h>
|
#include <dbt.h>
|
||||||
@@ -158,17 +162,17 @@ typedef enum PROCESS_DPI_AWARENESS
|
|||||||
|
|
||||||
// winmm.dll function pointer typedefs
|
// winmm.dll function pointer typedefs
|
||||||
typedef DWORD (WINAPI * PFN_timeGetTime)(void);
|
typedef DWORD (WINAPI * PFN_timeGetTime)(void);
|
||||||
#define timeGetTime _glfw.win32.winmm.GetTime
|
#define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime
|
||||||
|
|
||||||
// xinput.dll function pointer typedefs
|
// xinput.dll function pointer typedefs
|
||||||
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
|
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
|
||||||
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
|
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
|
||||||
#define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities
|
#define _glfw_XInputGetCapabilities _glfw.win32.xinput.XInputGetCapabilities
|
||||||
#define XInputGetState _glfw.win32.xinput.GetState
|
#define _glfw_XInputGetState _glfw.win32.xinput.XInputGetState
|
||||||
|
|
||||||
// dinput8.dll function pointer typedefs
|
// dinput8.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
|
typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
|
||||||
#define DirectInput8Create _glfw.win32.dinput8.Create
|
#define _glfw_DirectInput8Create _glfw.win32.dinput8.DirectInput8Create
|
||||||
|
|
||||||
// user32.dll function pointer typedefs
|
// user32.dll function pointer typedefs
|
||||||
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
||||||
@@ -179,8 +183,8 @@ typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEF
|
|||||||
// dwmapi.dll function pointer typedefs
|
// dwmapi.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||||
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
||||||
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
#define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled
|
||||||
#define DwmFlush _glfw.win32.dwmapi.Flush
|
#define _glfw_DwmFlush _glfw.win32.dwmapi.DwmFlush
|
||||||
|
|
||||||
// shcore.dll function pointer typedefs
|
// shcore.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||||
@@ -203,7 +207,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
|
|||||||
#include "win32_joystick.h"
|
#include "win32_joystick.h"
|
||||||
#include "wgl_context.h"
|
#include "wgl_context.h"
|
||||||
#include "egl_context.h"
|
#include "egl_context.h"
|
||||||
#include "osmesa_context.h"
|
|
||||||
|
|
||||||
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
||||||
|
|
||||||
@@ -216,11 +219,10 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
|
|||||||
|
|
||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
|
||||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
||||||
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32
|
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time
|
||||||
|
#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsWin32 win32_tls
|
||||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32
|
||||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32
|
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32
|
||||||
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32
|
|
||||||
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexWin32 win32
|
|
||||||
|
|
||||||
|
|
||||||
// Win32-specific per-window data
|
// Win32-specific per-window data
|
||||||
@@ -232,7 +234,6 @@ typedef struct _GLFWwindowWin32
|
|||||||
HICON smallIcon;
|
HICON smallIcon;
|
||||||
|
|
||||||
GLFWbool cursorTracked;
|
GLFWbool cursorTracked;
|
||||||
GLFWbool frameAction;
|
|
||||||
GLFWbool iconified;
|
GLFWbool iconified;
|
||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
|
|
||||||
@@ -247,33 +248,30 @@ typedef struct _GLFWlibraryWin32
|
|||||||
{
|
{
|
||||||
HWND helperWindowHandle;
|
HWND helperWindowHandle;
|
||||||
DWORD foregroundLockTimeout;
|
DWORD foregroundLockTimeout;
|
||||||
int acquiredMonitorCount;
|
|
||||||
char* clipboardString;
|
char* clipboardString;
|
||||||
|
char keyName[64];
|
||||||
short int keycodes[512];
|
short int keycodes[512];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
char keynames[GLFW_KEY_LAST + 1][5];
|
|
||||||
// Where to place the cursor when re-enabled
|
// Where to place the cursor when re-enabled
|
||||||
double restoreCursorPosX, restoreCursorPosY;
|
double restoreCursorPosX, restoreCursorPosY;
|
||||||
// The window whose disabled cursor mode is active
|
// The window whose disabled cursor mode is active
|
||||||
_GLFWwindow* disabledCursorWindow;
|
_GLFWwindow* disabledCursorWindow;
|
||||||
RAWINPUT* rawInput;
|
|
||||||
int rawInputSize;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_timeGetTime GetTime;
|
PFN_timeGetTime timeGetTime;
|
||||||
} winmm;
|
} winmm;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_DirectInput8Create Create;
|
PFN_DirectInput8Create DirectInput8Create;
|
||||||
IDirectInput8W* api;
|
IDirectInput8W* api;
|
||||||
} dinput8;
|
} dinput8;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_XInputGetCapabilities GetCapabilities;
|
PFN_XInputGetCapabilities XInputGetCapabilities;
|
||||||
PFN_XInputGetState GetState;
|
PFN_XInputGetState XInputGetState;
|
||||||
} xinput;
|
} xinput;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -284,8 +282,8 @@ typedef struct _GLFWlibraryWin32
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
PFN_DwmIsCompositionEnabled DwmIsCompositionEnabled;
|
||||||
PFN_DwmFlush Flush;
|
PFN_DwmFlush DwmFlush;
|
||||||
} dwmapi;
|
} dwmapi;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -299,7 +297,6 @@ typedef struct _GLFWlibraryWin32
|
|||||||
//
|
//
|
||||||
typedef struct _GLFWmonitorWin32
|
typedef struct _GLFWmonitorWin32
|
||||||
{
|
{
|
||||||
HMONITOR handle;
|
|
||||||
// This size matches the static size of DISPLAY_DEVICE.DeviceName
|
// This size matches the static size of DISPLAY_DEVICE.DeviceName
|
||||||
WCHAR adapterName[32];
|
WCHAR adapterName[32];
|
||||||
WCHAR displayName[32];
|
WCHAR displayName[32];
|
||||||
@@ -320,43 +317,35 @@ typedef struct _GLFWcursorWin32
|
|||||||
|
|
||||||
// Win32-specific global timer data
|
// Win32-specific global timer data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWtimerWin32
|
typedef struct _GLFWtimeWin32
|
||||||
{
|
{
|
||||||
GLFWbool hasPC;
|
GLFWbool hasPC;
|
||||||
uint64_t frequency;
|
uint64_t frequency;
|
||||||
|
|
||||||
} _GLFWtimerWin32;
|
} _GLFWtimeWin32;
|
||||||
|
|
||||||
// Win32-specific thread local storage data
|
// Win32-specific global TLS data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWtlsWin32
|
typedef struct _GLFWtlsWin32
|
||||||
{
|
{
|
||||||
GLFWbool allocated;
|
GLFWbool allocated;
|
||||||
DWORD index;
|
DWORD context;
|
||||||
|
|
||||||
} _GLFWtlsWin32;
|
} _GLFWtlsWin32;
|
||||||
|
|
||||||
// Win32-specific mutex data
|
|
||||||
//
|
|
||||||
typedef struct _GLFWmutexWin32
|
|
||||||
{
|
|
||||||
GLFWbool allocated;
|
|
||||||
CRITICAL_SECTION section;
|
|
||||||
|
|
||||||
} _GLFWmutexWin32;
|
|
||||||
|
|
||||||
|
|
||||||
GLFWbool _glfwRegisterWindowClassWin32(void);
|
GLFWbool _glfwRegisterWindowClassWin32(void);
|
||||||
void _glfwUnregisterWindowClassWin32(void);
|
void _glfwUnregisterWindowClassWin32(void);
|
||||||
|
|
||||||
|
GLFWbool _glfwInitThreadLocalStorageWin32(void);
|
||||||
|
void _glfwTerminateThreadLocalStorageWin32(void);
|
||||||
|
|
||||||
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
||||||
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
||||||
void _glfwInputErrorWin32(int error, const char* description);
|
|
||||||
void _glfwUpdateKeyNamesWin32(void);
|
|
||||||
|
|
||||||
void _glfwInitTimerWin32(void);
|
void _glfwInitTimerWin32(void);
|
||||||
|
|
||||||
void _glfwPollMonitorsWin32(void);
|
|
||||||
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||||
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
|
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
|
||||||
|
|
||||||
|
#endif // _glfw3_win32_platform_h_
|
||||||
|
|||||||
+7
-7
@@ -40,13 +40,13 @@ void _glfwInitTimerWin32(void)
|
|||||||
|
|
||||||
if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency))
|
if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency))
|
||||||
{
|
{
|
||||||
_glfw.timer.win32.hasPC = GLFW_TRUE;
|
_glfw.win32_time.hasPC = GLFW_TRUE;
|
||||||
_glfw.timer.win32.frequency = frequency;
|
_glfw.win32_time.frequency = frequency;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_glfw.timer.win32.hasPC = GLFW_FALSE;
|
_glfw.win32_time.hasPC = GLFW_FALSE;
|
||||||
_glfw.timer.win32.frequency = 1000;
|
_glfw.win32_time.frequency = 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,18 +57,18 @@ void _glfwInitTimerWin32(void)
|
|||||||
|
|
||||||
uint64_t _glfwPlatformGetTimerValue(void)
|
uint64_t _glfwPlatformGetTimerValue(void)
|
||||||
{
|
{
|
||||||
if (_glfw.timer.win32.hasPC)
|
if (_glfw.win32_time.hasPC)
|
||||||
{
|
{
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*) &value);
|
QueryPerformanceCounter((LARGE_INTEGER*) &value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return (uint64_t) timeGetTime();
|
return (uint64_t) _glfw_timeGetTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t _glfwPlatformGetTimerFrequency(void)
|
uint64_t _glfwPlatformGetTimerFrequency(void)
|
||||||
{
|
{
|
||||||
return _glfw.timer.win32.frequency;
|
return _glfw.win32_time.frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,71 +27,43 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW internal API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GLFWbool _glfwInitThreadLocalStorageWin32(void)
|
||||||
|
{
|
||||||
|
_glfw.win32_tls.context = TlsAlloc();
|
||||||
|
if (_glfw.win32_tls.context == TLS_OUT_OF_INDEXES)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to allocate TLS index");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.win32_tls.allocated = GLFW_TRUE;
|
||||||
|
return GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwTerminateThreadLocalStorageWin32(void)
|
||||||
|
{
|
||||||
|
if (_glfw.win32_tls.allocated)
|
||||||
|
TlsFree(_glfw.win32_tls.context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
|
void _glfwPlatformSetCurrentContext(_GLFWwindow* context)
|
||||||
{
|
{
|
||||||
assert(tls->win32.allocated == GLFW_FALSE);
|
TlsSetValue(_glfw.win32_tls.context, context);
|
||||||
|
|
||||||
tls->win32.index = TlsAlloc();
|
|
||||||
if (tls->win32.index == TLS_OUT_OF_INDEXES)
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to allocate TLS index");
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
tls->win32.allocated = GLFW_TRUE;
|
|
||||||
return GLFW_TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
|
||||||
{
|
{
|
||||||
if (tls->win32.allocated)
|
return TlsGetValue(_glfw.win32_tls.context);
|
||||||
TlsFree(tls->win32.index);
|
|
||||||
memset(tls, 0, sizeof(_GLFWtls));
|
|
||||||
}
|
|
||||||
|
|
||||||
void* _glfwPlatformGetTls(_GLFWtls* tls)
|
|
||||||
{
|
|
||||||
assert(tls->win32.allocated == GLFW_TRUE);
|
|
||||||
return TlsGetValue(tls->win32.index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
|
|
||||||
{
|
|
||||||
assert(tls->win32.allocated == GLFW_TRUE);
|
|
||||||
TlsSetValue(tls->win32.index, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
assert(mutex->win32.allocated == GLFW_FALSE);
|
|
||||||
InitializeCriticalSection(&mutex->win32.section);
|
|
||||||
return mutex->win32.allocated = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
if (mutex->win32.allocated)
|
|
||||||
DeleteCriticalSection(&mutex->win32.section);
|
|
||||||
memset(mutex, 0, sizeof(_GLFWmutex));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
assert(mutex->win32.allocated == GLFW_TRUE);
|
|
||||||
EnterCriticalSection(&mutex->win32.section);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
|
|
||||||
{
|
|
||||||
assert(mutex->win32.allocated == GLFW_TRUE);
|
|
||||||
LeaveCriticalSection(&mutex->win32.section);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+133
-237
@@ -111,7 +111,7 @@ static HICON createIcon(const GLFWimage* image,
|
|||||||
unsigned char* source = image->pixels;
|
unsigned char* source = image->pixels;
|
||||||
|
|
||||||
ZeroMemory(&bi, sizeof(bi));
|
ZeroMemory(&bi, sizeof(bi));
|
||||||
bi.bV5Size = sizeof(bi);
|
bi.bV5Size = sizeof(BITMAPV5HEADER);
|
||||||
bi.bV5Width = image->width;
|
bi.bV5Width = image->width;
|
||||||
bi.bV5Height = -image->height;
|
bi.bV5Height = -image->height;
|
||||||
bi.bV5Planes = 1;
|
bi.bV5Planes = 1;
|
||||||
@@ -133,16 +133,16 @@ static HICON createIcon(const GLFWimage* image,
|
|||||||
|
|
||||||
if (!color)
|
if (!color)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to create RGBA bitmap");
|
"Win32: Failed to create RGBA bitmap");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mask = CreateBitmap(image->width, image->height, 1, 1, NULL);
|
mask = CreateBitmap(image->width, image->height, 1, 1, NULL);
|
||||||
if (!mask)
|
if (!mask)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to create mask bitmap");
|
"Win32: Failed to create mask bitmap");
|
||||||
DeleteObject(color);
|
DeleteObject(color);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -172,15 +172,9 @@ static HICON createIcon(const GLFWimage* image,
|
|||||||
if (!handle)
|
if (!handle)
|
||||||
{
|
{
|
||||||
if (icon)
|
if (icon)
|
||||||
{
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create icon");
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to create icon");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create cursor");
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to create cursor");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
@@ -369,19 +363,20 @@ static int getAsyncKeyMods(void)
|
|||||||
//
|
//
|
||||||
static int translateKey(WPARAM wParam, LPARAM lParam)
|
static int translateKey(WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
// The Ctrl keys require special handling
|
|
||||||
if (wParam == VK_CONTROL)
|
if (wParam == VK_CONTROL)
|
||||||
{
|
{
|
||||||
|
// The CTRL keys require special handling
|
||||||
|
|
||||||
MSG next;
|
MSG next;
|
||||||
DWORD time;
|
DWORD time;
|
||||||
|
|
||||||
// Right side keys have the extended key bit set
|
// Is this an extended key (i.e. right key)?
|
||||||
if (lParam & 0x01000000)
|
if (lParam & 0x01000000)
|
||||||
return GLFW_KEY_RIGHT_CONTROL;
|
return GLFW_KEY_RIGHT_CONTROL;
|
||||||
|
|
||||||
// HACK: Alt Gr sends Left Ctrl and then Right Alt in close sequence
|
// Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only
|
||||||
// We only want the Right Alt message, so if the next message is
|
// want the RALT message, so we try to see if the next message
|
||||||
// Right Alt we ignore this (synthetic) Left Ctrl message
|
// is a RALT message. In that case, this is a false LCTRL!
|
||||||
time = GetMessageTime();
|
time = GetMessageTime();
|
||||||
|
|
||||||
if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
|
if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
|
||||||
@@ -395,7 +390,8 @@ static int translateKey(WPARAM wParam, LPARAM lParam)
|
|||||||
(next.lParam & 0x01000000) &&
|
(next.lParam & 0x01000000) &&
|
||||||
next.time == time)
|
next.time == time)
|
||||||
{
|
{
|
||||||
// Next message is Right Alt down so discard this
|
// Next message is a RALT down message, which
|
||||||
|
// means that this is not a proper LCTRL message
|
||||||
return _GLFW_KEY_INVALID;
|
return _GLFW_KEY_INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -422,11 +418,6 @@ static GLFWbool acquireMonitor(_GLFWwindow* window)
|
|||||||
GLFWbool status;
|
GLFWbool status;
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
|
|
||||||
if (!_glfw.win32.acquiredMonitorCount)
|
|
||||||
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
|
|
||||||
if (!window->monitor->window)
|
|
||||||
_glfw.win32.acquiredMonitorCount++;
|
|
||||||
|
|
||||||
status = _glfwSetVideoModeWin32(window->monitor, &window->videoMode);
|
status = _glfwSetVideoModeWin32(window->monitor, &window->videoMode);
|
||||||
|
|
||||||
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
||||||
@@ -436,7 +427,7 @@ static GLFWbool acquireMonitor(_GLFWwindow* window)
|
|||||||
xpos, ypos, mode.width, mode.height,
|
xpos, ypos, mode.width, mode.height,
|
||||||
SWP_NOACTIVATE | SWP_NOCOPYBITS);
|
SWP_NOACTIVATE | SWP_NOCOPYBITS);
|
||||||
|
|
||||||
_glfwInputMonitorWindow(window->monitor, window);
|
_glfwInputMonitorWindowChange(window->monitor, window);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,11 +438,7 @@ static void releaseMonitor(_GLFWwindow* window)
|
|||||||
if (window->monitor->window != window)
|
if (window->monitor->window != window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_glfw.win32.acquiredMonitorCount--;
|
_glfwInputMonitorWindowChange(window->monitor, NULL);
|
||||||
if (!_glfw.win32.acquiredMonitorCount)
|
|
||||||
SetThreadExecutionState(ES_CONTINUOUS);
|
|
||||||
|
|
||||||
_glfwInputMonitorWindow(window->monitor, NULL);
|
|
||||||
_glfwRestoreVideoModeWin32(window->monitor);
|
_glfwRestoreVideoModeWin32(window->monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,23 +454,30 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
|
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case WM_DISPLAYCHANGE:
|
|
||||||
_glfwPollMonitorsWin32();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_DEVICECHANGE:
|
case WM_DEVICECHANGE:
|
||||||
{
|
{
|
||||||
if (wParam == DBT_DEVICEARRIVAL)
|
if (wParam == DBT_DEVNODES_CHANGED)
|
||||||
|
{
|
||||||
|
_glfwInputMonitorChange();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (wParam == DBT_DEVICEARRIVAL)
|
||||||
{
|
{
|
||||||
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
|
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
|
||||||
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
|
if (dbh)
|
||||||
_glfwDetectJoystickConnectionWin32();
|
{
|
||||||
|
if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
|
||||||
|
_glfwDetectJoystickConnectionWin32();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (wParam == DBT_DEVICEREMOVECOMPLETE)
|
else if (wParam == DBT_DEVICEREMOVECOMPLETE)
|
||||||
{
|
{
|
||||||
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
|
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
|
||||||
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
|
if (dbh)
|
||||||
_glfwDetectJoystickDisconnectionWin32();
|
{
|
||||||
|
if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
|
||||||
|
_glfwDetectJoystickDisconnectionWin32();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -495,47 +489,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
|
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case WM_MOUSEACTIVATE:
|
|
||||||
{
|
|
||||||
// HACK: Postpone cursor disabling when the window was activated by
|
|
||||||
// clicking a caption button
|
|
||||||
if (HIWORD(lParam) == WM_LBUTTONDOWN)
|
|
||||||
{
|
|
||||||
if (LOWORD(lParam) == HTCLOSE ||
|
|
||||||
LOWORD(lParam) == HTMINBUTTON ||
|
|
||||||
LOWORD(lParam) == HTMAXBUTTON)
|
|
||||||
{
|
|
||||||
window->win32.frameAction = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_CAPTURECHANGED:
|
|
||||||
{
|
|
||||||
// HACK: Disable the cursor once the caption button action has been
|
|
||||||
// completed or cancelled
|
|
||||||
if (lParam == 0 && window->win32.frameAction)
|
|
||||||
{
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
|
||||||
|
|
||||||
window->win32.frameAction = GLFW_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_SETFOCUS:
|
case WM_SETFOCUS:
|
||||||
{
|
{
|
||||||
_glfwInputWindowFocus(window, GLFW_TRUE);
|
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||||
|
|
||||||
// HACK: Do not disable cursor while the user is interacting with
|
|
||||||
// a caption button
|
|
||||||
if (window->win32.frameAction)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
||||||
|
|
||||||
@@ -584,12 +541,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_INPUTLANGCHANGE:
|
|
||||||
{
|
|
||||||
_glfwUpdateKeyNamesWin32();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
case WM_SYSCHAR:
|
case WM_SYSCHAR:
|
||||||
case WM_UNICHAR:
|
case WM_UNICHAR:
|
||||||
@@ -623,15 +574,14 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
|
|
||||||
if (action == GLFW_RELEASE && wParam == VK_SHIFT)
|
if (action == GLFW_RELEASE && wParam == VK_SHIFT)
|
||||||
{
|
{
|
||||||
// HACK: Release both Shift keys on Shift up event, as when both
|
// Release both Shift keys on Shift up event, as only one event
|
||||||
// are pressed the first release does not emit any event
|
// is sent even if both keys are released
|
||||||
// NOTE: The other half of this is in _glfwPlatformPollEvents
|
|
||||||
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods);
|
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods);
|
||||||
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods);
|
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods);
|
||||||
}
|
}
|
||||||
else if (wParam == VK_SNAPSHOT)
|
else if (wParam == VK_SNAPSHOT)
|
||||||
{
|
{
|
||||||
// HACK: Key down is not reported for the Print Screen key
|
// Key down is not reported for the Print Screen key
|
||||||
_glfwInputKey(window, key, scancode, GLFW_PRESS, mods);
|
_glfwInputKey(window, key, scancode, GLFW_PRESS, mods);
|
||||||
_glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);
|
_glfwInputKey(window, key, scancode, GLFW_RELEASE, mods);
|
||||||
}
|
}
|
||||||
@@ -650,7 +600,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
case WM_MBUTTONUP:
|
case WM_MBUTTONUP:
|
||||||
case WM_XBUTTONUP:
|
case WM_XBUTTONUP:
|
||||||
{
|
{
|
||||||
int i, button, action;
|
int button, action;
|
||||||
|
|
||||||
if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
|
if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
|
||||||
button = GLFW_MOUSE_BUTTON_LEFT;
|
button = GLFW_MOUSE_BUTTON_LEFT;
|
||||||
@@ -667,30 +617,16 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
uMsg == WM_MBUTTONDOWN || uMsg == WM_XBUTTONDOWN)
|
uMsg == WM_MBUTTONDOWN || uMsg == WM_XBUTTONDOWN)
|
||||||
{
|
{
|
||||||
action = GLFW_PRESS;
|
action = GLFW_PRESS;
|
||||||
|
SetCapture(hWnd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
action = GLFW_RELEASE;
|
|
||||||
|
|
||||||
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
|
|
||||||
{
|
{
|
||||||
if (window->mouseButtons[i] == GLFW_PRESS)
|
action = GLFW_RELEASE;
|
||||||
break;
|
ReleaseCapture();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i > GLFW_MOUSE_BUTTON_LAST)
|
|
||||||
SetCapture(hWnd);
|
|
||||||
|
|
||||||
_glfwInputMouseClick(window, button, action, getKeyMods());
|
_glfwInputMouseClick(window, button, action, getKeyMods());
|
||||||
|
|
||||||
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
|
|
||||||
{
|
|
||||||
if (window->mouseButtons[i] == GLFW_PRESS)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i > GLFW_MOUSE_BUTTON_LAST)
|
|
||||||
ReleaseCapture();
|
|
||||||
|
|
||||||
if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP)
|
if (uMsg == WM_XBUTTONDOWN || uMsg == WM_XBUTTONUP)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@@ -702,11 +638,20 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
const int x = GET_X_LPARAM(lParam);
|
const int x = GET_X_LPARAM(lParam);
|
||||||
const int y = GET_Y_LPARAM(lParam);
|
const int y = GET_Y_LPARAM(lParam);
|
||||||
|
|
||||||
// Disabled cursor motion input is provided by WM_INPUT
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
break;
|
{
|
||||||
|
const int dx = x - window->win32.lastCursorPosX;
|
||||||
|
const int dy = y - window->win32.lastCursorPosY;
|
||||||
|
|
||||||
_glfwInputCursorPos(window, x, y);
|
if (_glfw.win32.disabledCursorWindow != window)
|
||||||
|
break;
|
||||||
|
|
||||||
|
_glfwInputCursorPos(window,
|
||||||
|
window->virtualCursorPosX + dx,
|
||||||
|
window->virtualCursorPosY + dy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_glfwInputCursorPos(window, x, y);
|
||||||
|
|
||||||
window->win32.lastCursorPosX = x;
|
window->win32.lastCursorPosX = x;
|
||||||
window->win32.lastCursorPosY = y;
|
window->win32.lastCursorPosY = y;
|
||||||
@@ -727,56 +672,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_INPUT:
|
|
||||||
{
|
|
||||||
UINT size;
|
|
||||||
HRAWINPUT ri = (HRAWINPUT) lParam;
|
|
||||||
RAWINPUT* data;
|
|
||||||
int dx, dy;
|
|
||||||
|
|
||||||
// Only process input when disabled cursor mode is applied
|
|
||||||
if (_glfw.win32.disabledCursorWindow != window)
|
|
||||||
break;
|
|
||||||
|
|
||||||
GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
|
|
||||||
if (size > (UINT) _glfw.win32.rawInputSize)
|
|
||||||
{
|
|
||||||
free(_glfw.win32.rawInput);
|
|
||||||
_glfw.win32.rawInput = calloc(size, 1);
|
|
||||||
_glfw.win32.rawInputSize = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = _glfw.win32.rawInputSize;
|
|
||||||
if (GetRawInputData(ri, RID_INPUT,
|
|
||||||
_glfw.win32.rawInput, &size,
|
|
||||||
sizeof(RAWINPUTHEADER)) == (UINT) -1)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to retrieve raw input data");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = _glfw.win32.rawInput;
|
|
||||||
if (data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
|
|
||||||
{
|
|
||||||
dx = data->data.mouse.lLastX - window->win32.lastCursorPosX;
|
|
||||||
dy = data->data.mouse.lLastY - window->win32.lastCursorPosY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dx = data->data.mouse.lLastX;
|
|
||||||
dy = data->data.mouse.lLastY;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputCursorPos(window,
|
|
||||||
window->virtualCursorPosX + dx,
|
|
||||||
window->virtualCursorPosY + dy);
|
|
||||||
|
|
||||||
window->win32.lastCursorPosX += dx;
|
|
||||||
window->win32.lastCursorPosY += dy;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_MOUSELEAVE:
|
case WM_MOUSELEAVE:
|
||||||
{
|
{
|
||||||
window->win32.cursorTracked = GLFW_FALSE;
|
window->win32.cursorTracked = GLFW_FALSE;
|
||||||
@@ -801,8 +696,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
case WM_ENTERMENULOOP:
|
case WM_ENTERMENULOOP:
|
||||||
{
|
{
|
||||||
// HACK: Postpone cursor disabling while the user is moving or
|
|
||||||
// resizing the window or using the menu
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
|
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
|
||||||
|
|
||||||
@@ -812,8 +705,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
case WM_EXITSIZEMOVE:
|
case WM_EXITSIZEMOVE:
|
||||||
case WM_EXITMENULOOP:
|
case WM_EXITMENULOOP:
|
||||||
{
|
{
|
||||||
// HACK: Disable the cursor once the user is done moving or
|
|
||||||
// resizing the window or using the menu
|
|
||||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||||
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
|
||||||
|
|
||||||
@@ -994,7 +885,7 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
// NOTE: This window placement is temporary and approximate, as the
|
// NOTE: This window placement is temporary and approximate, as the
|
||||||
// correct position and size cannot be known until the monitor
|
// correct position and size cannot be known until the monitor
|
||||||
// video mode has been picked in _glfwSetVideoModeWin32
|
// video mode has been set
|
||||||
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
|
_glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
|
||||||
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
_glfwPlatformGetVideoMode(window->monitor, &mode);
|
||||||
fullWidth = mode.width;
|
fullWidth = mode.width;
|
||||||
@@ -1015,7 +906,11 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
|
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
|
||||||
if (!wideTitle)
|
if (!wideTitle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to convert window title to UTF-16");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
window->win32.handle = CreateWindowExW(exStyle,
|
window->win32.handle = CreateWindowExW(exStyle,
|
||||||
_GLFW_WNDCLASSNAME,
|
_GLFW_WNDCLASSNAME,
|
||||||
@@ -1032,8 +927,7 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
if (!window->win32.handle)
|
if (!window->win32.handle)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create window");
|
||||||
"Win32: Failed to create window");
|
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1087,8 +981,8 @@ GLFWbool _glfwRegisterWindowClassWin32(void)
|
|||||||
|
|
||||||
if (!RegisterClassExW(&wc))
|
if (!RegisterClassExW(&wc))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to register window class");
|
"Win32: Failed to register window class");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1124,20 +1018,13 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
|
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
else
|
||||||
{
|
{
|
||||||
if (!_glfwInitEGL())
|
if (!_glfwInitEGL())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwInitOSMesa())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->monitor)
|
if (window->monitor)
|
||||||
@@ -1147,8 +1034,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
if (!acquireMonitor(window))
|
if (!acquireMonitor(window))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (wndconfig->centerCursor)
|
centerCursor(window);
|
||||||
centerCursor(window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
@@ -1183,7 +1069,11 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
|||||||
{
|
{
|
||||||
WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title);
|
WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title);
|
||||||
if (!wideTitle)
|
if (!wideTitle)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to convert window title to UTF-16");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SetWindowTextW(window->win32.handle, wideTitle);
|
SetWindowTextW(window->win32.handle, wideTitle);
|
||||||
free(wideTitle);
|
free(wideTitle);
|
||||||
@@ -1363,11 +1253,6 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
|
|||||||
ShowWindow(window->win32.handle, SW_HIDE);
|
ShowWindow(window->win32.handle, SW_HIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
FlashWindow(window->win32.handle, TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
BringWindowToTop(window->win32.handle);
|
BringWindowToTop(window->win32.handle);
|
||||||
@@ -1508,9 +1393,9 @@ void _glfwPlatformPollEvents(void)
|
|||||||
{
|
{
|
||||||
if (msg.message == WM_QUIT)
|
if (msg.message == WM_QUIT)
|
||||||
{
|
{
|
||||||
// NOTE: While GLFW does not itself post WM_QUIT, other processes
|
// Treat WM_QUIT as a close on all windows
|
||||||
// may post it to this one, for example Task Manager
|
// While GLFW does not itself post WM_QUIT, other processes may post
|
||||||
// HACK: Treat WM_QUIT as a close on all windows
|
// it to this one, for example Task Manager
|
||||||
|
|
||||||
window = _glfw.windowListHead;
|
window = _glfw.windowListHead;
|
||||||
while (window)
|
while (window)
|
||||||
@@ -1529,28 +1414,25 @@ void _glfwPlatformPollEvents(void)
|
|||||||
handle = GetActiveWindow();
|
handle = GetActiveWindow();
|
||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
// NOTE: Shift keys on Windows tend to "stick" when both are pressed as
|
// LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix)
|
||||||
// no key up message is generated by the first key release
|
// This is the only async event handling in GLFW, but it solves some
|
||||||
// The other half of this is in the handling of WM_KEYUP
|
// nasty problems
|
||||||
// HACK: Query actual key state and synthesize release events as needed
|
|
||||||
window = GetPropW(handle, L"GLFW");
|
window = GetPropW(handle, L"GLFW");
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
const GLFWbool lshift = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;
|
const int mods = getAsyncKeyMods();
|
||||||
const GLFWbool rshift = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;
|
|
||||||
|
|
||||||
if (!lshift && window->keys[GLFW_KEY_LEFT_SHIFT] == GLFW_PRESS)
|
// Get current state of left and right shift keys
|
||||||
{
|
const int lshiftDown = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;
|
||||||
const int mods = getAsyncKeyMods();
|
const int rshiftDown = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;
|
||||||
const int scancode = _glfw.win32.scancodes[GLFW_KEY_LEFT_SHIFT];
|
|
||||||
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods);
|
// See if this differs from our belief of what has happened
|
||||||
}
|
// (we only have to check for lost key up events)
|
||||||
else if (!rshift && window->keys[GLFW_KEY_RIGHT_SHIFT] == GLFW_PRESS)
|
if (!lshiftDown && window->keys[GLFW_KEY_LEFT_SHIFT] == 1)
|
||||||
{
|
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, 0, GLFW_RELEASE, mods);
|
||||||
const int mods = getAsyncKeyMods();
|
|
||||||
const int scancode = _glfw.win32.scancodes[GLFW_KEY_RIGHT_SHIFT];
|
if (!rshiftDown && window->keys[GLFW_KEY_RIGHT_SHIFT] == 1)
|
||||||
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods);
|
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, 0, GLFW_RELEASE, mods);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1620,45 +1502,48 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
{
|
{
|
||||||
if (mode == GLFW_CURSOR_DISABLED)
|
if (mode == GLFW_CURSOR_DISABLED)
|
||||||
{
|
{
|
||||||
const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
|
|
||||||
|
|
||||||
_glfw.win32.disabledCursorWindow = window;
|
_glfw.win32.disabledCursorWindow = window;
|
||||||
_glfwPlatformGetCursorPos(window,
|
_glfwPlatformGetCursorPos(window,
|
||||||
&_glfw.win32.restoreCursorPosX,
|
&_glfw.win32.restoreCursorPosX,
|
||||||
&_glfw.win32.restoreCursorPosY);
|
&_glfw.win32.restoreCursorPosY);
|
||||||
centerCursor(window);
|
centerCursor(window);
|
||||||
updateClipRect(window);
|
updateClipRect(window);
|
||||||
|
|
||||||
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to register raw input device");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (_glfw.win32.disabledCursorWindow == window)
|
else if (_glfw.win32.disabledCursorWindow == window)
|
||||||
{
|
{
|
||||||
const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
|
|
||||||
|
|
||||||
_glfw.win32.disabledCursorWindow = NULL;
|
_glfw.win32.disabledCursorWindow = NULL;
|
||||||
updateClipRect(NULL);
|
updateClipRect(NULL);
|
||||||
_glfwPlatformSetCursorPos(window,
|
_glfwPlatformSetCursorPos(window,
|
||||||
_glfw.win32.restoreCursorPosX,
|
_glfw.win32.restoreCursorPosX,
|
||||||
_glfw.win32.restoreCursorPosY);
|
_glfw.win32.restoreCursorPosY);
|
||||||
|
|
||||||
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
|
|
||||||
{
|
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to remove raw input device");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cursorInClientArea(window))
|
if (cursorInClientArea(window))
|
||||||
updateCursorImage(window);
|
updateCursorImage(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetKeyName(int key, int scancode)
|
||||||
{
|
{
|
||||||
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
|
WCHAR name[16];
|
||||||
|
|
||||||
|
if (key != GLFW_KEY_UNKNOWN)
|
||||||
|
scancode = _glfw.win32.scancodes[key];
|
||||||
|
|
||||||
|
if (!_glfwIsPrintable(_glfw.win32.keycodes[scancode]))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!GetKeyNameTextW(scancode << 16, name, sizeof(name) / sizeof(WCHAR)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!WideCharToMultiByte(CP_UTF8, 0, name, -1,
|
||||||
|
_glfw.win32.keyName,
|
||||||
|
sizeof(_glfw.win32.keyName),
|
||||||
|
NULL, NULL))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _glfw.win32.keyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformGetKeyScancode(int key)
|
int _glfwPlatformGetKeyScancode(int key)
|
||||||
@@ -1683,8 +1568,8 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
|||||||
CopyCursor(LoadCursorW(NULL, translateCursorShape(shape)));
|
CopyCursor(LoadCursorW(NULL, translateCursorShape(shape)));
|
||||||
if (!cursor->win32.handle)
|
if (!cursor->win32.handle)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to create standard cursor");
|
"Win32: Failed to create standard cursor");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1711,22 +1596,26 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
|||||||
|
|
||||||
characterCount = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
|
characterCount = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
|
||||||
if (!characterCount)
|
if (!characterCount)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to convert clipboard string to UTF-16");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR));
|
object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR));
|
||||||
if (!object)
|
if (!object)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(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;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = GlobalLock(object);
|
buffer = GlobalLock(object);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to lock global handle");
|
|
||||||
GlobalFree(object);
|
GlobalFree(object);
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1735,9 +1624,9 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
|||||||
|
|
||||||
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
|
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to open clipboard");
|
|
||||||
GlobalFree(object);
|
GlobalFree(object);
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1753,35 +1642,43 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
|||||||
|
|
||||||
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
|
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");
|
||||||
"Win32: Failed to open clipboard");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
object = GetClipboardData(CF_UNICODETEXT);
|
object = GetClipboardData(CF_UNICODETEXT);
|
||||||
if (!object)
|
if (!object)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_FORMAT_UNAVAILABLE,
|
|
||||||
"Win32: Failed to convert clipboard to string");
|
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
|
"Win32: Failed to convert clipboard to string");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer = GlobalLock(object);
|
buffer = GlobalLock(object);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
|
||||||
"Win32: Failed to lock global handle");
|
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(_glfw.win32.clipboardString);
|
free(_glfw.win32.clipboardString);
|
||||||
_glfw.win32.clipboardString = _glfwCreateUTF8FromWideStringWin32(buffer);
|
_glfw.win32.clipboardString =
|
||||||
|
_glfwCreateUTF8FromWideStringWin32(buffer);
|
||||||
|
|
||||||
GlobalUnlock(object);
|
GlobalUnlock(object);
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
|
|
||||||
|
if (!_glfw.win32.clipboardString)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to convert wide string to UTF-8");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return _glfw.win32.clipboardString;
|
return _glfw.win32.clipboardString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1798,8 +1695,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|||||||
VkPhysicalDevice device,
|
VkPhysicalDevice device,
|
||||||
uint32_t queuefamily)
|
uint32_t queuefamily)
|
||||||
{
|
{
|
||||||
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
|
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR =
|
||||||
vkGetPhysicalDeviceWin32PresentationSupportKHR =
|
|
||||||
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
||||||
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
|
||||||
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
||||||
|
|||||||
+88
-109
@@ -40,26 +40,30 @@
|
|||||||
|
|
||||||
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
|
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
|
||||||
{
|
{
|
||||||
if (window->callbacks.focus)
|
if (focused)
|
||||||
window->callbacks.focus((GLFWwindow*) window, focused);
|
|
||||||
|
|
||||||
if (!focused)
|
|
||||||
{
|
{
|
||||||
int key, button;
|
if (window->callbacks.focus)
|
||||||
|
window->callbacks.focus((GLFWwindow*) window, focused);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
for (key = 0; key <= GLFW_KEY_LAST; key++)
|
if (window->callbacks.focus)
|
||||||
|
window->callbacks.focus((GLFWwindow*) window, focused);
|
||||||
|
|
||||||
|
// Release all pressed keyboard keys
|
||||||
|
for (i = 0; i <= GLFW_KEY_LAST; i++)
|
||||||
{
|
{
|
||||||
if (window->keys[key] == GLFW_PRESS)
|
if (window->keys[i] == GLFW_PRESS)
|
||||||
{
|
_glfwInputKey(window, i, 0, GLFW_RELEASE, 0);
|
||||||
const int scancode = _glfwPlatformGetKeyScancode(key);
|
|
||||||
_glfwInputKey(window, key, scancode, GLFW_RELEASE, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (button = 0; button <= GLFW_MOUSE_BUTTON_LAST; button++)
|
// Release all pressed mouse buttons
|
||||||
|
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
|
||||||
{
|
{
|
||||||
if (window->mouseButtons[button] == GLFW_PRESS)
|
if (window->mouseButtons[i] == GLFW_PRESS)
|
||||||
_glfwInputMouseClick(window, button, GLFW_RELEASE, 0);
|
_glfwInputMouseClick(window, i, GLFW_RELEASE, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,8 +134,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
|||||||
_GLFWwindow* previous;
|
_GLFWwindow* previous;
|
||||||
|
|
||||||
assert(title != NULL);
|
assert(title != NULL);
|
||||||
assert(width >= 0);
|
|
||||||
assert(height >= 0);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
@@ -192,7 +194,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
|||||||
window->denom = GLFW_DONT_CARE;
|
window->denom = GLFW_DONT_CARE;
|
||||||
|
|
||||||
// Save the currently current context so it can be restored later
|
// Save the currently current context so it can be restored later
|
||||||
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
|
previous = _glfwPlatformGetCurrentContext();
|
||||||
if (ctxconfig.client != GLFW_NO_API)
|
if (ctxconfig.client != GLFW_NO_API)
|
||||||
glfwMakeContextCurrent(NULL);
|
glfwMakeContextCurrent(NULL);
|
||||||
|
|
||||||
@@ -237,15 +239,15 @@ void glfwDefaultWindowHints(void)
|
|||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
|
memset(&_glfw.hints, 0, sizeof(_glfw.hints));
|
||||||
|
|
||||||
// The default is OpenGL with minimum version 1.0
|
// The default is OpenGL with minimum version 1.0
|
||||||
memset(&_glfw.hints.context, 0, sizeof(_glfw.hints.context));
|
|
||||||
_glfw.hints.context.client = GLFW_OPENGL_API;
|
_glfw.hints.context.client = GLFW_OPENGL_API;
|
||||||
_glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API;
|
_glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API;
|
||||||
_glfw.hints.context.major = 1;
|
_glfw.hints.context.major = 1;
|
||||||
_glfw.hints.context.minor = 0;
|
_glfw.hints.context.minor = 0;
|
||||||
|
|
||||||
// The default is a focused, visible, resizable window with decorations
|
// The default is a focused, visible, resizable window with decorations
|
||||||
memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window));
|
|
||||||
_glfw.hints.window.resizable = GLFW_TRUE;
|
_glfw.hints.window.resizable = GLFW_TRUE;
|
||||||
_glfw.hints.window.visible = GLFW_TRUE;
|
_glfw.hints.window.visible = GLFW_TRUE;
|
||||||
_glfw.hints.window.decorated = GLFW_TRUE;
|
_glfw.hints.window.decorated = GLFW_TRUE;
|
||||||
@@ -254,7 +256,6 @@ void glfwDefaultWindowHints(void)
|
|||||||
|
|
||||||
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
|
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
|
||||||
// double buffered
|
// double buffered
|
||||||
memset(&_glfw.hints.framebuffer, 0, sizeof(_glfw.hints.framebuffer));
|
|
||||||
_glfw.hints.framebuffer.redBits = 8;
|
_glfw.hints.framebuffer.redBits = 8;
|
||||||
_glfw.hints.framebuffer.greenBits = 8;
|
_glfw.hints.framebuffer.greenBits = 8;
|
||||||
_glfw.hints.framebuffer.blueBits = 8;
|
_glfw.hints.framebuffer.blueBits = 8;
|
||||||
@@ -278,118 +279,110 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
|||||||
{
|
{
|
||||||
case GLFW_RED_BITS:
|
case GLFW_RED_BITS:
|
||||||
_glfw.hints.framebuffer.redBits = value;
|
_glfw.hints.framebuffer.redBits = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_GREEN_BITS:
|
case GLFW_GREEN_BITS:
|
||||||
_glfw.hints.framebuffer.greenBits = value;
|
_glfw.hints.framebuffer.greenBits = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_BLUE_BITS:
|
case GLFW_BLUE_BITS:
|
||||||
_glfw.hints.framebuffer.blueBits = value;
|
_glfw.hints.framebuffer.blueBits = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_ALPHA_BITS:
|
case GLFW_ALPHA_BITS:
|
||||||
_glfw.hints.framebuffer.alphaBits = value;
|
_glfw.hints.framebuffer.alphaBits = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_DEPTH_BITS:
|
case GLFW_DEPTH_BITS:
|
||||||
_glfw.hints.framebuffer.depthBits = value;
|
_glfw.hints.framebuffer.depthBits = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_STENCIL_BITS:
|
case GLFW_STENCIL_BITS:
|
||||||
_glfw.hints.framebuffer.stencilBits = value;
|
_glfw.hints.framebuffer.stencilBits = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_ACCUM_RED_BITS:
|
case GLFW_ACCUM_RED_BITS:
|
||||||
_glfw.hints.framebuffer.accumRedBits = value;
|
_glfw.hints.framebuffer.accumRedBits = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_ACCUM_GREEN_BITS:
|
case GLFW_ACCUM_GREEN_BITS:
|
||||||
_glfw.hints.framebuffer.accumGreenBits = value;
|
_glfw.hints.framebuffer.accumGreenBits = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_ACCUM_BLUE_BITS:
|
case GLFW_ACCUM_BLUE_BITS:
|
||||||
_glfw.hints.framebuffer.accumBlueBits = value;
|
_glfw.hints.framebuffer.accumBlueBits = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_ACCUM_ALPHA_BITS:
|
case GLFW_ACCUM_ALPHA_BITS:
|
||||||
_glfw.hints.framebuffer.accumAlphaBits = value;
|
_glfw.hints.framebuffer.accumAlphaBits = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_AUX_BUFFERS:
|
case GLFW_AUX_BUFFERS:
|
||||||
_glfw.hints.framebuffer.auxBuffers = value;
|
_glfw.hints.framebuffer.auxBuffers = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_STEREO:
|
case GLFW_STEREO:
|
||||||
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_DOUBLEBUFFER:
|
case GLFW_DOUBLEBUFFER:
|
||||||
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_SAMPLES:
|
case GLFW_SAMPLES:
|
||||||
_glfw.hints.framebuffer.samples = value;
|
_glfw.hints.framebuffer.samples = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_SRGB_CAPABLE:
|
case GLFW_SRGB_CAPABLE:
|
||||||
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_RESIZABLE:
|
case GLFW_RESIZABLE:
|
||||||
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_DECORATED:
|
case GLFW_DECORATED:
|
||||||
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_FOCUSED:
|
case GLFW_FOCUSED:
|
||||||
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_AUTO_ICONIFY:
|
case GLFW_AUTO_ICONIFY:
|
||||||
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_FLOATING:
|
case GLFW_FLOATING:
|
||||||
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_MAXIMIZED:
|
case GLFW_MAXIMIZED:
|
||||||
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_VISIBLE:
|
case GLFW_VISIBLE:
|
||||||
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
||||||
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_COCOA_FRAME_AUTOSAVE:
|
|
||||||
_glfw.hints.window.ns.frame = value ? GLFW_TRUE : GLFW_FALSE;
|
|
||||||
return;
|
|
||||||
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
|
||||||
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
|
||||||
return;
|
|
||||||
case GLFW_CENTER_CURSOR:
|
|
||||||
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
|
||||||
return;
|
|
||||||
case GLFW_CLIENT_API:
|
case GLFW_CLIENT_API:
|
||||||
_glfw.hints.context.client = value;
|
_glfw.hints.context.client = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_CONTEXT_CREATION_API:
|
case GLFW_CONTEXT_CREATION_API:
|
||||||
_glfw.hints.context.source = value;
|
_glfw.hints.context.source = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_CONTEXT_VERSION_MAJOR:
|
case GLFW_CONTEXT_VERSION_MAJOR:
|
||||||
_glfw.hints.context.major = value;
|
_glfw.hints.context.major = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_CONTEXT_VERSION_MINOR:
|
case GLFW_CONTEXT_VERSION_MINOR:
|
||||||
_glfw.hints.context.minor = value;
|
_glfw.hints.context.minor = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_CONTEXT_ROBUSTNESS:
|
case GLFW_CONTEXT_ROBUSTNESS:
|
||||||
_glfw.hints.context.robustness = value;
|
_glfw.hints.context.robustness = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_OPENGL_FORWARD_COMPAT:
|
case GLFW_OPENGL_FORWARD_COMPAT:
|
||||||
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_OPENGL_DEBUG_CONTEXT:
|
case GLFW_OPENGL_DEBUG_CONTEXT:
|
||||||
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_CONTEXT_NO_ERROR:
|
case GLFW_CONTEXT_NO_ERROR:
|
||||||
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
break;
|
||||||
case GLFW_OPENGL_PROFILE:
|
case GLFW_OPENGL_PROFILE:
|
||||||
_glfw.hints.context.profile = value;
|
_glfw.hints.context.profile = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_CONTEXT_RELEASE_BEHAVIOR:
|
case GLFW_CONTEXT_RELEASE_BEHAVIOR:
|
||||||
_glfw.hints.context.release = value;
|
_glfw.hints.context.release = value;
|
||||||
return;
|
break;
|
||||||
case GLFW_REFRESH_RATE:
|
case GLFW_REFRESH_RATE:
|
||||||
_glfw.hints.refreshRate = value;
|
_glfw.hints.refreshRate = value;
|
||||||
return;
|
break;
|
||||||
|
default:
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint %i", hint);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
||||||
@@ -407,7 +400,7 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
|||||||
|
|
||||||
// The window's context must not be current on another thread when the
|
// The window's context must not be current on another thread when the
|
||||||
// window is destroyed
|
// window is destroyed
|
||||||
if (window == _glfwPlatformGetTls(&_glfw.contextSlot))
|
if (window == _glfwPlatformGetCurrentContext())
|
||||||
glfwMakeContextCurrent(NULL);
|
glfwMakeContextCurrent(NULL);
|
||||||
|
|
||||||
_glfwPlatformDestroyWindow(window);
|
_glfwPlatformDestroyWindow(window);
|
||||||
@@ -447,6 +440,7 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
|
|||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
assert(window != NULL);
|
assert(window != NULL);
|
||||||
|
|
||||||
assert(title != NULL);
|
assert(title != NULL);
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
@@ -510,8 +504,6 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
|
|||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
assert(window != NULL);
|
assert(window != NULL);
|
||||||
assert(width >= 0);
|
|
||||||
assert(height >= 0);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
@@ -570,8 +562,6 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
|
|||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
assert(window != NULL);
|
assert(window != NULL);
|
||||||
assert(numer != 0);
|
|
||||||
assert(denom != 0);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
@@ -674,16 +664,6 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
|
|||||||
_glfwPlatformFocusWindow(window);
|
_glfwPlatformFocusWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle)
|
|
||||||
{
|
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
|
||||||
assert(window != NULL);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
|
||||||
|
|
||||||
_glfwPlatformRequestWindowAttention(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI void glfwHideWindow(GLFWwindow* handle)
|
GLFWAPI void glfwHideWindow(GLFWwindow* handle)
|
||||||
{
|
{
|
||||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||||
@@ -756,7 +736,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
|||||||
return window->context.noerror;
|
return window->context.noerror;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute %i", attrib);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -769,37 +749,41 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
|
|||||||
|
|
||||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
|
||||||
if (attrib == GLFW_AUTO_ICONIFY)
|
switch (attrib)
|
||||||
window->autoIconify = value;
|
|
||||||
else if (attrib == GLFW_RESIZABLE)
|
|
||||||
{
|
{
|
||||||
if (window->resizable == value)
|
case GLFW_RESIZABLE:
|
||||||
|
if (window->resizable != value)
|
||||||
|
{
|
||||||
|
window->resizable = value;
|
||||||
|
if (!window->monitor)
|
||||||
|
_glfwPlatformSetWindowResizable(window, value);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
window->resizable = value;
|
case GLFW_DECORATED:
|
||||||
if (!window->monitor)
|
if (window->decorated != value)
|
||||||
_glfwPlatformSetWindowResizable(window, value);
|
{
|
||||||
}
|
window->decorated = value;
|
||||||
else if (attrib == GLFW_DECORATED)
|
if (!window->monitor)
|
||||||
{
|
_glfwPlatformSetWindowDecorated(window, value);
|
||||||
if (window->decorated == value)
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
window->decorated = value;
|
case GLFW_FLOATING:
|
||||||
if (!window->monitor)
|
if (window->floating != value)
|
||||||
_glfwPlatformSetWindowDecorated(window, value);
|
{
|
||||||
}
|
window->floating = value;
|
||||||
else if (attrib == GLFW_FLOATING)
|
if (!window->monitor)
|
||||||
{
|
_glfwPlatformSetWindowFloating(window, value);
|
||||||
if (window->floating == value)
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
window->floating = value;
|
case GLFW_AUTO_ICONIFY:
|
||||||
if (!window->monitor)
|
window->autoIconify = value;
|
||||||
_glfwPlatformSetWindowFloating(window, value);
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute %i", attrib);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
|
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)
|
||||||
@@ -820,8 +804,6 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
|
|||||||
_GLFWwindow* window = (_GLFWwindow*) wh;
|
_GLFWwindow* window = (_GLFWwindow*) wh;
|
||||||
_GLFWmonitor* monitor = (_GLFWmonitor*) mh;
|
_GLFWmonitor* monitor = (_GLFWmonitor*) mh;
|
||||||
assert(window != NULL);
|
assert(window != NULL);
|
||||||
assert(width >= 0);
|
|
||||||
assert(height >= 0);
|
|
||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
@@ -975,9 +957,6 @@ GLFWAPI void glfwWaitEvents(void)
|
|||||||
GLFWAPI void glfwWaitEventsTimeout(double timeout)
|
GLFWAPI void glfwWaitEventsTimeout(double timeout)
|
||||||
{
|
{
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
assert(timeout == timeout);
|
|
||||||
assert(timeout >= 0.0);
|
|
||||||
assert(timeout <= DBL_MAX);
|
|
||||||
|
|
||||||
if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)
|
if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)
|
||||||
{
|
{
|
||||||
|
|||||||
+11
-5
@@ -109,8 +109,6 @@ static void pointerHandleButton(void* data,
|
|||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_glfw.wl.pointerSerial = serial;
|
|
||||||
|
|
||||||
/* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
|
/* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
|
||||||
* codes. */
|
* codes. */
|
||||||
glfwButton = button - BTN_LEFT;
|
glfwButton = button - BTN_LEFT;
|
||||||
@@ -294,7 +292,7 @@ static int toGLFWKeyCode(uint32_t key)
|
|||||||
|
|
||||||
static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
|
static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
|
||||||
{
|
{
|
||||||
if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)
|
if (sym == XKB_KEY_NoSymbol)
|
||||||
return sym;
|
return sym;
|
||||||
if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)
|
if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)
|
||||||
!= XKB_COMPOSE_FEED_ACCEPTED)
|
!= XKB_COMPOSE_FEED_ACCEPTED)
|
||||||
@@ -521,7 +519,6 @@ static void createKeyTables(void)
|
|||||||
_glfw.wl.keycodes[KEY_8] = GLFW_KEY_8;
|
_glfw.wl.keycodes[KEY_8] = GLFW_KEY_8;
|
||||||
_glfw.wl.keycodes[KEY_9] = GLFW_KEY_9;
|
_glfw.wl.keycodes[KEY_9] = GLFW_KEY_9;
|
||||||
_glfw.wl.keycodes[KEY_0] = GLFW_KEY_0;
|
_glfw.wl.keycodes[KEY_0] = GLFW_KEY_0;
|
||||||
_glfw.wl.keycodes[KEY_SPACE] = GLFW_KEY_SPACE;
|
|
||||||
_glfw.wl.keycodes[KEY_MINUS] = GLFW_KEY_MINUS;
|
_glfw.wl.keycodes[KEY_MINUS] = GLFW_KEY_MINUS;
|
||||||
_glfw.wl.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL;
|
_glfw.wl.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL;
|
||||||
_glfw.wl.keycodes[KEY_Q] = GLFW_KEY_Q;
|
_glfw.wl.keycodes[KEY_Q] = GLFW_KEY_Q;
|
||||||
@@ -653,6 +650,9 @@ int _glfwPlatformInit(void)
|
|||||||
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
|
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
|
||||||
wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL);
|
wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL);
|
||||||
|
|
||||||
|
_glfw.wl.monitors = calloc(4, sizeof(_GLFWmonitor*));
|
||||||
|
_glfw.wl.monitorsSize = 4;
|
||||||
|
|
||||||
createKeyTables();
|
createKeyTables();
|
||||||
|
|
||||||
_glfw.wl.xkb.context = xkb_context_new(0);
|
_glfw.wl.xkb.context = xkb_context_new(0);
|
||||||
@@ -669,6 +669,9 @@ int _glfwPlatformInit(void)
|
|||||||
// Sync so we got all initial output events
|
// Sync so we got all initial output events
|
||||||
wl_display_roundtrip(_glfw.wl.display);
|
wl_display_roundtrip(_glfw.wl.display);
|
||||||
|
|
||||||
|
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!_glfwInitJoysticksLinux())
|
if (!_glfwInitJoysticksLinux())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
@@ -694,6 +697,7 @@ void _glfwPlatformTerminate(void)
|
|||||||
{
|
{
|
||||||
_glfwTerminateEGL();
|
_glfwTerminateEGL();
|
||||||
_glfwTerminateJoysticksLinux();
|
_glfwTerminateJoysticksLinux();
|
||||||
|
_glfwTerminateThreadLocalStoragePOSIX();
|
||||||
|
|
||||||
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
|
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
|
||||||
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
xkb_keymap_unref(_glfw.wl.xkb.keymap);
|
||||||
@@ -737,7 +741,9 @@ const char* _glfwPlatformGetVersionString(void)
|
|||||||
#else
|
#else
|
||||||
" gettimeofday"
|
" gettimeofday"
|
||||||
#endif
|
#endif
|
||||||
" evdev"
|
#if defined(__linux__)
|
||||||
|
" /dev/js"
|
||||||
|
#endif
|
||||||
#if defined(_GLFW_BUILD_DLL)
|
#if defined(_GLFW_BUILD_DLL)
|
||||||
" shared"
|
" shared"
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+107
-23
@@ -32,6 +32,12 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct _GLFWvidmodeWayland
|
||||||
|
{
|
||||||
|
GLFWvidmode base;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
static void geometry(void* data,
|
static void geometry(void* data,
|
||||||
struct wl_output* output,
|
struct wl_output* output,
|
||||||
int32_t x,
|
int32_t x,
|
||||||
@@ -44,15 +50,21 @@ static void geometry(void* data,
|
|||||||
int32_t transform)
|
int32_t transform)
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor *monitor = data;
|
struct _GLFWmonitor *monitor = data;
|
||||||
char name[1024];
|
char* name;
|
||||||
|
size_t nameLength;
|
||||||
|
|
||||||
monitor->wl.x = x;
|
monitor->wl.x = x;
|
||||||
monitor->wl.y = y;
|
monitor->wl.y = y;
|
||||||
monitor->widthMM = physicalWidth;
|
monitor->widthMM = physicalWidth;
|
||||||
monitor->heightMM = physicalHeight;
|
monitor->heightMM = physicalHeight;
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "%s %s", make, model);
|
nameLength = strlen(make) + 1 + strlen(model) + 1;
|
||||||
monitor->name = strdup(name);
|
name = realloc(monitor->name, nameLength);
|
||||||
|
if (name)
|
||||||
|
{
|
||||||
|
sprintf(name, "%s %s", make, model);
|
||||||
|
monitor->name = name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mode(void* data,
|
static void mode(void* data,
|
||||||
@@ -63,29 +75,32 @@ static void mode(void* data,
|
|||||||
int32_t refresh)
|
int32_t refresh)
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor *monitor = data;
|
struct _GLFWmonitor *monitor = data;
|
||||||
GLFWvidmode mode;
|
_GLFWvidmodeWayland mode = { { 0 }, };
|
||||||
|
|
||||||
mode.width = width;
|
mode.base.width = width;
|
||||||
mode.height = height;
|
mode.base.height = height;
|
||||||
mode.redBits = 8;
|
mode.base.refreshRate = refresh / 1000;
|
||||||
mode.greenBits = 8;
|
mode.flags = flags;
|
||||||
mode.blueBits = 8;
|
|
||||||
mode.refreshRate = refresh / 1000;
|
|
||||||
|
|
||||||
monitor->modeCount++;
|
if (monitor->wl.modesCount + 1 >= monitor->wl.modesSize)
|
||||||
monitor->modes =
|
{
|
||||||
realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
|
int size = monitor->wl.modesSize * 2;
|
||||||
monitor->modes[monitor->modeCount - 1] = mode;
|
_GLFWvidmodeWayland* modes =
|
||||||
|
realloc(monitor->wl.modes,
|
||||||
|
size * sizeof(_GLFWvidmodeWayland));
|
||||||
|
monitor->wl.modes = modes;
|
||||||
|
monitor->wl.modesSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & WL_OUTPUT_MODE_CURRENT)
|
monitor->wl.modes[monitor->wl.modesCount++] = mode;
|
||||||
monitor->wl.currentMode = monitor->modeCount - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void done(void* data, struct wl_output* output)
|
static void done(void* data,
|
||||||
|
struct wl_output* output)
|
||||||
{
|
{
|
||||||
struct _GLFWmonitor *monitor = data;
|
struct _GLFWmonitor *monitor = data;
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
monitor->wl.done = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scale(void* data,
|
static void scale(void* data,
|
||||||
@@ -134,10 +149,26 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor->wl.scale = 1;
|
monitor->wl.modes = calloc(4, sizeof(_GLFWvidmodeWayland));
|
||||||
monitor->wl.output = output;
|
monitor->wl.modesSize = 4;
|
||||||
|
|
||||||
|
monitor->wl.scale = 1;
|
||||||
|
|
||||||
|
monitor->wl.output = output;
|
||||||
wl_output_add_listener(output, &outputListener, monitor);
|
wl_output_add_listener(output, &outputListener, monitor);
|
||||||
|
|
||||||
|
if (_glfw.wl.monitorsCount + 1 >= _glfw.wl.monitorsSize)
|
||||||
|
{
|
||||||
|
_GLFWmonitor** monitors = _glfw.wl.monitors;
|
||||||
|
int size = _glfw.wl.monitorsSize * 2;
|
||||||
|
|
||||||
|
monitors = realloc(monitors, size * sizeof(_GLFWmonitor*));
|
||||||
|
|
||||||
|
_glfw.wl.monitors = monitors;
|
||||||
|
_glfw.wl.monitorsSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfw.wl.monitors[_glfw.wl.monitorsCount++] = monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -145,6 +176,42 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||||
|
{
|
||||||
|
_GLFWmonitor** monitors;
|
||||||
|
_GLFWmonitor* monitor;
|
||||||
|
int i, monitorsCount = _glfw.wl.monitorsCount;
|
||||||
|
|
||||||
|
if (_glfw.wl.monitorsCount == 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
monitors = calloc(monitorsCount, sizeof(_GLFWmonitor*));
|
||||||
|
|
||||||
|
for (i = 0; i < monitorsCount; i++)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* origMonitor = _glfw.wl.monitors[i];
|
||||||
|
monitor = calloc(1, sizeof(_GLFWmonitor));
|
||||||
|
|
||||||
|
monitor->modes =
|
||||||
|
_glfwPlatformGetVideoModes(origMonitor,
|
||||||
|
&origMonitor->wl.modesCount);
|
||||||
|
*monitor = *_glfw.wl.monitors[i];
|
||||||
|
monitors[i] = monitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
*count = monitorsCount;
|
||||||
|
return monitors;
|
||||||
|
|
||||||
|
err:
|
||||||
|
*count = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
||||||
|
{
|
||||||
|
return first->wl.output == second->wl.output;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
if (xpos)
|
if (xpos)
|
||||||
@@ -155,13 +222,30 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
|||||||
|
|
||||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||||
{
|
{
|
||||||
*found = monitor->modeCount;
|
GLFWvidmode *modes;
|
||||||
return monitor->modes;
|
int i, modesCount = monitor->wl.modesCount;
|
||||||
|
|
||||||
|
modes = calloc(modesCount, sizeof(GLFWvidmode));
|
||||||
|
|
||||||
|
for (i = 0; i < modesCount; i++)
|
||||||
|
modes[i] = monitor->wl.modes[i].base;
|
||||||
|
|
||||||
|
*found = modesCount;
|
||||||
|
return modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||||
{
|
{
|
||||||
*mode = monitor->modes[monitor->wl.currentMode];
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < monitor->wl.modesCount; i++)
|
||||||
|
{
|
||||||
|
if (monitor->wl.modes[i].flags & WL_OUTPUT_MODE_CURRENT)
|
||||||
|
{
|
||||||
|
*mode = monitor->wl.modes[i].base;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||||
|
|||||||
+18
-4
@@ -24,6 +24,9 @@
|
|||||||
//
|
//
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
|
#ifndef _glfw3_wayland_platform_h_
|
||||||
|
#define _glfw3_wayland_platform_h_
|
||||||
|
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#include <xkbcommon/xkbcommon-compose.h>
|
#include <xkbcommon/xkbcommon-compose.h>
|
||||||
@@ -43,12 +46,11 @@ typedef struct VkWaylandSurfaceCreateInfoKHR
|
|||||||
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||||
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
|
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
|
||||||
|
|
||||||
#include "posix_thread.h"
|
#include "posix_tls.h"
|
||||||
#include "posix_time.h"
|
#include "posix_time.h"
|
||||||
#include "linux_joystick.h"
|
#include "linux_joystick.h"
|
||||||
#include "xkb_unicode.h"
|
#include "xkb_unicode.h"
|
||||||
#include "egl_context.h"
|
#include "egl_context.h"
|
||||||
#include "osmesa_context.h"
|
|
||||||
|
|
||||||
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
||||||
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
||||||
@@ -69,6 +71,10 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
|||||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
||||||
|
|
||||||
|
|
||||||
|
// Wayland-specific video mode data
|
||||||
|
//
|
||||||
|
typedef struct _GLFWvidmodeWayland _GLFWvidmodeWayland;
|
||||||
|
|
||||||
// Wayland-specific per-window data
|
// Wayland-specific per-window data
|
||||||
//
|
//
|
||||||
typedef struct _GLFWwindowWayland
|
typedef struct _GLFWwindowWayland
|
||||||
@@ -120,6 +126,10 @@ typedef struct _GLFWlibraryWayland
|
|||||||
struct wl_surface* cursorSurface;
|
struct wl_surface* cursorSurface;
|
||||||
uint32_t pointerSerial;
|
uint32_t pointerSerial;
|
||||||
|
|
||||||
|
_GLFWmonitor** monitors;
|
||||||
|
int monitorsCount;
|
||||||
|
int monitorsSize;
|
||||||
|
|
||||||
short int keycodes[256];
|
short int keycodes[256];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
|
|
||||||
@@ -145,12 +155,15 @@ typedef struct _GLFWlibraryWayland
|
|||||||
typedef struct _GLFWmonitorWayland
|
typedef struct _GLFWmonitorWayland
|
||||||
{
|
{
|
||||||
struct wl_output* output;
|
struct wl_output* output;
|
||||||
int currentMode;
|
|
||||||
|
_GLFWvidmodeWayland* modes;
|
||||||
|
int modesCount;
|
||||||
|
int modesSize;
|
||||||
|
GLFWbool done;
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
int scale;
|
int scale;
|
||||||
|
|
||||||
} _GLFWmonitorWayland;
|
} _GLFWmonitorWayland;
|
||||||
|
|
||||||
// Wayland-specific per-cursor data
|
// Wayland-specific per-cursor data
|
||||||
@@ -166,3 +179,4 @@ typedef struct _GLFWcursorWayland
|
|||||||
|
|
||||||
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
||||||
|
|
||||||
|
#endif // _glfw3_wayland_platform_h_
|
||||||
|
|||||||
+6
-27
@@ -249,8 +249,6 @@ static GLFWbool createShellSurface(_GLFWwindow* window)
|
|||||||
wl_shell_surface_set_toplevel(window->wl.shellSurface);
|
wl_shell_surface_set_toplevel(window->wl.shellSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_commit(window->wl.surface);
|
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,21 +393,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
{
|
{
|
||||||
if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||
|
if (!_glfwInitEGL())
|
||||||
ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
return GLFW_FALSE;
|
||||||
{
|
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||||
if (!_glfwInitEGL())
|
return GLFW_FALSE;
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
|
||||||
{
|
|
||||||
if (!_glfwInitOSMesa())
|
|
||||||
return GLFW_FALSE;
|
|
||||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
|
||||||
return GLFW_FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wndconfig->title)
|
if (wndconfig->title)
|
||||||
@@ -599,13 +586,6 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"Wayland: Window attention request not implemented yet");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@@ -721,7 +701,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
_glfwPlatformSetCursor(window, window->wl.currentCursor);
|
_glfwPlatformSetCursor(window, window->wl.currentCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetKeyName(int key, int scancode)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1019,8 +999,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|||||||
VkPhysicalDevice device,
|
VkPhysicalDevice device,
|
||||||
uint32_t queuefamily)
|
uint32_t queuefamily)
|
||||||
{
|
{
|
||||||
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR =
|
||||||
vkGetPhysicalDeviceWaylandPresentationSupportKHR =
|
|
||||||
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)
|
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)
|
||||||
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
|
||||||
if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
|
if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
|
||||||
|
|||||||
+69
-185
@@ -237,8 +237,8 @@ static void createKeyTables(void)
|
|||||||
|
|
||||||
if (_glfw.x11.xkb.available)
|
if (_glfw.x11.xkb.available)
|
||||||
{
|
{
|
||||||
// Use XKB to determine physical key locations independently of the
|
// Use XKB to determine physical key locations independently of the current
|
||||||
// current keyboard layout
|
// keyboard layout
|
||||||
|
|
||||||
char name[XkbKeyNameLength + 1];
|
char name[XkbKeyNameLength + 1];
|
||||||
XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
|
XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
|
||||||
@@ -381,11 +381,13 @@ static void detectEWMH(void)
|
|||||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
|
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
|
||||||
|
|
||||||
// Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
|
// Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
|
||||||
if (!_glfwGetWindowPropertyX11(_glfw.x11.root,
|
if (_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||||
supportingWmCheck,
|
supportingWmCheck,
|
||||||
XA_WINDOW,
|
XA_WINDOW,
|
||||||
(unsigned char**) &windowFromRoot))
|
(unsigned char**) &windowFromRoot) != 1)
|
||||||
{
|
{
|
||||||
|
if (windowFromRoot)
|
||||||
|
XFree(windowFromRoot);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,12 +395,14 @@ static void detectEWMH(void)
|
|||||||
|
|
||||||
// It should be the ID of a child window (of the root)
|
// It should be the ID of a child window (of the root)
|
||||||
// Then we look for the same property on the child window
|
// Then we look for the same property on the child window
|
||||||
if (!_glfwGetWindowPropertyX11(*windowFromRoot,
|
if (_glfwGetWindowPropertyX11(*windowFromRoot,
|
||||||
supportingWmCheck,
|
supportingWmCheck,
|
||||||
XA_WINDOW,
|
XA_WINDOW,
|
||||||
(unsigned char**) &windowFromChild))
|
(unsigned char**) &windowFromChild) != 1)
|
||||||
{
|
{
|
||||||
XFree(windowFromRoot);
|
XFree(windowFromRoot);
|
||||||
|
if (windowFromChild)
|
||||||
|
XFree(windowFromChild);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,8 +442,6 @@ static void detectEWMH(void)
|
|||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");
|
||||||
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ =
|
_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");
|
||||||
_glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION =
|
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_DEMANDS_ATTENTION");
|
|
||||||
_glfw.x11.NET_WM_FULLSCREEN_MONITORS =
|
_glfw.x11.NET_WM_FULLSCREEN_MONITORS =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
|
||||||
_glfw.x11.NET_WM_WINDOW_TYPE =
|
_glfw.x11.NET_WM_WINDOW_TYPE =
|
||||||
@@ -453,15 +455,14 @@ static void detectEWMH(void)
|
|||||||
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
|
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
|
||||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
|
getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
|
||||||
|
|
||||||
if (supportedAtoms)
|
XFree(supportedAtoms);
|
||||||
XFree(supportedAtoms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for and initialize supported X11 extensions
|
// Initialize X11 display and look for supported X11 extensions
|
||||||
//
|
//
|
||||||
static GLFWbool initExtensions(void)
|
static GLFWbool initExtensions(void)
|
||||||
{
|
{
|
||||||
_glfw.x11.vidmode.handle = dlopen("libXxf86vm.so.1", RTLD_LAZY | RTLD_GLOBAL);
|
_glfw.x11.vidmode.handle = dlopen("libXxf86vm.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
if (_glfw.x11.vidmode.handle)
|
if (_glfw.x11.vidmode.handle)
|
||||||
{
|
{
|
||||||
_glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
|
_glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
|
||||||
@@ -479,89 +480,23 @@ static GLFWbool initExtensions(void)
|
|||||||
&_glfw.x11.vidmode.errorBase);
|
&_glfw.x11.vidmode.errorBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.x11.xi.handle = dlopen("libXi.so.6", RTLD_LAZY | RTLD_GLOBAL);
|
// Check for RandR extension
|
||||||
if (_glfw.x11.xi.handle)
|
if (XRRQueryExtension(_glfw.x11.display,
|
||||||
|
&_glfw.x11.randr.eventBase,
|
||||||
|
&_glfw.x11.randr.errorBase))
|
||||||
{
|
{
|
||||||
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
|
if (XRRQueryVersion(_glfw.x11.display,
|
||||||
dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
|
&_glfw.x11.randr.major,
|
||||||
_glfw.x11.xi.SelectEvents = (PFN_XISelectEvents)
|
&_glfw.x11.randr.minor))
|
||||||
dlsym(_glfw.x11.xi.handle, "XISelectEvents");
|
|
||||||
|
|
||||||
if (XQueryExtension(_glfw.x11.display,
|
|
||||||
"XInputExtension",
|
|
||||||
&_glfw.x11.xi.majorOpcode,
|
|
||||||
&_glfw.x11.xi.eventBase,
|
|
||||||
&_glfw.x11.xi.errorBase))
|
|
||||||
{
|
{
|
||||||
_glfw.x11.xi.major = 2;
|
// The GLFW RandR path requires at least version 1.3
|
||||||
_glfw.x11.xi.minor = 0;
|
if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
|
||||||
|
_glfw.x11.randr.available = GLFW_TRUE;
|
||||||
if (XIQueryVersion(_glfw.x11.display,
|
|
||||||
&_glfw.x11.xi.major,
|
|
||||||
&_glfw.x11.xi.minor) == Success)
|
|
||||||
{
|
|
||||||
_glfw.x11.xi.available = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
_glfw.x11.randr.handle = dlopen("libXrandr.so.2", RTLD_LAZY | RTLD_GLOBAL);
|
|
||||||
if (_glfw.x11.randr.handle)
|
|
||||||
{
|
|
||||||
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
|
|
||||||
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
|
|
||||||
_glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
|
|
||||||
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
|
|
||||||
_glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
|
|
||||||
_glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
|
|
||||||
_glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
|
|
||||||
_glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
|
|
||||||
_glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
|
|
||||||
_glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
|
|
||||||
_glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
|
|
||||||
_glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
|
|
||||||
_glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
|
|
||||||
_glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
|
|
||||||
_glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
|
|
||||||
_glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
|
|
||||||
_glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
|
|
||||||
_glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
|
|
||||||
dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");
|
|
||||||
|
|
||||||
if (XRRQueryExtension(_glfw.x11.display,
|
|
||||||
&_glfw.x11.randr.eventBase,
|
|
||||||
&_glfw.x11.randr.errorBase))
|
|
||||||
{
|
{
|
||||||
if (XRRQueryVersion(_glfw.x11.display,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
&_glfw.x11.randr.major,
|
"X11: Failed to query RandR version");
|
||||||
&_glfw.x11.randr.minor))
|
|
||||||
{
|
|
||||||
// The GLFW RandR path requires at least version 1.3
|
|
||||||
if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
|
|
||||||
_glfw.x11.randr.available = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"X11: Failed to query RandR version");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,57 +507,30 @@ static GLFWbool initExtensions(void)
|
|||||||
|
|
||||||
if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))
|
if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))
|
||||||
{
|
{
|
||||||
// This is likely an older Nvidia driver with broken gamma support
|
// This is either a headless system or an older Nvidia binary driver
|
||||||
// Flag it as useless and fall back to xf86vm gamma, if available
|
// with broken gamma support
|
||||||
|
// Flag it as useless and fall back to Xf86VidMode gamma, if
|
||||||
|
// available
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: RandR gamma ramp support seems broken");
|
||||||
_glfw.x11.randr.gammaBroken = GLFW_TRUE;
|
_glfw.x11.randr.gammaBroken = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sr->ncrtc)
|
|
||||||
{
|
|
||||||
// A system without CRTCs is likely a system with broken RandR
|
|
||||||
// Disable the RandR monitor path and fall back to core functions
|
|
||||||
_glfw.x11.randr.monitorBroken = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
XRRFreeScreenResources(sr);
|
XRRFreeScreenResources(sr);
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
|
||||||
{
|
|
||||||
XRRSelectInput(_glfw.x11.display, _glfw.x11.root,
|
XRRSelectInput(_glfw.x11.display, _glfw.x11.root,
|
||||||
RROutputChangeNotifyMask);
|
RROutputChangeNotifyMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.x11.xcursor.handle = dlopen("libXcursor.so.1", RTLD_LAZY | RTLD_GLOBAL);
|
if (XineramaQueryExtension(_glfw.x11.display,
|
||||||
if (_glfw.x11.xcursor.handle)
|
&_glfw.x11.xinerama.major,
|
||||||
|
&_glfw.x11.xinerama.minor))
|
||||||
{
|
{
|
||||||
_glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
|
if (XineramaIsActive(_glfw.x11.display))
|
||||||
dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate");
|
_glfw.x11.xinerama.available = GLFW_TRUE;
|
||||||
_glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy)
|
|
||||||
dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
|
|
||||||
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
|
|
||||||
dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfw.x11.xinerama.handle = dlopen("libXinerama.so.1", RTLD_LAZY | RTLD_GLOBAL);
|
|
||||||
if (_glfw.x11.xinerama.handle)
|
|
||||||
{
|
|
||||||
_glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
|
|
||||||
dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive");
|
|
||||||
_glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension)
|
|
||||||
dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension");
|
|
||||||
_glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens)
|
|
||||||
dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens");
|
|
||||||
|
|
||||||
if (XineramaQueryExtension(_glfw.x11.display,
|
|
||||||
&_glfw.x11.xinerama.major,
|
|
||||||
&_glfw.x11.xinerama.minor))
|
|
||||||
{
|
|
||||||
if (XineramaIsActive(_glfw.x11.display))
|
|
||||||
_glfw.x11.xinerama.available = GLFW_TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if Xkb is supported on this display
|
||||||
_glfw.x11.xkb.major = 1;
|
_glfw.x11.xkb.major = 1;
|
||||||
_glfw.x11.xkb.minor = 0;
|
_glfw.x11.xkb.minor = 0;
|
||||||
_glfw.x11.xkb.available =
|
_glfw.x11.xkb.available =
|
||||||
@@ -644,10 +552,10 @@ static GLFWbool initExtensions(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.x11.x11xcb.handle = dlopen("libX11-xcb.so.1", RTLD_LAZY | RTLD_GLOBAL);
|
_glfw.x11.x11xcb.handle = dlopen("libX11-xcb.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
if (_glfw.x11.x11xcb.handle)
|
if (_glfw.x11.x11xcb.handle)
|
||||||
{
|
{
|
||||||
_glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection)
|
_glfw.x11.x11xcb.XGetXCBConnection = (PFN_XGetXCBConnection)
|
||||||
dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
|
dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -661,7 +569,10 @@ static GLFWbool initExtensions(void)
|
|||||||
|
|
||||||
// String format atoms
|
// String format atoms
|
||||||
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
|
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
|
||||||
_glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
|
_glfw.x11.UTF8_STRING =
|
||||||
|
XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
|
||||||
|
_glfw.x11.COMPOUND_STRING =
|
||||||
|
XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);
|
||||||
_glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);
|
_glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);
|
||||||
|
|
||||||
// Custom selection property atom
|
// Custom selection property atom
|
||||||
@@ -671,8 +582,6 @@ static GLFWbool initExtensions(void)
|
|||||||
// ICCCM standard clipboard atoms
|
// ICCCM standard clipboard atoms
|
||||||
_glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
|
_glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
|
||||||
_glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
|
_glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
|
||||||
_glfw.x11.PRIMARY = XInternAtom(_glfw.x11.display, "PRIMARY", False);
|
|
||||||
_glfw.x11.INCR = XInternAtom(_glfw.x11.display, "INCR", False);
|
|
||||||
_glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);
|
_glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);
|
||||||
|
|
||||||
// Clipboard manager atoms
|
// Clipboard manager atoms
|
||||||
@@ -688,10 +597,9 @@ static GLFWbool initExtensions(void)
|
|||||||
_glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False);
|
_glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False);
|
||||||
_glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False);
|
_glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False);
|
||||||
_glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False);
|
_glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False);
|
||||||
|
_glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", False);
|
||||||
_glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False);
|
_glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False);
|
||||||
_glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False);
|
_glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False);
|
||||||
_glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False);
|
|
||||||
_glfw.x11.text_uri_list = XInternAtom(_glfw.x11.display, "text/uri-list", False);
|
|
||||||
|
|
||||||
// ICCCM, EWMH and Motif window property atoms
|
// ICCCM, EWMH and Motif window property atoms
|
||||||
// These can be set safely even without WM support
|
// These can be set safely even without WM support
|
||||||
@@ -724,8 +632,11 @@ static GLFWbool initExtensions(void)
|
|||||||
//
|
//
|
||||||
static Cursor createHiddenCursor(void)
|
static Cursor createHiddenCursor(void)
|
||||||
{
|
{
|
||||||
unsigned char pixels[16 * 16 * 4] = { 0 };
|
unsigned char pixels[16 * 16 * 4];
|
||||||
GLFWimage image = { 16, 16, pixels };
|
GLFWimage image = { 16, 16, pixels };
|
||||||
|
|
||||||
|
memset(pixels, 0, sizeof(pixels));
|
||||||
|
|
||||||
return _glfwCreateCursorX11(&image, 0, 0);
|
return _glfwCreateCursorX11(&image, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,7 +688,7 @@ void _glfwReleaseErrorHandlerX11(void)
|
|||||||
//
|
//
|
||||||
void _glfwInputErrorX11(int error, const char* message)
|
void _glfwInputErrorX11(int error, const char* message)
|
||||||
{
|
{
|
||||||
char buffer[_GLFW_MESSAGE_SIZE];
|
char buffer[8192];
|
||||||
XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode,
|
XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode,
|
||||||
buffer, sizeof(buffer));
|
buffer, sizeof(buffer));
|
||||||
|
|
||||||
@@ -791,9 +702,6 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
|
|||||||
int i;
|
int i;
|
||||||
Cursor cursor;
|
Cursor cursor;
|
||||||
|
|
||||||
if (!_glfw.x11.xcursor.handle)
|
|
||||||
return None;
|
|
||||||
|
|
||||||
XcursorImage* native = XcursorImageCreate(image->width, image->height);
|
XcursorImage* native = XcursorImageCreate(image->width, image->height);
|
||||||
if (native == NULL)
|
if (native == NULL)
|
||||||
return None;
|
return None;
|
||||||
@@ -828,11 +736,8 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
|
|||||||
int _glfwPlatformInit(void)
|
int _glfwPlatformInit(void)
|
||||||
{
|
{
|
||||||
#if !defined(X_HAVE_UTF8_STRING)
|
#if !defined(X_HAVE_UTF8_STRING)
|
||||||
// HACK: If the current locale is "C" and the Xlib UTF-8 functions are
|
// HACK: If the current locale is C, apply the environment's locale
|
||||||
// unavailable, apply the environment's locale in the hope that it's
|
// This is done because the C locale breaks wide character input
|
||||||
// both available and not "C"
|
|
||||||
// This is done because the "C" locale breaks wide character input,
|
|
||||||
// which is what we fall back on when UTF-8 support is missing
|
|
||||||
if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0)
|
if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0)
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
#endif
|
#endif
|
||||||
@@ -860,13 +765,12 @@ int _glfwPlatformInit(void)
|
|||||||
_glfw.x11.screen = DefaultScreen(_glfw.x11.display);
|
_glfw.x11.screen = DefaultScreen(_glfw.x11.display);
|
||||||
_glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
|
_glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
|
||||||
_glfw.x11.context = XUniqueContext();
|
_glfw.x11.context = XUniqueContext();
|
||||||
|
_glfw.x11.helperWindowHandle = createHelperWindow();
|
||||||
|
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
|
||||||
|
|
||||||
if (!initExtensions())
|
if (!initExtensions())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
_glfw.x11.helperWindowHandle = createHelperWindow();
|
|
||||||
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
|
|
||||||
|
|
||||||
if (XSupportsLocale())
|
if (XSupportsLocale())
|
||||||
{
|
{
|
||||||
XSetLocaleModifiers("");
|
XSetLocaleModifiers("");
|
||||||
@@ -882,19 +786,25 @@ int _glfwPlatformInit(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__linux__)
|
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!_glfwInitJoysticksLinux())
|
if (!_glfwInitJoysticksLinux())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
#endif
|
|
||||||
|
|
||||||
_glfwInitTimerPOSIX();
|
_glfwInitTimerPOSIX();
|
||||||
|
|
||||||
_glfwPollMonitorsX11();
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformTerminate(void)
|
void _glfwPlatformTerminate(void)
|
||||||
{
|
{
|
||||||
|
if (_glfw.x11.x11xcb.handle)
|
||||||
|
{
|
||||||
|
dlclose(_glfw.x11.x11xcb.handle);
|
||||||
|
_glfw.x11.x11xcb.handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (_glfw.x11.helperWindowHandle)
|
if (_glfw.x11.helperWindowHandle)
|
||||||
{
|
{
|
||||||
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
|
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
|
||||||
@@ -913,7 +823,6 @@ void _glfwPlatformTerminate(void)
|
|||||||
_glfw.x11.hiddenCursorHandle = (Cursor) 0;
|
_glfw.x11.hiddenCursorHandle = (Cursor) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(_glfw.x11.primarySelectionString);
|
|
||||||
free(_glfw.x11.clipboardString);
|
free(_glfw.x11.clipboardString);
|
||||||
|
|
||||||
if (_glfw.x11.im)
|
if (_glfw.x11.im)
|
||||||
@@ -930,37 +839,12 @@ void _glfwPlatformTerminate(void)
|
|||||||
_glfw.x11.display = NULL;
|
_glfw.x11.display = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_glfw.x11.x11xcb.handle)
|
|
||||||
{
|
|
||||||
dlclose(_glfw.x11.x11xcb.handle);
|
|
||||||
_glfw.x11.x11xcb.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.xcursor.handle)
|
|
||||||
{
|
|
||||||
dlclose(_glfw.x11.xcursor.handle);
|
|
||||||
_glfw.x11.xcursor.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.randr.handle)
|
|
||||||
{
|
|
||||||
dlclose(_glfw.x11.randr.handle);
|
|
||||||
_glfw.x11.randr.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_glfw.x11.xinerama.handle)
|
|
||||||
{
|
|
||||||
dlclose(_glfw.x11.xinerama.handle);
|
|
||||||
_glfw.x11.xinerama.handle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: This needs to be done after XCloseDisplay, as libGL registers
|
// NOTE: This needs to be done after XCloseDisplay, as libGL registers
|
||||||
// cleanup callbacks that get called by it
|
// cleanup callbacks that get called by it
|
||||||
_glfwTerminateGLX();
|
_glfwTerminateGLX();
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
_glfwTerminateJoysticksLinux();
|
_glfwTerminateJoysticksLinux();
|
||||||
#endif
|
_glfwTerminateThreadLocalStoragePOSIX();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* _glfwPlatformGetVersionString(void)
|
const char* _glfwPlatformGetVersionString(void)
|
||||||
@@ -972,7 +856,7 @@ const char* _glfwPlatformGetVersionString(void)
|
|||||||
" gettimeofday"
|
" gettimeofday"
|
||||||
#endif
|
#endif
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
" evdev"
|
" /dev/js"
|
||||||
#endif
|
#endif
|
||||||
#if defined(_GLFW_BUILD_DLL)
|
#if defined(_GLFW_BUILD_DLL)
|
||||||
" shared"
|
" shared"
|
||||||
|
|||||||
+117
-131
@@ -95,126 +95,6 @@ static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi,
|
|||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Poll for changes in the set of connected monitors
|
|
||||||
//
|
|
||||||
void _glfwPollMonitorsX11(void)
|
|
||||||
{
|
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
|
||||||
{
|
|
||||||
int i, j, disconnectedCount, screenCount = 0;
|
|
||||||
_GLFWmonitor** disconnected = NULL;
|
|
||||||
XineramaScreenInfo* screens = NULL;
|
|
||||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
|
||||||
_glfw.x11.root);
|
|
||||||
RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
|
|
||||||
_glfw.x11.root);
|
|
||||||
|
|
||||||
if (_glfw.x11.xinerama.available)
|
|
||||||
screens = XineramaQueryScreens(_glfw.x11.display, &screenCount);
|
|
||||||
|
|
||||||
disconnectedCount = _glfw.monitorCount;
|
|
||||||
if (disconnectedCount)
|
|
||||||
{
|
|
||||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
|
||||||
memcpy(disconnected,
|
|
||||||
_glfw.monitors,
|
|
||||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < sr->noutput; i++)
|
|
||||||
{
|
|
||||||
int type, widthMM, heightMM;
|
|
||||||
XRROutputInfo* oi;
|
|
||||||
XRRCrtcInfo* ci;
|
|
||||||
_GLFWmonitor* monitor;
|
|
||||||
|
|
||||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
|
|
||||||
if (oi->connection != RR_Connected || oi->crtc == None)
|
|
||||||
{
|
|
||||||
XRRFreeOutputInfo(oi);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < disconnectedCount; j++)
|
|
||||||
{
|
|
||||||
if (disconnected[j] &&
|
|
||||||
disconnected[j]->x11.output == sr->outputs[i])
|
|
||||||
{
|
|
||||||
disconnected[j] = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j < disconnectedCount)
|
|
||||||
{
|
|
||||||
XRRFreeOutputInfo(oi);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
|
||||||
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
|
||||||
{
|
|
||||||
widthMM = oi->mm_height;
|
|
||||||
heightMM = oi->mm_width;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
widthMM = oi->mm_width;
|
|
||||||
heightMM = oi->mm_height;
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
|
||||||
monitor->x11.output = sr->outputs[i];
|
|
||||||
monitor->x11.crtc = oi->crtc;
|
|
||||||
|
|
||||||
for (j = 0; j < screenCount; j++)
|
|
||||||
{
|
|
||||||
if (screens[j].x_org == ci->x &&
|
|
||||||
screens[j].y_org == ci->y &&
|
|
||||||
screens[j].width == ci->width &&
|
|
||||||
screens[j].height == ci->height)
|
|
||||||
{
|
|
||||||
monitor->x11.index = j;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (monitor->x11.output == primary)
|
|
||||||
type = _GLFW_INSERT_FIRST;
|
|
||||||
else
|
|
||||||
type = _GLFW_INSERT_LAST;
|
|
||||||
|
|
||||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
|
||||||
|
|
||||||
XRRFreeOutputInfo(oi);
|
|
||||||
XRRFreeCrtcInfo(ci);
|
|
||||||
}
|
|
||||||
|
|
||||||
XRRFreeScreenResources(sr);
|
|
||||||
|
|
||||||
if (screens)
|
|
||||||
XFree(screens);
|
|
||||||
|
|
||||||
for (i = 0; i < disconnectedCount; i++)
|
|
||||||
{
|
|
||||||
if (disconnected[i])
|
|
||||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(disconnected);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_glfw.monitorCount)
|
|
||||||
{
|
|
||||||
const int widthMM = DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen);
|
|
||||||
const int heightMM = DisplayHeightMM(_glfw.x11.display, _glfw.x11.screen);
|
|
||||||
|
|
||||||
_glfwInputMonitor(_glfwAllocMonitor("Display", widthMM, heightMM),
|
|
||||||
GLFW_CONNECTED,
|
|
||||||
_GLFW_INSERT_FIRST);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the current video mode for the specified monitor
|
// Set the current video mode for the specified monitor
|
||||||
//
|
//
|
||||||
GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||||
@@ -318,6 +198,119 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
|
|||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||||
|
{
|
||||||
|
int i, j, k, found = 0;
|
||||||
|
_GLFWmonitor** monitors = NULL;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
if (_glfw.x11.randr.available)
|
||||||
|
{
|
||||||
|
int screenCount = 0;
|
||||||
|
XineramaScreenInfo* screens = NULL;
|
||||||
|
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
||||||
|
_glfw.x11.root);
|
||||||
|
RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
|
||||||
|
_glfw.x11.root);
|
||||||
|
|
||||||
|
monitors = calloc(sr->noutput, sizeof(_GLFWmonitor*));
|
||||||
|
|
||||||
|
if (_glfw.x11.xinerama.available)
|
||||||
|
screens = XineramaQueryScreens(_glfw.x11.display, &screenCount);
|
||||||
|
|
||||||
|
for (i = 0; i < sr->ncrtc; i++)
|
||||||
|
{
|
||||||
|
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display,
|
||||||
|
sr, sr->crtcs[i]);
|
||||||
|
|
||||||
|
for (j = 0; j < ci->noutput; j++)
|
||||||
|
{
|
||||||
|
int widthMM, heightMM;
|
||||||
|
_GLFWmonitor* monitor;
|
||||||
|
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display,
|
||||||
|
sr, ci->outputs[j]);
|
||||||
|
if (oi->connection != RR_Connected)
|
||||||
|
{
|
||||||
|
XRRFreeOutputInfo(oi);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
||||||
|
{
|
||||||
|
widthMM = oi->mm_height;
|
||||||
|
heightMM = oi->mm_width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
widthMM = oi->mm_width;
|
||||||
|
heightMM = oi->mm_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
||||||
|
monitor->x11.output = ci->outputs[j];
|
||||||
|
monitor->x11.crtc = oi->crtc;
|
||||||
|
|
||||||
|
for (k = 0; k < screenCount; k++)
|
||||||
|
{
|
||||||
|
if (screens[k].x_org == ci->x &&
|
||||||
|
screens[k].y_org == ci->y &&
|
||||||
|
screens[k].width == ci->width &&
|
||||||
|
screens[k].height == ci->height)
|
||||||
|
{
|
||||||
|
monitor->x11.index = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeOutputInfo(oi);
|
||||||
|
|
||||||
|
found++;
|
||||||
|
monitors[found - 1] = monitor;
|
||||||
|
|
||||||
|
if (ci->outputs[j] == primary)
|
||||||
|
_GLFW_SWAP_POINTERS(monitors[0], monitors[found - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeCrtcInfo(ci);
|
||||||
|
}
|
||||||
|
|
||||||
|
XRRFreeScreenResources(sr);
|
||||||
|
|
||||||
|
if (screens)
|
||||||
|
XFree(screens);
|
||||||
|
|
||||||
|
if (found == 0)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"X11: RandR monitor support seems broken");
|
||||||
|
|
||||||
|
_glfw.x11.randr.monitorBroken = GLFW_TRUE;
|
||||||
|
free(monitors);
|
||||||
|
monitors = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!monitors)
|
||||||
|
{
|
||||||
|
monitors = calloc(1, sizeof(_GLFWmonitor*));
|
||||||
|
monitors[0] = _glfwAllocMonitor("Display",
|
||||||
|
DisplayWidthMM(_glfw.x11.display,
|
||||||
|
_glfw.x11.screen),
|
||||||
|
DisplayHeightMM(_glfw.x11.display,
|
||||||
|
_glfw.x11.screen));
|
||||||
|
found = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*count = found;
|
||||||
|
return monitors;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
||||||
|
{
|
||||||
|
return first->x11.crtc == second->x11.crtc;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||||
{
|
{
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||||
@@ -430,9 +423,9 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
|||||||
|
|
||||||
_glfwAllocGammaArrays(ramp, size);
|
_glfwAllocGammaArrays(ramp, size);
|
||||||
|
|
||||||
memcpy(ramp->red, gamma->red, size * sizeof(unsigned short));
|
memcpy(ramp->red, gamma->red, size * sizeof(unsigned short));
|
||||||
memcpy(ramp->green, gamma->green, size * sizeof(unsigned short));
|
memcpy(ramp->green, gamma->green, size * sizeof(unsigned short));
|
||||||
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
|
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
|
||||||
|
|
||||||
XRRFreeGamma(gamma);
|
XRRFreeGamma(gamma);
|
||||||
}
|
}
|
||||||
@@ -453,18 +446,11 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
|||||||
{
|
{
|
||||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
|
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
|
||||||
{
|
{
|
||||||
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size)
|
|
||||||
{
|
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
|
||||||
"X11: Gamma ramp size must match current ramp size");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size);
|
XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size);
|
||||||
|
|
||||||
memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short));
|
memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short));
|
||||||
memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short));
|
memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short));
|
||||||
memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short));
|
memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short));
|
||||||
|
|
||||||
XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma);
|
XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma);
|
||||||
XRRFreeGamma(gamma);
|
XRRFreeGamma(gamma);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user