mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 10:05:10 +00:00
parent
918b4e81d2
commit
a570d0a129
@ -168,6 +168,7 @@ information on what to include when reporting a bug.
|
||||
function on macOS 10.12+
|
||||
- [Cocoa] Bugfix: Running in AppSandbox would emit warnings (#816,#882)
|
||||
- [Cocoa] Bugfix: Windows created after the first were not cascaded (#195)
|
||||
- [X11] Moved to XI2 `XI_RawMotion` for disable cursor mode motion input (#125)
|
||||
- [EGL] Added support for `EGL_KHR_get_all_proc_addresses` (#871)
|
||||
- [EGL] Bugfix: The test for `EGL_RGB_BUFFER` was invalid
|
||||
|
||||
|
@ -477,6 +477,32 @@ static GLFWbool initExtensions(void)
|
||||
&_glfw.x11.vidmode.errorBase);
|
||||
}
|
||||
|
||||
_glfw.x11.xi.handle = dlopen("libXi.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||
if (_glfw.x11.xi.handle)
|
||||
{
|
||||
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
|
||||
dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
|
||||
_glfw.x11.xi.SelectEvents = (PFN_XISelectEvents)
|
||||
dlsym(_glfw.x11.xi.handle, "XISelectEvents");
|
||||
|
||||
if (XQueryExtension(_glfw.x11.display,
|
||||
"XInputExtension",
|
||||
&_glfw.x11.xi.majorOpcode,
|
||||
&_glfw.x11.xi.eventBase,
|
||||
&_glfw.x11.xi.errorBase))
|
||||
{
|
||||
_glfw.x11.xi.major = 2;
|
||||
_glfw.x11.xi.minor = 0;
|
||||
|
||||
if (XIQueryVersion(_glfw.x11.display,
|
||||
&_glfw.x11.xi.major,
|
||||
&_glfw.x11.xi.minor) == Success)
|
||||
{
|
||||
_glfw.x11.xi.available = GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for RandR extension
|
||||
if (XRRQueryExtension(_glfw.x11.display,
|
||||
&_glfw.x11.randr.eventBase,
|
||||
|
@ -47,6 +47,9 @@
|
||||
// The Xinerama extension provides legacy monitor indices
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
|
||||
// The XInput extension provides raw mouse motion input
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
typedef XID xcb_window_t;
|
||||
typedef XID xcb_visualid_t;
|
||||
typedef struct xcb_connection_t xcb_connection_t;
|
||||
@ -61,6 +64,11 @@ typedef Bool (* PFN_XF86VidModeGetGammaRampSize)(Display*,int,int*);
|
||||
#define XF86VidModeSetGammaRamp _glfw.x11.vidmode.SetGammaRamp
|
||||
#define XF86VidModeGetGammaRampSize _glfw.x11.vidmode.GetGammaRampSize
|
||||
|
||||
typedef Status (* PFN_XIQueryVersion)(Display*,int*,int*);
|
||||
typedef int (* PFN_XISelectEvents)(Display*,Window,XIEventMask*,int);
|
||||
#define XIQueryVersion _glfw.x11.xi.QueryVersion
|
||||
#define XISelectEvents _glfw.x11.xi.SelectEvents
|
||||
|
||||
typedef VkFlags VkXlibSurfaceCreateFlagsKHR;
|
||||
typedef VkFlags VkXcbSurfaceCreateFlagsKHR;
|
||||
|
||||
@ -269,6 +277,18 @@ typedef struct _GLFWlibraryX11
|
||||
PFN_XF86VidModeGetGammaRampSize GetGammaRampSize;
|
||||
} vidmode;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
void* handle;
|
||||
int majorOpcode;
|
||||
int eventBase;
|
||||
int errorBase;
|
||||
int major;
|
||||
int minor;
|
||||
PFN_XIQueryVersion QueryVersion;
|
||||
PFN_XISelectEvents SelectEvents;
|
||||
} xi;
|
||||
|
||||
} _GLFWlibraryX11;
|
||||
|
||||
// X11-specific per-monitor data
|
||||
|
@ -920,14 +920,48 @@ static void processEvent(XEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
if (event->type != GenericEvent)
|
||||
if (event->type == GenericEvent)
|
||||
{
|
||||
window = findWindowByHandle(event->xany.window);
|
||||
if (window == NULL)
|
||||
if (_glfw.x11.xi.available)
|
||||
{
|
||||
// This is an event for a window that has already been destroyed
|
||||
return;
|
||||
_GLFWwindow* window = _glfw.x11.disabledCursorWindow;
|
||||
|
||||
if (window &&
|
||||
event->xcookie.extension == _glfw.x11.xi.majorOpcode &&
|
||||
XGetEventData(_glfw.x11.display, &event->xcookie) &&
|
||||
event->xcookie.evtype == XI_RawMotion)
|
||||
{
|
||||
XIRawEvent* re = event->xcookie.data;
|
||||
if (re->valuators.mask_len)
|
||||
{
|
||||
const double* values = re->raw_values;
|
||||
double xpos = window->virtualCursorPosX;
|
||||
double ypos = window->virtualCursorPosY;
|
||||
|
||||
if (XIMaskIsSet(re->valuators.mask, 0))
|
||||
{
|
||||
xpos += *values;
|
||||
values++;
|
||||
}
|
||||
|
||||
if (XIMaskIsSet(re->valuators.mask, 1))
|
||||
ypos += *values;
|
||||
|
||||
_glfwInputCursorPos(window, xpos, ypos);
|
||||
}
|
||||
}
|
||||
|
||||
XFreeEventData(_glfw.x11.display, &event->xcookie);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
window = findWindowByHandle(event->xany.window);
|
||||
if (window == NULL)
|
||||
{
|
||||
// This is an event for a window that has already been destroyed
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event->type)
|
||||
@ -1170,6 +1204,8 @@ static void processEvent(XEvent *event)
|
||||
{
|
||||
if (_glfw.x11.disabledCursorWindow != window)
|
||||
return;
|
||||
if (_glfw.x11.xi.available)
|
||||
return;
|
||||
|
||||
const int dx = x - window->x11.lastCursorPosX;
|
||||
const int dy = y - window->x11.lastCursorPosY;
|
||||
@ -2157,6 +2193,8 @@ void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
|
||||
#if defined(__linux__)
|
||||
_glfwDetectJoystickConnectionLinux();
|
||||
#endif
|
||||
@ -2168,8 +2206,20 @@ void _glfwPlatformPollEvents(void)
|
||||
processEvent(&event);
|
||||
}
|
||||
|
||||
if (_glfw.x11.disabledCursorWindow)
|
||||
centerCursor(_glfw.x11.disabledCursorWindow);
|
||||
window = _glfw.x11.disabledCursorWindow;
|
||||
if (window)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
|
||||
// NOTE: Re-center the cursor only if it has moved since the last call,
|
||||
// to avoid breaking glfwWaitEvents with MotionNotify
|
||||
if (window->x11.lastCursorPosX != width / 2 ||
|
||||
window->x11.lastCursorPosY != height / 2)
|
||||
{
|
||||
_glfwPlatformSetCursorPos(window, width / 2, height / 2);
|
||||
}
|
||||
}
|
||||
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
@ -2239,6 +2289,19 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
{
|
||||
if (mode == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
if (_glfw.x11.xi.available)
|
||||
{
|
||||
XIEventMask em;
|
||||
unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
|
||||
|
||||
em.deviceid = XIAllMasterDevices;
|
||||
em.mask_len = sizeof(mask);
|
||||
em.mask = mask;
|
||||
XISetMask(mask, XI_RawMotion);
|
||||
|
||||
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
|
||||
}
|
||||
|
||||
_glfw.x11.disabledCursorWindow = window;
|
||||
_glfwPlatformGetCursorPos(window,
|
||||
&_glfw.x11.restoreCursorPosX,
|
||||
@ -2253,6 +2316,18 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
||||
}
|
||||
else if (_glfw.x11.disabledCursorWindow == window)
|
||||
{
|
||||
if (_glfw.x11.xi.available)
|
||||
{
|
||||
XIEventMask em;
|
||||
unsigned char mask[] = { 0 };
|
||||
|
||||
em.deviceid = XIAllMasterDevices;
|
||||
em.mask_len = sizeof(mask);
|
||||
em.mask = mask;
|
||||
|
||||
XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
|
||||
}
|
||||
|
||||
_glfw.x11.disabledCursorWindow = NULL;
|
||||
XUngrabPointer(_glfw.x11.display, CurrentTime);
|
||||
_glfwPlatformSetCursorPos(window,
|
||||
|
Loading…
Reference in New Issue
Block a user