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 { |