dmenu-qalc-5.2.diff (6671B)
1 diff -up dmenu-5.2/config.mk dmenu-qalc-5.2/config.mk 2 --- dmenu-5.2/config.mk 2022-10-04 13:36:58.000000000 -0400 3 +++ dmenu-qalc-5.2/config.mk 2023-10-27 19:29:48.197693355 -0400 4 @@ -24,7 +24,7 @@ INCS = -I$(X11INC) -I$(FREETYPEINC) 5 LIBS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS) 6 7 # flags 8 -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) 9 +CPPFLAGS = -D_DEFAULT_SOURCE -D_GNU_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_POSIX_C_SOURCE=200809L -DVERSION=\"$(VERSION)\" $(XINERAMAFLAGS) 10 CFLAGS = -std=c99 -pedantic -Wall -Os $(INCS) $(CPPFLAGS) 11 LDFLAGS = $(LIBS) 12 13 diff -up dmenu-5.2/dmenu.1 dmenu-qalc-5.2/dmenu.1 14 --- dmenu-5.2/dmenu.1 2022-10-04 13:36:58.000000000 -0400 15 +++ dmenu-qalc-5.2/dmenu.1 2023-10-27 19:28:48.676578875 -0400 16 @@ -40,6 +40,9 @@ which lists programs in the user's $PATH 17 .B \-b 18 dmenu appears at the bottom of the screen. 19 .TP 20 +.B \-C 21 +dmenu becomes a calculator. 22 +.TP 23 .B \-f 24 dmenu grabs the keyboard before reading stdin if not reading from a tty. This 25 is faster, but will lock up X until stdin reaches end\-of\-file. 26 diff -up dmenu-5.2/dmenu.c dmenu-qalc-5.2/dmenu.c 27 --- dmenu-5.2/dmenu.c 2022-10-04 13:36:58.000000000 -0400 28 +++ dmenu-qalc-5.2/dmenu.c 2023-10-27 20:00:21.438467597 -0400 29 @@ -7,6 +7,11 @@ 30 #include <strings.h> 31 #include <time.h> 32 #include <unistd.h> 33 +#include <errno.h> 34 +#include <fcntl.h> 35 +#include <signal.h> 36 +#include <sys/prctl.h> 37 +#include <sys/select.h> 38 39 #include <X11/Xlib.h> 40 #include <X11/Xatom.h> 41 @@ -34,6 +39,12 @@ struct item { 42 int out; 43 }; 44 45 +static struct { 46 + pid_t pid; 47 + int enable, in[2], out[2]; 48 + char buf[256]; 49 +} qalc; 50 + 51 static char text[BUFSIZ] = ""; 52 static char *embed; 53 static int bh, mw, mh; 54 @@ -228,8 +239,81 @@ grabkeyboard(void) 55 } 56 57 static void 58 +init_qalc(void) 59 +{ 60 + pipe(qalc.in); 61 + pipe2(qalc.out, O_NONBLOCK); 62 + qalc.pid = fork(); 63 + if (qalc.pid == -1) 64 + die("failed to fork for qalc"); 65 + if (qalc.pid == 0) { 66 + dup2(qalc.in[0], STDIN_FILENO); 67 + dup2(qalc.out[1], STDOUT_FILENO); 68 + close(qalc.in[1]); 69 + close(qalc.out[0]); 70 + prctl(PR_SET_PDEATHSIG, SIGTERM); 71 + execl("/usr/bin/qalc", "qalc", "-c0", "-t", NULL); 72 + die ("execl qalc failed"); 73 + } else { // parent 74 + close(qalc.in[0]); 75 + close(qalc.out[1]); 76 + items = malloc(sizeof(struct item)*2); 77 + items[0].text = malloc(LENGTH(qalc.buf)); 78 + strcpy(items[0].text, "no result"); 79 + items[1].out = 0; 80 + items[1].text = NULL; 81 + } 82 +} 83 + 84 +static void 85 +recv_qalc(void) 86 +{ 87 + ssize_t r = read(qalc.out[0], qalc.buf, LENGTH(qalc.buf)); 88 + 89 + if (r < 0) 90 + die("error reading qalc.out"); 91 + 92 + if (qalc.buf[0] == '\n') { 93 + int i; 94 + for (i = 3; i < LENGTH(qalc.buf) && qalc.buf[i] != '\n'; ++i) 95 + items[0].text[i-3] = qalc.buf[i]; 96 + items[0].text[i-3] = 0; 97 + if (r != LENGTH(qalc.buf)) 98 + return; 99 + } 100 + 101 + while (read(qalc.out[0], qalc.buf, LENGTH(qalc.buf)) != -1) 102 + ; // empty the pipe 103 + if (errno != EAGAIN && errno != EWOULDBLOCK) 104 + die("error emptying qalc.out"); 105 +} 106 + 107 +static void 108 +send_qalc(void) 109 +{ 110 + int s = strlen(text); 111 + text[s] = '\n'; 112 + write(qalc.in[1], text, s+1); 113 + text[s] = 0; 114 +} 115 + 116 +static void 117 +match_qalc(void) 118 +{ 119 + matches = matchend = NULL; 120 + appenditem(items, &matches, &matchend); 121 + curr = sel = matches; 122 + calcoffsets(); 123 +} 124 + 125 +static void 126 match(void) 127 { 128 + if (qalc.enable) { 129 + match_qalc(); 130 + return; 131 + } 132 + 133 static char **tokv = NULL; 134 static int tokn = 0; 135 136 @@ -524,6 +608,9 @@ insert: 137 break; 138 } 139 140 + if (qalc.enable) 141 + send_qalc(); 142 + 143 draw: 144 drawmenu(); 145 } 146 @@ -573,37 +660,52 @@ run(void) 147 { 148 XEvent ev; 149 150 - while (!XNextEvent(dpy, &ev)) { 151 - if (XFilterEvent(&ev, win)) 152 - continue; 153 - switch(ev.type) { 154 - case DestroyNotify: 155 - if (ev.xdestroywindow.window != win) 156 - break; 157 - cleanup(); 158 - exit(1); 159 - case Expose: 160 - if (ev.xexpose.count == 0) 161 - drw_map(drw, win, 0, 0, mw, mh); 162 - break; 163 - case FocusIn: 164 - /* regrab focus from parent window */ 165 - if (ev.xfocus.window != win) 166 - grabfocus(); 167 - break; 168 - case KeyPress: 169 - keypress(&ev.xkey); 170 - break; 171 - case SelectionNotify: 172 - if (ev.xselection.property == utf8) 173 - paste(); 174 - break; 175 - case VisibilityNotify: 176 - if (ev.xvisibility.state != VisibilityUnobscured) 177 - XRaiseWindow(dpy, win); 178 - break; 179 - } 180 - } 181 + fd_set rfds; 182 + int xfd = ConnectionNumber(dpy); 183 + 184 + for (;;) { 185 + FD_ZERO(&rfds); 186 + FD_SET(xfd, &rfds); 187 + FD_SET(qalc.out[0], &rfds); 188 + 189 + if (select(MAX(xfd, qalc.out[0])+1, &rfds, NULL, NULL, NULL) > 0) { 190 + if (qalc.enable && FD_ISSET(qalc.out[0], &rfds)) { 191 + recv_qalc(); 192 + drawmenu(); 193 + } 194 + while (XPending(dpy) && !XNextEvent(dpy, &ev)) { 195 + if (XFilterEvent(&ev, win)) 196 + continue; 197 + switch(ev.type) { 198 + case DestroyNotify: 199 + if (ev.xdestroywindow.window != win) 200 + break; 201 + cleanup(); 202 + exit(1); 203 + case Expose: 204 + if (ev.xexpose.count == 0) 205 + drw_map(drw, win, 0, 0, mw, mh); 206 + break; 207 + case FocusIn: 208 + /* regrab focus from parent window */ 209 + if (ev.xfocus.window != win) 210 + grabfocus(); 211 + break; 212 + case KeyPress: 213 + keypress(&ev.xkey); 214 + break; 215 + case SelectionNotify: 216 + if (ev.xselection.property == utf8) 217 + paste(); 218 + break; 219 + case VisibilityNotify: 220 + if (ev.xvisibility.state != VisibilityUnobscured) 221 + XRaiseWindow(dpy, win); 222 + break; 223 + } 224 + } 225 + } 226 + } 227 } 228 229 static void 230 @@ -710,7 +812,7 @@ setup(void) 231 static void 232 usage(void) 233 { 234 - die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" 235 + die("usage: dmenu [-bCfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" 236 " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]"); 237 } 238 239 @@ -727,6 +829,8 @@ main(int argc, char *argv[]) 240 exit(0); 241 } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */ 242 topbar = 0; 243 + else if (!strcmp(argv[i], "-C")) /* grabs keyboard before reading stdin */ 244 + qalc.enable = 1; 245 else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */ 246 fast = 1; 247 else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */ 248 @@ -777,7 +881,10 @@ main(int argc, char *argv[]) 249 die("pledge"); 250 #endif 251 252 - if (fast && !isatty(0)) { 253 + if (qalc.enable) { 254 + init_qalc(); 255 + grabkeyboard(); 256 + } else if (fast && !isatty(0)) { 257 grabkeyboard(); 258 readstdin(); 259 } else {