| dmenu-qalc-5.2.diff - sites - public wiki contents of suckless.org | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| 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… | |
| 9 +CPPFLAGS = -D_DEFAULT_SOURCE -D_GNU_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURC… | |
| 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… | |
| 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 != VisibilityUnobscure… | |
| 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… | |
| 235 + die("usage: dmenu [-bCfiv] [-l lines] [-p prompt] [-fn font] [-… | |
| 236 " [-nb color] [-nf color] [-sb color] [-sf colo… | |
| 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 bo… | |
| 242 topbar = 0; | |
| 243 + else if (!strcmp(argv[i], "-C")) /* grabs keyboard be… | |
| 244 + qalc.enable = 1; | |
| 245 else if (!strcmp(argv[i], "-f")) /* grabs keyboard be… | |
| 246 fast = 1; | |
| 247 else if (!strcmp(argv[i], "-i")) { /* case-insensitive … | |
| 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 { |