Compare commits

..

5 Commits

Author SHA1 Message Date
Camilla Löwy 8429402f9e Documentation work 2017-09-15 18:38:05 +02:00
Camilla Löwy c4b73750b7 Cleanup
Related to #1012.
2017-09-15 18:38:05 +02:00
Camilla Löwy 750ac64245 X11: Fix event time wrapping
Related to #1012.
2017-09-15 18:37:53 +02:00
Camilla Löwy 138b10eb28 Win32: Fix event time wrapping
Related to #1012.
2017-09-15 18:35:24 +02:00
Felipe Ferreira da Silva c577ae4b0e Add glfwGetEventTime for querying input event time
Fixes #1012.
2017-09-15 18:34:34 +02:00
33 changed files with 302 additions and 1375 deletions
+2 -23
View File
@@ -41,9 +41,8 @@ if (WIN32)
endif()
if (UNIX AND NOT APPLE)
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
option(GLFW_USE_MIR "Use Mir for window creation" OFF)
option(GLFW_USE_EGLDEVICE "Use EGLDevice for window creation" OFF)
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
option(GLFW_USE_MIR "Use Mir for window creation" OFF)
endif()
if (MSVC)
@@ -164,9 +163,6 @@ elseif (GLFW_USE_MIR)
elseif (GLFW_USE_OSMESA)
set(_GLFW_OSMESA 1)
message(STATUS "Using OSMesa for headless context creation")
elseif (GLFW_USE_EGLDEVICE)
set(_GLFW_EGLDEVICE 1)
message(STATUS "Using EGLDevice for window creation")
elseif (WIN32)
set(_GLFW_WIN32 1)
message(STATUS "Using Win32 for window creation")
@@ -295,23 +291,6 @@ if (_GLFW_WAYLAND)
list(APPEND glfw_LIBRARIES "${XKBCOMMON_LIBRARY}")
endif()
#--------------------------------------------------------------------
# Use EGLDevice for window creation
#--------------------------------------------------------------------
if (_GLFW_EGLDEVICE)
find_path(DRM_INCLUDE_DIR NAMES drm.h PATH_SUFFIXES drm libdrm)
if (NOT DRM_INCLUDE_DIR)
message(FATAL_ERROR "The libdrm headers were not found")
endif()
list(APPEND glfw_INCLUDE_DIRS "${DRM_INCLUDE_DIR}")
list(APPEND glfw_LIBRARIES "-ldrm")
list(APPEND glfw_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
endif()
#--------------------------------------------------------------------
# Use Mir for window creation
#--------------------------------------------------------------------
+6 -13
View File
@@ -11,9 +11,8 @@ application development. It provides a simple, platform-independent API for
creating windows, contexts and surfaces, reading input, handling events, etc.
GLFW natively supports Windows, macOS and Linux and other Unix-like systems.
Experimental implementations for the Wayland protocol, the Mir display server
and direct rendering via EGLDevice are available but not yet officially
supported.
Experimental implementations for the Wayland protocol and the Mir display server
are available but not yet officially supported.
GLFW is licensed under the [zlib/libpng
license](http://www.glfw.org/license.html).
@@ -46,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,
OSMesa) or rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
does not need the headers for any context creation API (WGL, GLX, EGL, NSGL) or
rendering API (OpenGL, OpenGL ES, Vulkan) to enable support for them.
GLFW supports compilation on Windows with Visual C++ 2010 and later, MinGW and
MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC
@@ -92,9 +91,6 @@ GLFW itself depends only on the headers and libraries for your window system.
The (experimental) Wayland backend also depends on the `extra-cmake-modules`
package, which is used to generated Wayland protocol headers.
The (experimental) EGLDevice backend also depends on the `libdrm-dev`
development package.
The examples and test programs depend on a number of tiny libraries. These are
located in the `deps/` directory.
@@ -142,6 +138,8 @@ information on what to include when reporting a bug.
for retrieving gamepad input state (#900)
- Added `glfwRequestWindowAttention` function for requesting attention from the
user (#732,#988)
- Added `glfwGetEventTime` function for querying the time of the last input
event (#1012)
- Added `glfwGetKeyScancode` function that allows retrieving platform dependent
scancodes for keys (#830)
- Added `glfwSetWindowMaximizeCallback` and `GLFWwindowmaximizefun` for
@@ -209,10 +207,6 @@ 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] Added experimental support for direct rendering via EGLDevice (#786)
- [Linux] Moved to evdev for joystick input (#906,#1005)
- [Linux] Bugfix: Event processing did not detect joystick disconnection (#932)
- [Linux] Bugfix: The joystick device path could be truncated (#1025)
@@ -287,7 +281,6 @@ skills.
- David Carlier
- Arturo Castro
- Chi-kwan Chan
- Kamal Chandra
- Ian Clarkson
- Michał Cichoń
- Lambert Clara
-1
View File
@@ -257,7 +257,6 @@ ramps and clipboard. The options are:
- @b _GLFW_WAYLAND to use the Wayland API (experimental and incomplete)
- @b _GLFW_MIR to use the Mir API (experimental and incomplete)
- @b _GLFW_OSMESA to use the OSMesa API (headless and non-interactive)
- @b _GLFW_EGLDEVICE to use the EGLDevice API (experimental and incomplete)
If you are building GLFW as a shared library / dynamic library / DLL then you
must also define @b _GLFW_BUILD_DLL. Otherwise, you must not define it.
+25
View File
@@ -3366,6 +3366,31 @@ GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* window,
*/
GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* window, GLFWframebuffersizefun cbfun);
/*! @brief Returns the time of the last input event.
*
* This function returns the time, in seconds, that the last input event
* occurred. The time is collected for key, mouse button, scrolling and cursor
* position events including enter and leave. The function is intended to be
* called from the relevant event callback.
*
* @return The time of the input event, in seconds, or zero if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remarks The event timestamps provided by most platforms have much lower
* resolution than the GLFW timer.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref events
*
* @since Added in version 3.3.
*
* @ingroup window
*/
GLFWAPI double glfwGetEventTime(void);
/*! @brief Processes all pending events.
*
* This function processes only those events that are already in the event
+1 -7
View File
@@ -47,12 +47,6 @@ elseif (_GLFW_WAYLAND)
PROTOCOL
"${WAYLAND_PROTOCOLS_PKGDATADIR}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml"
BASENAME pointer-constraints-unstable-v1)
elseif(_GLFW_EGLDEVICE)
set(glfw_HEADERS ${common_HEADERS} egldevice_platform.h linux_joystick.h
posix_time.h posix_thread.h xkb_unicode.h egl_context.h)
set(glfw_SOURCES ${common_SOURCES} egldevice_init.c egldevice_monitor.c egldevice_window.c
linux_joystick.c posix_time.c posix_thread.c xkb_unicode.c
egl_context.c)
elseif (_GLFW_MIR)
set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h
posix_time.h posix_thread.h xkb_unicode.h egl_context.h
@@ -94,7 +88,7 @@ set_target_properties(glfw PROPERTIES
target_compile_definitions(glfw PRIVATE
_GLFW_USE_CONFIG_H
$<$<BOOL:${UNIX}>:_POSIX_C_SOURCE=200809L>)
$<$<BOOL:${UNIX}>:_XOPEN_SOURCE=600>)
target_include_directories(glfw PUBLIC
"$<BUILD_INTERFACE:${GLFW_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>")
+3 -5
View File
@@ -215,9 +215,8 @@ static GLFWbool updateUnicodeDataNS(void)
return GLFW_FALSE;
}
_glfw.ns.unicodeData =
TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
_glfw.ns.unicodeData = TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
if (!_glfw.ns.unicodeData)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@@ -233,8 +232,7 @@ static GLFWbool updateUnicodeDataNS(void)
static GLFWbool initializeTIS(void)
{
// This works only because Cocoa has already loaded it properly
_glfw.ns.tis.bundle =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
_glfw.ns.tis.bundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
if (!_glfw.ns.tis.bundle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
+2 -5
View File
@@ -73,9 +73,7 @@ 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;
@@ -185,8 +183,7 @@ 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;
+3 -14
View File
@@ -54,8 +54,7 @@ static char* getDisplayName(CGDirectDisplayID displayID)
while ((service = IOIteratorNext(it)) != 0)
{
info = IODisplayCreateInfoDictionary(service,
kIODisplayOnlyPreferredName);
info = IODisplayCreateInfoDictionary(service, kIODisplayOnlyPreferredName);
CFNumberRef vendorIDRef =
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
@@ -186,13 +185,7 @@ static CGDisplayFadeReservationToken beginFadeReservation(void)
CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
{
CGDisplayFade(token, 0.3,
kCGDisplayBlendNormal,
kCGDisplayBlendSolidColor,
0.0, 0.0, 0.0,
TRUE);
}
CGDisplayFade(token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, TRUE);
return token;
}
@@ -203,11 +196,7 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
{
if (token != kCGDisplayFadeReservationInvalidToken)
{
CGDisplayFade(token, 0.5,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal,
0.0, 0.0, 0.0,
FALSE);
CGDisplayFade(token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, FALSE);
CGReleaseDisplayFadeReservation(token);
}
}
+3
View File
@@ -118,6 +118,9 @@ typedef struct _GLFWlibraryNS
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// The time of the last event
double lastEventTime;
struct {
CFBundleRef bundle;
PFN_TISCopyCurrentKeyboardLayoutInputSource CopyCurrentKeyboardLayoutInputSource;
+31
View File
@@ -446,6 +446,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)mouseDown:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_LEFT,
GLFW_PRESS,
@@ -454,11 +456,15 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)mouseDragged:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
[self mouseMoved:event];
}
- (void)mouseUp:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_LEFT,
GLFW_RELEASE,
@@ -467,6 +473,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)mouseMoved:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
const double dx = [event deltaX] - window->ns.cursorWarpDeltaX;
@@ -490,6 +498,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)rightMouseDown:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_RIGHT,
GLFW_PRESS,
@@ -498,11 +508,15 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)rightMouseDragged:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
[self mouseMoved:event];
}
- (void)rightMouseUp:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
GLFW_MOUSE_BUTTON_RIGHT,
GLFW_RELEASE,
@@ -511,6 +525,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)otherMouseDown:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
(int) [event buttonNumber],
GLFW_PRESS,
@@ -519,11 +535,15 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
- (void)otherMouseDragged:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
[self mouseMoved:event];
}
- (void)otherMouseUp:(NSEvent *)event
{
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputMouseClick(window,
(int) [event buttonNumber],
GLFW_RELEASE,
@@ -588,6 +608,8 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
const int key = translateKey([event keyCode]);
const int mods = translateFlags([event modifierFlags]);
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputKey(window, key, [event keyCode], GLFW_PRESS, mods);
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
@@ -619,6 +641,9 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
{
const int key = translateKey([event keyCode]);
const int mods = translateFlags([event modifierFlags]);
_glfw.ns.lastEventTime = [event timestamp];
_glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods);
}
@@ -1462,6 +1487,12 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
[window->ns.object setLevel:NSNormalWindowLevel];
}
double _glfwPlatformGetEventTime(void)
{
/* Windows events are stored in seconds */
return _glfw.ns.lastEventTime;
}
void _glfwPlatformPollEvents(void)
{
for (;;)
-16
View File
@@ -116,18 +116,10 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
continue;
#if defined(_GLFW_EGLDEVICE)
// Only consider stream EGLConfigs
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_STREAM_BIT_KHR))
continue;
#else
// Only consider window EGLConfigs
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
continue;
#endif
#if defined(_GLFW_X11)
// Only consider EGLConfigs with associated Visuals
if (!getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID))
@@ -384,9 +376,6 @@ GLFWbool _glfwInitEGL(void)
return GLFW_FALSE;
}
// For EGLDevice backend the display gets initialized
// in _glfwPlatformInit()
#if !defined(_GLFW_EGLDEVICE)
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
if (_glfw.egl.display == EGL_NO_DISPLAY)
{
@@ -407,7 +396,6 @@ GLFWbool _glfwInitEGL(void)
_glfwTerminateEGL();
return GLFW_FALSE;
}
#endif
_glfw.egl.KHR_create_context =
extensionSupportedEGL("EGL_KHR_create_context");
@@ -593,9 +581,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
setAttrib(EGL_NONE, EGL_NONE);
}
// The surface for EGLDevice backened is created in _glfwPlatformCreateWindow
//
#if !defined (_GLFW_EGLDEVICE)
window->context.egl.surface =
eglCreateWindowSurface(_glfw.egl.display,
config,
@@ -608,7 +593,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
#endif
window->context.egl.config = config;
-7
View File
@@ -47,10 +47,6 @@ typedef struct wl_egl_window* EGLNativeWindowType;
#define EGLAPIENTRY
typedef MirEGLNativeDisplayType EGLNativeDisplayType;
typedef MirEGLNativeWindowType EGLNativeWindowType;
#elif defined(_GLFW_EGLDEVICE)
#define EGLAPIENTRY
typedef void* EGLNativeDisplayType;
typedef int EGLNativeWindowType;
#else
#error "No supported EGL platform selected"
#endif
@@ -88,8 +84,6 @@ typedef int EGLNativeWindowType;
#define EGL_OPENGL_ES_API 0x30a0
#define EGL_OPENGL_API 0x30a2
#define EGL_NONE 0x3038
#define EGL_WIDTH 0x3057
#define EGL_HEIGHT 0x3056
#define EGL_EXTENSIONS 0x3055
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
#define EGL_NATIVE_VISUAL_ID 0x302e
@@ -124,7 +118,6 @@ typedef void* EGLConfig;
typedef void* EGLContext;
typedef void* EGLDisplay;
typedef void* EGLSurface;
typedef intptr_t EGLAttrib;
// EGL function pointer typedefs
typedef EGLBoolean (EGLAPIENTRY * PFN_eglGetConfigAttrib)(EGLDisplay,EGLConfig,EGLint,EGLint*);
-284
View File
@@ -1,284 +0,0 @@
//========================================================================
// GLFW 3.3 EGLDevice - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <linux/limits.h>
static GLFWbool initializeExtensions(void)
{
_glfw.egldevice.QueryDevicesEXT =
(PFNEGLQUERYDEVICESEXTPROC)
eglGetProcAddress("eglQueryDevicesEXT");
_glfw.egldevice.QueryDeviceStringEXT =
(PFNEGLQUERYDEVICESTRINGEXTPROC)
eglGetProcAddress("eglQueryDeviceStringEXT");
_glfw.egldevice.GetPlatformDisplayEXT =
(PFNEGLGETPLATFORMDISPLAYEXTPROC)
eglGetProcAddress("eglGetPlatformDisplayEXT");
_glfw.egldevice.GetOutputLayersEXT =
(PFNEGLGETOUTPUTLAYERSEXTPROC)
eglGetProcAddress("eglGetOutputLayersEXT");
_glfw.egldevice.CreateStreamKHR =
(PFNEGLCREATESTREAMKHRPROC)
eglGetProcAddress("eglCreateStreamKHR");
_glfw.egldevice.DestroyStreamKHR =
(PFNEGLDESTROYSTREAMKHRPROC)
eglGetProcAddress("eglDestroyStreamKHR");
_glfw.egldevice.StreamConsumerOutputEXT =
(PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)
eglGetProcAddress("eglStreamConsumerOutputEXT");
_glfw.egldevice.CreateStreamProducerSurfaceKHR =
(PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)
eglGetProcAddress("eglCreateStreamProducerSurfaceKHR");
if(!_glfw.egldevice.QueryDevicesEXT ||
!_glfw.egldevice.QueryDeviceStringEXT ||
!_glfw.egldevice.GetPlatformDisplayEXT ||
!_glfw.egldevice.GetOutputLayersEXT ||
!_glfw.egldevice.CreateStreamKHR ||
!_glfw.egldevice.DestroyStreamKHR ||
!_glfw.egldevice.StreamConsumerOutputEXT ||
!_glfw.egldevice.CreateStreamProducerSurfaceKHR)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Failed to find required EGL extension functions");
return GLFW_FALSE;
}
return GLFW_TRUE;
}
static EGLDeviceEXT getEGLDevice(void)
{
int i, num_devs;
EGLDeviceEXT* egl_devs, eglDevice;
const char *clientExtensionString;
eglDevice = EGL_NO_DEVICE_EXT;
clientExtensionString = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if (!_glfwStringInExtensionString("EGL_EXT_device_base",
clientExtensionString) &&
(!_glfwStringInExtensionString("EGL_EXT_device_enumeration",
clientExtensionString) ||
!_glfwStringInExtensionString("EGL_EXT_device_query",
clientExtensionString)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: EGL_EXT_device base extensions not found");
}
if (!eglQueryDevicesEXT(0, NULL, &num_devs))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Falied to query EGLDevice");
}
if (num_devs < 1)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: No devices found");
}
egl_devs = calloc(sizeof(EGLDeviceEXT), num_devs);
if (egl_devs == NULL)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to allocate memory for device storage");
}
// Select suitable device
if (!eglQueryDevicesEXT(num_devs, egl_devs, &num_devs))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Failed to query EGL devices");
}
for (i = 0; i <= num_devs; i++)
{
const char* deviceExtensionString;
deviceExtensionString = eglQueryDeviceStringEXT(egl_devs[i], EGL_EXTENSIONS);
if (_glfwStringInExtensionString("EGL_EXT_device_drm",
deviceExtensionString))
{
eglDevice = egl_devs[i];
break;
}
}
free(egl_devs);
if (eglDevice == EGL_NO_DEVICE_EXT)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_EXT_device_drm");
}
return eglDevice;
}
static int getDRMFd(EGLDeviceEXT eglDevice)
{
int drm_fd;
const char* drmName;
drmName = eglQueryDeviceStringEXT(eglDevice, EGL_DRM_DEVICE_FILE_EXT);
if (!drmName || (strnlen(drmName, PATH_MAX) == 0))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Couldn't obtain device file from 0x%p",
(void*)(uintptr_t)eglDevice);
}
drm_fd = drmOpen(drmName, NULL);
if (drm_fd < 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Couldn't open device file '%s'", drmName);
}
return drm_fd;
}
static GLFWbool initEGLDisplay(EGLDeviceEXT egl_dev, int drm_fd)
{
const char* displayExtensionString;
EGLint displayAttribs[] = {
EGL_DRM_MASTER_FD_EXT,
drm_fd,
EGL_NONE
};
_glfw.egl.display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT,
(void*)egl_dev,
displayAttribs);
if (_glfw.egl.display == EGL_NO_DISPLAY)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Couldn't obtain EGLDisplay for device");
return GLFW_FALSE;
}
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Failed to initialize EGL");
return GLFW_FALSE;
}
// Check for stream_consumer_egloutput + output_drm support
displayExtensionString = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
if (!_glfwStringInExtensionString("EGL_EXT_output_base",
displayExtensionString))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_EXT_output_base");
return GLFW_FALSE;
}
if (!_glfwStringInExtensionString("EGL_EXT_output_drm",
displayExtensionString))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_EXT_output_drm");
return GLFW_FALSE;
}
if (!_glfwStringInExtensionString("EGL_KHR_stream",
displayExtensionString))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_KHR_stream");
return GLFW_FALSE;
}
if (!_glfwStringInExtensionString("EGL_KHR_stream_producer_eglsurface",
displayExtensionString))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_KHR_stream_producer_eglsurface");
return GLFW_FALSE;
}
if (!_glfwStringInExtensionString("EGL_EXT_stream_consumer_egloutput",
displayExtensionString))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Missing required extension EGL_EXT_stream_consumer_egloutput");
return GLFW_FALSE;
}
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
int _glfwPlatformInit(void)
{
EGLDeviceEXT egl_dev;
int drm_fd;
// Initialize EGL
if (!_glfwInitEGL())
return GLFW_FALSE;
// Initialize global data and extension function pointers
if (!initializeExtensions())
return GLFW_FALSE;
// Query and Obtain EGLDevice
egl_dev = getEGLDevice();
// Obtain and open DRM device file
drm_fd = getDRMFd(egl_dev);
// Store for use later
_glfw.egldevice.drmFd = drm_fd;
// Obtain EGLDisplay
if (!initEGLDisplay(egl_dev, drm_fd))
return GLFW_FALSE;
_glfwInitTimerPOSIX();
_glfwPollMonitorsEGLDevice();
return GLFW_TRUE;
}
void _glfwPlatformTerminate(void)
{
_glfwTerminateEGL();
_glfwTerminateJoysticksLinux();
}
const char* _glfwPlatformGetVersionString(void)
{
return _GLFW_VERSION_NUMBER "EGLDevice EGL"
#if defined(_GLFW_BUILD_DLL)
" shared"
#endif
;
}
-165
View File
@@ -1,165 +0,0 @@
//========================================================================
// GLFW 3.3 EGLDevice - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
static GLFWbool pickConnector(_GLFWmonitor* monitor, int drm_fd, drmModeRes* res_info)
{
int i, j;
// Getting suitable connector, encoder and crtc
for (i = 0; i < res_info->count_connectors; i++)
{
monitor->egldevice.connId = res_info->connectors[i];
drmModeConnector* conn_info;
conn_info =
drmModeGetConnector(drm_fd, monitor->egldevice.connId);
if (!conn_info)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to obtain info for connector (%d)",
monitor->egldevice.connId);
return GLFW_FALSE;
}
if (conn_info->connection == DRM_MODE_CONNECTED &&
conn_info->count_modes > 0 &&
conn_info->count_encoders > 0)
{
monitor->egldevice.encId = conn_info->encoders[0];
drmModeEncoder* enc_info;
enc_info =
drmModeGetEncoder(drm_fd, monitor->egldevice.encId);
if (!enc_info) {
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to query DRM-KMS information for connector index %d", i);
}
// Select the modesize
monitor->currentMode.width = (int)conn_info->modes[0].hdisplay;
monitor->currentMode.height = (int)conn_info->modes[0].vdisplay;
monitor->currentMode.refreshRate = (int)conn_info->modes[0].vrefresh;
monitor->modeCount = (int)conn_info->count_modes;
monitor->name = conn_info->modes[0].name;
for (j = 0; j < res_info->count_crtcs; j++)
{
if ((enc_info->possible_crtcs & (1 << j)) == 0)
continue;
monitor->egldevice.crtcId = res_info->crtcs[j];
monitor->egldevice.crtcIndex = j;
if (res_info->crtcs[i] == enc_info->crtc_id)
break;
}
if (monitor->egldevice.crtcId == 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to select suitable CRTC");
return GLFW_FALSE;
}
drmModeFreeEncoder(enc_info);
}
drmModeFreeConnector(conn_info);
}
return GLFW_TRUE;
}
static GLFWbool initDRMResources(_GLFWmonitor* monitor, int drm_fd)
{
drmModeRes* res_info;
res_info = drmModeGetResources(drm_fd);
if (!res_info)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Couldn't obtain DRM-KMS resources");
return GLFW_FALSE;
}
if(!pickConnector(monitor, drm_fd, res_info))
return GLFW_FALSE;
drmModeFreeResources(res_info);
return GLFW_TRUE;
}
/////////////////////////////////////////////////////////////////////////////
/////////// GLFW platform API //////////////
/////////////////////////////////////////////////////////////////////////////
void _glfwPollMonitorsEGLDevice(void)
{
_GLFWmonitor* monitor = _glfwAllocMonitor("Monitor", 0, 0);
// Obtain DRM resource info
if (!initDRMResources(monitor, _glfw.egldevice.drmFd))
{
_glfwFreeMonitor(monitor);
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_FIRST);
}
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetMonitorPos not implemented");
}
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetVideoModes not implemented");
*found = 0;
return NULL;
}
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetVideoMode not implemented");
}
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetGammaRamp not implemented");
}
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetGammaRamp not implemented");
}
-151
View File
@@ -1,151 +0,0 @@
//========================================================================
// GLFW 3.3 EGLDevice - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/select.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <dlfcn.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
#include <drm_fourcc.h>
#include "posix_time.h"
#include "linux_joystick.h"
#include "posix_thread.h"
#include "egl_context.h"
#include "osmesa_context.h"
#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT) 0)
#define EGL_DRM_DEVICE_FILE_EXT 0x3233
#define EGL_PLATFORM_DEVICE_EXT 0x313f
#define EGL_DRM_MASTER_FD_EXT 0x333c
#define EGL_STREAM_FIFO_LENGTH_KHR 0x31fc
#define EGL_DRM_CRTC_EXT 0x3234
#define EGL_NO_STREAM_KHR ((EGLStreamKHR) 0)
#define EGL_STREAM_BIT_KHR 0x0800
typedef void* EGLOutputLayerEXT;
typedef void* EGLStreamKHR;
typedef void* EGLDeviceEXT;
typedef EGLBoolean (EGLAPIENTRY * PFNEGLQUERYDEVICESEXTPROC)(EGLint,EGLDeviceEXT*,EGLint*);
typedef const char *(EGLAPIENTRY * PFNEGLQUERYDEVICESTRINGEXTPROC)(EGLDeviceEXT,EGLint);
typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLGETOUTPUTLAYERSEXTPROC)(EGLDisplay,const EGLAttrib*,EGLOutputLayerEXT*,EGLint,EGLint*);
typedef EGLStreamKHR (EGLAPIENTRY * PFNEGLCREATESTREAMKHRPROC)(EGLDisplay,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLDESTROYSTREAMKHRPROC)(EGLDisplay,EGLStreamKHR);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMCONSUMEROUTPUTEXTPROC)(EGLDisplay,EGLStreamKHR,EGLOutputLayerEXT);
typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay,EGLConfig,EGLStreamKHR,const EGLint*);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMATTRIBKHRPROC)(EGLDisplay,EGLStreamKHR,EGLenum,EGLint);
typedef EGLBoolean (EGLAPIENTRY * PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC)(EGLDisplay,EGLStreamKHR,const EGLAttrib*);
#define eglQueryDevicesEXT _glfw.egldevice.QueryDevicesEXT
#define eglQueryDeviceStringEXT _glfw.egldevice.QueryDeviceStringEXT
#define eglGetPlatformDisplayEXT _glfw.egldevice.GetPlatformDisplayEXT
#define eglGetOutputLayersEXT _glfw.egldevice.GetOutputLayersEXT
#define eglCreateStreamKHR _glfw.egldevice.CreateStreamKHR
#define eglDestroyStreamKHR _glfw.egldevice.DestroyStreamKHR
#define eglStreamConsumerOutputEXT _glfw.egldevice.StreamConsumerOutputEXT
#define eglCreateStreamProducerSurfaceKHR _glfw.egldevice.CreateStreamProducerSurfaceKHR
#define eglStreamAttribKHR _glfw.egldevice.StreamAttribKHR
#define eglStreamConsumerAcquireAttribKHR _glfw.egldevice.StreamConsumerAcquireAttribKHR
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
#define _glfw_dlclose(handle) dlclose(handle)
#define _glfw_dlsym(handle, name) dlsym(handle, name)
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType)window->egldevice.handle)
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowEGLDevice egldevice
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryEGLDevice egldevice
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorEGLDevice egldevice
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorEGLDevice egldevice
#define _GLFW_PLATFORM_CONTEXT_STATE
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
// EGLDevice-specific per-window data
//
typedef struct _GLFWwindowEGLDevice
{
int xsurfsize, ysurfsize;
int xoffset, yoffset;
int fifo;
uint32_t planeId;
EGLDisplay handle;
EGLOutputLayerEXT eglLayer;
EGLStreamKHR eglStream;
} _GLFWwindowEGLDevice;
// EGLDevice-specific global data
//
typedef struct _GLFWlibraryEGLDevice
{
int drmFd;
PFNEGLQUERYDEVICESEXTPROC QueryDevicesEXT;
PFNEGLQUERYDEVICESTRINGEXTPROC QueryDeviceStringEXT;
PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT;
PFNEGLGETOUTPUTLAYERSEXTPROC GetOutputLayersEXT;
PFNEGLCREATESTREAMKHRPROC CreateStreamKHR;
PFNEGLDESTROYSTREAMKHRPROC DestroyStreamKHR;
PFNEGLSTREAMCONSUMEROUTPUTEXTPROC StreamConsumerOutputEXT;
PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC CreateStreamProducerSurfaceKHR;
PFNEGLSTREAMATTRIBKHRPROC StreamAttribKHR;
PFNEGLSTREAMCONSUMERACQUIREATTRIBKHRPROC StreamConsumerAcquireAttribKHR;
} _GLFWlibraryEGLDevice;
// EGLDevice-specific per-monitor data
//
typedef struct _GLFWmonitorEGLDevice
{
int crtcIndex;
uint32_t connId, encId, crtcId;
} _GLFWmonitorEGLDevice;
// EGLDevice-specific per-cursor data
//
typedef struct _GLFWcursorEGLDevice
{
} _GLFWcursorEGLDevice;
void _glfwPollMonitorsEGLDevice(void);
-430
View File
@@ -1,430 +0,0 @@
//========================================================================
// GLFW 3.3 EGLDevice - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
///////////////////////////////////////////////////////////////////////////
//////// GLFW platform API /////////////
///////////////////////////////////////////////////////////////////////////
int _glfwPlatformCreateWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
int n;
_GLFWmonitor* monitor;
EGLAttrib layerAttribs[] = { EGL_NONE, EGL_NONE, EGL_NONE };
EGLint streamAttribs[] = { EGL_STREAM_FIFO_LENGTH_KHR,
window->egldevice.fifo, EGL_NONE };
EGLint surfaceAttribs[] = { EGL_WIDTH, 0, EGL_HEIGHT, 0, EGL_NONE };
if (window->monitor)
monitor = window->monitor;
else
monitor = _glfw.monitors[0];
window->egldevice.xsurfsize = wndconfig->width;
window->egldevice.ysurfsize = wndconfig->height;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
// Get the layer for this crtc/plane
layerAttribs[0] = EGL_DRM_CRTC_EXT;
layerAttribs[1] = (EGLAttrib)monitor->egldevice.crtcId;
if (!eglGetOutputLayersEXT(_glfw.egl.display, layerAttribs,
&window->egldevice.eglLayer,
1, &n) || !n)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to obtain EGLOutputLayer");
return GLFW_FALSE;
}
// Create a stream and connect to the output
window->egldevice.eglStream =
eglCreateStreamKHR(_glfw.egl.display, streamAttribs);
if (window->egldevice.eglStream == EGL_NO_STREAM_KHR)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to create stream (error 0x%x)",
eglGetError());
return GLFW_FALSE;
}
if (!eglStreamConsumerOutputEXT(_glfw.egl.display,
window->egldevice.eglStream,
window->egldevice.eglLayer))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to connect stream (error 0x%x)",
eglGetError());
return GLFW_FALSE;
}
// Create a surface to feed the stream
surfaceAttribs[1] = window->egldevice.xsurfsize;
surfaceAttribs[3] = window->egldevice.ysurfsize;
window->context.egl.surface =
eglCreateStreamProducerSurfaceKHR(_glfw.egl.display,
window->context.egl.config,
window->egldevice.eglStream,
surfaceAttribs);
if (window->context.egl.surface == EGL_NO_SURFACE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Unable to create rendering surface (error 0x%x)", eglGetError());
return GLFW_FALSE;
}
return GLFW_TRUE;
}
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
{
if (window->context.client != GLFW_NO_API)
window->context.destroy(window);
if (window->egldevice.eglStream != EGL_NO_STREAM_KHR)
eglDestroyStreamKHR(_glfw.egl.display, window->egldevice.eglStream);
}
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowTitle is not supported");
}
void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
int count, const GLFWimage* images)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowIcon is not supported");
}
void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
{
if (xpos)
*xpos = window->egldevice.xoffset;
if (ypos)
*ypos = window->egldevice.yoffset;
}
void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos)
{
window->egldevice.xoffset = xpos;
window->egldevice.yoffset = ypos;
drmModeRes* res_info;
_GLFWmonitor* monitor;
if (window->monitor)
monitor = window->monitor;
else
monitor = _glfw.monitors[0];
res_info = drmModeGetResources(_glfw.egldevice.drmFd);
if (drmModeSetCrtc(_glfw.egldevice.drmFd,
res_info->crtcs[monitor->egldevice.crtcIndex],
-1, window->egldevice.xoffset, window->egldevice.yoffset,
&res_info->connectors[monitor->egldevice.crtcIndex], 1, NULL))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: Setting window pos failed");
}
drmModeFreeResources(res_info);
}
void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->egldevice.xsurfsize;
if (height)
*height = window->egldevice.ysurfsize;
}
void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowSize not implemented");
}
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowSizeLimits not implemented");
}
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowAspectRatio not implemented");
}
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height)
{
_glfwPlatformGetWindowSize(window, width, height);
}
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetWindowFrameSize not implemented");
}
void _glfwPlatformIconifyWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformIconifyWindow not implemented");
}
void _glfwPlatformRestoreWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformRestoreWindow not implemented");
}
void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformMaximizeWindow not implemented");
}
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowResizable not implemented");
}
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowDecorated not implemented");
}
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowFloating not implemented");
}
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformRequestWindowAttention not implemented");
}
void _glfwPlatformShowWindow(_GLFWwindow* window)
{
return;
}
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformUnhideWindow not implemented");
}
void _glfwPlatformHideWindow(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformHideWindow not implemented");
}
void _glfwPlatformFocusWindow(_GLFWwindow* window)
{
return;
}
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetWindowMonitor not implemented");
}
int _glfwPlatformWindowFocused(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWindowFocused not implemented");
return GLFW_FALSE;
}
int _glfwPlatformWindowIconified(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWindowIconified not implemented");
return GLFW_FALSE;
}
int _glfwPlatformWindowVisible(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWindowVisible not implemented");
return GLFW_FALSE;
}
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWindowMaximized not implemented");
return 0;
}
void _glfwPlatformPollEvents(void)
{
_glfwDetectJoystickConnectionLinux();
}
void _glfwPlatformWaitEvents(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWaitEvents not supported");
}
void _glfwPlatformWaitEventsTimeout(double timeout)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformWaitEventsTimeout not supported");
}
void _glfwPlatformPostEmptyEvent(void)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformPostEmptyEvent not supported");
}
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetCursorPos not supported");
}
void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetCursorPos not supported");
}
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetCursorMode not supported");
}
const char* _glfwPlatformGetKeyName(int key, int scancode)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetKeyName not supported");
return NULL;
}
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformCreateCursor not supported");
return GLFW_FALSE;
}
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformCreateStandardCursor not supported");
return GLFW_FALSE;
}
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
{
return;
}
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetCursor not supported");
}
void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformSetClipboardString not supported");
}
const char* _glfwPlatformGetClipboardString(_GLFWwindow* window)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetClipboardString not supported");
return NULL;
}
const char* _glfwPlatformGetScancodeName(int scancode)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetScancodeName not supported");
return "";
}
int _glfwPlatformGetKeyScancode(int key)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetKeyScancode not supported");
return -1;
}
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetRequiredInstanceExtensions not supported");
}
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformGetPhysicalDevicePresentationSupport not supported");
return GLFW_FALSE;
}
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGLDevice: _glfwPlatformCreateWindowSurface not supported");
return VK_ERROR_INITIALIZATION_FAILED;
}
-2
View File
@@ -46,8 +46,6 @@
#cmakedefine _GLFW_MIR
// Define this to 1 if building GLFW for OSMesa
#cmakedefine _GLFW_OSMESA
// Define this to 1 if building GLFW for EGLDevice
#cmakedefine _GLFW_EGLDEVICE
// Define this to 1 if building as a shared library / dynamic library / DLL
#cmakedefine _GLFW_BUILD_DLL
+1 -2
View File
@@ -190,8 +190,6 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
#include "mir_platform.h"
#elif defined(_GLFW_OSMESA)
#include "null_platform.h"
#elif defined(_GLFW_EGLDEVICE)
#include "egldevice_platform.h"
#else
#error "No supported window creation API selected"
#endif
@@ -687,6 +685,7 @@ void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
double _glfwPlatformGetEventTime(void);
void _glfwPlatformPollEvents(void);
void _glfwPlatformWaitEvents(void);
void _glfwPlatformWaitEventsTimeout(double timeout);
+3
View File
@@ -114,6 +114,9 @@ typedef struct _GLFWlibraryMir
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// The time of the last event
int64_t lastEventTime;
} _GLFWlibraryMir;
// Mir-specific per-cursor data
+13 -2
View File
@@ -147,6 +147,8 @@ static void handleKeyEvent(const MirKeyboardEvent* key_event, _GLFWwindow* windo
const long text = _glfwKeySym2Unicode(key_code);
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
_glfw.mir.lastEventTime = mir_input_event_get_event_time((MirInputEvent *) key_event);
_glfwInputKey(window, toGLFWKeyCode(scan_code), scan_code, pressed, mods);
if (text != -1)
@@ -164,6 +166,8 @@ static void handlePointerButton(_GLFWwindow* window,
uint32_t newButtonStates = mir_pointer_event_buttons(pointer_event);
int publicButton = GLFW_MOUSE_BUTTON_LEFT;
_glfw.mir.lastEventTime = mir_input_event_get_event_time((MirEvent *) pointer_event);
// XOR our old button states our new states to figure out what was added or removed
button = newButtonStates ^ oldButtonStates;
@@ -201,6 +205,8 @@ static void handlePointerMotion(_GLFWwindow* window,
const int hscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_hscroll);
const int vscroll = mir_pointer_event_axis_value(pointer_event, mir_pointer_axis_vscroll);
_glfw.mir.lastEventTime = mir_input_event_get_event_time((MirEvent *) pointer_event);
if (window->cursorMode == GLFW_CURSOR_DISABLED)
{
if (_glfw.mir.disabledCursorWindow != window)
@@ -632,6 +638,12 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
"Mir: Unsupported function %s", __PRETTY_FUNCTION__);
}
double _glfwPlatformGetEventTime(void)
{
/* Mir events are stored in nanoseconds */
return (double) _glfw.mir.lastEventTime / 1000000000.0;
}
void _glfwPlatformPollEvents(void)
{
EventNode* node = NULL;
@@ -869,8 +881,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
vkGetPhysicalDeviceMirPresentationSupportKHR =
PFN_vkGetPhysicalDeviceMirPresentationSupportKHR vkGetPhysicalDeviceMirPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceMirPresentationSupportKHR");
if (!vkGetPhysicalDeviceMirPresentationSupportKHR)
+5
View File
@@ -204,6 +204,11 @@ int _glfwPlatformWindowVisible(_GLFWwindow* window)
return GLFW_FALSE;
}
double _glfwPlatformGetEventTime(void)
{
return 0.0;
}
void _glfwPlatformPollEvents(void)
{
}
+3 -6
View File
@@ -30,8 +30,7 @@
#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
@@ -69,8 +68,7 @@ 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;
}
@@ -80,8 +78,7 @@ 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;
}
+14 -26
View File
@@ -50,26 +50,16 @@ 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_Button = {0xa36d02f0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_POV = {0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
#define GUID_XAxis _glfw_GUID_XAxis
@@ -355,12 +345,10 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
_GLFWjoystick* js = _glfw.joysticks + jid;
if (js->present)
{
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE;
}
if (!_glfw.joysticks[jid].present)
continue;
if (memcmp(&_glfw.joysticks[jid].win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE;
}
if (supportsXInput(&di->guidProduct))
+4
View File
@@ -259,6 +259,10 @@ typedef struct _GLFWlibraryWin32
RAWINPUT* rawInput;
int rawInputSize;
// State for accumulating a non-wrapping event time
uint32_t lastTimestamp;
uint64_t eventTime;
struct {
HINSTANCE instance;
PFN_timeGetTime GetTime;
+21 -2
View File
@@ -347,6 +347,14 @@ static int getKeyMods(void)
return mods;
}
// Updates the event time with the specified timestamp
//
static void updateEventTime(LONG timestamp)
{
_glfw.win32.eventTime += (uint32_t) timestamp - _glfw.win32.lastTimestamp;
_glfw.win32.lastTimestamp = timestamp;
}
// Retrieves and translates modifier keys
//
static int getAsyncKeyMods(void)
@@ -595,6 +603,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_UNICHAR:
{
const GLFWbool plain = (uMsg != WM_SYSCHAR);
updateEventTime(GetMessageTime());
if (uMsg == WM_UNICHAR && wParam == UNICODE_NOCHAR)
{
@@ -617,6 +626,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
const int scancode = (lParam >> 16) & 0x1ff;
const int action = ((lParam >> 31) & 1) ? GLFW_RELEASE : GLFW_PRESS;
const int mods = getKeyMods();
updateEventTime(GetMessageTime());
if (key == _GLFW_KEY_INVALID)
break;
@@ -651,6 +661,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_XBUTTONUP:
{
int i, button, action;
updateEventTime(GetMessageTime());
if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
button = GLFW_MOUSE_BUTTON_LEFT;
@@ -701,6 +712,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
{
const int x = GET_X_LPARAM(lParam);
const int y = GET_Y_LPARAM(lParam);
updateEventTime(GetMessageTime());
// Disabled cursor motion input is provided by WM_INPUT
if (window->cursorMode == GLFW_CURSOR_DISABLED)
@@ -779,6 +791,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOUSELEAVE:
{
updateEventTime(GetMessageTime());
window->win32.cursorTracked = GLFW_FALSE;
_glfwInputCursorEnter(window, GLFW_FALSE);
return 0;
@@ -786,6 +799,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOUSEWHEEL:
{
updateEventTime(GetMessageTime());
_glfwInputScroll(window, 0.0, (SHORT) HIWORD(wParam) / (double) WHEEL_DELTA);
return 0;
}
@@ -793,6 +807,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_MOUSEHWHEEL:
{
// This message is only sent on Windows Vista and later
updateEventTime(GetMessageTime());
// NOTE: The X-axis is inverted for consistency with macOS and X11
_glfwInputScroll(window, -((SHORT) HIWORD(wParam) / (double) WHEEL_DELTA), 0.0);
return 0;
@@ -1498,6 +1513,11 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
}
double _glfwPlatformGetEventTime(void)
{
return (double) _glfw.win32.eventTime / 1000.0;
}
void _glfwPlatformPollEvents(void)
{
MSG msg;
@@ -1798,8 +1818,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
vkGetPhysicalDeviceWin32PresentationSupportKHR =
PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWin32PresentationSupportKHR");
if (!vkGetPhysicalDeviceWin32PresentationSupportKHR)
+6
View File
@@ -956,6 +956,12 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle
return cbfun;
}
GLFWAPI double glfwGetEventTime(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0.0);
return _glfwPlatformGetEventTime();
}
GLFWAPI void glfwPollEvents(void)
{
_GLFW_REQUIRE_INIT();
+4
View File
@@ -83,6 +83,7 @@ static void pointerHandleMotion(void* data,
if (!window)
return;
_glfw.wl.lastEventTime = time;
if (window->cursorMode == GLFW_CURSOR_DISABLED)
return;
else
@@ -109,6 +110,7 @@ static void pointerHandleButton(void* data,
if (!window)
return;
_glfw.wl.lastEventTime = time;
_glfw.wl.pointerSerial = serial;
/* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
@@ -136,6 +138,7 @@ static void pointerHandleAxis(void* data,
if (!window)
return;
_glfw.wl.lastEventTime = time;
/* Wayland scroll events are in pointer motion coordinate space (think
* two finger scroll). The factor 10 is commonly used to convert to
* "scroll step means 1.0. */
@@ -349,6 +352,7 @@ static void keyboardHandleKey(void* data,
if (!window)
return;
_glfw.wl.lastEventTime = time;
keyCode = toGLFWKeyCode(key);
action = state == WL_KEYBOARD_KEY_STATE_PRESSED
? GLFW_PRESS : GLFW_RELEASE;
+4
View File
@@ -97,6 +97,7 @@ typedef struct _GLFWwindowWayland
struct zwp_relative_pointer_v1* relativePointer;
struct zwp_locked_pointer_v1* lockedPointer;
} pointerLock;
} _GLFWwindowWayland;
// Wayland-specific global data
@@ -138,6 +139,9 @@ typedef struct _GLFWlibraryWayland
_GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus;
// The time of the last event
unsigned int lastEventTime;
} _GLFWlibraryWayland;
// Wayland-specific per-monitor data
+6 -2
View File
@@ -675,6 +675,11 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
"Wayland: Window attribute setting not implemented yet");
}
double _glfwPlatformGetEventTime(void)
{
return (double) _glfw.wl.lastEventTime / 1000.0;
}
void _glfwPlatformPollEvents(void)
{
handleEvents(0);
@@ -1019,8 +1024,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
vkGetPhysicalDeviceWaylandPresentationSupportKHR =
PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceWaylandPresentationSupportKHR");
if (!vkGetPhysicalDeviceWaylandPresentationSupportKHR)
+8 -7
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);
@@ -661,7 +661,10 @@ static GLFWbool initExtensions(void)
// String format atoms
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
_glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
_glfw.x11.UTF8_STRING =
XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
_glfw.x11.COMPOUND_STRING =
XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);
_glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);
// Custom selection property atom
@@ -672,7 +675,6 @@ 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
@@ -860,13 +862,12 @@ int _glfwPlatformInit(void)
_glfw.x11.screen = DefaultScreen(_glfw.x11.display);
_glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
_glfw.x11.context = XUniqueContext();
_glfw.x11.helperWindowHandle = createHelperWindow();
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
if (!initExtensions())
return GLFW_FALSE;
_glfw.x11.helperWindowHandle = createHelperWindow();
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
if (XSupportsLocale())
{
XSetLocaleModifiers("");
+3 -1
View File
@@ -225,6 +225,9 @@ typedef struct _GLFWlibraryX11
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// State for accumulating a non-wrapping event time
Time lastTimestamp;
uint64_t eventTime;
// Window manager atoms
Atom WM_PROTOCOLS;
@@ -265,7 +268,6 @@ typedef struct _GLFWlibraryX11
// Selection (clipboard) atoms
Atom TARGETS;
Atom MULTIPLE;
Atom INCR;
Atom CLIPBOARD;
Atom PRIMARY;
Atom CLIPBOARD_MANAGER;
+115 -192
View File
@@ -164,17 +164,6 @@ 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)
@@ -460,81 +449,6 @@ 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)
@@ -758,7 +672,9 @@ static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
{
int i;
char* selectionString = NULL;
const Atom formats[] = { _glfw.x11.UTF8_STRING, XA_STRING };
const Atom formats[] = { _glfw.x11.UTF8_STRING,
_glfw.x11.COMPOUND_STRING,
XA_STRING };
const int formatCount = sizeof(formats) / sizeof(formats[0]);
if (request->selection == _glfw.x11.PRIMARY)
@@ -780,6 +696,7 @@ 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,
@@ -924,8 +841,10 @@ static const char* getSelectionString(Atom selection)
{
size_t i;
char** selectionString = NULL;
const Atom targets[] = { _glfw.x11.UTF8_STRING, XA_STRING };
const size_t targetCount = sizeof(targets) / sizeof(targets[0]);
const Atom formats[] = { _glfw.x11.UTF8_STRING,
_glfw.x11.COMPOUND_STRING,
XA_STRING };
const size_t formatCount = sizeof(formats) / sizeof(formats[0]);
if (selection == _glfw.x11.PRIMARY)
selectionString = &_glfw.x11.primarySelectionString;
@@ -943,17 +862,14 @@ static const char* getSelectionString(Atom selection)
free(*selectionString);
*selectionString = NULL;
for (i = 0; i < targetCount; i++)
for (i = 0; i < formatCount; i++)
{
char* data;
Atom actualType;
int actualFormat;
unsigned long itemCount, bytesAfter;
XEvent notification, dummy;
XEvent event;
XConvertSelection(_glfw.x11.display,
selection,
targets[i],
formats[i],
_glfw.x11.GLFW_SELECTION,
_glfw.x11.helperWindowHandle,
CurrentTime);
@@ -961,92 +877,28 @@ static const char* getSelectionString(Atom selection)
while (!XCheckTypedWindowEvent(_glfw.x11.display,
_glfw.x11.helperWindowHandle,
SelectionNotify,
&notification))
&event))
{
waitForEvent(NULL);
}
if (notification.xselection.property == None)
if (event.xselection.property == None)
continue;
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)
if (_glfwGetWindowPropertyX11(event.xselection.requestor,
event.xselection.property,
event.xselection.target,
(unsigned char**) &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);
*selectionString = strdup(data);
}
XFree(data);
if (data)
XFree(data);
XDeleteProperty(_glfw.x11.display,
event.xselection.requestor,
event.xselection.property);
if (*selectionString)
break;
@@ -1055,7 +907,7 @@ static const char* getSelectionString(Atom selection)
if (!*selectionString)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"X11: Failed to convert selection to string");
"X11: Failed to convert clipboard to string");
}
return *selectionString;
@@ -1126,6 +978,70 @@ 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*/
// Updates the event time with the specified timestamp
//
static void updateEventTime(Time timestamp)
{
_glfw.x11.eventTime += timestamp - _glfw.x11.lastTimestamp;
_glfw.x11.lastTimestamp = timestamp;
}
// Process the specified X event
//
static void processEvent(XEvent *event)
@@ -1168,6 +1084,7 @@ static void processEvent(XEvent *event)
const double* values = re->raw_values;
double xpos = window->virtualCursorPosX;
double ypos = window->virtualCursorPosY;
updateEventTime(re->time);
if (XIMaskIsSet(re->valuators.mask, 0))
{
@@ -1213,6 +1130,7 @@ static void processEvent(XEvent *event)
const int key = translateKey(keycode);
const int mods = translateState(event->xkey.state);
const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
updateEventTime(event->xkey.time);
if (window->x11.ic)
{
@@ -1263,10 +1181,8 @@ 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)
{
@@ -1308,6 +1224,7 @@ static void processEvent(XEvent *event)
{
const int key = translateKey(keycode);
const int mods = translateState(event->xkey.state);
updateEventTime(event->xkey.time);
if (!_glfw.x11.xkb.detectable)
{
@@ -1348,6 +1265,7 @@ static void processEvent(XEvent *event)
case ButtonPress:
{
const int mods = translateState(event->xbutton.state);
updateEventTime(event->xbutton.time);
if (event->xbutton.button == Button1)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods);
@@ -1382,6 +1300,7 @@ static void processEvent(XEvent *event)
case ButtonRelease:
{
const int mods = translateState(event->xbutton.state);
updateEventTime(event->xbutton.time);
if (event->xbutton.button == Button1)
{
@@ -1419,6 +1338,8 @@ static void processEvent(XEvent *event)
case EnterNotify:
{
updateEventTime(event->xcrossing.time);
// HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
// ignore the defined cursor for hidden cursor mode
if (window->cursorMode == GLFW_CURSOR_HIDDEN)
@@ -1430,6 +1351,7 @@ static void processEvent(XEvent *event)
case LeaveNotify:
{
updateEventTime(event->xcrossing.time);
_glfwInputCursorEnter(window, GLFW_FALSE);
return;
}
@@ -1438,9 +1360,9 @@ static void processEvent(XEvent *event)
{
const int x = event->xmotion.x;
const int y = event->xmotion.y;
updateEventTime(event->xmotion.time);
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
@@ -1519,15 +1441,14 @@ 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;
@@ -1869,10 +1790,9 @@ 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;
}
@@ -2525,6 +2445,11 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
XFlush(_glfw.x11.display);
}
double _glfwPlatformGetEventTime(void)
{
return (double) _glfw.x11.eventTime / 1000.0;
}
void _glfwPlatformPollEvents(void)
{
_GLFWwindow* window;
@@ -2792,8 +2717,7 @@ 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)
@@ -2818,8 +2742,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
}
else
{
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR
vkGetPhysicalDeviceXlibPresentationSupportKHR =
PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR =
(PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)
vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
if (!vkGetPhysicalDeviceXlibPresentationSupportKHR)
+16 -12
View File
@@ -336,33 +336,35 @@ static void window_maximize_callback(GLFWwindow* window, int maximized)
static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Mouse button %i (%s) (with%s) was %s\n",
printf("%08x to %i at %0.3f: Mouse button %i (%s) (with%s) was %s at %0.3f\n",
counter++, slot->number, glfwGetTime(), button,
get_button_name(button),
get_mods_name(mods),
get_action_name(action));
get_action_name(action),
glfwGetEventTime());
}
static void cursor_position_callback(GLFWwindow* window, double x, double y)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Cursor position: %f %f\n",
counter++, slot->number, glfwGetTime(), x, y);
printf("%08x to %i at %0.3f: Cursor position: %f %f at %0.3f\n",
counter++, slot->number, glfwGetTime(), x, y, glfwGetEventTime());
}
static void cursor_enter_callback(GLFWwindow* window, int entered)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Cursor %s window\n",
printf("%08x to %i at %0.3f: Cursor %s window at %0.3f\n",
counter++, slot->number, glfwGetTime(),
entered ? "entered" : "left");
entered ? "entered" : "left",
glfwGetEventTime());
}
static void scroll_callback(GLFWwindow* window, double x, double y)
{
Slot* slot = glfwGetWindowUserPointer(window);
printf("%08x to %i at %0.3f: Scroll: %0.3f %0.3f\n",
counter++, slot->number, glfwGetTime(), x, y);
printf("%08x to %i at %0.3f: Scroll: %0.3f %0.3f at %0.3f\n",
counter++, slot->number, glfwGetTime(), x, y, glfwGetEventTime());
}
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
@@ -372,20 +374,22 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action,
if (name)
{
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (%s) (with%s) was %s\n",
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (%s) (with%s) was %s at %0.3f\n",
counter++, slot->number, glfwGetTime(), key, scancode,
get_key_name(key),
name,
get_mods_name(mods),
get_action_name(action));
get_action_name(action),
glfwGetEventTime());
}
else
{
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (with%s) was %s\n",
printf("%08x to %i at %0.3f: Key 0x%04x Scancode 0x%04x (%s) (with%s) was %s at %0.3f\n",
counter++, slot->number, glfwGetTime(), key, scancode,
get_key_name(key),
get_mods_name(mods),
get_action_name(action));
get_action_name(action),
glfwGetEventTime());
}
if (action != GLFW_PRESS)