summaryrefslogtreecommitdiff
path: root/events.c
diff options
context:
space:
mode:
Diffstat (limited to 'events.c')
-rw-r--r--events.c103
1 files changed, 102 insertions, 1 deletions
diff --git a/events.c b/events.c
index 28e1e29..beeb2e8 100644
--- a/events.c
+++ b/events.c
@@ -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 ();
}
}