mirror of
https://github.com/glfw/glfw.git
synced 2026-09-20 16:30:45 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 70297aeb49 | |||
| 8eb2345347 | |||
| 97b652c584 |
+3
-4
@@ -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 +0,0 @@
|
||||
*.m linguist-language=Objective-C
|
||||
+8
-53
@@ -8,7 +8,7 @@
|
||||
- [Reporting a segfault or other crash bug](#reporting-a-segfault-or-other-crash-bug)
|
||||
- [Reporting a 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
@@ -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:
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# Usage:
|
||||
# cmake -P GenerateMappings.cmake <path/to/mappings.h.in> <path/to/mappings.h>
|
||||
|
||||
set(source_url "https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt")
|
||||
set(source_path "${CMAKE_CURRENT_BINARY_DIR}/gamecontrollerdb.txt")
|
||||
set(template_path "${CMAKE_ARGV3}")
|
||||
set(target_path "${CMAKE_ARGV4}")
|
||||
|
||||
if (NOT EXISTS "${template_path}")
|
||||
message(FATAL_ERROR "Failed to find template file ${template_path}")
|
||||
endif()
|
||||
|
||||
file(DOWNLOAD "${source_url}" "${source_path}"
|
||||
STATUS download_status
|
||||
TLS_VERIFY on)
|
||||
|
||||
list(GET download_status 0 status_code)
|
||||
list(GET download_status 1 status_message)
|
||||
|
||||
if (status_code)
|
||||
message(FATAL_ERROR "Failed to download ${source_url}: ${status_message}")
|
||||
endif()
|
||||
|
||||
file(STRINGS "${source_path}" lines)
|
||||
foreach(line ${lines})
|
||||
if ("${line}" MATCHES "^[0-9a-fA-F].*$")
|
||||
set(GLFW_GAMEPAD_MAPPINGS "${GLFW_GAMEPAD_MAPPINGS}\"${line}\\n\"\n")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
configure_file("${template_path}" "${target_path}" @ONLY NEWLINE_STYLE UNIX)
|
||||
file(REMOVE "${source_path}")
|
||||
|
||||
+27
-24
@@ -1,34 +1,37 @@
|
||||
# FindMir
|
||||
# -------
|
||||
# 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 ()
|
||||
|
||||
@@ -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
@@ -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,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
|
||||
@@ -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
|
||||
|
||||
Vendored
+1
-1
@@ -192,7 +192,7 @@ static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
|
||||
vec3 u = {x, y, z};
|
||||
|
||||
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);
|
||||
|
||||
Vendored
+1036
-2666
File diff suppressed because it is too large
Load Diff
Vendored
+9
-31
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Nuklear - v1.32.0 - public domain
|
||||
* Nuklear - v1.17 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* 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
|
||||
|
||||
Vendored
+1
-1
@@ -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,
|
||||
|
||||
Vendored
+7
-647
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because one or more lines are too long
+1
-27
@@ -76,17 +76,8 @@
|
||||
border:2px solid desaturate(darken(@base-color, 10%), 20%);
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
|
||||
@page metal Metal guide
|
||||
|
||||
@tableofcontents
|
||||
|
||||
*/
|
||||
+2
-2
@@ -195,8 +195,8 @@ glfwSetGammaRamp(monitor, &ramp);
|
||||
The gamma ramp data is copied before the function returns, so there is no need
|
||||
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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
//========================================================================
|
||||
// Simple GLFW+Metal example
|
||||
// Copyright (c) Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
//! [code]
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#import <GLFW/glfw3.h>
|
||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||
#import <GLFW/glfw3native.h>
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <simd/simd.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static void error_callback(int error, const char* description)
|
||||
{
|
||||
fputs(description, stderr);
|
||||
}
|
||||
|
||||
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
|
||||
if (!device)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* window = glfwCreateWindow(640, 480, "Metal Example", NULL, NULL);
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
NSWindow* nswin = glfwGetCocoaWindow(window);
|
||||
CAMetalLayer* layer = [CAMetalLayer layer];
|
||||
layer.device = device;
|
||||
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||
nswin.contentView.layer = layer;
|
||||
nswin.contentView.wantsLayer = YES;
|
||||
|
||||
MTLCompileOptions* compileOptions = [MTLCompileOptions new];
|
||||
compileOptions.languageVersion = MTLLanguageVersion1_1;
|
||||
NSError* compileError;
|
||||
id<MTLLibrary> lib = [device newLibraryWithSource:
|
||||
@"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"vertex float4 v_simple(\n"
|
||||
" constant float4* in [[buffer(0)]],\n"
|
||||
" uint vid [[vertex_id]])\n"
|
||||
"{\n"
|
||||
" return in[vid];\n"
|
||||
"}\n"
|
||||
"fragment float4 f_simple(\n"
|
||||
" float4 in [[stage_in]])\n"
|
||||
"{\n"
|
||||
" return float4(1, 0, 0, 1);\n"
|
||||
"}\n"
|
||||
options:compileOptions error:&compileError];
|
||||
if (!lib)
|
||||
{
|
||||
NSLog(@"can't create library: %@", compileError);
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
id<MTLFunction> vs = [lib newFunctionWithName:@"v_simple"];
|
||||
assert(vs);
|
||||
id<MTLFunction> fs = [lib newFunctionWithName:@"f_simple"];
|
||||
assert(fs);
|
||||
|
||||
id<MTLCommandQueue> cq = [device newCommandQueue];
|
||||
assert(cq);
|
||||
|
||||
MTLRenderPipelineDescriptor* rpd = [MTLRenderPipelineDescriptor new];
|
||||
rpd.vertexFunction = vs;
|
||||
rpd.fragmentFunction = fs;
|
||||
rpd.colorAttachments[0].pixelFormat = layer.pixelFormat;
|
||||
id<MTLRenderPipelineState> rps = [device newRenderPipelineStateWithDescriptor:rpd error:NULL];
|
||||
assert(rps);
|
||||
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
float ratio;
|
||||
int width, height;
|
||||
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
ratio = width / (float) height;
|
||||
|
||||
layer.drawableSize = CGSizeMake(width, height);
|
||||
id<CAMetalDrawable> drawable = [layer nextDrawable];
|
||||
assert(drawable);
|
||||
|
||||
id<MTLCommandBuffer> cb = [cq commandBuffer];
|
||||
|
||||
MTLRenderPassDescriptor* rpd = [MTLRenderPassDescriptor new];
|
||||
MTLRenderPassColorAttachmentDescriptor* cd = rpd.colorAttachments[0];
|
||||
cd.texture = drawable.texture;
|
||||
cd.loadAction = MTLLoadActionClear;
|
||||
cd.clearColor = MTLClearColorMake(1.0, 1.0, 1.0, 1.0);
|
||||
cd.storeAction = MTLStoreActionStore;
|
||||
id<MTLRenderCommandEncoder> rce = [cb renderCommandEncoderWithDescriptor:rpd];
|
||||
|
||||
[rce setRenderPipelineState:rps];
|
||||
[rce setVertexBytes:(vector_float4[]){
|
||||
{ 0, 0, 0, 1 },
|
||||
{ -1, 1, 0, 1 },
|
||||
{ 1, 1, 0, 1 },
|
||||
} length:3 * sizeof(vector_float4) atIndex:0];
|
||||
[rce drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3];
|
||||
|
||||
[rce endEncoding];
|
||||
[cb presentDrawable:drawable];
|
||||
[cb commit];
|
||||
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
|
||||
glfwTerminate();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
//! [code]
|
||||
@@ -87,8 +87,6 @@ int main(void)
|
||||
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
glfwInitHint(GLFW_COCOA_MENUBAR, GLFW_FALSE);
|
||||
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
|
||||
+110
-662
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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_
|
||||
|
||||
@@ -1,284 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 EGLDevice - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <linux/limits.h>
|
||||
|
||||
static GLFWbool initializeExtensions(void)
|
||||
{
|
||||
_glfw.egldevice.QueryDevicesEXT =
|
||||
(PFNEGLQUERYDEVICESEXTPROC)
|
||||
eglGetProcAddress("eglQueryDevicesEXT");
|
||||
_glfw.egldevice.QueryDeviceStringEXT =
|
||||
(PFNEGLQUERYDEVICESTRINGEXTPROC)
|
||||
eglGetProcAddress("eglQueryDeviceStringEXT");
|
||||
_glfw.egldevice.GetPlatformDisplayEXT =
|
||||
(PFNEGLGETPLATFORMDISPLAYEXTPROC)
|
||||
eglGetProcAddress("eglGetPlatformDisplayEXT");
|
||||
_glfw.egldevice.GetOutputLayersEXT =
|
||||
(PFNEGLGETOUTPUTLAYERSEXTPROC)
|
||||
eglGetProcAddress("eglGetOutputLayersEXT");
|
||||
_glfw.egldevice.CreateStreamKHR =
|
||||
(PFNEGLCREATESTREAMKHRPROC)
|
||||
eglGetProcAddress("eglCreateStreamKHR");
|
||||
_glfw.egldevice.DestroyStreamKHR =
|
||||
(PFNEGLDESTROYSTREAMKHRPROC)
|
||||
eglGetProcAddress("eglDestroyStreamKHR");
|
||||
_glfw.egldevice.StreamConsumerOutputEXT =
|
||||
(PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)
|
||||
eglGetProcAddress("eglStreamConsumerOutputEXT");
|
||||
_glfw.egldevice.CreateStreamProducerSurfaceKHR =
|
||||
(PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)
|
||||
eglGetProcAddress("eglCreateStreamProducerSurfaceKHR");
|
||||
|
||||
if(!_glfw.egldevice.QueryDevicesEXT ||
|
||||
!_glfw.egldevice.QueryDeviceStringEXT ||
|
||||
!_glfw.egldevice.GetPlatformDisplayEXT ||
|
||||
!_glfw.egldevice.GetOutputLayersEXT ||
|
||||
!_glfw.egldevice.CreateStreamKHR ||
|
||||
!_glfw.egldevice.DestroyStreamKHR ||
|
||||
!_glfw.egldevice.StreamConsumerOutputEXT ||
|
||||
!_glfw.egldevice.CreateStreamProducerSurfaceKHR)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Failed to find required EGL extension functions");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
static EGLDeviceEXT getEGLDevice(void)
|
||||
{
|
||||
int i, num_devs;
|
||||
EGLDeviceEXT* egl_devs, eglDevice;
|
||||
const char *clientExtensionString;
|
||||
|
||||
eglDevice = EGL_NO_DEVICE_EXT;
|
||||
clientExtensionString = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
if (!_glfwStringInExtensionString("EGL_EXT_device_base",
|
||||
clientExtensionString) &&
|
||||
(!_glfwStringInExtensionString("EGL_EXT_device_enumeration",
|
||||
clientExtensionString) ||
|
||||
!_glfwStringInExtensionString("EGL_EXT_device_query",
|
||||
clientExtensionString)))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: EGL_EXT_device base extensions not found");
|
||||
}
|
||||
|
||||
if (!eglQueryDevicesEXT(0, NULL, &num_devs))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Falied to query EGLDevice");
|
||||
}
|
||||
if (num_devs < 1)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: No devices found");
|
||||
}
|
||||
|
||||
egl_devs = calloc(sizeof(EGLDeviceEXT), num_devs);
|
||||
if (egl_devs == NULL)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Unable to allocate memory for device storage");
|
||||
}
|
||||
|
||||
// Select suitable device
|
||||
if (!eglQueryDevicesEXT(num_devs, egl_devs, &num_devs))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Failed to query EGL devices");
|
||||
}
|
||||
|
||||
for (i = 0; i <= num_devs; i++)
|
||||
{
|
||||
const char* deviceExtensionString;
|
||||
|
||||
deviceExtensionString = eglQueryDeviceStringEXT(egl_devs[i], EGL_EXTENSIONS);
|
||||
if (_glfwStringInExtensionString("EGL_EXT_device_drm",
|
||||
deviceExtensionString))
|
||||
{
|
||||
eglDevice = egl_devs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(egl_devs);
|
||||
|
||||
if (eglDevice == EGL_NO_DEVICE_EXT)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Missing required extension EGL_EXT_device_drm");
|
||||
}
|
||||
return eglDevice;
|
||||
}
|
||||
|
||||
static int getDRMFd(EGLDeviceEXT eglDevice)
|
||||
{
|
||||
int drm_fd;
|
||||
const char* drmName;
|
||||
|
||||
drmName = eglQueryDeviceStringEXT(eglDevice, EGL_DRM_DEVICE_FILE_EXT);
|
||||
if (!drmName || (strnlen(drmName, PATH_MAX) == 0))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Couldn't obtain device file from 0x%p",
|
||||
(void*)(uintptr_t)eglDevice);
|
||||
}
|
||||
|
||||
drm_fd = drmOpen(drmName, NULL);
|
||||
if (drm_fd < 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Couldn't open device file '%s'", drmName);
|
||||
}
|
||||
|
||||
return drm_fd;
|
||||
}
|
||||
|
||||
static GLFWbool initEGLDisplay(EGLDeviceEXT egl_dev, int drm_fd)
|
||||
{
|
||||
const char* displayExtensionString;
|
||||
EGLint displayAttribs[] = {
|
||||
EGL_DRM_MASTER_FD_EXT,
|
||||
drm_fd,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
_glfw.egl.display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT,
|
||||
(void*)egl_dev,
|
||||
displayAttribs);
|
||||
if (_glfw.egl.display == EGL_NO_DISPLAY)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Couldn't obtain EGLDisplay for device");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Failed to initialize EGL");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
// Check for stream_consumer_egloutput + output_drm support
|
||||
displayExtensionString = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
|
||||
if (!_glfwStringInExtensionString("EGL_EXT_output_base",
|
||||
displayExtensionString))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Missing required extension EGL_EXT_output_base");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfwStringInExtensionString("EGL_EXT_output_drm",
|
||||
displayExtensionString))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Missing required extension EGL_EXT_output_drm");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfwStringInExtensionString("EGL_KHR_stream",
|
||||
displayExtensionString))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Missing required extension EGL_KHR_stream");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!_glfwStringInExtensionString("EGL_KHR_stream_producer_eglsurface",
|
||||
displayExtensionString))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Missing required extension EGL_KHR_stream_producer_eglsurface");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
if (!_glfwStringInExtensionString("EGL_EXT_stream_consumer_egloutput",
|
||||
displayExtensionString))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Missing required extension EGL_EXT_stream_consumer_egloutput");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformInit(void)
|
||||
{
|
||||
EGLDeviceEXT egl_dev;
|
||||
int drm_fd;
|
||||
|
||||
// Initialize EGL
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
|
||||
// Initialize global data and extension function pointers
|
||||
if (!initializeExtensions())
|
||||
return GLFW_FALSE;
|
||||
|
||||
// Query and Obtain EGLDevice
|
||||
egl_dev = getEGLDevice();
|
||||
|
||||
// Obtain and open DRM device file
|
||||
drm_fd = getDRMFd(egl_dev);
|
||||
|
||||
// Store for use later
|
||||
_glfw.egldevice.drmFd = drm_fd;
|
||||
|
||||
// Obtain EGLDisplay
|
||||
if (!initEGLDisplay(egl_dev, drm_fd))
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfwInitTimerPOSIX();
|
||||
|
||||
_glfwPollMonitorsEGLDevice();
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
{
|
||||
_glfwTerminateEGL();
|
||||
_glfwTerminateJoysticksLinux();
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
{
|
||||
return _GLFW_VERSION_NUMBER "EGLDevice EGL"
|
||||
#if defined(_GLFW_BUILD_DLL)
|
||||
" shared"
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 EGLDevice - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
static GLFWbool pickConnector(_GLFWmonitor* monitor, int drm_fd, drmModeRes* res_info)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// Getting suitable connector, encoder and crtc
|
||||
for (i = 0; i < res_info->count_connectors; i++)
|
||||
{
|
||||
monitor->egldevice.connId = res_info->connectors[i];
|
||||
|
||||
drmModeConnector* conn_info;
|
||||
|
||||
conn_info =
|
||||
drmModeGetConnector(drm_fd, monitor->egldevice.connId);
|
||||
if (!conn_info)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Unable to obtain info for connector (%d)",
|
||||
monitor->egldevice.connId);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
if (conn_info->connection == DRM_MODE_CONNECTED &&
|
||||
conn_info->count_modes > 0 &&
|
||||
conn_info->count_encoders > 0)
|
||||
{
|
||||
monitor->egldevice.encId = conn_info->encoders[0];
|
||||
|
||||
drmModeEncoder* enc_info;
|
||||
|
||||
enc_info =
|
||||
drmModeGetEncoder(drm_fd, monitor->egldevice.encId);
|
||||
if (!enc_info) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Unable to query DRM-KMS information for connector index %d", i);
|
||||
}
|
||||
|
||||
// Select the modesize
|
||||
monitor->currentMode.width = (int)conn_info->modes[0].hdisplay;
|
||||
monitor->currentMode.height = (int)conn_info->modes[0].vdisplay;
|
||||
monitor->currentMode.refreshRate = (int)conn_info->modes[0].vrefresh;
|
||||
monitor->modeCount = (int)conn_info->count_modes;
|
||||
monitor->name = conn_info->modes[0].name;
|
||||
|
||||
for (j = 0; j < res_info->count_crtcs; j++)
|
||||
{
|
||||
if ((enc_info->possible_crtcs & (1 << j)) == 0)
|
||||
continue;
|
||||
|
||||
monitor->egldevice.crtcId = res_info->crtcs[j];
|
||||
monitor->egldevice.crtcIndex = j;
|
||||
|
||||
if (res_info->crtcs[i] == enc_info->crtc_id)
|
||||
break;
|
||||
}
|
||||
if (monitor->egldevice.crtcId == 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Unable to select suitable CRTC");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
drmModeFreeEncoder(enc_info);
|
||||
}
|
||||
drmModeFreeConnector(conn_info);
|
||||
}
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
static GLFWbool initDRMResources(_GLFWmonitor* monitor, int drm_fd)
|
||||
{
|
||||
drmModeRes* res_info;
|
||||
|
||||
res_info = drmModeGetResources(drm_fd);
|
||||
if (!res_info)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Couldn't obtain DRM-KMS resources");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if(!pickConnector(monitor, drm_fd, res_info))
|
||||
return GLFW_FALSE;
|
||||
|
||||
drmModeFreeResources(res_info);
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////// GLFW platform API //////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPollMonitorsEGLDevice(void)
|
||||
{
|
||||
_GLFWmonitor* monitor = _glfwAllocMonitor("Monitor", 0, 0);
|
||||
|
||||
// Obtain DRM resource info
|
||||
if (!initDRMResources(monitor, _glfw.egldevice.drmFd))
|
||||
{
|
||||
_glfwFreeMonitor(monitor);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_FIRST);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetMonitorPos not implemented");
|
||||
}
|
||||
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetVideoModes not implemented");
|
||||
*found = 0;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetVideoMode not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetGammaRamp not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetGammaRamp not implemented");
|
||||
}
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 EGLDevice - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
#include "posix_time.h"
|
||||
#include "linux_joystick.h"
|
||||
#include "posix_thread.h"
|
||||
#include "egl_context.h"
|
||||
#include "osmesa_context.h"
|
||||
|
||||
#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT) 0)
|
||||
#define EGL_DRM_DEVICE_FILE_EXT 0x3233
|
||||
#define EGL_PLATFORM_DEVICE_EXT 0x313f
|
||||
#define EGL_DRM_MASTER_FD_EXT 0x333c
|
||||
#define EGL_STREAM_FIFO_LENGTH_KHR 0x31fc
|
||||
#define EGL_DRM_CRTC_EXT 0x3234
|
||||
#define EGL_NO_STREAM_KHR ((EGLStreamKHR) 0)
|
||||
#define EGL_STREAM_BIT_KHR 0x0800
|
||||
|
||||
typedef void* EGLOutputLayerEXT;
|
||||
typedef void* EGLStreamKHR;
|
||||
typedef void* EGLDeviceEXT;
|
||||
|
||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLQUERYDEVICESEXTPROC)(EGLint,EGLDeviceEXT*,EGLint*);
|
||||
typedef const char *(EGLAPIENTRY * PFNEGLQUERYDEVICESTRINGEXTPROC)(EGLDeviceEXT,EGLint);
|
||||
typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);
|
||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLGETOUTPUTLAYERSEXTPROC)(EGLDisplay,const EGLAttrib*,EGLOutputLayerEXT*,EGLint,EGLint*);
|
||||
typedef EGLStreamKHR (EGLAPIENTRY * PFNEGLCREATESTREAMKHRPROC)(EGLDisplay,const EGLint*);
|
||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLDESTROYSTREAMKHRPROC)(EGLDisplay,EGLStreamKHR);
|
||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)(EGLDisplay,EGLStreamKHR,EGLOutputLayerEXT);
|
||||
typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay,EGLConfig,EGLStreamKHR,const EGLint*);
|
||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMATTRIBKHRPROC)(EGLDisplay,EGLStreamKHR,EGLenum,EGLint);
|
||||
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC)(EGLDisplay,EGLStreamKHR,const EGLAttrib*);
|
||||
#define eglQueryDevicesEXT _glfw.egldevice.QueryDevicesEXT
|
||||
#define eglQueryDeviceStringEXT _glfw.egldevice.QueryDeviceStringEXT
|
||||
#define eglGetPlatformDisplayEXT _glfw.egldevice.GetPlatformDisplayEXT
|
||||
#define eglGetOutputLayersEXT _glfw.egldevice.GetOutputLayersEXT
|
||||
#define eglCreateStreamKHR _glfw.egldevice.CreateStreamKHR
|
||||
#define eglDestroyStreamKHR _glfw.egldevice.DestroyStreamKHR
|
||||
#define eglStreamConsumerOutputEXT _glfw.egldevice.StreamConsumerOutputEXT
|
||||
#define eglCreateStreamProducerSurfaceKHR _glfw.egldevice.CreateStreamProducerSurfaceKHR
|
||||
#define eglStreamAttribKHR _glfw.egldevice.StreamAttribKHR
|
||||
#define eglStreamConsumerAcquireAttribKHR _glfw.egldevice.StreamConsumerAcquireAttribKHR
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||
|
||||
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType)window->egldevice.handle)
|
||||
|
||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowEGLDevice egldevice
|
||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryEGLDevice egldevice
|
||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorEGLDevice egldevice
|
||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorEGLDevice egldevice
|
||||
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
||||
|
||||
// EGLDevice-specific per-window data
|
||||
//
|
||||
typedef struct _GLFWwindowEGLDevice
|
||||
{
|
||||
int xsurfsize, ysurfsize;
|
||||
int xoffset, yoffset;
|
||||
int fifo;
|
||||
|
||||
uint32_t planeId;
|
||||
|
||||
EGLDisplay handle;
|
||||
EGLOutputLayerEXT eglLayer;
|
||||
EGLStreamKHR eglStream;
|
||||
} _GLFWwindowEGLDevice;
|
||||
|
||||
// EGLDevice-specific global data
|
||||
//
|
||||
typedef struct _GLFWlibraryEGLDevice
|
||||
{
|
||||
int drmFd;
|
||||
|
||||
PFNEGLQUERYDEVICESEXTPROC QueryDevicesEXT;
|
||||
PFNEGLQUERYDEVICESTRINGEXTPROC QueryDeviceStringEXT;
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;
|
||||
PFNEGLGETOUTPUTLAYERSEXTPROC GetOutputLayersEXT;
|
||||
PFNEGLCREATESTREAMKHRPROC CreateStreamKHR;
|
||||
PFNEGLDESTROYSTREAMKHRPROC DestroyStreamKHR;
|
||||
PFNEGLSTREAMCONSUMEROUTPUTEXTPROC StreamConsumerOutputEXT;
|
||||
PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC CreateStreamProducerSurfaceKHR;
|
||||
PFNEGLSTREAMATTRIBKHRPROC StreamAttribKHR;
|
||||
PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC StreamConsumerAcquireAttribKHR;
|
||||
} _GLFWlibraryEGLDevice;
|
||||
|
||||
// EGLDevice-specific per-monitor data
|
||||
//
|
||||
typedef struct _GLFWmonitorEGLDevice
|
||||
{
|
||||
int crtcIndex;
|
||||
uint32_t connId, encId, crtcId;
|
||||
} _GLFWmonitorEGLDevice;
|
||||
|
||||
// EGLDevice-specific per-cursor data
|
||||
//
|
||||
typedef struct _GLFWcursorEGLDevice
|
||||
{
|
||||
} _GLFWcursorEGLDevice;
|
||||
|
||||
void _glfwPollMonitorsEGLDevice(void);
|
||||
|
||||
@@ -1,430 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 EGLDevice - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
//////// GLFW platform API /////////////
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
int n;
|
||||
_GLFWmonitor* monitor;
|
||||
EGLAttrib layerAttribs[] = { EGL_NONE, EGL_NONE, EGL_NONE };
|
||||
EGLint streamAttribs[] = { EGL_STREAM_FIFO_LENGTH_KHR,
|
||||
window->egldevice.fifo, EGL_NONE };
|
||||
EGLint surfaceAttribs[] = { EGL_WIDTH, 0, EGL_HEIGHT, 0, EGL_NONE };
|
||||
|
||||
if (window->monitor)
|
||||
monitor = window->monitor;
|
||||
else
|
||||
monitor = _glfw.monitors[0];
|
||||
|
||||
window->egldevice.xsurfsize = wndconfig->width;
|
||||
window->egldevice.ysurfsize = wndconfig->height;
|
||||
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
|
||||
// Get the layer for this crtc/plane
|
||||
layerAttribs[0] = EGL_DRM_CRTC_EXT;
|
||||
layerAttribs[1] = (EGLAttrib)monitor->egldevice.crtcId;
|
||||
|
||||
if (!eglGetOutputLayersEXT(_glfw.egl.display, layerAttribs,
|
||||
&window->egldevice.eglLayer,
|
||||
1, &n) || !n)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Unable to obtain EGLOutputLayer");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
// Create a stream and connect to the output
|
||||
window->egldevice.eglStream =
|
||||
eglCreateStreamKHR(_glfw.egl.display, streamAttribs);
|
||||
if (window->egldevice.eglStream == EGL_NO_STREAM_KHR)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Unable to create stream (error 0x%x)",
|
||||
eglGetError());
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
if (!eglStreamConsumerOutputEXT(_glfw.egl.display,
|
||||
window->egldevice.eglStream,
|
||||
window->egldevice.eglLayer))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Unable to connect stream (error 0x%x)",
|
||||
eglGetError());
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
// Create a surface to feed the stream
|
||||
surfaceAttribs[1] = window->egldevice.xsurfsize;
|
||||
surfaceAttribs[3] = window->egldevice.ysurfsize;
|
||||
window->context.egl.surface =
|
||||
eglCreateStreamProducerSurfaceKHR(_glfw.egl.display,
|
||||
window->context.egl.config,
|
||||
window->egldevice.eglStream,
|
||||
surfaceAttribs);
|
||||
if (window->context.egl.surface == EGL_NO_SURFACE)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Unable to create rendering surface (error 0x%x)", eglGetError());
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
window->context.destroy(window);
|
||||
|
||||
if (window->egldevice.eglStream != EGL_NO_STREAM_KHR)
|
||||
eglDestroyStreamKHR(_glfw.egl.display, window->egldevice.eglStream);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetWindowTitle is not supported");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||
int count, const GLFWimage* images)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetWindowIcon is not supported");
|
||||
}
|
||||
|
||||
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
||||
{
|
||||
if (xpos)
|
||||
*xpos = window->egldevice.xoffset;
|
||||
if (ypos)
|
||||
*ypos = window->egldevice.yoffset;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
|
||||
{
|
||||
window->egldevice.xoffset = xpos;
|
||||
window->egldevice.yoffset = ypos;
|
||||
|
||||
drmModeRes* res_info;
|
||||
_GLFWmonitor* monitor;
|
||||
|
||||
if (window->monitor)
|
||||
monitor = window->monitor;
|
||||
else
|
||||
monitor = _glfw.monitors[0];
|
||||
|
||||
res_info = drmModeGetResources(_glfw.egldevice.drmFd);
|
||||
if (drmModeSetCrtc(_glfw.egldevice.drmFd,
|
||||
res_info->crtcs[monitor->egldevice.crtcIndex],
|
||||
-1, window->egldevice.xoffset, window->egldevice.yoffset,
|
||||
&res_info->connectors[monitor->egldevice.crtcIndex], 1, NULL))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: Setting window pos failed");
|
||||
}
|
||||
drmModeFreeResources(res_info);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
|
||||
{
|
||||
if (width)
|
||||
*width = window->egldevice.xsurfsize;
|
||||
if (height)
|
||||
*height = window->egldevice.ysurfsize;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetWindowSize not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||
int minwidth, int minheight,
|
||||
int maxwidth, int maxheight)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetWindowSizeLimits not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetWindowAspectRatio not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
|
||||
{
|
||||
_glfwPlatformGetWindowSize(window, width, height);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||
int* left, int* top,
|
||||
int* right, int* bottom)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetWindowFrameSize not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformIconifyWindow not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformRestoreWindow not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformMaximizeWindow not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetWindowResizable not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetWindowDecorated not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetWindowFloating not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformRequestWindowAttention not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformShowWindow(_GLFWwindow* window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformUnhideWindow not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformHideWindow(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformHideWindow not implemented");
|
||||
}
|
||||
|
||||
void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||
_GLFWmonitor* monitor,
|
||||
int xpos, int ypos,
|
||||
int width, int height,
|
||||
int refreshRate)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetWindowMonitor not implemented");
|
||||
}
|
||||
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformWindowFocused not implemented");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformWindowIconified not implemented");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformWindowVisible not implemented");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformWindowMaximized not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
_glfwDetectJoystickConnectionLinux();
|
||||
}
|
||||
|
||||
void _glfwPlatformWaitEvents(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformWaitEvents not supported");
|
||||
}
|
||||
|
||||
void _glfwPlatformWaitEventsTimeout(double timeout)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformWaitEventsTimeout not supported");
|
||||
}
|
||||
|
||||
void _glfwPlatformPostEmptyEvent(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformPostEmptyEvent not supported");
|
||||
}
|
||||
|
||||
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetCursorPos not supported");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetCursorPos not supported");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetCursorMode not supported");
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetKeyName(int key, int scancode)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetKeyName not supported");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||
const GLFWimage* image,
|
||||
int xhot, int yhot)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformCreateCursor not supported");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformCreateStandardCursor not supported");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetCursor not supported");
|
||||
}
|
||||
|
||||
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformSetClipboardString not supported");
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetClipboardString not supported");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetScancodeName not supported");
|
||||
return "";
|
||||
}
|
||||
|
||||
int _glfwPlatformGetKeyScancode(int key)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetKeyScancode not supported");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetRequiredInstanceExtensions not supported");
|
||||
}
|
||||
|
||||
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||
VkPhysicalDevice device,
|
||||
uint32_t queuefamily)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformGetPhysicalDevicePresentationSupport not supported");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||
_GLFWwindow* window,
|
||||
const VkAllocationCallbacks* allocator,
|
||||
VkSurfaceKHR* surface)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGLDevice: _glfwPlatformCreateWindowSurface not supported");
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
@@ -46,8 +46,6 @@
|
||||
#cmakedefine _GLFW_MIR
|
||||
// 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,241 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// As mappings.h.in, this file is used by CMake to produce the mappings.h
|
||||
// header file. If you are adding a GLFW specific gamepad mapping, this is
|
||||
// where to put it.
|
||||
//========================================================================
|
||||
// As mappings.h, this provides all pre-defined gamepad mappings, including
|
||||
// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
|
||||
// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
|
||||
// This file can be re-generated from mappings.h.in and the upstream
|
||||
// gamecontrollerdb.txt with the GenerateMappings.cmake script.
|
||||
//========================================================================
|
||||
|
||||
// All gamepad mappings not labeled GLFW are copied from the
|
||||
// SDL_GameControllerDB project under the following license:
|
||||
//
|
||||
// Simple DirectMedia Layer
|
||||
// Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the
|
||||
// use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
const char* _glfwDefaultMappings =
|
||||
"8f0e1200000000000000504944564944,Acme,platform:Windows,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
|
||||
"341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,\n"
|
||||
"ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,\n"
|
||||
"6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,\n"
|
||||
"0d0f6e00000000000000504944564944,HORIPAD 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
||||
"6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,\n"
|
||||
"88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,\n"
|
||||
"4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,\n"
|
||||
"25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,\n"
|
||||
"4c05c405000000000000504944564944,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows,\n"
|
||||
"4c05cc09000000000000504944564944,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows,\n"
|
||||
"4c05a00b000000000000504944564944,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Windows,\n"
|
||||
"6d0418c2000000000000504944564944,Logitech RumblePad 2 USB,platform:Windows,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
||||
"36280100000000000000504944564944,OUYA Controller,platform:Windows,a:b0,b:b3,y:b2,x:b1,start:b14,guide:b15,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b8,dpleft:b10,dpdown:b9,dpright:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b12,righttrigger:b13,\n"
|
||||
"4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Windows,\n"
|
||||
"00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows,\n"
|
||||
"00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Windows,\n"
|
||||
"28040140000000000000504944564944,GamePad Pro USB,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,\n"
|
||||
"ff113133000000000000504944564944,SVEN X-PAD,platform:Windows,a:b2,b:b3,y:b1,x:b0,start:b5,back:b4,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b8,righttrigger:b9,\n"
|
||||
"8f0e0300000000000000504944564944,Piranha xtreme,platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
|
||||
"8f0e0d31000000000000504944564944,Multilaser JS071 USB,platform:Windows,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
|
||||
"10080300000000000000504944564944,PS2 USB,platform:Windows,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a4,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
|
||||
"79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
||||
"4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,x:b2,y:b3,back:b8,guide:b10,start:b9,leftstick:a0,rightstick:a2,leftshoulder:a3,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:h0.6,lefty:h0.12,rightx:h0.9,righty:h0.4,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
||||
"d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.0,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
||||
"a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,y:b1,x:b0,start:b4,guide:b10,back:b5,leftstick:b8,rightstick:b9,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows,\n"
|
||||
"4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,platform:Windows,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
||||
"6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
|
||||
"83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Windows,\n"
|
||||
"10080100000000000000504944564944,PS1 USB,platform:Windows,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
|
||||
"49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b8,righttrigger:b9,platform:Windows,\n"
|
||||
"4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
||||
"0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
||||
"79004318000000000000504944564944,Mayflash GameCube Controller Adapter,platform:Windows,a:b1,b:b2,x:b0,y:b3,back:b0,start:b9,guide:b0,leftshoulder:b4,rightshoulder:b7,leftstick:b0,rightstick:b0,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
|
||||
"79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
||||
"2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
||||
"300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,x:b0,y:b1,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b5,righttrigger:b7,platform:Windows,\n"
|
||||
"10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,y:b3,x:b4,start:b11,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,platform:Windows,\n"
|
||||
"63252305000000000000504944564944,USB Vibration Joystick (BM),platform:Windows,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
||||
"20380900000000000000504944564944,8Bitdo NES30 PRO Wireless,platform:Windows,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"02200090000000000000504944564944,8Bitdo NES30 PRO USB,platform:Windows,a:b0,b:b1,x:b3,y:b4,leftshoulder:b6,rightshoulder:b7,lefttrigger:b8,righttrigger:b9,back:b10,start:b11,leftstick:b13,rightstick:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"ff113133000000000000504944564944,Gembird JPD-DualForce,platform:Windows,a:b2,b:b3,x:b0,y:b1,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,leftstick:b10,rightstick:b11,\n"
|
||||
"341a0108000000000000504944564944,EXEQ RF USB Gamepad 8206,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,leftstick:b8,rightstick:b7,back:b8,start:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Windows,\n"
|
||||
"c0111352000000000000504944564944,Battalife Joystick,platform:Windows,x:b4,a:b6,b:b7,y:b5,back:b2,start:b3,leftshoulder:b0,rightshoulder:b1,leftx:a0,lefty:a1,\n"
|
||||
"100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,platform:Windows,\n"
|
||||
"79000600000000000000504944564944,NGS Phantom,a:b2,b:b3,y:b1,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Windows,\n"
|
||||
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,\n"
|
||||
"6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,\n"
|
||||
"6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,\n"
|
||||
"6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,\n"
|
||||
"6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,\n"
|
||||
"4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,\n"
|
||||
"4c05000000000000c405000000000000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Mac OS X,\n"
|
||||
"4c05000000000000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Mac OS X,\n"
|
||||
"5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,\n"
|
||||
"891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b8,guide:b10,back:b9,leftstick:b6,rightstick:b7,leftshoulder:b4,rightshoulder:b5,dpup:b11,dpleft:b13,dpdown:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Mac OS X,\n"
|
||||
"4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Mac OS X,\n"
|
||||
"8f0e0000000000000300000000000000,Piranha xtreme,platform:Mac OS X,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
|
||||
"0d0f0000000000004d00000000000000,HORI Gem Pad 3,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
|
||||
"79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,x:b3,y:b0,back:b8,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,\n"
|
||||
"4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,platform:Mac OS X,x:b1,a:b0,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
||||
"AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,\n"
|
||||
"050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,y:b9,x:b10,start:b6,guide:b8,back:b7,dpup:b2,dpleft:b0,dpdown:b3,dpright:b1,leftx:a0,lefty:a1,lefttrigger:b12,righttrigger:,leftshoulder:b11,platform:Mac OS X,\n"
|
||||
"83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X,\n"
|
||||
"bd1200000000000015d0000000000000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Mac OS X,\n"
|
||||
"79000000000000001100000000000000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a3,lefty:a4,platform:Mac OS X,\n"
|
||||
"5e04000000000000dd02000000000000,Xbox One Wired Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"5e04000000000000ea02000000000000,Xbox Wireless Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b9,guide:b10,start:b8,dpleft:b13,dpdown:b12,dpright:b14,dpup:b11,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b6,rightstick:b7,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"5e04000000000000e002000000000000,Xbox Wireless Controller,platform:Mac OS X,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b10,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,x:b18,y:b17,back:b7,guide:b8,start:b6,leftstick:b23,rightstick:b24,leftshoulder:b19,rightshoulder:b20,dpup:b11,dpdown:b12,dpleft:b13,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b21,righttrigger:b22,platform:Mac OS X,\n"
|
||||
"79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,x:b0,y:b12,back:b32,start:b36,leftstick:b40,rightstick:b44,leftshoulder:b16,rightshoulder:b20,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a4,rightx:a8,righty:a12,lefttrigger:b24,righttrigger:b28,platform:Mac OS X,\n"
|
||||
"2509000000000000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,x:b3,y:b2,back:b8,guide:b10,start:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:b11,dpdown:b13,dpleft:b12,dpright:b14,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,\n"
|
||||
"351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X,\n"
|
||||
"b4040000000000000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,x:b3,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X,\n"
|
||||
"81170000000000007e05000000000000,Sega Saturn,x:b0,a:b2,b:b4,y:b6,start:b13,dpleft:b15,dpdown:b16,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,lefttrigger:b10,rightshoulder:b9,righttrigger:a4,righttrigger:b11,leftx:a0,lefty:a2,platform:Mac OS X,\n"
|
||||
"10280000000000000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,x:b4,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Mac OS X,\n"
|
||||
"d814000000000000cecf000000000000,MC Cthulhu,platform:Mac OS X,leftx:,lefty:,rightx:,righty:,lefttrigger:b6,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,righttrigger:b7,\n"
|
||||
"0d0f0000000000006600000000000000,HORIPAD FPS PLUS 4,platform:Mac OS X,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:a4,\n"
|
||||
"0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,\n"
|
||||
"03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,\n"
|
||||
"030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,\n"
|
||||
"030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
||||
"030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,\n"
|
||||
"030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
||||
"030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,\n"
|
||||
"030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
||||
"030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,\n"
|
||||
"030000004c050000c405000011010000,Sony DualShock 4,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
|
||||
"050000004c050000c405000000010000,Sony DualShock 4 BT,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,\n"
|
||||
"030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
|
||||
"050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
|
||||
"030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b13,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,\n"
|
||||
"030000006f0e00003001000001010000,EA Sports PS3 Controller,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
|
||||
"03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
||||
"030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
||||
"030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
||||
"030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,\n"
|
||||
"03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,y:b0,x:b3,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux,\n"
|
||||
"03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,y:b3,x:b0,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a4,lefttrigger:b6,righttrigger:b7,platform:Linux,\n"
|
||||
"030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,y:b3,x:b1,start:b9,guide:,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Linux,\n"
|
||||
"030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a5,\n"
|
||||
"030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick ,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
|
||||
"030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick ,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b5,rightshoulder:b6,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a2,\n"
|
||||
"030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,\n"
|
||||
"030000006d04000016c2000010010000,Logitech Logitech Dual Action,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
||||
"03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,y:b3,x:b1,start:b7,leftshoulder:,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,rightstick:,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Linux,\n"
|
||||
"030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,y:b4,x:b3,start:b8,guide:b5,back:b2,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:b9,righttrigger:b10,platform:Linux,\n"
|
||||
"030000006d04000018c2000010010000,Logitech Logitech RumblePad 2 USB,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
||||
"05000000d6200000ad0d000001000000,Moga Pro,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b6,leftstick:b7,rightstick:b8,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a5,righttrigger:a4,\n"
|
||||
"030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,platform:Linux,a:b1,b:b2,x:b0,y:b3,start:b9,guide:b12,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
|
||||
"030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,platform:Linux,a:b1,b:b2,x:b0,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:b6,righttrigger:b7,\n"
|
||||
"0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Linux,\n"
|
||||
"0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,x:b0,y:b4,back:b2,start:b3,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,platform:Linux,\n"
|
||||
"030000006f0e00001f01000000010000,Generic X-Box pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"03000000280400000140000000010000,Gravis GamePad Pro USB ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftx:a0,lefty:a1,\n"
|
||||
"030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"030000005e0400008502000000010000,Microsoft X-Box pad (Japan),platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b6,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:a2,rightshoulder:b2,righttrigger:a5,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,platform:Linux,a:b1,b:b2,x:b0,y:b3,back:b8,start:b9,guide:b12,leftshoulder:b4,rightshoulder:b5,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
|
||||
"03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,platform:Linux,a:b2,b:b1,y:b0,x:b3,start:b8,back:b9,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,\n"
|
||||
"030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b11,dpdown:b14,dpright:b12,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,\n"
|
||||
"030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,y:b3,x:b1,start:b10,guide:b8,back:b9,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,platform:Linux,\n"
|
||||
"03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Linux,\n"
|
||||
"060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux,\n"
|
||||
"050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,y:b12,x:b15,start:b3,guide:b16,back:b0,leftstick:b1,rightstick:b2,leftshoulder:b10,rightshoulder:b11,dpup:b4,dpleft:b7,dpdown:b6,dpright:b5,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b8,righttrigger:b9,platform:Linux,\n"
|
||||
"03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick ,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a3,rightx:a1,righty:a4,\n"
|
||||
"03000000666600000488000000010000,Super Joy Box 5 Pro,platform:Linux,a:b2,b:b1,x:b3,y:b0,back:b9,start:b8,leftshoulder:b6,rightshoulder:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b4,righttrigger:b5,dpup:b12,dpleft:b15,dpdown:b14,dpright:b13,\n"
|
||||
"05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,\n"
|
||||
"05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,platform:Linux,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,\n"
|
||||
"030000008916000001fd000024010000,Razer Onza Classic Edition,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:b11,dpdown:b14,dpright:b12,dpup:b13,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"030000005e040000d102000001010000,Microsoft X-Box One pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"030000005e040000dd02000003020000,Microsoft X-Box One pad v2,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux,\n"
|
||||
"03000000790000001100000010010000,RetroLink Saturn Classic Controller,platform:Linux,x:b3,a:b0,b:b1,y:b4,back:b5,guide:b2,start:b8,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,\n"
|
||||
"050000007e0500003003000001000000,Nintendo Wii U Pro Controller,platform:Linux,a:b0,b:b1,x:b3,y:b2,back:b8,start:b9,guide:b10,leftshoulder:b4,rightshoulder:b5,leftstick:b11,rightstick:b12,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,\n"
|
||||
"030000005e0400008e02000004010000,Microsoft X-Box 360 pad,platform:Linux,a:b0,b:b1,x:b2,y:b3,back:b6,start:b7,guide:b8,leftshoulder:b4,rightshoulder:b5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,\n"
|
||||
"030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,\n"
|
||||
"030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7\n"
|
||||
"03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
||||
"0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b7,back:b6,guide:b8,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftshoulder:b4,rightshoulder:b5,lefttrigger:a5,righttrigger:a4,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
||||
"03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,\n"
|
||||
"030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"030000006f0e00001304000000010000,Generic X-Box pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:a0,rightstick:a3,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,start:b9,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,x:b3,y:b2,back:b6,start:b7,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux,\n"
|
||||
"03000000bd12000015d0000010010000,Tomee SNES USB Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux,\n"
|
||||
"03000000790000001100000010010000,Retrolink Classic Controller,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,platform:Linux,\n"
|
||||
"03000000c9110000f055000011010000,HJC Game GAMEPAD,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b2,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:h0.2,righttrigger:b7,b:b1,platform:Linux,\n"
|
||||
"03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,platform:Linux,\n"
|
||||
"03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,y:b3,x:b0,start:b9,guide:,back:,leftstick:,rightstick:,leftshoulder:,dpleft:b15,dpdown:b14,dpright:b13,leftx:a0,lefty:a1,rightx:a5,righty:a2,lefttrigger:a3,righttrigger:a4,rightshoulder:b7,dpup:b12,platform:Linux,\n"
|
||||
"030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,platform:Linux,x:b0,a:b2,b:b3,y:b1,back:b10,guide:b12,start:b11,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
||||
"030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,platform:Linux,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,guide:b8,leftstick:b9,rightstick:b10,lefttrigger:a2,righttrigger:a5,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,platform:Linux,\n"
|
||||
"030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,platform:Linux,a:b0,b:b2,x:b1,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b6,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b5,righttrigger:b7,\n"
|
||||
"05000000102800000900000000010000,8Bitdo SFC30 GamePad,platform:Linux,x:b4,a:b1,b:b0,y:b3,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,\n"
|
||||
"03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,platform:Linux,a:b1,b:b2,y:b3,x:b0,start:b12,guide:b9,back:b8,leftshoulder:b4,rightshoulder:b5,lefttrigger:b6,righttrigger:b7,leftx:a0,lefty:a1,\n"
|
||||
"030000000d0f00000d00000000010000,hori,platform:Linux,a:b0,b:b6,y:b2,x:b1,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,start:b9,guide:b10,back:b8,leftshoulder:b3,rightshoulder:b7,leftx:b4,lefty:b5,\n"
|
||||
"03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,\n"
|
||||
"03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,platform:Linux,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,leftx:a0,lefty:a1,lefttrigger:b6,righttrigger:b7,\n"
|
||||
"03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),platform:Linux,a:b3,b:b4,y:b1,x:b0,start:b7,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,\n"
|
||||
"05000000010000000100000003000000,Nintendo Wiimote,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b9,guide:b10,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,\n"
|
||||
"030000005e0400008e02000062230000,Microsoft X-Box 360 pad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,y:b1,x:b0,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b6,righttrigger:b7,platform:Linux,\n"
|
||||
"030000006f0e00000103000000020000,Logic3 Controller,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.0,dpdown:h0.4,dpright:h0.0,dpright:h0.2,dpup:h0.0,dpup:h0.1,leftshoulder:h0.0,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"05000000380700006652000025010000,Mad Catz C.T.R.L.R ,platform:Linux,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,\n"
|
||||
"030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,platform:Linux,x:b2,a:b0,b:b1,y:b3,back:b6,guide:b8,start:b7,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,leftstick:b9,rightstick:b10,leftx:a0,lefty:a1,rightx:a3,righty:a4,\n"
|
||||
"03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,platform:Linux,a:b0,b:b1,y:b3,x:b2,start:b7,guide:b8,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,lefttrigger:a2,righttrigger:a5,\n"
|
||||
"05000000a00500003232000001000000,8Bitdo Zero GamePad,platform:Linux,a:b0,b:b1,x:b3,y:b4,back:b10,start:b11,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,\n"
|
||||
"030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b0,b:b1,back:b8,start:b9,rightx:a2,righty:a3,leftx:a0,lefty:a1,platform:Linux,\n"
|
||||
"03000000100800000300000010010000,USB Gamepad,platform:Linux,a:b2,b:b1,x:b3,y:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
|
||||
"05000000ac0500003232000001000000,VR-BOX,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
|
||||
"03000000780000000600000010010000,Microntek USB Joystick,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1,\n"
|
||||
|
||||
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n";
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// As mappings.h.in, this file is used by CMake to produce the mappings.h
|
||||
// header file. If you are adding a GLFW specific gamepad mapping, this is
|
||||
// where to put it.
|
||||
//========================================================================
|
||||
// As mappings.h, this provides all pre-defined gamepad mappings, including
|
||||
// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
|
||||
// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
|
||||
// This file can be re-generated from mappings.h.in and the upstream
|
||||
// gamecontrollerdb.txt with the GenerateMappings.cmake script.
|
||||
//========================================================================
|
||||
|
||||
// All gamepad mappings not labeled GLFW are copied from the
|
||||
// SDL_GameControllerDB project under the following license:
|
||||
//
|
||||
// Simple DirectMedia Layer
|
||||
// Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the
|
||||
// use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
const char* _glfwDefaultMappings =
|
||||
@GLFW_GAMEPAD_MAPPINGS@
|
||||
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
|
||||
"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n";
|
||||
|
||||
+12
-4
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Mir - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// 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
@@ -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
@@ -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
@@ -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, ®ion);
|
||||
|
||||
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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#define _GLFW_PLATFORM_JOYSTICK_STATE int nulljs
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs
|
||||
|
||||
#define _GLFW_PLATFORM_MAPPING_NAME ""
|
||||
|
||||
+16
-19
@@ -36,26 +36,25 @@ static void makeContextCurrentOSMesa(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
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
@@ -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_
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
@@ -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_
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
|
||||
{
|
||||
assert(tls->posix.allocated == GLFW_FALSE);
|
||||
|
||||
if (pthread_key_create(&tls->posix.key, NULL) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"POSIX: Failed to create context TLS");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
tls->posix.allocated = GLFW_TRUE;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
||||
{
|
||||
if (tls->posix.allocated)
|
||||
pthread_key_delete(tls->posix.key);
|
||||
memset(tls, 0, sizeof(_GLFWtls));
|
||||
}
|
||||
|
||||
void* _glfwPlatformGetTls(_GLFWtls* tls)
|
||||
{
|
||||
assert(tls->posix.allocated == GLFW_TRUE);
|
||||
return pthread_getspecific(tls->posix.key);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
|
||||
{
|
||||
assert(tls->posix.allocated == GLFW_TRUE);
|
||||
pthread_setspecific(tls->posix.key, value);
|
||||
}
|
||||
|
||||
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->posix.allocated == GLFW_FALSE);
|
||||
|
||||
if (pthread_mutex_init(&mutex->posix.handle, NULL) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "POSIX: Failed to create mutex");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
return mutex->posix.allocated = GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
if (mutex->posix.allocated)
|
||||
pthread_mutex_destroy(&mutex->posix.handle);
|
||||
memset(mutex, 0, sizeof(_GLFWmutex));
|
||||
}
|
||||
|
||||
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->posix.allocated == GLFW_TRUE);
|
||||
pthread_mutex_lock(&mutex->posix.handle);
|
||||
}
|
||||
|
||||
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->posix.allocated == GLFW_TRUE);
|
||||
pthread_mutex_unlock(&mutex->posix.handle);
|
||||
}
|
||||
|
||||
+6
-6
@@ -44,14 +44,14 @@ void _glfwInitTimerPOSIX(void)
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||
{
|
||||
_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
@@ -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_
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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, ¤t);
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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, ®istryListener, 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user