Merge branch 'master' into android

This commit is contained in:
Curi0 2017-09-30 17:25:58 +05:30
commit 9b9cfc1914
40 changed files with 1037 additions and 393 deletions

View 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}")

View File

@ -45,8 +45,8 @@ guide](http://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
## Compiling GLFW
GLFW itself requires only the headers and libraries for your window system. It
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL,
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
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)
- Added headless [OSMesa](http://mesa3d.org/osmesa.html) backend (#850)
- 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
(#749,#842)
- 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_OSMESA_CONTEXT_API` for creating OpenGL contexts with
[OSMesa](https://www.mesa3d.org/osmesa.html) (#281)
- Added `GenerateMappings.cmake` script for updating gamepad mappings
- Removed `GLFW_USE_RETINA` compile-time option
- Removed `GLFW_USE_CHDIR` compile-time option
- Removed `GLFW_USE_MENUBAR` compile-time option
@ -173,6 +176,7 @@ information on what to include when reporting a bug.
`vkGetInstanceProcAddr` when `_GLFW_VULKAN_STATIC` was enabled
- Bugfix: Invalid library paths were used in test and example CMake files (#930)
- Bugfix: The scancode for synthetic key release events was always zero
- Bugfix: The generated Doxyfile did not handle paths with spaces (#1081)
- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
@ -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: Disabled cursor mode prevented use of caption buttons
(#650,#1071)
- [Win32] Bugfix: Returned key names did not match other platforms (#943)
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
- [X11] Replaced `_GLFW_HAS_XF86VM` compile-time option with dynamic loading
- [X11] Bugfix: `glfwGetVideoMode` would segfault on Cygwin/X
@ -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: Gamma ramp setting via RandR did not validate ramp size
- [X11] Bugfix: Key name string encoding depended on current locale (#981,#983)
- [X11] Bugfix: Incremental reading of selections was not supported (#275)
- [X11] Bugfix: Selection I/O reported but did not support `COMPOUND_TEXT`
- [X11] Bugfix: Latin-1 text read from selections was not converted to UTF-8
- [Linux] Moved to evdev for joystick input (#906,#1005)
- [Linux] Bugfix: Event processing did not detect joystick disconnection (#932)
- [Linux] Bugfix: The joystick device path could be truncated (#1025)
@ -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
notification was shown (#971,#1028)
- [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_ARB_create_context_no_error`
- [GLX] Added support for `GLX_ARB_create_context_no_error`
@ -283,6 +292,7 @@ skills.
- Yaron Cohen-Tal
- Omar Cornut
- Andrew Corrigan
- Bailey Cosier
- Noel Cower
- Jason Daly
- Jarrod Davis
@ -291,6 +301,7 @@ skills.
- Michael Dickens
- Роман Донченко
- Mario Dorn
- Wolfgang Draxinger
- Jonathan Dummer
- Ralph Eastwood
- Fredrik Ehnbom
@ -316,6 +327,7 @@ skills.
- Erik S. V. Jansson
- Toni Jovanoski
- Arseny Kapoulkine
- Cem Karan
- Osman Keskin
- Josh Kilmer
- Cameron King
@ -357,6 +369,7 @@ skills.
- Andri Pálsson
- Peoro
- Braden Pellett
- Christopher Pelloux
- Arturo J. Pérez
- Anthony Pesch
- Orson Peters

View File

@ -23,7 +23,7 @@ if (GLFW_DOCUMENT_INTERNALS)
endif()
foreach(arg ${glfw_DOCS_SOURCES})
set(GLFW_DOCS_SOURCES "${GLFW_DOCS_SOURCES} ${arg}")
set(GLFW_DOCS_SOURCES "${GLFW_DOCS_SOURCES} \\\n\"${arg}\"")
endforeach()
configure_file(Doxyfile.in Doxyfile @ONLY)

View File

@ -52,7 +52,7 @@ PROJECT_LOGO =
# 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.
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
# 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
# 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
@ -722,7 +722,7 @@ EXCLUDE_SYMBOLS = APIENTRY GLFWAPI
# directories that contain example code fragments that are included (see
# 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
# 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
# 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
# each generated HTML page. If it is left blank doxygen will generate a
# 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
# 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
# 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
# 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
# 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.
# Doxygen will adjust the colors in the style sheet and background images

View File

@ -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
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

View File

@ -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
external version.
If you are using a custom name for the Vulkan, EGL, GLX, OSMesa, OpenGL, GLESv1
or GLESv2 library, you can override the default names by defining those you need
of @b _GLFW_VULKAN_LIBRARY, @b _GLFW_EGL_LIBRARY, @b _GLFW_GLX_LIBRARY, @b
_GLFW_OSMESA_LIBRARY, @b _GLFW_OPENGL_LIBRARY, @b _GLFW_GLESV1_LIBRARY and @b
_GLFW_GLESV2_LIBRARY. Otherwise, GLFW will use the built-in default names.
For the EGL context creation API, the following options are available:
- @b _GLFW_USE_EGLPLATFORM_H to use `EGL/eglplatform.h` for native handle

View File

@ -25,7 +25,6 @@ $extrastylesheet
<ul class="glfwnavbar">
<li><a href="http://www.glfw.org/documentation.html">Documentation</a></li>
<li><a href="http://www.glfw.org/download.html">Download</a></li>
<li><a href="http://www.glfw.org/media.html">Media</a></li>
<li><a href="http://www.glfw.org/community.html">Community</a></li>
</ul>
</div>

View File

@ -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
them. Setting these hints requires no platform specific headers or functions.
@subsubsection init_hints_shared Shared init hints
@anchor GLFW_JOYSTICK_HAT_BUTTONS
__GLFW_JOYSTICK_HAT_BUTTONS__ specifies whether to also expose joystick hats as
buttons, for compatibility with earlier versions of GLFW that did not have @ref
@ -299,35 +302,39 @@ functions not on this list will not be made non-reentrant.
@subsection thread_safety Thread safety
Most GLFW functions must only be called from the main thread, but some may be
called from any thread. However, no GLFW function may be called from any thread
but the main thread until GLFW has been successfully initialized, including
functions that may called before initialization.
Most GLFW functions must only be called from the main thread (the thread that
calls main), but some may be called from any thread once the library has been
initialized. Before initialization the whole library is thread-unsafe.
The reference documentation for every GLFW function states whether it is limited
to the main thread.
Initialization and termination, event processing and the creation and
destruction of windows, contexts and cursors are all limited to the main thread
due to limitations of one or several platforms.
Initialization, termination, event processing and the creation and
destruction of windows, cursors and OpenGL and OpenGL ES contexts are all
restricted to the main thread due to limitations of one or several platforms.
Because event processing must be performed on the main thread, all callbacks
except for the error callback will only be called on that thread. The error
callback may be called on any thread, as any GLFW function may generate errors.
The posting of empty events may be done from any thread. The window user
pointer and close flag may also be accessed and modified from any thread, but
this is not synchronized by GLFW. The following window related functions may
be called from any thread:
The error code and description may be queried from any thread.
- @ref glfwGetError
Empty events may be posted from any thread.
- @ref glfwPostEmptyEvent
The window user pointer and close flag may be read and written from any thread,
but this is not synchronized by GLFW.
- @ref glfwGetWindowUserPointer
- @ref glfwSetWindowUserPointer
- @ref glfwWindowShouldClose
- @ref glfwSetWindowShouldClose
Rendering may be done on any thread. The following context related functions
may be called from any thread:
These functions for working with OpenGL and OpenGL ES contexts may be called
from any thread, but the window object is not synchronized by GLFW.
- @ref glfwMakeContextCurrent
- @ref glfwGetCurrentContext
@ -336,27 +343,23 @@ may be called from any thread:
- @ref glfwExtensionSupported
- @ref glfwGetProcAddress
The raw timer may be queried from any thread. The following raw timer related
functions may be called from any thread:
The raw timer functions may be called from any thread.
- @ref glfwGetTimerFrequency
- @ref glfwGetTimerValue
The regular timer may be used from any thread, but the reading and writing of
the timer offset is not synchronized by GLFW. The following timer related
functions may be called from any thread:
The regular timer may be used from any thread, but reading and writing the timer
offset is not synchronized by GLFW.
- @ref glfwGetTime
- @ref glfwSetTime
Library version information may be queried from any thread. The following
version related functions may be called from any thread:
Library version information may be queried from any thread.
- @ref glfwGetVersion
- @ref glfwGetVersionString
Vulkan objects may be created and information queried from any thread. The
following Vulkan related functions may be called from any thread:
All Vulkan related functions may be called from any thread.
- @ref glfwVulkanSupported
- @ref glfwGetRequiredInstanceExtensions
@ -364,9 +367,9 @@ following Vulkan related functions may be called from any thread:
- @ref glfwGetPhysicalDevicePresentationSupport
- @ref glfwCreateWindowSurface
GLFW uses no synchronization objects internally except for thread-local storage
to keep track of the current context for each thread. Synchronization is left
to the application.
GLFW uses synchronization objects internally only to manage the per-thread
context and error states. Additional synchronization is left to the
application.
Functions that may currently be called from any thread will always remain so,
but functions that are currently limited to the main thread may be updated to

View File

@ -85,6 +85,13 @@ be disabled with the @ref GLFW_JOYSTICK_HAT_BUTTONS init hint.
@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
GLFW now supports controlling whether the cursor is centered over newly created

View File

@ -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
`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
@ -470,6 +477,7 @@ GLFW_AUTO_ICONIFY | `GLFW_TRUE` | `GLFW_TRUE` or `GL
GLFW_FLOATING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_MAXIMIZED | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_TRANSPARENT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE`
@ -1061,6 +1069,30 @@ window contents are saved off-screen, this callback might only be called when
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
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
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

View File

@ -172,6 +172,7 @@ static GLfloat angle = 0.f;
/* OpenGL draw function & timing */
static void draw(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
@ -311,6 +312,7 @@ int main(int argc, char *argv[])
}
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_TRANSPARENT, GLFW_TRUE);
window = glfwCreateWindow( 300, 300, "Gears", NULL, NULL );
if (!window)

View File

@ -787,6 +787,12 @@ extern "C" {
* Cursor centering [window hint](@ref GLFW_CENTER_CURSOR_hint).
*/
#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.
*
@ -868,6 +874,7 @@ extern "C" {
* Framebuffer double buffering [hint](@ref GLFW_DOUBLEBUFFER).
*/
#define GLFW_DOUBLEBUFFER 0x00021010
/*! @brief Context client API hint and attribute.
*
* Context client API [hint](@ref GLFW_CLIENT_API_hint) and

View File

@ -215,8 +215,9 @@ static GLFWbool updateUnicodeDataNS(void)
return GLFW_FALSE;
}
_glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
_glfw.ns.unicodeData =
TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
if (!_glfw.ns.unicodeData)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@ -232,7 +233,8 @@ static GLFWbool updateUnicodeDataNS(void)
static GLFWbool initializeTIS(void)
{
// This works only because Cocoa has already loaded it properly
_glfw.ns.tis.bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
_glfw.ns.tis.bundle =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
if (!_glfw.ns.tis.bundle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,

View File

@ -73,7 +73,9 @@ static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
// 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* se = sp;
@ -183,7 +185,8 @@ static void matchCallback(void* context,
for (i = 0; i < CFArrayGetCount(elements); i++)
{
IOHIDElementRef native = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i);
IOHIDElementRef native = (IOHIDElementRef)
CFArrayGetValueAtIndex(elements, i);
if (CFGetTypeID(native) != IOHIDElementGetTypeID())
continue;

View File

@ -54,7 +54,8 @@ static char* getDisplayName(CGDirectDisplayID displayID)
while ((service = IOIteratorNext(it)) != 0)
{
info = IODisplayCreateInfoDictionary(service, kIODisplayOnlyPreferredName);
info = IODisplayCreateInfoDictionary(service,
kIODisplayOnlyPreferredName);
CFNumberRef vendorIDRef =
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
@ -185,7 +186,13 @@ static CGDisplayFadeReservationToken beginFadeReservation(void)
CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
CGDisplayFade(token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
{
CGDisplayFade(token, 0.3,
kCGDisplayBlendNormal,
kCGDisplayBlendSolidColor,
0.0, 0.0, 0.0,
TRUE);
}
return token;
}
@ -196,7 +203,11 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
{
if (token != kCGDisplayFadeReservationInvalidToken)
{
CGDisplayFade(token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
CGDisplayFade(token, 0.5,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal,
0.0, 0.0, 0.0,
FALSE);
CGReleaseDisplayFadeReservation(token);
}
}

View File

@ -228,13 +228,13 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
_GLFWwindow* window;
}
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow;
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;
@end
@implementation GLFWWindowDelegate
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow
{
self = [super init];
if (self != nil)
@ -381,13 +381,13 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
NSMutableAttributedString* markedText;
}
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow;
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow;
@end
@implementation GLFWContentView
- (id)initWithGlfwWindow:(_GLFWwindow *)initWindow
- (instancetype)initWithGlfwWindow:(_GLFWwindow *)initWindow
{
self = [super init];
if (self != nil)
@ -413,7 +413,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (BOOL)isOpaque
{
return YES;
return [window->ns.object isOpaque];
}
- (BOOL)canBecomeKeyView
@ -1012,7 +1012,8 @@ static GLFWbool initializeAppKit(void)
// Create the Cocoa window
//
static GLFWbool createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig)
const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig* fbconfig)
{
window->ns.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window];
if (window->ns.delegate == nil)
@ -1081,6 +1082,12 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
if (wndconfig->ns.retina)
[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 makeFirstResponder:window->ns.view];
[window->ns.object setTitle:[NSString stringWithUTF8String:wndconfig->title]];
@ -1104,7 +1111,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
if (!initializeAppKit())
return GLFW_FALSE;
if (!createNativeWindow(window, wndconfig))
if (!createNativeWindow(window, wndconfig, fbconfig))
return GLFW_FALSE;
if (ctxconfig->client != GLFW_NO_API)
@ -1175,7 +1182,11 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
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,
@ -1420,6 +1431,9 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
[window->ns.object setLevel:NSNormalWindowLevel];
[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];
}
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
{
return ![window->ns.object isOpaque] && ![window->ns.view isOpaque];
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
{
[window->ns.object setStyleMask:getStyleMask(window)];

View File

@ -208,6 +208,9 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
// not important to us here, so we count them as one
missing++;
}
if (desired->transparent != current->transparent)
missing++;
}
// These polynomials make many small channel size differences matter

View File

@ -121,9 +121,25 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
continue;
#if defined(_GLFW_X11)
XVisualInfo vi = {0};
// 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;
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
if (ctxconfig->client == GLFW_OPENGL_ES_API)
@ -286,7 +302,9 @@ GLFWbool _glfwInitEGL(void)
int i;
const char* sonames[] =
{
#if defined(_GLFW_WIN32)
#if defined(_GLFW_EGL_LIBRARY)
_GLFW_EGL_LIBRARY,
#elif defined(_GLFW_WIN32)
"libEGL.dll",
"EGL.dll",
#elif defined(_GLFW_COCOA)
@ -605,7 +623,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const char** sonames;
const char* es1sonames[] =
{
#if defined(_GLFW_WIN32)
#if defined(_GLFW_GLESV1_LIBRARY)
_GLFW_GLESV1_LIBRARY,
#elif defined(_GLFW_WIN32)
"GLESv1_CM.dll",
"libGLES_CM.dll",
#elif defined(_GLFW_COCOA)
@ -618,7 +638,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
};
const char* es2sonames[] =
{
#if defined(_GLFW_WIN32)
#if defined(_GLFW_GLESV2_LIBRARY)
_GLFW_GLESV2_LIBRARY,
#elif defined(_GLFW_WIN32)
"GLESv2.dll",
"libGLESv2.dll",
#elif defined(_GLFW_COCOA)
@ -632,7 +654,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
};
const char* glsonames[] =
{
#if defined(_GLFW_WIN32)
#if defined(_GLFW_OPENGL_LIBRARY)
_GLFW_OPENGL_LIBRARY,
#elif defined(_GLFW_WIN32)
#elif defined(_GLFW_COCOA)
#else
"libGL.so.1",
@ -685,7 +709,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
// Returns the Visual and depth of the chosen EGLConfig
//
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth)
{

View File

@ -187,7 +187,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);
#endif /*_GLFW_X11*/

View File

@ -47,7 +47,8 @@ static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
// 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;
_GLFWfbconfig* usableConfigs;
@ -89,6 +90,16 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* res
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->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
@ -244,7 +255,9 @@ GLFWbool _glfwInitGLX(void)
int i;
const char* sonames[] =
{
#if defined(__CYGWIN__)
#if defined(_GLFW_GLX_LIBRARY)
_GLFW_GLX_LIBRARY,
#elif defined(__CYGWIN__)
"libGL-1.so",
#else
"libGL.so.1",
@ -620,7 +633,8 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
// 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,
Visual** visual, int* depth)
{
@ -643,7 +657,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
}
*visual = result->visual;
*depth = result->depth;
*depth = result->depth;
XFree(result);
return GLFW_TRUE;

View File

@ -168,14 +168,14 @@ typedef struct _GLFWlibraryGLX
} _GLFWlibraryGLX;
GLFWbool _glfwInitGLX(void);
void _glfwTerminateGLX(void);
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextGLX(_GLFWwindow* window);
GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth);

View File

@ -354,10 +354,10 @@ GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
return window->stickyKeys;
case GLFW_STICKY_MOUSE_BUTTONS:
return window->stickyMouseButtons;
default:
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
return 0;
}
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
return 0;
}
GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
@ -367,79 +367,72 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
_GLFW_REQUIRE_INIT();
switch (mode)
if (mode == GLFW_CURSOR)
{
case GLFW_CURSOR:
if (value != GLFW_CURSOR_NORMAL &&
value != GLFW_CURSOR_HIDDEN &&
value != GLFW_CURSOR_DISABLED)
{
if (value != GLFW_CURSOR_NORMAL &&
value != GLFW_CURSOR_HIDDEN &&
value != GLFW_CURSOR_DISABLED)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid cursor mode 0x%08X",
value);
return;
}
if (window->cursorMode == value)
return;
window->cursorMode = value;
_glfwPlatformGetCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
if (_glfwPlatformWindowFocused(window))
_glfwPlatformSetCursorMode(window, value);
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid cursor mode 0x%08X",
value);
return;
}
case GLFW_STICKY_KEYS:
{
if (window->stickyKeys == value)
return;
if (!value)
{
int i;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
{
if (window->keys[i] == _GLFW_STICK)
window->keys[i] = GLFW_RELEASE;
}
}
window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
if (window->cursorMode == value)
return;
}
case GLFW_STICKY_MOUSE_BUTTONS:
{
if (window->stickyMouseButtons == value)
return;
window->cursorMode = value;
if (!value)
{
int i;
_glfwPlatformGetCursorPos(window,
&window->virtualCursorPosX,
&window->virtualCursorPosY);
// Release all sticky mouse buttons
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{
if (window->mouseButtons[i] == _GLFW_STICK)
window->mouseButtons[i] = GLFW_RELEASE;
}
}
window->stickyMouseButtons = value ? GLFW_TRUE : GLFW_FALSE;
return;
}
if (_glfwPlatformWindowFocused(window))
_glfwPlatformSetCursorMode(window, value);
}
else if (mode == GLFW_STICKY_KEYS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyKeys == value)
return;
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
if (!value)
{
int i;
// Release all sticky keys
for (i = 0; i <= GLFW_KEY_LAST; i++)
{
if (window->keys[i] == _GLFW_STICK)
window->keys[i] = GLFW_RELEASE;
}
}
window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
}
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
{
value = value ? GLFW_TRUE : GLFW_FALSE;
if (window->stickyMouseButtons == value)
return;
if (!value)
{
int i;
// Release all sticky mouse buttons
for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
{
if (window->mouseButtons[i] == _GLFW_STICK)
window->mouseButtons[i] = GLFW_RELEASE;
}
}
window->stickyMouseButtons = value ? GLFW_TRUE : GLFW_FALSE;
}
else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
}
GLFWAPI const char* glfwGetKeyName(int key, int scancode)

View File

@ -362,6 +362,7 @@ struct _GLFWfbconfig
int samples;
GLFWbool sRGB;
GLFWbool doublebuffer;
GLFWbool transparent;
uintptr_t handle;
};
@ -686,6 +687,7 @@ int _glfwPlatformWindowFocused(_GLFWwindow* window);
int _glfwPlatformWindowIconified(_GLFWwindow* window);
int _glfwPlatformWindowVisible(_GLFWwindow* window);
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);

View File

@ -23,6 +23,16 @@
// 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:
@ -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"
"05000000ac0500003232000001000000,VR-BOX,platform:Linux,a:b0,b:b1,x:b2,y:b3,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b6,rightshoulder:b7,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,leftx:a0,lefty:a1,rightx:a3,righty:a2,lefttrigger:b4,righttrigger:b5,\n"
"03000000780000000600000010010000,Microntek USB Joystick,platform:Linux,x:b3,a:b2,b:b1,y:b0,back:b8,start:b9,leftshoulder:b6,lefttrigger:b4,rightshoulder:b7,righttrigger:b5,leftx:a0,lefty:a1,\n"
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,\n"

70
src/mappings.h.in Normal file
View 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";

View File

@ -614,6 +614,13 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
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)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@ -869,7 +876,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR =
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
vkGetPhysicalDeviceMirPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
if (!vkGetPhysicalDeviceMirPresentationSupportKHR)

View File

@ -296,6 +296,12 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
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.makeCurrent = makeContextCurrentNSGL;

View File

@ -156,6 +156,11 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
return GLFW_FALSE;
}
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
{
return GLFW_FALSE;
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
{
}

View File

@ -113,7 +113,9 @@ GLFWbool _glfwInitOSMesa(void)
int i;
const char* sonames[] =
{
#if defined(_WIN32)
#if defined(_GLFW_OSMESA_LIBRARY)
_GLFW_OSMESA_LIBRARY,
#elif defined(_WIN32)
"libOSMesa.dll",
"OSMesa.dll",
#elif defined(__APPLE__)

View File

@ -49,7 +49,9 @@ GLFWbool _glfwInitVulkan(int mode)
return GLFW_TRUE;
#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");
#elif defined(_GLFW_COCOA)
_glfw.vk.handle = _glfw_dlopen("libMoltenVK.dylib");

View File

@ -152,10 +152,10 @@ static int choosePixelFormat(_GLFWwindow* window,
}
else
{
PIXELFORMATDESCRIPTOR pfd;
// Get pixel format attributes through legacy PFDs
PIXELFORMATDESCRIPTOR pfd;
if (!DescribePixelFormat(window->context.wgl.dc,
n,
sizeof(PIXELFORMATDESCRIPTOR),
@ -229,21 +229,6 @@ static int choosePixelFormat(_GLFWwindow* window,
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)
{
if (window)
@ -272,7 +257,7 @@ static void makeContextCurrentWGL(_GLFWwindow* window)
static void swapBuffersWGL(_GLFWwindow* window)
{
// HACK: Use DwmFlush when desktop composition is enabled
if (isCompositionEnabled() && !window->monitor)
if (_glfwIsCompositionEnabledWin32() && !window->monitor)
{
int count = abs(window->context.wgl.interval);
while (count--)
@ -290,7 +275,7 @@ static void swapIntervalWGL(int interval)
// HACK: Disable WGL swap interval when desktop composition is enabled to
// avoid interfering with DWM vsync
if (isCompositionEnabled() && !window->monitor)
if (_glfwIsCompositionEnabledWin32() && !window->monitor)
interval = 0;
if (_glfw.wgl.EXT_swap_control)

View File

@ -30,7 +30,8 @@
#include <stdlib.h>
#include <malloc.h>
static const GUID _glfw_GUID_DEVINTERFACE_HID = {0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
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
@ -61,6 +62,17 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
#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)
//
static GLFWbool loadLibraries(void)
@ -68,7 +80,8 @@ static GLFWbool loadLibraries(void)
_glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");
if (!_glfw.win32.winmm.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "Win32: Failed to load winmm.dll");
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to load winmm.dll");
return GLFW_FALSE;
}
@ -78,13 +91,14 @@ static GLFWbool loadLibraries(void)
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
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;
}
_glfw.win32.user32.SetProcessDPIAware = (PFN_SetProcessDPIAware)
_glfw.win32.user32.SetProcessDPIAware_ = (PFN_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");
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
@ -128,12 +142,14 @@ static GLFWbool loadLibraries(void)
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
_glfw.win32.dwmapi.Flush = (PFN_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");
if (_glfw.win32.shcore.instance)
{
_glfw.win32.shcore.SetProcessDpiAwareness = (PFN_SetProcessDpiAwareness)
_glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
}
@ -357,19 +373,19 @@ static HWND createHelperWindow(void)
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
{
WCHAR* target;
int length;
int count;
length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
if (!length)
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
if (!count)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8");
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,
"Win32: Failed to convert string from UTF-8");
@ -385,19 +401,19 @@ WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
{
char* target;
int length;
int size;
length = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
if (!length)
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
if (!size)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
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,
"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);
}
// 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 //////
@ -448,11 +518,12 @@ int _glfwPlatformInit(void)
return GLFW_FALSE;
createKeyTables();
_glfwUpdateKeyNamesWin32();
if (_glfw_SetProcessDpiAwareness)
_glfw_SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
else if (_glfw_SetProcessDPIAware)
_glfw_SetProcessDPIAware();
if (IsWindows8Point1OrGreater())
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
else if (IsWindowsVistaOrGreater())
SetProcessDPIAware();
if (!_glfwRegisterWindowClassWin32())
return GLFW_FALSE;

View File

@ -50,16 +50,24 @@ typedef struct _GLFWobjenumWin32
// 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_GUID_XAxis = {0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_YAxis = {0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_ZAxis = {0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RxAxis = {0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RyAxis = {0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RzAxis = {0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_Slider = {0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_Button = {0xa36d02f0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_POV = {0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_IID_IDirectInput8W =
{0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
static const GUID _glfw_GUID_XAxis =
{0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_YAxis =
{0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_ZAxis =
{0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RxAxis =
{0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RyAxis =
{0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RzAxis =
{0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_Slider =
{0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_POV =
{0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
#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_RzAxis _glfw_GUID_RzAxis
#define GUID_Slider _glfw_GUID_Slider
#define GUID_Button _glfw_GUID_Button
#define GUID_POV _glfw_GUID_POV
// Object data array for our clone of c_dfDIJoystick
@ -345,10 +352,12 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (!_glfw.joysticks[jid].present)
continue;
if (memcmp(&_glfw.joysticks[jid].win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE;
_GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present)
{
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE;
}
}
if (supportsXInput(&di->guidProduct))

View File

@ -63,7 +63,6 @@
#include <wctype.h>
#include <windows.h>
#include <mmsystem.h>
#include <dinput.h>
#include <xinput.h>
#include <dbt.h>
@ -101,6 +100,9 @@
#ifndef DISPLAY_DEVICE_ACTIVE
#define DISPLAY_DEVICE_ACTIVE 0x00000001
#endif
#ifndef _WIN32_WINNT_WINBLUE
#define _WIN32_WINNT_WINBLUE 0x0602
#endif
#if WINVER < 0x0601
typedef struct tagCHANGEFILTERSTRUCT
@ -114,6 +116,18 @@ typedef struct tagCHANGEFILTERSTRUCT
#endif
#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
typedef enum PROCESS_DPI_AWARENESS
{
@ -123,6 +137,21 @@ typedef enum PROCESS_DPI_AWARENESS
} PROCESS_DPI_AWARENESS;
#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
#ifndef XINPUT_CAPS_WIRELESS
#define XINPUT_CAPS_WIRELESS 0x0002
@ -174,18 +203,20 @@ typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*
// user32.dll function pointer typedefs
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT);
#define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware
#define _glfw_ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
// dwmapi.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
#define DwmFlush _glfw.win32.dwmapi.Flush
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
// shcore.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
#define _glfw_SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness
#define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
@ -236,6 +267,8 @@ typedef struct _GLFWwindowWin32
GLFWbool frameAction;
GLFWbool iconified;
GLFWbool maximized;
// Whether to enable framebuffer transparency on DWM
GLFWbool transparent;
// The last received cursor position, regardless of source
int lastCursorPosX, lastCursorPosY;
@ -250,9 +283,9 @@ typedef struct _GLFWlibraryWin32
DWORD foregroundLockTimeout;
int acquiredMonitorCount;
char* clipboardString;
char keyName[64];
short int keycodes[512];
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
@ -279,19 +312,20 @@ typedef struct _GLFWlibraryWin32
struct {
HINSTANCE instance;
PFN_SetProcessDPIAware SetProcessDPIAware;
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx;
PFN_SetProcessDPIAware SetProcessDPIAware_;
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
} user32;
struct {
HINSTANCE instance;
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
PFN_DwmFlush Flush;
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
} dwmapi;
struct {
HINSTANCE instance;
PFN_SetProcessDpiAwareness SetProcessDpiAwareness;
PFN_SetProcessDpiAwareness SetProcessDpiAwareness_;
} shcore;
} _GLFWlibraryWin32;
@ -349,10 +383,12 @@ typedef struct _GLFWmutexWin32
GLFWbool _glfwRegisterWindowClassWin32(void);
void _glfwUnregisterWindowClassWin32(void);
GLFWbool _glfwIsCompositionEnabledWin32(void);
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
void _glfwInputErrorWin32(int error, const char* description);
void _glfwUpdateKeyNamesWin32(void);
void _glfwInitTimerWin32(void);

View File

@ -306,6 +306,55 @@ static void updateWindowStyles(const _GLFWwindow* window)
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
//
static LPWSTR translateCursorShape(int shape)
@ -584,6 +633,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return 0;
}
case WM_INPUTLANGCHANGE:
{
_glfwUpdateKeyNamesWin32();
break;
}
case WM_CHAR:
case WM_SYSCHAR:
case WM_UNICHAR:
@ -910,6 +965,13 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
return TRUE;
}
case WM_DWMCOMPOSITIONCHANGED:
{
if (window->win32.transparent)
updateFramebufferTransparency(window);
return 0;
}
case WM_SETCURSOR:
{
if (LOWORD(lParam) == HTCLIENT)
@ -975,7 +1037,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
// Creates the GLFW window
//
static int createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig)
const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig* fbconfig)
{
int xpos, ypos, fullWidth, fullHeight;
WCHAR* wideTitle;
@ -1033,18 +1096,24 @@ static int createNativeWindow(_GLFWwindow* window,
SetPropW(window->win32.handle, L"GLFW", window);
if (_glfw_ChangeWindowMessageFilterEx)
if (IsWindows7OrGreater())
{
_glfw_ChangeWindowMessageFilterEx(window->win32.handle,
WM_DROPFILES, MSGFLT_ALLOW, NULL);
_glfw_ChangeWindowMessageFilterEx(window->win32.handle,
WM_COPYDATA, MSGFLT_ALLOW, NULL);
_glfw_ChangeWindowMessageFilterEx(window->win32.handle,
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
ChangeWindowMessageFilterEx(window->win32.handle,
WM_DROPFILES, MSGFLT_ALLOW, NULL);
ChangeWindowMessageFilterEx(window->win32.handle,
WM_COPYDATA, MSGFLT_ALLOW, NULL);
ChangeWindowMessageFilterEx(window->win32.handle,
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
}
DragAcceptFiles(window->win32.handle, TRUE);
if (fbconfig->transparent)
{
updateFramebufferTransparency(window);
window->win32.transparent = GLFW_TRUE;
}
return GLFW_TRUE;
}
@ -1096,6 +1165,20 @@ void _glfwUnregisterWindowClassWin32(void)
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 //////
@ -1106,7 +1189,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
if (!createNativeWindow(window, wndconfig))
if (!createNativeWindow(window, wndconfig, fbconfig))
return GLFW_FALSE;
if (ctxconfig->client != GLFW_NO_API)
@ -1475,6 +1558,11 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
return IsZoomed(window->win32.handle);
}
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
{
return window->win32.transparent && _glfwIsCompositionEnabledWin32();
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
{
updateWindowStyles(window);
@ -1652,20 +1740,7 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
const char* _glfwPlatformGetScancodeName(int scancode)
{
WCHAR name[16];
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;
return _glfw.win32.keynames[_glfw.win32.keycodes[scancode]];
}
int _glfwPlatformGetKeyScancode(int key)
@ -1805,7 +1880,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR =
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
vkGetPhysicalDeviceWin32PresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)

View File

@ -278,119 +278,121 @@ GLFWAPI void glfwWindowHint(int hint, int value)
{
case GLFW_RED_BITS:
_glfw.hints.framebuffer.redBits = value;
break;
return;
case GLFW_GREEN_BITS:
_glfw.hints.framebuffer.greenBits = value;
break;
return;
case GLFW_BLUE_BITS:
_glfw.hints.framebuffer.blueBits = value;
break;
return;
case GLFW_ALPHA_BITS:
_glfw.hints.framebuffer.alphaBits = value;
break;
return;
case GLFW_DEPTH_BITS:
_glfw.hints.framebuffer.depthBits = value;
break;
return;
case GLFW_STENCIL_BITS:
_glfw.hints.framebuffer.stencilBits = value;
break;
return;
case GLFW_ACCUM_RED_BITS:
_glfw.hints.framebuffer.accumRedBits = value;
break;
return;
case GLFW_ACCUM_GREEN_BITS:
_glfw.hints.framebuffer.accumGreenBits = value;
break;
return;
case GLFW_ACCUM_BLUE_BITS:
_glfw.hints.framebuffer.accumBlueBits = value;
break;
return;
case GLFW_ACCUM_ALPHA_BITS:
_glfw.hints.framebuffer.accumAlphaBits = value;
break;
return;
case GLFW_AUX_BUFFERS:
_glfw.hints.framebuffer.auxBuffers = value;
break;
return;
case GLFW_STEREO:
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_DOUBLEBUFFER:
_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:
_glfw.hints.framebuffer.samples = value;
break;
return;
case GLFW_SRGB_CAPABLE:
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_RESIZABLE:
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_DECORATED:
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_FOCUSED:
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_AUTO_ICONIFY:
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_FLOATING:
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_MAXIMIZED:
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_VISIBLE:
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_COCOA_RETINA_FRAMEBUFFER:
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_COCOA_FRAME_AUTOSAVE:
_glfw.hints.window.ns.frame = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_COCOA_GRAPHICS_SWITCHING:
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_CENTER_CURSOR:
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_CLIENT_API:
_glfw.hints.context.client = value;
break;
return;
case GLFW_CONTEXT_CREATION_API:
_glfw.hints.context.source = value;
break;
return;
case GLFW_CONTEXT_VERSION_MAJOR:
_glfw.hints.context.major = value;
break;
return;
case GLFW_CONTEXT_VERSION_MINOR:
_glfw.hints.context.minor = value;
break;
return;
case GLFW_CONTEXT_ROBUSTNESS:
_glfw.hints.context.robustness = value;
break;
return;
case GLFW_OPENGL_FORWARD_COMPAT:
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_OPENGL_DEBUG_CONTEXT:
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_CONTEXT_NO_ERROR:
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
break;
return;
case GLFW_OPENGL_PROFILE:
_glfw.hints.context.profile = value;
break;
return;
case GLFW_CONTEXT_RELEASE_BEHAVIOR:
_glfw.hints.context.release = value;
break;
return;
case GLFW_REFRESH_RATE:
_glfw.hints.refreshRate = value;
break;
default:
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
break;
return;
}
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);
}
GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
@ -725,6 +727,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
return _glfwPlatformWindowVisible(window);
case GLFW_MAXIMIZED:
return _glfwPlatformWindowMaximized(window);
case GLFW_TRANSPARENT:
return _glfwPlatformFramebufferTransparent(window);
case GLFW_RESIZABLE:
return window->resizable;
case GLFW_DECORATED:
@ -770,41 +774,37 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
value = value ? GLFW_TRUE : GLFW_FALSE;
switch (attrib)
if (attrib == GLFW_AUTO_ICONIFY)
window->autoIconify = value;
else if (attrib == GLFW_RESIZABLE)
{
case GLFW_RESIZABLE:
if (window->resizable != value)
{
window->resizable = value;
if (!window->monitor)
_glfwPlatformSetWindowResizable(window, value);
}
if (window->resizable == value)
return;
case GLFW_DECORATED:
if (window->decorated != value)
{
window->decorated = value;
if (!window->monitor)
_glfwPlatformSetWindowDecorated(window, value);
}
return;
case GLFW_FLOATING:
if (window->floating != value)
{
window->floating = value;
if (!window->monitor)
_glfwPlatformSetWindowFloating(window, value);
}
return;
case GLFW_AUTO_ICONIFY:
window->autoIconify = value;
return;
window->resizable = value;
if (!window->monitor)
_glfwPlatformSetWindowResizable(window, value);
}
else if (attrib == GLFW_DECORATED)
{
if (window->decorated == value)
return;
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
window->decorated = value;
if (!window->monitor)
_glfwPlatformSetWindowDecorated(window, value);
}
else if (attrib == GLFW_FLOATING)
{
if (window->floating == value)
return;
window->floating = value;
if (!window->monitor)
_glfwPlatformSetWindowFloating(window, value);
}
else
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib);
}
GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle)

View File

@ -654,6 +654,13 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
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)
{
// TODO
@ -1019,7 +1026,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR =
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
vkGetPhysicalDeviceWaylandPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)

View File

@ -237,8 +237,8 @@ static void createKeyTables(void)
if (_glfw.x11.xkb.available)
{
// Use XKB to determine physical key locations independently of the current
// keyboard layout
// Use XKB to determine physical key locations independently of the
// current keyboard layout
char name[XkbKeyNameLength + 1];
XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
@ -651,6 +651,29 @@ static GLFWbool initExtensions(void)
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
// FIXME: We should listen to XkbMapNotify events to track changes to
// the keyboard mapping.
@ -661,10 +684,7 @@ static GLFWbool initExtensions(void)
// String format atoms
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
_glfw.x11.UTF8_STRING =
XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
_glfw.x11.COMPOUND_STRING =
XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);
_glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
_glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);
// Custom selection property atom
@ -675,6 +695,7 @@ static GLFWbool initExtensions(void)
_glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
_glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
_glfw.x11.PRIMARY = XInternAtom(_glfw.x11.display, "PRIMARY", False);
_glfw.x11.INCR = XInternAtom(_glfw.x11.display, "INCR", False);
_glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);
// Clipboard manager atoms
@ -862,12 +883,13 @@ int _glfwPlatformInit(void)
_glfw.x11.screen = DefaultScreen(_glfw.x11.display);
_glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
_glfw.x11.context = XUniqueContext();
_glfw.x11.helperWindowHandle = createHelperWindow();
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
if (!initExtensions())
return GLFW_FALSE;
_glfw.x11.helperWindowHandle = createHelperWindow();
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
if (XSupportsLocale())
{
XSetLocaleModifiers("");

View File

@ -116,6 +116,13 @@ typedef int (* PFN_XISelectEvents)(Display*,Window,XIEventMask*,int);
#define XIQueryVersion _glfw.x11.xi.QueryVersion
#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 VkXcbSurfaceCreateFlagsKHR;
@ -179,6 +186,9 @@ typedef struct _GLFWwindowX11
GLFWbool iconified;
GLFWbool maximized;
// Whether the visual supports framebuffer transparency
GLFWbool transparent;
// Cached position and size used to filter out duplicate events
int width, height;
int xpos, ypos;
@ -265,6 +275,7 @@ typedef struct _GLFWlibraryX11
// Selection (clipboard) atoms
Atom TARGETS;
Atom MULTIPLE;
Atom INCR;
Atom CLIPBOARD;
Atom PRIMARY;
Atom CLIPBOARD_MANAGER;
@ -372,6 +383,18 @@ typedef struct _GLFWlibraryX11
PFN_XISelectEvents SelectEvents;
} 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;
// X11-specific per-monitor data
@ -407,6 +430,7 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
Atom property,
Atom type,
unsigned char** value);
GLFWbool _glfwIsVisualTransparentX11(Visual* visual);
void _glfwGrabErrorHandlerX11(void);
void _glfwReleaseErrorHandlerX11(void);

View File

@ -164,6 +164,17 @@ static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointe
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
//
static int translateCursorShape(int shape)
@ -353,6 +364,7 @@ static void updateWindowMode(_GLFWwindow* window)
}
// Enable compositor bypass
if (!window->x11.transparent)
{
const unsigned long value = 1;
@ -391,6 +403,7 @@ static void updateWindowMode(_GLFWwindow* window)
}
// Disable compositor bypass
if (!window->x11.transparent)
{
XDeleteProperty(_glfw.x11.display, window->x11.handle,
_glfw.x11.NET_WM_BYPASS_COMPOSITOR);
@ -449,6 +462,81 @@ static char** parseUriList(char* text, int* count)
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
//
static void centerCursor(_GLFWwindow* window)
@ -491,6 +579,8 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
visual,
AllocNone);
window->x11.transparent = _glfwIsVisualTransparentX11(visual);
// Create the actual window
{
XSetWindowAttributes wa;
@ -672,9 +762,7 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
{
int i;
char* selectionString = NULL;
const Atom formats[] = { _glfw.x11.UTF8_STRING,
_glfw.x11.COMPOUND_STRING,
XA_STRING };
const Atom formats[] = { _glfw.x11.UTF8_STRING, XA_STRING };
const int formatCount = sizeof(formats) / sizeof(formats[0]);
if (request->selection == _glfw.x11.PRIMARY)
@ -696,7 +784,6 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
const Atom targets[] = { _glfw.x11.TARGETS,
_glfw.x11.MULTIPLE,
_glfw.x11.UTF8_STRING,
_glfw.x11.COMPOUND_STRING,
XA_STRING };
XChangeProperty(_glfw.x11.display,
@ -841,10 +928,8 @@ static const char* getSelectionString(Atom selection)
{
size_t i;
char** selectionString = NULL;
const Atom formats[] = { _glfw.x11.UTF8_STRING,
_glfw.x11.COMPOUND_STRING,
XA_STRING };
const size_t formatCount = sizeof(formats) / sizeof(formats[0]);
const Atom targets[] = { _glfw.x11.UTF8_STRING, XA_STRING };
const size_t targetCount = sizeof(targets) / sizeof(targets[0]);
if (selection == _glfw.x11.PRIMARY)
selectionString = &_glfw.x11.primarySelectionString;
@ -862,14 +947,17 @@ static const char* getSelectionString(Atom selection)
free(*selectionString);
*selectionString = NULL;
for (i = 0; i < formatCount; i++)
for (i = 0; i < targetCount; i++)
{
char* data;
XEvent event;
Atom actualType;
int actualFormat;
unsigned long itemCount, bytesAfter;
XEvent notification, dummy;
XConvertSelection(_glfw.x11.display,
selection,
formats[i],
targets[i],
_glfw.x11.GLFW_SELECTION,
_glfw.x11.helperWindowHandle,
CurrentTime);
@ -877,28 +965,92 @@ static const char* getSelectionString(Atom selection)
while (!XCheckTypedWindowEvent(_glfw.x11.display,
_glfw.x11.helperWindowHandle,
SelectionNotify,
&event))
&notification))
{
waitForEvent(NULL);
}
if (event.xselection.property == None)
if (notification.xselection.property == None)
continue;
if (_glfwGetWindowPropertyX11(event.xselection.requestor,
event.xselection.property,
event.xselection.target,
(unsigned char**) &data))
XCheckIfEvent(_glfw.x11.display,
&dummy,
isSelPropNewValueNotify,
(XPointer) &notification);
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)
{
*selectionString = strdup(data);
size_t size = 1;
char* string = NULL;
for (;;)
{
while (!XCheckIfEvent(_glfw.x11.display,
&dummy,
isSelPropNewValueNotify,
(XPointer) &notification))
{
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);
}
if (data)
XFree(data);
XDeleteProperty(_glfw.x11.display,
event.xselection.requestor,
event.xselection.property);
XFree(data);
if (*selectionString)
break;
@ -907,7 +1059,7 @@ static const char* getSelectionString(Atom selection)
if (!*selectionString)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"X11: Failed to convert clipboard to string");
"X11: Failed to convert selection to string");
}
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
//
static void processEvent(XEvent *event)
@ -1171,8 +1267,10 @@ static void processEvent(XEvent *event)
count = XwcLookupString(window->x11.ic,
&event->xkey,
buffer, sizeof(buffer) / sizeof(wchar_t),
NULL, &status);
buffer,
sizeof(buffer) / sizeof(wchar_t),
NULL,
&status);
if (status == XBufferOverflow)
{
@ -1345,7 +1443,8 @@ static void processEvent(XEvent *event)
const int x = event->xmotion.x;
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
@ -1424,14 +1523,15 @@ static void processEvent(XEvent *event)
if (protocol == _glfw.x11.WM_DELETE_WINDOW)
{
// The window manager was asked to close the window, for example by
// the user pressing a 'close' window decoration button
// The window manager was asked to close the window, for
// example by the user pressing a 'close' window decoration
// button
_glfwInputWindowCloseRequest(window);
}
else if (protocol == _glfw.x11.NET_WM_PING)
{
// The window manager is pinging the application to ensure it's
// still responding to events
// The window manager is pinging the application to ensure
// it's still responding to events
XEvent reply = *event;
reply.xclient.window = _glfw.x11.root;
@ -1742,6 +1842,15 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
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
//
void _glfwPushSelectionToManagerX11(void)
@ -1773,9 +1882,10 @@ void _glfwPushSelectionToManagerX11(void)
{
if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
{
// This means one of two things; either the selection was
// not owned, which means there is no clipboard manager, or
// the transfer to the clipboard manager has completed
// This means one of two things; either the selection
// was not owned, which means there is no clipboard
// manager, or the transfer to the clipboard manager has
// completed
// In either case, it means we are done here
return;
}
@ -1808,14 +1918,14 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
{
if (!_glfwInitGLX())
return GLFW_FALSE;
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE;
}
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
{
if (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth))
return GLFW_FALSE;
}
else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
@ -2325,6 +2435,18 @@ int _glfwPlatformWindowMaximized(_GLFWwindow* window)
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)
{
int width, height;
@ -2695,7 +2817,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)
{
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR =
PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR
vkGetPhysicalDeviceXcbPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
if (!vkGetPhysicalDeviceXcbPresentationSupportKHR)
@ -2720,7 +2843,8 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
}
else
{
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR =
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR
vkGetPhysicalDeviceXlibPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
if (!vkGetPhysicalDeviceXlibPresentationSupportKHR)