commit eb412e4

chld  ·  2026-07-13 17:02:09 +0000 UTC
parent 6b44f18
clang-format
3 files changed,  +215, -230
M rd.c
M rd.h
M xl.c
M rd.c
+21, -24
 1@@ -1,40 +1,37 @@
 2-#include<stdio.h>
 3-#include<stdlib.h>
 4-#include<unistd.h>
 5+#include <stdio.h>
 6+#include <stdlib.h>
 7+#include <unistd.h>
 8 
 9-char* fbuf(const char* file)
10-{
11-  FILE* f = fopen(file, "rb");
12+char *fbuf(const char *file) {
13+  FILE *f = fopen(file, "rb");
14 
15-  if (!f) return NULL;
16+  if (!f)
17+    return NULL;
18 
19   fseek(f, 0, SEEK_END);
20   long size = ftell(f);
21 
22-  if (size < 0)
23-    {
24-      fclose(f);
25-      return NULL;
26-    }
27+  if (size < 0) {
28+    fclose(f);
29+    return NULL;
30+  }
31 
32   rewind(f);
33 
34-  char* buf = malloc((size_t)size+1);
35-  if (!buf)
36-    {
37-      fclose(f);
38-      return NULL;
39-    }
40+  char *buf = malloc((size_t)size + 1);
41+  if (!buf) {
42+    fclose(f);
43+    return NULL;
44+  }
45 
46   size_t readb = fread(buf, 1, (size_t)size, f);
47   fclose(f);
48 
49-  if (readb != (size_t)size)
50-    {
51-      free(buf);
52-      return NULL;
53-    }
54+  if (readb != (size_t)size) {
55+    free(buf);
56+    return NULL;
57+  }
58 
59-  buf[size] = '\0'; 
60+  buf[size] = '\0';
61   return buf;
62 }
M rd.h
+1, -2
1@@ -1,2 +1 @@
2-char* fbuf(const char* file)
3-	;
4+char *fbuf(const char *file);
M xl.c
+193, -204
  1@@ -1,217 +1,206 @@
  2-#include<X11/Xlib.h>
  3-#include<X11/keysym.h>
  4+#include <X11/Xlib.h>
  5+#include <X11/keysym.h>
  6 
  7-#include<stdbool.h>
  8-#include<stdio.h>
  9-#include<stdlib.h>
 10-#include<string.h>
 11+#include <stdbool.h>
 12+#include <stdio.h>
 13+#include <stdlib.h>
 14+#include <string.h>
 15 
 16-#include<getopt.h>
 17+#include <getopt.h>
 18 
 19-#include"rd.h"
 20+#include "rd.h"
 21 
 22 /*
 23  * a remake of the late `lnd`.
 24- * since X is less secure, 
 25+ * since X is less secure,
 26  * i can actually find the mouse position
 27  * and make it really dropdown.
 28  */
 29 
 30-int main(int ac, char **av)
 31-{
 32-	int wi=80, hi=150, x=0, y=0;
 33-
 34-	char path[128];
 35-	snprintf(path, sizeof path, "%s/%s", getenv("HOME"), ".xlrc");
 36-
 37-	int opt;
 38-	while((opt=getopt(ac, av, "c:g:h "))!= -1){
 39-		switch(opt){
 40-			case 'c':
 41-				snprintf(path, sizeof path, "%s", optarg);
 42-				break;
 43-			case 'g': {
 44-				const char *p=strchr(optarg, 'x');
 45-				if (!p){
 46-					fprintf(stderr, "invalid geom (default: 80x150)\n");
 47-					return 1;
 48-				}
 49-
 50-				wi=atoi(optarg);
 51-				hi=atoi(p+1);
 52-				break;
 53-			}
 54-			case 'h':
 55-				fprintf(stderr, "usage: %s [-c file] [-g WxH]\nusage: %s [-h]\nusage: %s\n", av[0], av[0], av[0]);
 56-				return 0;
 57-				break;
 58-			case ':':
 59-				fprintf(stderr, "-%c needs a argument!\n", optopt); 
 60-				return 1;
 61-				break;
 62-			case '?':
 63-				fprintf(stderr, "unknown flag: -%c\n", optopt); 
 64-				return 1;
 65-				break;
 66-		}
 67-	}
 68-		
 69-
 70-	Display *d=XOpenDisplay(NULL);
 71-	if(!d)
 72-	{
 73-		fprintf(stderr, "couldnt open display\n");
 74-		return 1;
 75-	}
 76-
 77-	int s=DefaultScreen(d);
 78-	Window r=DefaultRootWindow(d);
 79-	Window w_r;
 80-	unsigned int m_r;
 81-	int d1, d2;
 82-
 83-	if(XQueryPointer(d,r,
 84-				&w_r,&w_r,&x,&y,
 85-				&d1,&d2,
 86-				&m_r)){}
 87-
 88-	Window w=XCreateSimpleWindow(d, RootWindow(d, s),
 89-			x, y, wi, hi, 0, BlackPixel(d,s), 
 90-			WhitePixel(d, s));
 91-	XStoreName(d, w, "xlnd");
 92-	XSelectInput(d, w, ExposureMask|KeyPressMask|StructureNotifyMask|
 93-			ButtonPressMask|ButtonReleaseMask|
 94-			PointerMotionMask|LeaveWindowMask);
 95-	/* 
 96-	 * dont make it a regular window
 97-	 * kinda like rofi or layer-shell
 98-	 */
 99-	XSetWindowAttributes at; at.override_redirect=True;
100-	XChangeWindowAttributes(d,w,CWOverrideRedirect, &at);
101-	
102-	XMapWindow(d, w);
103-	XMapRaised(d, w);
104-	XSetInputFocus(d,w,RevertToPointerRoot,CurrentTime);
105-	XGrabKeyboard(d,w,True,GrabModeAsync,GrabModeAsync,CurrentTime);
106-	XGrabPointer(d,w,True,ButtonPressMask|PointerMotionMask,GrabModeAsync,GrabModeAsync,None,None,CurrentTime);
107-
108-	GC gc=XCreateGC(d, w, 0, NULL);
109-	XSetForeground(d, gc, WhitePixel(d,s));
110-	XFillRectangle(d, w,gc,0,0,wi,hi);
111-	XSetForeground(d, gc, BlackPixel(d,s));
112-
113-	XFontStruct *font = XLoadQueryFont(d, "fixed");
114-	XSetFont(d, gc, font->fid);
115-
116-	int32_t sel=0;
117-	int32_t lidx=0;
118-
119-	/* file reading */
120-	char *prg=fbuf(path);
121-	if(!prg)
122-	{
123-		fprintf(stderr, "could not read from %s\n", path);
124-		free(prg);
125-		goto q;
126-	}
127-
128-	/* init prg list */
129-	char *prgs[64];
130-
131-	size_t p_i=0;
132-	char p_c[1024];
133-	strncpy(p_c, prg, sizeof p_c -1); p_c[sizeof p_c-1]='\0';
134-
135-	char *t = strtok(p_c, "\n");
136-	while (t != NULL && p_i < 64){
137-		prgs[p_i++]=t;
138-		t=strtok(NULL, "\n");
139-	}
140-
141-	while(1)
142-	{
143-		XEvent ev;
144-		XNextEvent(d, &ev);
145-
146-		switch(ev.type)
147-		{
148-			case Expose:
149-				if (ev.xexpose.count != 0)
150-        				break;
151-
152-				for(int j=0; j<(int)p_i; ++j)
153-				{
154-					if(sel==j){
155-						XSetForeground(d, gc, WhitePixel(d,s));
156-					}else{
157-						XSetForeground(d, gc, BlackPixel(d,s));
158-					}
159-					
160-					XFillRectangle(d,w,gc,0,(hi*j)/(int)p_i,wi,hi/(int)p_i);
161-				}
162-
163-				for(int i=0; i<(int)p_i; ++i)
164-				{
165-					int direction, as, des;
166-					XCharStruct ov;
167-
168-					XTextExtents(font, prgs[i], strlen(prgs[i]),
169-						&direction,
170-             					&as,
171-             					&des,
172-             					&ov);
173-
174-					if(sel==i){
175-						XSetForeground(d, gc, BlackPixel(d,s));
176-					}else{
177-						XSetForeground(d, gc, WhitePixel(d,s));
178-					}
179-					
180-					XDrawString(d,w,gc,
181-							(wi-ov.width)/2,
182-							(hi*i)/(int)p_i+(hi/(int)p_i+(as+des))/2,
183-							prgs[i],
184-							strlen(prgs[i]));
185-				}
186-				break;
187-			case ConfigureNotify:
188-				break;
189-			case LeaveNotify:
190-				goto q;
191-				break;
192-			case ButtonPress:
193-				printf("%s\n", prgs[sel]);
194-				goto q;
195-				break;
196-			case ButtonRelease:
197-				break;
198-			case MotionNotify: {
199-				int ssel=ev.xmotion.y/(hi/(int)p_i);
200-				if(ssel>=(int)p_i) ssel=(int)p_i-1;
201-				
202-				if(ssel!=sel)
203-				{
204-					sel=ssel;
205-					XClearArea(d, w, 0, 0, 0, 0, True);
206-				}
207-				break;
208-			}
209-			case KeyPress: {
210-				KeySym k=XLookupKeysym(&ev.xkey, 0);
211-				if (k==XK_Escape) goto q;
212-
213-				break;
214-			}
215-		}
216-	}
217+int main(int ac, char **av) {
218+  int wi = 80, hi = 150, x = 0, y = 0;
219+
220+  char path[128];
221+  snprintf(path, sizeof path, "%s/%s", getenv("HOME"), ".xlrc");
222+
223+  int opt;
224+  while ((opt = getopt(ac, av, "c:g:h ")) != -1) {
225+    switch (opt) {
226+    case 'c':
227+      snprintf(path, sizeof path, "%s", optarg);
228+      break;
229+    case 'g': {
230+      const char *p = strchr(optarg, 'x');
231+      if (!p) {
232+        fprintf(stderr, "invalid geom (default: 80x150)\n");
233+        return 1;
234+      }
235+
236+      wi = atoi(optarg);
237+      hi = atoi(p + 1);
238+      break;
239+    }
240+    case 'h':
241+      fprintf(stderr,
242+              "usage: %s [-c file] [-g WxH]\nusage: %s [-h]\nusage: %s\n",
243+              av[0], av[0], av[0]);
244+      return 0;
245+      break;
246+    case ':':
247+      fprintf(stderr, "-%c needs a argument!\n", optopt);
248+      return 1;
249+      break;
250+    case '?':
251+      fprintf(stderr, "unknown flag: -%c\n", optopt);
252+      return 1;
253+      break;
254+    }
255+  }
256+
257+  Display *d = XOpenDisplay(NULL);
258+  if (!d) {
259+    fprintf(stderr, "couldnt open display\n");
260+    return 1;
261+  }
262+
263+  int s = DefaultScreen(d);
264+  Window r = DefaultRootWindow(d);
265+  Window w_r;
266+  unsigned int m_r;
267+  int d1, d2;
268+
269+  if (XQueryPointer(d, r, &w_r, &w_r, &x, &y, &d1, &d2, &m_r)) {
270+  }
271+
272+  Window w = XCreateSimpleWindow(d, RootWindow(d, s), x, y, wi, hi, 0,
273+                                 BlackPixel(d, s), WhitePixel(d, s));
274+  XStoreName(d, w, "xlnd");
275+  XSelectInput(d, w,
276+               ExposureMask | KeyPressMask | StructureNotifyMask |
277+                   ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
278+                   LeaveWindowMask);
279+  /*
280+   * dont make it a regular window
281+   * kinda like rofi or layer-shell
282+   */
283+  XSetWindowAttributes at;
284+  at.override_redirect = True;
285+  XChangeWindowAttributes(d, w, CWOverrideRedirect, &at);
286+
287+  XMapWindow(d, w);
288+  XMapRaised(d, w);
289+  XSetInputFocus(d, w, RevertToPointerRoot, CurrentTime);
290+  XGrabKeyboard(d, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
291+  XGrabPointer(d, w, True, ButtonPressMask | PointerMotionMask, GrabModeAsync,
292+               GrabModeAsync, None, None, CurrentTime);
293+
294+  GC gc = XCreateGC(d, w, 0, NULL);
295+  XSetForeground(d, gc, WhitePixel(d, s));
296+  XFillRectangle(d, w, gc, 0, 0, wi, hi);
297+  XSetForeground(d, gc, BlackPixel(d, s));
298+
299+  XFontStruct *font = XLoadQueryFont(d, "fixed");
300+  XSetFont(d, gc, font->fid);
301+
302+  int32_t sel = 0;
303+  int32_t lidx = 0;
304+
305+  /* file reading */
306+  char *prg = fbuf(path);
307+  if (!prg) {
308+    fprintf(stderr, "could not read from %s\n", path);
309+    free(prg);
310+    goto q;
311+  }
312+
313+  /* init prg list */
314+  char *prgs[64];
315+
316+  size_t p_i = 0;
317+  char p_c[1024];
318+  strncpy(p_c, prg, sizeof p_c - 1);
319+  p_c[sizeof p_c - 1] = '\0';
320+
321+  char *t = strtok(p_c, "\n");
322+  while (t != NULL && p_i < 64) {
323+    prgs[p_i++] = t;
324+    t = strtok(NULL, "\n");
325+  }
326+
327+  while (1) {
328+    XEvent ev;
329+    XNextEvent(d, &ev);
330+
331+    switch (ev.type) {
332+    case Expose:
333+      if (ev.xexpose.count != 0)
334+        break;
335+
336+      for (int j = 0; j < (int)p_i; ++j) {
337+        if (sel == j) {
338+          XSetForeground(d, gc, WhitePixel(d, s));
339+        } else {
340+          XSetForeground(d, gc, BlackPixel(d, s));
341+        }
342+
343+        XFillRectangle(d, w, gc, 0, (hi * j) / (int)p_i, wi, hi / (int)p_i);
344+      }
345+
346+      for (int i = 0; i < (int)p_i; ++i) {
347+        int direction, as, des;
348+        XCharStruct ov;
349+
350+        XTextExtents(font, prgs[i], strlen(prgs[i]), &direction, &as, &des,
351+                     &ov);
352+
353+        if (sel == i) {
354+          XSetForeground(d, gc, BlackPixel(d, s));
355+        } else {
356+          XSetForeground(d, gc, WhitePixel(d, s));
357+        }
358+
359+        XDrawString(d, w, gc, (wi - ov.width) / 2,
360+                    (hi * i) / (int)p_i + (hi / (int)p_i + (as + des)) / 2,
361+                    prgs[i], strlen(prgs[i]));
362+      }
363+      break;
364+    case ConfigureNotify:
365+      break;
366+    case LeaveNotify:
367+      goto q;
368+      break;
369+    case ButtonPress:
370+      printf("%s\n", prgs[sel]);
371+      goto q;
372+      break;
373+    case ButtonRelease:
374+      break;
375+    case MotionNotify: {
376+      int ssel = ev.xmotion.y / (hi / (int)p_i);
377+      if (ssel >= (int)p_i)
378+        ssel = (int)p_i - 1;
379+
380+      if (ssel != sel) {
381+        sel = ssel;
382+        XClearArea(d, w, 0, 0, 0, 0, True);
383+      }
384+      break;
385+    }
386+    case KeyPress: {
387+      KeySym k = XLookupKeysym(&ev.xkey, 0);
388+      if (k == XK_Escape)
389+        goto q;
390+
391+      break;
392+    }
393+    }
394+  }
395 
396 q:
397-	XUngrabKeyboard(d,CurrentTime);
398-	XUngrabPointer(d,CurrentTime);
399-	XFreeGC(d,gc);
400-	XDestroyWindow(d,w);
401-	XCloseDisplay(d);
402-	return 0;
403-
404+  XUngrabKeyboard(d, CurrentTime);
405+  XUngrabPointer(d, CurrentTime);
406+  XFreeGC(d, gc);
407+  XDestroyWindow(d, w);
408+  XCloseDisplay(d);
409+  return 0;
410 }
411-