aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nx-X11/programs/Xserver/include/os.h13
-rw-r--r--nx-X11/programs/Xserver/os/WaitFor.c5
-rw-r--r--nx-X11/programs/Xserver/os/connection.c94
-rw-r--r--nx-X11/programs/Xserver/os/osdep.h5
-rw-r--r--nx-X11/programs/Xserver/os/osinit.c1
5 files changed, 118 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h
index 0fd687d18..dfcc639d3 100644
--- a/nx-X11/programs/Xserver/include/os.h
+++ b/nx-X11/programs/Xserver/include/os.h
@@ -147,6 +147,19 @@ extern void AddEnabledDevice(int /*fd*/);
extern void RemoveEnabledDevice(int /*fd*/);
+typedef void (*NotifyFdProcPtr)(int fd, int ready, void *data);
+
+#define X_NOTIFY_NONE 0
+#define X_NOTIFY_READ 1
+#define X_NOTIFY_WRITE 2
+
+extern Bool SetNotifyFd(int fd, NotifyFdProcPtr notify_fd, int mask, void *data);
+
+static inline void RemoveNotifyFd(int fd)
+{
+ (void) SetNotifyFd(fd, NULL, X_NOTIFY_NONE, NULL);
+}
+
extern void OnlyListenToOneClient(ClientPtr /*client*/);
extern void ListenToAllClients(void);
diff --git a/nx-X11/programs/Xserver/os/WaitFor.c b/nx-X11/programs/Xserver/os/WaitFor.c
index 0ecca8b7a..19a1b9809 100644
--- a/nx-X11/programs/Xserver/os/WaitFor.c
+++ b/nx-X11/programs/Xserver/os/WaitFor.c
@@ -504,6 +504,11 @@ WaitForSomething(int *pClientsReady)
if (XFD_ANYSET(&tmp_set))
QueueWorkProc(EstablishNewConnections, NULL,
(void *)&LastSelectMask);
+
+ XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
+ if (XFD_ANYSET(&tmp_set))
+ HandleNotifyFds();
+
#ifdef DPMSExtension
if (XFD_ANYSET (&devicesReadable) && (DPMSPowerLevel != DPMSModeOn))
DPMSSet(DPMSModeOn);
diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c
index 458daab54..23df49883 100644
--- a/nx-X11/programs/Xserver/os/connection.c
+++ b/nx-X11/programs/Xserver/os/connection.c
@@ -108,6 +108,7 @@ SOFTWARE.
#include <nx-X11/Xpoll.h>
#include "opaque.h"
#include "dixstruct.h"
+#include "list.h"
#ifdef XCSECURITY
#define _SECURITY_SERVER
#include <nx-X11/extensions/security.h>
@@ -123,6 +124,7 @@ int lastfdesc; /* maximum file descriptor */
fd_set WellKnownConnections; /* Listener mask */
fd_set EnabledDevices; /* mask for input devices that are on */
+fd_set NotifyReadFds; /* mask for other file descriptors */
fd_set AllSockets; /* select on this */
fd_set AllClients; /* available clients */
fd_set LastSelectMask; /* mask returned from last select call */
@@ -1013,6 +1015,98 @@ RemoveEnabledDevice(int fd)
FD_CLR(fd, &SavedAllSockets);
}
+struct notify_fd {
+ struct xorg_list list;
+ int fd;
+ int mask;
+ NotifyFdProcPtr notify;
+ void *data;
+};
+
+static struct xorg_list notify_fds;
+
+void
+InitNotifyFds(void)
+{
+ struct notify_fd *s, *next;
+ static int been_here;
+
+ if (been_here)
+ xorg_list_for_each_entry_safe(s, next, &notify_fds, list)
+ RemoveNotifyFd(s->fd);
+
+ xorg_list_init(&notify_fds);
+ been_here = 1;
+}
+
+/*****************
+ * SetNotifyFd
+ * Registers a callback to be invoked when the specified
+ * file descriptor becomes readable.
+ *****************/
+
+Bool
+SetNotifyFd(int fd, NotifyFdProcPtr notify, int mask, void *data)
+{
+ struct notify_fd *n;
+ int changes;
+
+ xorg_list_for_each_entry(n, &notify_fds, list)
+ if (n->fd == fd)
+ break;
+
+ if (&n->list == &notify_fds) {
+ if (mask == 0)
+ return TRUE;
+
+ n = calloc(1, sizeof (struct notify_fd));
+ if (!n)
+ return FALSE;
+ n->fd = fd;
+ xorg_list_add(&n->list, &notify_fds);
+ }
+
+ changes = n->mask ^ mask;
+
+ if (changes & X_NOTIFY_READ) {
+ if (mask & X_NOTIFY_READ) {
+ FD_SET(fd, &NotifyReadFds);
+ AddGeneralSocket(fd);
+ } else {
+ RemoveGeneralSocket(fd);
+ FD_CLR(fd, &NotifyReadFds);
+ }
+ }
+ if (mask == 0) {
+ xorg_list_del(&n->list);
+ free(n);
+ } else {
+ n->mask = mask;
+ n->data = data;
+ n->notify = notify;
+ }
+
+ return TRUE;
+}
+
+/*****************
+ * HandlNotifyFds
+ * A WorkProc to be called when any of the registered
+ * file descriptors are readable.
+ *****************/
+
+void
+HandleNotifyFds(void)
+{
+ struct notify_fd *s, *next;
+
+ xorg_list_for_each_entry_safe(s, next, &notify_fds, list) {
+ if (FD_ISSET(s->fd, &LastSelectMask)) {
+ s->notify(s->fd, X_NOTIFY_READ, s->data);
+ }
+ }
+}
+
/*****************
* OnlyListenToOneClient:
* Only accept requests from one client. Continue to handle new
diff --git a/nx-X11/programs/Xserver/os/osdep.h b/nx-X11/programs/Xserver/os/osdep.h
index f0e8b707b..dce44e612 100644
--- a/nx-X11/programs/Xserver/os/osdep.h
+++ b/nx-X11/programs/Xserver/os/osdep.h
@@ -188,6 +188,10 @@ extern void FreeOsBuffers(
OsCommPtr /*oc*/
);
+extern void InitNotifyFds(void);
+
+extern void HandleNotifyFds(void);
+
#include "dix.h"
extern ConnectionInputPtr AllocateInputBuffer(void);
@@ -199,6 +203,7 @@ extern fd_set AllClients;
extern fd_set LastSelectMask;
extern fd_set WellKnownConnections;
extern fd_set EnabledDevices;
+extern fd_set NotifyReadFds;
extern fd_set ClientsWithInput;
extern fd_set ClientsWriteBlocked;
extern fd_set OutputPending;
diff --git a/nx-X11/programs/Xserver/os/osinit.c b/nx-X11/programs/Xserver/os/osinit.c
index adafa3cf4..e1986a577 100644
--- a/nx-X11/programs/Xserver/os/osinit.c
+++ b/nx-X11/programs/Xserver/os/osinit.c
@@ -203,6 +203,7 @@ OsInit(void)
#endif
been_here = TRUE;
}
+ InitNotifyFds();
TimerInit();
#ifdef DDXOSINIT
OsVendorInit();