mirror of
https://github.com/X11Libre/xserver.git
synced 2026-03-24 08:04:30 +00:00
kdrive: add fd notification machinery
This will be needed by Xfbdev's keyboard driver, which cannot work with input threads yet. Signed-off-by: stefan11111 <stefan11111@shitposting.expert> Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
committed by
Enrico Weigelt
parent
205c07979b
commit
be7784fce2
@@ -431,6 +431,12 @@ void
|
||||
void
|
||||
KdCloseInput(void);
|
||||
|
||||
Bool KdRegisterFd(int fd, void (*read) (int fd, void *closure), void *closure);
|
||||
|
||||
void KdUnregisterFds(void *closure, Bool do_close);
|
||||
|
||||
void KdUnregisterFd(void *closure, int fd, Bool do_close);
|
||||
|
||||
void
|
||||
KdEnqueueKeyboardEvent(KdKeyboardInfo * ki, unsigned char scan_code,
|
||||
unsigned char is_up);
|
||||
|
||||
@@ -77,6 +77,22 @@ static KdPointerMatrix kdPointerMatrix = {
|
||||
{0, 1, 0}}
|
||||
};
|
||||
|
||||
#define KD_MAX_INPUT_FDS 8
|
||||
|
||||
typedef struct _kdInputFd {
|
||||
int fd;
|
||||
void (*read) (int fd, void *closure);
|
||||
int (*enable) (int fd, void *closure);
|
||||
void (*disable) (int fd, void *closure);
|
||||
void *closure;
|
||||
} KdInputFd;
|
||||
|
||||
static KdInputFd kdInputFds[KD_MAX_INPUT_FDS];
|
||||
static int kdNumInputFds = 0;
|
||||
#ifdef KDRIVE_KBD
|
||||
static int kdnFds = 0;
|
||||
#endif
|
||||
|
||||
extern Bool kdRawPointerCoordinates;
|
||||
|
||||
extern const char *kdGlobalXkbRules;
|
||||
@@ -85,6 +101,14 @@ extern const char *kdGlobalXkbLayout;
|
||||
extern const char *kdGlobalXkbVariant;
|
||||
extern const char *kdGlobalXkbOptions;
|
||||
|
||||
#ifdef KDRIVE_KBD
|
||||
static void KdSigio(int sig)
|
||||
{
|
||||
for (int i = 0; i < kdNumInputFds; i++)
|
||||
(*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FNONBLOCK
|
||||
#define NOBLOCK FNONBLOCK
|
||||
#else
|
||||
@@ -102,6 +126,106 @@ KdResetInputMachine(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void KdNonBlockFd(int fd)
|
||||
{
|
||||
#ifndef WIN32
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
flags |= FASYNC | NOBLOCK;
|
||||
fcntl(fd, F_SETFL, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void KdNotifyFd(int fd, int ready, void *data)
|
||||
{
|
||||
int i = (int) (intptr_t) data;
|
||||
(*kdInputFds[i].read)(fd, kdInputFds[i].closure);
|
||||
}
|
||||
|
||||
static void KdAddFd(int fd, int i)
|
||||
{
|
||||
#ifdef KDRIVE_KBD
|
||||
struct sigaction act;
|
||||
|
||||
sigset_t set;
|
||||
|
||||
kdnFds++;
|
||||
fcntl(fd, F_SETOWN, getpid());
|
||||
#endif
|
||||
KdNonBlockFd(fd);
|
||||
InputThreadRegisterDev(fd, KdNotifyFd, (void *) (intptr_t) i);
|
||||
#ifdef KDRIVE_KBD
|
||||
memset(&act, '\0', sizeof act);
|
||||
act.sa_handler = KdSigio;
|
||||
|
||||
sigemptyset(&act.sa_mask);
|
||||
sigaddset(&act.sa_mask, SIGIO);
|
||||
sigaddset(&act.sa_mask, SIGALRM);
|
||||
sigaddset(&act.sa_mask, SIGVTALRM);
|
||||
sigaction(SIGIO, &act, 0);
|
||||
sigemptyset(&set);
|
||||
sigprocmask(SIG_SETMASK, &set, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void KdRemoveFd(int fd)
|
||||
{
|
||||
InputThreadUnregisterDev(fd);
|
||||
#ifndef WIN32
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
flags &= ~(FASYNC | NOBLOCK);
|
||||
fcntl(fd, F_SETFL, flags);
|
||||
#endif
|
||||
#ifdef KDRIVE_KBD
|
||||
struct sigaction act;
|
||||
kdnFds--;
|
||||
if (kdnFds == 0) {
|
||||
memset(&act, '\0', sizeof act);
|
||||
act.sa_handler = SIG_IGN;
|
||||
sigemptyset(&act.sa_mask);
|
||||
sigaction(SIGIO, &act, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
Bool KdRegisterFd(int fd, void (*read) (int fd, void *closure), void *closure)
|
||||
{
|
||||
if (kdNumInputFds == KD_MAX_INPUT_FDS)
|
||||
return FALSE;
|
||||
kdInputFds[kdNumInputFds].fd = fd;
|
||||
kdInputFds[kdNumInputFds].read = read;
|
||||
kdInputFds[kdNumInputFds].enable = 0;
|
||||
kdInputFds[kdNumInputFds].disable = 0;
|
||||
kdInputFds[kdNumInputFds].closure = closure;
|
||||
if (kdInputEnabled)
|
||||
KdAddFd(fd, kdNumInputFds);
|
||||
kdNumInputFds++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void KdUnregisterFd(void *closure, int fd, Bool do_close)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < kdNumInputFds; i++) {
|
||||
if (kdInputFds[i].closure == closure &&
|
||||
(fd == -1 || kdInputFds[i].fd == fd)) {
|
||||
if (kdInputEnabled)
|
||||
KdRemoveFd(kdInputFds[i].fd);
|
||||
if (do_close)
|
||||
close(kdInputFds[i].fd);
|
||||
for (j = i; j < (kdNumInputFds - 1); j++)
|
||||
kdInputFds[j] = kdInputFds[j + 1];
|
||||
kdNumInputFds--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KdUnregisterFds(void *closure, Bool do_close)
|
||||
{
|
||||
KdUnregisterFd(closure, -1, do_close);
|
||||
}
|
||||
|
||||
void
|
||||
KdDisableInput(void)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user