mirror of
https://github.com/glfw/glfw.git
synced 2026-09-23 09:08:58 +00:00
Share X11 fd polling logic with Wayland
This moves the X11 polling implementation to a separate file where it can be used by either the X11 or Wayland backend or both. This code should be POSIX compatible where necessary but will use the lower latency but non-standard polling functions ppoll or pollts where those are available. This commit is based on work by OlivierSohn and kovidgoyal. Fixes #1281 Closes #1285
This commit is contained in:
+2
-55
@@ -27,18 +27,12 @@
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#if defined(__linux__)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/Xmd.h>
|
||||
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@@ -62,53 +56,6 @@
|
||||
|
||||
#define _GLFW_XDND_VERSION 5
|
||||
|
||||
// Wait for data to arrive on any of the specified file descriptors
|
||||
//
|
||||
static GLFWbool waitForData(struct pollfd* fds, nfds_t count, double* timeout)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (timeout)
|
||||
{
|
||||
const uint64_t base = _glfwPlatformGetTimerValue();
|
||||
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
|
||||
const time_t seconds = (time_t) *timeout;
|
||||
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
|
||||
const struct timespec ts = { seconds, nanoseconds };
|
||||
const int result = ppoll(fds, count, &ts, NULL);
|
||||
#elif defined(__NetBSD__)
|
||||
const time_t seconds = (time_t) *timeout;
|
||||
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
|
||||
const struct timespec ts = { seconds, nanoseconds };
|
||||
const int result = pollts(fds, count, &ts, NULL);
|
||||
#else
|
||||
const int milliseconds = (int) (*timeout * 1e3);
|
||||
const int result = poll(fds, count, milliseconds);
|
||||
#endif
|
||||
const int error = errno; // clock_gettime may overwrite our error
|
||||
|
||||
*timeout -= (_glfwPlatformGetTimerValue() - base) /
|
||||
(double) _glfwPlatformGetTimerFrequency();
|
||||
|
||||
if (result > 0)
|
||||
return GLFW_TRUE;
|
||||
else if (result == -1 && error != EINTR && error != EAGAIN)
|
||||
return GLFW_FALSE;
|
||||
else if (*timeout <= 0.0)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int result = poll(fds, count, -1);
|
||||
if (result > 0)
|
||||
return GLFW_TRUE;
|
||||
else if (result == -1 && errno != EINTR && errno != EAGAIN)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for event data to arrive on the X11 display socket
|
||||
// This avoids blocking other threads via the per-display Xlib lock that also
|
||||
// covers GLX functions
|
||||
@@ -119,7 +66,7 @@ static GLFWbool waitForX11Event(double* timeout)
|
||||
|
||||
while (!XPending(_glfw.x11.display))
|
||||
{
|
||||
if (!waitForData(&fd, 1, timeout))
|
||||
if (!_glfwPollPOSIX(&fd, 1, timeout))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
@@ -146,7 +93,7 @@ static GLFWbool waitForAnyEvent(double* timeout)
|
||||
|
||||
while (!XPending(_glfw.x11.display))
|
||||
{
|
||||
if (!waitForData(fds, count, timeout))
|
||||
if (!_glfwPollPOSIX(fds, count, timeout))
|
||||
return GLFW_FALSE;
|
||||
|
||||
for (int i = 1; i < count; i++)
|
||||
|
||||
Reference in New Issue
Block a user