commit 27b2e09f579c84c2c268866e65448e1973c9db55
parent 138e8991421ebca4db85e6d942df0bd6926ff2a5
Author: Christophe-Marie Duquesne <chm.duquesne@gmail.com>
Date: Tue, 7 Dec 2010 18:05:39 +0100
Added my patch for reading stdin and X with select()
Diffstat:
2 files changed, 130 insertions(+), 0 deletions(-)
diff --git a/tools.suckless.org/dmenu/patches/dmenu-tip-non-blocking-stdin.diff b/tools.suckless.org/dmenu/patches/dmenu-tip-non-blocking-stdin.diff
@@ -0,0 +1,110 @@
+diff -r 2b9683c50723 dmenu.c
+--- a/dmenu.c Wed Dec 01 20:25:10 2010 +0000
++++ b/dmenu.c Tue Dec 07 17:32:54 2010 +0100
+@@ -4,6 +4,8 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
++#include <fcntl.h>
++#include <sys/select.h>
+ #include <X11/Xlib.h>
+ #include <X11/Xatom.h>
+ #include <X11/Xutil.h>
+@@ -34,6 +36,7 @@
+ static size_t nextrune(int incr);
+ static void paste(void);
+ static void readstdin(void);
++static void readXEvent(void);
+ static void run(void);
+ static void setup(void);
+ static void usage(void);
+@@ -59,6 +62,7 @@
+ static Item *items = NULL;
+ static Item *matches, *sel;
+ static Item *prev, *curr, *next;
++static Item **end = &items;
+ static Window root, win;
+
+ static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
+@@ -102,7 +106,6 @@
+
+ dc = initdc();
+ initfont(dc, font);
+- readstdin();
+ setup();
+ run();
+
+@@ -433,9 +436,9 @@
+ void
+ readstdin(void) {
+ char buf[sizeof text], *p;
+- Item *item, **end;
++ Item *item;
+
+- for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) {
++ while (fgets(buf, sizeof buf, stdin)) {
+ if((p = strchr(buf, '\n')))
+ *p = '\0';
+ if(!(item = malloc(sizeof *item)))
+@@ -444,14 +447,17 @@
+ eprintf("cannot strdup %u bytes\n", strlen(buf)+1);
+ item->next = item->left = item->right = NULL;
+ inputw = MAX(inputw, textw(dc, item->text));
++ *end = item;
++ end = &item->next;
+ }
++ match();
+ }
+
+ void
+-run(void) {
++readXEvent(void) {
+ XEvent ev;
+
+- while(!XNextEvent(dc->dpy, &ev))
++ while(XPending(dc->dpy) && !XNextEvent(dc->dpy, &ev))
+ switch(ev.type) {
+ case Expose:
+ if(ev.xexpose.count == 0)
+@@ -472,6 +478,32 @@
+ }
+
+ void
++run(void) {
++ fd_set fds;
++ int x11_fd, n, nfds, flags;
++
++ flags = fcntl(STDIN_FILENO, F_GETFL);
++ flags |= O_NONBLOCK;
++ fcntl(STDIN_FILENO, F_SETFL, flags);
++
++ x11_fd = XConnectionNumber(dc->dpy);
++ nfds = MAX(STDIN_FILENO, x11_fd) + 1;
++ while(1) {
++ FD_ZERO(&fds);
++ if (!feof(stdin))
++ FD_SET(STDIN_FILENO, &fds);
++ FD_SET(x11_fd, &fds);
++ n = select(nfds, &fds, NULL, NULL, NULL);
++ if(n < 0)
++ eprintf("cannot select\n");
++ if (FD_ISSET(STDIN_FILENO, &fds))
++ readstdin();
++ if (FD_ISSET(x11_fd, &fds))
++ readXEvent();
++ }
++}
++
++void
+ setup(void) {
+ int x, y, screen;
+ XSetWindowAttributes wa;
+@@ -531,7 +563,7 @@
+ promptw = prompt ? textw(dc, prompt) : 0;
+ XMapRaised(dc->dpy, win);
+ text[0] = '\0';
+- match();
++ drawmenu();
+ }
+
+ void
diff --git a/tools.suckless.org/dmenu/patches/non_blocking_stdin.md b/tools.suckless.org/dmenu/patches/non_blocking_stdin.md
@@ -0,0 +1,20 @@
+NON BLOCKING STDIN
+==================
+
+Description
+-----------
+
+A patch to have dmenu read stdin in a non blocking way, making it wait for
+input both from stdin and from X. This way, you can continue feeding dmenu
+while you type. This patch is meant to be used along with the incremental
+patch, so that you can use stdout to feed stdin.
+
+Download
+--------
+
+* [dmenu-tip-non-blocking-stdin.diff](dmenu-tip-non-blocking-stdin.diff)
+
+Author
+------
+
+* Christophe-Marie Duquesne