diff options
-rw-r--r-- | nx-X11/programs/Xserver/include/os.h | 13 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/os/WaitFor.c | 5 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/os/connection.c | 94 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/os/osdep.h | 5 | ||||
-rw-r--r-- | nx-X11/programs/Xserver/os/osinit.c | 1 |
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, ¬ify_fds, list) + RemoveNotifyFd(s->fd); + + xorg_list_init(¬ify_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, ¬ify_fds, list) + if (n->fd == fd) + break; + + if (&n->list == ¬ify_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, ¬ify_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, ¬ify_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(); |