Update glfw from upstream

Adds glfwpostemptyevent not working fix to wayland backend as well
This commit is contained in:
Kovid Goyal 2018-06-08 09:14:14 +05:30
parent 66dd83027d
commit eecf80469e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 77 additions and 51 deletions

24
glfw/wl_init.c vendored
View File

@ -24,6 +24,7 @@
// //
//======================================================================== //========================================================================
#define _GNU_SOURCE
#include "internal.h" #include "internal.h"
#include <assert.h> #include <assert.h>
@ -33,6 +34,7 @@
#include <string.h> #include <string.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h>
#include <wayland-client.h> #include <wayland-client.h>
@ -615,6 +617,13 @@ static const struct wl_registry_listener registryListener = {
int _glfwPlatformInit(void) int _glfwPlatformInit(void)
{ {
if (pipe2(_glfw.wl.eventLoopData.wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: failed to create self pipe");
return GLFW_FALSE;
}
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0"); _glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
if (!_glfw.wl.cursor.handle) if (!_glfw.wl.cursor.handle)
{ {
@ -654,6 +663,10 @@ int _glfwPlatformInit(void)
"Wayland: Failed to connect to display"); "Wayland: Failed to connect to display");
return GLFW_FALSE; return GLFW_FALSE;
} }
_glfw.wl.eventLoopData.fds[0].fd = _glfw.wl.eventLoopData.wakeupFds[0];
_glfw.wl.eventLoopData.fds[1].fd = wl_display_get_fd(_glfw.wl.display);
_glfw.wl.eventLoopData.fds[0].events = POLLIN;
_glfw.wl.eventLoopData.fds[1].events = POLLIN;
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL); wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);
@ -691,6 +704,17 @@ int _glfwPlatformInit(void)
void _glfwPlatformTerminate(void) void _glfwPlatformTerminate(void)
{ {
if (_glfw.wl.eventLoopData.wakeupFds[0] > 0)
{
close(_glfw.wl.eventLoopData.wakeupFds[0]);
_glfw.wl.eventLoopData.wakeupFds[0] = -1;
}
if (_glfw.wl.eventLoopData.wakeupFds[1] > 0)
{
close(_glfw.wl.eventLoopData.wakeupFds[1]);
_glfw.wl.eventLoopData.wakeupFds[1] = -1;
}
#ifdef __linux__ #ifdef __linux__
_glfwTerminateJoysticksLinux(); _glfwTerminateJoysticksLinux();
#endif #endif

6
glfw/wl_platform.h vendored
View File

@ -26,6 +26,7 @@
#include <wayland-client.h> #include <wayland-client.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <poll.h>
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR; typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
@ -228,6 +229,11 @@ typedef struct _GLFWlibraryWayland
PFN_wl_egl_window_resize window_resize; PFN_wl_egl_window_resize window_resize;
} egl; } egl;
struct {
struct pollfd fds[2];
int wakeupFds[2];
} eventLoopData;
} _GLFWlibraryWayland; } _GLFWlibraryWayland;
// Wayland-specific per-monitor data // Wayland-specific per-monitor data

50
glfw/wl_window.c vendored
View File

@ -700,21 +700,30 @@ dispatchPendingKeyRepeats() {
} }
} }
static int static double
adjustTimeoutForKeyRepeat(int timeout) { adjustTimeoutForKeyRepeat(double timeout) {
if (_glfw.wl.keyRepeatInfo.nextRepeatAt <= 0 || _glfw.wl.keyRepeatInfo.keyboardFocus != _glfw.wl.keyboardFocus || _glfw.wl.keyboardRepeatRate == 0) return timeout; if (_glfw.wl.keyRepeatInfo.nextRepeatAt <= 0 || _glfw.wl.keyRepeatInfo.keyboardFocus != _glfw.wl.keyboardFocus || _glfw.wl.keyboardRepeatRate == 0) return timeout;
double now = glfwGetTime(); double now = glfwGetTime();
if (timeout < 0 || now + timeout / 1000. > _glfw.wl.keyRepeatInfo.nextRepeatAt) { if (timeout < 0 || now + timeout > _glfw.wl.keyRepeatInfo.nextRepeatAt) {
timeout = _glfw.wl.keyRepeatInfo.nextRepeatAt <= now ? 0 : ( (_glfw.wl.keyRepeatInfo.nextRepeatAt - now) * 1000 + 1 ); timeout = _glfw.wl.keyRepeatInfo.nextRepeatAt <= now ? 0 : ( (_glfw.wl.keyRepeatInfo.nextRepeatAt - now) + 0.001 );
} }
return timeout; return timeout;
} }
#ifdef __NetBSD__
#define ppoll pollts
#endif
static inline void
drainFd(int fd) {
static char drain_buf[64];
while(read(fd, drain_buf, sizeof(drain_buf)) < 0 && errno == EINTR);
}
static void static void
handleEvents(int timeout) handleEvents(double timeout)
{ {
struct wl_display* display = _glfw.wl.display; struct wl_display* display = _glfw.wl.display;
struct pollfd pfd = { wl_display_get_fd(display), POLLIN };
while (wl_display_prepare_read(display) != 0) while (wl_display_prepare_read(display) != 0)
wl_display_dispatch_pending(display); wl_display_dispatch_pending(display);
@ -736,19 +745,27 @@ handleEvents(int timeout)
dispatchPendingKeyRepeats(); dispatchPendingKeyRepeats();
timeout = adjustTimeoutForKeyRepeat(timeout); timeout = adjustTimeoutForKeyRepeat(timeout);
GLFWbool read_ok = GLFW_FALSE;
if (poll(&pfd, 1, timeout) > 0) if (timeout >= 0) {
{ const long seconds = (long) timeout;
if (pfd.revents & POLLIN) const long nanoseconds = (long) ((timeout - seconds) * 1e9);
struct timespec tv = { seconds, nanoseconds };
const int result = ppoll(_glfw.wl.eventLoopData.fds, 2, &tv, NULL);
if (result > 0)
{ {
wl_display_read_events(display); if (_glfw.wl.eventLoopData.fds[0].revents && POLLIN) drainFd(_glfw.wl.eventLoopData.fds[0].fd);
wl_display_dispatch_pending(display); read_ok = _glfw.wl.eventLoopData.fds[1].revents && POLLIN;
} }
else } else {
{ if (poll(_glfw.wl.eventLoopData.fds, 2, -1) > 0) {
wl_display_cancel_read(display); if (_glfw.wl.eventLoopData.fds[0].revents && POLLIN) drainFd(_glfw.wl.eventLoopData.fds[0].fd);
read_ok = _glfw.wl.eventLoopData.fds[1].revents && POLLIN;
} }
}
if (read_ok) {
wl_display_read_events(display);
wl_display_dispatch_pending(display);
} }
else else
{ {
@ -1206,12 +1223,13 @@ void _glfwPlatformWaitEvents(void)
void _glfwPlatformWaitEventsTimeout(double timeout) void _glfwPlatformWaitEventsTimeout(double timeout)
{ {
handleEvents((int) (timeout * 1e3)); handleEvents(timeout);
} }
void _glfwPlatformPostEmptyEvent(void) void _glfwPlatformPostEmptyEvent(void)
{ {
wl_display_sync(_glfw.wl.display); wl_display_sync(_glfw.wl.display);
while (write(_glfw.wl.eventLoopData.wakeupFds[1], "w", 1) < 0 && errno == EINTR);
} }
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)

23
glfw/x11_init.c vendored
View File

@ -25,6 +25,7 @@
// //
//======================================================================== //========================================================================
#define _GNU_SOURCE
#include "internal.h" #include "internal.h"
#include <X11/Xresource.h> #include <X11/Xresource.h>
@ -590,24 +591,6 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
return cursor; return cursor;
} }
static inline GLFWbool
selfPipe(int fds[2]) {
int flags;
flags = pipe(fds);
if (flags != 0) return GLFW_FALSE;
for (int i = 0; i < 2; i++) {
flags = fcntl(fds[i], F_GETFD);
if (flags == -1) { return GLFW_FALSE; }
if (fcntl(fds[i], F_SETFD, flags | FD_CLOEXEC) == -1) { return GLFW_FALSE; }
flags = fcntl(fds[i], F_GETFL);
if (flags == -1) { return GLFW_FALSE; }
if (fcntl(fds[i], F_SETFL, flags | O_NONBLOCK) == -1) { return GLFW_FALSE; }
}
return GLFW_TRUE;
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -617,7 +600,7 @@ int _glfwPlatformInit(void)
XInitThreads(); XInitThreads();
XrmInitialize(); XrmInitialize();
if (!selfPipe(_glfw.x11.eventLoopData.wakeupFds)) if (pipe2(_glfw.x11.eventLoopData.wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
"X11: failed to create self pipe"); "X11: failed to create self pipe");
@ -706,8 +689,8 @@ void _glfwPlatformTerminate(void)
} }
if (_glfw.x11.eventLoopData.wakeupFds[1] > 0) if (_glfw.x11.eventLoopData.wakeupFds[1] > 0)
{ {
_glfw.x11.eventLoopData.wakeupFds[1] = -1;
close(_glfw.x11.eventLoopData.wakeupFds[1]); close(_glfw.x11.eventLoopData.wakeupFds[1]);
_glfw.x11.eventLoopData.wakeupFds[1] = -1;
} }
_glfw.x11.eventLoopData.fds[0].fd = -1; _glfw.x11.eventLoopData.fds[0].fd = -1;
} }

25
glfw/x11_window.c vendored
View File

@ -25,6 +25,7 @@
// //
//======================================================================== //========================================================================
#define _GNU_SOURCE
#include "internal.h" #include "internal.h"
#include <X11/cursorfont.h> #include <X11/cursorfont.h>
@ -51,16 +52,12 @@
static inline void static inline void
drainFd(int fd) { drainFd(int fd) {
static char drain_buf[64]; static char drain_buf[64];
while(1) { while(read(fd, drain_buf, sizeof(drain_buf)) < 0 && errno == EINTR);
ssize_t len = read(fd, drain_buf, sizeof(drain_buf));
if (len < 0) {
if (errno == EINTR) continue;
break;
}
break;
}
} }
#ifdef __NetBSD__
#define ppoll pollts
#endif
// Wait for data to arrive using poll // Wait for data to arrive using poll
// This avoids blocking other threads via the per-display Xlib lock that also // This avoids blocking other threads via the per-display Xlib lock that also
@ -82,9 +79,11 @@ static GLFWbool waitForEvent(double* timeout)
for (nfds_t i = 0; i < count; i++) _glfw.x11.eventLoopData.fds[i].revents = 0; for (nfds_t i = 0; i < count; i++) _glfw.x11.eventLoopData.fds[i].revents = 0;
if (timeout) if (timeout)
{ {
const int milliseconds = (int) ((*timeout) * 1000); const long seconds = (long) *timeout;
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
struct timespec tv = { seconds, nanoseconds };
const uint64_t base = _glfwPlatformGetTimerValue(); const uint64_t base = _glfwPlatformGetTimerValue();
const int result = poll(_glfw.x11.eventLoopData.fds, count, milliseconds); const int result = ppoll(_glfw.x11.eventLoopData.fds, count, &tv, NULL);
*timeout -= (_glfwPlatformGetTimerValue() - base) / *timeout -= (_glfwPlatformGetTimerValue() - base) /
(double) _glfwPlatformGetTimerFrequency(); (double) _glfwPlatformGetTimerFrequency();
@ -2612,11 +2611,7 @@ void _glfwPlatformPostEmptyEvent(void)
XSendEvent(_glfw.x11.display, _glfw.x11.helperWindowHandle, False, 0, &event); XSendEvent(_glfw.x11.display, _glfw.x11.helperWindowHandle, False, 0, &event);
XFlush(_glfw.x11.display); XFlush(_glfw.x11.display);
while(1) while (write(_glfw.x11.eventLoopData.wakeupFds[1], "w", 1) < 0 && errno == EINTR);
{
if (write(_glfw.x11.eventLoopData.wakeupFds[1], "w", 1) >= 0 || errno != EINTR)
break;
}
} }
void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos)