Compare commits

..

3 Commits

Author SHA1 Message Date
Camilla Berglund 70297aeb49 Metal example code cleanup 2016-12-19 13:50:57 +01:00
Camilla Berglund 8eb2345347 Add Metal guide 2016-12-19 13:49:57 +01:00
Keith Bauer 97b652c584 Initial Metal example 2016-12-19 13:49:57 +01:00
111 changed files with 4933 additions and 11866 deletions
+3 -4
View File
@@ -4,7 +4,6 @@ branches:
- master
skip_tags: true
environment:
CFLAGS: /WX
matrix:
- BUILD_SHARED_LIBS: ON
- BUILD_SHARED_LIBS: OFF
@@ -13,11 +12,11 @@ matrix:
build_script:
- mkdir build
- cd build
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% ..
- cmake -DBUILD_SHARED_LIBS=%BUILD_SHARED_LIBS% ..
- cmake --build .
notifications:
- provider: Email
to:
- ci@glfw.org
on_build_failure: true
on_build_success: false
- on_build_failure: true
- on_build_success: false
-1
View File
@@ -1 +0,0 @@
*.m linguist-language=Objective-C
+8 -53
View File
@@ -8,7 +8,7 @@
- [Reporting a segfault or other crash bug](#reporting-a-segfault-or-other-crash-bug)
- [Reporting a context creation bug](#reporting-a-context-creation-bug)
- [Reporting a monitor or video mode bug](#reporting-a-monitor-or-video-mode-bug)
- [Reporting 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 a documentation bug](#reporting-a-documentation-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
handles and other pointers are valid.
For bugs where it makes sense, a short, self contained example is absolutely
invaluable. Just put it inline in the body text. Note that if the bug is
reproducible with one of the test programs that come with GLFW, just mention
that instead.
For bugs where it makes sense, a [Short, Self Contained, Correct (Compilable),
Example](http://www.sscce.org/) is absolutely invaluable. Just put it inline in
the body text. Note that if the bug is reproducible with one of the test
programs that come with GLFW, just mention that instead.
__Don't worry about adding too much information__. Unimportant information can
be abbreviated or removed later, but missing information can stall bug fixing,
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
need to mention these in the subject line. If you do, it will be removed when
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
__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
/dev/js`), as described
[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
__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
[error
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:__ Window moving and resizing (by the user) will block the main thread on
some platforms. This is not a bug. Set a [refresh
__Note:__ Window moving and resizing (by the user) will block the main thread on some
platforms. This is not a bug. Set a [refresh
callback](http://www.glfw.org/docs/latest/window.html#window_refresh) if you
want to keep the window contents updated during a move or size operation.
@@ -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
__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
[error
callback](http://www.glfw.org/docs/latest/intro_guide.html#error_handling) and
if relevant, the __output of `events`__ when reporting this kind of bug. If
this tool doesn't run on the machine, mention this instead.
__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
@@ -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
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
@@ -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
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
as one adding a thousand line one, if that is the appropriate size for the
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
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,
but please keep in mind that maintainer time is finite and that there are many
other features and bugs to work on.
+3 -11
View File
@@ -8,27 +8,19 @@ os:
- linux
- osx
sudo: false
dist: trusty
addons:
apt:
sources:
- kubuntu-backports
packages:
- cmake
- libxrandr-dev
- libxinerama-dev
- libxcursor-dev
- libxi-dev
env:
global:
- CFLAGS=-Werror
matrix:
- BUILD_SHARED_LIBS=ON
- BUILD_SHARED_LIBS=OFF
- BUILD_SHARED_LIBS=ON
- BUILD_SHARED_LIBS=OFF
script:
- mkdir build
- cd build
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} ..
- cmake -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} ..
- cmake --build .
notifications:
email:
-33
View File
@@ -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
View File
@@ -1,34 +1,37 @@
# FindMir
# -------
# Finds the Mir library
# Try to find Mir on a Unix system
#
# This will will define the following variables::
# This will define:
#
# MIR_FOUND - the system has Mir
# MIR_INCLUDE_DIRS - the Mir include directory
# MIR_LIBRARIES - the Mir libraries
# MIR_DEFINITIONS - the Mir definitions
# MIR_FOUND - System has Mir
# MIR_LIBRARIES - Link these to use Mir
# MIR_INCLUDE_DIR - Include directory for Mir
# MIR_DEFINITIONS - Compiler switches required for using Mir
if (NOT WIN32)
find_package (PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules (PC_MIR mirclient>=0.26.2 QUIET)
find_package (PkgConfig)
pkg_check_modules (PKG_MIR QUIET mirclient)
set(MIR_DEFINITIONS ${PKG_MIR_CFLAGS_OTHER})
find_path(MIR_INCLUDE_DIR NAMES mir_toolkit/mir_client_library.h
PATHS ${PC_MIR_INCLUDE_DIRS})
find_path(MIR_INCLUDE_DIR
NAMES xkbcommon/xkbcommon.h
HINTS ${PC_XKBCOMMON_INCLUDE_DIR} ${PC_XKBCOMMON_INCLUDE_DIRS}
)
find_library(MIR_LIBRARY NAMES mirclient
PATHS ${PC_MIR_LIBRARIES} ${PC_MIR_LIBRARY_DIRS})
find_library(MIR_LIBRARY
NAMES mirclient
HINTS ${PKG_MIR_LIBRARIES} ${MIR_LIBRARY_DIRS}
)
set (MIR_INCLUDE_DIR ${PKG_MIR_INCLUDE_DIRS})
set (MIR_LIBRARIES ${MIR_LIBRARY})
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (MIR
REQUIRED_VARS MIR_LIBRARY MIR_INCLUDE_DIR)
find_package_handle_standard_args (MIR DEFAULT_MSG
MIR_LIBRARIES
MIR_INCLUDE_DIR
)
if (MIR_FOUND)
set(MIR_LIBRARIES ${MIR_LIBRARY})
set(MIR_INCLUDE_DIRS ${PC_MIR_INCLUDE_DIRS})
set(MIR_DEFINITIONS -DHAVE_MIR=1)
endif()
mark_as_advanced (MIR_LIBRARIES MIR_INCLUDE_DIR)
mark_as_advanced (MIR_LIBRARY MIR_INCLUDE_DIR)
endif()
endif ()
+6 -13
View File
@@ -8,32 +8,25 @@ if (WIN32)
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
"$ENV{VULKAN_SDK}/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
"$ENV{VULKAN_SDK}/Lib"
"$ENV{VULKAN_SDK}/Bin"
"$ENV{VK_SDK_PATH}/Bin")
find_library(VULKAN_STATIC_LIBRARY NAMES vkstatic.1 HINTS
"$ENV{VULKAN_SDK}/Lib"
"$ENV{VULKAN_SDK}/Bin"
"$ENV{VK_SDK_PATH}/Bin")
else()
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{VK_SDK_PATH}/Bin32")
endif()
elseif (APPLE)
set(CMAKE_FIND_FRAMEWORK NEVER)
find_library(VULKAN_LIBRARY MoltenVK)
set(CMAKE_FIND_FRAMEWORK ONLY)
find_library(VULKAN_STATIC_LIBRARY MoltenVK)
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
"${VULKAN_LIBRARY}/Headers")
if (VULKAN_LIBRARY)
set(VULKAN_STATIC_LIBRARY ${VULKAN_LIBRARY})
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
"${VULKAN_LIBRARY}/Headers")
endif()
else()
find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS
"$ENV{VULKAN_SDK}/include")
+38 -40
View File
@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 2.8.12)
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
project(GLFW C)
set(CMAKE_LEGACY_CYGWIN_WIN32 OFF)
cmake_minimum_required(VERSION 2.8.12)
if (NOT CMAKE_VERSION VERSION_LESS "3.0")
# 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)
endif()
if (NOT CMAKE_VERSION VERSION_LESS "3.1")
cmake_policy(SET CMP0054 NEW)
endif()
set(GLFW_VERSION_MAJOR "3")
set(GLFW_VERSION_MINOR "3")
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)
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)
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
option(GLFW_USE_MIR "Use Mir for window creation" OFF)
option(GLFW_USE_EGLDEVICE "Use EGLDevice for window creation" OFF)
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
option(GLFW_USE_MIR "Use Mir for window creation" OFF)
endif()
if (MSVC)
@@ -164,9 +164,6 @@ elseif (GLFW_USE_MIR)
elseif (GLFW_USE_OSMESA)
set(_GLFW_OSMESA 1)
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)
set(_GLFW_WIN32 1)
message(STATUS "Using Win32 for window creation")
@@ -185,7 +182,7 @@ endif()
#--------------------------------------------------------------------
if (GLFW_VULKAN_STATIC)
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)
message(WARNING "Linking Vulkan loader static library into GLFW")
endif()
@@ -249,28 +246,38 @@ if (_GLFW_X11)
# Check for XRandR (modern resolution switching and gamma control)
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()
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)
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()
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)
if (NOT X11_Xkb_FOUND)
message(FATAL_ERROR "The X keyboard extension headers were not found")
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)
message(FATAL_ERROR "The Xcursor headers were not found")
message(FATAL_ERROR "The Xcursor libraries and headers were not found")
endif()
list(APPEND glfw_INCLUDE_DIRS "${X11_Xrandr_INCLUDE_PATH}"
"${X11_Xinerama_INCLUDE_PATH}"
"${X11_Xkb_INCLUDE_PATH}"
"${X11_Xcursor_INCLUDE_PATH}")
list(APPEND glfw_INCLUDE_DIR "${X11_Xcursor_INCLUDE_PATH}")
list(APPEND glfw_LIBRARIES "${X11_Xcursor_LIB}")
list(APPEND glfw_PKG_DEPS "xcursor")
endif()
#--------------------------------------------------------------------
@@ -278,7 +285,7 @@ endif()
#--------------------------------------------------------------------
if (_GLFW_WAYLAND)
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(WaylandScanner REQUIRED)
@@ -295,23 +302,6 @@ if (_GLFW_WAYLAND)
list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}")
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
#--------------------------------------------------------------------
@@ -319,7 +309,7 @@ if (_GLFW_MIR)
find_package(Mir REQUIRED)
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}")
find_package(XKBCommon REQUIRED)
@@ -341,6 +331,14 @@ endif()
#--------------------------------------------------------------------
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
"-framework Cocoa"
"-framework IOKit"
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2002-2006 Marcus Geelnard
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
+30 -178
View File
@@ -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
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
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.
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
[tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW 3 useful. If
you have used GLFW 2 in the past, there is a [transition
guide](http://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
3 API.
[tutorial](http://www.glfw.org/docs/latest/quick.html) for GLFW
3 useful. If you have used GLFW 2 in the past, there is a
[transition guide](http://www.glfw.org/docs/latest/moving.html) for moving to
the GLFW 3 API.
## Compiling GLFW
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,
OSMesa) or rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
GLFW supports compilation on Windows with Visual C++ 2010 and later, MinGW and
MinGW-w64, on 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
not regularly tested.
There are [pre-compiled Windows binaries](http://www.glfw.org/download.html)
available for all supported compilers.
There are also [pre-compiled Windows
binaries](http://www.glfw.org/download.html) available for all compilers
supported on that platform.
See the [compilation guide](http://www.glfw.org/docs/latest/compile.html) for
more information about how to compile GLFW yourself.
See the [compilation guide](http://www.glfw.org/docs/latest/compile.html) in the
documentation for more information.
## Using GLFW
See the [documentation](http://www.glfw.org/docs/latest/) for tutorials, guides
and the API reference.
## Contributing to GLFW
See the [contribution
guide](https://github.com/glfw/glfw/blob/master/.github/CONTRIBUTING.md) for
more information.
See the [building application guide](http://www.glfw.org/docs/latest/build.html)
guide in the documentation for more information.
## System requirements
GLFW supports Windows XP and later and macOS 10.7 and later. Linux and other
Unix-like systems running the X Window System are supported even without
a desktop environment or modern extensions, although some features require
a running window or clipboard manager. The OSMesa backend requires Mesa 6.3.
GLFW supports Windows XP and later, OS X 10.7 Lion and later, and Linux and
other Unix-like systems with the X Window System. Experimental implementations
for the Wayland protocol and the Mir display server are available but not yet
officially supported.
See the [compatibility guide](http://www.glfw.org/docs/latest/compat.html)
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.
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
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
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
MoltenVK SDK manually as it has no standard installation location.
will not be included in the build.
The documentation is generated with [Doxygen](http://doxygen.org/) if CMake can
find that tool.
The documentation is generated with [Doxygen](http://doxygen.org/). If CMake
does not find Doxygen, the documentation will not be generated when you build.
## Reporting bugs
@@ -128,99 +103,24 @@ information on what to include when reporting a bug.
## 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
scancodes for keys (#830)
- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
receiving window maximization events (#778)
- Added `glfwSetWindowAttrib` function for changing window attributes (#537)
- Added `glfwGetJoystickHats` function for querying joystick hats
(#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 headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#281,#850)
- 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_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_CHDIR` compile-time option
- Removed `GLFW_USE_MENUBAR` compile-time option
- Bugfix: Calling `glfwMaximizeWindow` on a full screen window was not ignored
- Bugfix: `GLFW_INCLUDE_VULKAN` could not be combined with the corresponding
OpenGL and OpenGL ES header macros
- Bugfix: `glfwGetInstanceProcAddress` returned `NULL` for
`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: 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] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
- [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] Added support for Vulkan window surface creation via MoltenVK (#870)
- [Cocoa] Bugfix: Disabling window aspect ratio would assert (#852)
- [Cocoa] Bugfix: Window creation failed to set first responder (#876,#883)
- [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`
function on macOS 10.12+
- [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_context_flush_control`
- [EGL] Bugfix: The test for `EGL_RGB_BUFFER` was invalid
## Contact
@@ -272,27 +154,19 @@ GLFW exists because people around the world donated their time and lent their
skills.
- Bobyshev Alexander
- artblanc
- arturo
- Matt Arsenault
- David Avedissian
- Keith Bauer
- John Bartholomew
- Niklas Behrens
- Niklas Bergström
- Denis Bernard
- Doug Binks
- blanco
- Kyle Brenneman
- Rok Breulj
- Martin Capitanio
- David Carlier
- Arturo Castro
- Chi-kwan Chan
- Kamal Chandra
- Ian Clarkson
- Michał Cichoń
- Lambert Clara
- Yaron Cohen-Tal
- Omar Cornut
- Andrew Corrigan
- Noel Cower
- Jason Daly
@@ -304,10 +178,7 @@ skills.
- Mario Dorn
- Jonathan Dummer
- Ralph Eastwood
- Fredrik Ehnbom
- Robin Eklind
- Siavash Eliasi
- Felipe Ferreira
- Michael Fogleman
- Gerald Franz
- Mário Freitas
@@ -315,7 +186,6 @@ skills.
- Marcus Geelnard
- Eloi Marín Gratacós
- Stefan Gustavson
- Jonathan Hale
- Sylvain Hellegouarch
- Matthew Henry
- heromyth
@@ -328,79 +198,63 @@ skills.
- Toni Jovanoski
- Arseny Kapoulkine
- Osman Keskin
- Josh Kilmer
- Cameron King
- Peter Knut
- Christoph Kubisch
- Yuri Kunde Schlesner
- Konstantin Käfer
- Eric Larson
- Robin Leffmann
- Glenn Lewis
- Shane Liesegang
- Eyal Lotem
- Дмитри Малышев
- Martins Mozeiko
- Tristam MacDonald
- Hans Mackowiak
- Дмитри Малышев
- Zbigniew Mandziejewicz
- Célestin Marot
- Kyle McDonald
- David Medlock
- Bryce Mehring
- Jonathan Mercier
- Marcel Metz
- Liam Middlebrook
- Jonathan Miller
- Kenneth Miller
- Bruce Mitchener
- Jack Moffitt
- Jeff Molofee
- Pierre Morel
- Jon Morton
- Pierre Moulon
- Martins Mozeiko
- Julian Møller
- ndogxj
- Kristian Nielsen
- Kamil Nowakowski
- Denis Ovod
- Ozzy
- Andri Pálsson
- Peoro
- Braden Pellett
- Arturo J. Pérez
- Anthony Pesch
- Orson Peters
- Emmanuel Gil Peyrot
- Cyril Pichard
- Keith Pitt
- Stanislav Podgorskiy
- Alexandre Pretyman
- Pieroman
- Philip Rideout
- Eddie Ringle
- Jorge Rodriguez
- Ed Ropple
- Aleksey Rybalkin
- Riku Salminen
- Brandon Schaefer
- Sebastian Schuberth
- Christian Sdunek
- Matt Sealey
- SephiRok
- Steve Sexton
- Arkady Shapkin
- Systemcluster
- Yoshiki Shibukawa
- Dmitri Shuralyov
- Daniel Skorupski
- Bradley Smith
- Patrick Snape
- Erlend Sogge Heggen
- Julian Squires
- Johannes Stein
- Pontus Stenetorp
- Michael Stocker
- Justin Stoecker
- Elviss Strazdins
- Paul Sultana
- Nathan Sweet
- TTK-Bandit
- Sergey Tikhomirov
@@ -410,7 +264,6 @@ skills.
- Matthew Turner
- urraka
- Elias Vanderstuyft
- Stef Velzel
- Jari Vetoniemi
- Ricardo Vieira
- Nicholas Vitovitch
@@ -420,8 +273,7 @@ skills.
- Xo Wang
- Jay Weisskopf
- Frank Wille
- Ryogo Yoshimura
- Andrey Zholos
- yuriks
- Santi Zupancic
- Jonas Ådahl
- Lasse Öörni
+1 -1
View File
@@ -192,7 +192,7 @@ static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
vec3 u = {x, y, z};
if(vec3_len(u) > 1e-4) {
mat4x4 T, C, S = {{0}};
mat4x4 T, C, S;
vec3_norm(u, u);
mat4x4_from_vec3_mul_outer(T, u, u);
+1036 -2666
View File
File diff suppressed because it is too large Load Diff
+9 -31
View File
@@ -1,7 +1,7 @@
/*
* Nuklear - v1.32.0 - public domain
* Nuklear - v1.17 - public domain
* 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_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_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
#define NK_GLFW_TEXT_MAX 256
#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_buffer cmds;
@@ -73,8 +67,7 @@ static struct nk_glfw {
struct nk_vec2 fb_scale;
unsigned int text[NK_GLFW_TEXT_MAX];
int text_len;
struct nk_vec2 scroll;
double last_button_click;
float scroll;
} glfw;
NK_INTERN void
@@ -90,7 +83,7 @@ nk_glfw3_device_upload_atlas(const void *image, int width, int height)
}
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 */
struct nk_glfw_device *dev = &glfw.ogl;
@@ -207,22 +200,7 @@ NK_API void
nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
{
(void)win; (void)xoff;
glfw.scroll.x += (float)xoff;
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);
glfw.scroll += (float)yoff;
}
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) {
glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
glfwSetCharCallback(win, nk_glfw3_char_callback);
glfwSetMouseButtonCallback(win, nk_glfw3_mouse_button_callback);
}
nk_init_default(&glfw.ctx, 0);
glfw.ctx.clip.copy = nk_glfw3_clipbard_copy;
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 ||
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_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_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == 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_end(&glfw.ctx);
glfw.text_len = 0;
glfw.scroll = nk_vec2(0,0);
glfw.scroll = 0;
}
NK_API
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C"
#define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#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"
// 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,
+7 -647
View File
@@ -6,7 +6,7 @@ extern "C" {
#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");
** 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_PATCH(version) ((uint32_t)(version) & 0xfff)
// Version of this file
#define VK_HEADER_VERSION 39
#define VK_HEADER_VERSION 26
#define VK_NULL_HANDLE 0
@@ -145,7 +145,6 @@ typedef enum VkResult {
VK_ERROR_INCOMPATIBLE_DISPLAY_KHR = -1000003001,
VK_ERROR_VALIDATION_FAILED_EXT = -1000011001,
VK_ERROR_INVALID_SHADER_NV = -1000012000,
VK_ERROR_OUT_OF_POOL_MEMORY_KHR = -1000069000,
VK_RESULT_BEGIN_RANGE = VK_ERROR_FRAGMENTED_POOL,
VK_RESULT_END_RANGE = VK_INCOMPLETE,
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_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001,
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_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),
@@ -856,8 +833,6 @@ typedef enum VkFormatFeatureFlagBits {
VK_FORMAT_FEATURE_BLIT_DST_BIT = 0x00000800,
VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT = 0x00001000,
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
} VkFormatFeatureFlagBits;
typedef VkFlags VkFormatFeatureFlags;
@@ -881,7 +856,6 @@ typedef enum VkImageCreateFlagBits {
VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008,
VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010,
VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR = 0x00000020,
VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkImageCreateFlagBits;
typedef VkFlags VkImageCreateFlags;
@@ -943,7 +917,6 @@ typedef enum VkPipelineStageFlagBits {
VK_PIPELINE_STAGE_HOST_BIT = 0x00004000,
VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT = 0x00008000,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT = 0x00010000,
VK_PIPELINE_STAGE_COMMAND_PROCESS_BIT_NVX = 0x00020000,
VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkPipelineStageFlagBits;
typedef VkFlags VkPipelineStageFlags;
@@ -1118,8 +1091,6 @@ typedef enum VkAccessFlagBits {
VK_ACCESS_HOST_WRITE_BIT = 0x00004000,
VK_ACCESS_MEMORY_READ_BIT = 0x00008000,
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
} VkAccessFlagBits;
typedef VkFlags VkAccessFlags;
@@ -3225,18 +3196,6 @@ VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
typedef enum VkColorSpaceKHR {
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_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),
@@ -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_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
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_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_SWAPCHAIN_KHR_EXT = 27,
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_END_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX_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_END_RANGE_EXT = VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
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
} VkDebugReportObjectTypeEXT;
@@ -4147,8 +3972,8 @@ typedef struct VkDedicatedAllocationMemoryAllocateInfoNV {
#define VK_AMD_draw_indirect_count 1
#define VK_AMD_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_SPEC_VERSION 1
#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_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);
#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_SPEC_VERSION 1
#define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc"
@@ -4306,456 +4116,6 @@ typedef struct VkWin32KeyedMutexAcquireReleaseInfoNV {
#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
}
#endif
+2 -3
View File
@@ -14,12 +14,11 @@ set(glfw_DOCS_SOURCES
"${GLFW_SOURCE_DIR}/docs/window.dox"
"${GLFW_SOURCE_DIR}/docs/input.dox"
"${GLFW_SOURCE_DIR}/docs/vulkan.dox"
"${GLFW_SOURCE_DIR}/docs/metal.dox"
"${GLFW_SOURCE_DIR}/docs/compat.dox")
if (GLFW_DOCUMENT_INTERNALS)
list(APPEND glfw_DOCS_SOURCES
"${GLFW_SOURCE_DIR}/docs/internal.dox"
"${GLFW_SOURCE_DIR}/src/internal.h")
list(APPEND glfw_DOCS_SOURCES "${GLFW_SOURCE_DIR}/src/internal.h")
endif()
foreach(arg ${glfw_DOCS_SOURCES})
+2 -3
View File
@@ -204,8 +204,7 @@ ALIASES = "thread_safety=@par Thread safety\n" \
"x11=__X11:__" \
"wayland=__Wayland:__" \
"win32=__Windows:__" \
"macos=__macOS:__" \
"linux=__Linux:__"
"macos=__macOS:__"
# 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
@@ -476,7 +475,7 @@ SORT_MEMBER_DOCS = NO
# by member name. If set to NO (the default) the members will appear in
# declaration order.
SORT_BRIEF_DOCS = NO
SORT_BRIEF_DOCS = YES
# 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
+17 -46
View File
@@ -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
the documentation for your development environment.
@section build_include Including the GLFW header file
You should include the GLFW header in the source files where you use OpenGL or
GLFW.
In the source files of your application where you use OpenGL or GLFW, you should
include the GLFW header file, i.e.:
@code
#include <GLFW/glfw3.h>
@endcode
This header declares the GLFW API and by default also includes the OpenGL header
from your development environment. See below for how to control this.
The GLFW header declares the GLFW API and by default also includes the OpenGL
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
header, so it can be included without needing any window system headers.
The GLFW header also defines everything necessary for your OpenGL header to
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`
before the OpenGL header, which would bring in the whole Win32 API. The GLFW
header duplicates the small number of macros needed.
It does this only when needed, so if `windows.h` _is_ included, the GLFW header
Instead, the GLFW header takes care of this for you, not by including
`windows.h`, but by duplicating only the very few necessary parts of it. 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.
`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
[glad](https://github.com/Dav1dde/glad), the extension loader header should
be included _before_ the GLFW one.
@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
either be included _before_ the GLFW one, or the @ref GLFW_INCLUDE_NONE macro
(described below) should be defined.
@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
`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
__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.
@@ -239,8 +222,7 @@ target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
@endcode
@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
transition guide for suggested replacements.
legacy code requires it.
@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)
@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
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
@@ -292,8 +265,7 @@ target_link_libraries(myapp ${OPENGL_glu_LIBRARY})
@endcode
@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
transition guide for suggested replacements.
legacy code requires it.
@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
@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
transition guide for suggested replacements.
legacy code requires it.
If you are using the static version of the GLFW library, make sure you don't
link statically against GLU.
+9 -14
View File
@@ -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
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
@@ -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.
@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
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,
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
at most OpenGL version 2.1.
contexts. Versions of Mac OS X earlier than 10.7 support at most OpenGL
version 2.1.
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
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_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts. The
`GLFW_OPENGL_DEBUG_CONTEXT` and `GLFW_CONTEXT_NO_ERROR` hints are ignored.
`GLFW_OPENGL_CORE_PROFILE` when creating OpenGL 3.2 and later contexts and the
`GLFW_OPENGL_DEBUG_CONTEXT` hint is ignored.
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,
@@ -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
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
functional ICD is missing, @ref glfwVulkanSupported will return `GLFW_FALSE` and
all other Vulkan-related functions will fail with an @ref GLFW_API_UNAVAILABLE
error.
drivers and Vulkan SDKs. If the loader is not found, @ref glfwVulkanSupported
will return `GLFW_FALSE` and all other Vulkan-related functions will fail with
an @ref GLFW_API_UNAVAILABLE error.
@section compat_wsi Vulkan WSI extensions
+19 -7
View File
@@ -219,6 +219,17 @@ __GLFW_VULKAN_STATIC__ determines whether to use the Vulkan loader linked
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
@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_MIR to use the Mir API (experimental and incomplete)
- @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
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
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:
- @b _GLFW_USE_EGLPLATFORM_H to use `EGL/eglplatform.h` for native handle
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
GLFW. If you define any of these in your build files, make sure they are not
applied to the GLFW sources.
+4 -3
View File
@@ -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
window, even if none of them are visible.
@macos The first time a window is created the menu bar is created. This is not
desirable for example when writing a command-line only application. Menu bar
creation can be disabled with the @ref GLFW_COCOA_MENUBAR init hint.
@macos The first time a window is created the menu bar is populated with
common commands like Hide, Quit and About. This is not desirable for example
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
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -27
View File
@@ -76,17 +76,8 @@
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 {
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 {
#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;
}
@@ -192,13 +183,6 @@ address.footer {
background:@header-footer-link-color;
}
#main-nav {
max-width:960px;
min-width:800px;
margin:0 auto;
font-size:13px;
}
#navrow1,#navrow2,#navrow3,#navrow4 {
max-width:920px;
min-width:800px;
@@ -206,15 +190,6 @@ address.footer {
font-size:13px;
}
.memtitle {
display:none;
}
.memproto,.memname {
font-weight:bold;
text-shadow:none;
}
.tablist {
height:36px;
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%);
box-shadow:inset 0 0 32px @table-background-color1;
text-shadow:0 -1px 1px darken(@table-background-color1, 15%);
text-align:left;
color:@table-text-color;
}
+1
View File
@@ -25,6 +25,7 @@ $extrastylesheet
<ul class="glfwnavbar">
<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/media.html">Media</a></li>
<li><a href="http://www.glfw.org/community.html">Community</a></li>
</ul>
</div>
+23 -238
View File
@@ -145,9 +145,7 @@ per-window state arrays that can be polled with @ref glfwGetKey.
@code
int state = glfwGetKey(window, GLFW_KEY_E);
if (state == GLFW_PRESS)
{
activate_airship();
}
@endcode
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
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.
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
@@ -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
layouts and modifier keys and supports composing characters using
[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,
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
offer regular text input, set a character callback.
@@ -272,9 +271,8 @@ glfwGetCursorPos(window, &xpos, &ypos);
@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
mouse motion input. By default, the cursor mode is `GLFW_CURSOR_NORMAL`,
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 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.
per channel. The pixels are arranged canonically as sequential rows, starting
from the top-left corner.
@subsubsection cursor_standard Standard cursor creation
@@ -369,10 +367,8 @@ When a cursor is no longer needed, destroy it with @ref glfwDestroyCursor.
glfwDestroyCursor(cursor);
@endcode
Cursor destruction always succeeds. If the cursor is current for any window,
that window will revert to the default cursor. This does not affect the cursor
mode. All remaining cursors remaining are destroyed when @ref glfwTerminate is
called.
Cursor destruction always succeeds. All cursors remaining when @ref
glfwTerminate is called are destroyed as well.
@subsubsection cursor_set Cursor setting
@@ -389,14 +385,14 @@ to `GLFW_CURSOR_NORMAL`.
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
glfwSetCursor(window, NULL);
@endcode
When a cursor is destroyed, any window that has it set will revert to the
default cursor. This does not affect the cursor mode.
When a cursor is destroyed, it is removed from any window where it is set. This
does not affect the cursor modes of those windows.
@subsection cursor_enter Cursor enter/leave events
@@ -453,9 +449,7 @@ per-window state arrays that can be polled with @ref glfwGetMouseButton.
@code
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
if (state == GLFW_PRESS)
{
upgrade_cow();
}
@endcode
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
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.
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
@@ -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
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_LAST`. You can test whether a [joystick](@ref joysticks) is
present with @ref glfwJoystickPresent.
`GLFW_JOYSTICK_1`, `GLFW_JOYSTICK_2` up to `GLFW_JOYSTICK_LAST`. You can test
whether a [joystick](@ref joysticks) is present with @ref glfwJoystickPresent.
@code
int present = glfwJoystickPresent(GLFW_JOYSTICK_1);
@endcode
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
disconnected or the library is terminated, so as joysticks are connected and
disconnected, there may appear gaps in the IDs.
the array, starting with `GLFW_JOYSTICK_1`. Once a joystick is detected, it
keeps its assigned index until it is disconnected, so as joysticks are connected
and disconnected, they will become spread out.
Joystick axis, button and hat state is updated when polled and does not require
a window to be created or events to be processed. However, if you want joystick
connection and disconnection events reliably delivered to the
[joystick callback](@ref joystick_event) then you must
[process events](@ref events).
Joystick state is updated as needed when a joystick function is called and does
not require a window to be created or @ref glfwPollEvents or @ref glfwWaitEvents
to be called.
To see all the properties of all connected joysticks in real-time, run the
`joysticks` test program.
@@ -539,7 +529,7 @@ returned array.
@code
int count;
const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_5, &count);
const float* axes = glfwGetJoystickAxes(GLFW_JOYSTICK_1, &count);
@endcode
Each element in the returned array is a value between -1.0 and 1.0.
@@ -553,55 +543,11 @@ returned array.
@code
int count;
const unsigned char* buttons = glfwGetJoystickButtons(GLFW_JOYSTICK_3, &count);
const unsigned char* axes = glfwGetJoystickButtons(GLFW_JOYSTICK_1, &count);
@endcode
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
@@ -610,7 +556,7 @@ glfwGetJoystickName. See the reference documentation for the lifetime of the
returned string.
@code
const char* name = glfwGetJoystickName(GLFW_JOYSTICK_4);
const char* name = glfwGetJoystickName(GLFW_JOYSTICK_1);
@endcode
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
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
@@ -849,9 +636,7 @@ reference documentation for the lifetime of the returned string.
@code
const char* text = glfwGetClipboardString(window);
if (text)
{
insert_text(text);
}
@endcode
If the clipboard is empty or if its contents could not be converted, `NULL` is
+54 -149
View File
@@ -30,10 +30,7 @@ successfully initialized, and only from the main thread.
- @ref glfwGetVersion
- @ref glfwGetVersionString
- @ref glfwGetError
- @ref glfwSetErrorCallback
- @ref glfwInitHint
- @ref glfwInitHintString
- @ref glfwInit
- @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.
@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
Before your application exits, you should terminate the GLFW library if it has
@@ -146,76 +83,41 @@ immediately.
@section error_handling Error handling
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.
Other functions have no return value reserved for errors, so error notification
needs a separate channel. Finally, far from all GLFW functions have return
values.
not very helpful when trying to figure out _why_ the error occurred. Some
functions also return otherwise valid values on error. Finally, far from all
GLFW functions have return values.
The last [error code](@ref errors) for the calling thread can be queried at any
time with @ref glfwGetError.
@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.
This is where the error callback comes in. This callback is called whenever an
error occurs. It is set with @ref glfwSetErrorCallback, a function that may be
called regardless of whether GLFW is initialized.
@code
glfwSetErrorCallback(error_callback);
@endcode
The error callback receives the same error code and human-readable description
returned by @ref glfwGetError.
The error callback receives a human-readable description of the error and (when
possible) its cause. The description encoded as UTF-8. The callback is also
provided with an [error code](@ref errors).
@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
The error callback is called after the error is stored, so calling @ref
glfwGetError from within the error callback returns the same values as the
callback argument.
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.
The description string passed to the callback is only valid until the error
callback returns. This means you must make a copy of it if you want to keep it.
The description string is only valid until the error callback returns, as it may
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
initialized, it will remain initialized and in a safe state until terminated
regardless of how many errors occur. If an error occurs during initialization
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.
@note Relying on erroneous behavior is not forward compatible. In other words,
do not rely on a currently invalid call to generate a specific error, as that
same call may in future versions generate a different error or become valid.
@section coordinate_systems Coordinate systems
@@ -286,10 +188,14 @@ releases.
@subsection reentrancy Reentrancy
GLFW event processing and object destruction are not reentrant. This means that
the following functions must not be called from any callback function:
GLFW event processing and object creation and destruction are not reentrant.
This means that the following functions must not be called from any callback
function:
- @ref glfwCreateWindow
- @ref glfwDestroyWindow
- @ref glfwCreateCursor
- @ref glfwCreateStandardCursor
- @ref glfwDestroyCursor
- @ref glfwPollEvents
- @ref glfwWaitEvents
@@ -302,39 +208,35 @@ functions not on this list will not be made non-reentrant.
@subsection thread_safety Thread safety
Most GLFW functions must only be called from the main thread (the thread that
calls main), but some may be called from any thread once the library has been
initialized. Before initialization the whole library is thread-unsafe.
Most GLFW functions must only be called from the main thread, but some may be
called from any thread. However, no GLFW function may be called from any thread
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
to the main thread.
Initialization, termination, event processing and the creation and
destruction of windows, cursors and OpenGL and OpenGL ES contexts are all
restricted to the main thread due to limitations of one or several platforms.
Initialization and termination, event processing and the creation and
destruction of windows, contexts and cursors are all limited to the main thread
due to limitations of one or several platforms.
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
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.
- @ref glfwGetError
Empty events may be posted 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
this is not synchronized by GLFW. The following window related functions may
be called from any thread:
- @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 glfwSetWindowUserPointer
- @ref glfwWindowShouldClose
- @ref glfwSetWindowShouldClose
These functions for working with OpenGL and OpenGL ES contexts may be called
from any thread, but the window object is not synchronized by GLFW.
Rendering may be done on any thread. The following context related functions
may be called from any thread:
- @ref glfwMakeContextCurrent
- @ref glfwGetCurrentContext
@@ -343,23 +245,27 @@ from any thread, but the window object is not synchronized by GLFW.
- @ref glfwExtensionSupported
- @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 glfwGetTimerValue
The regular timer may be used from any thread, but reading and writing the timer
offset is not synchronized by GLFW.
The regular timer may be used from any thread, but the reading and writing of
the timer offset is not synchronized by GLFW. The following timer related
functions may be called from any thread:
- @ref glfwGetTime
- @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 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 glfwGetRequiredInstanceExtensions
@@ -367,9 +273,9 @@ All Vulkan related functions may be called from any thread.
- @ref glfwGetPhysicalDevicePresentationSupport
- @ref glfwCreateWindowSurface
GLFW uses synchronization objects internally only to manage the per-thread
context and error states. Additional synchronization is left to the
application.
GLFW uses no synchronization objects internally except for thread-local storage
to keep track of the current context for each thread. Synchronization is left
to the application.
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
@@ -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.
If the reference documentation and the implementation differ, the reference
documentation will almost always take precedence and the implementation will be
fixed in the next release. The reference documentation will also take
precedence over anything stated in a guide.
documentation is correct and the implementation will be fixed in the next
release.
@subsection event_order Event order
+3 -1
View File
@@ -8,7 +8,7 @@ GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and
Vulkan application development. It provides a simple, platform-independent API
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.
@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,
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
design, implementation and use of GLFW.
+7
View File
@@ -0,0 +1,7 @@
/*!
@page metal Metal guide
@tableofcontents
*/
+2 -2
View File
@@ -195,8 +195,8 @@ glfwSetGammaRamp(monitor, &ramp);
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.
It is recommended that your gamma ramp have the same size as the current gamma
ramp for that monitor.
@note It is recommended to use gamma ramps of size 256, as that is the size
supported by all graphics cards on all platforms.
The current gamma ramp for a monitor is returned by @ref glfwGetGammaRamp. See
the reference documentation for the lifetime of the returned structure.
-7
View File
@@ -447,13 +447,6 @@ defining @ref GLFW_INCLUDE_GLU before the inclusion of the GLFW header.
#include <GLFW/glfw3.h>
@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
+11 -99
View File
@@ -1,50 +1,19 @@
/*!
@page news Release notes
@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
@page news New features
@section news_33 New features in 3.3
@subsection news_33_maximize Window maximization callback
GLFW now supports notifying the application that the window has been maximized
@ref glfwSetWindowMaximizeCallback.
@see @ref window_maximize
GLFW now supports window maximization notifications with @ref
glfwSetWindowMaximizeCallback.
@subsection news_33_keyscancode Platform-specific key scancode query
GLFW now supports querying the platform dependent scancode of any physical key
with @ref glfwGetKeyScancode.
@see @ref input_key
GLFW now supports querying the platform dependent scancode of any key with
@ref glfwGetKeyScancode.
@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
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
GLFW now supports the `VK_MVK_macos_surface` window surface creation extension
provided by [MoltenVK](https://moltengl.com/moltenvk/).
@see @ref vulkan_guide
@subsection news_33_osmesa OSMesa backend for headless software rendering
GLFW now supports creating offscreen OpenGL contexts using
[OSMesa](https://www.mesa3d.org/osmesa.html) by setting
[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.
GLFW now supports headless context creation and software rendering via OSMesa,
intended for automated testing. This backend does not provide input.
@subsection news_33_primary X11 primary selection access
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
@section news_32 New features in 3.2
@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.
@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
[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.
@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
[version history](http://www.glfw.org/changelog.html).
+15 -19
View File
@@ -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
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
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
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
not need to be linked against the loader. However, it also means that if you
are using the static library form of the Vulkan loader GLFW will either fail to
find it or (worse) use the wrong one.
Unix-like systems). This means that GLFW does not need to be linked against the
loader. However, it also means that if you are using the static library form of
the Vulkan loader GLFW will either fail to find it or (worse) use the wrong one.
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
a compile-time error.
static form. Not linking against the Vulkan loader will then be a compile-time
error.
@macos When using the static library form of MoltenVK (i.e. `MetalVK.framework`
and not `libMoltenVK.dylib`) you must also link against its dependencies: the
`Cocoa`, `Metal` and `QuartzCore` system frameworks and the `libc++` library.
@macos MoltenVK only provides the static library form of the Vulkan loader, but
GLFW is able to find it without @ref GLFW_VULKAN_STATIC as long as it is linked
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
@@ -85,7 +81,7 @@ section. The canonical desktop loader library exports all Vulkan core and
Khronos extension functions, allowing them to be called 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.
@code
@@ -95,11 +91,11 @@ if (glfwVulkanSupported())
}
@endcode
This function returns `GLFW_TRUE` if the Vulkan loader and any minimally
functional ICD was found.
This function returns `GLFW_TRUE` if the Vulkan loader was found. This check is
performed by @ref glfwInit.
If if one or both were not found, calling any other Vulkan related GLFW function
will generate a @ref GLFW_API_UNAVAILABLE error.
If no loader was found, calling any other Vulkan related GLFW function will
generate a @ref GLFW_API_UNAVAILABLE error.
@subsection vulkan_proc Querying Vulkan function pointers
+34 -109
View File
@@ -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
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
@@ -182,48 +179,38 @@ context, but are ignored when requesting an OpenGL ES context:
@anchor GLFW_RESIZABLE_hint
__GLFW_RESIZABLE__ specifies whether the windowed mode window will be resizable
_by the user_. The window will still be resizable using the @ref
glfwSetWindowSize function. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
This hint is ignored for full screen and undecorated windows.
glfwSetWindowSize function. This hint is ignored for full screen and
undecorated windows.
@anchor GLFW_VISIBLE_hint
__GLFW_VISIBLE__ specifies whether the windowed mode window will be initially
visible. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This hint is
ignored for full screen windows.
visible. This hint is ignored for full screen windows.
@anchor GLFW_DECORATED_hint
__GLFW_DECORATED__ specifies whether the windowed mode window will have window
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
events on some platforms. Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
This hint is ignored for full screen windows.
events on some platforms. This hint is ignored for full screen windows.
@anchor GLFW_FOCUSED_hint
__GLFW_FOCUSED__ specifies whether the windowed mode window will be given input
focus when created. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This
hint is ignored for full screen and initially hidden windows.
focus when created. This hint is ignored for full screen and initially hidden
windows.
@anchor GLFW_AUTO_ICONIFY_hint
__GLFW_AUTO_ICONIFY__ specifies whether the full screen window will
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
windowed mode windows.
This hint is ignored for windowed mode windows.
@anchor GLFW_FLOATING_hint
__GLFW_FLOATING__ specifies whether the windowed mode window will be floating
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
full screen windows. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This
hint is ignored for full screen windows.
full screen windows. This hint is ignored for full screen windows.
@anchor GLFW_MAXIMIZED_hint
__GLFW_MAXIMIZED__ specifies whether the windowed mode window will be maximized
when created. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This hint is
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.
when created. This hint is ignored for full screen windows.
@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.
@anchor GLFW_STEREO
__GLFW_STEREO__ specifies whether to use OpenGL stereoscopic rendering.
Possible values are `GLFW_TRUE` and `GLFW_FALSE`. This is a hard constraint.
__GLFW_STEREO__ specifies whether to use OpenGL stereoscopic rendering. This is
a hard constraint.
@anchor GLFW_SAMPLES
__GLFW_SAMPLES__ specifies the desired number of samples to use for
@@ -271,21 +258,14 @@ the application has no preference.
@anchor GLFW_SRGB_CAPABLE
__GLFW_SRGB_CAPABLE__ specifies whether the framebuffer should be sRGB capable.
Possible values are `GLFW_TRUE` and `GLFW_FALSE`.
@par
__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.
If supported, a created OpenGL context will support the `GL_FRAMEBUFFER_SRGB`
enable, also called `GL_FRAMEBUFFER_SRGB_EXT`) for controlling sRGB rendering
and a created OpenGL ES context will always have sRGB rendering enabled.
@anchor GLFW_DOUBLEBUFFER
__GLFW_DOUBLEBUFFER__ specifies whether the framebuffer should be double
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
@@ -305,9 +285,9 @@ This is a hard constraint.
@anchor GLFW_CONTEXT_CREATION_API_hint
__GLFW_CONTEXT_CREATION_API__ specifies which context creation API to use to
create the context. Possible values are `GLFW_NATIVE_CONTEXT_API`,
`GLFW_EGL_CONTEXT_API` and `GLFW_OSMESA_CONTEXT_API`. This is a hard
constraint. If no client API is requested, this hint is ignored.
create the context. Possible values are `GLFW_NATIVE_CONTEXT_API` and
`GLFW_EGL_CONTEXT_API`. This is a hard constraint. If no client API is
requested, this hint is ignored.
@par
@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
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
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
@@ -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
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
__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
@@ -380,8 +351,7 @@ Forward-compatibility is described in detail in the
@anchor GLFW_OPENGL_DEBUG_CONTEXT_hint
__GLFW_OPENGL_DEBUG_CONTEXT__ specifies whether to create a debug OpenGL
context, which may have additional error and performance issue reporting
functionality. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If OpenGL ES
is requested, this hint is ignored.
functionality. If OpenGL ES is requested, this hint is ignored.
@anchor GLFW_OPENGL_PROFILE_hint
__GLFW_OPENGL_PROFILE__ specifies which OpenGL profile to create the context
@@ -418,44 +388,28 @@ extension.
@anchor GLFW_CONTEXT_NO_ERROR_hint
__GLFW_CONTEXT_NO_ERROR__ specifies whether errors should be generated by the
context. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If enabled,
situations that would have generated errors instead cause undefined behavior.
context. If enabled, situations that would have generated errors instead cause
undefined behavior.
@par
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)
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
__GLFW_COCOA_RETINA_FRAMEBUFFER__ specifies whether to use full resolution
framebuffers on Retina displays. Possible values are `GLFW_TRUE` and
`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`.
framebuffers on Retina displays. This is ignored on other platforms.
@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_FLOATING | `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_GREEN_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_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_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_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`
@@ -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_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_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
@@ -777,10 +728,6 @@ images[1] = load_icon("my_icon_small.png");
glfwSetWindowIcon(window, 2, images);
@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.
@code
@@ -980,10 +927,6 @@ glfwFocusWindow.
glfwFocusWindow(window);
@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
the user, system or your own code, set a focus callback.
@@ -1022,20 +965,6 @@ glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE);
@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
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
__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`
or `GLFW_OSMESA_CONTEXT_API`.
the window's context; either `GLFW_NATIVE_CONTEXT_API` or
`GLFW_EGL_CONTEXT_API`.
@anchor GLFW_CONTEXT_VERSION_MAJOR_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
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
__GLFW_OPENGL_FORWARD_COMPAT__ is `GLFW_TRUE` if the window's context is an
OpenGL forward-compatible one, or `GLFW_FALSE` otherwise.
+9 -4
View File
@@ -3,7 +3,7 @@ link_libraries(glfw)
include_directories(${glfw_INCLUDE_DIRS} "${GLFW_SOURCE_DIR}/deps")
if (MATH_LIBRARY)
if (BUILD_SHARED_LIBS)
link_libraries("${MATH_LIBRARY}")
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(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD})
target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}")
if (RT_LIBRARY)
target_link_libraries(particles "${RT_LIBRARY}")
target_link_libraries(particles "${CMAKE_THREAD_LIBS_INIT}" "${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()
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(gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears")
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(simple PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Simple")
set_target_properties(splitview PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "SplitView")
+162
View File
@@ -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]
-2
View File
@@ -87,8 +87,6 @@ int main(void)
glfwSetErrorCallback(error_callback);
glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE);
if (!glfwInit())
exit(EXIT_FAILURE);
+110 -662
View File
File diff suppressed because it is too large Load Diff
+6 -60
View File
@@ -45,7 +45,6 @@ extern "C" {
* more information.
*/
/*! @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
* 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
// 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
#if defined(GLFW_APIENTRY_DEFINED)
#undef APIENTRY
#undef GLFW_APIENTRY_DEFINED
#endif
#undef APIENTRY
#include <windows.h>
#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
#include <ApplicationServices/ApplicationServices.h>
@@ -292,56 +288,6 @@ GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
* @ingroup native
*/
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
#if defined(GLFW_EXPOSE_NATIVE_GLX)
@@ -447,9 +393,9 @@ GLFWAPI MirConnection* glfwGetMirDisplay(void);
*/
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.
*
* @thread_safety This function may be called from any thread. Access is not
@@ -459,7 +405,7 @@ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* monitor);
*
* @ingroup native
*/
GLFWAPI MirWindow* glfwGetMirWindow(GLFWwindow* window);
GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
@@ -517,7 +463,7 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
* @param[out] buffer Where to store the address of the color buffer, or
* `NULL`.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` 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
* synchronized.
@@ -538,7 +484,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height
* @param[out] buffer Where to store the address of the depth buffer, or
* `NULL`.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` 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
* synchronized.
+30 -62
View File
@@ -1,5 +1,5 @@
set(common_HEADERS internal.h mappings.h
set(common_HEADERS internal.h
"${GLFW_BINARY_DIR}/src/glfw_config.h"
"${GLFW_SOURCE_DIR}/include/GLFW/glfw3.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)
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
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_thread.c
nsgl_context.m egl_context.c osmesa_context.c)
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_tls.c
nsgl_context.m)
elseif (_GLFW_WIN32)
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
win32_monitor.c win32_time.c win32_thread.c win32_window.c
wgl_context.c egl_context.c osmesa_context.c)
win32_monitor.c win32_time.c win32_tls.c win32_window.c
wgl_context.c egl_context.c)
elseif (_GLFW_X11)
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h posix_time.h
posix_thread.h glx_context.h egl_context.h osmesa_context.h)
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.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
xkb_unicode.c posix_time.c posix_thread.c glx_context.c
egl_context.c osmesa_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()
xkb_unicode.c linux_joystick.c posix_time.c posix_tls.c
glx_context.c egl_context.c)
elseif (_GLFW_WAYLAND)
set(glfw_HEADERS ${common_HEADERS} wl_platform.h linux_joystick.h
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
osmesa_context.h)
posix_time.h posix_tls.h xkb_unicode.h egl_context.h)
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
egl_context.c osmesa_context.c)
linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c
egl_context.c)
ecm_add_wayland_client_protocol(glfw_SOURCES
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)
ecm_add_wayland_client_protocol(glfw_SOURCES
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)
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)
set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
osmesa_context.h)
posix_time.h posix_tls.h xkb_unicode.h egl_context.h)
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
egl_context.c osmesa_context.c)
linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c
egl_context.c)
elseif (_GLFW_OSMESA)
set(glfw_HEADERS ${common_HEADERS} null_platform.h null_joystick.h
posix_time.h posix_thread.h osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} null_init.c null_monitor.c null_window.c
null_joystick.c posix_time.c posix_thread.c osmesa_context.c)
set(glfw_HEADERS ${common_HEADERS} osmesa_platform.h
posix_time.h posix_tls.h osmesa_context.h)
set(glfw_SOURCES ${common_SOURCES} osmesa_init.c osmesa_monitor.c
osmesa_window.c posix_time.c posix_tls.c
osmesa_context.c)
endif()
if (APPLE)
@@ -72,18 +58,6 @@ if (APPLE)
set_source_files_properties(${glfw_SOURCES} PROPERTIES LANGUAGE C)
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})
set_target_properties(glfw PROPERTIES
OUTPUT_NAME ${GLFW_LIB_NAME}
@@ -92,12 +66,10 @@ set_target_properties(glfw PROPERTIES
POSITION_INDEPENDENT_CODE ON
FOLDER "GLFW3")
target_compile_definitions(glfw PRIVATE
_GLFW_USE_CONFIG_H
$<$<BOOL:${UNIX}>:_POSIX_C_SOURCE=200809L>)
target_compile_definitions(glfw PRIVATE -D_GLFW_USE_CONFIG_H)
target_include_directories(glfw PUBLIC
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>")
$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)
target_include_directories(glfw PRIVATE
"${GLFW_SOURCE_DIR}/src"
"${GLFW_BINARY_DIR}/src"
@@ -138,7 +110,7 @@ if (BUILD_SHARED_LIBS)
target_compile_options(glfw PRIVATE "-fvisibility=hidden")
endif()
target_compile_definitions(glfw INTERFACE GLFW_DLL)
target_compile_definitions(glfw INTERFACE -DGLFW_DLL)
target_link_libraries(glfw PRIVATE ${glfw_LIBRARIES})
else()
target_link_libraries(glfw INTERFACE ${glfw_LIBRARIES})
@@ -149,10 +121,6 @@ if (MSVC)
endif()
if (GLFW_INSTALL)
install(TARGETS glfw
EXPORT glfwTargets
RUNTIME DESTINATION "bin"
ARCHIVE DESTINATION "lib${LIB_SUFFIX}"
LIBRARY DESTINATION "lib${LIB_SUFFIX}")
install(TARGETS glfw EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX})
endif()
+24 -9
View File
@@ -28,6 +28,8 @@
#include <sys/param.h> // For MAXPATHLEN
#if defined(_GLFW_USE_CHDIR)
// Change to our application bundle's resources directory, if present
//
static void changeToResourcesDirectory(void)
@@ -64,6 +66,8 @@ static void changeToResourcesDirectory(void)
chdir(resourcesPath);
}
#endif /* _GLFW_USE_CHDIR */
// Create key code translation tables
//
static void createKeyTables(void)
@@ -215,9 +219,8 @@ static GLFWbool updateUnicodeDataNS(void)
return GLFW_FALSE;
}
_glfw.ns.unicodeData =
TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
_glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
if (!_glfw.ns.unicodeData)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@@ -233,8 +236,7 @@ static GLFWbool updateUnicodeDataNS(void)
static GLFWbool initializeTIS(void)
{
// This works only because Cocoa has already loaded it properly
_glfw.ns.tis.bundle =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
_glfw.ns.tis.bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
if (!_glfw.ns.tis.bundle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@@ -292,9 +294,6 @@ int _glfwPlatformInit(void)
{
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
if (_glfw.hints.init.ns.chdir)
changeToResourcesDirectory();
_glfw.ns.listener = [[GLFWLayoutListener alloc] init];
[[NSNotificationCenter defaultCenter]
addObserver:_glfw.ns.listener
@@ -302,6 +301,10 @@ int _glfwPlatformInit(void)
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
#if defined(_GLFW_USE_CHDIR)
changeToResourcesDirectory();
#endif
createKeyTables();
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
@@ -313,10 +316,12 @@ int _glfwPlatformInit(void)
if (!initializeTIS())
return GLFW_FALSE;
if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE;
_glfwInitTimerNS();
_glfwInitJoysticksNS();
_glfwPollMonitorsNS();
return GLFW_TRUE;
}
@@ -354,10 +359,14 @@ void _glfwPlatformTerminate(void)
_glfw.ns.listener = nil;
}
[_glfw.ns.cursor release];
_glfw.ns.cursor = nil;
free(_glfw.ns.clipboardString);
_glfwTerminateNSGL();
_glfwTerminateJoysticksNS();
_glfwTerminateThreadLocalStoragePOSIX();
[_glfw.ns.autoreleasePool release];
_glfw.ns.autoreleasePool = nil;
@@ -366,6 +375,12 @@ void _glfwPlatformTerminate(void)
const char* _glfwPlatformGetVersionString(void)
{
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)
" dynamic"
#endif
+17 -7
View File
@@ -24,27 +24,37 @@
//
//========================================================================
#ifndef _glfw3_cocoa_joystick_h_
#define _glfw3_cocoa_joystick_h_
#include <IOKit/IOKitLib.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/hid/IOHIDLib.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
//
typedef struct _GLFWjoystickNS
{
IOHIDDeviceRef device;
CFMutableArrayRef axes;
CFMutableArrayRef buttons;
CFMutableArrayRef hats;
GLFWbool present;
char name[256];
IOHIDDeviceRef deviceRef;
CFMutableArrayRef axisElements;
CFMutableArrayRef buttonElements;
CFMutableArrayRef hatElements;
float* axes;
unsigned char* buttons;
} _GLFWjoystickNS;
void _glfwInitJoysticksNS(void);
void _glfwTerminateJoysticksNS(void);
#endif // _glfw3_cocoa_joystick_h_
+358 -309
View File
@@ -42,167 +42,42 @@
//
typedef struct _GLFWjoyelementNS
{
IOHIDElementRef native;
uint32_t usage;
int index;
long minimum;
long maximum;
IOHIDElementRef elementRef;
long min;
long max;
long minReport;
long maxReport;
} _GLFWjoyelementNS;
// Returns the value of the specified element of the specified joystick
//
static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
{
IOHIDValueRef valueRef;
long value = 0;
static void getElementsCFArrayHandler(const void* value, void* parameter);
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;
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);
buttons = CFArrayCreateMutable(NULL, 0, NULL);
hats = CFArrayCreateMutable(NULL, 0, NULL);
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
if (property)
switch (usagePage)
{
CFStringGetCString(property,
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)
case kHIDPage_GenericDesktop:
{
switch (usage)
{
@@ -215,48 +90,241 @@ static void matchCallback(void* context,
case kHIDUsage_GD_Slider:
case kHIDUsage_GD_Dial:
case kHIDUsage_GD_Wheel:
target = axes;
elementsArray = js->axisElements;
break;
case kHIDUsage_GD_Hatswitch:
target = hats;
elementsArray = js->hatElements;
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));
element->native = native;
element->usage = usage;
element->index = (int) CFArrayGetCount(target);
element->minimum = IOHIDElementGetLogicalMin(native);
element->maximum = IOHIDElementGetLogicalMax(native);
CFArrayAppendValue(target, element);
value = IOHIDValueGetIntegerValue(valueRef);
// Record min and max for auto calibration
if (value < element->minReport)
element->minReport = value;
if (value > element->maxReport)
element->maxReport = value;
}
}
CFRelease(elements);
// Auto user scale
return value;
}
CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)),
compareElements, NULL);
CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)),
compareElements, NULL);
CFArraySortValues(hats, CFRangeMake(0, CFArrayGetCount(hats)),
compareElements, NULL);
// Removes the specified joystick
//
static void removeJoystick(_GLFWjoystickNS* js)
{
int i;
js = _glfwAllocJoystick(name, guid,
CFArrayGetCount(axes),
CFArrayGetCount(buttons),
CFArrayGetCount(hats));
if (!js->present)
return;
js->ns.device = device;
js->ns.axes = axes;
js->ns.buttons = buttons;
js->ns.hats = hats;
for (i = 0; i < CFArrayGetCount(js->axisElements); i++)
free((void*) CFArrayGetValueAtIndex(js->axisElements, i));
CFArrayRemoveAllValues(js->axisElements);
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
@@ -264,20 +332,60 @@ static void matchCallback(void* context,
static void removeCallback(void* context,
IOReturn result,
void* sender,
IOHIDDeviceRef device)
IOHIDDeviceRef deviceRef)
{
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;
}
}
}
// 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 //////
@@ -287,73 +395,56 @@ static void removeCallback(void* context,
//
void _glfwInitJoysticksNS(void)
{
CFMutableArrayRef matching;
const long usages[] =
{
kHIDUsage_GD_Joystick,
kHIDUsage_GD_GamePad,
kHIDUsage_GD_MultiAxisController
};
CFMutableArrayRef matchingCFArrayRef;
_glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone);
matching = CFArrayCreateMutable(kCFAllocatorDefault,
0,
&kCFTypeArrayCallBacks);
if (!matching)
matchingCFArrayRef = CFArrayCreateMutable(kCFAllocatorDefault,
0,
&kCFTypeArrayCallBacks);
if (matchingCFArrayRef)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array");
return;
}
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)
CFDictionaryRef matchingCFDictRef =
createMatchingDictionary(kHIDPage_GenericDesktop,
kHIDUsage_GD_Joystick);
if (matchingCFDictRef)
{
CFDictionarySetValue(dict,
CFSTR(kIOHIDDeviceUsagePageKey),
pageRef);
CFDictionarySetValue(dict,
CFSTR(kIOHIDDeviceUsageKey),
usageRef);
CFArrayAppendValue(matching, dict);
CFArrayAppendValue(matchingCFArrayRef, matchingCFDictRef);
CFRelease(matchingCFDictRef);
}
if (pageRef)
CFRelease(pageRef);
if (usageRef)
CFRelease(usageRef);
matchingCFDictRef = createMatchingDictionary(kHIDPage_GenericDesktop,
kHIDUsage_GD_GamePad);
if (matchingCFDictRef)
{
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,
&matchCallback, NULL);
IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager,
&removeCallback, NULL);
IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager,
CFRunLoopGetMain(),
kCFRunLoopDefaultMode);
IOHIDManagerOpen(_glfw.ns.hidManager, kIOHIDOptionsTypeNone);
// Execute the run loop once in order to register any initially-attached
@@ -367,8 +458,11 @@ void _glfwTerminateJoysticksNS(void)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
closeJoystick(_glfw.joysticks + jid);
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
{
_GLFWjoystickNS* js = _glfw.ns_js + jid;
removeJoystick(js);
}
CFRelease(_glfw.ns.hidManager);
_glfw.ns.hidManager = NULL;
@@ -379,84 +473,39 @@ void _glfwTerminateJoysticksNS(void)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
int _glfwPlatformJoystickPresent(int jid)
{
if (mode & _GLFW_POLL_AXES)
{
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]);
}
}
_GLFWjoystickNS* js = _glfw.ns_js + jid;
return js->present;
}
void _glfwPlatformUpdateGamepadGUID(char* guid)
const float* _glfwPlatformGetJoystickAxes(int jid, int* count)
{
if ((strncmp(guid + 4, "000000000000", 12) == 0) &&
(strncmp(guid + 20, "000000000000", 12) == 0))
{
char original[33];
strcpy(original, guid);
sprintf(guid, "03000000%.4s0000%.4s000000000000",
original, original + 16);
}
_GLFWjoystickNS* js = _glfw.ns_js + jid;
if (!pollJoystickAxisEvents(js))
return NULL;
*count = (int) CFArrayGetCount(js->axisElements);
return js->axes;
}
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
View File
@@ -48,14 +48,14 @@ static char* getDisplayName(CGDirectDisplayID displayID)
IOServiceMatching("IODisplayConnect"),
&it) != 0)
{
// This may happen if a desktop Mac is running headless
return NULL;
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to get display service port iterator");
return 0;
}
while ((service = IOIteratorNext(it)) != 0)
{
info = IODisplayCreateInfoDictionary(service,
kIODisplayOnlyPreferredName);
info = IODisplayCreateInfoDictionary(service, kIODisplayOnlyPreferredName);
CFNumberRef vendorIDRef =
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
@@ -99,6 +99,8 @@ static char* getDisplayName(CGDirectDisplayID displayID)
(const void**) &nameRef))
{
// This may happen if a desktop Mac is running headless
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve display name");
CFRelease(info);
return NULL;
}
@@ -126,7 +128,7 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode)
if (flags & kDisplayModeStretchedFlag)
return GLFW_FALSE;
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101200
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
@@ -157,7 +159,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
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);
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
{
@@ -173,7 +175,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
result.blueBits = 8;
}
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101200
CFRelease(format);
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
return result;
@@ -186,13 +188,7 @@ static CGDisplayFadeReservationToken beginFadeReservation(void)
CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
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;
}
@@ -203,11 +199,7 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
{
if (token != kCGDisplayFadeReservationInvalidToken)
{
CGDisplayFade(token, 0.5,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal,
0.0, 0.0, 0.0,
FALSE);
CGDisplayFade(token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
CGReleaseDisplayFadeReservation(token);
}
}
@@ -217,71 +209,6 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
////// 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
//
GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
@@ -361,6 +288,55 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
////// 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)
{
const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
+12 -12
View File
@@ -24,6 +24,9 @@
//
//========================================================================
#ifndef _glfw3_cocoa_platform_h_
#define _glfw3_cocoa_platform_h_
#include <stdint.h>
#include <dlfcn.h>
@@ -48,25 +51,23 @@ typedef struct VkMacOSSurfaceCreateInfoMVK
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
#include "posix_thread.h"
#include "posix_tls.h"
#include "cocoa_joystick.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_dlclose(handle) dlclose(handle)
#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_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_CURSOR_STATE _GLFWcursorNS ns
#define _GLFW_EGL_CONTEXT_STATE
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE
// HIToolbox.framework pointer typedefs
#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void);
@@ -102,7 +103,7 @@ typedef struct _GLFWlibraryNS
CGEventSourceRef eventSource;
id delegate;
id autoreleasePool;
GLFWbool cursorHidden;
id cursor;
TISInputSourceRef inputSource;
IOHIDManagerRef hidManager;
id unicodeData;
@@ -112,7 +113,6 @@ typedef struct _GLFWlibraryNS
short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1];
char* clipboardString;
CGPoint cascadePoint;
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
@@ -148,16 +148,16 @@ typedef struct _GLFWcursorNS
// Cocoa-specific global timer data
//
typedef struct _GLFWtimerNS
typedef struct _GLFWtimeNS
{
uint64_t frequency;
} _GLFWtimerNS;
} _GLFWtimeNS;
void _glfwInitTimerNS(void);
void _glfwPollMonitorsNS(void);
GLFWbool _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
#endif // _glfw3_cocoa_platform_h_
+2 -2
View File
@@ -40,7 +40,7 @@ void _glfwInitTimerNS(void)
mach_timebase_info_data_t 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)
{
return _glfw.timer.ns.frequency;
return _glfw.ns_time.frequency;
}
+95 -160
View File
@@ -50,6 +50,29 @@
#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
//
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]];
}
// 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
//
static void updateCursorImage(_GLFWwindow* window)
{
if (window->cursorMode == GLFW_CURSOR_NORMAL)
{
showCursor(window);
if (window->cursor)
[(NSCursor*) window->cursor->ns.object set];
else
[[NSCursor arrowCursor] set];
}
else
hideCursor(window);
[(NSCursor*) _glfw.ns.cursor set];
}
// 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];
_glfwInputMonitorWindow(window->monitor, window);
_glfwInputMonitorWindowChange(window->monitor, window);
return status;
}
@@ -159,7 +158,7 @@ static void releaseMonitor(_GLFWwindow* window)
if (window->monitor->window != window)
return;
_glfwInputMonitorWindow(window->monitor, NULL);
_glfwInputMonitorWindowChange(window->monitor, NULL);
_glfwRestoreVideoModeNS(window->monitor);
}
@@ -341,15 +340,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
{
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next)
{
if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update];
}
_glfwPollMonitorsNS();
_glfwInputMonitorChange();
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
@@ -387,6 +378,20 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
@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
{
self = [super init];
@@ -433,10 +438,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (id)makeBackingLayer
{
if (window->ns.layer)
return window->ns.layer;
return [super makeBackingLayer];
return window->ns.layer;
}
- (void)cursorUpdate:(NSEvent *)event
@@ -532,17 +534,11 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)mouseExited:(NSEvent *)event
{
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
showCursor(window);
_glfwInputCursorEnter(window, GLFW_FALSE);
}
- (void)mouseEntered:(NSEvent *)event
{
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
hideCursor(window);
_glfwInputCursorEnter(window, GLFW_TRUE);
}
@@ -714,11 +710,10 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
selectedRange:(NSRange)selectedRange
replacementRange:(NSRange)replacementRange
{
[markedText release];
if ([string isKindOfClass:[NSAttributedString class]])
markedText = [[NSMutableAttributedString alloc] initWithAttributedString:string];
[markedText initWithAttributedString:string];
else
markedText = [[NSMutableAttributedString alloc] initWithString:string];
[markedText initWithString:string];
}
- (void)unmarkText
@@ -797,11 +792,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
return YES;
}
- (BOOL)canBecomeMainWindow
{
return YES;
}
@end
@@ -810,10 +800,6 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
//------------------------------------------------------------------------
@interface GLFWApplication : NSApplication
{
NSArray* nibObjects;
}
@end
@implementation GLFWApplication
@@ -838,58 +824,53 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (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
// 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. Add a nib to save us this horror.
#if defined(_GLFW_USE_MENUBAR)
// Try to figure out what the calling application is called
//
static void createMenuBar(void)
static NSString* findAppName(void)
{
size_t i;
NSString* appName = nil;
NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
NSString* nameKeys[] =
NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary];
// Keys to search for as potential application names
NSString* GLFWNameKeys[] =
{
@"CFBundleDisplayName",
@"CFBundleName",
@"CFBundleExecutable",
};
// Try to figure out what the calling application is called
for (i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
for (i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++)
{
id name = [bundleInfo objectForKey:nameKeys[i]];
id name = [infoDictionary objectForKey:GLFWNameKeys[i]];
if (name &&
[name isKindOfClass:[NSString class]] &&
![name isEqualToString:@""])
{
appName = name;
break;
return name;
}
}
if (!appName)
{
char** progname = _NSGetProgname();
if (progname && *progname)
appName = [NSString stringWithUTF8String:*progname];
else
appName = @"GLFW Application";
}
char** progname = _NSGetProgname();
if (progname && *progname)
return [NSString stringWithUTF8String:*progname];
// Really shouldn't get here
return @"GLFW Application";
}
// Set up the menu bar (manually)
// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
// could go away at any moment, lots of stuff that really should be
// localize(d|able), etc. Loading a nib would save us this horror, but that
// doesn't seem like a good thing to require of GLFW users.
//
static void createMenuBar(void)
{
NSString* appName = findAppName();
NSMenu* bar = [[NSMenu alloc] init];
[NSApp setMainMenu:bar];
@@ -956,6 +937,8 @@ static void createMenuBar(void)
[NSApp performSelector:setAppleMenuSelector withObject:appMenu];
}
#endif /* _GLFW_USE_MENUBAR */
// Initialize the Cocoa Application Kit
//
static GLFWbool initializeAppKit(void)
@@ -971,20 +954,15 @@ static GLFWbool initializeAppKit(void)
toTarget:NSApp
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
// finishLaunching below, in order to properly emulate the behavior
// of NSApplicationMain
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
[NSApp loadMainMenu];
else
createMenuBar();
}
#if defined(_GLFW_USE_MENUBAR)
// Menu bar setup must go between sharedApplication above and
// finishLaunching below, in order to properly emulate the behavior
// of NSApplicationMain
createMenuBar();
#endif
// 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
@@ -999,13 +977,6 @@ static GLFWbool initializeAppKit(void)
[NSApp setDelegate:_glfw.ns.delegate];
[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;
}
@@ -1054,17 +1025,9 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
else
{
[window->ns.object center];
_glfw.ns.cascadePoint =
NSPointToCGPoint([window->ns.object cascadeTopLeftFromPoint:
NSPointFromCGPoint(_glfw.ns.cascadePoint)]);
if (wndconfig->resizable)
{
const NSWindowCollectionBehavior behavior =
NSWindowCollectionBehaviorFullScreenPrimary |
NSWindowCollectionBehaviorManaged;
[window->ns.object setCollectionBehavior:behavior];
}
[window->ns.object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
if (wndconfig->floating)
[window->ns.object setLevel:NSFloatingWindowLevel];
@@ -1073,9 +1036,6 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
[window->ns.object zoom:nil];
}
if (wndconfig->ns.frame)
[window->ns.object setFrameAutosaveName:[NSString stringWithUTF8String:wndconfig->title]];
window->ns.view = [[GLFWContentView alloc] initWithGlfwWindow:window];
if (wndconfig->ns.retina)
@@ -1116,19 +1076,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
}
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
else
{
if (!_glfwInitEGL())
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;
_glfwInputError(GLFW_API_UNAVAILABLE, "Cocoa: EGL not available");
return GLFW_FALSE;
}
}
@@ -1139,8 +1090,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!acquireMonitor(window))
return GLFW_FALSE;
if (wndconfig->centerCursor)
centerCursor(window);
centerCursor(window);
}
return GLFW_TRUE;
@@ -1306,11 +1256,6 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
[window->ns.object orderOut:nil];
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{
[NSApp requestUserAttention:NSInformationalRequest];
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
{
// Make us the active application
@@ -1354,10 +1299,6 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_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);
[window->ns.object setStyleMask:styleMask];
[window->ns.object makeFirstResponder:window->ns.view];
@@ -1584,8 +1525,14 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
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;
UniChar characters[8];
UniCharCount characterCount = 0;
@@ -1673,19 +1620,7 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
if (!initializeAppKit())
return GLFW_FALSE;
if (shape == GLFW_ARROW_CURSOR)
cursor->ns.object = [NSCursor arrowCursor];
else if (shape == GLFW_IBEAM_CURSOR)
cursor->ns.object = [NSCursor IBeamCursor];
else if (shape == GLFW_CROSSHAIR_CURSOR)
cursor->ns.object = [NSCursor crosshairCursor];
else if (shape == GLFW_HAND_CURSOR)
cursor->ns.object = [NSCursor pointingHandCursor];
else if (shape == GLFW_HRESIZE_CURSOR)
cursor->ns.object = [NSCursor resizeLeftRightCursor];
else if (shape == GLFW_VRESIZE_CURSOR)
cursor->ns.object = [NSCursor resizeUpDownCursor];
cursor->ns.object = getStandardCursor(shape);
if (!cursor->ns.object)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
+13 -13
View File
@@ -41,11 +41,10 @@
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
{
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
ctxconfig->source != GLFW_EGL_CONTEXT_API &&
ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
ctxconfig->source != GLFW_EGL_CONTEXT_API)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context creation API 0x%08X",
"Invalid context creation API %i",
ctxconfig->source);
return GLFW_FALSE;
}
@@ -55,7 +54,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
ctxconfig->client != GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid client API 0x%08X",
"Invalid client API %i",
ctxconfig->client);
return GLFW_FALSE;
}
@@ -85,7 +84,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid OpenGL profile 0x%08X",
"Invalid OpenGL profile %i",
ctxconfig->profile);
return GLFW_FALSE;
}
@@ -134,7 +133,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context robustness mode 0x%08X",
"Invalid context robustness mode %i",
ctxconfig->robustness);
return GLFW_FALSE;
}
@@ -146,7 +145,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context release behavior 0x%08X",
"Invalid context release behavior %i",
ctxconfig->release);
return GLFW_FALSE;
}
@@ -331,7 +330,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
NULL
};
window = _glfwPlatformGetTls(&_glfw.contextSlot);
window = _glfwPlatformGetCurrentContext();
window->context.source = ctxconfig->source;
window->context.client = GLFW_OPENGL_API;
@@ -578,7 +577,7 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFWwindow* previous = _glfwPlatformGetTls(&_glfw.contextSlot);
_GLFWwindow* previous = _glfwPlatformGetCurrentContext();
_GLFW_REQUIRE_INIT();
@@ -601,7 +600,7 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetTls(&_glfw.contextSlot);
return (GLFWwindow*) _glfwPlatformGetCurrentContext();
}
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
@@ -626,7 +625,7 @@ GLFWAPI void glfwSwapInterval(int interval)
_GLFW_REQUIRE_INIT();
window = _glfwPlatformGetTls(&_glfw.contextSlot);
window = _glfwPlatformGetCurrentContext();
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
@@ -639,11 +638,12 @@ GLFWAPI void glfwSwapInterval(int interval)
GLFWAPI int glfwExtensionSupported(const char* extension)
{
_GLFWwindow* window;
assert(extension != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
window = _glfwPlatformGetTls(&_glfw.contextSlot);
window = _glfwPlatformGetCurrentContext();
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
@@ -708,7 +708,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
window = _glfwPlatformGetTls(&_glfw.contextSlot);
window = _glfwPlatformGetCurrentContext();
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
+41 -77
View File
@@ -113,21 +113,13 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
_GLFWfbconfig* u = usableConfigs + usableCount;
// 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;
#if defined(_GLFW_EGLDEVICE)
// Only consider stream EGLConfigs
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_STREAM_BIT_KHR))
continue;
#else
// Only consider window EGLConfigs
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
continue;
#endif
#if defined(_GLFW_X11)
// Only consider EGLConfigs with associated Visuals
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)
{
if (window != _glfwPlatformGetTls(&_glfw.contextSlot))
if (window != _glfwPlatformGetCurrentContext())
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"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)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
if (window->context.egl.client)
{
@@ -294,15 +286,11 @@ GLFWbool _glfwInitEGL(void)
int i;
const char* sonames[] =
{
#if defined(_GLFW_EGL_LIBRARY)
_GLFW_EGL_LIBRARY,
#elif defined(_GLFW_WIN32)
#if defined(_GLFW_WIN32)
"libEGL.dll",
"EGL.dll",
#elif defined(_GLFW_COCOA)
"libEGL.dylib",
#elif defined(__CYGWIN__)
"libEGL-1.so",
#else
"libEGL.so.1",
#endif
@@ -384,9 +372,6 @@ GLFWbool _glfwInitEGL(void)
return GLFW_FALSE;
}
// For EGLDevice backend the display gets initialized
// in _glfwPlatformInit()
#if !defined(_GLFW_EGLDEVICE)
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
if (_glfw.egl.display == EGL_NO_DISPLAY)
{
@@ -407,7 +392,6 @@ GLFWbool _glfwInitEGL(void)
_glfwTerminateEGL();
return GLFW_FALSE;
}
#endif
_glfw.egl.KHR_create_context =
extensionSupportedEGL("EGL_KHR_create_context");
@@ -417,8 +401,6 @@ GLFWbool _glfwInitEGL(void)
extensionSupportedEGL("EGL_KHR_gl_colorspace");
_glfw.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;
}
@@ -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++] = a; \
attribs[index++] = v; \
attribs[index++] = attribName; \
attribs[index++] = attribValue; \
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
}
// Create the OpenGL or OpenGL ES context
@@ -456,7 +438,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
EGLint attribs[40];
EGLConfig config;
EGLContext share = NULL;
int index = 0;
if (!_glfw.egl.display)
{
@@ -497,7 +478,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (_glfw.egl.KHR_create_context)
{
int mask = 0, flags = 0;
int index = 0, mask = 0, flags = 0;
if (ctxconfig->client == GLFW_OPENGL_API)
{
@@ -508,6 +489,12 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
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)
@@ -517,57 +504,44 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_NO_RESET_NOTIFICATION_KHR);
setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_NO_RESET_NOTIFICATION_KHR);
}
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{
setAttrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_LOSE_CONTEXT_ON_RESET_KHR);
setEGLattrib(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_LOSE_CONTEXT_ON_RESET_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)
{
setAttrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
setAttrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
setEGLattrib(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
setEGLattrib(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
}
if (mask)
setAttrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
setEGLattrib(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
if (flags)
setAttrib(EGL_CONTEXT_FLAGS_KHR, flags);
setEGLattrib(EGL_CONTEXT_FLAGS_KHR, flags);
setEGLattrib(EGL_NONE, EGL_NONE);
}
else
{
int index = 0;
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)
{
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);
// Context release behaviors (GL_KHR_context_flush_control) are not yet
// supported on EGL but are not a hard constraint, so ignore and continue
window->context.egl.handle = eglCreateContext(_glfw.egl.display,
config, share, attribs);
@@ -587,15 +561,14 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
if (fbconfig->sRGB)
{
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 =
eglCreateWindowSurface(_glfw.egl.display,
config,
@@ -608,7 +581,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
#endif
window->context.egl.config = config;
@@ -619,9 +591,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const char** sonames;
const char* es1sonames[] =
{
#if defined(_GLFW_GLESV1_LIBRARY)
_GLFW_GLESV1_LIBRARY,
#elif defined(_GLFW_WIN32)
#if defined(_GLFW_WIN32)
"GLESv1_CM.dll",
"libGLES_CM.dll",
#elif defined(_GLFW_COCOA)
@@ -634,15 +604,11 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
};
const char* es2sonames[] =
{
#if defined(_GLFW_GLESV2_LIBRARY)
_GLFW_GLESV2_LIBRARY,
#elif defined(_GLFW_WIN32)
#if defined(_GLFW_WIN32)
"GLESv2.dll",
"libGLESv2.dll",
#elif defined(_GLFW_COCOA)
"libGLESv2.dylib",
#elif defined(__CYGWIN__)
"libGLESv2-2.so",
#else
"libGLESv2.so.2",
#endif
@@ -650,9 +616,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
};
const char* glsonames[] =
{
#if defined(_GLFW_OPENGL_LIBRARY)
_GLFW_OPENGL_LIBRARY,
#elif defined(_GLFW_WIN32)
#if defined(_GLFW_WIN32)
#elif defined(_GLFW_COCOA)
#else
"libGL.so.1",
@@ -700,7 +664,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
return GLFW_TRUE;
}
#undef setAttrib
#undef setEGLattrib
// Returns the Visual and depth of the chosen EGLConfig
//
+4 -15
View File
@@ -25,16 +25,15 @@
//
//========================================================================
#ifndef _glfw3_egl_context_h_
#define _glfw3_egl_context_h_
#if defined(_GLFW_USE_EGLPLATFORM_H)
#include <EGL/eglplatform.h>
#elif defined(_GLFW_WIN32)
#define EGLAPIENTRY __stdcall
typedef HDC EGLNativeDisplayType;
typedef HWND EGLNativeWindowType;
#elif defined(_GLFW_COCOA)
#define EGLAPIENTRY
typedef void* EGLNativeDisplayType;
typedef id EGLNativeWindowType;
#elif defined(_GLFW_X11)
#define EGLAPIENTRY
typedef Display* EGLNativeDisplayType;
@@ -47,10 +46,6 @@ typedef struct wl_egl_window* EGLNativeWindowType;
#define EGLAPIENTRY
typedef MirEGLNativeDisplayType EGLNativeDisplayType;
typedef MirEGLNativeWindowType EGLNativeWindowType;
#elif defined(_GLFW_EGLDEVICE)
#define EGLAPIENTRY
typedef void* EGLNativeDisplayType;
typedef int EGLNativeWindowType;
#else
#error "No supported EGL platform selected"
#endif
@@ -88,8 +83,6 @@ typedef int EGLNativeWindowType;
#define EGL_OPENGL_ES_API 0x30a0
#define EGL_OPENGL_API 0x30a2
#define EGL_NONE 0x3038
#define EGL_WIDTH 0x3057
#define EGL_HEIGHT 0x3056
#define EGL_EXTENSIONS 0x3055
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_NATIVE_VISUAL_ID 0x302e
@@ -113,9 +106,6 @@ typedef int EGLNativeWindowType;
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR 0x31b3
#define EGL_GL_COLORSPACE_KHR 0x309d
#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 unsigned int EGLBoolean;
@@ -124,7 +114,6 @@ typedef void* EGLConfig;
typedef void* EGLContext;
typedef void* EGLDisplay;
typedef void* EGLSurface;
typedef intptr_t EGLAttrib;
// EGL function pointer typedefs
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
@@ -188,7 +177,6 @@ typedef struct _GLFWlibraryEGL
GLFWbool KHR_create_context_no_error;
GLFWbool KHR_gl_colorspace;
GLFWbool KHR_get_all_proc_addresses;
GLFWbool KHR_context_flush_control;
void* handle;
@@ -223,3 +211,4 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
Visual** visual, int* depth);
#endif /*_GLFW_X11*/
#endif // _glfw3_egl_context_h_
-284
View File
@@ -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
;
}
-165
View File
@@ -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");
}
-151
View File
@@ -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);
-430
View File
@@ -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;
}
+5 -2
View File
@@ -46,8 +46,6 @@
#cmakedefine _GLFW_MIR
// Define this to 1 if building GLFW for 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
#cmakedefine _GLFW_BUILD_DLL
@@ -57,3 +55,8 @@
// Define this to 1 to force use of high-performance GPU on hybrid systems
#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
View File
@@ -59,12 +59,12 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
// HACK: This is a (hopefully temporary) workaround for Chromium
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
if (vendor && strcmp(vendor, "Chromium") == 0)
if (strcmp(vendor, "Chromium") == 0)
trustWindowBit = GLFW_FALSE;
nativeConfigs =
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
if (!nativeConfigs || !nativeCount)
if (!nativeCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
return GLFW_FALSE;
@@ -165,7 +165,7 @@ static void makeContextCurrentGLX(_GLFWwindow* window)
}
}
_glfwPlatformSetTls(&_glfw.contextSlot, window);
_glfwPlatformSetCurrentContext(window);
}
static void swapBuffersGLX(_GLFWwindow* window)
@@ -175,7 +175,7 @@ static void swapBuffersGLX(_GLFWwindow* window)
static void swapIntervalGLX(int interval)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
if (_glfw.glx.EXT_swap_control)
{
@@ -244,9 +244,7 @@ GLFWbool _glfwInitGLX(void)
int i;
const char* sonames[] =
{
#if defined(_GLFW_GLX_LIBRARY)
_GLFW_GLX_LIBRARY,
#elif defined(__CYGWIN__)
#if defined(__CYGWIN__)
"libGL-1.so",
#else
"libGL.so.1",
@@ -399,9 +397,6 @@ GLFWbool _glfwInitGLX(void)
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
_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"))
_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++] = a; \
attribs[index++] = v; \
attribs[index++] = attribName; \
attribs[index++] = attribValue; \
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
}
// Create the OpenGL or OpenGL ES context
@@ -503,6 +498,8 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
if (ctxconfig->debug)
flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
if (ctxconfig->noerror)
flags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;
if (ctxconfig->robustness)
{
@@ -510,13 +507,13 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_NO_RESET_NOTIFICATION_ARB);
setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_NO_RESET_NOTIFICATION_ARB);
}
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{
setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_LOSE_CONTEXT_ON_RESET_ARB);
setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_LOSE_CONTEXT_ON_RESET_ARB);
}
flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
@@ -529,39 +526,33 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
{
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
}
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{
setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_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
// explicitly requesting version 1.0 does not always return the
// highest version supported by the driver
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
}
if (mask)
setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
if (flags)
setAttrib(GLX_CONTEXT_FLAGS_ARB, flags);
setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags);
setAttrib(None, None);
setGLXattrib(None, None);
window->context.glx.handle =
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
@@ -618,7 +609,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
return GLFW_TRUE;
}
#undef setAttrib
#undef setGLXattrib
// Returns the Visual and depth of the chosen GLXFBConfig
//
+4 -2
View File
@@ -25,6 +25,9 @@
//
//========================================================================
#ifndef _glfw3_glx_context_h_
#define _glfw3_glx_context_h_
#define GLX_VENDOR 1
#define GLX_RGBA_BIT 0x00000001
#define GLX_WINDOW_BIT 0x00000001
@@ -64,7 +67,6 @@
#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
typedef XID GLXWindow;
typedef XID GLXDrawable;
@@ -163,7 +165,6 @@ typedef struct _GLFWlibraryGLX
GLFWbool ARB_create_context_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
} _GLFWlibraryGLX;
@@ -179,3 +180,4 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);
#endif // _glfw3_glx_context_h_
+83 -202
View File
@@ -26,45 +26,33 @@
//========================================================================
#include "internal.h"
#include "mappings.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.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.
// 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
// after termination
// This is outside of _glfw so it can be initialized and usable before
// glfwInit is called, which lets that function report errors
//
static _GLFWerror _glfwMainThreadError;
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
}
};
static GLFWerrorfun _glfwErrorCallback = NULL;
// 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:
return "The GLFW library is not initialized";
@@ -81,7 +69,7 @@ static const char* getErrorString(int code)
case GLFW_VERSION_UNAVAILABLE:
return "The requested API version is unavailable";
case GLFW_PLATFORM_ERROR:
return "An undocumented platform-specific error occurred";
return "A platform-specific error occurred";
case GLFW_FORMAT_UNAVAILABLE:
return "The requested format is unavailable";
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;
if (!_glfwInitialized)
return;
memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks));
while (_glfw.windowListHead)
@@ -110,174 +161,28 @@ static void terminate(void)
_GLFWmonitor* monitor = _glfw.monitors[i];
if (monitor->originalRamp.size)
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
_glfwFreeMonitor(monitor);
}
free(_glfw.monitors);
_glfwTerminateVulkan();
_glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount);
_glfw.monitors = NULL;
_glfw.monitorCount = 0;
free(_glfw.mappings);
_glfw.mappings = NULL;
_glfw.mappingCount = 0;
_glfwTerminateVulkan();
_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));
}
//////////////////////////////////////////////////////////////////////////
////// 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);
_glfwInitialized = GLFW_FALSE;
}
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
{
if (major != NULL)
*major = GLFW_VERSION_MAJOR;
if (minor != NULL)
*minor = GLFW_VERSION_MINOR;
if (rev != NULL)
*rev = GLFW_VERSION_REVISION;
}
@@ -287,30 +192,6 @@ GLFWAPI const char* glfwGetVersionString(void)
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)
{
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
+87 -566
View File
@@ -29,144 +29,11 @@
#include <assert.h>
#include <float.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// Internal key state used for sticky keys
#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 //////
@@ -223,6 +90,7 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
return;
// Register mouse button action
if (action == GLFW_RELEASE && window->stickyMouseButtons)
window->mouseButtons[button] = _GLFW_STICK;
else
@@ -256,82 +124,22 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** 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)
_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 //////
//////////////////////////////////////////////////////////////////////////
_GLFWjoystick* _glfwAllocJoystick(const char* name,
const char* guid,
int axisCount,
int buttonCount,
int hatCount)
GLFWbool _glfwIsPrintable(int key)
{
int jid;
_GLFWjoystick* js;
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));
return (key >= GLFW_KEY_APOSTROPHE && key <= GLFW_KEY_WORLD_2) ||
(key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD) ||
key == GLFW_KEY_KP_EQUAL;
}
@@ -354,10 +162,10 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
return window->stickyKeys;
case GLFW_STICKY_MOUSE_BUTTONS:
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)
@@ -367,91 +175,85 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
_GLFW_REQUIRE_INIT();
if (mode == GLFW_CURSOR)
switch (mode)
{
if (value != GLFW_CURSOR_NORMAL &&
value != GLFW_CURSOR_HIDDEN &&
value != GLFW_CURSOR_DISABLED)
case GLFW_CURSOR:
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid cursor mode 0x%08X",
value);
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 (value != GLFW_CURSOR_NORMAL &&
value != GLFW_CURSOR_HIDDEN &&
value != GLFW_CURSOR_DISABLED)
{
if (window->keys[i] == _GLFW_STICK)
window->keys[i] = GLFW_RELEASE;
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid cursor mode %i",
value);
return;
}
}
window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
}
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyMouseButtons == value)
if (window->cursorMode == value)
return;
window->cursorMode = value;
_glfwPlatformGetCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
if (_glfwPlatformWindowFocused(window))
_glfwPlatformSetCursorMode(window, 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;
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)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
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);
return _glfwPlatformGetKeyName(key, scancode);
}
GLFWAPI int glfwGetKeyScancode(int key)
@@ -602,7 +404,7 @@ GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
shape != GLFW_HRESIZE_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;
}
@@ -753,165 +555,60 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
GLFWAPI int glfwJoystickPresent(int jid)
{
_GLFWjoystick* js;
assert(jid >= GLFW_JOYSTICK_1);
assert(jid <= GLFW_JOYSTICK_LAST);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFW_REQUIRE_INIT_OR_RETURN(0);
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
return GLFW_FALSE;
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", jid);
return 0;
}
js = _glfw.joysticks + jid;
if (!js->present)
return GLFW_FALSE;
return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
return _glfwPlatformJoystickPresent(jid);
}
GLFWAPI const float* glfwGetJoystickAxes(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);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", jid);
return NULL;
}
js = _glfw.joysticks + jid;
if (!js->present)
return NULL;
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES))
return NULL;
*count = js->axisCount;
return js->axes;
return _glfwPlatformGetJoystickAxes(jid, 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);
*count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
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;
}
js = _glfw.joysticks + jid;
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;
return _glfwPlatformGetJoystickButtons(jid, count);
}
GLFWAPI const char* glfwGetJoystickName(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);
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", jid);
return NULL;
}
js = _glfw.joysticks + 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;
return _glfwPlatformGetJoystickName(jid);
}
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
@@ -921,182 +618,6 @@ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun 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)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
@@ -1119,7 +640,7 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
GLFWAPI double glfwGetTime(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0.0);
return (double) (_glfwPlatformGetTimerValue() - _glfw.timer.offset) /
return (double) (_glfwPlatformGetTimerValue() - _glfw.timerOffset) /
_glfwPlatformGetTimerFrequency();
}
@@ -1133,7 +654,7 @@ GLFWAPI void glfwSetTime(double time)
return;
}
_glfw.timer.offset = _glfwPlatformGetTimerValue() -
_glfw.timerOffset = _glfwPlatformGetTimerValue() -
(uint64_t) (time * _glfwPlatformGetTimerFrequency());
}
+308 -223
View File
@@ -25,6 +25,10 @@
//
//========================================================================
#ifndef _glfw3_internal_h_
#define _glfw3_internal_h_
#if defined(_GLFW_USE_CONFIG_H)
#include "glfw_config.h"
#endif
@@ -33,8 +37,6 @@
defined(GLFW_INCLUDE_ES1) || \
defined(GLFW_INCLUDE_ES2) || \
defined(GLFW_INCLUDE_ES3) || \
defined(GLFW_INCLUDE_ES31) || \
defined(GLFW_INCLUDE_ES32) || \
defined(GLFW_INCLUDE_NONE) || \
defined(GLFW_INCLUDE_GLEXT) || \
defined(GLFW_INCLUDE_GLU) || \
@@ -46,20 +48,8 @@
#define GLFW_INCLUDE_NONE
#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 struct _GLFWerror _GLFWerror;
typedef struct _GLFWinitconfig _GLFWinitconfig;
typedef struct _GLFWwndconfig _GLFWwndconfig;
typedef struct _GLFWctxconfig _GLFWctxconfig;
typedef struct _GLFWfbconfig _GLFWfbconfig;
@@ -68,11 +58,6 @@ typedef struct _GLFWwindow _GLFWwindow;
typedef struct _GLFWlibrary _GLFWlibrary;
typedef struct _GLFWmonitor _GLFWmonitor;
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 (* _GLFWswapbuffersfun)(_GLFWwindow*);
@@ -189,9 +174,7 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
#elif defined(_GLFW_MIR)
#include "mir_platform.h"
#elif defined(_GLFW_OSMESA)
#include "null_platform.h"
#elif defined(_GLFW_EGLDEVICE)
#include "egldevice_platform.h"
#include "osmesa_platform.h"
#else
#error "No supported window creation API selected"
#endif
@@ -237,13 +220,13 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
// Checks for whether the library has been initialized
#define _GLFW_REQUIRE_INIT() \
if (!_glfw.initialized) \
if (!_glfwInitialized) \
{ \
_glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
return; \
}
#define _GLFW_REQUIRE_INIT_OR_RETURN(x) \
if (!_glfw.initialized) \
if (!_glfwInitialized) \
{ \
_glfwInputError(GLFW_NOT_INITIALIZED, NULL); \
return x; \
@@ -263,30 +246,6 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
// 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.
*
* Parameters relating to the creation of the window but not directly related
@@ -305,10 +264,8 @@ struct _GLFWwndconfig
GLFWbool autoIconify;
GLFWbool floating;
GLFWbool maximized;
GLFWbool centerCursor;
struct {
GLFWbool retina;
GLFWbool frame;
} ns;
};
@@ -331,9 +288,6 @@ struct _GLFWctxconfig
int robustness;
int release;
_GLFWwindow* share;
struct {
GLFWbool offline;
} nsgl;
};
/*! @brief Framebuffer configuration.
@@ -391,8 +345,6 @@ struct _GLFWcontext
_GLFW_PLATFORM_CONTEXT_STATE;
// This is defined in egl_context.h
_GLFW_EGL_CONTEXT_STATE;
// This is defined in osmesa_context.h
_GLFW_OSMESA_CONTEXT_STATE;
};
/*! @brief Window and context structure.
@@ -482,93 +434,25 @@ struct _GLFWcursor
_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.
*/
struct _GLFWlibrary
{
GLFWbool initialized;
struct {
_GLFWinitconfig init;
_GLFWfbconfig framebuffer;
_GLFWwndconfig window;
_GLFWctxconfig context;
int refreshRate;
} hints;
_GLFWerror* errorListHead;
_GLFWcursor* cursorListHead;
_GLFWwindow* windowListHead;
_GLFWmonitor** monitors;
int monitorCount;
_GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1];
_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;
uint64_t timerOffset;
struct {
GLFWbool available;
@@ -602,12 +486,14 @@ struct _GLFWlibrary
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
// This is defined in the context API's context.h
_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
_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
_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
//========================================================================
/*! @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;
@@ -624,96 +516,332 @@ extern _GLFWlibrary _glfw;
// 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);
/*! @brief Terminates the platform-specific part of the library.
* @ingroup platform
*/
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);
/*! @copydoc glfwGetCursorPos
* @ingroup platform
*/
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);
/*! @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);
/*! @copydoc glfwGetVideoModes
* @ingroup platform
*/
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
/*! @ingroup platform
*/
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
/*! @copydoc glfwGetGammaRamp
* @ingroup platform
*/
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
/*! @copydoc glfwSetGammaRamp
* @ingroup platform
*/
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
/*! @copydoc glfwSetClipboardString
* @ingroup platform
*/
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);
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
void _glfwPlatformUpdateGamepadGUID(char* guid);
/*! @copydoc glfwJoystickPresent
* @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);
/*! @copydoc glfwGetTimerFrequency
* @ingroup platform
*/
uint64_t _glfwPlatformGetTimerFrequency(void);
/*! @ingroup platform
*/
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
/*! @ingroup platform
*/
void _glfwPlatformDestroyWindow(_GLFWwindow* window);
/*! @copydoc glfwSetWindowTitle
* @ingroup platform
*/
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title);
/*! @copydoc glfwSetWindowIcon
* @ingroup platform
*/
void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count, const GLFWimage* images);
/*! @copydoc glfwGetWindowPos
* @ingroup platform
*/
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos);
/*! @copydoc glfwSetWindowPos
* @ingroup platform
*/
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos);
/*! @copydoc glfwGetWindowSize
* @ingroup platform
*/
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height);
/*! @copydoc glfwSetWindowSize
* @ingroup platform
*/
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height);
/*! @copydoc glfwSetWindowSizeLimits
* @ingroup platform
*/
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
/*! @copydoc glfwSetWindowAspectRatio
* @ingroup platform
*/
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
/*! @copydoc glfwGetFramebufferSize
* @ingroup platform
*/
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
/*! @copydoc glfwGetWindowFrameSize
* @ingroup platform
*/
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
/*! @copydoc glfwIconifyWindow
* @ingroup platform
*/
void _glfwPlatformIconifyWindow(_GLFWwindow* window);
/*! @copydoc glfwRestoreWindow
* @ingroup platform
*/
void _glfwPlatformRestoreWindow(_GLFWwindow* window);
/*! @copydoc glfwMaximizeWindow
* @ingroup platform
*/
void _glfwPlatformMaximizeWindow(_GLFWwindow* window);
/*! @copydoc glfwShowWindow
* @ingroup platform
*/
void _glfwPlatformShowWindow(_GLFWwindow* window);
/*! @copydoc glfwHideWindow
* @ingroup platform
*/
void _glfwPlatformHideWindow(_GLFWwindow* window);
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window);
/*! @copydoc glfwFocusWindow
* @ingroup platform
*/
void _glfwPlatformFocusWindow(_GLFWwindow* window);
/*! @copydoc glfwSetWindowMonitor
* @ingroup platform
*/
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);
/*! @brief Returns whether the window is iconified.
* @ingroup platform
*/
int _glfwPlatformWindowIconified(_GLFWwindow* window);
/*! @brief Returns whether the window is visible.
* @ingroup platform
*/
int _glfwPlatformWindowVisible(_GLFWwindow* window);
/*! @brief Returns whether the window is maximized.
* @ingroup platform
*/
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
/*! @brief Sets whether the window is resizable by the user.
* @ingroup platform
*/
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
/*! @brief Sets whether the window is decorated.
* @ingroup platform
*/
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
/*! @brief Sets whether the window is floating.
* @ingroup platform
*/
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
/*! @copydoc glfwPollEvents
* @ingroup platform
*/
void _glfwPlatformPollEvents(void);
/*! @copydoc glfwWaitEvents
* @ingroup platform
*/
void _glfwPlatformWaitEvents(void);
/*! @copydoc glfwWaitEventsTimeout
* @ingroup platform
*/
void _glfwPlatformWaitEventsTimeout(double timeout);
/*! @copydoc glfwPostEmptyEvent
* @ingroup platform
*/
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);
/*! @ingroup platform
*/
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
/*! @ingroup platform
*/
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
//========================================================================
/*! @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] focused `GLFW_TRUE` if the window received focus, or `GLFW_FALSE`
* if it lost focus.
@@ -721,7 +849,7 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
*/
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] 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.
@@ -729,7 +857,7 @@ void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
*/
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] width The new width 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);
/*! @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] width The new width, 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);
/*! @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] iconified `GLFW_TRUE` if the window was iconified, or
* `GLFW_FALSE` if it was restored.
@@ -753,7 +881,7 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
*/
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] maximized `GLFW_TRUE` if the window was maximized, or
* `GLFW_FALSE` if it was restored.
@@ -761,22 +889,17 @@ void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);
*/
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.
*/
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.
* @ingroup event
*/
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);
/*! @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] button The button that was pressed or released.
* @param[in] action @ref GLFW_PRESS or @ref GLFW_RELEASE.
* @param[in] mods The modifiers pressed when the event was generated.
* @ingroup event
*/
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);
/*! @brief Notifies shared code of a monitor connection or disconnection.
* @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
/*! @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
* 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
/*! @ingroup event
*/
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
void _glfwInputMonitorWindowChange(_GLFWmonitor* monitor, _GLFWwindow* window);
/*! @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
* description.
* @ingroup event
*/
#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
void _glfwInputError(int code, const char* format, ...);
void _glfwInputError(int error, const char* format, ...);
#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] count The number of 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);
/*! @brief Notifies shared code of a joystick connection or disconnection.
* @param[in] js The joystick that was connected or disconnected.
/*! @brief Notifies shared code of a joystick connection/disconnection event.
* @param[in] jid The joystick that was connected or disconnected.
* @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`.
* @ingroup event
*/
void _glfwInputJoystick(_GLFWjoystick* js, 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);
void _glfwInputJoystickChange(int jid, int event);
//========================================================================
// Utility functions
//========================================================================
/*! @brief Chooses the video mode most closely matching the desired one.
* @ingroup utility
/*! @ingroup utility
*/
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
const GLFWvidmode* desired);
@@ -959,13 +1051,11 @@ GLFWbool _glfwRefreshContextAttribs(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);
/*! @brief Frees the red, green and blue value arrays and clears the struct.
* @ingroup utility
/*! @ingroup utility
*/
void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
@@ -984,19 +1074,13 @@ _GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM);
*/
void _glfwFreeMonitor(_GLFWmonitor* monitor);
/*! @brief Returns an available joystick object with arrays and name allocated.
* @ingroup utility
/*! @ingroup utility
*/
_GLFWjoystick* _glfwAllocJoystick(const char* name,
const char* guid,
int axisCount,
int buttonCount,
int hatCount);
void _glfwFreeMonitors(_GLFWmonitor** monitors, int count);
/*! @brief Frees arrays and name and flags the joystick object as unused.
* @ingroup utility
*/
void _glfwFreeJoystick(_GLFWjoystick* js);
/*! @ingroup utility
*/
GLFWbool _glfwIsPrintable(int key);
/*! @ingroup utility
*/
@@ -1010,3 +1094,4 @@ void _glfwTerminateVulkan(void);
*/
const char* _glfwGetVulkanResultString(VkResult result);
#endif // _glfw3_internal_h_
+179 -268
View File
@@ -27,6 +27,9 @@
#include "internal.h"
#if defined(__linux__)
#include <linux/joystick.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/inotify.h>
@@ -37,220 +40,129 @@
#include <stdlib.h>
#include <string.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
//
#if defined(__linux__)
static GLFWbool openJoystickDevice(const char* path)
{
int jid, code;
char axisCount, buttonCount;
char name[256] = "";
char guid[33] = "";
char evBits[(EV_CNT + 7) / 8] = {0};
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;
int jid, fd, version;
_GLFWjoystickLinux* js;
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;
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
if (strcmp(_glfw.linux_js.js[jid].path, path) == 0)
return GLFW_FALSE;
}
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
if (linjs.fd == -1)
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (!_glfw.linux_js.js[jid].present)
break;
}
if (jid > GLFW_JOYSTICK_LAST)
return GLFW_FALSE;
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
ioctl(linjs.fd, EVIOCGID, &id) < 0)
fd = open(path, O_RDONLY | O_NONBLOCK);
if (fd == -1)
return GLFW_FALSE;
// Verify that the joystick driver version is at least 1.0
ioctl(fd, JSIOCGVERSION, &version);
if (version < 0x010000)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Linux: Failed to query input device: %s",
strerror(errno));
close(linjs.fd);
// It's an old 0.x interface (we don't support it)
close(fd);
return GLFW_FALSE;
}
// Ensure this device supports the events expected of a joystick
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
{
close(linjs.fd);
return GLFW_FALSE;
}
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0)
strncpy(name, "Unknown", sizeof(name));
// Generate a joystick GUID that matches the SDL 2.0.5+ one
if (id.vendor && id.product && id.version)
{
sprintf(guid, "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000",
id.bustype & 0xff, id.bustype >> 8,
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]);
}
js = _glfw.linux_js.js + jid;
js->present = GLFW_TRUE;
js->name = strdup(name);
js->path = strdup(path);
js->fd = fd;
for (code = BTN_MISC; code < KEY_CNT; code++)
{
if (!isBitSet(code, keyBits))
continue;
ioctl(fd, JSIOCGAXES, &axisCount);
js->axisCount = (int) axisCount;
js->axes = calloc(axisCount, sizeof(float));
linjs.keyMap[code - BTN_MISC] = buttonCount;
buttonCount++;
}
ioctl(fd, JSIOCGBUTTONS, &buttonCount);
js->buttonCount = (int) buttonCount;
js->buttons = calloc(buttonCount, 1);
for (code = 0; code < ABS_CNT; code++)
{
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);
_glfwInputJoystickChange(jid, GLFW_CONNECTED);
return GLFW_TRUE;
}
#endif // __linux__
#undef isBitSet
// Frees all resources associated with the specified joystick
// Polls for and processes events the specified joystick
//
static void closeJoystick(_GLFWjoystick* js)
static GLFWbool pollJoystickEvents(_GLFWjoystickLinux* js)
{
close(js->linjs.fd);
_glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
#if defined(__linux__)
_glfwPollJoystickEvents();
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
//
#if defined(__linux__)
static int compareJoysticks(const void* fp, const void* sp)
{
const _GLFWjoystick* fj = fp;
const _GLFWjoystick* sj = sp;
return strcmp(fj->linjs.path, sj->linjs.path);
const _GLFWjoystickLinux* fj = fp;
const _GLFWjoystickLinux* sj = sp;
return strcmp(fj->path, sj->path);
}
#endif // __linux__
//////////////////////////////////////////////////////////////////////////
@@ -261,24 +173,36 @@ static int compareJoysticks(const void* fp, const void* sp)
//
GLFWbool _glfwInitJoysticksLinux(void)
{
#if defined(__linux__)
DIR* dir;
int count = 0;
const char* dirname = "/dev/input";
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (_glfw.linjs.inotify > 0)
_glfw.linux_js.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (_glfw.linux_js.inotify == -1)
{
// HACK: Register for IN_ATTRIB to get notified when udev is done
// This works well in practice but the true way is libudev
_glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify,
dirname,
IN_CREATE | IN_ATTRIB | IN_DELETE);
_glfwInputError(GLFW_PLATFORM_ERROR,
"Linux: Failed to initialize inotify: %s",
strerror(errno));
return GLFW_FALSE;
}
// 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");
return GLFW_FALSE;
@@ -291,15 +215,13 @@ GLFWbool _glfwInitJoysticksLinux(void)
while ((entry = readdir(dir)))
{
char path[20];
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;
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
if (openJoystickDevice(path))
count++;
}
@@ -307,10 +229,17 @@ GLFWbool _glfwInitJoysticksLinux(void)
closedir(dir);
}
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;
}
@@ -318,65 +247,56 @@ GLFWbool _glfwInitJoysticksLinux(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 (js->present)
closeJoystick(js);
if (_glfw.linux_js.js[i].present)
{
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)
inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
if (_glfw.linux_js.watch > 0)
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;
char buffer[16384];
if (_glfw.linjs.inotify <= 0)
return;
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
const ssize_t size = read(_glfw.linux_js.inotify, buffer, sizeof(buffer));
while (size > offset)
{
regmatch_t match;
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
offset += sizeof(struct inotify_event) + e->len;
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)
if (regexec(&_glfw.linux_js.regex, e->name, 1, &match, 0) == 0)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
{
closeJoystick(_glfw.joysticks + jid);
break;
}
}
char path[20];
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
openJoystickDevice(path);
}
offset += sizeof(struct inotify_event) + e->len;
}
#endif
}
@@ -384,47 +304,38 @@ void _glfwDetectJoystickConnectionLinux(void)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
int _glfwPlatformJoystickPresent(int jid)
{
// Read all queued events (non-blocking)
for (;;)
{
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;
_GLFWjoystickLinux* js = _glfw.linux_js.js + jid;
return pollJoystickEvents(js);
}
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
View File
@@ -24,39 +24,45 @@
//
//========================================================================
#include <linux/input.h>
#include <linux/limits.h>
#ifndef _glfw3_linux_joystick_h_
#define _glfw3_linux_joystick_h_
#include <regex.h>
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWjoylistLinux linux_js
#define _GLFW_PLATFORM_MAPPING_NAME "Linux"
// Linux-specific joystick data
//
typedef struct _GLFWjoystickLinux
{
int fd;
char path[PATH_MAX];
int keyMap[KEY_CNT - BTN_MISC];
int absMap[ABS_CNT];
struct input_absinfo absInfo[ABS_CNT];
int hats[4][2];
GLFWbool present;
int fd;
float* axes;
int axisCount;
unsigned char* buttons;
int buttonCount;
char* name;
char* path;
} _GLFWjoystickLinux;
// Linux-specific joystick API data
//
typedef struct _GLFWlibraryLinux
typedef struct _GLFWjoylistLinux
{
int inotify;
int watch;
regex_t regex;
GLFWbool dropped;
} _GLFWlibraryLinux;
_GLFWjoystickLinux js[GLFW_JOYSTICK_LAST + 1];
#if defined(__linux__)
int inotify;
int watch;
regex_t regex;
#endif /*__linux__*/
} _GLFWjoylistLinux;
GLFWbool _glfwInitJoysticksLinux(void);
void _glfwTerminateJoysticksLinux(void);
void _glfwDetectJoystickConnectionLinux(void);
void _glfwPollJoystickEvents(void);
#endif // _glfw3_linux_joystick_h_
-241
View File
@@ -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";
-70
View File
@@ -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
View File
@@ -1,7 +1,7 @@
//========================================================================
// 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
// 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_9] = GLFW_KEY_9;
_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_EQUAL] = GLFW_KEY_EQUAL;
_glfw.mir.keycodes[KEY_Q] = GLFW_KEY_Q;
@@ -190,11 +189,18 @@ int _glfwPlatformInit(void)
createKeyTables();
if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE;
if (!_glfwInitJoysticksLinux())
return GLFW_FALSE;
_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));
_glfwInitEventQueueMir(_glfw.mir.eventQueue);
@@ -207,7 +213,6 @@ int _glfwPlatformInit(void)
return GLFW_FALSE;
}
_glfwPollMonitorsMir();
return GLFW_TRUE;
}
@@ -215,6 +220,7 @@ void _glfwPlatformTerminate(void)
{
_glfwTerminateEGL();
_glfwTerminateJoysticksLinux();
_glfwTerminateThreadLocalStoragePOSIX();
_glfwDeleteEventQueueMir(_glfw.mir.eventQueue);
@@ -231,7 +237,9 @@ const char* _glfwPlatformGetVersionString(void)
#else
" gettimeofday"
#endif
" evdev"
#if defined(__linux__)
" /dev/js"
#endif
#if defined(_GLFW_BUILD_DLL)
" shared"
#endif
+47 -70
View File
@@ -1,7 +1,7 @@
//========================================================================
// 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
// 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
//
void _glfwPollMonitorsMir(void)
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
{
int i;
MirDisplayConfig* displayConfig =
mir_connection_create_display_configuration(_glfw.mir.connection);
int i, found = 0;
_GLFWmonitor** monitors = NULL;
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);
MirOutputConnectionState state = mir_output_get_connection_state(output);
bool enabled = mir_output_is_enabled(output);
const MirDisplayOutput* out = displayConfig->outputs + i;
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);
int heightMM = mir_output_get_physical_height_mm(output);
int x = mir_output_get_position_x(output);
int y = mir_output_get_position_y(output);
int id = mir_output_get_id(output);
size_t currentMode = mir_output_get_current_mode_index(output);
const char* name = mir_output_type_name(mir_output_get_type(output));
found++;
monitors = realloc(monitors, sizeof(_GLFWmonitor*) * found);
monitors[i] = _glfwAllocMonitor("Unknown",
out->physical_width_mm,
out->physical_height_mm);
_GLFWmonitor* monitor = _glfwAllocMonitor(name,
widthMM,
heightMM);
monitor->mir.x = x;
monitor->mir.y = y;
monitor->mir.outputId = id;
monitor->mir.curMode = currentMode;
monitor->modes = _glfwPlatformGetVideoModes(monitor, &monitor->modeCount);
monitors[i]->mir.x = out->position_x;
monitors[i]->mir.y = out->position_y;
monitors[i]->mir.outputId = out->output_id;
monitors[i]->mir.curMode = out->current_mode;
_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;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
{
return first->mir.outputId == second->mir.outputId;
}
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
@@ -88,7 +86,7 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
*ypos = monitor->mir.y;
}
static void FillInRGBBitsFromPixelFormat(GLFWvidmode* mode, const MirPixelFormat pf)
void FillInRGBBitsFromPixelFormat(GLFWvidmode* mode, const MirPixelFormat pf)
{
switch (pf)
{
@@ -125,52 +123,30 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
{
int i;
GLFWvidmode* modes = NULL;
MirDisplayConfig* displayConfig =
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);
for (i = 0; i < numOutputs; i++)
for (i = 0; i < displayConfig->num_outputs; i++)
{
const MirOutput* output = mir_display_config_get_output(displayConfig, i);
int id = mir_output_get_id(output);
if (id != monitor->mir.outputId)
const MirDisplayOutput* out = displayConfig->outputs + i;
if (out->output_id != monitor->mir.outputId)
continue;
MirOutputConnectionState state = mir_output_get_connection_state(output);
bool enabled = mir_output_is_enabled(output);
modes = calloc(out->num_modes, sizeof(GLFWvidmode));
// We must have been disconnected
if (!enabled || state != mir_output_connection_state_connected)
for (*found = 0; *found < out->num_modes; (*found)++)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Monitor no longer connected");
return NULL;
}
modes[*found].width = out->modes[*found].horizontal_resolution;
modes[*found].height = out->modes[*found].vertical_resolution;
modes[*found].refreshRate = out->modes[*found].refresh_rate;
int numModes = mir_output_get_num_modes(output);
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);
FillInRGBBitsFromPixelFormat(&modes[*found], out->output_formats[*found]);
}
break;
}
mir_display_config_release(displayConfig);
mir_display_config_destroy(displayConfig);
return modes;
}
@@ -203,3 +179,4 @@ GLFWAPI int glfwGetMirMonitor(GLFWmonitor* handle)
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return monitor->mir.outputId;
}
+20 -17
View File
@@ -1,7 +1,7 @@
//========================================================================
// 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
// 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 <pthread.h>
#include <dlfcn.h>
#include <mir_toolkit/mir_client_library.h>
typedef VkFlags VkMirWindowCreateFlagsKHR;
typedef VkFlags VkMirSurfaceCreateFlagsKHR;
typedef struct VkMirWindowCreateInfoKHR
typedef struct VkMirSurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkMirWindowCreateFlagsKHR flags;
VkMirSurfaceCreateFlagsKHR flags;
MirConnection* connection;
MirWindow* mirWindow;
} VkMirWindowCreateInfoKHR;
MirSurface* mirSurface;
} 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*);
#include "posix_thread.h"
#include "posix_tls.h"
#include "posix_time.h"
#include "linux_joystick.h"
#include "xkb_unicode.h"
#include "egl_context.h"
#include "osmesa_context.h"
#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_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_PLATFORM_WINDOW_STATE _GLFWwindowMir mir
@@ -78,10 +80,10 @@ typedef struct EventQueue
//
typedef struct _GLFWwindowMir
{
MirWindow* window;
MirSurface* surface;
int width;
int height;
MirEGLNativeWindowType nativeWindow;
MirEGLNativeWindowType window;
_GLFWcursor* currentCursor;
} _GLFWwindowMir;
@@ -103,16 +105,18 @@ typedef struct _GLFWlibraryMir
{
MirConnection* connection;
MirEGLNativeDisplayType display;
MirCursorConfiguration* defaultConf;
MirCursorConfiguration* disabledConf;
EventQueue* eventQueue;
short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1];
short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1];
pthread_mutex_t eventMutex;
pthread_cond_t eventCond;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
_GLFWwindow* disabledCursorWindow;
} _GLFWlibraryMir;
@@ -123,11 +127,10 @@ typedef struct _GLFWcursorMir
{
MirCursorConfiguration* conf;
MirBufferStream* customCursor;
char const* cursorName; // only needed for system cursors
} _GLFWcursorMir;
extern void _glfwPollMonitorsMir(void);
extern void _glfwInitEventQueueMir(EventQueue* queue);
extern void _glfwDeleteEventQueueMir(EventQueue* queue);
#endif // _glfw3_mir_platform_h_
+137 -148
View File
@@ -1,7 +1,7 @@
//========================================================================
// 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
// warranty. In no event will the authors be held liable for any damages
@@ -89,6 +89,9 @@ static EventNode* dequeueEvent(EventQueue* queue)
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)
{
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);
}
static GLFWbool createWindow(_GLFWwindow* window)
static GLFWbool createSurface(_GLFWwindow* window)
{
MirWindowSpec* spec;
MirSurfaceSpec* spec;
MirBufferUsage buffer_usage = mir_buffer_usage_hardware;
MirPixelFormat pixel_format = findValidPixelFormat();
@@ -298,39 +301,40 @@ static GLFWbool createWindow(_GLFWwindow* window)
return GLFW_FALSE;
}
spec = mir_create_normal_window_spec(_glfw.mir.connection,
window->mir.width,
window->mir.height);
spec = mir_connection_create_spec_for_normal_surface(_glfw.mir.connection,
window->mir.width,
window->mir.height,
pixel_format);
mir_window_spec_set_pixel_format(spec, pixel_format);
mir_window_spec_set_buffer_usage(spec, buffer_usage);
mir_surface_spec_set_buffer_usage(spec, buffer_usage);
mir_surface_spec_set_name(spec, "MirSurface");
window->mir.window = mir_create_window_sync(spec);
mir_window_spec_release(spec);
window->mir.surface = mir_surface_create_sync(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,
"Mir: Unable to create window: %s",
mir_window_get_error_message(window->mir.window));
"Mir: Unable to create surface: %s",
mir_surface_get_error_message(window->mir.surface));
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;
}
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);
mir_window_spec_set_pointer_confinement(spec, state);
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_pointer_confinement(spec, state);
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);
}
//////////////////////////////////////////////////////////////////////////
@@ -377,12 +381,12 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
GLFWvidmode 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)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Requested window size too large: %ix%i",
"Mir: Requested surface size too large: %ix%i",
wndconfig->width, wndconfig->height);
return GLFW_FALSE;
@@ -393,29 +397,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
window->mir.height = wndconfig->height;
window->mir.currentCursor = NULL;
if (!createWindow(window))
if (!createSurface(window))
return GLFW_FALSE;
window->mir.nativeWindow = mir_buffer_stream_get_egl_native_window(
mir_window_get_buffer_stream(window->mir.window));
window->mir.window = mir_buffer_stream_get_egl_native_window(
mir_surface_get_buffer_stream(window->mir.surface));
if (ctxconfig->client != GLFW_NO_API)
{
if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||
ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{
if (!_glfwInitEGL())
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 (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
}
return GLFW_TRUE;
@@ -426,10 +419,10 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
if (_glfw.mir.disabledCursorWindow == window)
_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);
window->mir.window= NULL;
mir_surface_release_sync(window->mir.surface);
window->mir.surface = NULL;
}
if (window->context.destroy)
@@ -438,12 +431,14 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
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);
mir_window_spec_set_name(spec, title);
mir_window_apply_spec(window->mir.window, spec);
mir_window_spec_release(spec);
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_name(spec, e_title);
mir_surface_apply_spec(window->mir.surface, spec);
mir_surface_spec_release(spec);
}
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
@@ -455,30 +450,22 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
MirWindowSpec* spec;
MirSurfaceSpec* spec;
spec = mir_create_window_spec(_glfw.mir.connection);
mir_window_spec_set_width (spec, width);
mir_window_spec_set_height(spec, height);
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_width (spec, width);
mir_surface_spec_set_height(spec, height);
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 _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight)
{
MirWindowSpec* spec;
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);
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
@@ -517,63 +504,57 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
MirWindowSpec* spec;
MirSurfaceSpec* spec;
spec = mir_create_window_spec(_glfw.mir.connection);
mir_window_spec_set_state(spec, mir_window_state_minimized);
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_state(spec, mir_surface_state_minimized);
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 _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
MirWindowSpec* spec;
MirSurfaceSpec* spec;
spec = mir_create_window_spec(_glfw.mir.connection);
mir_window_spec_set_state(spec, mir_window_state_restored);
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_state(spec, mir_surface_state_restored);
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 _glfwPlatformMaximizeWindow(_GLFWwindow* window)
{
MirWindowSpec* spec;
MirSurfaceSpec* spec;
spec = mir_create_window_spec(_glfw.mir.connection);
mir_window_spec_set_state(spec, mir_window_state_maximized);
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_state(spec, mir_surface_state_maximized);
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 _glfwPlatformHideWindow(_GLFWwindow* window)
{
MirWindowSpec* spec;
MirSurfaceSpec* spec;
spec = mir_create_window_spec(_glfw.mir.connection);
mir_window_spec_set_state(spec, mir_window_state_hidden);
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_state(spec, mir_surface_state_hidden);
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 _glfwPlatformShowWindow(_GLFWwindow* window)
{
MirWindowSpec* spec;
MirSurfaceSpec* spec;
spec = mir_create_window_spec(_glfw.mir.connection);
mir_window_spec_set_state(spec, mir_window_state_restored);
spec = mir_connection_create_spec_for_changes(_glfw.mir.connection);
mir_surface_spec_set_state(spec, mir_surface_state_restored);
mir_window_apply_spec(window->mir.window, spec);
mir_window_spec_release(spec);
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
mir_surface_apply_spec(window->mir.surface, spec);
mir_surface_spec_release(spec);
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
@@ -594,7 +575,7 @@ void _glfwPlatformSetWindowMonitor(_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)
@@ -606,12 +587,12 @@ int _glfwPlatformWindowIconified(_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)
{
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)
@@ -647,7 +628,7 @@ void _glfwPlatformWaitEvents(void)
{
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_mutex_unlock(&_glfw.mir.eventMutex);
@@ -690,40 +671,54 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int xhot, int yhot)
{
MirBufferStream* stream;
MirPixelFormat pixel_format = findValidPixelFormat();
int i_w = image->width;
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,
i_w, i_h,
mir_pixel_format_argb_8888,
pixel_format,
mir_buffer_usage_software);
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;
mir_buffer_stream_get_graphics_region(stream, &region);
unsigned char* pixels = image->pixels;
char* dest = region.vaddr;
int i;
// FIXME Figure this out based on the current_pf
bytes_per_pixel = 4;
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];
*dest++ = (char)(pixels[2] * alpha / 255);
*dest++ = (char)(pixels[1] * alpha / 255);
*dest++ = (char)(pixels[0] * alpha / 255);
*dest++ = (char)alpha;
memcpy(dest, pixels, bytes_per_row);
dest += r_stride;
pixels += r_stride;
}
mir_buffer_stream_swap_buffers_sync(stream);
cursor->mir.customCursor = stream;
return GLFW_TRUE;
}
static const char* getSystemCursorName(int shape)
const char* getSystemCursorName(int shape)
{
switch (shape)
{
@@ -746,11 +741,17 @@ static const char* getSystemCursorName(int shape)
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
cursor->mir.conf = NULL;
cursor->mir.customCursor = NULL;
cursor->mir.cursorName = getSystemCursorName(shape);
const char* cursor_name = 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)
@@ -761,32 +762,21 @@ void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
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)
{
if (cursor)
if (cursor && cursor->mir.conf)
{
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);
}
else if (cursor->mir.conf)
{
mir_window_configure_cursor(window->mir.window, cursor->mir.conf);
mir_buffer_stream_swap_buffers_sync(cursor->mir.customCursor);
}
}
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)
{
_glfw.mir.disabledCursorWindow = window;
setWindowConfinement(window, mir_pointer_confined_to_window);
setCursorNameForWindow(window->mir.window, mir_disabled_cursor_name);
setSurfaceConfinement(window, mir_pointer_confined_to_surface);
mir_wait_for(mir_surface_configure_cursor(window->mir.surface, _glfw.mir.disabledConf));
}
else
{
@@ -816,7 +806,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
if (_glfw.mir.disabledCursorWindow == window)
{
_glfw.mir.disabledCursorWindow = NULL;
setWindowConfinement(window, mir_pointer_unconfined);
setSurfaceConfinement(window, mir_pointer_unconfined);
}
if (window->cursorMode == GLFW_CURSOR_NORMAL)
@@ -825,12 +815,12 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
}
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,
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
@@ -869,8 +859,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
vkGetPhysicalDeviceMirPresentationSupportKHR =
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
if (!vkGetPhysicalDeviceMirPresentationSupportKHR)
@@ -891,12 +880,12 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
VkSurfaceKHR* surface)
{
VkResult err;
VkMirWindowCreateInfoKHR sci;
PFN_vkCreateMirWindowKHR vkCreateMirWindowKHR;
VkMirSurfaceCreateInfoKHR sci;
PFN_vkCreateMirSurfaceKHR vkCreateMirSurfaceKHR;
vkCreateMirWindowKHR = (PFN_vkCreateMirWindowKHR)
vkGetInstanceProcAddr(instance, "vkCreateMirWindowKHR");
if (!vkCreateMirWindowKHR)
vkCreateMirSurfaceKHR = (PFN_vkCreateMirSurfaceKHR)
vkGetInstanceProcAddr(instance, "vkCreateMirSurfaceKHR");
if (!vkCreateMirSurfaceKHR)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Mir: Vulkan instance missing VK_KHR_mir_surface extension");
@@ -906,9 +895,9 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
memset(&sci, 0, sizeof(sci));
sci.sType = VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR;
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)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@@ -930,10 +919,10 @@ GLFWAPI MirConnection* glfwGetMirDisplay(void)
return _glfw.mir.connection;
}
GLFWAPI MirWindow* glfwGetMirWindow(GLFWwindow* handle)
GLFWAPI MirSurface* glfwGetMirWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return window->mir.window;
return window->mir.surface;
}
+74 -36
View File
@@ -86,49 +86,83 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
void _glfwInputMonitorChange(void)
{
if (action == GLFW_CONNECTED)
{
_glfw.monitorCount++;
_glfw.monitors =
realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount);
int i, j, monitorCount = _glfw.monitorCount;
_GLFWmonitor** monitors = _glfw.monitors;
if (placement == _GLFW_INSERT_FIRST)
{
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;
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
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--;
memmove(_glfw.monitors + i,
_glfw.monitors + i + 1,
(_glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
_glfwFreeMonitor(_glfw.monitors[i]);
_glfw.monitors[i] = monitors[j];
break;
}
}
}
if (_glfw.callbacks.monitor)
_glfw.callbacks.monitor((GLFWmonitor*) monitor, action);
// Find and report disconnected monitors (not in the new list)
if (action == GLFW_DISCONNECTED)
_glfwFreeMonitor(monitor);
for (i = 0; i < monitorCount; i++)
{
_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;
}
@@ -180,6 +214,16 @@ void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
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* desired)
{
@@ -262,7 +306,6 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)
GLFWAPI GLFWmonitor** glfwGetMonitors(int* count)
{
assert(count != NULL);
*count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@@ -363,10 +406,6 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
int i;
unsigned short values[256];
GLFWgammaramp ramp;
assert(handle != NULL);
assert(gamma == gamma);
assert(gamma >= 0.f);
assert(gamma <= FLT_MAX);
_GLFW_REQUIRE_INIT();
@@ -418,7 +457,6 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
assert(ramp != NULL);
assert(ramp->size > 0);
assert(ramp->red != NULL);
assert(ramp->green != NULL);
assert(ramp->blue != NULL);
+4
View File
@@ -24,6 +24,9 @@
//
//========================================================================
#ifndef _glfw3_nsgl_context_h_
#define _glfw3_nsgl_context_h_
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
@@ -54,3 +57,4 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextNSGL(_GLFWwindow* window);
#endif // _glfw3_nsgl_context_h_
+29 -49
View File
@@ -34,7 +34,7 @@ static void makeContextCurrentNSGL(_GLFWwindow* window)
else
[NSOpenGLContext clearCurrentContext];
_glfwPlatformSetTls(&_glfw.contextSlot, window);
_glfwPlatformSetCurrentContext(window);
}
static void swapBuffersNSGL(_GLFWwindow* window)
@@ -45,7 +45,7 @@ static void swapBuffersNSGL(_GLFWwindow* window)
static void swapIntervalNSGL(int interval)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
GLint sync = interval;
[window->context.nsgl.object setValues:&sync
@@ -119,6 +119,8 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
unsigned int attributeCount = 0;
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
_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
// 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
// a hard constraint, so ignore and continue
#define ADD_ATTR(x) { attributes[attributeCount++] = x; }
#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
// are not a hard constraint, so ignore and continue
// Arbitrary array size here
NSOpenGLPixelFormatAttribute attributes[40];
#define addAttrib(a) \
{ \
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*/
}
ADD_ATTR(NSOpenGLPFAAccelerated);
ADD_ATTR(NSOpenGLPFAClosestPolicy);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
if (ctxconfig->major >= 4)
{
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
}
else
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
if (ctxconfig->major >= 3)
{
setAttrib(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
}
if (ctxconfig->major <= 2)
{
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
@@ -207,7 +187,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
fbconfig->accumBlueBits +
fbconfig->accumAlphaBits;
setAttrib(NSOpenGLPFAAccumSize, accumBits);
ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits);
}
}
@@ -225,17 +205,17 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
else if (colorBits < 15)
colorBits = 15;
setAttrib(NSOpenGLPFAColorSize, colorBits);
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
}
if (fbconfig->alphaBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
if (fbconfig->depthBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFADepthSize, fbconfig->depthBits);
ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits);
if (fbconfig->stencilBits != GLFW_DONT_CARE)
setAttrib(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
if (fbconfig->stereo)
{
@@ -244,36 +224,36 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
"NSGL: Stereo rendering is deprecated");
return GLFW_FALSE;
#else
addAttrib(NSOpenGLPFAStereo);
ADD_ATTR(NSOpenGLPFAStereo);
#endif
}
if (fbconfig->doublebuffer)
addAttrib(NSOpenGLPFADoubleBuffer);
ADD_ATTR(NSOpenGLPFADoubleBuffer);
if (fbconfig->samples != GLFW_DONT_CARE)
{
if (fbconfig->samples == 0)
{
setAttrib(NSOpenGLPFASampleBuffers, 0);
ADD_ATTR2(NSOpenGLPFASampleBuffers, 0);
}
else
{
setAttrib(NSOpenGLPFASampleBuffers, 1);
setAttrib(NSOpenGLPFASamples, fbconfig->samples);
ADD_ATTR2(NSOpenGLPFASampleBuffers, 1);
ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
}
}
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
// framebuffer, so there's no need (and no way) to request it
addAttrib(0);
ADD_ATTR(0);
#undef addAttrib
#undef setAttrib
#undef ADD_ATTR
#undef ADD_ATTR2
window->context.nsgl.pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
if (window->context.nsgl.pixelFormat == nil)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
-31
View File
@@ -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
View File
@@ -36,26 +36,25 @@ static void makeContextCurrentOSMesa(_GLFWwindow* window)
{
if (window)
{
int width, height;
_glfwPlatformGetFramebufferSize(window, &width, &height);
// Check to see if we need to allocate a new buffer
if ((window->context.osmesa.buffer == NULL) ||
(width != window->context.osmesa.width) ||
(height != window->context.osmesa.height))
(window->osmesa.width != window->context.osmesa.width) ||
(window->osmesa.height != window->context.osmesa.height))
{
free(window->context.osmesa.buffer);
// Allocate the new buffer (width * height * 8-bit RGBA)
window->context.osmesa.buffer = calloc(4, width * height);
window->context.osmesa.width = width;
window->context.osmesa.height = height;
window->context.osmesa.buffer =
calloc(4, window->osmesa.width * window->osmesa.height);
window->context.osmesa.width = window->osmesa.width;
window->context.osmesa.height = window->osmesa.height;
}
if (!OSMesaMakeCurrent(window->context.osmesa.handle,
window->context.osmesa.buffer,
GL_UNSIGNED_BYTE,
width, height))
window->context.osmesa.buffer,
GL_UNSIGNED_BYTE,
window->osmesa.width, window->osmesa.height))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"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)
@@ -113,9 +112,7 @@ GLFWbool _glfwInitOSMesa(void)
int i;
const char* sonames[] =
{
#if defined(_GLFW_OSMESA_LIBRARY)
_GLFW_OSMESA_LIBRARY,
#elif defined(_WIN32)
#if defined(_WIN32)
"libOSMesa.dll",
"OSMesa.dll",
#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++] = a; \
attribs[index++] = v; \
attribs[index++] = attribName; \
attribs[index++] = attribValue; \
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
}
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
+10 -6
View File
@@ -25,6 +25,9 @@
//
//========================================================================
#ifndef _glfw3_osmesa_context_h_
#define _glfw3_osmesa_context_h_
#define OSMESA_RGBA 0x1908
#define OSMESA_FORMAT 0x22
#define OSMESA_DEPTH_BITS 0x30
@@ -54,18 +57,18 @@ typedef GLFWglproc (GLAPIENTRY * PFN_OSMesaGetProcAddress)(const char*);
#define OSMesaGetDepthBuffer _glfw.osmesa.GetDepthBuffer
#define OSMesaGetProcAddress _glfw.osmesa.GetProcAddress
#define _GLFW_OSMESA_CONTEXT_STATE _GLFWcontextOSMesa osmesa
#define _GLFW_OSMESA_LIBRARY_CONTEXT_STATE _GLFWlibraryOSMesa osmesa
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextOSMesa osmesa
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryOSMesa osmesa
// OSMesa-specific per-context data
//
typedef struct _GLFWcontextOSMesa
{
OSMesaContext handle;
int width;
int height;
void* buffer;
OSMesaContext handle;
int width;
int height;
void* buffer;
} _GLFWcontextOSMesa;
@@ -92,3 +95,4 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
#endif // _glfw3_osmesa_context_h_
+6 -2
View File
@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.3 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
@@ -34,6 +34,9 @@
int _glfwPlatformInit(void)
{
if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE;
_glfwInitTimerPOSIX();
return GLFW_TRUE;
}
@@ -41,10 +44,11 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void)
{
_glfwTerminateOSMesa();
_glfwTerminateThreadLocalStoragePOSIX();
}
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER " null OSMesa";
return _GLFW_VERSION_NUMBER " none OSMesa";
}
+13 -1
View File
@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.3 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
@@ -32,6 +32,18 @@
////// 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)
{
}
+12 -9
View File
@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.3 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// 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>
#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_CURSOR_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_LIBRARY_CONTEXT_STATE
#include "osmesa_context.h"
#include "posix_time.h"
#include "posix_thread.h"
#include "null_joystick.h"
#include "posix_tls.h"
#if defined(_GLFW_WIN32)
#define _glfw_dlopen(name) LoadLibraryA(name)
@@ -52,11 +53,13 @@
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#endif
// Null-specific per-window data
// OSMesa-specific per-window data
//
typedef struct _GLFWwindowNull
typedef struct _GLFWwindowOSMesa
{
int width;
int height;
} _GLFWwindowNull;
} _GLFWwindowOSMesa;
#endif // _glfw3_osmesa_platform_h_
+40 -18
View File
@@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.3 - www.glfw.org
// GLFW 3.3 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
@@ -31,8 +31,8 @@
static int createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig)
{
window->null.width = wndconfig->width;
window->null.height = wndconfig->height;
window->osmesa.width = wndconfig->width;
window->osmesa.height = wndconfig->height;
return GLFW_TRUE;
}
@@ -52,8 +52,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (ctxconfig->client != GLFW_NO_API)
{
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API ||
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{
if (!_glfwInitOSMesa())
return GLFW_FALSE;
@@ -62,7 +61,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available");
_glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: EGL not available");
return GLFW_FALSE;
}
}
@@ -104,15 +103,15 @@ void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->null.width;
*width = window->osmesa.width;
if (height)
*height = window->null.height;
*height = window->osmesa.height;
}
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
window->null.width = width;
window->null.height = height;
window->osmesa.width = width;
window->osmesa.height = height;
}
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
@@ -128,15 +127,19 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d)
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->null.width;
*width = window->osmesa.width;
if (height)
*height = window->null.height;
*height = window->osmesa.height;
}
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom)
{
if (right)
*right = window->osmesa.width;
if (bottom)
*top = window->osmesa.height;
}
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
@@ -172,11 +175,6 @@ void _glfwPlatformShowWindow(_GLFWwindow* window)
{
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{
}
@@ -232,6 +230,10 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
}
void _glfwPlatformApplyCursorMode(_GLFWwindow* window)
{
}
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
@@ -261,7 +263,7 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
return NULL;
}
const char* _glfwPlatformGetScancodeName(int scancode)
const char* _glfwPlatformGetKeyName(int key, int scancode)
{
return "";
}
@@ -271,6 +273,26 @@ int _glfwPlatformGetKeyScancode(int key)
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)
{
}
-103
View File
@@ -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
View File
@@ -44,14 +44,14 @@ void _glfwInitTimerPOSIX(void)
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
{
_glfw.timer.posix.monotonic = GLFW_TRUE;
_glfw.timer.posix.frequency = 1000000000;
_glfw.posix_time.monotonic = GLFW_TRUE;
_glfw.posix_time.frequency = 1000000000;
}
else
#endif
{
_glfw.timer.posix.monotonic = GLFW_FALSE;
_glfw.timer.posix.frequency = 1000000;
_glfw.posix_time.monotonic = GLFW_FALSE;
_glfw.posix_time.frequency = 1000000;
}
}
@@ -63,7 +63,7 @@ void _glfwInitTimerPOSIX(void)
uint64_t _glfwPlatformGetTimerValue(void)
{
#if defined(CLOCK_MONOTONIC)
if (_glfw.timer.posix.monotonic)
if (_glfw.posix_time.monotonic)
{
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
@@ -80,6 +80,6 @@ uint64_t _glfwPlatformGetTimerValue(void)
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.posix.frequency;
return _glfw.posix_time.frequency;
}
+7 -3
View File
@@ -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>
// POSIX-specific global timer data
//
typedef struct _GLFWtimerPOSIX
typedef struct _GLFWtimePOSIX
{
GLFWbool monotonic;
uint64_t frequency;
} _GLFWtimerPOSIX;
} _GLFWtimePOSIX;
void _glfwInitTimerPOSIX(void);
#endif // _glfw3_posix_time_h_
+30 -4
View File
@@ -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>
//
// This software is provided 'as-is', without any express or implied
@@ -27,16 +28,41 @@
#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 //////
//////////////////////////////////////////////////////////////////////////
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);
}
+9 -11
View File
@@ -25,27 +25,25 @@
//
//========================================================================
#ifndef _glfw3_posix_tls_h_
#define _glfw3_posix_tls_h_
#include <pthread.h>
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsPOSIX posix
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexPOSIX posix
#define _GLFW_PLATFORM_LIBRARY_TLS_STATE _GLFWtlsPOSIX posix_tls
// POSIX-specific thread local storage data
// POSIX-specific global TLS data
//
typedef struct _GLFWtlsPOSIX
{
GLFWbool allocated;
pthread_key_t key;
pthread_key_t context;
} _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
View File
@@ -49,12 +49,11 @@ GLFWbool _glfwInitVulkan(int mode)
return GLFW_TRUE;
#if !defined(_GLFW_VULKAN_STATIC)
#if defined(_GLFW_VULKAN_LIBRARY)
_glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY);
#elif defined(_GLFW_WIN32)
#if defined(_GLFW_WIN32)
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
#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
_glfw.vk.handle = _glfw_dlopen("libvulkan.so.1");
#endif
@@ -70,8 +69,16 @@ GLFWbool _glfwInitVulkan(int mode)
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
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,
"Vulkan: Loader does not export vkGetInstanceProcAddr");
#endif
_glfwTerminateVulkan();
return GLFW_FALSE;
@@ -92,13 +99,9 @@ GLFWbool _glfwInitVulkan(int mode)
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
if (err)
{
// NOTE: This happens on systems with a loader but without any Vulkan ICD
if (mode == _GLFW_REQUIRE_LOADER)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Failed to query instance extension count: %s",
_glfwGetVulkanResultString(err));
}
_glfwInputError(GLFW_PLATFORM_ERROR,
"Vulkan: Failed to query instance extension count: %s",
_glfwGetVulkanResultString(err));
_glfwTerminateVulkan();
return GLFW_FALSE;
@@ -109,7 +112,7 @@ GLFWbool _glfwInitVulkan(int mode)
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
if (err)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
_glfwInputError(GLFW_PLATFORM_ERROR,
"Vulkan: Failed to query instance extensions: %s",
_glfwGetVulkanResultString(err));
@@ -227,8 +230,6 @@ GLFWAPI int glfwVulkanSupported(void)
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
{
assert(count != NULL);
*count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@@ -247,7 +248,6 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
const char* procname)
{
GLFWvkproc proc;
assert(procname != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@@ -273,9 +273,6 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
assert(instance != VK_NULL_HANDLE);
assert(device != VK_NULL_HANDLE);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
@@ -299,7 +296,6 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
VkSurfaceKHR* surface)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(instance != VK_NULL_HANDLE);
assert(window != NULL);
assert(surface != NULL);
+62 -90
View File
@@ -44,8 +44,9 @@ static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib
pixelFormat,
0, 1, &attrib, &value))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attribute");
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attribute %i",
attrib);
return 0;
}
@@ -54,9 +55,7 @@ static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib
// Return a list of available and usable framebuffer configs
//
static int choosePixelFormat(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* desired)
{
_GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest;
@@ -129,25 +128,11 @@ static int choosePixelFormat(_GLFWwindow* window,
if (_glfw.wgl.ARB_multisample)
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 ||
_glfw.wgl.EXT_framebuffer_sRGB)
{
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;
}
}
if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
u->sRGB = GLFW_TRUE;
}
}
else
@@ -213,7 +198,7 @@ static int choosePixelFormat(_GLFWwindow* window,
return 0;
}
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
if (!closest)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
@@ -233,15 +218,15 @@ static int choosePixelFormat(_GLFWwindow* window,
//
static GLFWbool isCompositionEnabled(void)
{
if (_glfw.win32.dwmapi.instance)
{
BOOL enabled;
BOOL enabled;
if (DwmIsCompositionEnabled(&enabled) == S_OK)
return enabled;
}
if (!_glfw_DwmIsCompositionEnabled)
return FALSE;
return FALSE;
if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK)
return FALSE;
return enabled;
}
static void makeContextCurrentWGL(_GLFWwindow* window)
@@ -249,23 +234,23 @@ static void makeContextCurrentWGL(_GLFWwindow* window)
if (window)
{
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
_glfwPlatformSetTls(&_glfw.contextSlot, window);
_glfwPlatformSetCurrentContext(window);
else
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to make context current");
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to make context current");
_glfwPlatformSetCurrentContext(NULL);
}
}
else
{
if (!wglMakeCurrent(NULL, NULL))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to clear current context");
_glfwInputError(GLFW_PLATFORM_ERROR,
"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);
while (count--)
DwmFlush();
_glfw_DwmFlush();
}
SwapBuffers(window->context.wgl.dc);
@@ -284,7 +269,7 @@ static void swapBuffersWGL(_GLFWwindow* window)
static void swapIntervalWGL(int interval)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
window->context.wgl.interval = interval;
@@ -368,24 +353,25 @@ static void loadWGLExtensions(void)
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to set pixel format for dummy context");
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to set pixel format for dummy context");
return;
}
rc = wglCreateContext(dc);
if (!rc)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to create dummy context");
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to create dummy context");
return;
}
if (!wglMakeCurrent(dc, rc))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to make dummy context current");
wglDeleteContext(rc);
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to make dummy context current");
return;
}
@@ -418,12 +404,8 @@ static void loadWGLExtensions(void)
extensionSupportedWGL("WGL_EXT_create_context_es2_profile");
_glfw.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 =
extensionSupportedWGL("WGL_EXT_swap_control");
_glfw.wgl.EXT_colorspace =
extensionSupportedWGL("WGL_EXT_colorspace");
_glfw.wgl.ARB_pixel_format =
extensionSupportedWGL("WGL_ARB_pixel_format");
_glfw.wgl.ARB_context_flush_control =
@@ -448,8 +430,7 @@ GLFWbool _glfwInitWGL(void)
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
if (!_glfw.wgl.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to load opengl32.dll");
_glfwInputError(GLFW_PLATFORM_ERROR, "WGL: Failed to load opengl32.dll");
return GLFW_FALSE;
}
@@ -477,11 +458,11 @@ void _glfwTerminateWGL(void)
FreeLibrary(_glfw.wgl.instance);
}
#define setAttrib(a, v) \
#define setWGLattrib(attribName, attribValue) \
{ \
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
attribs[index++] = attribName; \
attribs[index++] = attribValue; \
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
}
// Create the OpenGL or OpenGL ES context
@@ -509,22 +490,22 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
return GLFW_FALSE;
}
pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig);
pixelFormat = choosePixelFormat(window, fbconfig);
if (!pixelFormat)
return GLFW_FALSE;
if (!DescribePixelFormat(window->context.wgl.dc,
pixelFormat, sizeof(pfd), &pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve PFD for selected pixel format");
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve PFD for selected pixel format");
return GLFW_FALSE;
}
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to set selected pixel format");
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to set selected pixel format");
return GLFW_FALSE;
}
@@ -581,6 +562,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
if (ctxconfig->debug)
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
if (ctxconfig->noerror)
flags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;
if (ctxconfig->robustness)
{
@@ -588,13 +571,13 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
WGL_NO_RESET_NOTIFICATION_ARB);
setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
WGL_NO_RESET_NOTIFICATION_ARB);
}
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
WGL_LOSE_CONTEXT_ON_RESET_ARB);
setWGLattrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
WGL_LOSE_CONTEXT_ON_RESET_ARB);
}
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
@@ -607,39 +590,33 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
}
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
setWGLattrib(WGL_CONTEXT_RELEASE_BEHAVIOR_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
// explicitly requesting version 1.0 does not always return the
// highest version supported by the driver
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
setWGLattrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
setWGLattrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
}
if (flags)
setAttrib(WGL_CONTEXT_FLAGS_ARB, flags);
setWGLattrib(WGL_CONTEXT_FLAGS_ARB, flags);
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 =
_glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,
@@ -670,11 +647,6 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"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
{
if (ctxconfig->client == GLFW_OPENGL_API)
@@ -697,8 +669,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
if (!window->context.wgl.handle)
{
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL context");
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL context");
return GLFW_FALSE;
}
@@ -706,8 +678,8 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
{
if (!wglShareLists(share, window->context.wgl.handle))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to enable sharing with specified OpenGL context");
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to enable sharing with specified OpenGL context");
return GLFW_FALSE;
}
}
@@ -723,7 +695,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
return GLFW_TRUE;
}
#undef setAttrib
#undef setWGLattrib
//////////////////////////////////////////////////////////////////////////
+5 -6
View File
@@ -25,6 +25,10 @@
//
//========================================================================
#ifndef _glfw3_wgl_context_h_
#define _glfw3_wgl_context_h_
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
@@ -68,13 +72,9 @@
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#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_PROFILE_ARB 0x2096
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
@@ -135,7 +135,6 @@ typedef struct _GLFWlibraryWGL
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool EXT_swap_control;
GLFWbool EXT_colorspace;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
@@ -144,7 +143,6 @@ typedef struct _GLFWlibraryWGL
GLFWbool ARB_create_context_profile;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
} _GLFWlibraryWGL;
@@ -156,3 +154,4 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
#endif // _glfw3_wgl_context_h_
+28 -118
View File
@@ -30,10 +30,8 @@
#include <stdlib.h>
#include <malloc.h>
static const GUID _glfw_GUID_DEVINTERFACE_HID =
{0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
#define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID
#include <initguid.h>
DEFINE_GUID(GUID_DEVINTERFACE_HID,0x4d1e55b2,0xf16f,0x11cf,0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30);
#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");
if (!_glfw.win32.winmm.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to load winmm.dll");
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to load winmm.dll");
return GLFW_FALSE;
}
_glfw.win32.winmm.GetTime = (PFN_timeGetTime)
_glfw.win32.winmm.timeGetTime = (PFN_timeGetTime)
GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime");
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
if (!_glfw.win32.user32.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to load user32.dll");
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to load user32.dll");
return GLFW_FALSE;
}
@@ -93,7 +89,7 @@ static GLFWbool loadLibraries(void)
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
if (_glfw.win32.dinput8.instance)
{
_glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
_glfw.win32.dinput8.DirectInput8Create = (PFN_DirectInput8Create)
GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create");
}
@@ -114,9 +110,9 @@ static GLFWbool loadLibraries(void)
_glfw.win32.xinput.instance = LoadLibraryA(names[i]);
if (_glfw.win32.xinput.instance)
{
_glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
_glfw.win32.xinput.XInputGetCapabilities = (PFN_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");
break;
@@ -127,9 +123,9 @@ static GLFWbool loadLibraries(void)
_glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
if (_glfw.win32.dwmapi.instance)
{
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
_glfw.win32.dwmapi.DwmIsCompositionEnabled = (PFN_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");
}
@@ -311,16 +307,16 @@ static HWND createHelperWindow(void)
MSG msg;
HWND window = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
_GLFW_WNDCLASSNAME,
L"GLFW message window",
L"GLFW helper window",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0, 1, 1,
NULL, NULL,
HWND_MESSAGE, NULL,
GetModuleHandleW(NULL),
NULL);
if (!window)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to create helper window");
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to create helper window");
return NULL;
}
@@ -360,22 +356,16 @@ static HWND createHelperWindow(void)
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
{
WCHAR* target;
int count;
int length;
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
if (!count)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8");
length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
if (!length)
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);
return NULL;
}
@@ -388,22 +378,16 @@ WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
{
char* target;
int size;
int length;
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
if (!size)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
length = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
if (!length)
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);
return NULL;
}
@@ -411,81 +395,6 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
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 //////
@@ -493,6 +402,9 @@ void _glfwUpdateKeyNamesWin32(void)
int _glfwPlatformInit(void)
{
if (!_glfwInitThreadLocalStorageWin32())
return GLFW_FALSE;
// To make SetForegroundWindow work as we want, we need to fiddle
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
// as possible in the hope of still being the foreground process)
@@ -505,7 +417,6 @@ int _glfwPlatformInit(void)
return GLFW_FALSE;
createKeyTables();
_glfwUpdateKeyNamesWin32();
if (_glfw_SetProcessDpiAwareness)
_glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
@@ -522,7 +433,6 @@ int _glfwPlatformInit(void)
_glfwInitTimerWin32();
_glfwInitJoysticksWin32();
_glfwPollMonitorsWin32();
return GLFW_TRUE;
}
@@ -539,12 +449,12 @@ void _glfwPlatformTerminate(void)
SPIF_SENDCHANGE);
free(_glfw.win32.clipboardString);
free(_glfw.win32.rawInput);
_glfwTerminateWGL();
_glfwTerminateEGL();
_glfwTerminateJoysticksWin32();
_glfwTerminateThreadLocalStorageWin32();
freeLibraries();
}
+296 -285
View File
@@ -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) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
@@ -27,9 +27,13 @@
#include "internal.h"
#include <stdio.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_SLIDER 1
#define _GLFW_TYPE_BUTTON 2
@@ -48,39 +52,18 @@ typedef struct _GLFWobjenumWin32
int povCount;
} _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 =
{0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
static const GUID _glfw_GUID_XAxis =
{0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_YAxis =
{0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_ZAxis =
{0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RxAxis =
{0xa36d02f4,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
DEFINE_GUID(IID_IDirectInput8W,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);
DEFINE_GUID(GUID_YAxis,0xa36d02e1,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);
DEFINE_GUID(GUID_RxAxis,0xa36d02f4,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);
DEFINE_GUID(GUID_RzAxis,0xa36d02e3,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);
DEFINE_GUID(GUID_Button,0xa36d02f0,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);
// Object data array for our clone of c_dfDIJoystick
// Generated with https://github.com/elmindreda/c_dfDIJoystick2
@@ -166,9 +149,9 @@ static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic)
case XINPUT_DEVSUBTYPE_GAMEPAD:
{
if (xic->Flags & XINPUT_CAPS_WIRELESS)
return "Wireless Xbox Controller";
return "Wireless Xbox 360 Controller";
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
//
static void closeJoystick(_GLFWjoystick* js)
static void closeJoystick(_GLFWjoystickWin32* js)
{
if (js->win32.device)
if (js->device)
{
IDirectInputDevice8_Unacquire(js->win32.device);
IDirectInputDevice8_Release(js->win32.device);
IDirectInputDevice8_Unacquire(js->device);
IDirectInputDevice8_Release(js->device);
}
_glfwFreeJoystick(js);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
free(js->name);
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
// Insights gleaned from SDL
// Insights gleaned from SDL2
//
static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,
void* user)
@@ -349,20 +337,23 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
DIPROPDWORD dipd;
IDirectInputDevice8* device;
_GLFWobjenumWin32 data;
_GLFWjoystick* js;
char guid[33];
char name[256];
_GLFWjoystickWin32* js;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
{
_GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present)
{
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE;
}
if (memcmp(&_glfw.win32_js[jid].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))
return DIENUM_CONTINUE;
@@ -435,54 +426,226 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
sizeof(_GLFWjoyobjectWin32),
compareJoystickObjects);
if (!WideCharToMultiByte(CP_UTF8, 0,
di->tszInstanceName, -1,
name, sizeof(name),
NULL, NULL))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert joystick name to UTF-8");
js = _glfw.win32_js + jid;
js->device = device;
js->guid = di->guidInstance;
js->axisCount = data.axisCount + data.sliderCount;
js->axes = calloc(js->axisCount, sizeof(float));
js->buttonCount += data.buttonCount + data.povCount * 4;
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);
free(data.objects);
return DIENUM_STOP;
_glfwInputJoystickChange(jid, GLFW_CONNECTED);
return DIENUM_CONTINUE;
}
// 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
if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
{
sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
(uint8_t) di->guidProduct.Data1,
(uint8_t) (di->guidProduct.Data1 >> 8),
(uint8_t) (di->guidProduct.Data1 >> 16),
(uint8_t) (di->guidProduct.Data1 >> 24));
if (!_glfw.win32_js[jid].present)
break;
}
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
{
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]);
int i;
DWORD result;
XINPUT_STATE xis;
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 (FAILED(DirectInput8Create(GetModuleHandle(NULL),
DIRECTINPUT_VERSION,
&IID_IDirectInput8W,
(void**) &_glfw.win32.dinput8.api,
NULL)))
if (FAILED(_glfw_DirectInput8Create(GetModuleHandle(NULL),
DIRECTINPUT_VERSION,
&IID_IDirectInput8W,
(void**) &_glfw.win32.dinput8.api,
NULL)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to create interface");
@@ -517,7 +680,7 @@ void _glfwTerminateJoysticksWin32(void)
int 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)
IDirectInput8_Release(_glfw.win32.dinput8.api);
@@ -529,43 +692,10 @@ void _glfwDetectJoystickConnectionWin32(void)
{
if (_glfw.win32.xinput.instance)
{
DWORD index;
DWORD i;
for (index = 0; index < XUSER_MAX_COUNT; index++)
{
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);
}
for (i = 0; i < XUSER_MAX_COUNT; i++)
openXinputDevice(i);
}
if (_glfw.win32.dinput8.api)
@@ -589,12 +719,8 @@ void _glfwDetectJoystickDisconnectionWin32(void)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
_GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present)
_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
}
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
pollJoystickState(_glfw.win32_js + jid, _GLFW_PRESENCE_ONLY);
}
@@ -602,153 +728,38 @@ void _glfwDetectJoystickDisconnectionWin32(void)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
int _glfwPlatformJoystickPresent(int jid)
{
if (js->win32.device)
{
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;
_GLFWjoystickWin32* js = _glfw.win32_js + jid;
return pollJoystickState(js, _GLFW_PRESENCE_ONLY);
}
void _glfwPlatformUpdateGamepadGUID(char* guid)
const float* _glfwPlatformGetJoystickAxes(int jid, int* count)
{
if (strcmp(guid + 20, "504944564944") == 0)
{
char original[33];
strcpy(original, guid);
sprintf(guid, "03000000%.4s0000%.4s000000000000",
original, original + 4);
}
_GLFWjoystickWin32* js = _glfw.win32_js + jid;
if (!pollJoystickState(js, _GLFW_UPDATE_STATE))
return NULL;
*count = js->axisCount;
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
View File
@@ -24,10 +24,11 @@
//
//========================================================================
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int dummy
#ifndef _glfw3_win32_joystick_h_
#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)
//
@@ -41,8 +42,14 @@ typedef struct _GLFWjoyobjectWin32
//
typedef struct _GLFWjoystickWin32
{
GLFWbool present;
float* axes;
int axisCount;
unsigned char* buttons;
int buttonCount;
_GLFWjoyobjectWin32* objects;
int objectCount;
char* name;
IDirectInputDevice8W* device;
DWORD index;
GUID guid;
@@ -54,3 +61,4 @@ void _glfwTerminateJoysticksWin32(void);
void _glfwDetectJoystickConnectionWin32(void);
void _glfwDetectJoystickDisconnectionWin32(void);
#endif // _glfw3_win32_joystick_h_
+107 -182
View File
@@ -33,27 +33,6 @@
#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
//
static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
@@ -62,15 +41,17 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
_GLFWmonitor* monitor;
char* name;
HDC dc;
DEVMODEW dm;
RECT rect;
if (display)
name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
else
name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);
if (!name)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
return NULL;
}
dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
@@ -101,16 +82,6 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
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;
}
@@ -119,116 +90,6 @@ static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
////// 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
//
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
@@ -236,7 +97,6 @@ GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desire
GLFWvidmode current;
const GLFWvidmode* best;
DEVMODEW dm;
LONG result;
best = _glfwChooseVideoMode(monitor, desired);
_glfwPlatformGetVideoMode(monitor, &current);
@@ -244,7 +104,7 @@ GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desire
return GLFW_TRUE;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
dm.dmSize = sizeof(DEVMODEW);
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
DM_DISPLAYFREQUENCY;
dm.dmPelsWidth = best->width;
@@ -255,34 +115,13 @@ GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desire
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
dm.dmBitsPerPel = 32;
result = ChangeDisplaySettingsExW(monitor->win32.adapterName,
&dm,
NULL,
CDS_FULLSCREEN,
NULL);
if (result != DISP_CHANGE_SUCCESSFUL)
if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
&dm,
NULL,
CDS_FULLSCREEN,
NULL) != DISP_CHANGE_SUCCESSFUL)
{
const char* description = "Unknown error";
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);
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to set video mode");
return GLFW_FALSE;
}
@@ -307,21 +146,106 @@ void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
////// 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)
{
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
DEVMODEW settings;
ZeroMemory(&settings, sizeof(DEVMODEW));
settings.dmSize = sizeof(DEVMODEW);
EnumDisplaySettingsExW(monitor->win32.adapterName,
ENUM_CURRENT_SETTINGS,
&dm,
&settings,
EDS_ROTATEDMODE);
if (xpos)
*xpos = dm.dmPosition.x;
*xpos = settings.dmPosition.x;
if (ypos)
*ypos = dm.dmPosition.y;
*ypos = settings.dmPosition.y;
}
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
@@ -337,8 +261,8 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
GLFWvidmode mode;
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
ZeroMemory(&dm, sizeof(DEVMODEW));
dm.dmSize = sizeof(DEVMODEW);
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
break;
@@ -404,8 +328,9 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
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);
+27 -38
View File
@@ -25,6 +25,9 @@
//
//========================================================================
#ifndef _glfw3_win32_platform_h_
#define _glfw3_win32_platform_h_
// We don't need all the fancy stuff
#ifndef NOMINMAX
#define NOMINMAX
@@ -63,6 +66,7 @@
#include <wctype.h>
#include <windows.h>
#include <mmsystem.h>
#include <dinput.h>
#include <xinput.h>
#include <dbt.h>
@@ -158,17 +162,17 @@ typedef enum PROCESS_DPI_AWARENESS
// winmm.dll function pointer typedefs
typedef DWORD (WINAPI * PFN_timeGetTime)(void);
#define timeGetTime _glfw.win32.winmm.GetTime
#define _glfw_timeGetTime _glfw.win32.winmm.timeGetTime
// xinput.dll function pointer typedefs
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
#define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities
#define XInputGetState _glfw.win32.xinput.GetState
#define _glfw_XInputGetCapabilities _glfw.win32.xinput.XInputGetCapabilities
#define _glfw_XInputGetState _glfw.win32.xinput.XInputGetState
// dinput8.dll function pointer typedefs
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
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
@@ -179,8 +183,8 @@ typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEF
// dwmapi.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
#define DwmFlush _glfw.win32.dwmapi.Flush
#define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled
#define _glfw_DwmFlush _glfw.win32.dwmapi.DwmFlush
// shcore.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
@@ -203,7 +207,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
#include "win32_joystick.h"
#include "wgl_context.h"
#include "egl_context.h"
#include "osmesa_context.h"
#define _GLFW_WNDCLASSNAME L"GLFW30"
@@ -216,11 +219,10 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 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_CURSOR_STATE _GLFWcursorWin32 win32
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexWin32 win32
// Win32-specific per-window data
@@ -232,7 +234,6 @@ typedef struct _GLFWwindowWin32
HICON smallIcon;
GLFWbool cursorTracked;
GLFWbool frameAction;
GLFWbool iconified;
GLFWbool maximized;
@@ -247,33 +248,30 @@ typedef struct _GLFWlibraryWin32
{
HWND helperWindowHandle;
DWORD foregroundLockTimeout;
int acquiredMonitorCount;
char* clipboardString;
char keyName[64];
short int keycodes[512];
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
RAWINPUT* rawInput;
int rawInputSize;
struct {
HINSTANCE instance;
PFN_timeGetTime GetTime;
PFN_timeGetTime timeGetTime;
} winmm;
struct {
HINSTANCE instance;
PFN_DirectInput8Create Create;
PFN_DirectInput8Create DirectInput8Create;
IDirectInput8W* api;
} dinput8;
struct {
HINSTANCE instance;
PFN_XInputGetCapabilities GetCapabilities;
PFN_XInputGetState GetState;
PFN_XInputGetCapabilities XInputGetCapabilities;
PFN_XInputGetState XInputGetState;
} xinput;
struct {
@@ -284,8 +282,8 @@ typedef struct _GLFWlibraryWin32
struct {
HINSTANCE instance;
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
PFN_DwmFlush Flush;
PFN_DwmIsCompositionEnabled DwmIsCompositionEnabled;
PFN_DwmFlush DwmFlush;
} dwmapi;
struct {
@@ -299,7 +297,6 @@ typedef struct _GLFWlibraryWin32
//
typedef struct _GLFWmonitorWin32
{
HMONITOR handle;
// This size matches the static size of DISPLAY_DEVICE.DeviceName
WCHAR adapterName[32];
WCHAR displayName[32];
@@ -320,43 +317,35 @@ typedef struct _GLFWcursorWin32
// Win32-specific global timer data
//
typedef struct _GLFWtimerWin32
typedef struct _GLFWtimeWin32
{
GLFWbool hasPC;
uint64_t frequency;
} _GLFWtimerWin32;
} _GLFWtimeWin32;
// Win32-specific thread local storage data
// Win32-specific global TLS data
//
typedef struct _GLFWtlsWin32
{
GLFWbool allocated;
DWORD index;
DWORD context;
} _GLFWtlsWin32;
// Win32-specific mutex data
//
typedef struct _GLFWmutexWin32
{
GLFWbool allocated;
CRITICAL_SECTION section;
} _GLFWmutexWin32;
GLFWbool _glfwRegisterWindowClassWin32(void);
void _glfwUnregisterWindowClassWin32(void);
GLFWbool _glfwInitThreadLocalStorageWin32(void);
void _glfwTerminateThreadLocalStorageWin32(void);
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
void _glfwInputErrorWin32(int error, const char* description);
void _glfwUpdateKeyNamesWin32(void);
void _glfwInitTimerWin32(void);
void _glfwPollMonitorsWin32(void);
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
#endif // _glfw3_win32_platform_h_
+7 -7
View File
@@ -40,13 +40,13 @@ void _glfwInitTimerWin32(void)
if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency))
{
_glfw.timer.win32.hasPC = GLFW_TRUE;
_glfw.timer.win32.frequency = frequency;
_glfw.win32_time.hasPC = GLFW_TRUE;
_glfw.win32_time.frequency = frequency;
}
else
{
_glfw.timer.win32.hasPC = GLFW_FALSE;
_glfw.timer.win32.frequency = 1000;
_glfw.win32_time.hasPC = GLFW_FALSE;
_glfw.win32_time.frequency = 1000;
}
}
@@ -57,18 +57,18 @@ void _glfwInitTimerWin32(void)
uint64_t _glfwPlatformGetTimerValue(void)
{
if (_glfw.timer.win32.hasPC)
if (_glfw.win32_time.hasPC)
{
uint64_t value;
QueryPerformanceCounter((LARGE_INTEGER*) &value);
return value;
}
else
return (uint64_t) timeGetTime();
return (uint64_t) _glfw_timeGetTime();
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.win32.frequency;
return _glfw.win32_time.frequency;
}
+28 -56
View File
@@ -27,71 +27,43 @@
#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 //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
void _glfwPlatformSetCurrentContext(_GLFWwindow* context)
{
assert(tls->win32.allocated == GLFW_FALSE);
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;
TlsSetValue(_glfw.win32_tls.context, context);
}
void _glfwPlatformDestroyTls(_GLFWtls* tls)
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
if (tls->win32.allocated)
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);
return TlsGetValue(_glfw.win32_tls.context);
}
+133 -237
View File
@@ -111,7 +111,7 @@ static HICON createIcon(const GLFWimage* image,
unsigned char* source = image->pixels;
ZeroMemory(&bi, sizeof(bi));
bi.bV5Size = sizeof(bi);
bi.bV5Size = sizeof(BITMAPV5HEADER);
bi.bV5Width = image->width;
bi.bV5Height = -image->height;
bi.bV5Planes = 1;
@@ -133,16 +133,16 @@ static HICON createIcon(const GLFWimage* image,
if (!color)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to create RGBA bitmap");
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to create RGBA bitmap");
return NULL;
}
mask = CreateBitmap(image->width, image->height, 1, 1, NULL);
if (!mask)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to create mask bitmap");
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to create mask bitmap");
DeleteObject(color);
return NULL;
}
@@ -172,15 +172,9 @@ static HICON createIcon(const GLFWimage* image,
if (!handle)
{
if (icon)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to create icon");
}
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create icon");
else
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to create cursor");
}
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create cursor");
}
return handle;
@@ -369,19 +363,20 @@ static int getAsyncKeyMods(void)
//
static int translateKey(WPARAM wParam, LPARAM lParam)
{
// The Ctrl keys require special handling
if (wParam == VK_CONTROL)
{
// The CTRL keys require special handling
MSG next;
DWORD time;
// Right side keys have the extended key bit set
// Is this an extended key (i.e. right key)?
if (lParam & 0x01000000)
return GLFW_KEY_RIGHT_CONTROL;
// HACK: Alt Gr sends Left Ctrl and then Right Alt in close sequence
// We only want the Right Alt message, so if the next message is
// Right Alt we ignore this (synthetic) Left Ctrl message
// Here is a trick: "Alt Gr" sends LCTRL, then RALT. We only
// want the RALT message, so we try to see if the next message
// is a RALT message. In that case, this is a false LCTRL!
time = GetMessageTime();
if (PeekMessageW(&next, NULL, 0, 0, PM_NOREMOVE))
@@ -395,7 +390,8 @@ static int translateKey(WPARAM wParam, LPARAM lParam)
(next.lParam & 0x01000000) &&
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;
}
}
@@ -422,11 +418,6 @@ static GLFWbool acquireMonitor(_GLFWwindow* window)
GLFWbool status;
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);
_glfwPlatformGetVideoMode(window->monitor, &mode);
@@ -436,7 +427,7 @@ static GLFWbool acquireMonitor(_GLFWwindow* window)
xpos, ypos, mode.width, mode.height,
SWP_NOACTIVATE | SWP_NOCOPYBITS);
_glfwInputMonitorWindow(window->monitor, window);
_glfwInputMonitorWindowChange(window->monitor, window);
return status;
}
@@ -447,11 +438,7 @@ static void releaseMonitor(_GLFWwindow* window)
if (window->monitor->window != window)
return;
_glfw.win32.acquiredMonitorCount--;
if (!_glfw.win32.acquiredMonitorCount)
SetThreadExecutionState(ES_CONTINUOUS);
_glfwInputMonitorWindow(window->monitor, NULL);
_glfwInputMonitorWindowChange(window->monitor, NULL);
_glfwRestoreVideoModeWin32(window->monitor);
}
@@ -467,23 +454,30 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
switch (uMsg)
{
case WM_DISPLAYCHANGE:
_glfwPollMonitorsWin32();
break;
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;
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickConnectionWin32();
if (dbh)
{
if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickConnectionWin32();
}
}
else if (wParam == DBT_DEVICEREMOVECOMPLETE)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickDisconnectionWin32();
if (dbh)
{
if (dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickDisconnectionWin32();
}
}
break;
@@ -495,47 +489,10 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT 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:
{
_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)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
@@ -584,12 +541,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return 0;
}
case WM_INPUTLANGCHANGE:
{
_glfwUpdateKeyNamesWin32();
break;
}
case WM_CHAR:
case WM_SYSCHAR:
case WM_UNICHAR:
@@ -623,15 +574,14 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
if (action == GLFW_RELEASE && wParam == VK_SHIFT)
{
// HACK: Release both Shift keys on Shift up event, as when both
// are pressed the first release does not emit any event
// NOTE: The other half of this is in _glfwPlatformPollEvents
// Release both Shift keys on Shift up event, as only one event
// is sent even if both keys are released
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, action, mods);
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, action, mods);
}
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_RELEASE, mods);
}
@@ -650,7 +600,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MBUTTONUP:
case WM_XBUTTONUP:
{
int i, button, action;
int button, action;
if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
button = GLFW_MOUSE_BUTTON_LEFT;
@@ -667,30 +617,16 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
uMsg == WM_MBUTTONDOWN || uMsg == WM_XBUTTONDOWN)
{
action = GLFW_PRESS;
SetCapture(hWnd);
}
else
action = GLFW_RELEASE;
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{
if (window->mouseButtons[i] == GLFW_PRESS)
break;
action = GLFW_RELEASE;
ReleaseCapture();
}
if (i > GLFW_MOUSE_BUTTON_LAST)
SetCapture(hWnd);
_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)
return TRUE;
@@ -702,11 +638,20 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam);
// Disabled cursor motion input is provided by WM_INPUT
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.lastCursorPosY = y;
@@ -727,56 +672,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
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:
{
window->win32.cursorTracked = GLFW_FALSE;
@@ -801,8 +696,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_ENTERSIZEMOVE:
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)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_NORMAL);
@@ -812,8 +705,6 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_EXITSIZEMOVE:
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)
_glfwPlatformSetCursorMode(window, GLFW_CURSOR_DISABLED);
@@ -994,7 +885,7 @@ static int createNativeWindow(_GLFWwindow* window,
// NOTE: This window placement is temporary and approximate, as the
// 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);
_glfwPlatformGetVideoMode(window->monitor, &mode);
fullWidth = mode.width;
@@ -1015,7 +906,11 @@ static int createNativeWindow(_GLFWwindow* window,
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title);
if (!wideTitle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert window title to UTF-16");
return GLFW_FALSE;
}
window->win32.handle = CreateWindowExW(exStyle,
_GLFW_WNDCLASSNAME,
@@ -1032,8 +927,7 @@ static int createNativeWindow(_GLFWwindow* window,
if (!window->win32.handle)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to create window");
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create window");
return GLFW_FALSE;
}
@@ -1087,8 +981,8 @@ GLFWbool _glfwRegisterWindowClassWin32(void)
if (!RegisterClassExW(&wc))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to register window class");
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to register window class");
return GLFW_FALSE;
}
@@ -1124,20 +1018,13 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
}
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
else
{
if (!_glfwInitEGL())
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 (window->monitor)
@@ -1147,8 +1034,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!acquireMonitor(window))
return GLFW_FALSE;
if (wndconfig->centerCursor)
centerCursor(window);
centerCursor(window);
}
return GLFW_TRUE;
@@ -1183,7 +1069,11 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{
WCHAR* wideTitle = _glfwCreateWideStringFromUTF8Win32(title);
if (!wideTitle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert window title to UTF-16");
return;
}
SetWindowTextW(window->win32.handle, wideTitle);
free(wideTitle);
@@ -1363,11 +1253,6 @@ void _glfwPlatformHideWindow(_GLFWwindow* window)
ShowWindow(window->win32.handle, SW_HIDE);
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{
FlashWindow(window->win32.handle, TRUE);
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
{
BringWindowToTop(window->win32.handle);
@@ -1508,9 +1393,9 @@ void _glfwPlatformPollEvents(void)
{
if (msg.message == WM_QUIT)
{
// NOTE: While GLFW does not itself post WM_QUIT, other processes
// may post it to this one, for example Task Manager
// HACK: Treat WM_QUIT as a close on all windows
// Treat WM_QUIT as a close on all windows
// While GLFW does not itself post WM_QUIT, other processes may post
// it to this one, for example Task Manager
window = _glfw.windowListHead;
while (window)
@@ -1529,28 +1414,25 @@ void _glfwPlatformPollEvents(void)
handle = GetActiveWindow();
if (handle)
{
// NOTE: Shift keys on Windows tend to "stick" when both are pressed as
// no key up message is generated by the first key release
// The other half of this is in the handling of WM_KEYUP
// HACK: Query actual key state and synthesize release events as needed
// LSHIFT/RSHIFT fixup (keys tend to "stick" without this fix)
// This is the only async event handling in GLFW, but it solves some
// nasty problems
window = GetPropW(handle, L"GLFW");
if (window)
{
const GLFWbool lshift = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;
const GLFWbool rshift = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;
const int mods = getAsyncKeyMods();
if (!lshift && window->keys[GLFW_KEY_LEFT_SHIFT] == GLFW_PRESS)
{
const int mods = getAsyncKeyMods();
const int scancode = _glfw.win32.scancodes[GLFW_KEY_LEFT_SHIFT];
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, scancode, GLFW_RELEASE, mods);
}
else if (!rshift && window->keys[GLFW_KEY_RIGHT_SHIFT] == GLFW_PRESS)
{
const int mods = getAsyncKeyMods();
const int scancode = _glfw.win32.scancodes[GLFW_KEY_RIGHT_SHIFT];
_glfwInputKey(window, GLFW_KEY_RIGHT_SHIFT, scancode, GLFW_RELEASE, mods);
}
// Get current state of left and right shift keys
const int lshiftDown = (GetAsyncKeyState(VK_LSHIFT) >> 15) & 1;
const int rshiftDown = (GetAsyncKeyState(VK_RSHIFT) >> 15) & 1;
// See if this differs from our belief of what has happened
// (we only have to check for lost key up events)
if (!lshiftDown && window->keys[GLFW_KEY_LEFT_SHIFT] == 1)
_glfwInputKey(window, GLFW_KEY_LEFT_SHIFT, 0, GLFW_RELEASE, mods);
if (!rshiftDown && window->keys[GLFW_KEY_RIGHT_SHIFT] == 1)
_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)
{
const RAWINPUTDEVICE rid = { 0x01, 0x02, 0, window->win32.handle };
_glfw.win32.disabledCursorWindow = window;
_glfwPlatformGetCursorPos(window,
&_glfw.win32.restoreCursorPosX,
&_glfw.win32.restoreCursorPosY);
centerCursor(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)
{
const RAWINPUTDEVICE rid = { 0x01, 0x02, RIDEV_REMOVE, NULL };
_glfw.win32.disabledCursorWindow = NULL;
updateClipRect(NULL);
_glfwPlatformSetCursorPos(window,
_glfw.win32.restoreCursorPosX,
_glfw.win32.restoreCursorPosY);
if (!RegisterRawInputDevices(&rid, 1, sizeof(rid)))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to remove raw input device");
}
}
if (cursorInClientArea(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)
@@ -1683,8 +1568,8 @@ int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
CopyCursor(LoadCursorW(NULL, translateCursorShape(shape)));
if (!cursor->win32.handle)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to create standard cursor");
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to create standard cursor");
return GLFW_FALSE;
}
@@ -1711,22 +1596,26 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
characterCount = MultiByteToWideChar(CP_UTF8, 0, string, -1, NULL, 0);
if (!characterCount)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert clipboard string to UTF-16");
return;
}
object = GlobalAlloc(GMEM_MOVEABLE, characterCount * sizeof(WCHAR));
if (!object)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to allocate global handle for clipboard");
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to allocate global handle for clipboard");
return;
}
buffer = GlobalLock(object);
if (!buffer)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to lock global handle");
GlobalFree(object);
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");
return;
}
@@ -1735,9 +1624,9 @@ void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to open clipboard");
GlobalFree(object);
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");
return;
}
@@ -1753,35 +1642,43 @@ const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
if (!OpenClipboard(_glfw.win32.helperWindowHandle))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to open clipboard");
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to open clipboard");
return NULL;
}
object = GetClipboardData(CF_UNICODETEXT);
if (!object)
{
_glfwInputErrorWin32(GLFW_FORMAT_UNAVAILABLE,
"Win32: Failed to convert clipboard to string");
CloseClipboard();
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"Win32: Failed to convert clipboard to string");
return NULL;
}
buffer = GlobalLock(object);
if (!buffer)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to lock global handle");
CloseClipboard();
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to lock global handle");
return NULL;
}
free(_glfw.win32.clipboardString);
_glfw.win32.clipboardString = _glfwCreateUTF8FromWideStringWin32(buffer);
_glfw.win32.clipboardString =
_glfwCreateUTF8FromWideStringWin32(buffer);
GlobalUnlock(object);
CloseClipboard();
if (!_glfw.win32.clipboardString)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert wide string to UTF-8");
return NULL;
}
return _glfw.win32.clipboardString;
}
@@ -1798,8 +1695,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
vkGetPhysicalDeviceWin32PresentationSupportKHR =
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
+88 -109
View File
@@ -40,26 +40,30 @@
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
{
if (window->callbacks.focus)
window->callbacks.focus((GLFWwindow*) window, focused);
if (!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)
{
const int scancode = _glfwPlatformGetKeyScancode(key);
_glfwInputKey(window, key, scancode, GLFW_RELEASE, 0);
}
if (window->keys[i] == GLFW_PRESS)
_glfwInputKey(window, i, 0, 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)
_glfwInputMouseClick(window, button, GLFW_RELEASE, 0);
if (window->mouseButtons[i] == GLFW_PRESS)
_glfwInputMouseClick(window, i, GLFW_RELEASE, 0);
}
}
}
@@ -130,8 +134,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
_GLFWwindow* previous;
assert(title != NULL);
assert(width >= 0);
assert(height >= 0);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
@@ -192,7 +194,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
window->denom = GLFW_DONT_CARE;
// Save the currently current context so it can be restored later
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
previous = _glfwPlatformGetCurrentContext();
if (ctxconfig.client != GLFW_NO_API)
glfwMakeContextCurrent(NULL);
@@ -237,15 +239,15 @@ void glfwDefaultWindowHints(void)
{
_GLFW_REQUIRE_INIT();
memset(&_glfw.hints, 0, sizeof(_glfw.hints));
// 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.source = GLFW_NATIVE_CONTEXT_API;
_glfw.hints.context.major = 1;
_glfw.hints.context.minor = 0;
// 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.visible = 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,
// double buffered
memset(&_glfw.hints.framebuffer, 0, sizeof(_glfw.hints.framebuffer));
_glfw.hints.framebuffer.redBits = 8;
_glfw.hints.framebuffer.greenBits = 8;
_glfw.hints.framebuffer.blueBits = 8;
@@ -278,118 +279,110 @@ GLFWAPI void glfwWindowHint(int hint, int value)
{
case GLFW_RED_BITS:
_glfw.hints.framebuffer.redBits = value;
return;
break;
case GLFW_GREEN_BITS:
_glfw.hints.framebuffer.greenBits = value;
return;
break;
case GLFW_BLUE_BITS:
_glfw.hints.framebuffer.blueBits = value;
return;
break;
case GLFW_ALPHA_BITS:
_glfw.hints.framebuffer.alphaBits = value;
return;
break;
case GLFW_DEPTH_BITS:
_glfw.hints.framebuffer.depthBits = value;
return;
break;
case GLFW_STENCIL_BITS:
_glfw.hints.framebuffer.stencilBits = value;
return;
break;
case GLFW_ACCUM_RED_BITS:
_glfw.hints.framebuffer.accumRedBits = value;
return;
break;
case GLFW_ACCUM_GREEN_BITS:
_glfw.hints.framebuffer.accumGreenBits = value;
return;
break;
case GLFW_ACCUM_BLUE_BITS:
_glfw.hints.framebuffer.accumBlueBits = value;
return;
break;
case GLFW_ACCUM_ALPHA_BITS:
_glfw.hints.framebuffer.accumAlphaBits = value;
return;
break;
case GLFW_AUX_BUFFERS:
_glfw.hints.framebuffer.auxBuffers = value;
return;
break;
case GLFW_STEREO:
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_DOUBLEBUFFER:
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_SAMPLES:
_glfw.hints.framebuffer.samples = value;
return;
break;
case GLFW_SRGB_CAPABLE:
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_RESIZABLE:
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_DECORATED:
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_FOCUSED:
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_AUTO_ICONIFY:
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_FLOATING:
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_MAXIMIZED:
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_VISIBLE:
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_COCOA_RETINA_FRAMEBUFFER:
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
return;
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;
break;
case GLFW_CLIENT_API:
_glfw.hints.context.client = value;
return;
break;
case GLFW_CONTEXT_CREATION_API:
_glfw.hints.context.source = value;
return;
break;
case GLFW_CONTEXT_VERSION_MAJOR:
_glfw.hints.context.major = value;
return;
break;
case GLFW_CONTEXT_VERSION_MINOR:
_glfw.hints.context.minor = value;
return;
break;
case GLFW_CONTEXT_ROBUSTNESS:
_glfw.hints.context.robustness = value;
return;
break;
case GLFW_OPENGL_FORWARD_COMPAT:
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_OPENGL_DEBUG_CONTEXT:
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_CONTEXT_NO_ERROR:
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
return;
break;
case GLFW_OPENGL_PROFILE:
_glfw.hints.context.profile = value;
return;
break;
case GLFW_CONTEXT_RELEASE_BEHAVIOR:
_glfw.hints.context.release = value;
return;
break;
case GLFW_REFRESH_RATE:
_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)
@@ -407,7 +400,7 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
// The window's context must not be current on another thread when the
// window is destroyed
if (window == _glfwPlatformGetTls(&_glfw.contextSlot))
if (window == _glfwPlatformGetCurrentContext())
glfwMakeContextCurrent(NULL);
_glfwPlatformDestroyWindow(window);
@@ -447,6 +440,7 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(title != NULL);
_GLFW_REQUIRE_INIT();
@@ -510,8 +504,6 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(width >= 0);
assert(height >= 0);
_GLFW_REQUIRE_INIT();
@@ -570,8 +562,6 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(numer != 0);
assert(denom != 0);
_GLFW_REQUIRE_INIT();
@@ -674,16 +664,6 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
_glfwPlatformFocusWindow(window);
}
GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
_glfwPlatformRequestWindowAttention(window);
}
GLFWAPI void glfwHideWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
@@ -756,7 +736,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
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;
}
@@ -769,37 +749,41 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
value = value ? GLFW_TRUE : GLFW_FALSE;
if (attrib == GLFW_AUTO_ICONIFY)
window->autoIconify = value;
else if (attrib == GLFW_RESIZABLE)
switch (attrib)
{
if (window->resizable == value)
case GLFW_RESIZABLE:
if (window->resizable != value)
{
window->resizable = value;
if (!window->monitor)
_glfwPlatformSetWindowResizable(window, value);
}
return;
window->resizable = value;
if (!window->monitor)
_glfwPlatformSetWindowResizable(window, value);
}
else if (attrib == GLFW_DECORATED)
{
if (window->decorated == value)
case GLFW_DECORATED:
if (window->decorated != value)
{
window->decorated = value;
if (!window->monitor)
_glfwPlatformSetWindowDecorated(window, value);
}
return;
window->decorated = value;
if (!window->monitor)
_glfwPlatformSetWindowDecorated(window, value);
}
else if (attrib == GLFW_FLOATING)
{
if (window->floating == value)
case GLFW_FLOATING:
if (window->floating != value)
{
window->floating = value;
if (!window->monitor)
_glfwPlatformSetWindowFloating(window, value);
}
return;
window->floating = value;
if (!window->monitor)
_glfwPlatformSetWindowFloating(window, value);
case GLFW_AUTO_ICONIFY:
window->autoIconify = 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)
@@ -820,8 +804,6 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
_GLFWwindow* window = (_GLFWwindow*) wh;
_GLFWmonitor* monitor = (_GLFWmonitor*) mh;
assert(window != NULL);
assert(width >= 0);
assert(height >= 0);
_GLFW_REQUIRE_INIT();
@@ -975,9 +957,6 @@ GLFWAPI void glfwWaitEvents(void)
GLFWAPI void glfwWaitEventsTimeout(double timeout)
{
_GLFW_REQUIRE_INIT();
assert(timeout == timeout);
assert(timeout >= 0.0);
assert(timeout <= DBL_MAX);
if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)
{
+11 -5
View File
@@ -109,8 +109,6 @@ static void pointerHandleButton(void* data,
if (!window)
return;
_glfw.wl.pointerSerial = serial;
/* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
* codes. */
glfwButton = button - BTN_LEFT;
@@ -294,7 +292,7 @@ static int toGLFWKeyCode(uint32_t key)
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;
if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)
!= XKB_COMPOSE_FEED_ACCEPTED)
@@ -521,7 +519,6 @@ static void createKeyTables(void)
_glfw.wl.keycodes[KEY_8] = GLFW_KEY_8;
_glfw.wl.keycodes[KEY_9] = GLFW_KEY_9;
_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_EQUAL] = GLFW_KEY_EQUAL;
_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);
wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);
_glfw.wl.monitors = calloc(4, sizeof(_GLFWmonitor*));
_glfw.wl.monitorsSize = 4;
createKeyTables();
_glfw.wl.xkb.context = xkb_context_new(0);
@@ -669,6 +669,9 @@ int _glfwPlatformInit(void)
// Sync so we got all initial output events
wl_display_roundtrip(_glfw.wl.display);
if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE;
if (!_glfwInitJoysticksLinux())
return GLFW_FALSE;
@@ -694,6 +697,7 @@ void _glfwPlatformTerminate(void)
{
_glfwTerminateEGL();
_glfwTerminateJoysticksLinux();
_glfwTerminateThreadLocalStoragePOSIX();
xkb_compose_state_unref(_glfw.wl.xkb.composeState);
xkb_keymap_unref(_glfw.wl.xkb.keymap);
@@ -737,7 +741,9 @@ const char* _glfwPlatformGetVersionString(void)
#else
" gettimeofday"
#endif
" evdev"
#if defined(__linux__)
" /dev/js"
#endif
#if defined(_GLFW_BUILD_DLL)
" shared"
#endif
+107 -23
View File
@@ -32,6 +32,12 @@
#include <errno.h>
struct _GLFWvidmodeWayland
{
GLFWvidmode base;
uint32_t flags;
};
static void geometry(void* data,
struct wl_output* output,
int32_t x,
@@ -44,15 +50,21 @@ static void geometry(void* data,
int32_t transform)
{
struct _GLFWmonitor *monitor = data;
char name[1024];
char* name;
size_t nameLength;
monitor->wl.x = x;
monitor->wl.y = y;
monitor->widthMM = physicalWidth;
monitor->heightMM = physicalHeight;
snprintf(name, sizeof(name), "%s %s", make, model);
monitor->name = strdup(name);
nameLength = strlen(make) + 1 + strlen(model) + 1;
name = realloc(monitor->name, nameLength);
if (name)
{
sprintf(name, "%s %s", make, model);
monitor->name = name;
}
}
static void mode(void* data,
@@ -63,29 +75,32 @@ static void mode(void* data,
int32_t refresh)
{
struct _GLFWmonitor *monitor = data;
GLFWvidmode mode;
_GLFWvidmodeWayland mode = { { 0 }, };
mode.width = width;
mode.height = height;
mode.redBits = 8;
mode.greenBits = 8;
mode.blueBits = 8;
mode.refreshRate = refresh / 1000;
mode.base.width = width;
mode.base.height = height;
mode.base.refreshRate = refresh / 1000;
mode.flags = flags;
monitor->modeCount++;
monitor->modes =
realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
monitor->modes[monitor->modeCount - 1] = mode;
if (monitor->wl.modesCount + 1 >= monitor->wl.modesSize)
{
int size = monitor->wl.modesSize * 2;
_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.currentMode = monitor->modeCount - 1;
monitor->wl.modes[monitor->wl.modesCount++] = mode;
}
static void done(void* data, struct wl_output* output)
static void done(void* data,
struct wl_output* output)
{
struct _GLFWmonitor *monitor = data;
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
monitor->wl.done = GLFW_TRUE;
}
static void scale(void* data,
@@ -134,10 +149,26 @@ void _glfwAddOutputWayland(uint32_t name, uint32_t version)
return;
}
monitor->wl.scale = 1;
monitor->wl.output = output;
monitor->wl.modes = calloc(4, sizeof(_GLFWvidmodeWayland));
monitor->wl.modesSize = 4;
monitor->wl.scale = 1;
monitor->wl.output = output;
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 //////
//////////////////////////////////////////////////////////////////////////
_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)
{
if (xpos)
@@ -155,13 +222,30 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
{
*found = monitor->modeCount;
return monitor->modes;
GLFWvidmode *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)
{
*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)
+18 -4
View File
@@ -24,6 +24,9 @@
//
//========================================================================
#ifndef _glfw3_wayland_platform_h_
#define _glfw3_wayland_platform_h_
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.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 VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
#include "posix_thread.h"
#include "posix_tls.h"
#include "posix_time.h"
#include "linux_joystick.h"
#include "xkb_unicode.h"
#include "egl_context.h"
#include "osmesa_context.h"
#include "wayland-relative-pointer-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
// Wayland-specific video mode data
//
typedef struct _GLFWvidmodeWayland _GLFWvidmodeWayland;
// Wayland-specific per-window data
//
typedef struct _GLFWwindowWayland
@@ -120,6 +126,10 @@ typedef struct _GLFWlibraryWayland
struct wl_surface* cursorSurface;
uint32_t pointerSerial;
_GLFWmonitor** monitors;
int monitorsCount;
int monitorsSize;
short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1];
@@ -145,12 +155,15 @@ typedef struct _GLFWlibraryWayland
typedef struct _GLFWmonitorWayland
{
struct wl_output* output;
int currentMode;
_GLFWvidmodeWayland* modes;
int modesCount;
int modesSize;
GLFWbool done;
int x;
int y;
int scale;
} _GLFWmonitorWayland;
// Wayland-specific per-cursor data
@@ -166,3 +179,4 @@ typedef struct _GLFWcursorWayland
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
#endif // _glfw3_wayland_platform_h_
+6 -27
View File
@@ -249,8 +249,6 @@ static GLFWbool createShellSurface(_GLFWwindow* window)
wl_shell_surface_set_toplevel(window->wl.shellSurface);
}
wl_surface_commit(window->wl.surface);
return GLFW_TRUE;
}
@@ -395,21 +393,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (ctxconfig->client != GLFW_NO_API)
{
if (ctxconfig->source == GLFW_EGL_CONTEXT_API ||
ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
{
if (!_glfwInitEGL())
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 (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
}
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)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@@ -721,7 +701,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
_glfwPlatformSetCursor(window, window->wl.currentCursor);
}
const char* _glfwPlatformGetScancodeName(int scancode)
const char* _glfwPlatformGetKeyName(int key, int scancode)
{
// TODO
return NULL;
@@ -1019,8 +999,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
vkGetPhysicalDeviceWaylandPresentationSupportKHR =
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
+69 -185
View File
@@ -237,8 +237,8 @@ static void createKeyTables(void)
if (_glfw.x11.xkb.available)
{
// Use XKB to determine physical key locations independently of the
// current keyboard layout
// Use XKB to determine physical key locations independently of the current
// keyboard layout
char name[XkbKeyNameLength + 1];
XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
@@ -381,11 +381,13 @@ static void detectEWMH(void)
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
// Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
if (!_glfwGetWindowPropertyX11(_glfw.x11.root,
supportingWmCheck,
XA_WINDOW,
(unsigned char**) &windowFromRoot))
if (_glfwGetWindowPropertyX11(_glfw.x11.root,
supportingWmCheck,
XA_WINDOW,
(unsigned char**) &windowFromRoot) != 1)
{
if (windowFromRoot)
XFree(windowFromRoot);
return;
}
@@ -393,12 +395,14 @@ static void detectEWMH(void)
// It should be the ID of a child window (of the root)
// Then we look for the same property on the child window
if (!_glfwGetWindowPropertyX11(*windowFromRoot,
supportingWmCheck,
XA_WINDOW,
(unsigned char**) &windowFromChild))
if (_glfwGetWindowPropertyX11(*windowFromRoot,
supportingWmCheck,
XA_WINDOW,
(unsigned char**) &windowFromChild) != 1)
{
XFree(windowFromRoot);
if (windowFromChild)
XFree(windowFromChild);
return;
}
@@ -438,8 +442,6 @@ static void detectEWMH(void)
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");
_glfw.x11.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 =
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
_glfw.x11.NET_WM_WINDOW_TYPE =
@@ -453,15 +455,14 @@ static void detectEWMH(void)
_glfw.x11.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)
{
_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)
{
_glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
@@ -479,89 +480,23 @@ static GLFWbool initExtensions(void)
&_glfw.x11.vidmode.errorBase);
}
_glfw.x11.xi.handle = dlopen("libXi.so.6", RTLD_LAZY | RTLD_GLOBAL);
if (_glfw.x11.xi.handle)
// Check for RandR extension
if (XRRQueryExtension(_glfw.x11.display,
&_glfw.x11.randr.eventBase,
&_glfw.x11.randr.errorBase))
{
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
_glfw.x11.xi.SelectEvents = (PFN_XISelectEvents)
dlsym(_glfw.x11.xi.handle, "XISelectEvents");
if (XQueryExtension(_glfw.x11.display,
"XInputExtension",
&_glfw.x11.xi.majorOpcode,
&_glfw.x11.xi.eventBase,
&_glfw.x11.xi.errorBase))
if (XRRQueryVersion(_glfw.x11.display,
&_glfw.x11.randr.major,
&_glfw.x11.randr.minor))
{
_glfw.x11.xi.major = 2;
_glfw.x11.xi.minor = 0;
if (XIQueryVersion(_glfw.x11.display,
&_glfw.x11.xi.major,
&_glfw.x11.xi.minor) == Success)
{
_glfw.x11.xi.available = GLFW_TRUE;
}
// 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;
}
}
_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))
else
{
if (XRRQueryVersion(_glfw.x11.display,
&_glfw.x11.randr.major,
&_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");
}
_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]))
{
// This is likely an older Nvidia driver with broken gamma support
// Flag it as useless and fall back to xf86vm gamma, if available
// This is either a headless system or an older Nvidia binary driver
// 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;
}
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);
}
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
XRRSelectInput(_glfw.x11.display, _glfw.x11.root,
RROutputChangeNotifyMask);
}
_glfw.x11.xcursor.handle = dlopen("libXcursor.so.1", RTLD_LAZY | RTLD_GLOBAL);
if (_glfw.x11.xcursor.handle)
if (XineramaQueryExtension(_glfw.x11.display,
&_glfw.x11.xinerama.major,
&_glfw.x11.xinerama.minor))
{
_glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate");
_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;
}
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.minor = 0;
_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)
{
_glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection)
_glfw.x11.x11xcb.XGetXCBConnection = (PFN_XGetXCBConnection)
dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
}
@@ -661,7 +569,10 @@ static GLFWbool initExtensions(void)
// String format atoms
_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);
// Custom selection property atom
@@ -671,8 +582,6 @@ static GLFWbool initExtensions(void)
// ICCCM standard clipboard atoms
_glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", 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);
// Clipboard manager atoms
@@ -688,10 +597,9 @@ static GLFWbool initExtensions(void)
_glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False);
_glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", 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.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
// These can be set safely even without WM support
@@ -724,8 +632,11 @@ static GLFWbool initExtensions(void)
//
static Cursor createHiddenCursor(void)
{
unsigned char pixels[16 * 16 * 4] = { 0 };
unsigned char pixels[16 * 16 * 4];
GLFWimage image = { 16, 16, pixels };
memset(pixels, 0, sizeof(pixels));
return _glfwCreateCursorX11(&image, 0, 0);
}
@@ -777,7 +688,7 @@ void _glfwReleaseErrorHandlerX11(void)
//
void _glfwInputErrorX11(int error, const char* message)
{
char buffer[_GLFW_MESSAGE_SIZE];
char buffer[8192];
XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode,
buffer, sizeof(buffer));
@@ -791,9 +702,6 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
int i;
Cursor cursor;
if (!_glfw.x11.xcursor.handle)
return None;
XcursorImage* native = XcursorImageCreate(image->width, image->height);
if (native == NULL)
return None;
@@ -828,11 +736,8 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
int _glfwPlatformInit(void)
{
#if !defined(X_HAVE_UTF8_STRING)
// HACK: If the current locale is "C" and the Xlib UTF-8 functions are
// unavailable, apply the environment's locale in the hope that it's
// 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
// HACK: If the current locale is C, apply the environment's locale
// This is done because the C locale breaks wide character input
if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0)
setlocale(LC_CTYPE, "");
#endif
@@ -860,13 +765,12 @@ int _glfwPlatformInit(void)
_glfw.x11.screen = DefaultScreen(_glfw.x11.display);
_glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
_glfw.x11.context = XUniqueContext();
_glfw.x11.helperWindowHandle = createHelperWindow();
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
if (!initExtensions())
return GLFW_FALSE;
_glfw.x11.helperWindowHandle = createHelperWindow();
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
if (XSupportsLocale())
{
XSetLocaleModifiers("");
@@ -882,19 +786,25 @@ int _glfwPlatformInit(void)
}
}
#if defined(__linux__)
if (!_glfwInitThreadLocalStoragePOSIX())
return GLFW_FALSE;
if (!_glfwInitJoysticksLinux())
return GLFW_FALSE;
#endif
_glfwInitTimerPOSIX();
_glfwPollMonitorsX11();
return GLFW_TRUE;
}
void _glfwPlatformTerminate(void)
{
if (_glfw.x11.x11xcb.handle)
{
dlclose(_glfw.x11.x11xcb.handle);
_glfw.x11.x11xcb.handle = NULL;
}
if (_glfw.x11.helperWindowHandle)
{
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
@@ -913,7 +823,6 @@ void _glfwPlatformTerminate(void)
_glfw.x11.hiddenCursorHandle = (Cursor) 0;
}
free(_glfw.x11.primarySelectionString);
free(_glfw.x11.clipboardString);
if (_glfw.x11.im)
@@ -930,37 +839,12 @@ void _glfwPlatformTerminate(void)
_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
// cleanup callbacks that get called by it
_glfwTerminateGLX();
#if defined(__linux__)
_glfwTerminateJoysticksLinux();
#endif
_glfwTerminateThreadLocalStoragePOSIX();
}
const char* _glfwPlatformGetVersionString(void)
@@ -972,7 +856,7 @@ const char* _glfwPlatformGetVersionString(void)
" gettimeofday"
#endif
#if defined(__linux__)
" evdev"
" /dev/js"
#endif
#if defined(_GLFW_BUILD_DLL)
" shared"
+117 -131
View File
@@ -95,126 +95,6 @@ static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi,
////// 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
//
GLFWbool _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
@@ -318,6 +198,119 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
////// 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)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
@@ -430,9 +423,9 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
_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->blue, gamma->blue, size * sizeof(unsigned short));
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
XRRFreeGamma(gamma);
}
@@ -453,18 +446,11 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
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);
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->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);
XRRFreeGamma(gamma);

Some files were not shown because too many files have changed in this diff Show More