diff options
Diffstat (limited to 'events.c')
-rw-r--r-- | events.c | 103 |
1 files changed, 102 insertions, 1 deletions
@@ -38,6 +38,9 @@ #include <stdio.h> #include <string.h> +#include <signal.h> +#include <poll.h> +#include <errno.h> #include "twm.h" #include <X11/Xatom.h> #include "add_window.h" @@ -63,6 +66,9 @@ #include <sys/types.h> /* RAISEDELAY */ #include <unistd.h> #endif +#include <unistd.h> +#include <assert.h> +#include <sys/fcntl.h> extern void IconDown(); /* djhjr - 4/26/99 */ @@ -362,6 +368,68 @@ Bool DispatchEvent () /*********************************************************************** * + * Procedures: + * HandleSignal use instead of signal + * + *********************************************************************** + */ + +#define HANDLE_SIG_MAX 256 /* increase means changing type written to pipe */ + +static SigProc signaltable[HANDLE_SIG_MAX]; +static int sigselfpipe[2] = { -1, -1 }; + +static void +SelfPipeHandler(sig) + int sig; +{ + unsigned char sigchar = sig; + int esave; + + esave = errno; + write(sigselfpipe[1], &sigchar, 1); + errno = esave; +} + +void +HandleSignal(sig, func) + int sig; + SigProc func; +{ + struct sigaction sa; + int r, i; + + if (sigselfpipe[0] == -1) { + r = pipe(sigselfpipe); + if (r) { perror("pipe for signals"); exit(-1); } + for (i = 0; i < 2; i++) { + r = fcntl(sigselfpipe[i], F_GETFL); + if (r<0) { perror("fcntl get for pipe"); exit(-1); } + r |= O_NONBLOCK; + r = fcntl(sigselfpipe[i], F_SETFL, r); + if (r<0) { perror("fcntl get for pipe"); exit(-1); } + } + } + + assert(sig < HANDLE_SIG_MAX); + + r = sigaction(sig, NULL, &sa); + if (r) { perror("sigaction get"); exit(-1); } + + if (sa.sa_handler != SIG_DFL) + return; + + signaltable[sig] = func; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SelfPipeHandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + r = sigaction(sig, &sa, NULL); + if (r) { perror("sigaction set"); exit(-1); } +} + +/*********************************************************************** + * * Procedure: * HandleEvents - handle X events * @@ -371,6 +439,14 @@ Bool DispatchEvent () void HandleEvents() { + struct pollfd pfds[2]; + pfds[0].fd = ConnectionNumber(dpy); + pfds[0].events = POLLIN|POLLPRI; + pfds[1].fd = sigselfpipe[0]; + pfds[1].events = POLLIN|POLLPRI; + sigset_t emptyset; + sigemptyset(&emptyset); + while (TRUE) { if (enter_flag && !QLength(dpy)) { @@ -384,7 +460,32 @@ HandleEvents() InstallWindowColormaps(ColormapNotify, (TwmWindow *) NULL); } WindowMoved = FALSE; - XNextEvent(dpy, &Event); + while (!XCheckMaskEvent(dpy, -1 /* wot no AllEventMask */, &Event)) { + int r; + unsigned char signum; + r = poll(pfds, 2, -1); + if (r<0 && errno!=EINTR) { + perror("vtwm: poll failed"); + exit(-1); + } + for (;;) { + r = read(sigselfpipe[0], &signum, 1); + if (r < 0) { + if (errno == EINTR) continue; + if (errno == EAGAIN) break; + if (errno == EWOULDBLOCK) break; + perror("vtwm: read signal self-pipe"); + exit(-1); + } + if (!r) { + fputs("signal self-pipe read EOF!",stderr); + exit(-1); + } + assert(signum < HANDLE_SIG_MAX); + assert(signaltable[signum]); + signaltable[signum](signum); + } + } (void) DispatchEvent (); } } |