mirror of
https://github.com/glfw/glfw.git
synced 2025-10-05 06:06:36 +00:00
Merge branch 'master' into android
This commit is contained in:
commit
9b9cfc1914
33
CMake/GenerateMappings.cmake
Normal file
33
CMake/GenerateMappings.cmake
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# 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}")
|
||||||
|
|
17
README.md
17
README.md
@ -45,8 +45,8 @@ guide](http://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
|
|||||||
## Compiling GLFW
|
## Compiling GLFW
|
||||||
|
|
||||||
GLFW itself requires only the headers and libraries for your window system. It
|
GLFW itself requires only the headers and libraries for your window system. It
|
||||||
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
|
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL,
|
||||||
rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
|
OSMesa) 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
|
GLFW supports compilation on Windows with Visual C++ 2010 and later, MinGW and
|
||||||
MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC
|
MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC
|
||||||
@ -150,6 +150,8 @@ information on what to include when reporting a bug.
|
|||||||
functions for accessing X11 primary selection (#894,#1056)
|
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 (#850)
|
||||||
- Added definition of `GLAPIENTRY` to public header
|
- Added definition of `GLAPIENTRY` to public header
|
||||||
|
- Added `GLFW_TRANSPARENT` window hint for enabling window framebuffer
|
||||||
|
transparency (#197,#663,#715,#723,#1078)
|
||||||
- Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering
|
- Added `GLFW_CENTER_CURSOR` window hint for controlling cursor centering
|
||||||
(#749,#842)
|
(#749,#842)
|
||||||
- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
|
- Added `GLFW_JOYSTICK_HAT_BUTTONS` init hint (#889)
|
||||||
@ -163,6 +165,7 @@ information on what to include when reporting a bug.
|
|||||||
- Added `GLFW_INCLUDE_ES32` for including the OpenGL ES 3.2 header
|
- Added `GLFW_INCLUDE_ES32` for including the OpenGL ES 3.2 header
|
||||||
- Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with
|
- Added `GLFW_OSMESA_CONTEXT_API` for creating OpenGL contexts with
|
||||||
[OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
|
[OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
|
||||||
|
- Added `GenerateMappings.cmake` script for updating gamepad mappings
|
||||||
- Removed `GLFW_USE_RETINA` compile-time option
|
- Removed `GLFW_USE_RETINA` compile-time option
|
||||||
- Removed `GLFW_USE_CHDIR` compile-time option
|
- Removed `GLFW_USE_CHDIR` compile-time option
|
||||||
- Removed `GLFW_USE_MENUBAR` compile-time option
|
- Removed `GLFW_USE_MENUBAR` compile-time option
|
||||||
@ -173,6 +176,7 @@ information on what to include when reporting a bug.
|
|||||||
`vkGetInstanceProcAddr` when `_GLFW_VULKAN_STATIC` was enabled
|
`vkGetInstanceProcAddr` when `_GLFW_VULKAN_STATIC` was enabled
|
||||||
- Bugfix: Invalid library paths were used in test and example CMake files (#930)
|
- Bugfix: Invalid library paths were used in test and example CMake files (#930)
|
||||||
- Bugfix: The scancode for synthetic key release events was always zero
|
- Bugfix: The scancode for synthetic key release events was always zero
|
||||||
|
- Bugfix: The generated Doxyfile did not handle paths with spaces (#1081)
|
||||||
- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
|
- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
|
||||||
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
|
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
|
||||||
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
|
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
|
||||||
@ -193,6 +197,7 @@ information on what to include when reporting a bug.
|
|||||||
- [Win32] Bugfix: `glfw3native.h` would undefine a foreign `APIENTRY` (#1062)
|
- [Win32] Bugfix: `glfw3native.h` would undefine a foreign `APIENTRY` (#1062)
|
||||||
- [Win32] Bugfix: Disabled cursor mode prevented use of caption buttons
|
- [Win32] Bugfix: Disabled cursor mode prevented use of caption buttons
|
||||||
(#650,#1071)
|
(#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] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
|
||||||
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
|
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
|
||||||
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
|
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
|
||||||
@ -203,6 +208,9 @@ information on what to include when reporting a bug.
|
|||||||
- [X11] Bugfix: IM-duplicated key events would leak at low polling rates (#747)
|
- [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: Gamma ramp setting via RandR did not validate ramp size
|
||||||
- [X11] Bugfix: Key name string encoding depended on current locale (#981,#983)
|
- [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] Moved to evdev for joystick input (#906,#1005)
|
- [Linux] Moved to evdev for joystick input (#906,#1005)
|
||||||
- [Linux] Bugfix: Event processing did not detect joystick disconnection (#932)
|
- [Linux] Bugfix: Event processing did not detect joystick disconnection (#932)
|
||||||
- [Linux] Bugfix: The joystick device path could be truncated (#1025)
|
- [Linux] Bugfix: The joystick device path could be truncated (#1025)
|
||||||
@ -229,6 +237,7 @@ information on what to include when reporting a bug.
|
|||||||
- [Cocoa] Bugfix: A hidden or disabled cursor would become visible when a user
|
- [Cocoa] Bugfix: A hidden or disabled cursor would become visible when a user
|
||||||
notification was shown (#971,#1028)
|
notification was shown (#971,#1028)
|
||||||
- [Cocoa] Bugfix: Some characters did not repeat due to Press and Hold (#1010)
|
- [Cocoa] Bugfix: Some characters did not repeat due to Press and Hold (#1010)
|
||||||
|
- [Cocoa] Bugfix: Window title was lost when full screen or undecorated (#1082)
|
||||||
- [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts
|
- [WGL] Added support for `WGL_EXT_colorspace` for OpenGL ES contexts
|
||||||
- [WGL] Added support for `WGL_ARB_create_context_no_error`
|
- [WGL] Added support for `WGL_ARB_create_context_no_error`
|
||||||
- [GLX] Added support for `GLX_ARB_create_context_no_error`
|
- [GLX] Added support for `GLX_ARB_create_context_no_error`
|
||||||
@ -283,6 +292,7 @@ skills.
|
|||||||
- Yaron Cohen-Tal
|
- Yaron Cohen-Tal
|
||||||
- Omar Cornut
|
- Omar Cornut
|
||||||
- Andrew Corrigan
|
- Andrew Corrigan
|
||||||
|
- Bailey Cosier
|
||||||
- Noel Cower
|
- Noel Cower
|
||||||
- Jason Daly
|
- Jason Daly
|
||||||
- Jarrod Davis
|
- Jarrod Davis
|
||||||
@ -291,6 +301,7 @@ skills.
|
|||||||
- Michael Dickens
|
- Michael Dickens
|
||||||
- Роман Донченко
|
- Роман Донченко
|
||||||
- Mario Dorn
|
- Mario Dorn
|
||||||
|
- Wolfgang Draxinger
|
||||||
- Jonathan Dummer
|
- Jonathan Dummer
|
||||||
- Ralph Eastwood
|
- Ralph Eastwood
|
||||||
- Fredrik Ehnbom
|
- Fredrik Ehnbom
|
||||||
@ -316,6 +327,7 @@ skills.
|
|||||||
- Erik S. V. Jansson
|
- Erik S. V. Jansson
|
||||||
- Toni Jovanoski
|
- Toni Jovanoski
|
||||||
- Arseny Kapoulkine
|
- Arseny Kapoulkine
|
||||||
|
- Cem Karan
|
||||||
- Osman Keskin
|
- Osman Keskin
|
||||||
- Josh Kilmer
|
- Josh Kilmer
|
||||||
- Cameron King
|
- Cameron King
|
||||||
@ -357,6 +369,7 @@ skills.
|
|||||||
- Andri Pálsson
|
- Andri Pálsson
|
||||||
- Peoro
|
- Peoro
|
||||||
- Braden Pellett
|
- Braden Pellett
|
||||||
|
- Christopher Pelloux
|
||||||
- Arturo J. Pérez
|
- Arturo J. Pérez
|
||||||
- Anthony Pesch
|
- Anthony Pesch
|
||||||
- Orson Peters
|
- Orson Peters
|
||||||
|
@ -23,7 +23,7 @@ if (GLFW_DOCUMENT_INTERNALS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
foreach(arg ${glfw_DOCS_SOURCES})
|
foreach(arg ${glfw_DOCS_SOURCES})
|
||||||
set(GLFW_DOCS_SOURCES "${GLFW_DOCS_SOURCES} ${arg}")
|
set(GLFW_DOCS_SOURCES "${GLFW_DOCS_SOURCES} \\\n\"${arg}\"")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
configure_file(Doxyfile.in Doxyfile @ONLY)
|
configure_file(Doxyfile.in Doxyfile @ONLY)
|
||||||
|
@ -52,7 +52,7 @@ PROJECT_LOGO =
|
|||||||
# If a relative path is entered, it will be relative to the location
|
# If a relative path is entered, it will be relative to the location
|
||||||
# where doxygen was started. If left blank the current directory will be used.
|
# where doxygen was started. If left blank the current directory will be used.
|
||||||
|
|
||||||
OUTPUT_DIRECTORY = @GLFW_BINARY_DIR@/docs
|
OUTPUT_DIRECTORY = "@GLFW_BINARY_DIR@/docs"
|
||||||
|
|
||||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
||||||
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
||||||
@ -651,7 +651,7 @@ WARN_FORMAT = "$file:$line: $text"
|
|||||||
# and error messages should be written. If left blank the output is written
|
# and error messages should be written. If left blank the output is written
|
||||||
# to stderr.
|
# to stderr.
|
||||||
|
|
||||||
WARN_LOGFILE = @GLFW_BINARY_DIR@/docs/warnings.txt
|
WARN_LOGFILE = "@GLFW_BINARY_DIR@/docs/warnings.txt"
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# configuration options related to the input files
|
# configuration options related to the input files
|
||||||
@ -722,7 +722,7 @@ EXCLUDE_SYMBOLS = APIENTRY GLFWAPI
|
|||||||
# directories that contain example code fragments that are included (see
|
# directories that contain example code fragments that are included (see
|
||||||
# the \include command).
|
# the \include command).
|
||||||
|
|
||||||
EXAMPLE_PATH = @GLFW_SOURCE_DIR@/examples
|
EXAMPLE_PATH = "@GLFW_SOURCE_DIR@/examples"
|
||||||
|
|
||||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||||
@ -898,13 +898,13 @@ HTML_FILE_EXTENSION = .html
|
|||||||
# have to redo this when upgrading to a newer version of doxygen or when
|
# have to redo this when upgrading to a newer version of doxygen or when
|
||||||
# changing the value of configuration settings such as GENERATE_TREEVIEW!
|
# changing the value of configuration settings such as GENERATE_TREEVIEW!
|
||||||
|
|
||||||
HTML_HEADER = @GLFW_SOURCE_DIR@/docs/header.html
|
HTML_HEADER = "@GLFW_SOURCE_DIR@/docs/header.html"
|
||||||
|
|
||||||
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
|
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
|
||||||
# each generated HTML page. If it is left blank doxygen will generate a
|
# each generated HTML page. If it is left blank doxygen will generate a
|
||||||
# standard footer.
|
# standard footer.
|
||||||
|
|
||||||
HTML_FOOTER = @GLFW_SOURCE_DIR@/docs/footer.html
|
HTML_FOOTER = "@GLFW_SOURCE_DIR@/docs/footer.html"
|
||||||
|
|
||||||
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
|
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
|
||||||
# style sheet that is used by each HTML page. It can be used to
|
# style sheet that is used by each HTML page. It can be used to
|
||||||
@ -923,7 +923,7 @@ HTML_STYLESHEET =
|
|||||||
# robust against future updates. Doxygen will copy the style sheet file to
|
# robust against future updates. Doxygen will copy the style sheet file to
|
||||||
# the output directory.
|
# the output directory.
|
||||||
|
|
||||||
HTML_EXTRA_STYLESHEET = @GLFW_SOURCE_DIR@/docs/extra.css
|
HTML_EXTRA_STYLESHEET = "@GLFW_SOURCE_DIR@/docs/extra.css"
|
||||||
|
|
||||||
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||||
# other source files which should be copied to the HTML output directory. Note
|
# other source files which should be copied to the HTML output directory. Note
|
||||||
@ -932,7 +932,7 @@ HTML_EXTRA_STYLESHEET = @GLFW_SOURCE_DIR@/docs/extra.css
|
|||||||
# files. In the HTML_STYLESHEET file, use the file name only. Also note that
|
# files. In the HTML_STYLESHEET file, use the file name only. Also note that
|
||||||
# the files will be copied as-is; there are no commands or markers available.
|
# the files will be copied as-is; there are no commands or markers available.
|
||||||
|
|
||||||
HTML_EXTRA_FILES = @GLFW_SOURCE_DIR@/docs/spaces.svg
|
HTML_EXTRA_FILES = "@GLFW_SOURCE_DIR@/docs/spaces.svg"
|
||||||
|
|
||||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
|
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
|
||||||
# Doxygen will adjust the colors in the style sheet and background images
|
# Doxygen will adjust the colors in the style sheet and background images
|
||||||
|
@ -80,6 +80,11 @@ 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
|
when the cursor is disabled. If the running X server does not support this
|
||||||
extension, regular accelerated mouse motion will be used.
|
extension, regular accelerated mouse motion will be used.
|
||||||
|
|
||||||
|
GLFW uses both the XRender extension and the compositing manager to support
|
||||||
|
transparent window framebuffers. If the running X server does not support this
|
||||||
|
extension or there is no running compositing manager, the `GLFW_TRANSPARENT`
|
||||||
|
framebuffer hint will have no effect.
|
||||||
|
|
||||||
|
|
||||||
@section compat_glx GLX extensions
|
@section compat_glx GLX extensions
|
||||||
|
|
||||||
|
@ -265,6 +265,12 @@ If you are linking the Vulkan loader statically into your application then you
|
|||||||
must also define @b _GLFW_VULKAN_STATIC. Otherwise, GLFW will attempt to use the
|
must also define @b _GLFW_VULKAN_STATIC. Otherwise, GLFW will attempt to use the
|
||||||
external version.
|
external version.
|
||||||
|
|
||||||
|
If you are using a custom name for the Vulkan, EGL, GLX, OSMesa, OpenGL, GLESv1
|
||||||
|
or GLESv2 library, you can override the default names by defining those you need
|
||||||
|
of @b _GLFW_VULKAN_LIBRARY, @b _GLFW_EGL_LIBRARY, @b _GLFW_GLX_LIBRARY, @b
|
||||||
|
_GLFW_OSMESA_LIBRARY, @b _GLFW_OPENGL_LIBRARY, @b _GLFW_GLESV1_LIBRARY and @b
|
||||||
|
_GLFW_GLESV2_LIBRARY. Otherwise, GLFW will use the built-in default names.
|
||||||
|
|
||||||
For the EGL context creation API, the following options are available:
|
For the EGL context creation API, the following options are available:
|
||||||
|
|
||||||
- @b _GLFW_USE_EGLPLATFORM_H to use `EGL/eglplatform.h` for native handle
|
- @b _GLFW_USE_EGLPLATFORM_H to use `EGL/eglplatform.h` for native handle
|
||||||
|
@ -25,7 +25,6 @@ $extrastylesheet
|
|||||||
<ul class="glfwnavbar">
|
<ul class="glfwnavbar">
|
||||||
<li><a href="http://www.glfw.org/documentation.html">Documentation</a></li>
|
<li><a href="http://www.glfw.org/documentation.html">Documentation</a></li>
|
||||||
<li><a href="http://www.glfw.org/download.html">Download</a></li>
|
<li><a href="http://www.glfw.org/download.html">Download</a></li>
|
||||||
<li><a href="http://www.glfw.org/media.html">Media</a></li>
|
|
||||||
<li><a href="http://www.glfw.org/community.html">Community</a></li>
|
<li><a href="http://www.glfw.org/community.html">Community</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -82,6 +82,9 @@ 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
|
will only affect their specific platform. Other platforms will simply ignore
|
||||||
them. Setting these hints requires no platform specific headers or functions.
|
them. Setting these hints requires no platform specific headers or functions.
|
||||||
|
|
||||||
|
|
||||||
|
@subsubsection init_hints_shared Shared init hints
|
||||||
|
|
||||||
@anchor GLFW_JOYSTICK_HAT_BUTTONS
|
@anchor GLFW_JOYSTICK_HAT_BUTTONS
|
||||||
__GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
|
__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
|
buttons, for compatibility with earlier versions of GLFW that did not have @ref
|
||||||
@ -299,35 +302,39 @@ functions not on this list will not be made non-reentrant.
|
|||||||
|
|
||||||
@subsection thread_safety Thread safety
|
@subsection thread_safety Thread safety
|
||||||
|
|
||||||
Most GLFW functions must only be called from the main thread, but some may be
|
Most GLFW functions must only be called from the main thread (the thread that
|
||||||
called from any thread. However, no GLFW function may be called from any thread
|
calls main), but some may be called from any thread once the library has been
|
||||||
but the main thread until GLFW has been successfully initialized, including
|
initialized. Before initialization the whole library is thread-unsafe.
|
||||||
functions that may called before initialization.
|
|
||||||
|
|
||||||
The reference documentation for every GLFW function states whether it is limited
|
The reference documentation for every GLFW function states whether it is limited
|
||||||
to the main thread.
|
to the main thread.
|
||||||
|
|
||||||
Initialization and termination, event processing and the creation and
|
Initialization, termination, event processing and the creation and
|
||||||
destruction of windows, contexts and cursors are all limited to the main thread
|
destruction of windows, cursors and OpenGL and OpenGL ES contexts are all
|
||||||
due to limitations of one or several platforms.
|
restricted to the main thread due to limitations of one or several platforms.
|
||||||
|
|
||||||
Because event processing must be performed on the main thread, all callbacks
|
Because event processing must be performed on the main thread, all callbacks
|
||||||
except for the error callback will only be called on that thread. The error
|
except for the error callback will only be called on that thread. The error
|
||||||
callback may be called on any thread, as any GLFW function may generate errors.
|
callback may be called on any thread, as any GLFW function may generate errors.
|
||||||
|
|
||||||
The posting of empty events may be done from any thread. The window user
|
The error code and description may be queried from any thread.
|
||||||
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
|
- @ref glfwGetError
|
||||||
be called from any thread:
|
|
||||||
|
Empty events may be posted from any thread.
|
||||||
|
|
||||||
- @ref glfwPostEmptyEvent
|
- @ref glfwPostEmptyEvent
|
||||||
|
|
||||||
|
The window user pointer and close flag may be read and written from any thread,
|
||||||
|
but this is not synchronized by GLFW.
|
||||||
|
|
||||||
- @ref glfwGetWindowUserPointer
|
- @ref glfwGetWindowUserPointer
|
||||||
- @ref glfwSetWindowUserPointer
|
- @ref glfwSetWindowUserPointer
|
||||||
- @ref glfwWindowShouldClose
|
- @ref glfwWindowShouldClose
|
||||||
- @ref glfwSetWindowShouldClose
|
- @ref glfwSetWindowShouldClose
|
||||||
|
|
||||||
Rendering may be done on any thread. The following context related functions
|
These functions for working with OpenGL and OpenGL ES contexts may be called
|
||||||
may be called from any thread:
|
from any thread, but the window object is not synchronized by GLFW.
|
||||||
|
|
||||||
- @ref glfwMakeContextCurrent
|
- @ref glfwMakeContextCurrent
|
||||||
- @ref glfwGetCurrentContext
|
- @ref glfwGetCurrentContext
|
||||||
@ -336,27 +343,23 @@ may be called from any thread:
|
|||||||
- @ref glfwExtensionSupported
|
- @ref glfwExtensionSupported
|
||||||
- @ref glfwGetProcAddress
|
- @ref glfwGetProcAddress
|
||||||
|
|
||||||
The raw timer may be queried from any thread. The following raw timer related
|
The raw timer functions may be called from any thread.
|
||||||
functions may be called from any thread:
|
|
||||||
|
|
||||||
- @ref glfwGetTimerFrequency
|
- @ref glfwGetTimerFrequency
|
||||||
- @ref glfwGetTimerValue
|
- @ref glfwGetTimerValue
|
||||||
|
|
||||||
The regular timer may be used from any thread, but the reading and writing of
|
The regular timer may be used from any thread, but reading and writing the timer
|
||||||
the timer offset is not synchronized by GLFW. The following timer related
|
offset is not synchronized by GLFW.
|
||||||
functions may be called from any thread:
|
|
||||||
|
|
||||||
- @ref glfwGetTime
|
- @ref glfwGetTime
|
||||||
- @ref glfwSetTime
|
- @ref glfwSetTime
|
||||||
|
|
||||||
Library version information may be queried from any thread. The following
|
Library version information may be queried from any thread.
|
||||||
version related functions may be called from any thread:
|
|
||||||
|
|
||||||
- @ref glfwGetVersion
|
- @ref glfwGetVersion
|
||||||
- @ref glfwGetVersionString
|
- @ref glfwGetVersionString
|
||||||
|
|
||||||
Vulkan objects may be created and information queried from any thread. The
|
All Vulkan related functions may be called from any thread.
|
||||||
following Vulkan related functions may be called from any thread:
|
|
||||||
|
|
||||||
- @ref glfwVulkanSupported
|
- @ref glfwVulkanSupported
|
||||||
- @ref glfwGetRequiredInstanceExtensions
|
- @ref glfwGetRequiredInstanceExtensions
|
||||||
@ -364,9 +367,9 @@ following Vulkan related functions may be called from any thread:
|
|||||||
- @ref glfwGetPhysicalDevicePresentationSupport
|
- @ref glfwGetPhysicalDevicePresentationSupport
|
||||||
- @ref glfwCreateWindowSurface
|
- @ref glfwCreateWindowSurface
|
||||||
|
|
||||||
GLFW uses no synchronization objects internally except for thread-local storage
|
GLFW uses synchronization objects internally only to manage the per-thread
|
||||||
to keep track of the current context for each thread. Synchronization is left
|
context and error states. Additional synchronization is left to the
|
||||||
to the application.
|
application.
|
||||||
|
|
||||||
Functions that may currently be called from any thread will always remain so,
|
Functions that may currently be called from any thread will always remain so,
|
||||||
but functions that are currently limited to the main thread may be updated to
|
but functions that are currently limited to the main thread may be updated to
|
||||||
|
@ -85,6 +85,13 @@ be disabled with the @ref GLFW_JOYSTICK_HAT_BUTTONS init hint.
|
|||||||
@see @ref joystick_hat
|
@see @ref joystick_hat
|
||||||
|
|
||||||
|
|
||||||
|
@subsection news_33_transparent Support for transparent window framebuffer
|
||||||
|
|
||||||
|
GLFW now supports the creation of windows with transparent framebuffers on
|
||||||
|
systems with desktop compositing enabled with the @ref GLFW_TRANSPARENT window
|
||||||
|
hint and attribute. Any window decorations will still be opaque.
|
||||||
|
|
||||||
|
|
||||||
@subsection news_33_centercursor Cursor centering window hint
|
@subsection news_33_centercursor Cursor centering window hint
|
||||||
|
|
||||||
GLFW now supports controlling whether the cursor is centered over newly created
|
GLFW now supports controlling whether the cursor is centered over newly created
|
||||||
|
@ -225,6 +225,13 @@ __GLFW_CENTER_CURSOR__ specifies whether the cursor should be centered over
|
|||||||
newly created full screen windows. Possible values are `GLFW_TRUE` and
|
newly created full screen windows. Possible values are `GLFW_TRUE` and
|
||||||
`GLFW_FALSE`. This hint is ignored for windowed mode windows.
|
`GLFW_FALSE`. This hint is ignored for windowed mode windows.
|
||||||
|
|
||||||
|
@anchor GLFW_TRANSPARENT_hint
|
||||||
|
__GLFW_TRANSPARENT__ specifies whether the window framebuffer will be
|
||||||
|
transparent. If enabled and supported by the system, the window framebuffer
|
||||||
|
alpha channel will be used to combine the framebuffer with the background. This
|
||||||
|
does not affect window decorations. Possible values are `GLFW_TRUE` and
|
||||||
|
`GLFW_FALSE`.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection window_hints_fb Framebuffer related hints
|
@subsubsection window_hints_fb Framebuffer related hints
|
||||||
|
|
||||||
@ -470,6 +477,7 @@ GLFW_AUTO_ICONIFY | `GLFW_TRUE` | `GLFW_TRUE` or `GL
|
|||||||
GLFW_FLOATING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_FLOATING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_MAXIMIZED | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_MAXIMIZED | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
|
GLFW_TRANSPARENT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||||
GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
|
||||||
@ -1061,6 +1069,30 @@ window contents are saved off-screen, this callback might only be called when
|
|||||||
the window or framebuffer is resized.
|
the window or framebuffer is resized.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection window_transparency Window transparency
|
||||||
|
|
||||||
|
Window framebuffers can be made transparent on a per-pixel per-frame basis with
|
||||||
|
the [GLFW_TRANSPARENT](@ref GLFW_TRANSPARENT_hint) window hint.
|
||||||
|
|
||||||
|
@code
|
||||||
|
glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE);
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
If supported by the system, the window framebuffer will be composited with the
|
||||||
|
background using the framebuffer per-pixel alpha channel. This requires desktop
|
||||||
|
compositing to be enabled on the system. It does not affect window decorations.
|
||||||
|
|
||||||
|
You can check whether the window framebuffer was successfully made transparent
|
||||||
|
with the [GLFW_TRANSPARENT](@ref GLFW_TRANSPARENT_attrib) window attribute.
|
||||||
|
|
||||||
|
@code
|
||||||
|
if (glfwGetWindowAttrib(window, GLFW_TRANSPARENT))
|
||||||
|
{
|
||||||
|
// window framebuffer is currently transparent
|
||||||
|
}
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
@subsection window_attribs Window attributes
|
@subsection window_attribs Window attributes
|
||||||
|
|
||||||
Windows have a number of attributes that can be returned using @ref
|
Windows have a number of attributes that can be returned using @ref
|
||||||
@ -1130,6 +1162,11 @@ called topmost or always-on-top. This can be set before creation with the
|
|||||||
[GLFW_FLOATING](@ref GLFW_FLOATING_hint) window hint or after with @ref
|
[GLFW_FLOATING](@ref GLFW_FLOATING_hint) window hint or after with @ref
|
||||||
glfwSetWindowAttrib.
|
glfwSetWindowAttrib.
|
||||||
|
|
||||||
|
@anchor GLFW_TRANSPARENT_attrib
|
||||||
|
__GLFW_TRANSPARENT__ indicates whether the specified window has a transparent
|
||||||
|
framebuffer, i.e. the window contents is composited with the background using
|
||||||
|
the window framebuffer alpha channel. See @ref window_transparency for details.
|
||||||
|
|
||||||
|
|
||||||
@subsubsection window_attribs_ctx Context related attributes
|
@subsubsection window_attribs_ctx Context related attributes
|
||||||
|
|
||||||
|
@ -172,6 +172,7 @@ static GLfloat angle = 0.f;
|
|||||||
/* OpenGL draw function & timing */
|
/* OpenGL draw function & timing */
|
||||||
static void draw(void)
|
static void draw(void)
|
||||||
{
|
{
|
||||||
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
@ -311,6 +312,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
glfwWindowHint(GLFW_DEPTH_BITS, 16);
|
glfwWindowHint(GLFW_DEPTH_BITS, 16);
|
||||||
|
glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE);
|
||||||
|
|
||||||
window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL );
|
window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL );
|
||||||
if (!window)
|
if (!window)
|
||||||
|
@ -787,6 +787,12 @@ extern "C" {
|
|||||||
* Cursor centering [window hint](@ref GLFW_CENTER_CURSOR_hint).
|
* Cursor centering [window hint](@ref GLFW_CENTER_CURSOR_hint).
|
||||||
*/
|
*/
|
||||||
#define GLFW_CENTER_CURSOR 0x00020009
|
#define GLFW_CENTER_CURSOR 0x00020009
|
||||||
|
/*! @brief Window framebuffer transparency hint and attribute
|
||||||
|
*
|
||||||
|
* Window framebuffer transparency [window hint](@ref GLFW_TRANSPARENT_hint)
|
||||||
|
* and [window attribute](@ref GLFW_TRANSPARENT_attrib).
|
||||||
|
*/
|
||||||
|
#define GLFW_TRANSPARENT 0x0002000A
|
||||||
|
|
||||||
/*! @brief Framebuffer bit depth hint.
|
/*! @brief Framebuffer bit depth hint.
|
||||||
*
|
*
|
||||||
@ -868,6 +874,7 @@ extern "C" {
|
|||||||
* Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER).
|
* Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER).
|
||||||
*/
|
*/
|
||||||
#define GLFW_DOUBLEBUFFER 0x00021010
|
#define GLFW_DOUBLEBUFFER 0x00021010
|
||||||
|
|
||||||
/*! @brief Context client API hint and attribute.
|
/*! @brief Context client API hint and attribute.
|
||||||
*
|
*
|
||||||
* Context client API [hint](@ref GLFW_CLIENT_API_hint) and
|
* Context client API [hint](@ref GLFW_CLIENT_API_hint) and
|
||||||
|
@ -215,7 +215,8 @@ static GLFWbool updateUnicodeDataNS(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource,
|
_glfw.ns.unicodeData =
|
||||||
|
TISGetInputSourceProperty(_glfw.ns.inputSource,
|
||||||
kTISPropertyUnicodeKeyLayoutData);
|
kTISPropertyUnicodeKeyLayoutData);
|
||||||
if (!_glfw.ns.unicodeData)
|
if (!_glfw.ns.unicodeData)
|
||||||
{
|
{
|
||||||
@ -232,7 +233,8 @@ static GLFWbool updateUnicodeDataNS(void)
|
|||||||
static GLFWbool initializeTIS(void)
|
static GLFWbool initializeTIS(void)
|
||||||
{
|
{
|
||||||
// This works only because Cocoa has already loaded it properly
|
// This works only because Cocoa has already loaded it properly
|
||||||
_glfw.ns.tis.bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
|
_glfw.ns.tis.bundle =
|
||||||
|
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
|
||||||
if (!_glfw.ns.tis.bundle)
|
if (!_glfw.ns.tis.bundle)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
@ -73,7 +73,9 @@ static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
|
|||||||
|
|
||||||
// Comparison function for matching the SDL element order
|
// Comparison function for matching the SDL element order
|
||||||
//
|
//
|
||||||
static CFComparisonResult compareElements(const void* fp, const void* sp, void* user)
|
static CFComparisonResult compareElements(const void* fp,
|
||||||
|
const void* sp,
|
||||||
|
void* user)
|
||||||
{
|
{
|
||||||
const _GLFWjoyelementNS* fe = fp;
|
const _GLFWjoyelementNS* fe = fp;
|
||||||
const _GLFWjoyelementNS* se = sp;
|
const _GLFWjoyelementNS* se = sp;
|
||||||
@ -183,7 +185,8 @@ static void matchCallback(void* context,
|
|||||||
|
|
||||||
for (i = 0; i < CFArrayGetCount(elements); i++)
|
for (i = 0; i < CFArrayGetCount(elements); i++)
|
||||||
{
|
{
|
||||||
IOHIDElementRef native = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i);
|
IOHIDElementRef native = (IOHIDElementRef)
|
||||||
|
CFArrayGetValueAtIndex(elements, i);
|
||||||
if (CFGetTypeID(native) != IOHIDElementGetTypeID())
|
if (CFGetTypeID(native) != IOHIDElementGetTypeID())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ static char* getDisplayName(CGDirectDisplayID displayID)
|
|||||||
|
|
||||||
while ((service = IOIteratorNext(it)) != 0)
|
while ((service = IOIteratorNext(it)) != 0)
|
||||||
{
|
{
|
||||||
info = IODisplayCreateInfoDictionary(service, kIODisplayOnlyPreferredName);
|
info = IODisplayCreateInfoDictionary(service,
|
||||||
|
kIODisplayOnlyPreferredName);
|
||||||
|
|
||||||
CFNumberRef vendorIDRef =
|
CFNumberRef vendorIDRef =
|
||||||
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
|
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
|
||||||
@ -185,7 +186,13 @@ static CGDisplayFadeReservationToken beginFadeReservation(void)
|
|||||||
CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
|
CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
|
||||||
|
|
||||||
if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
|
if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
|
||||||
CGDisplayFade(token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
|
{
|
||||||
|
CGDisplayFade(token, 0.3,
|
||||||
|
kCGDisplayBlendNormal,
|
||||||
|
kCGDisplayBlendSolidColor,
|
||||||
|
0.0, 0.0, 0.0,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@ -196,7 +203,11 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
|
|||||||
{
|
{
|
||||||
if (token != kCGDisplayFadeReservationInvalidToken)
|
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);
|
CGReleaseDisplayFadeReservation(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,13 +228,13 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
_GLFWwindow* window;
|
_GLFWwindow* window;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow;
|
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GLFWWindowDelegate
|
@implementation GLFWWindowDelegate
|
||||||
|
|
||||||
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow
|
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
@ -381,13 +381,13 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
NSMutableAttributedString* markedText;
|
NSMutableAttributedString* markedText;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow;
|
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GLFWContentView
|
@implementation GLFWContentView
|
||||||
|
|
||||||
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow
|
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
@ -413,7 +413,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
|||||||
|
|
||||||
- (BOOL)isOpaque
|
- (BOOL)isOpaque
|
||||||
{
|
{
|
||||||
return YES;
|
return [window->ns.object isOpaque];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)canBecomeKeyView
|
- (BOOL)canBecomeKeyView
|
||||||
@ -1012,7 +1012,8 @@ static GLFWbool initializeAppKit(void)
|
|||||||
// Create the Cocoa window
|
// Create the Cocoa window
|
||||||
//
|
//
|
||||||
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
static GLFWbool createNativeWindow(_GLFWwindow* window,
|
||||||
const _GLFWwndconfig* wndconfig)
|
const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window];
|
window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window];
|
||||||
if (window->ns.delegate == nil)
|
if (window->ns.delegate == nil)
|
||||||
@ -1081,6 +1082,12 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
if (wndconfig->ns.retina)
|
if (wndconfig->ns.retina)
|
||||||
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
|
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
|
||||||
|
|
||||||
|
if (fbconfig->transparent)
|
||||||
|
{
|
||||||
|
[window->ns.object setOpaque:NO];
|
||||||
|
[window->ns.object setBackgroundColor:[NSColor clearColor]];
|
||||||
|
}
|
||||||
|
|
||||||
[window->ns.object setContentView:window->ns.view];
|
[window->ns.object setContentView:window->ns.view];
|
||||||
[window->ns.object makeFirstResponder:window->ns.view];
|
[window->ns.object makeFirstResponder:window->ns.view];
|
||||||
[window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]];
|
[window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]];
|
||||||
@ -1104,7 +1111,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
if (!initializeAppKit())
|
if (!initializeAppKit())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (!createNativeWindow(window, wndconfig))
|
if (!createNativeWindow(window, wndconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
@ -1175,7 +1182,11 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
|
|
||||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title)
|
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title)
|
||||||
{
|
{
|
||||||
[window->ns.object setTitle:[NSString stringWithUTF8String:title]];
|
NSString* string = [NSString stringWithUTF8String:title];
|
||||||
|
[window->ns.object setTitle:string];
|
||||||
|
// HACK: Set the miniwindow title explicitly as setTitle: doesn't update it
|
||||||
|
// if the window lacks NSWindowStyleMaskTitled
|
||||||
|
[window->ns.object setMiniwindowTitle:string];
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
|
||||||
@ -1420,6 +1431,9 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
|||||||
[window->ns.object setLevel:NSNormalWindowLevel];
|
[window->ns.object setLevel:NSNormalWindowLevel];
|
||||||
|
|
||||||
[window->ns.object setHasShadow:YES];
|
[window->ns.object setHasShadow:YES];
|
||||||
|
// HACK: Clearing NSWindowStyleMaskTitled resets and disables the window
|
||||||
|
// title property but the miniwindow title property is unaffected
|
||||||
|
[window->ns.object setTitle:[window->ns.object miniwindowTitle]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1443,6 +1457,11 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
|||||||
return [window->ns.object isZoomed];
|
return [window->ns.object isZoomed];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return ![window->ns.object isOpaque] && ![window->ns.view isOpaque];
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
[window->ns.object setStyleMask:getStyleMask(window)];
|
[window->ns.object setStyleMask:getStyleMask(window)];
|
||||||
|
@ -208,6 +208,9 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
|||||||
// not important to us here, so we count them as one
|
// not important to us here, so we count them as one
|
||||||
missing++;
|
missing++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (desired->transparent != current->transparent)
|
||||||
|
missing++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// These polynomials make many small channel size differences matter
|
// These polynomials make many small channel size differences matter
|
||||||
|
@ -121,9 +121,25 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
#if defined(_GLFW_X11)
|
#if defined(_GLFW_X11)
|
||||||
|
XVisualInfo vi = {0};
|
||||||
|
|
||||||
// Only consider EGLConfigs with associated Visuals
|
// Only consider EGLConfigs with associated Visuals
|
||||||
if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))
|
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
|
||||||
|
if (!vi.visualid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (desired->transparent)
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
XVisualInfo* vis = XGetVisualInfo(_glfw.x11.display,
|
||||||
|
VisualIDMask, &vi,
|
||||||
|
&count);
|
||||||
|
if (vis)
|
||||||
|
{
|
||||||
|
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
|
||||||
|
XFree(vis);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif // _GLFW_X11
|
#endif // _GLFW_X11
|
||||||
|
|
||||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||||
@ -286,7 +302,9 @@ GLFWbool _glfwInitEGL(void)
|
|||||||
int i;
|
int i;
|
||||||
const char* sonames[] =
|
const char* sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_WIN32)
|
#if defined(_GLFW_EGL_LIBRARY)
|
||||||
|
_GLFW_EGL_LIBRARY,
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
"libEGL.dll",
|
"libEGL.dll",
|
||||||
"EGL.dll",
|
"EGL.dll",
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
@ -605,7 +623,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
const char** sonames;
|
const char** sonames;
|
||||||
const char* es1sonames[] =
|
const char* es1sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_WIN32)
|
#if defined(_GLFW_GLESV1_LIBRARY)
|
||||||
|
_GLFW_GLESV1_LIBRARY,
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
"GLESv1_CM.dll",
|
"GLESv1_CM.dll",
|
||||||
"libGLES_CM.dll",
|
"libGLES_CM.dll",
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
@ -618,7 +638,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
};
|
};
|
||||||
const char* es2sonames[] =
|
const char* es2sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_WIN32)
|
#if defined(_GLFW_GLESV2_LIBRARY)
|
||||||
|
_GLFW_GLESV2_LIBRARY,
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
"GLESv2.dll",
|
"GLESv2.dll",
|
||||||
"libGLESv2.dll",
|
"libGLESv2.dll",
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
@ -632,7 +654,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
};
|
};
|
||||||
const char* glsonames[] =
|
const char* glsonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_WIN32)
|
#if defined(_GLFW_OPENGL_LIBRARY)
|
||||||
|
_GLFW_OPENGL_LIBRARY,
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
#else
|
#else
|
||||||
"libGL.so.1",
|
"libGL.so.1",
|
||||||
@ -685,7 +709,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
// Returns the Visual and depth of the chosen EGLConfig
|
// Returns the Visual and depth of the chosen EGLConfig
|
||||||
//
|
//
|
||||||
#if defined(_GLFW_X11)
|
#if defined(_GLFW_X11)
|
||||||
GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig,
|
const _GLFWfbconfig* fbconfig,
|
||||||
Visual** visual, int* depth)
|
Visual** visual, int* depth)
|
||||||
{
|
{
|
||||||
|
@ -187,7 +187,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
#if defined(_GLFW_X11)
|
#if defined(_GLFW_X11)
|
||||||
GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig,
|
const _GLFWfbconfig* fbconfig,
|
||||||
Visual** visual, int* depth);
|
Visual** visual, int* depth);
|
||||||
#endif /*_GLFW_X11*/
|
#endif /*_GLFW_X11*/
|
||||||
|
@ -47,7 +47,8 @@ static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
|
|||||||
|
|
||||||
// Return the GLXFBConfig most closely matching the specified hints
|
// Return the GLXFBConfig most closely matching the specified hints
|
||||||
//
|
//
|
||||||
static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result)
|
static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||||
|
GLXFBConfig* result)
|
||||||
{
|
{
|
||||||
GLXFBConfig* nativeConfigs;
|
GLXFBConfig* nativeConfigs;
|
||||||
_GLFWfbconfig* usableConfigs;
|
_GLFWfbconfig* usableConfigs;
|
||||||
@ -89,6 +90,16 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (desired->transparent)
|
||||||
|
{
|
||||||
|
XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
|
||||||
|
if (vi)
|
||||||
|
{
|
||||||
|
u->transparent = _glfwIsVisualTransparentX11(vi->visual);
|
||||||
|
XFree(vi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
|
u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
|
||||||
u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
|
u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
|
||||||
u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
|
u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
|
||||||
@ -244,7 +255,9 @@ GLFWbool _glfwInitGLX(void)
|
|||||||
int i;
|
int i;
|
||||||
const char* sonames[] =
|
const char* sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(__CYGWIN__)
|
#if defined(_GLFW_GLX_LIBRARY)
|
||||||
|
_GLFW_GLX_LIBRARY,
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
"libGL-1.so",
|
"libGL-1.so",
|
||||||
#else
|
#else
|
||||||
"libGL.so.1",
|
"libGL.so.1",
|
||||||
@ -620,7 +633,8 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
|||||||
|
|
||||||
// Returns the Visual and depth of the chosen GLXFBConfig
|
// Returns the Visual and depth of the chosen GLXFBConfig
|
||||||
//
|
//
|
||||||
GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
|
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig,
|
const _GLFWfbconfig* fbconfig,
|
||||||
Visual** visual, int* depth)
|
Visual** visual, int* depth)
|
||||||
{
|
{
|
||||||
|
@ -168,14 +168,14 @@ typedef struct _GLFWlibraryGLX
|
|||||||
|
|
||||||
} _GLFWlibraryGLX;
|
} _GLFWlibraryGLX;
|
||||||
|
|
||||||
|
|
||||||
GLFWbool _glfwInitGLX(void);
|
GLFWbool _glfwInitGLX(void);
|
||||||
void _glfwTerminateGLX(void);
|
void _glfwTerminateGLX(void);
|
||||||
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig);
|
const _GLFWfbconfig* fbconfig);
|
||||||
void _glfwDestroyContextGLX(_GLFWwindow* window);
|
void _glfwDestroyContextGLX(_GLFWwindow* window);
|
||||||
GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
|
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig,
|
const _GLFWfbconfig* fbconfig,
|
||||||
Visual** visual, int* depth);
|
Visual** visual, int* depth);
|
||||||
|
|
||||||
|
23
src/input.c
23
src/input.c
@ -354,11 +354,11 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
|
|||||||
return window->stickyKeys;
|
return window->stickyKeys;
|
||||||
case GLFW_STICKY_MOUSE_BUTTONS:
|
case GLFW_STICKY_MOUSE_BUTTONS:
|
||||||
return window->stickyMouseButtons;
|
return window->stickyMouseButtons;
|
||||||
default:
|
}
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||||
{
|
{
|
||||||
@ -367,9 +367,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
|||||||
|
|
||||||
_GLFW_REQUIRE_INIT();
|
_GLFW_REQUIRE_INIT();
|
||||||
|
|
||||||
switch (mode)
|
if (mode == GLFW_CURSOR)
|
||||||
{
|
|
||||||
case GLFW_CURSOR:
|
|
||||||
{
|
{
|
||||||
if (value != GLFW_CURSOR_NORMAL &&
|
if (value != GLFW_CURSOR_NORMAL &&
|
||||||
value != GLFW_CURSOR_HIDDEN &&
|
value != GLFW_CURSOR_HIDDEN &&
|
||||||
@ -392,12 +390,10 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
|||||||
|
|
||||||
if (_glfwPlatformWindowFocused(window))
|
if (_glfwPlatformWindowFocused(window))
|
||||||
_glfwPlatformSetCursorMode(window, value);
|
_glfwPlatformSetCursorMode(window, value);
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (mode == GLFW_STICKY_KEYS)
|
||||||
case GLFW_STICKY_KEYS:
|
|
||||||
{
|
{
|
||||||
|
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
if (window->stickyKeys == value)
|
if (window->stickyKeys == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -414,11 +410,10 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
|
window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
|
||||||
case GLFW_STICKY_MOUSE_BUTTONS:
|
|
||||||
{
|
{
|
||||||
|
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
if (window->stickyMouseButtons == value)
|
if (window->stickyMouseButtons == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -435,10 +430,8 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
window->stickyMouseButtons = value ? GLFW_TRUE : GLFW_FALSE;
|
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 0x%08X", mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,6 +362,7 @@ struct _GLFWfbconfig
|
|||||||
int samples;
|
int samples;
|
||||||
GLFWbool sRGB;
|
GLFWbool sRGB;
|
||||||
GLFWbool doublebuffer;
|
GLFWbool doublebuffer;
|
||||||
|
GLFWbool transparent;
|
||||||
uintptr_t handle;
|
uintptr_t handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -686,6 +687,7 @@ int _glfwPlatformWindowFocused(_GLFWwindow* window);
|
|||||||
int _glfwPlatformWindowIconified(_GLFWwindow* window);
|
int _glfwPlatformWindowIconified(_GLFWwindow* window);
|
||||||
int _glfwPlatformWindowVisible(_GLFWwindow* window);
|
int _glfwPlatformWindowVisible(_GLFWwindow* window);
|
||||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
|
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
|
||||||
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
||||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
||||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
||||||
|
@ -23,6 +23,16 @@
|
|||||||
// distribution.
|
// 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
|
// All gamepad mappings not labeled GLFW are copied from the
|
||||||
// SDL_GameControllerDB project under the following license:
|
// SDL_GameControllerDB project under the following license:
|
||||||
@ -220,6 +230,7 @@ const char* _glfwDefaultMappings =
|
|||||||
"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"
|
"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"
|
"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"
|
"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"
|
"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"
|
"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"
|
"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"
|
||||||
|
70
src/mappings.h.in
Normal file
70
src/mappings.h.in
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
//========================================================================
|
||||||
|
// 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";
|
||||||
|
|
@ -614,6 +614,13 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
|||||||
return mir_window_get_state(window->mir.window) == mir_window_state_maximized;
|
return mir_window_get_state(window->mir.window) == mir_window_state_maximized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
@ -869,7 +876,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|||||||
VkPhysicalDevice device,
|
VkPhysicalDevice device,
|
||||||
uint32_t queuefamily)
|
uint32_t queuefamily)
|
||||||
{
|
{
|
||||||
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR =
|
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
|
||||||
|
vkGetPhysicalDeviceMirPresentationSupportKHR =
|
||||||
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
|
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
|
||||||
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
|
||||||
if (!vkGetPhysicalDeviceMirPresentationSupportKHR)
|
if (!vkGetPhysicalDeviceMirPresentationSupportKHR)
|
||||||
|
@ -296,6 +296,12 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fbconfig->transparent)
|
||||||
|
{
|
||||||
|
GLint opaque = 0;
|
||||||
|
[window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLCPSurfaceOpacity];
|
||||||
|
}
|
||||||
|
|
||||||
[window->context.nsgl.object setView:window->ns.view];
|
[window->context.nsgl.object setView:window->ns.view];
|
||||||
|
|
||||||
window->context.makeCurrent = makeContextCurrentNSGL;
|
window->context.makeCurrent = makeContextCurrentNSGL;
|
||||||
|
@ -156,6 +156,11 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,9 @@ GLFWbool _glfwInitOSMesa(void)
|
|||||||
int i;
|
int i;
|
||||||
const char* sonames[] =
|
const char* sonames[] =
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_GLFW_OSMESA_LIBRARY)
|
||||||
|
_GLFW_OSMESA_LIBRARY,
|
||||||
|
#elif defined(_WIN32)
|
||||||
"libOSMesa.dll",
|
"libOSMesa.dll",
|
||||||
"OSMesa.dll",
|
"OSMesa.dll",
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
|
@ -49,7 +49,9 @@ GLFWbool _glfwInitVulkan(int mode)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
|
|
||||||
#if !defined(_GLFW_VULKAN_STATIC)
|
#if !defined(_GLFW_VULKAN_STATIC)
|
||||||
#if defined(_GLFW_WIN32)
|
#if defined(_GLFW_VULKAN_LIBRARY)
|
||||||
|
_glfw.vk.handle = _glfw_dlopen(_GLFW_VULKAN_LIBRARY);
|
||||||
|
#elif defined(_GLFW_WIN32)
|
||||||
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
|
_glfw.vk.handle = _glfw_dlopen("vulkan-1.dll");
|
||||||
#elif defined(_GLFW_COCOA)
|
#elif defined(_GLFW_COCOA)
|
||||||
_glfw.vk.handle = _glfw_dlopen("libMoltenVK.dylib");
|
_glfw.vk.handle = _glfw_dlopen("libMoltenVK.dylib");
|
||||||
|
@ -152,10 +152,10 @@ static int choosePixelFormat(_GLFWwindow* window,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
|
||||||
|
|
||||||
// Get pixel format attributes through legacy PFDs
|
// Get pixel format attributes through legacy PFDs
|
||||||
|
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
|
||||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||||
n,
|
n,
|
||||||
sizeof(PIXELFORMATDESCRIPTOR),
|
sizeof(PIXELFORMATDESCRIPTOR),
|
||||||
@ -229,21 +229,6 @@ static int choosePixelFormat(_GLFWwindow* window,
|
|||||||
return pixelFormat;
|
return pixelFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns whether desktop compositing is enabled
|
|
||||||
//
|
|
||||||
static GLFWbool isCompositionEnabled(void)
|
|
||||||
{
|
|
||||||
if (_glfw.win32.dwmapi.instance)
|
|
||||||
{
|
|
||||||
BOOL enabled;
|
|
||||||
|
|
||||||
if (DwmIsCompositionEnabled(&enabled) == S_OK)
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void makeContextCurrentWGL(_GLFWwindow* window)
|
static void makeContextCurrentWGL(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
if (window)
|
if (window)
|
||||||
@ -272,7 +257,7 @@ static void makeContextCurrentWGL(_GLFWwindow* window)
|
|||||||
static void swapBuffersWGL(_GLFWwindow* window)
|
static void swapBuffersWGL(_GLFWwindow* window)
|
||||||
{
|
{
|
||||||
// HACK: Use DwmFlush when desktop composition is enabled
|
// HACK: Use DwmFlush when desktop composition is enabled
|
||||||
if (isCompositionEnabled() && !window->monitor)
|
if (_glfwIsCompositionEnabledWin32() && !window->monitor)
|
||||||
{
|
{
|
||||||
int count = abs(window->context.wgl.interval);
|
int count = abs(window->context.wgl.interval);
|
||||||
while (count--)
|
while (count--)
|
||||||
@ -290,7 +275,7 @@ static void swapIntervalWGL(int interval)
|
|||||||
|
|
||||||
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
||||||
// avoid interfering with DWM vsync
|
// avoid interfering with DWM vsync
|
||||||
if (isCompositionEnabled() && !window->monitor)
|
if (_glfwIsCompositionEnabledWin32() && !window->monitor)
|
||||||
interval = 0;
|
interval = 0;
|
||||||
|
|
||||||
if (_glfw.wgl.EXT_swap_control)
|
if (_glfw.wgl.EXT_swap_control)
|
||||||
|
111
src/win32_init.c
111
src/win32_init.c
@ -30,7 +30,8 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
static const GUID _glfw_GUID_DEVINTERFACE_HID = {0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
|
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
|
#define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID
|
||||||
|
|
||||||
@ -61,6 +62,17 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
|||||||
|
|
||||||
#endif // _GLFW_BUILD_DLL
|
#endif // _GLFW_BUILD_DLL
|
||||||
|
|
||||||
|
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
||||||
|
BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp)
|
||||||
|
{
|
||||||
|
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
|
||||||
|
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
|
||||||
|
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||||
|
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
|
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||||
|
return VerifyVersionInfoW(&osvi, mask, cond);
|
||||||
|
}
|
||||||
|
|
||||||
// Load necessary libraries (DLLs)
|
// Load necessary libraries (DLLs)
|
||||||
//
|
//
|
||||||
static GLFWbool loadLibraries(void)
|
static GLFWbool loadLibraries(void)
|
||||||
@ -68,7 +80,8 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");
|
_glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");
|
||||||
if (!_glfw.win32.winmm.instance)
|
if (!_glfw.win32.winmm.instance)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "Win32: Failed to load winmm.dll");
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to load winmm.dll");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,13 +91,14 @@ static GLFWbool loadLibraries(void)
|
|||||||
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
|
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
|
||||||
if (!_glfw.win32.user32.instance)
|
if (!_glfw.win32.user32.instance)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "Win32: Failed to load user32.dll");
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
|
"Win32: Failed to load user32.dll");
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.win32.user32.SetProcessDPIAware = (PFN_SetProcessDPIAware)
|
_glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
|
||||||
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
|
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
|
||||||
_glfw.win32.user32.ChangeWindowMessageFilterEx = (PFN_ChangeWindowMessageFilterEx)
|
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
|
||||||
GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
|
GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
|
||||||
|
|
||||||
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
||||||
@ -128,12 +142,14 @@ static GLFWbool loadLibraries(void)
|
|||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
||||||
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
|
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
|
||||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
||||||
|
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
|
||||||
|
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
||||||
}
|
}
|
||||||
|
|
||||||
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
||||||
if (_glfw.win32.shcore.instance)
|
if (_glfw.win32.shcore.instance)
|
||||||
{
|
{
|
||||||
_glfw.win32.shcore.SetProcessDpiAwareness = (PFN_SetProcessDpiAwareness)
|
_glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
|
||||||
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
|
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,19 +373,19 @@ static HWND createHelperWindow(void)
|
|||||||
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
|
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
|
||||||
{
|
{
|
||||||
WCHAR* target;
|
WCHAR* target;
|
||||||
int length;
|
int count;
|
||||||
|
|
||||||
length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
|
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
|
||||||
if (!length)
|
if (!count)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to convert string from UTF-8");
|
"Win32: Failed to convert string from UTF-8");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
target = calloc(length, sizeof(WCHAR));
|
target = calloc(count, sizeof(WCHAR));
|
||||||
|
|
||||||
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, length))
|
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to convert string from UTF-8");
|
"Win32: Failed to convert string from UTF-8");
|
||||||
@ -385,19 +401,19 @@ WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
|
|||||||
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
||||||
{
|
{
|
||||||
char* target;
|
char* target;
|
||||||
int length;
|
int size;
|
||||||
|
|
||||||
length = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
|
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
|
||||||
if (!length)
|
if (!size)
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to convert string to UTF-8");
|
"Win32: Failed to convert string to UTF-8");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
target = calloc(length, 1);
|
target = calloc(size, 1);
|
||||||
|
|
||||||
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length, NULL, NULL))
|
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
|
||||||
{
|
{
|
||||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||||
"Win32: Failed to convert string to UTF-8");
|
"Win32: Failed to convert string to UTF-8");
|
||||||
@ -429,6 +445,60 @@ void _glfwInputErrorWin32(int error, const char* description)
|
|||||||
_glfwInputError(error, "%s: %s", description, message);
|
_glfwInputError(error, "%s: %s", description, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Updates key names according to the current keyboard layout
|
||||||
|
//
|
||||||
|
void _glfwUpdateKeyNamesWin32(void)
|
||||||
|
{
|
||||||
|
int key;
|
||||||
|
BYTE state[256] = {0};
|
||||||
|
|
||||||
|
memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
|
||||||
|
|
||||||
|
for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++)
|
||||||
|
{
|
||||||
|
UINT vk;
|
||||||
|
int scancode, length;
|
||||||
|
WCHAR chars[16];
|
||||||
|
|
||||||
|
scancode = _glfw.win32.scancodes[key];
|
||||||
|
if (scancode == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
|
||||||
|
{
|
||||||
|
const UINT vks[] = {
|
||||||
|
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
|
||||||
|
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
|
||||||
|
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
|
||||||
|
VK_MULTIPLY, VK_SUBTRACT, VK_ADD
|
||||||
|
};
|
||||||
|
|
||||||
|
vk = vks[key - GLFW_KEY_KP_0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
|
||||||
|
|
||||||
|
length = ToUnicode(vk, scancode, state,
|
||||||
|
chars, sizeof(chars) / sizeof(WCHAR),
|
||||||
|
0);
|
||||||
|
|
||||||
|
if (length == -1)
|
||||||
|
{
|
||||||
|
length = ToUnicode(vk, scancode, state,
|
||||||
|
chars, sizeof(chars) / sizeof(WCHAR),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
|
||||||
|
_glfw.win32.keynames[key],
|
||||||
|
sizeof(_glfw.win32.keynames[key]),
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@ -448,11 +518,12 @@ int _glfwPlatformInit(void)
|
|||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
createKeyTables();
|
createKeyTables();
|
||||||
|
_glfwUpdateKeyNamesWin32();
|
||||||
|
|
||||||
if (_glfw_SetProcessDpiAwareness)
|
if (IsWindows8Point1OrGreater())
|
||||||
_glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||||
else if (_glfw_SetProcessDPIAware)
|
else if (IsWindowsVistaOrGreater())
|
||||||
_glfw_SetProcessDPIAware();
|
SetProcessDPIAware();
|
||||||
|
|
||||||
if (!_glfwRegisterWindowClassWin32())
|
if (!_glfwRegisterWindowClassWin32())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
@ -50,16 +50,24 @@ typedef struct _GLFWobjenumWin32
|
|||||||
|
|
||||||
// Define local copies of the necessary GUIDs
|
// Define local copies of the necessary GUIDs
|
||||||
//
|
//
|
||||||
static const GUID _glfw_IID_IDirectInput8W = {0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
|
static const GUID _glfw_IID_IDirectInput8W =
|
||||||
static const GUID _glfw_GUID_XAxis = {0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
{0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
|
||||||
static const GUID _glfw_GUID_YAxis = {0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
static const GUID _glfw_GUID_XAxis =
|
||||||
static const GUID _glfw_GUID_ZAxis = {0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
{0xa36d02e0,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_YAxis =
|
||||||
static const GUID _glfw_GUID_RyAxis = {0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
{0xa36d02e1,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_ZAxis =
|
||||||
static const GUID _glfw_GUID_Slider = {0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
{0xa36d02e2,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_RxAxis =
|
||||||
static const GUID _glfw_GUID_POV = {0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
{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_POV =
|
||||||
|
{0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||||
|
|
||||||
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
|
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
|
||||||
#define GUID_XAxis _glfw_GUID_XAxis
|
#define GUID_XAxis _glfw_GUID_XAxis
|
||||||
@ -69,7 +77,6 @@ static const GUID _glfw_GUID_POV = {0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x4
|
|||||||
#define GUID_RyAxis _glfw_GUID_RyAxis
|
#define GUID_RyAxis _glfw_GUID_RyAxis
|
||||||
#define GUID_RzAxis _glfw_GUID_RzAxis
|
#define GUID_RzAxis _glfw_GUID_RzAxis
|
||||||
#define GUID_Slider _glfw_GUID_Slider
|
#define GUID_Slider _glfw_GUID_Slider
|
||||||
#define GUID_Button _glfw_GUID_Button
|
|
||||||
#define GUID_POV _glfw_GUID_POV
|
#define GUID_POV _glfw_GUID_POV
|
||||||
|
|
||||||
// Object data array for our clone of c_dfDIJoystick
|
// Object data array for our clone of c_dfDIJoystick
|
||||||
@ -345,11 +352,13 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
|||||||
|
|
||||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||||
{
|
{
|
||||||
if (!_glfw.joysticks[jid].present)
|
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||||
continue;
|
if (js->present)
|
||||||
if (memcmp(&_glfw.joysticks[jid].win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
|
{
|
||||||
|
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
|
||||||
return DIENUM_CONTINUE;
|
return DIENUM_CONTINUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (supportsXInput(&di->guidProduct))
|
if (supportsXInput(&di->guidProduct))
|
||||||
return DIENUM_CONTINUE;
|
return DIENUM_CONTINUE;
|
||||||
|
@ -63,7 +63,6 @@
|
|||||||
|
|
||||||
#include <wctype.h>
|
#include <wctype.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <mmsystem.h>
|
|
||||||
#include <dinput.h>
|
#include <dinput.h>
|
||||||
#include <xinput.h>
|
#include <xinput.h>
|
||||||
#include <dbt.h>
|
#include <dbt.h>
|
||||||
@ -101,6 +100,9 @@
|
|||||||
#ifndef DISPLAY_DEVICE_ACTIVE
|
#ifndef DISPLAY_DEVICE_ACTIVE
|
||||||
#define DISPLAY_DEVICE_ACTIVE 0x00000001
|
#define DISPLAY_DEVICE_ACTIVE 0x00000001
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef _WIN32_WINNT_WINBLUE
|
||||||
|
#define _WIN32_WINNT_WINBLUE 0x0602
|
||||||
|
#endif
|
||||||
|
|
||||||
#if WINVER < 0x0601
|
#if WINVER < 0x0601
|
||||||
typedef struct tagCHANGEFILTERSTRUCT
|
typedef struct tagCHANGEFILTERSTRUCT
|
||||||
@ -114,6 +116,18 @@ typedef struct tagCHANGEFILTERSTRUCT
|
|||||||
#endif
|
#endif
|
||||||
#endif /*Windows 7*/
|
#endif /*Windows 7*/
|
||||||
|
|
||||||
|
#if WINVER < 0x0600
|
||||||
|
#define DWM_BB_ENABLE 0x00000001
|
||||||
|
#define DWM_BB_BLURREGION 0x00000002
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DWORD dwFlags;
|
||||||
|
BOOL fEnable;
|
||||||
|
HRGN hRgnBlur;
|
||||||
|
BOOL fTransitionOnMaximized;
|
||||||
|
} DWM_BLURBEHIND;
|
||||||
|
#endif /*Windows Vista*/
|
||||||
|
|
||||||
#ifndef DPI_ENUMS_DECLARED
|
#ifndef DPI_ENUMS_DECLARED
|
||||||
typedef enum PROCESS_DPI_AWARENESS
|
typedef enum PROCESS_DPI_AWARENESS
|
||||||
{
|
{
|
||||||
@ -123,6 +137,21 @@ typedef enum PROCESS_DPI_AWARENESS
|
|||||||
} PROCESS_DPI_AWARENESS;
|
} PROCESS_DPI_AWARENESS;
|
||||||
#endif /*DPI_ENUMS_DECLARED*/
|
#endif /*DPI_ENUMS_DECLARED*/
|
||||||
|
|
||||||
|
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
||||||
|
BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp);
|
||||||
|
#define IsWindowsVistaOrGreater() \
|
||||||
|
IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA), \
|
||||||
|
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
||||||
|
#define IsWindows7OrGreater() \
|
||||||
|
IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7), \
|
||||||
|
LOBYTE(_WIN32_WINNT_WIN7), 0)
|
||||||
|
#define IsWindows8OrGreater() \
|
||||||
|
IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8), \
|
||||||
|
LOBYTE(_WIN32_WINNT_WIN8), 0)
|
||||||
|
#define IsWindows8Point1OrGreater() \
|
||||||
|
IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE), \
|
||||||
|
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
|
||||||
|
|
||||||
// HACK: Define macros that some xinput.h variants don't
|
// HACK: Define macros that some xinput.h variants don't
|
||||||
#ifndef XINPUT_CAPS_WIRELESS
|
#ifndef XINPUT_CAPS_WIRELESS
|
||||||
#define XINPUT_CAPS_WIRELESS 0x0002
|
#define XINPUT_CAPS_WIRELESS 0x0002
|
||||||
@ -174,18 +203,20 @@ typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*
|
|||||||
// user32.dll function pointer typedefs
|
// user32.dll function pointer typedefs
|
||||||
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
||||||
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT);
|
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT);
|
||||||
#define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware
|
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
||||||
#define _glfw_ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx
|
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
||||||
|
|
||||||
// dwmapi.dll function pointer typedefs
|
// dwmapi.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||||
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
||||||
|
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
|
||||||
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
||||||
#define DwmFlush _glfw.win32.dwmapi.Flush
|
#define DwmFlush _glfw.win32.dwmapi.Flush
|
||||||
|
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
||||||
|
|
||||||
// shcore.dll function pointer typedefs
|
// shcore.dll function pointer typedefs
|
||||||
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||||
#define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness
|
#define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
|
||||||
|
|
||||||
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
@ -236,6 +267,8 @@ typedef struct _GLFWwindowWin32
|
|||||||
GLFWbool frameAction;
|
GLFWbool frameAction;
|
||||||
GLFWbool iconified;
|
GLFWbool iconified;
|
||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
|
// Whether to enable framebuffer transparency on DWM
|
||||||
|
GLFWbool transparent;
|
||||||
|
|
||||||
// The last received cursor position, regardless of source
|
// The last received cursor position, regardless of source
|
||||||
int lastCursorPosX, lastCursorPosY;
|
int lastCursorPosX, lastCursorPosY;
|
||||||
@ -250,9 +283,9 @@ typedef struct _GLFWlibraryWin32
|
|||||||
DWORD foregroundLockTimeout;
|
DWORD foregroundLockTimeout;
|
||||||
int acquiredMonitorCount;
|
int acquiredMonitorCount;
|
||||||
char* clipboardString;
|
char* clipboardString;
|
||||||
char keyName[64];
|
|
||||||
short int keycodes[512];
|
short int keycodes[512];
|
||||||
short int scancodes[GLFW_KEY_LAST + 1];
|
short int scancodes[GLFW_KEY_LAST + 1];
|
||||||
|
char keynames[GLFW_KEY_LAST + 1][5];
|
||||||
// Where to place the cursor when re-enabled
|
// Where to place the cursor when re-enabled
|
||||||
double restoreCursorPosX, restoreCursorPosY;
|
double restoreCursorPosX, restoreCursorPosY;
|
||||||
// The window whose disabled cursor mode is active
|
// The window whose disabled cursor mode is active
|
||||||
@ -279,19 +312,20 @@ typedef struct _GLFWlibraryWin32
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_SetProcessDPIAware SetProcessDPIAware;
|
PFN_SetProcessDPIAware SetProcessDPIAware_;
|
||||||
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx;
|
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
|
||||||
} user32;
|
} user32;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
||||||
PFN_DwmFlush Flush;
|
PFN_DwmFlush Flush;
|
||||||
|
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
||||||
} dwmapi;
|
} dwmapi;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
PFN_SetProcessDpiAwareness SetProcessDpiAwareness;
|
PFN_SetProcessDpiAwareness SetProcessDpiAwareness_;
|
||||||
} shcore;
|
} shcore;
|
||||||
|
|
||||||
} _GLFWlibraryWin32;
|
} _GLFWlibraryWin32;
|
||||||
@ -349,10 +383,12 @@ typedef struct _GLFWmutexWin32
|
|||||||
|
|
||||||
GLFWbool _glfwRegisterWindowClassWin32(void);
|
GLFWbool _glfwRegisterWindowClassWin32(void);
|
||||||
void _glfwUnregisterWindowClassWin32(void);
|
void _glfwUnregisterWindowClassWin32(void);
|
||||||
|
GLFWbool _glfwIsCompositionEnabledWin32(void);
|
||||||
|
|
||||||
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
||||||
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
||||||
void _glfwInputErrorWin32(int error, const char* description);
|
void _glfwInputErrorWin32(int error, const char* description);
|
||||||
|
void _glfwUpdateKeyNamesWin32(void);
|
||||||
|
|
||||||
void _glfwInitTimerWin32(void);
|
void _glfwInitTimerWin32(void);
|
||||||
|
|
||||||
|
@ -306,6 +306,55 @@ static void updateWindowStyles(const _GLFWwindow* window)
|
|||||||
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER);
|
SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOZORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update window framebuffer transparency
|
||||||
|
//
|
||||||
|
static void updateFramebufferTransparency(const _GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (!IsWindowsVistaOrGreater())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_glfwIsCompositionEnabledWin32())
|
||||||
|
{
|
||||||
|
HRGN region = CreateRectRgn(0, 0, -1, -1);
|
||||||
|
DWM_BLURBEHIND bb = {0};
|
||||||
|
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
|
||||||
|
bb.hRgnBlur = region;
|
||||||
|
bb.fEnable = TRUE;
|
||||||
|
|
||||||
|
if (SUCCEEDED(DwmEnableBlurBehindWindow(window->win32.handle, &bb)))
|
||||||
|
{
|
||||||
|
// Decorated windows don't repaint the transparent background
|
||||||
|
// leaving a trail behind animations
|
||||||
|
// HACK: Making the window layered with a transparency color key
|
||||||
|
// seems to fix this. Normally, when specifying
|
||||||
|
// a transparency color key to be used when composing the
|
||||||
|
// layered window, all pixels painted by the window in this
|
||||||
|
// color will be transparent. That doesn't seem to be the
|
||||||
|
// case anymore, at least when used with blur behind window
|
||||||
|
// plus negative region.
|
||||||
|
LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
||||||
|
exStyle |= WS_EX_LAYERED;
|
||||||
|
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
|
||||||
|
|
||||||
|
// Using a color key not equal to black to fix the trailing
|
||||||
|
// issue. When set to black, something is making the hit test
|
||||||
|
// not resize with the window frame.
|
||||||
|
SetLayeredWindowAttributes(window->win32.handle,
|
||||||
|
RGB(0, 193, 48), 255, LWA_COLORKEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteObject(region);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LONG exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
||||||
|
exStyle &= ~WS_EX_LAYERED;
|
||||||
|
SetWindowLongW(window->win32.handle, GWL_EXSTYLE, exStyle);
|
||||||
|
RedrawWindow(window->win32.handle, NULL, NULL,
|
||||||
|
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Translates a GLFW standard cursor to a resource ID
|
// Translates a GLFW standard cursor to a resource ID
|
||||||
//
|
//
|
||||||
static LPWSTR translateCursorShape(int shape)
|
static LPWSTR translateCursorShape(int shape)
|
||||||
@ -584,6 +633,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_INPUTLANGCHANGE:
|
||||||
|
{
|
||||||
|
_glfwUpdateKeyNamesWin32();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_CHAR:
|
case WM_CHAR:
|
||||||
case WM_SYSCHAR:
|
case WM_SYSCHAR:
|
||||||
case WM_UNICHAR:
|
case WM_UNICHAR:
|
||||||
@ -910,6 +965,13 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_DWMCOMPOSITIONCHANGED:
|
||||||
|
{
|
||||||
|
if (window->win32.transparent)
|
||||||
|
updateFramebufferTransparency(window);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
case WM_SETCURSOR:
|
case WM_SETCURSOR:
|
||||||
{
|
{
|
||||||
if (LOWORD(lParam) == HTCLIENT)
|
if (LOWORD(lParam) == HTCLIENT)
|
||||||
@ -975,7 +1037,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
// Creates the GLFW window
|
// Creates the GLFW window
|
||||||
//
|
//
|
||||||
static int createNativeWindow(_GLFWwindow* window,
|
static int createNativeWindow(_GLFWwindow* window,
|
||||||
const _GLFWwndconfig* wndconfig)
|
const _GLFWwndconfig* wndconfig,
|
||||||
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
int xpos, ypos, fullWidth, fullHeight;
|
int xpos, ypos, fullWidth, fullHeight;
|
||||||
WCHAR* wideTitle;
|
WCHAR* wideTitle;
|
||||||
@ -1033,18 +1096,24 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
|
|
||||||
SetPropW(window->win32.handle, L"GLFW", window);
|
SetPropW(window->win32.handle, L"GLFW", window);
|
||||||
|
|
||||||
if (_glfw_ChangeWindowMessageFilterEx)
|
if (IsWindows7OrGreater())
|
||||||
{
|
{
|
||||||
_glfw_ChangeWindowMessageFilterEx(window->win32.handle,
|
ChangeWindowMessageFilterEx(window->win32.handle,
|
||||||
WM_DROPFILES, MSGFLT_ALLOW, NULL);
|
WM_DROPFILES, MSGFLT_ALLOW, NULL);
|
||||||
_glfw_ChangeWindowMessageFilterEx(window->win32.handle,
|
ChangeWindowMessageFilterEx(window->win32.handle,
|
||||||
WM_COPYDATA, MSGFLT_ALLOW, NULL);
|
WM_COPYDATA, MSGFLT_ALLOW, NULL);
|
||||||
_glfw_ChangeWindowMessageFilterEx(window->win32.handle,
|
ChangeWindowMessageFilterEx(window->win32.handle,
|
||||||
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
DragAcceptFiles(window->win32.handle, TRUE);
|
DragAcceptFiles(window->win32.handle, TRUE);
|
||||||
|
|
||||||
|
if (fbconfig->transparent)
|
||||||
|
{
|
||||||
|
updateFramebufferTransparency(window);
|
||||||
|
window->win32.transparent = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1096,6 +1165,20 @@ void _glfwUnregisterWindowClassWin32(void)
|
|||||||
UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));
|
UnregisterClassW(_GLFW_WNDCLASSNAME, GetModuleHandleW(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns whether desktop compositing is enabled
|
||||||
|
//
|
||||||
|
GLFWbool _glfwIsCompositionEnabledWin32(void)
|
||||||
|
{
|
||||||
|
if (IsWindowsVistaOrGreater())
|
||||||
|
{
|
||||||
|
BOOL enabled;
|
||||||
|
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)))
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW platform API //////
|
////// GLFW platform API //////
|
||||||
@ -1106,7 +1189,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
const _GLFWfbconfig* fbconfig)
|
const _GLFWfbconfig* fbconfig)
|
||||||
{
|
{
|
||||||
if (!createNativeWindow(window, wndconfig))
|
if (!createNativeWindow(window, wndconfig, fbconfig))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
if (ctxconfig->client != GLFW_NO_API)
|
if (ctxconfig->client != GLFW_NO_API)
|
||||||
@ -1475,6 +1558,11 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
|||||||
return IsZoomed(window->win32.handle);
|
return IsZoomed(window->win32.handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
return window->win32.transparent && _glfwIsCompositionEnabledWin32();
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
updateWindowStyles(window);
|
updateWindowStyles(window);
|
||||||
@ -1652,20 +1740,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
|
|
||||||
const char* _glfwPlatformGetScancodeName(int scancode)
|
const char* _glfwPlatformGetScancodeName(int scancode)
|
||||||
{
|
{
|
||||||
WCHAR name[16];
|
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
|
||||||
|
|
||||||
if (!GetKeyNameTextW(scancode << 16, name, sizeof(name) / sizeof(WCHAR)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!WideCharToMultiByte(CP_UTF8, 0, name, -1,
|
|
||||||
_glfw.win32.keyName,
|
|
||||||
sizeof(_glfw.win32.keyName),
|
|
||||||
NULL, NULL))
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _glfw.win32.keyName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int _glfwPlatformGetKeyScancode(int key)
|
int _glfwPlatformGetKeyScancode(int key)
|
||||||
@ -1805,7 +1880,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|||||||
VkPhysicalDevice device,
|
VkPhysicalDevice device,
|
||||||
uint32_t queuefamily)
|
uint32_t queuefamily)
|
||||||
{
|
{
|
||||||
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR =
|
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
|
||||||
|
vkGetPhysicalDeviceWin32PresentationSupportKHR =
|
||||||
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
||||||
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
|
||||||
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
|
||||||
|
114
src/window.c
114
src/window.c
@ -278,119 +278,121 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
|||||||
{
|
{
|
||||||
case GLFW_RED_BITS:
|
case GLFW_RED_BITS:
|
||||||
_glfw.hints.framebuffer.redBits = value;
|
_glfw.hints.framebuffer.redBits = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_GREEN_BITS:
|
case GLFW_GREEN_BITS:
|
||||||
_glfw.hints.framebuffer.greenBits = value;
|
_glfw.hints.framebuffer.greenBits = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_BLUE_BITS:
|
case GLFW_BLUE_BITS:
|
||||||
_glfw.hints.framebuffer.blueBits = value;
|
_glfw.hints.framebuffer.blueBits = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_ALPHA_BITS:
|
case GLFW_ALPHA_BITS:
|
||||||
_glfw.hints.framebuffer.alphaBits = value;
|
_glfw.hints.framebuffer.alphaBits = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_DEPTH_BITS:
|
case GLFW_DEPTH_BITS:
|
||||||
_glfw.hints.framebuffer.depthBits = value;
|
_glfw.hints.framebuffer.depthBits = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_STENCIL_BITS:
|
case GLFW_STENCIL_BITS:
|
||||||
_glfw.hints.framebuffer.stencilBits = value;
|
_glfw.hints.framebuffer.stencilBits = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_ACCUM_RED_BITS:
|
case GLFW_ACCUM_RED_BITS:
|
||||||
_glfw.hints.framebuffer.accumRedBits = value;
|
_glfw.hints.framebuffer.accumRedBits = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_ACCUM_GREEN_BITS:
|
case GLFW_ACCUM_GREEN_BITS:
|
||||||
_glfw.hints.framebuffer.accumGreenBits = value;
|
_glfw.hints.framebuffer.accumGreenBits = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_ACCUM_BLUE_BITS:
|
case GLFW_ACCUM_BLUE_BITS:
|
||||||
_glfw.hints.framebuffer.accumBlueBits = value;
|
_glfw.hints.framebuffer.accumBlueBits = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_ACCUM_ALPHA_BITS:
|
case GLFW_ACCUM_ALPHA_BITS:
|
||||||
_glfw.hints.framebuffer.accumAlphaBits = value;
|
_glfw.hints.framebuffer.accumAlphaBits = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_AUX_BUFFERS:
|
case GLFW_AUX_BUFFERS:
|
||||||
_glfw.hints.framebuffer.auxBuffers = value;
|
_glfw.hints.framebuffer.auxBuffers = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_STEREO:
|
case GLFW_STEREO:
|
||||||
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_DOUBLEBUFFER:
|
case GLFW_DOUBLEBUFFER:
|
||||||
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
|
case GLFW_TRANSPARENT:
|
||||||
|
_glfw.hints.framebuffer.transparent = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
return;
|
||||||
case GLFW_SAMPLES:
|
case GLFW_SAMPLES:
|
||||||
_glfw.hints.framebuffer.samples = value;
|
_glfw.hints.framebuffer.samples = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_SRGB_CAPABLE:
|
case GLFW_SRGB_CAPABLE:
|
||||||
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_RESIZABLE:
|
case GLFW_RESIZABLE:
|
||||||
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_DECORATED:
|
case GLFW_DECORATED:
|
||||||
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_FOCUSED:
|
case GLFW_FOCUSED:
|
||||||
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_AUTO_ICONIFY:
|
case GLFW_AUTO_ICONIFY:
|
||||||
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_FLOATING:
|
case GLFW_FLOATING:
|
||||||
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_MAXIMIZED:
|
case GLFW_MAXIMIZED:
|
||||||
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_VISIBLE:
|
case GLFW_VISIBLE:
|
||||||
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
||||||
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_COCOA_FRAME_AUTOSAVE:
|
case GLFW_COCOA_FRAME_AUTOSAVE:
|
||||||
_glfw.hints.window.ns.frame = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.ns.frame = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
||||||
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_CENTER_CURSOR:
|
case GLFW_CENTER_CURSOR:
|
||||||
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_CLIENT_API:
|
case GLFW_CLIENT_API:
|
||||||
_glfw.hints.context.client = value;
|
_glfw.hints.context.client = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_CONTEXT_CREATION_API:
|
case GLFW_CONTEXT_CREATION_API:
|
||||||
_glfw.hints.context.source = value;
|
_glfw.hints.context.source = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_CONTEXT_VERSION_MAJOR:
|
case GLFW_CONTEXT_VERSION_MAJOR:
|
||||||
_glfw.hints.context.major = value;
|
_glfw.hints.context.major = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_CONTEXT_VERSION_MINOR:
|
case GLFW_CONTEXT_VERSION_MINOR:
|
||||||
_glfw.hints.context.minor = value;
|
_glfw.hints.context.minor = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_CONTEXT_ROBUSTNESS:
|
case GLFW_CONTEXT_ROBUSTNESS:
|
||||||
_glfw.hints.context.robustness = value;
|
_glfw.hints.context.robustness = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_OPENGL_FORWARD_COMPAT:
|
case GLFW_OPENGL_FORWARD_COMPAT:
|
||||||
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_OPENGL_DEBUG_CONTEXT:
|
case GLFW_OPENGL_DEBUG_CONTEXT:
|
||||||
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_CONTEXT_NO_ERROR:
|
case GLFW_CONTEXT_NO_ERROR:
|
||||||
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
|
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
break;
|
return;
|
||||||
case GLFW_OPENGL_PROFILE:
|
case GLFW_OPENGL_PROFILE:
|
||||||
_glfw.hints.context.profile = value;
|
_glfw.hints.context.profile = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_CONTEXT_RELEASE_BEHAVIOR:
|
case GLFW_CONTEXT_RELEASE_BEHAVIOR:
|
||||||
_glfw.hints.context.release = value;
|
_glfw.hints.context.release = value;
|
||||||
break;
|
return;
|
||||||
case GLFW_REFRESH_RATE:
|
case GLFW_REFRESH_RATE:
|
||||||
_glfw.hints.refreshRate = value;
|
_glfw.hints.refreshRate = value;
|
||||||
break;
|
return;
|
||||||
default:
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
||||||
@ -725,6 +727,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
|||||||
return _glfwPlatformWindowVisible(window);
|
return _glfwPlatformWindowVisible(window);
|
||||||
case GLFW_MAXIMIZED:
|
case GLFW_MAXIMIZED:
|
||||||
return _glfwPlatformWindowMaximized(window);
|
return _glfwPlatformWindowMaximized(window);
|
||||||
|
case GLFW_TRANSPARENT:
|
||||||
|
return _glfwPlatformFramebufferTransparent(window);
|
||||||
case GLFW_RESIZABLE:
|
case GLFW_RESIZABLE:
|
||||||
return window->resizable;
|
return window->resizable;
|
||||||
case GLFW_DECORATED:
|
case GLFW_DECORATED:
|
||||||
@ -770,40 +774,36 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
|
|||||||
|
|
||||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||||
|
|
||||||
switch (attrib)
|
if (attrib == GLFW_AUTO_ICONIFY)
|
||||||
{
|
window->autoIconify = value;
|
||||||
case GLFW_RESIZABLE:
|
else if (attrib == GLFW_RESIZABLE)
|
||||||
if (window->resizable != value)
|
|
||||||
{
|
{
|
||||||
|
if (window->resizable == value)
|
||||||
|
return;
|
||||||
|
|
||||||
window->resizable = value;
|
window->resizable = value;
|
||||||
if (!window->monitor)
|
if (!window->monitor)
|
||||||
_glfwPlatformSetWindowResizable(window, value);
|
_glfwPlatformSetWindowResizable(window, value);
|
||||||
}
|
}
|
||||||
|
else if (attrib == GLFW_DECORATED)
|
||||||
|
{
|
||||||
|
if (window->decorated == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GLFW_DECORATED:
|
|
||||||
if (window->decorated != value)
|
|
||||||
{
|
|
||||||
window->decorated = value;
|
window->decorated = value;
|
||||||
if (!window->monitor)
|
if (!window->monitor)
|
||||||
_glfwPlatformSetWindowDecorated(window, value);
|
_glfwPlatformSetWindowDecorated(window, value);
|
||||||
}
|
}
|
||||||
|
else if (attrib == GLFW_FLOATING)
|
||||||
|
{
|
||||||
|
if (window->floating == value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case GLFW_FLOATING:
|
|
||||||
if (window->floating != value)
|
|
||||||
{
|
|
||||||
window->floating = value;
|
window->floating = value;
|
||||||
if (!window->monitor)
|
if (!window->monitor)
|
||||||
_glfwPlatformSetWindowFloating(window, value);
|
_glfwPlatformSetWindowFloating(window, value);
|
||||||
}
|
}
|
||||||
return;
|
else
|
||||||
|
|
||||||
case GLFW_AUTO_ICONIFY:
|
|
||||||
window->autoIconify = value;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
|
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,6 +654,13 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
|||||||
return window->wl.maximized;
|
return window->wl.maximized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Wayland: Framebuffer transparency attribute not implemented yet");
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
@ -1019,7 +1026,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|||||||
VkPhysicalDevice device,
|
VkPhysicalDevice device,
|
||||||
uint32_t queuefamily)
|
uint32_t queuefamily)
|
||||||
{
|
{
|
||||||
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR =
|
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||||
|
vkGetPhysicalDeviceWaylandPresentationSupportKHR =
|
||||||
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)
|
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)
|
||||||
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
|
||||||
if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
|
if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
|
||||||
|
@ -237,8 +237,8 @@ static void createKeyTables(void)
|
|||||||
|
|
||||||
if (_glfw.x11.xkb.available)
|
if (_glfw.x11.xkb.available)
|
||||||
{
|
{
|
||||||
// Use XKB to determine physical key locations independently of the current
|
// Use XKB to determine physical key locations independently of the
|
||||||
// keyboard layout
|
// current keyboard layout
|
||||||
|
|
||||||
char name[XkbKeyNameLength + 1];
|
char name[XkbKeyNameLength + 1];
|
||||||
XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
|
XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
|
||||||
@ -651,6 +651,29 @@ static GLFWbool initExtensions(void)
|
|||||||
dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
|
dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glfw.x11.xrender.handle = dlopen("libXrender.so.1", RTLD_LAZY | RTLD_GLOBAL);
|
||||||
|
if (_glfw.x11.xrender.handle)
|
||||||
|
{
|
||||||
|
_glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension)
|
||||||
|
dlsym(_glfw.x11.xrender.handle, "XRenderQueryExtension");
|
||||||
|
_glfw.x11.xrender.QueryVersion = (PFN_XRenderQueryVersion)
|
||||||
|
dlsym(_glfw.x11.xrender.handle, "XRenderQueryVersion");
|
||||||
|
_glfw.x11.xrender.FindVisualFormat = (PFN_XRenderFindVisualFormat)
|
||||||
|
dlsym(_glfw.x11.xrender.handle, "XRenderFindVisualFormat");
|
||||||
|
|
||||||
|
if (XRenderQueryExtension(_glfw.x11.display,
|
||||||
|
&_glfw.x11.xrender.errorBase,
|
||||||
|
&_glfw.x11.xrender.eventBase))
|
||||||
|
{
|
||||||
|
if (XRenderQueryVersion(_glfw.x11.display,
|
||||||
|
&_glfw.x11.xrender.major,
|
||||||
|
&_glfw.x11.xrender.minor))
|
||||||
|
{
|
||||||
|
_glfw.x11.xrender.available = GLFW_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the key code LUT
|
// Update the key code LUT
|
||||||
// FIXME: We should listen to XkbMapNotify events to track changes to
|
// FIXME: We should listen to XkbMapNotify events to track changes to
|
||||||
// the keyboard mapping.
|
// the keyboard mapping.
|
||||||
@ -661,10 +684,7 @@ static GLFWbool initExtensions(void)
|
|||||||
|
|
||||||
// String format atoms
|
// String format atoms
|
||||||
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
|
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
|
||||||
_glfw.x11.UTF8_STRING =
|
_glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
|
||||||
XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
|
|
||||||
_glfw.x11.COMPOUND_STRING =
|
|
||||||
XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);
|
|
||||||
_glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);
|
_glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);
|
||||||
|
|
||||||
// Custom selection property atom
|
// Custom selection property atom
|
||||||
@ -675,6 +695,7 @@ static GLFWbool initExtensions(void)
|
|||||||
_glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
|
_glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
|
||||||
_glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
|
_glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
|
||||||
_glfw.x11.PRIMARY = XInternAtom(_glfw.x11.display, "PRIMARY", False);
|
_glfw.x11.PRIMARY = XInternAtom(_glfw.x11.display, "PRIMARY", False);
|
||||||
|
_glfw.x11.INCR = XInternAtom(_glfw.x11.display, "INCR", False);
|
||||||
_glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);
|
_glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);
|
||||||
|
|
||||||
// Clipboard manager atoms
|
// Clipboard manager atoms
|
||||||
@ -862,12 +883,13 @@ int _glfwPlatformInit(void)
|
|||||||
_glfw.x11.screen = DefaultScreen(_glfw.x11.display);
|
_glfw.x11.screen = DefaultScreen(_glfw.x11.display);
|
||||||
_glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
|
_glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
|
||||||
_glfw.x11.context = XUniqueContext();
|
_glfw.x11.context = XUniqueContext();
|
||||||
_glfw.x11.helperWindowHandle = createHelperWindow();
|
|
||||||
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
|
|
||||||
|
|
||||||
if (!initExtensions())
|
if (!initExtensions())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
_glfw.x11.helperWindowHandle = createHelperWindow();
|
||||||
|
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
|
||||||
|
|
||||||
if (XSupportsLocale())
|
if (XSupportsLocale())
|
||||||
{
|
{
|
||||||
XSetLocaleModifiers("");
|
XSetLocaleModifiers("");
|
||||||
|
@ -116,6 +116,13 @@ typedef int (* PFN_XISelectEvents)(Display*,Window,XIEventMask*,int);
|
|||||||
#define XIQueryVersion _glfw.x11.xi.QueryVersion
|
#define XIQueryVersion _glfw.x11.xi.QueryVersion
|
||||||
#define XISelectEvents _glfw.x11.xi.SelectEvents
|
#define XISelectEvents _glfw.x11.xi.SelectEvents
|
||||||
|
|
||||||
|
typedef Bool (* PFN_XRenderQueryExtension)(Display*,int*,int*);
|
||||||
|
typedef Status (* PFN_XRenderQueryVersion)(Display*dpy,int*,int*);
|
||||||
|
typedef XRenderPictFormat* (* PFN_XRenderFindVisualFormat)(Display*,Visual const*);
|
||||||
|
#define XRenderQueryExtension _glfw.x11.xrender.QueryExtension
|
||||||
|
#define XRenderQueryVersion _glfw.x11.xrender.QueryVersion
|
||||||
|
#define XRenderFindVisualFormat _glfw.x11.xrender.FindVisualFormat
|
||||||
|
|
||||||
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
||||||
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
|
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
|
||||||
|
|
||||||
@ -179,6 +186,9 @@ typedef struct _GLFWwindowX11
|
|||||||
GLFWbool iconified;
|
GLFWbool iconified;
|
||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
|
|
||||||
|
// Whether the visual supports framebuffer transparency
|
||||||
|
GLFWbool transparent;
|
||||||
|
|
||||||
// Cached position and size used to filter out duplicate events
|
// Cached position and size used to filter out duplicate events
|
||||||
int width, height;
|
int width, height;
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
@ -265,6 +275,7 @@ typedef struct _GLFWlibraryX11
|
|||||||
// Selection (clipboard) atoms
|
// Selection (clipboard) atoms
|
||||||
Atom TARGETS;
|
Atom TARGETS;
|
||||||
Atom MULTIPLE;
|
Atom MULTIPLE;
|
||||||
|
Atom INCR;
|
||||||
Atom CLIPBOARD;
|
Atom CLIPBOARD;
|
||||||
Atom PRIMARY;
|
Atom PRIMARY;
|
||||||
Atom CLIPBOARD_MANAGER;
|
Atom CLIPBOARD_MANAGER;
|
||||||
@ -372,6 +383,18 @@ typedef struct _GLFWlibraryX11
|
|||||||
PFN_XISelectEvents SelectEvents;
|
PFN_XISelectEvents SelectEvents;
|
||||||
} xi;
|
} xi;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GLFWbool available;
|
||||||
|
void* handle;
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
int eventBase;
|
||||||
|
int errorBase;
|
||||||
|
PFN_XRenderQueryExtension QueryExtension;
|
||||||
|
PFN_XRenderQueryVersion QueryVersion;
|
||||||
|
PFN_XRenderFindVisualFormat FindVisualFormat;
|
||||||
|
} xrender;
|
||||||
|
|
||||||
} _GLFWlibraryX11;
|
} _GLFWlibraryX11;
|
||||||
|
|
||||||
// X11-specific per-monitor data
|
// X11-specific per-monitor data
|
||||||
@ -407,6 +430,7 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
|
|||||||
Atom property,
|
Atom property,
|
||||||
Atom type,
|
Atom type,
|
||||||
unsigned char** value);
|
unsigned char** value);
|
||||||
|
GLFWbool _glfwIsVisualTransparentX11(Visual* visual);
|
||||||
|
|
||||||
void _glfwGrabErrorHandlerX11(void);
|
void _glfwGrabErrorHandlerX11(void);
|
||||||
void _glfwReleaseErrorHandlerX11(void);
|
void _glfwReleaseErrorHandlerX11(void);
|
||||||
|
310
src/x11_window.c
310
src/x11_window.c
@ -164,6 +164,17 @@ static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointe
|
|||||||
event->xproperty.atom == _glfw.x11.NET_FRAME_EXTENTS;
|
event->xproperty.atom == _glfw.x11.NET_FRAME_EXTENTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns whether it is a property event for the specified selection transfer
|
||||||
|
//
|
||||||
|
static Bool isSelPropNewValueNotify(Display* display, XEvent* event, XPointer pointer)
|
||||||
|
{
|
||||||
|
XEvent* notification = (XEvent*) pointer;
|
||||||
|
return event->type == PropertyNotify &&
|
||||||
|
event->xproperty.state == PropertyNewValue &&
|
||||||
|
event->xproperty.window == notification->xselection.requestor &&
|
||||||
|
event->xproperty.atom == notification->xselection.property;
|
||||||
|
}
|
||||||
|
|
||||||
// Translates a GLFW standard cursor to a font cursor shape
|
// Translates a GLFW standard cursor to a font cursor shape
|
||||||
//
|
//
|
||||||
static int translateCursorShape(int shape)
|
static int translateCursorShape(int shape)
|
||||||
@ -353,6 +364,7 @@ static void updateWindowMode(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enable compositor bypass
|
// Enable compositor bypass
|
||||||
|
if (!window->x11.transparent)
|
||||||
{
|
{
|
||||||
const unsigned long value = 1;
|
const unsigned long value = 1;
|
||||||
|
|
||||||
@ -391,6 +403,7 @@ static void updateWindowMode(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Disable compositor bypass
|
// Disable compositor bypass
|
||||||
|
if (!window->x11.transparent)
|
||||||
{
|
{
|
||||||
XDeleteProperty(_glfw.x11.display, window->x11.handle,
|
XDeleteProperty(_glfw.x11.display, window->x11.handle,
|
||||||
_glfw.x11.NET_WM_BYPASS_COMPOSITOR);
|
_glfw.x11.NET_WM_BYPASS_COMPOSITOR);
|
||||||
@ -449,6 +462,81 @@ static char** parseUriList(char* text, int* count)
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode a Unicode code point to a UTF-8 stream
|
||||||
|
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
||||||
|
//
|
||||||
|
static size_t encodeUTF8(char* s, unsigned int ch)
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
if (ch < 0x80)
|
||||||
|
s[count++] = (char) ch;
|
||||||
|
else if (ch < 0x800)
|
||||||
|
{
|
||||||
|
s[count++] = (ch >> 6) | 0xc0;
|
||||||
|
s[count++] = (ch & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
else if (ch < 0x10000)
|
||||||
|
{
|
||||||
|
s[count++] = (ch >> 12) | 0xe0;
|
||||||
|
s[count++] = ((ch >> 6) & 0x3f) | 0x80;
|
||||||
|
s[count++] = (ch & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
else if (ch < 0x110000)
|
||||||
|
{
|
||||||
|
s[count++] = (ch >> 18) | 0xf0;
|
||||||
|
s[count++] = ((ch >> 12) & 0x3f) | 0x80;
|
||||||
|
s[count++] = ((ch >> 6) & 0x3f) | 0x80;
|
||||||
|
s[count++] = (ch & 0x3f) | 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode a Unicode code point from a UTF-8 stream
|
||||||
|
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
||||||
|
//
|
||||||
|
#if defined(X_HAVE_UTF8_STRING)
|
||||||
|
static unsigned int decodeUTF8(const char** s)
|
||||||
|
{
|
||||||
|
unsigned int ch = 0, count = 0;
|
||||||
|
static const unsigned int offsets[] =
|
||||||
|
{
|
||||||
|
0x00000000u, 0x00003080u, 0x000e2080u,
|
||||||
|
0x03c82080u, 0xfa082080u, 0x82082080u
|
||||||
|
};
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ch = (ch << 6) + (unsigned char) **s;
|
||||||
|
(*s)++;
|
||||||
|
count++;
|
||||||
|
} while ((**s & 0xc0) == 0x80);
|
||||||
|
|
||||||
|
assert(count <= 6);
|
||||||
|
return ch - offsets[count - 1];
|
||||||
|
}
|
||||||
|
#endif /*X_HAVE_UTF8_STRING*/
|
||||||
|
|
||||||
|
// Convert the specified Latin-1 string to UTF-8
|
||||||
|
//
|
||||||
|
static char* convertLatin1toUTF8(const char* source)
|
||||||
|
{
|
||||||
|
size_t size = 1;
|
||||||
|
const char* sp;
|
||||||
|
|
||||||
|
for (sp = source; *sp; sp++)
|
||||||
|
size += (*sp & 0x80) ? 2 : 1;
|
||||||
|
|
||||||
|
char* target = calloc(size, 1);
|
||||||
|
char* tp = target;
|
||||||
|
|
||||||
|
for (sp = source; *sp; sp++)
|
||||||
|
tp += encodeUTF8(tp, *sp);
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
// Centers the cursor over the window client area
|
// Centers the cursor over the window client area
|
||||||
//
|
//
|
||||||
static void centerCursor(_GLFWwindow* window)
|
static void centerCursor(_GLFWwindow* window)
|
||||||
@ -491,6 +579,8 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
|
|||||||
visual,
|
visual,
|
||||||
AllocNone);
|
AllocNone);
|
||||||
|
|
||||||
|
window->x11.transparent = _glfwIsVisualTransparentX11(visual);
|
||||||
|
|
||||||
// Create the actual window
|
// Create the actual window
|
||||||
{
|
{
|
||||||
XSetWindowAttributes wa;
|
XSetWindowAttributes wa;
|
||||||
@ -672,9 +762,7 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char* selectionString = NULL;
|
char* selectionString = NULL;
|
||||||
const Atom formats[] = { _glfw.x11.UTF8_STRING,
|
const Atom formats[] = { _glfw.x11.UTF8_STRING, XA_STRING };
|
||||||
_glfw.x11.COMPOUND_STRING,
|
|
||||||
XA_STRING };
|
|
||||||
const int formatCount = sizeof(formats) / sizeof(formats[0]);
|
const int formatCount = sizeof(formats) / sizeof(formats[0]);
|
||||||
|
|
||||||
if (request->selection == _glfw.x11.PRIMARY)
|
if (request->selection == _glfw.x11.PRIMARY)
|
||||||
@ -696,7 +784,6 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
|
|||||||
const Atom targets[] = { _glfw.x11.TARGETS,
|
const Atom targets[] = { _glfw.x11.TARGETS,
|
||||||
_glfw.x11.MULTIPLE,
|
_glfw.x11.MULTIPLE,
|
||||||
_glfw.x11.UTF8_STRING,
|
_glfw.x11.UTF8_STRING,
|
||||||
_glfw.x11.COMPOUND_STRING,
|
|
||||||
XA_STRING };
|
XA_STRING };
|
||||||
|
|
||||||
XChangeProperty(_glfw.x11.display,
|
XChangeProperty(_glfw.x11.display,
|
||||||
@ -841,10 +928,8 @@ static const char* getSelectionString(Atom selection)
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
char** selectionString = NULL;
|
char** selectionString = NULL;
|
||||||
const Atom formats[] = { _glfw.x11.UTF8_STRING,
|
const Atom targets[] = { _glfw.x11.UTF8_STRING, XA_STRING };
|
||||||
_glfw.x11.COMPOUND_STRING,
|
const size_t targetCount = sizeof(targets) / sizeof(targets[0]);
|
||||||
XA_STRING };
|
|
||||||
const size_t formatCount = sizeof(formats) / sizeof(formats[0]);
|
|
||||||
|
|
||||||
if (selection == _glfw.x11.PRIMARY)
|
if (selection == _glfw.x11.PRIMARY)
|
||||||
selectionString = &_glfw.x11.primarySelectionString;
|
selectionString = &_glfw.x11.primarySelectionString;
|
||||||
@ -862,14 +947,17 @@ static const char* getSelectionString(Atom selection)
|
|||||||
free(*selectionString);
|
free(*selectionString);
|
||||||
*selectionString = NULL;
|
*selectionString = NULL;
|
||||||
|
|
||||||
for (i = 0; i < formatCount; i++)
|
for (i = 0; i < targetCount; i++)
|
||||||
{
|
{
|
||||||
char* data;
|
char* data;
|
||||||
XEvent event;
|
Atom actualType;
|
||||||
|
int actualFormat;
|
||||||
|
unsigned long itemCount, bytesAfter;
|
||||||
|
XEvent notification, dummy;
|
||||||
|
|
||||||
XConvertSelection(_glfw.x11.display,
|
XConvertSelection(_glfw.x11.display,
|
||||||
selection,
|
selection,
|
||||||
formats[i],
|
targets[i],
|
||||||
_glfw.x11.GLFW_SELECTION,
|
_glfw.x11.GLFW_SELECTION,
|
||||||
_glfw.x11.helperWindowHandle,
|
_glfw.x11.helperWindowHandle,
|
||||||
CurrentTime);
|
CurrentTime);
|
||||||
@ -877,29 +965,93 @@ static const char* getSelectionString(Atom selection)
|
|||||||
while (!XCheckTypedWindowEvent(_glfw.x11.display,
|
while (!XCheckTypedWindowEvent(_glfw.x11.display,
|
||||||
_glfw.x11.helperWindowHandle,
|
_glfw.x11.helperWindowHandle,
|
||||||
SelectionNotify,
|
SelectionNotify,
|
||||||
&event))
|
¬ification))
|
||||||
{
|
{
|
||||||
waitForEvent(NULL);
|
waitForEvent(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.xselection.property == None)
|
if (notification.xselection.property == None)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (_glfwGetWindowPropertyX11(event.xselection.requestor,
|
XCheckIfEvent(_glfw.x11.display,
|
||||||
event.xselection.property,
|
&dummy,
|
||||||
event.xselection.target,
|
isSelPropNewValueNotify,
|
||||||
(unsigned char**) &data))
|
(XPointer) ¬ification);
|
||||||
|
|
||||||
|
XGetWindowProperty(_glfw.x11.display,
|
||||||
|
notification.xselection.requestor,
|
||||||
|
notification.xselection.property,
|
||||||
|
0,
|
||||||
|
LONG_MAX,
|
||||||
|
True,
|
||||||
|
AnyPropertyType,
|
||||||
|
&actualType,
|
||||||
|
&actualFormat,
|
||||||
|
&itemCount,
|
||||||
|
&bytesAfter,
|
||||||
|
(unsigned char**) &data);
|
||||||
|
|
||||||
|
if (actualType == _glfw.x11.INCR)
|
||||||
{
|
{
|
||||||
|
size_t size = 1;
|
||||||
|
char* string = NULL;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
while (!XCheckIfEvent(_glfw.x11.display,
|
||||||
|
&dummy,
|
||||||
|
isSelPropNewValueNotify,
|
||||||
|
(XPointer) ¬ification))
|
||||||
|
{
|
||||||
|
waitForEvent(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree(data);
|
||||||
|
XGetWindowProperty(_glfw.x11.display,
|
||||||
|
notification.xselection.requestor,
|
||||||
|
notification.xselection.property,
|
||||||
|
0,
|
||||||
|
LONG_MAX,
|
||||||
|
True,
|
||||||
|
AnyPropertyType,
|
||||||
|
&actualType,
|
||||||
|
&actualFormat,
|
||||||
|
&itemCount,
|
||||||
|
&bytesAfter,
|
||||||
|
(unsigned char**) &data);
|
||||||
|
|
||||||
|
if (itemCount)
|
||||||
|
{
|
||||||
|
size += itemCount;
|
||||||
|
string = realloc(string, size);
|
||||||
|
string[size - itemCount - 1] = '\0';
|
||||||
|
strcat(string, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!itemCount)
|
||||||
|
{
|
||||||
|
if (targets[i] == XA_STRING)
|
||||||
|
{
|
||||||
|
*selectionString = convertLatin1toUTF8(string);
|
||||||
|
free(string);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*selectionString = string;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (actualType == targets[i])
|
||||||
|
{
|
||||||
|
if (targets[i] == XA_STRING)
|
||||||
|
*selectionString = convertLatin1toUTF8(data);
|
||||||
|
else
|
||||||
*selectionString = strdup(data);
|
*selectionString = strdup(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data)
|
|
||||||
XFree(data);
|
XFree(data);
|
||||||
|
|
||||||
XDeleteProperty(_glfw.x11.display,
|
|
||||||
event.xselection.requestor,
|
|
||||||
event.xselection.property);
|
|
||||||
|
|
||||||
if (*selectionString)
|
if (*selectionString)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -907,7 +1059,7 @@ static const char* getSelectionString(Atom selection)
|
|||||||
if (!*selectionString)
|
if (!*selectionString)
|
||||||
{
|
{
|
||||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||||
"X11: Failed to convert clipboard to string");
|
"X11: Failed to convert selection to string");
|
||||||
}
|
}
|
||||||
|
|
||||||
return *selectionString;
|
return *selectionString;
|
||||||
@ -978,62 +1130,6 @@ static void releaseMonitor(_GLFWwindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode a Unicode code point to a UTF-8 stream
|
|
||||||
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
|
||||||
//
|
|
||||||
static size_t encodeUTF8(char* s, unsigned int ch)
|
|
||||||
{
|
|
||||||
size_t count = 0;
|
|
||||||
|
|
||||||
if (ch < 0x80)
|
|
||||||
s[count++] = (char) ch;
|
|
||||||
else if (ch < 0x800)
|
|
||||||
{
|
|
||||||
s[count++] = (ch >> 6) | 0xc0;
|
|
||||||
s[count++] = (ch & 0x3f) | 0x80;
|
|
||||||
}
|
|
||||||
else if (ch < 0x10000)
|
|
||||||
{
|
|
||||||
s[count++] = (ch >> 12) | 0xe0;
|
|
||||||
s[count++] = ((ch >> 6) & 0x3f) | 0x80;
|
|
||||||
s[count++] = (ch & 0x3f) | 0x80;
|
|
||||||
}
|
|
||||||
else if (ch < 0x110000)
|
|
||||||
{
|
|
||||||
s[count++] = (ch >> 18) | 0xf0;
|
|
||||||
s[count++] = ((ch >> 12) & 0x3f) | 0x80;
|
|
||||||
s[count++] = ((ch >> 6) & 0x3f) | 0x80;
|
|
||||||
s[count++] = (ch & 0x3f) | 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode a Unicode code point from a UTF-8 stream
|
|
||||||
// Based on cutef8 by Jeff Bezanson (Public Domain)
|
|
||||||
//
|
|
||||||
#if defined(X_HAVE_UTF8_STRING)
|
|
||||||
static unsigned int decodeUTF8(const char** s)
|
|
||||||
{
|
|
||||||
unsigned int ch = 0, count = 0;
|
|
||||||
static const unsigned int offsets[] =
|
|
||||||
{
|
|
||||||
0x00000000u, 0x00003080u, 0x000e2080u,
|
|
||||||
0x03c82080u, 0xfa082080u, 0x82082080u
|
|
||||||
};
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
ch = (ch << 6) + (unsigned char) **s;
|
|
||||||
(*s)++;
|
|
||||||
count++;
|
|
||||||
} while ((**s & 0xc0) == 0x80);
|
|
||||||
|
|
||||||
assert(count <= 6);
|
|
||||||
return ch - offsets[count - 1];
|
|
||||||
}
|
|
||||||
#endif /*X_HAVE_UTF8_STRING*/
|
|
||||||
|
|
||||||
// Process the specified X event
|
// Process the specified X event
|
||||||
//
|
//
|
||||||
static void processEvent(XEvent *event)
|
static void processEvent(XEvent *event)
|
||||||
@ -1171,8 +1267,10 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
count = XwcLookupString(window->x11.ic,
|
count = XwcLookupString(window->x11.ic,
|
||||||
&event->xkey,
|
&event->xkey,
|
||||||
buffer, sizeof(buffer) / sizeof(wchar_t),
|
buffer,
|
||||||
NULL, &status);
|
sizeof(buffer) / sizeof(wchar_t),
|
||||||
|
NULL,
|
||||||
|
&status);
|
||||||
|
|
||||||
if (status == XBufferOverflow)
|
if (status == XBufferOverflow)
|
||||||
{
|
{
|
||||||
@ -1345,7 +1443,8 @@ static void processEvent(XEvent *event)
|
|||||||
const int x = event->xmotion.x;
|
const int x = event->xmotion.x;
|
||||||
const int y = event->xmotion.y;
|
const int y = event->xmotion.y;
|
||||||
|
|
||||||
if (x != window->x11.warpCursorPosX || y != window->x11.warpCursorPosY)
|
if (x != window->x11.warpCursorPosX ||
|
||||||
|
y != window->x11.warpCursorPosY)
|
||||||
{
|
{
|
||||||
// The cursor was moved by something other than GLFW
|
// The cursor was moved by something other than GLFW
|
||||||
|
|
||||||
@ -1424,14 +1523,15 @@ static void processEvent(XEvent *event)
|
|||||||
|
|
||||||
if (protocol == _glfw.x11.WM_DELETE_WINDOW)
|
if (protocol == _glfw.x11.WM_DELETE_WINDOW)
|
||||||
{
|
{
|
||||||
// The window manager was asked to close the window, for example by
|
// The window manager was asked to close the window, for
|
||||||
// the user pressing a 'close' window decoration button
|
// example by the user pressing a 'close' window decoration
|
||||||
|
// button
|
||||||
_glfwInputWindowCloseRequest(window);
|
_glfwInputWindowCloseRequest(window);
|
||||||
}
|
}
|
||||||
else if (protocol == _glfw.x11.NET_WM_PING)
|
else if (protocol == _glfw.x11.NET_WM_PING)
|
||||||
{
|
{
|
||||||
// The window manager is pinging the application to ensure it's
|
// The window manager is pinging the application to ensure
|
||||||
// still responding to events
|
// it's still responding to events
|
||||||
|
|
||||||
XEvent reply = *event;
|
XEvent reply = *event;
|
||||||
reply.xclient.window = _glfw.x11.root;
|
reply.xclient.window = _glfw.x11.root;
|
||||||
@ -1742,6 +1842,15 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
|
|||||||
return itemCount;
|
return itemCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWbool _glfwIsVisualTransparentX11(Visual* visual)
|
||||||
|
{
|
||||||
|
if (!_glfw.x11.xrender.available)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
XRenderPictFormat* pf = XRenderFindVisualFormat(_glfw.x11.display, visual);
|
||||||
|
return pf && pf->direct.alphaMask;
|
||||||
|
}
|
||||||
|
|
||||||
// Push contents of our selection to clipboard manager
|
// Push contents of our selection to clipboard manager
|
||||||
//
|
//
|
||||||
void _glfwPushSelectionToManagerX11(void)
|
void _glfwPushSelectionToManagerX11(void)
|
||||||
@ -1773,9 +1882,10 @@ void _glfwPushSelectionToManagerX11(void)
|
|||||||
{
|
{
|
||||||
if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
|
if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
|
||||||
{
|
{
|
||||||
// This means one of two things; either the selection was
|
// This means one of two things; either the selection
|
||||||
// not owned, which means there is no clipboard manager, or
|
// was not owned, which means there is no clipboard
|
||||||
// the transfer to the clipboard manager has completed
|
// manager, or the transfer to the clipboard manager has
|
||||||
|
// completed
|
||||||
// In either case, it means we are done here
|
// In either case, it means we are done here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1808,14 +1918,14 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
|||||||
{
|
{
|
||||||
if (!_glfwInitGLX())
|
if (!_glfwInitGLX())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
|
if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
|
||||||
{
|
{
|
||||||
if (!_glfwInitEGL())
|
if (!_glfwInitEGL())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
|
if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth))
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
}
|
}
|
||||||
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
||||||
@ -2325,6 +2435,18 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
|||||||
return maximized;
|
return maximized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||||
|
{
|
||||||
|
if (!window->x11.transparent)
|
||||||
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
// Check whether a compositing manager is running
|
||||||
|
char name[32];
|
||||||
|
snprintf(name, sizeof(name), "_NET_WM_CM_S%u", _glfw.x11.screen);
|
||||||
|
const Atom selection = XInternAtom(_glfw.x11.display, name, False);
|
||||||
|
return XGetSelectionOwner(_glfw.x11.display, selection) != None;
|
||||||
|
}
|
||||||
|
|
||||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
@ -2695,7 +2817,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|||||||
|
|
||||||
if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)
|
if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)
|
||||||
{
|
{
|
||||||
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR =
|
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR
|
||||||
|
vkGetPhysicalDeviceXcbPresentationSupportKHR =
|
||||||
(PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)
|
(PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)
|
||||||
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
|
||||||
if (!vkGetPhysicalDeviceXcbPresentationSupportKHR)
|
if (!vkGetPhysicalDeviceXcbPresentationSupportKHR)
|
||||||
@ -2720,7 +2843,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR =
|
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR
|
||||||
|
vkGetPhysicalDeviceXlibPresentationSupportKHR =
|
||||||
(PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)
|
(PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)
|
||||||
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
|
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
|
||||||
if (!vkGetPhysicalDeviceXlibPresentationSupportKHR)
|
if (!vkGetPhysicalDeviceXlibPresentationSupportKHR)
|
||||||
|
Loading…
Reference in New Issue
Block a user