Compare commits

...

10 Commits

Author SHA1 Message Date
Camilla Löwy 4e1d7e9266 Cleanup
Related to #786.
2017-09-17 21:20:12 +02:00
Camilla Löwy 243db302bf EGLDevice: Fix build after rebase
Some minor bitrot had occurred since the patch was made.

Related to #786.
2017-09-17 21:17:42 +02:00
Kamal 5b1a187f71 Add EGLDevice backend to GLFW
This adds interface to graphics application to create EGLDisplay
directly over GPU device as enabled by EGLDevice extensions

Fixes #786.
2017-09-17 21:17:42 +02:00
Camilla Löwy f4fb25b63d X11: Fix init order breaking cursor hiding
The hidden cursor was created before Xcursor was loaded.
2017-09-17 16:06:02 +02:00
Camilla Löwy e3be6b8ae0 Cleanup
Break up some overly long lines.
2017-09-17 15:14:22 +02:00
Camilla Löwy 3d110d2e1b X11: Fix selection error nomenclature
[ci skip]
2017-09-17 13:54:17 +02:00
Camilla Löwy 0b5023bc62 X11: Fix Latin-1 text not being converted to UTF-8 2017-09-17 13:50:10 +02:00
Camilla Löwy 9dbc935afb X11: Stop reporting support for COMPOUND_TEXT 2017-09-17 13:50:10 +02:00
Camilla Löwy f7dc6df02c X11: Add support for reading clipboard via INCR
This allows glfwGetClipboardString to retrieve clipboard contents larger
than (typically) 2^18 bytes.

Related to #275.
2017-09-17 13:50:00 +02:00
Camilla Löwy f30acd8f74 Add OSMesa to context API list 2017-09-17 13:46:52 +02:00
23 changed files with 1363 additions and 136 deletions
+23 -2
View File
@@ -41,8 +41,9 @@ if (WIN32)
endif() endif()
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF) option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
option(GLFW_USE_MIR "Use Mir for window creation" OFF) option(GLFW_USE_MIR "Use Mir for window creation" OFF)
option(GLFW_USE_EGLDEVICE "Use EGLDevice for window creation" OFF)
endif() endif()
if (MSVC) if (MSVC)
@@ -163,6 +164,9 @@ elseif (GLFW_USE_MIR)
elseif (GLFW_USE_OSMESA) elseif (GLFW_USE_OSMESA)
set(_GLFW_OSMESA 1) set(_GLFW_OSMESA 1)
message(STATUS "Using OSMesa for headless context creation") message(STATUS "Using OSMesa for headless context creation")
elseif (GLFW_USE_EGLDEVICE)
set(_GLFW_EGLDEVICE 1)
message(STATUS "Using EGLDevice for window creation")
elseif (WIN32) elseif (WIN32)
set(_GLFW_WIN32 1) set(_GLFW_WIN32 1)
message(STATUS "Using Win32 for window creation") message(STATUS "Using Win32 for window creation")
@@ -291,6 +295,23 @@ if (_GLFW_WAYLAND)
list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}") list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}")
endif() endif()
#--------------------------------------------------------------------
# Use EGLDevice for window creation
#--------------------------------------------------------------------
if (_GLFW_EGLDEVICE)
find_path(DRM_INCLUDE_DIR NAMES drm.h PATH_SUFFIXES drm libdrm)
if (NOT DRM_INCLUDE_DIR)
message(FATAL_ERROR "The libdrm headers were not found")
endif()
list(APPEND glfw_INCLUDE_DIRS "${DRM_INCLUDE_DIR}")
list(APPEND glfw_LIBRARIES "-ldrm")
list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
endif()
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Use Mir for window creation # Use Mir for window creation
#-------------------------------------------------------------------- #--------------------------------------------------------------------
+13 -4
View File
@@ -11,8 +11,9 @@ application development. It provides a simple, platform-independent API for
creating windows, contexts and surfaces, reading input, handling events, etc. creating windows, contexts and surfaces, reading input, handling events, etc.
GLFW natively supports Windows, macOS and Linux and other Unix-like systems. GLFW natively supports Windows, macOS and Linux and other Unix-like systems.
Experimental implementations for the Wayland protocol and the Mir display server Experimental implementations for the Wayland protocol, the Mir display server
are available but not yet officially supported. and direct rendering via EGLDevice are available but not yet officially
supported.
GLFW is licensed under the [zlib/libpng GLFW is licensed under the [zlib/libpng
license](http://www.glfw.org/license.html). license](http://www.glfw.org/license.html).
@@ -45,8 +46,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
@@ -91,6 +92,9 @@ GLFW itself depends only on the headers and libraries for your window system.
The (experimental) Wayland backend also depends on the `extra-cmake-modules` The (experimental) Wayland backend also depends on the `extra-cmake-modules`
package, which is used to generated Wayland protocol headers. package, which is used to generated Wayland protocol headers.
The (experimental) EGLDevice backend also depends on the `libdrm-dev`
development package.
The examples and test programs depend on a number of tiny libraries. These are The examples and test programs depend on a number of tiny libraries. These are
located in the `deps/` directory. located in the `deps/` directory.
@@ -205,6 +209,10 @@ 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] Added experimental support for direct rendering via EGLDevice (#786)
- [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)
@@ -279,6 +287,7 @@ skills.
- David Carlier - David Carlier
- Arturo Castro - Arturo Castro
- Chi-kwan Chan - Chi-kwan Chan
- Kamal Chandra
- Ian Clarkson - Ian Clarkson
- Michał Cichoń - Michał Cichoń
- Lambert Clara - Lambert Clara
+1
View File
@@ -257,6 +257,7 @@ ramps and clipboard. The options are:
- @b _GLFW_WAYLAND to use the Wayland API (experimental and incomplete) - @b _GLFW_WAYLAND to use the Wayland API (experimental and incomplete)
- @b _GLFW_MIR to use the Mir API (experimental and incomplete) - @b _GLFW_MIR to use the Mir API (experimental and incomplete)
- @b _GLFW_OSMESA to use the OSMesa API (headless and non-interactive) - @b _GLFW_OSMESA to use the OSMesa API (headless and non-interactive)
- @b _GLFW_EGLDEVICE to use the EGLDevice API (experimental and incomplete)
If you are building GLFW as a shared library / dynamic library / DLL then you If you are building GLFW as a shared library / dynamic library / DLL then you
must also define @b _GLFW_BUILD_DLL. Otherwise, you must not define it. must also define @b _GLFW_BUILD_DLL. Otherwise, you must not define it.
+7 -1
View File
@@ -47,6 +47,12 @@ elseif (_GLFW_WAYLAND)
PROTOCOL PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml" "${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
BASENAME pointer-constraints-unstable-v1) BASENAME pointer-constraints-unstable-v1)
elseif(_GLFW_EGLDEVICE)
set(glfw_HEADERS ${common_HEADERS} egldevice_platform.h linux_joystick.h
posix_time.h posix_thread.h xkb_unicode.h egl_context.h)
set(glfw_SOURCES ${common_SOURCES} egldevice_init.c egldevice_monitor.c egldevice_window.c
linux_joystick.c posix_time.c posix_thread.c xkb_unicode.c
egl_context.c)
elseif (_GLFW_MIR) elseif (_GLFW_MIR)
set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h
posix_time.h posix_thread.h xkb_unicode.h egl_context.h posix_time.h posix_thread.h xkb_unicode.h egl_context.h
@@ -88,7 +94,7 @@ set_target_properties(glfw PROPERTIES
target_compile_definitions(glfw PRIVATE target_compile_definitions(glfw PRIVATE
_GLFW_USE_CONFIG_H _GLFW_USE_CONFIG_H
$<$<BOOL:${UNIX}>:_XOPEN_SOURCE=600>) $<$<BOOL:${UNIX}>:_POSIX_C_SOURCE=200809L>)
target_include_directories(glfw PUBLIC target_include_directories(glfw PUBLIC
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>" "$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>") "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>")
+5 -3
View File
@@ -215,8 +215,9 @@ static GLFWbool updateUnicodeDataNS(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource, _glfw.ns.unicodeData =
kTISPropertyUnicodeKeyLayoutData); TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
if (!_glfw.ns.unicodeData) if (!_glfw.ns.unicodeData)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@@ -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,
+5 -2
View File
@@ -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;
+14 -3
View File
@@ -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);
} }
} }
+16
View File
@@ -116,10 +116,18 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER) if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
continue; continue;
#if defined(_GLFW_EGLDEVICE)
// Only consider stream EGLConfigs
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_STREAM_BIT_KHR))
continue;
#else
// Only consider window EGLConfigs // Only consider window EGLConfigs
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT)) if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
continue; continue;
#endif
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
// Only consider EGLConfigs with associated Visuals // Only consider EGLConfigs with associated Visuals
if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID)) if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))
@@ -376,6 +384,9 @@ GLFWbool _glfwInitEGL(void)
return GLFW_FALSE; return GLFW_FALSE;
} }
// For EGLDevice backend the display gets initialized
// in _glfwPlatformInit()
#if !defined(_GLFW_EGLDEVICE)
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY); _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
if (_glfw.egl.display == EGL_NO_DISPLAY) if (_glfw.egl.display == EGL_NO_DISPLAY)
{ {
@@ -396,6 +407,7 @@ GLFWbool _glfwInitEGL(void)
_glfwTerminateEGL(); _glfwTerminateEGL();
return GLFW_FALSE; return GLFW_FALSE;
} }
#endif
_glfw.egl.KHR_create_context = _glfw.egl.KHR_create_context =
extensionSupportedEGL("EGL_KHR_create_context"); extensionSupportedEGL("EGL_KHR_create_context");
@@ -581,6 +593,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
setAttrib(EGL_NONE, EGL_NONE); setAttrib(EGL_NONE, EGL_NONE);
} }
// The surface for EGLDevice backened is created in _glfwPlatformCreateWindow
//
#if !defined (_GLFW_EGLDEVICE)
window->context.egl.surface = window->context.egl.surface =
eglCreateWindowSurface(_glfw.egl.display, eglCreateWindowSurface(_glfw.egl.display,
config, config,
@@ -593,6 +608,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
getEGLErrorString(eglGetError())); getEGLErrorString(eglGetError()));
return GLFW_FALSE; return GLFW_FALSE;
} }
#endif
window->context.egl.config = config; window->context.egl.config = config;
+7
View File
@@ -47,6 +47,10 @@ typedef struct wl_egl_window* EGLNativeWindowType;
#define EGLAPIENTRY #define EGLAPIENTRY
typedef MirEGLNativeDisplayType EGLNativeDisplayType; typedef MirEGLNativeDisplayType EGLNativeDisplayType;
typedef MirEGLNativeWindowType EGLNativeWindowType; typedef MirEGLNativeWindowType EGLNativeWindowType;
#elif defined(_GLFW_EGLDEVICE)
#define EGLAPIENTRY
typedef void* EGLNativeDisplayType;
typedef int EGLNativeWindowType;
#else #else
#error "No supported EGL platform selected" #error "No supported EGL platform selected"
#endif #endif
@@ -84,6 +88,8 @@ typedef MirEGLNativeWindowType EGLNativeWindowType;
#define EGL_OPENGL_ES_API 0x30a0 #define EGL_OPENGL_ES_API 0x30a0
#define EGL_OPENGL_API 0x30a2 #define EGL_OPENGL_API 0x30a2
#define EGL_NONE 0x3038 #define EGL_NONE 0x3038
#define EGL_WIDTH 0x3057
#define EGL_HEIGHT 0x3056
#define EGL_EXTENSIONS 0x3055 #define EGL_EXTENSIONS 0x3055
#define EGL_CONTEXT_CLIENT_VERSION 0x3098 #define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_NATIVE_VISUAL_ID 0x302e #define EGL_NATIVE_VISUAL_ID 0x302e
@@ -118,6 +124,7 @@ typedef void* EGLConfig;
typedef void* EGLContext; typedef void* EGLContext;
typedef void* EGLDisplay; typedef void* EGLDisplay;
typedef void* EGLSurface; typedef void* EGLSurface;
typedef intptr_t EGLAttrib;
// EGL function pointer typedefs // EGL function pointer typedefs
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*); typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
+284
View File
@@ -0,0 +1,284 @@
//========================================================================
// GLFW 3.3 EGLDevice - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <linux/limits.h>
static GLFWbool initializeExtensions(void)
{
_glfw.egldevice.QueryDevicesEXT =
(PFNEGLQUERYDEVICESEXTPROC)
eglGetProcAddress("eglQueryDevicesEXT");
_glfw.egldevice.QueryDeviceStringEXT =
(PFNEGLQUERYDEVICESTRINGEXTPROC)
eglGetProcAddress("eglQueryDeviceStringEXT");
_glfw.egldevice.GetPlatformDisplayEXT =
(PFNEGLGETPLATFORMDISPLAYEXTPROC)
eglGetProcAddress("eglGetPlatformDisplayEXT");
_glfw.egldevice.GetOutputLayersEXT =
(PFNEGLGETOUTPUTLAYERSEXTPROC)
eglGetProcAddress("eglGetOutputLayersEXT");
_glfw.egldevice.CreateStreamKHR =
(PFNEGLCREATESTREAMKHRPROC)
eglGetProcAddress("eglCreateStreamKHR");
_glfw.egldevice.DestroyStreamKHR =
(PFNEGLDESTROYSTREAMKHRPROC)
eglGetProcAddress("eglDestroyStreamKHR");
_glfw.egldevice.StreamConsumerOutputEXT =
(PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)
eglGetProcAddress("eglStreamConsumerOutputEXT");
_glfw.egldevice.CreateStreamProducerSurfaceKHR =
(PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)
eglGetProcAddress("eglCreateStreamProducerSurfaceKHR");
if(!_glfw.egldevice.QueryDevicesEXT ||
!_glfw.egldevice.QueryDeviceStringEXT ||
!_glfw.egldevice.GetPlatformDisplayEXT ||
!_glfw.egldevice.GetOutputLayersEXT ||
!_glfw.egldevice.CreateStreamKHR ||
!_glfw.egldevice.DestroyStreamKHR ||
!_glfw.egldevice.StreamConsumerOutputEXT ||
!_glfw.egldevice.CreateStreamProducerSurfaceKHR)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Failed to find required EGL extension functions");
return GLFW_FALSE;
}
return GLFW_TRUE;
}
static EGLDeviceEXT getEGLDevice(void)
{
int i, num_devs;
EGLDeviceEXT* egl_devs, eglDevice;
const char *clientExtensionString;
eglDevice = EGL_NO_DEVICE_EXT;
clientExtensionString = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if (!_glfwStringInExtensionString("EGL_EXT_device_base",
clientExtensionString) &&
(!_glfwStringInExtensionString("EGL_EXT_device_enumeration",
clientExtensionString) ||
!_glfwStringInExtensionString("EGL_EXT_device_query",
clientExtensionString)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: EGL_EXT_device base extensions not found");
}
if (!eglQueryDevicesEXT(0, NULL, &num_devs))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Falied to query EGLDevice");
}
if (num_devs < 1)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: No devices found");
}
egl_devs = calloc(sizeof(EGLDeviceEXT), num_devs);
if (egl_devs == NULL)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to allocate memory for device storage");
}
// Select suitable device
if (!eglQueryDevicesEXT(num_devs, egl_devs, &num_devs))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Failed to query EGL devices");
}
for (i = 0; i <= num_devs; i++)
{
const char* deviceExtensionString;
deviceExtensionString = eglQueryDeviceStringEXT(egl_devs[i], EGL_EXTENSIONS);
if (_glfwStringInExtensionString("EGL_EXT_device_drm",
deviceExtensionString))
{
eglDevice = egl_devs[i];
break;
}
}
free(egl_devs);
if (eglDevice == EGL_NO_DEVICE_EXT)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_EXT_device_drm");
}
return eglDevice;
}
static int getDRMFd(EGLDeviceEXT eglDevice)
{
int drm_fd;
const char* drmName;
drmName = eglQueryDeviceStringEXT(eglDevice, EGL_DRM_DEVICE_FILE_EXT);
if (!drmName || (strnlen(drmName, PATH_MAX) == 0))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Couldn't obtain device file from 0x%p",
(void*)(uintptr_t)eglDevice);
}
drm_fd = drmOpen(drmName, NULL);
if (drm_fd < 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Couldn't open device file '%s'", drmName);
}
return drm_fd;
}
static GLFWbool initEGLDisplay(EGLDeviceEXT egl_dev, int drm_fd)
{
const char* displayExtensionString;
EGLint displayAttribs[] = {
EGL_DRM_MASTER_FD_EXT,
drm_fd,
EGL_NONE
};
_glfw.egl.display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT,
(void*)egl_dev,
displayAttribs);
if (_glfw.egl.display == EGL_NO_DISPLAY)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Couldn't obtain EGLDisplay for device");
return GLFW_FALSE;
}
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Failed to initialize EGL");
return GLFW_FALSE;
}
// Check for stream_consumer_egloutput + output_drm support
displayExtensionString = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
if (!_glfwStringInExtensionString("EGL_EXT_output_base",
displayExtensionString))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_EXT_output_base");
return GLFW_FALSE;
}
if (!_glfwStringInExtensionString("EGL_EXT_output_drm",
displayExtensionString))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_EXT_output_drm");
return GLFW_FALSE;
}
if (!_glfwStringInExtensionString("EGL_KHR_stream",
displayExtensionString))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_KHR_stream");
return GLFW_FALSE;
}
if (!_glfwStringInExtensionString("EGL_KHR_stream_producer_eglsurface",
displayExtensionString))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_KHR_stream_producer_eglsurface");
return GLFW_FALSE;
}
if (!_glfwStringInExtensionString("EGL_EXT_stream_consumer_egloutput",
displayExtensionString))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_EXT_stream_consumer_egloutput");
return GLFW_FALSE;
}
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void)
{
EGLDeviceEXT egl_dev;
int drm_fd;
// Initialize EGL
if (!_glfwInitEGL())
return GLFW_FALSE;
// Initialize global data and extension function pointers
if (!initializeExtensions())
return GLFW_FALSE;
// Query and Obtain EGLDevice
egl_dev = getEGLDevice();
// Obtain and open DRM device file
drm_fd = getDRMFd(egl_dev);
// Store for use later
_glfw.egldevice.drmFd = drm_fd;
// Obtain EGLDisplay
if (!initEGLDisplay(egl_dev, drm_fd))
return GLFW_FALSE;
_glfwInitTimerPOSIX();
_glfwPollMonitorsEGLDevice();
return GLFW_TRUE;
}
void _glfwPlatformTerminate(void)
{
_glfwTerminateEGL();
_glfwTerminateJoysticksLinux();
}
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER "EGLDevice EGL"
#if defined(_GLFW_BUILD_DLL)
" shared"
#endif
;
}
+165
View File
@@ -0,0 +1,165 @@
//========================================================================
// GLFW 3.3 EGLDevice - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
static GLFWbool pickConnector(_GLFWmonitor* monitor, int drm_fd, drmModeRes* res_info)
{
int i, j;
// Getting suitable connector, encoder and crtc
for (i = 0; i < res_info->count_connectors; i++)
{
monitor->egldevice.connId = res_info->connectors[i];
drmModeConnector* conn_info;
conn_info =
drmModeGetConnector(drm_fd, monitor->egldevice.connId);
if (!conn_info)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to obtain info for connector (%d)",
monitor->egldevice.connId);
return GLFW_FALSE;
}
if (conn_info->connection == DRM_MODE_CONNECTED &&
conn_info->count_modes > 0 &&
conn_info->count_encoders > 0)
{
monitor->egldevice.encId = conn_info->encoders[0];
drmModeEncoder* enc_info;
enc_info =
drmModeGetEncoder(drm_fd, monitor->egldevice.encId);
if (!enc_info) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to query DRM-KMS information for connector index %d", i);
}
// Select the modesize
monitor->currentMode.width = (int)conn_info->modes[0].hdisplay;
monitor->currentMode.height = (int)conn_info->modes[0].vdisplay;
monitor->currentMode.refreshRate = (int)conn_info->modes[0].vrefresh;
monitor->modeCount = (int)conn_info->count_modes;
monitor->name = conn_info->modes[0].name;
for (j = 0; j < res_info->count_crtcs; j++)
{
if ((enc_info->possible_crtcs & (1 << j)) == 0)
continue;
monitor->egldevice.crtcId = res_info->crtcs[j];
monitor->egldevice.crtcIndex = j;
if (res_info->crtcs[i] == enc_info->crtc_id)
break;
}
if (monitor->egldevice.crtcId == 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to select suitable CRTC");
return GLFW_FALSE;
}
drmModeFreeEncoder(enc_info);
}
drmModeFreeConnector(conn_info);
}
return GLFW_TRUE;
}
static GLFWbool initDRMResources(_GLFWmonitor* monitor, int drm_fd)
{
drmModeRes* res_info;
res_info = drmModeGetResources(drm_fd);
if (!res_info)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Couldn't obtain DRM-KMS resources");
return GLFW_FALSE;
}
if(!pickConnector(monitor, drm_fd, res_info))
return GLFW_FALSE;
drmModeFreeResources(res_info);
return GLFW_TRUE;
}
/////////////////////////////////////////////////////////////////////////////
/////////// GLFW platform API //////////////
/////////////////////////////////////////////////////////////////////////////
void _glfwPollMonitorsEGLDevice(void)
{
_GLFWmonitor* monitor = _glfwAllocMonitor("Monitor", 0, 0);
// Obtain DRM resource info
if (!initDRMResources(monitor, _glfw.egldevice.drmFd))
{
_glfwFreeMonitor(monitor);
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_FIRST);
}
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetMonitorPos not implemented");
}
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetVideoModes not implemented");
*found = 0;
return NULL;
}
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetVideoMode not implemented");
}
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetGammaRamp not implemented");
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetGammaRamp not implemented");
}
+151
View File
@@ -0,0 +1,151 @@
//========================================================================
// GLFW 3.3 EGLDevice - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <dlfcn.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <drm_fourcc.h>
#include "posix_time.h"
#include "linux_joystick.h"
#include "posix_thread.h"
#include "egl_context.h"
#include "osmesa_context.h"
#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT) 0)
#define EGL_DRM_DEVICE_FILE_EXT 0x3233
#define EGL_PLATFORM_DEVICE_EXT 0x313f
#define EGL_DRM_MASTER_FD_EXT 0x333c
#define EGL_STREAM_FIFO_LENGTH_KHR 0x31fc
#define EGL_DRM_CRTC_EXT 0x3234
#define EGL_NO_STREAM_KHR ((EGLStreamKHR) 0)
#define EGL_STREAM_BIT_KHR 0x0800
typedef void* EGLOutputLayerEXT;
typedef void* EGLStreamKHR;
typedef void* EGLDeviceEXT;
typedef EGLBoolean (EGLAPIENTRY * PFNEGLQUERYDEVICESEXTPROC)(EGLint,EGLDeviceEXT*,EGLint*);
typedef const char *(EGLAPIENTRY * PFNEGLQUERYDEVICESTRINGEXTPROC)(EGLDeviceEXT,EGLint);
typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLGETOUTPUTLAYERSEXTPROC)(EGLDisplay,const EGLAttrib*,EGLOutputLayerEXT*,EGLint,EGLint*);
typedef EGLStreamKHR (EGLAPIENTRY * PFNEGLCREATESTREAMKHRPROC)(EGLDisplay,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLDESTROYSTREAMKHRPROC)(EGLDisplay,EGLStreamKHR);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)(EGLDisplay,EGLStreamKHR,EGLOutputLayerEXT);
typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay,EGLConfig,EGLStreamKHR,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMATTRIBKHRPROC)(EGLDisplay,EGLStreamKHR,EGLenum,EGLint);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC)(EGLDisplay,EGLStreamKHR,const EGLAttrib*);
#define eglQueryDevicesEXT _glfw.egldevice.QueryDevicesEXT
#define eglQueryDeviceStringEXT _glfw.egldevice.QueryDeviceStringEXT
#define eglGetPlatformDisplayEXT _glfw.egldevice.GetPlatformDisplayEXT
#define eglGetOutputLayersEXT _glfw.egldevice.GetOutputLayersEXT
#define eglCreateStreamKHR _glfw.egldevice.CreateStreamKHR
#define eglDestroyStreamKHR _glfw.egldevice.DestroyStreamKHR
#define eglStreamConsumerOutputEXT _glfw.egldevice.StreamConsumerOutputEXT
#define eglCreateStreamProducerSurfaceKHR _glfw.egldevice.CreateStreamProducerSurfaceKHR
#define eglStreamAttribKHR _glfw.egldevice.StreamAttribKHR
#define eglStreamConsumerAcquireAttribKHR _glfw.egldevice.StreamConsumerAcquireAttribKHR
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType)window->egldevice.handle)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowEGLDevice egldevice
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryEGLDevice egldevice
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorEGLDevice egldevice
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorEGLDevice egldevice
#define _GLFW_PLATFORM_CONTEXT_STATE
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
// EGLDevice-specific per-window data
//
typedef struct _GLFWwindowEGLDevice
{
int xsurfsize, ysurfsize;
int xoffset, yoffset;
int fifo;
uint32_t planeId;
EGLDisplay handle;
EGLOutputLayerEXT eglLayer;
EGLStreamKHR eglStream;
} _GLFWwindowEGLDevice;
// EGLDevice-specific global data
//
typedef struct _GLFWlibraryEGLDevice
{
int drmFd;
PFNEGLQUERYDEVICESEXTPROC QueryDevicesEXT;
PFNEGLQUERYDEVICESTRINGEXTPROC QueryDeviceStringEXT;
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;
PFNEGLGETOUTPUTLAYERSEXTPROC GetOutputLayersEXT;
PFNEGLCREATESTREAMKHRPROC CreateStreamKHR;
PFNEGLDESTROYSTREAMKHRPROC DestroyStreamKHR;
PFNEGLSTREAMCONSUMEROUTPUTEXTPROC StreamConsumerOutputEXT;
PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC CreateStreamProducerSurfaceKHR;
PFNEGLSTREAMATTRIBKHRPROC StreamAttribKHR;
PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC StreamConsumerAcquireAttribKHR;
} _GLFWlibraryEGLDevice;
// EGLDevice-specific per-monitor data
//
typedef struct _GLFWmonitorEGLDevice
{
int crtcIndex;
uint32_t connId, encId, crtcId;
} _GLFWmonitorEGLDevice;
// EGLDevice-specific per-cursor data
//
typedef struct _GLFWcursorEGLDevice
{
} _GLFWcursorEGLDevice;
void _glfwPollMonitorsEGLDevice(void);
+430
View File
@@ -0,0 +1,430 @@
//========================================================================
// GLFW 3.3 EGLDevice - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
///////////////////////////////////////////////////////////////////////////
//////// GLFW platform API /////////////
///////////////////////////////////////////////////////////////////////////
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
int n;
_GLFWmonitor* monitor;
EGLAttrib layerAttribs[] = { EGL_NONE, EGL_NONE, EGL_NONE };
EGLint streamAttribs[] = { EGL_STREAM_FIFO_LENGTH_KHR,
window->egldevice.fifo, EGL_NONE };
EGLint surfaceAttribs[] = { EGL_WIDTH, 0, EGL_HEIGHT, 0, EGL_NONE };
if (window->monitor)
monitor = window->monitor;
else
monitor = _glfw.monitors[0];
window->egldevice.xsurfsize = wndconfig->width;
window->egldevice.ysurfsize = wndconfig->height;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
// Get the layer for this crtc/plane
layerAttribs[0] = EGL_DRM_CRTC_EXT;
layerAttribs[1] = (EGLAttrib)monitor->egldevice.crtcId;
if (!eglGetOutputLayersEXT(_glfw.egl.display, layerAttribs,
&window->egldevice.eglLayer,
1, &n) || !n)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to obtain EGLOutputLayer");
return GLFW_FALSE;
}
// Create a stream and connect to the output
window->egldevice.eglStream =
eglCreateStreamKHR(_glfw.egl.display, streamAttribs);
if (window->egldevice.eglStream == EGL_NO_STREAM_KHR)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to create stream (error 0x%x)",
eglGetError());
return GLFW_FALSE;
}
if (!eglStreamConsumerOutputEXT(_glfw.egl.display,
window->egldevice.eglStream,
window->egldevice.eglLayer))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to connect stream (error 0x%x)",
eglGetError());
return GLFW_FALSE;
}
// Create a surface to feed the stream
surfaceAttribs[1] = window->egldevice.xsurfsize;
surfaceAttribs[3] = window->egldevice.ysurfsize;
window->context.egl.surface =
eglCreateStreamProducerSurfaceKHR(_glfw.egl.display,
window->context.egl.config,
window->egldevice.eglStream,
surfaceAttribs);
if (window->context.egl.surface == EGL_NO_SURFACE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to create rendering surface (error 0x%x)", eglGetError());
return GLFW_FALSE;
}
return GLFW_TRUE;
}
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
if (window->context.client != GLFW_NO_API)
window->context.destroy(window);
if (window->egldevice.eglStream != EGL_NO_STREAM_KHR)
eglDestroyStreamKHR(_glfw.egl.display, window->egldevice.eglStream);
}
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowTitle is not supported");
}
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
int count, const GLFWimage* images)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowIcon is not supported");
}
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
{
if (xpos)
*xpos = window->egldevice.xoffset;
if (ypos)
*ypos = window->egldevice.yoffset;
}
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
{
window->egldevice.xoffset = xpos;
window->egldevice.yoffset = ypos;
drmModeRes* res_info;
_GLFWmonitor* monitor;
if (window->monitor)
monitor = window->monitor;
else
monitor = _glfw.monitors[0];
res_info = drmModeGetResources(_glfw.egldevice.drmFd);
if (drmModeSetCrtc(_glfw.egldevice.drmFd,
res_info->crtcs[monitor->egldevice.crtcIndex],
-1, window->egldevice.xoffset, window->egldevice.yoffset,
&res_info->connectors[monitor->egldevice.crtcIndex], 1, NULL))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Setting window pos failed");
}
drmModeFreeResources(res_info);
}
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->egldevice.xsurfsize;
if (height)
*height = window->egldevice.ysurfsize;
}
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowSize not implemented");
}
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowSizeLimits not implemented");
}
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowAspectRatio not implemented");
}
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
{
_glfwPlatformGetWindowSize(window, width, height);
}
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetWindowFrameSize not implemented");
}
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformIconifyWindow not implemented");
}
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformRestoreWindow not implemented");
}
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformMaximizeWindow not implemented");
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowResizable not implemented");
}
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowDecorated not implemented");
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowFloating not implemented");
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformRequestWindowAttention not implemented");
}
void _glfwPlatformShowWindow(_GLFWwindow* window)
{
return;
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformUnhideWindow not implemented");
}
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformHideWindow not implemented");
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
{
return;
}
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowMonitor not implemented");
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWindowFocused not implemented");
return GLFW_FALSE;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWindowIconified not implemented");
return GLFW_FALSE;
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWindowVisible not implemented");
return GLFW_FALSE;
}
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWindowMaximized not implemented");
return 0;
}
void _glfwPlatformPollEvents(void)
{
_glfwDetectJoystickConnectionLinux();
}
void _glfwPlatformWaitEvents(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWaitEvents not supported");
}
void _glfwPlatformWaitEventsTimeout(double timeout)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWaitEventsTimeout not supported");
}
void _glfwPlatformPostEmptyEvent(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformPostEmptyEvent not supported");
}
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetCursorPos not supported");
}
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetCursorPos not supported");
}
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetCursorMode not supported");
}
const char* _glfwPlatformGetKeyName(int key, int scancode)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetKeyName not supported");
return NULL;
}
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformCreateCursor not supported");
return GLFW_FALSE;
}
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformCreateStandardCursor not supported");
return GLFW_FALSE;
}
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
{
return;
}
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetCursor not supported");
}
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetClipboardString not supported");
}
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetClipboardString not supported");
return NULL;
}
const char* _glfwPlatformGetScancodeName(int scancode)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetScancodeName not supported");
return "";
}
int _glfwPlatformGetKeyScancode(int key)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetKeyScancode not supported");
return -1;
}
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetRequiredInstanceExtensions not supported");
}
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetPhysicalDevicePresentationSupport not supported");
return GLFW_FALSE;
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformCreateWindowSurface not supported");
return VK_ERROR_INITIALIZATION_FAILED;
}
+2
View File
@@ -46,6 +46,8 @@
#cmakedefine _GLFW_MIR #cmakedefine _GLFW_MIR
// Define this to 1 if building GLFW for OSMesa // Define this to 1 if building GLFW for OSMesa
#cmakedefine _GLFW_OSMESA #cmakedefine _GLFW_OSMESA
// Define this to 1 if building GLFW for EGLDevice
#cmakedefine _GLFW_EGLDEVICE
// Define this to 1 if building as a shared library / dynamic library / DLL // Define this to 1 if building as a shared library / dynamic library / DLL
#cmakedefine _GLFW_BUILD_DLL #cmakedefine _GLFW_BUILD_DLL
+2
View File
@@ -190,6 +190,8 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
#include "mir_platform.h" #include "mir_platform.h"
#elif defined(_GLFW_OSMESA) #elif defined(_GLFW_OSMESA)
#include "null_platform.h" #include "null_platform.h"
#elif defined(_GLFW_EGLDEVICE)
#include "egldevice_platform.h"
#else #else
#error "No supported window creation API selected" #error "No supported window creation API selected"
#endif #endif
+2 -1
View File
@@ -869,7 +869,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)
+6 -3
View File
@@ -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
@@ -68,7 +69,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,7 +80,8 @@ 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;
} }
+26 -14
View File
@@ -50,16 +50,26 @@ 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_Button =
{0xa36d02f0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_POV =
{0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W #define IID_IDirectInput8W _glfw_IID_IDirectInput8W
#define GUID_XAxis _glfw_GUID_XAxis #define GUID_XAxis _glfw_GUID_XAxis
@@ -345,10 +355,12 @@ 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) {
return DIENUM_CONTINUE; if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE;
}
} }
if (supportsXInput(&di->guidProduct)) if (supportsXInput(&di->guidProduct))
+2 -1
View File
@@ -1798,7 +1798,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)
+2 -1
View File
@@ -1019,7 +1019,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)
+7 -8
View File
@@ -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);
@@ -661,10 +661,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 +672,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 +860,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("");
+1
View File
@@ -265,6 +265,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;
+192 -93
View File
@@ -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)
@@ -449,6 +460,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)
@@ -672,9 +758,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 +780,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 +924,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 +943,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,28 +961,92 @@ 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)) &notification))
{ {
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) &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);
XFree(data);
XDeleteProperty(_glfw.x11.display,
event.xselection.requestor,
event.xselection.property);
if (*selectionString) if (*selectionString)
break; break;
@@ -907,7 +1055,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 +1126,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 +1263,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 +1439,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 +1519,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;
@@ -1773,9 +1869,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;
} }
@@ -2695,7 +2792,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 +2818,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)