1 15aae8ae 2023-05-28 aa #include <ctype.h>
2 15aae8ae 2023-05-28 aa #include <errno.h>
3 cb28fcb8 2023-05-26 aa #include <stdarg.h>
4 15aae8ae 2023-05-28 aa #include <stdbool.h>
5 cb28fcb8 2023-05-26 aa #include <stdio.h>
6 cb28fcb8 2023-05-26 aa #include <stdlib.h>
7 cb28fcb8 2023-05-26 aa #include <string.h>
8 15aae8ae 2023-05-28 aa #include <time.h>
9 cb28fcb8 2023-05-26 aa #include <unistd.h>
11 cb28fcb8 2023-05-26 aa #include <X11/Xlib.h>
12 cb28fcb8 2023-05-26 aa #include <X11/Xutil.h>
13 cb28fcb8 2023-05-26 aa #include <X11/Xos.h>
14 cb28fcb8 2023-05-26 aa #include <X11/Xatom.h>
15 77968eb5 2023-05-29 aa #include <X11/Xft/Xft.h>
17 7c7bbaee 2023-05-27 aa #define PROGNAME "xitems"
18 843ffc79 2023-05-28 aa #define MAXKS 32
20 15aae8ae 2023-05-28 aa /* usage -- print usage information and die. */
25 15aae8ae 2023-05-28 aa "usage: " PROGNAME " [-font font] [-bg colour] [-fg colour]\n"
26 f1adc4ca 2023-05-28 aa " [-sbg colour] [-sfg colour] [-bc colour] [-bw width]\n"
27 15aae8ae 2023-05-28 aa " [-hp padding] [-vp padding] [-x x] [-y y]\n");
31 15aae8ae 2023-05-28 aa /* die -- print formatted string, and exit with the status eval. */
33 15aae8ae 2023-05-28 aa die(int eval, const char *fmt, ...)
35 7c7bbaee 2023-05-27 aa fputs(PROGNAME ": ", stderr);
38 cb28fcb8 2023-05-26 aa va_start(argp, fmt);
39 cb28fcb8 2023-05-26 aa vfprintf(stderr, fmt, argp);
42 cb28fcb8 2023-05-26 aa fputc('\n', stderr);
46 843ffc79 2023-05-28 aa /* warn -- print formatted string to stderr. */
48 843ffc79 2023-05-28 aa warn(const char *fmt, ...)
50 843ffc79 2023-05-28 aa fputs(PROGNAME ": ", stderr);
53 843ffc79 2023-05-28 aa va_start(argp, fmt);
54 843ffc79 2023-05-28 aa vfprintf(stderr, fmt, argp);
57 843ffc79 2023-05-28 aa fputc('\n', stderr);
60 6cdc5a3d 2023-05-28 aa enum direction {
65 cb28fcb8 2023-05-26 aa /* doubly-linked cyclic list */
67 cb28fcb8 2023-05-26 aa struct item *prev;
68 cb28fcb8 2023-05-26 aa struct item *next;
70 843ffc79 2023-05-28 aa KeySym ks[MAXKS]; /* array of associated keysyms */
71 843ffc79 2023-05-28 aa size_t len; /* length of string */
72 843ffc79 2023-05-28 aa size_t nks; /* number of associated keysyms */
73 15aae8ae 2023-05-28 aa bool dirty; /* should be redrawn */
76 15aae8ae 2023-05-28 aa static struct item *first = NULL; /* first member of the list */
77 cb28fcb8 2023-05-26 aa static struct item *selected = NULL;
79 15aae8ae 2023-05-28 aa /* command-line options and X resources */
80 15aae8ae 2023-05-28 aa static char *o_font = NULL;
81 f1adc4ca 2023-05-28 aa static char *o_bg = NULL, *o_fg = NULL, *o_sbg = NULL, *o_sfg = NULL,
83 15aae8ae 2023-05-28 aa static int o_x = -1, o_y = -1;
84 15aae8ae 2023-05-28 aa static int o_bw = -1;
85 15aae8ae 2023-05-28 aa static int o_hp = -1, o_vp = -1;
87 15aae8ae 2023-05-28 aa /* X globals */
88 15aae8ae 2023-05-28 aa static Display *dpy = NULL;
89 cb28fcb8 2023-05-26 aa static int screen;
90 15aae8ae 2023-05-28 aa static Window win;
91 15aae8ae 2023-05-28 aa static int height, width; /* height and width of one item */
92 77968eb5 2023-05-29 aa static XftFont *font;
93 77968eb5 2023-05-29 aa static XftColor c_fg, c_sfg, c_sbg;
95 843ffc79 2023-05-28 aa /* selpos -- mark the item at position y (from top) as selected. */
99 6cdc5a3d 2023-05-28 aa struct item *unselected = selected;
102 6cdc5a3d 2023-05-28 aa selected = first;
107 843ffc79 2023-05-28 aa for (selected = first; selected != first->prev;
108 843ffc79 2023-05-28 aa selected = selected->next) {
109 6cdc5a3d 2023-05-28 aa if (y >= top && y < top+height)
111 6cdc5a3d 2023-05-28 aa top += height;
115 6cdc5a3d 2023-05-28 aa if (unselected != selected)
116 6cdc5a3d 2023-05-28 aa unselected->dirty = selected->dirty = true;
119 15aae8ae 2023-05-28 aa /* redraw -- redraw the entire window */
123 15aae8ae 2023-05-28 aa struct item *it = first;
126 77968eb5 2023-05-29 aa static XftDraw *d = NULL;
128 77968eb5 2023-05-29 aa if (!d && !(d = XftDrawCreate(dpy, win, DefaultVisual(dpy, screen),
129 77968eb5 2023-05-29 aa DefaultColormap(dpy, screen))))
130 77968eb5 2023-05-29 aa die(1, "couldn't create XftDraw");
133 15aae8ae 2023-05-28 aa if (it->dirty) {
134 77968eb5 2023-05-29 aa XftColor *xftc;
136 b64495df 2023-05-29 aa XClearArea(dpy, win, 0, y, width, height, False);
138 15aae8ae 2023-05-28 aa if (it == selected) {
139 77968eb5 2023-05-29 aa xftc = &c_sfg;
140 77968eb5 2023-05-29 aa XftDrawRect(d, &c_sbg, 0, y, width, height);
142 77968eb5 2023-05-29 aa xftc = &c_fg;
144 77968eb5 2023-05-29 aa XftDrawStringUtf8(d, xftc, font,
145 77968eb5 2023-05-29 aa o_hp, y + o_vp+font->ascent,
146 77968eb5 2023-05-29 aa (FcChar8 *)it->s, it->len);
148 15aae8ae 2023-05-28 aa it->dirty = false;
152 15aae8ae 2023-05-28 aa it = it->next;
153 15aae8ae 2023-05-28 aa } while (it != first);
156 6cdc5a3d 2023-05-28 aa /* succeed -- exit successfully. If print is true, also print selected item. */
158 6cdc5a3d 2023-05-28 aa succeed(bool print)
160 6cdc5a3d 2023-05-28 aa if (print && selected)
161 6cdc5a3d 2023-05-28 aa puts(selected->s);
165 6cdc5a3d 2023-05-28 aa /* scroll -- select the previous, or next item, depending on dir. */
167 6cdc5a3d 2023-05-28 aa scroll(enum direction dir)
169 6cdc5a3d 2023-05-28 aa if (selected) {
170 6cdc5a3d 2023-05-28 aa selected->dirty = true;
171 6cdc5a3d 2023-05-28 aa selected = (dir == DIR_UP) ? selected->prev : selected->next;
173 6cdc5a3d 2023-05-28 aa selected = (dir == DIR_UP) ? first->prev : first;
174 6cdc5a3d 2023-05-28 aa selected->dirty = true;
178 843ffc79 2023-05-28 aa * keyselectd -- compare ks with keysyms stored in the items list, and mark
179 843ffc79 2023-05-28 aa * the first match as selected. Return true on match, and false otherwise.
182 843ffc79 2023-05-28 aa keyselect(KeySym ks)
184 843ffc79 2023-05-28 aa struct item *it = first;
185 843ffc79 2023-05-28 aa KeySym k, dummy;
187 843ffc79 2023-05-28 aa XConvertCase(ks, &k, &dummy);
191 843ffc79 2023-05-28 aa for (i = 0; i < it->nks; ++i)
192 843ffc79 2023-05-28 aa if (it->ks[i] == k) {
193 843ffc79 2023-05-28 aa selected->dirty = true;
194 843ffc79 2023-05-28 aa selected = it;
195 843ffc79 2023-05-28 aa selected->dirty = true;
198 843ffc79 2023-05-28 aa it = it->next;
199 843ffc79 2023-05-28 aa } while (it != first);
201 843ffc79 2023-05-28 aa return false;
204 15aae8ae 2023-05-28 aa /* proc -- body of the main event-reading loop. */
208 15aae8ae 2023-05-28 aa XKeyEvent ke;
210 15aae8ae 2023-05-28 aa char *dummy = "";
213 6cdc5a3d 2023-05-28 aa static bool inwin = false;
215 15aae8ae 2023-05-28 aa XNextEvent(dpy, &ev);
217 15aae8ae 2023-05-28 aa switch (ev.type) {
218 6cdc5a3d 2023-05-28 aa case EnterNotify:
219 6cdc5a3d 2023-05-28 aa inwin = true;
220 6cdc5a3d 2023-05-28 aa /* FALLTHRU */
221 6cdc5a3d 2023-05-28 aa case MotionNotify:
222 843ffc79 2023-05-28 aa selpos(ev.xbutton.y);
223 6cdc5a3d 2023-05-28 aa /* FALLTHRU */
227 6cdc5a3d 2023-05-28 aa case LeaveNotify:
228 6cdc5a3d 2023-05-28 aa inwin = false;
230 6cdc5a3d 2023-05-28 aa case ButtonPress:
231 6cdc5a3d 2023-05-28 aa if (ev.xbutton.button == Button4) {
232 6cdc5a3d 2023-05-28 aa scroll(DIR_UP);
234 6cdc5a3d 2023-05-28 aa } else if (ev.xbutton.button == Button5) {
235 6cdc5a3d 2023-05-28 aa scroll(DIR_DOWN);
237 6cdc5a3d 2023-05-28 aa } else if (inwin)
238 6cdc5a3d 2023-05-28 aa succeed(true);
240 6cdc5a3d 2023-05-28 aa succeed(false);
242 15aae8ae 2023-05-28 aa case KeyPress:
243 15aae8ae 2023-05-28 aa ke = ev.xkey;
244 15aae8ae 2023-05-28 aa XLookupString(&ke, dummy, 0, &ks, NULL);
246 15aae8ae 2023-05-28 aa if (ke.state & ControlMask) {
247 15aae8ae 2023-05-28 aa switch (ks) {
248 15aae8ae 2023-05-28 aa case XK_bracketleft:
251 15aae8ae 2023-05-28 aa ks = XK_Escape;
257 15aae8ae 2023-05-28 aa ks = XK_Return;
268 843ffc79 2023-05-28 aa } else if (keyselect(ks))
269 843ffc79 2023-05-28 aa succeed(true);
271 15aae8ae 2023-05-28 aa switch (ks) {
274 15aae8ae 2023-05-28 aa case XK_Down:
275 6cdc5a3d 2023-05-28 aa scroll(DIR_DOWN);
281 6cdc5a3d 2023-05-28 aa scroll(DIR_UP);
284 15aae8ae 2023-05-28 aa case XK_Return:
285 6cdc5a3d 2023-05-28 aa succeed(true);
286 15aae8ae 2023-05-28 aa /* NOTREACHED */
287 15aae8ae 2023-05-28 aa case XK_Escape:
288 6cdc5a3d 2023-05-28 aa succeed(false);
289 15aae8ae 2023-05-28 aa /* NOTREACHED */
296 6cdc5a3d 2023-05-28 aa /* grabptr -- try to grab pointer for a second */
298 6cdc5a3d 2023-05-28 aa grabptr(void)
300 6cdc5a3d 2023-05-28 aa struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
303 6cdc5a3d 2023-05-28 aa for (i = 0; i < 1000; ++i) {
304 6cdc5a3d 2023-05-28 aa if (XGrabPointer(dpy, RootWindow(dpy, screen), True,
305 6cdc5a3d 2023-05-28 aa ButtonPressMask, GrabModeAsync, GrabModeAsync, None, None,
306 6cdc5a3d 2023-05-28 aa CurrentTime) == GrabSuccess)
308 6cdc5a3d 2023-05-28 aa nanosleep(&ts, NULL);
310 6cdc5a3d 2023-05-28 aa die(1, "couldn't grab pointer");
313 15aae8ae 2023-05-28 aa /* grabkb -- try to grab keyboard for a second */
317 15aae8ae 2023-05-28 aa struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
320 15aae8ae 2023-05-28 aa for (i = 0; i < 1000; ++i) {
321 15aae8ae 2023-05-28 aa if (XGrabKeyboard(dpy, RootWindow(dpy, screen), True,
322 15aae8ae 2023-05-28 aa GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess)
324 15aae8ae 2023-05-28 aa nanosleep(&ts, NULL);
326 15aae8ae 2023-05-28 aa die(1, "couldn't grab keyboard");
329 6cdc5a3d 2023-05-28 aa /* setfocus -- try setting focus to the menu for a second */
331 6cdc5a3d 2023-05-28 aa setfocus(void)
333 6cdc5a3d 2023-05-28 aa struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
334 6cdc5a3d 2023-05-28 aa Window focuswin;
335 6cdc5a3d 2023-05-28 aa int i, dummy;
337 6cdc5a3d 2023-05-28 aa for (i = 0; i < 1000; ++i) {
338 6cdc5a3d 2023-05-28 aa XGetInputFocus(dpy, &focuswin, &dummy);
339 6cdc5a3d 2023-05-28 aa if (focuswin == win)
341 6cdc5a3d 2023-05-28 aa XSetInputFocus(dpy, win, RevertToParent, CurrentTime);
342 6cdc5a3d 2023-05-28 aa nanosleep(&ts, NULL);
344 6cdc5a3d 2023-05-28 aa die(1, "couldn't grab keyboard");
347 77968eb5 2023-05-29 aa /* alloccol_xft -- safely allocate new Xft colour c from string s. */
349 77968eb5 2023-05-29 aa alloccol_xft(char *s, XftColor *c)
351 77968eb5 2023-05-29 aa if (!(XftColorAllocName(dpy, DefaultVisual(dpy, screen),
352 77968eb5 2023-05-29 aa DefaultColormap(dpy, screen), s, c)))
353 77968eb5 2023-05-29 aa die(1, "couldn't allocate Xft colour %s\n", s);
356 77968eb5 2023-05-29 aa /* alloccol -- safely allocate new colour c from string s. */
358 b64495df 2023-05-29 aa alloccol(char *s, XColor *c)
360 b64495df 2023-05-29 aa XColor dummy;
361 b64495df 2023-05-29 aa if (!(XAllocNamedColor(dpy, DefaultColormap(dpy, screen), s, c, &dummy)))
362 b64495df 2023-05-29 aa die(1, "couldn't allocate colour %s\n", s);
366 15aae8ae 2023-05-28 aa * setupx -- create and map a window for n items; assign values to the X
370 15aae8ae 2023-05-28 aa setupx(int n)
372 15aae8ae 2023-05-28 aa struct item *it;
374 15aae8ae 2023-05-28 aa XClassHint ch = {PROGNAME, PROGNAME};
375 15aae8ae 2023-05-28 aa XSetWindowAttributes swa = {
376 15aae8ae 2023-05-28 aa .override_redirect = True,
377 15aae8ae 2023-05-28 aa .save_under = True,
378 6cdc5a3d 2023-05-28 aa .event_mask = ExposureMask | StructureNotifyMask |
379 6cdc5a3d 2023-05-28 aa KeyPressMask | ButtonPressMask | ButtonReleaseMask |
380 6cdc5a3d 2023-05-28 aa PointerMotionMask | LeaveWindowMask | EnterWindowMask,
383 77968eb5 2023-05-29 aa if (!(font = XftFontOpenName(dpy, screen, o_font)))
384 15aae8ae 2023-05-28 aa die(1, "couldn't load font");
385 77968eb5 2023-05-29 aa height = font->height + o_vp;
389 77968eb5 2023-05-29 aa XGlyphInfo gi;
390 77968eb5 2023-05-29 aa XftTextExtentsUtf8(dpy, font, (FcChar8 *)it->s, it->len, &gi);
391 77968eb5 2023-05-29 aa if (gi.xOff + o_hp*2 > width)
392 77968eb5 2023-05-29 aa width = gi.xOff + o_hp*2;
393 15aae8ae 2023-05-28 aa it = it->next;
394 15aae8ae 2023-05-28 aa } while (it != first);
396 f0265770 2023-05-28 aa if (o_x + width > DisplayWidth(dpy, screen))
397 f0265770 2023-05-28 aa o_x = DisplayWidth(dpy, screen) - width;
398 f0265770 2023-05-28 aa if (o_y + height*n > DisplayHeight(dpy, screen))
399 f0265770 2023-05-28 aa o_y = DisplayHeight(dpy, screen) - height*n;
401 b64495df 2023-05-29 aa alloccol(o_bc, &col);
402 f1adc4ca 2023-05-28 aa swa.border_pixel = col.pixel;
403 b64495df 2023-05-29 aa alloccol(o_bg, &col);
404 15aae8ae 2023-05-28 aa swa.background_pixel = col.pixel;
406 15aae8ae 2023-05-28 aa win = XCreateWindow(dpy, RootWindow(dpy, screen), o_x, o_y,
407 15aae8ae 2023-05-28 aa width, n*height, o_bw, CopyFromParent, CopyFromParent,
408 f1adc4ca 2023-05-28 aa CopyFromParent, CWOverrideRedirect | CWBackPixel | CWBorderPixel |
409 f1adc4ca 2023-05-28 aa CWEventMask | CWSaveUnder, &swa);
410 15aae8ae 2023-05-28 aa XSetClassHint(dpy, win, &ch);
412 77968eb5 2023-05-29 aa alloccol_xft(o_fg, &c_fg);
413 77968eb5 2023-05-29 aa alloccol_xft(o_sfg, &c_sfg);
414 77968eb5 2023-05-29 aa alloccol_xft(o_sbg, &c_sbg);
419 15aae8ae 2023-05-28 aa XMapRaised(dpy, win);
425 15aae8ae 2023-05-28 aa * Create a new struct item, and insert it a after the it item. The rest of the
426 15aae8ae 2023-05-28 aa * arguments are values that the new item receives. On success return pointer
427 15aae8ae 2023-05-28 aa * to the new item. Return NULL otherwise.
429 15aae8ae 2023-05-28 aa static struct item *
430 843ffc79 2023-05-28 aa insitem(struct item *it, char *s) {
431 cb28fcb8 2023-05-26 aa struct item *new;
432 843ffc79 2023-05-28 aa char *p, *end;
434 cb28fcb8 2023-05-26 aa if (!(new = calloc(1, sizeof *new)))
437 cb28fcb8 2023-05-26 aa new->prev = it;
438 cb28fcb8 2023-05-26 aa new->next = it->next;
439 cb28fcb8 2023-05-26 aa it->next->prev = new;
440 cb28fcb8 2023-05-26 aa it->next = new;
442 cb28fcb8 2023-05-26 aa new->prev = new->next = new;
443 843ffc79 2023-05-28 aa new->nks = 0;
444 15aae8ae 2023-05-28 aa new->dirty = true;
446 843ffc79 2023-05-28 aa for (p = s; ; p = end) {
451 843ffc79 2023-05-28 aa n = strspn(p, " ");
453 843ffc79 2023-05-28 aa if (!(n = strcspn(p, " \t"))) {
454 843ffc79 2023-05-28 aa p += strspn(p, " \t");
462 843ffc79 2023-05-28 aa if ((ks = XStringToKeysym(p)) == NoSymbol)
463 843ffc79 2023-05-28 aa warn("no such keysym: %s\n", p);
464 843ffc79 2023-05-28 aa else if (new->nks >= MAXKS)
465 843ffc79 2023-05-28 aa warn("too many keysyms (%s)\n", p);
467 843ffc79 2023-05-28 aa KeySym k, dummy;
468 843ffc79 2023-05-28 aa XConvertCase(ks, &k, &dummy);
469 843ffc79 2023-05-28 aa new->ks[new->nks++] = k;
475 843ffc79 2023-05-28 aa new->len = strlen(p);
476 843ffc79 2023-05-28 aa new->s = strdup(p);
482 15aae8ae 2023-05-28 aa * mkitems -- create a list of items from stdin, and return pointer to the
483 15aae8ae 2023-05-28 aa * new list's first element. If np is not NULL, set its value to the number of
484 15aae8ae 2023-05-28 aa * elements in the list. Return NULL on error.
486 15aae8ae 2023-05-28 aa static struct item *
487 15aae8ae 2023-05-28 aa mkitems(int *np)
489 15aae8ae 2023-05-28 aa struct item *last = NULL;
490 15aae8ae 2023-05-28 aa size_t n = 0;
491 15aae8ae 2023-05-28 aa char *line = NULL;
492 15aae8ae 2023-05-28 aa size_t linesize = 0;
493 15aae8ae 2023-05-28 aa ssize_t linelen;
495 15aae8ae 2023-05-28 aa while ((linelen = getline(&line, &linesize, stdin)) != -1) {
496 15aae8ae 2023-05-28 aa struct item *it;
497 f0265770 2023-05-28 aa if (line[linelen-1] == '\n')
498 f0265770 2023-05-28 aa line[--linelen] = '\0';
499 843ffc79 2023-05-28 aa if (!(it = insitem(last, line)))
500 15aae8ae 2023-05-28 aa die(1, "couldn't insert new item");
509 15aae8ae 2023-05-28 aa return last ? last->next : NULL;
513 15aae8ae 2023-05-28 aa * {s,i}default -- return the {char *,int} value of the X default, or def
516 15aae8ae 2023-05-28 aa static char *
517 f1adc4ca 2023-05-28 aa sdefault(const char *opt, const char *def)
519 7c7bbaee 2023-05-27 aa char *val = XGetDefault(dpy, PROGNAME, opt);
520 f1adc4ca 2023-05-28 aa return val ? val : (char *)def;
524 f1adc4ca 2023-05-28 aa idefault(const char *opt, int def)
526 7c7bbaee 2023-05-27 aa char *val = XGetDefault(dpy, PROGNAME, opt);
527 7c7bbaee 2023-05-27 aa return val ? atoi(val) : def;
530 15aae8ae 2023-05-28 aa /* nextarg -- safely skip the current command-line option */
532 15aae8ae 2023-05-28 aa nextarg(int *argcp, char **argvp[])
534 7c7bbaee 2023-05-27 aa if (--*argcp <= 0)
540 15aae8ae 2023-05-28 aa * {s,i}arg -- return the {char *,int} argument of the current command-line
543 15aae8ae 2023-05-28 aa static char *
544 15aae8ae 2023-05-28 aa sarg(int *argcp, char **argvp[])
546 15aae8ae 2023-05-28 aa nextarg(argcp, argvp);
547 7c7bbaee 2023-05-27 aa return **argvp;
551 7c7bbaee 2023-05-27 aa iarg(int *argcp, char **argvp[])
553 15aae8ae 2023-05-28 aa nextarg(argcp, argvp);
554 7c7bbaee 2023-05-27 aa return atoi(**argvp);
558 15aae8ae 2023-05-28 aa * xitems -- pop-up menu for X, constructed from stdin, and printing user choice
562 7c7bbaee 2023-05-27 aa main(int argc, char *argv[])
566 7c7bbaee 2023-05-27 aa for (--argc, ++argv; argc > 0; --argc, ++argv)
567 7c7bbaee 2023-05-27 aa if (argv[0][0] == '-')
568 7c7bbaee 2023-05-27 aa switch (argv[0][1]) {
570 7c7bbaee 2023-05-27 aa switch (argv[0][2]) {
571 f1adc4ca 2023-05-28 aa case 'c': /* -bc */
572 f1adc4ca 2023-05-28 aa o_bc = sarg(&argc, &argv);
574 7c7bbaee 2023-05-27 aa case 'g': /* -bg */
575 15aae8ae 2023-05-28 aa o_bg = sarg(&argc, &argv);
577 7c7bbaee 2023-05-27 aa case 'w': /* -bw */
578 15aae8ae 2023-05-28 aa o_bw = iarg(&argc, &argv);
582 7c7bbaee 2023-05-27 aa /* NOTREACHED */
586 7c7bbaee 2023-05-27 aa switch (argv[0][2]) {
587 7c7bbaee 2023-05-27 aa case 'g': /* -fg */
588 15aae8ae 2023-05-28 aa o_fg = sarg(&argc, &argv);
590 7c7bbaee 2023-05-27 aa case 'o': /* -font */
591 15aae8ae 2023-05-28 aa o_font = sarg(&argc, &argv);
595 7c7bbaee 2023-05-27 aa /* NOTREACHED */
598 15aae8ae 2023-05-28 aa case 'h': /* -hp */
599 15aae8ae 2023-05-28 aa o_hp = iarg(&argc, &argv);
602 7c7bbaee 2023-05-27 aa switch (argv[0][2]) {
603 7c7bbaee 2023-05-27 aa case 'b': /* -sbg */
604 15aae8ae 2023-05-28 aa o_sbg = sarg(&argc, &argv);
606 7c7bbaee 2023-05-27 aa case 'f': /* -sfg */
607 15aae8ae 2023-05-28 aa o_sfg = sarg(&argc, &argv);
611 7c7bbaee 2023-05-27 aa /* NOTREACHED */
614 15aae8ae 2023-05-28 aa case 'v': /* -vp */
615 15aae8ae 2023-05-28 aa o_vp = iarg(&argc, &argv);
617 7c7bbaee 2023-05-27 aa case 'x': /* -x */
618 15aae8ae 2023-05-28 aa o_x = iarg(&argc, &argv);
620 7c7bbaee 2023-05-27 aa case 'y': /* -y */
621 15aae8ae 2023-05-28 aa o_y = iarg(&argc, &argv);
625 7c7bbaee 2023-05-27 aa /* NOTREACHED */
628 7c7bbaee 2023-05-27 aa if (!(dpy = XOpenDisplay(NULL)))
629 15aae8ae 2023-05-28 aa die(1, "couldn't open display");
630 7c7bbaee 2023-05-27 aa screen = DefaultScreen(dpy);
633 15aae8ae 2023-05-28 aa o_bg = sdefault("background", "white");
635 15aae8ae 2023-05-28 aa o_fg = sdefault("foreground", "black");
637 77968eb5 2023-05-29 aa o_font = sdefault("font", "DejaVu Sans Mono-10");
639 15aae8ae 2023-05-28 aa o_sbg = sdefault("selectedBackground", "black");
641 15aae8ae 2023-05-28 aa o_sfg = sdefault("selectedForeground", "white");
643 f1adc4ca 2023-05-28 aa o_bc = sdefault("borderColour", "black");
644 15aae8ae 2023-05-28 aa if (o_bw == -1)
645 15aae8ae 2023-05-28 aa o_bw = idefault("borderWidth", 1);
646 15aae8ae 2023-05-28 aa if (o_hp == -1)
647 15aae8ae 2023-05-28 aa o_hp = idefault("horizontalPadding", 2);
648 15aae8ae 2023-05-28 aa if (o_vp == -1)
649 15aae8ae 2023-05-28 aa o_vp = idefault("verticalPadding", 1);
651 15aae8ae 2023-05-28 aa if (o_x == -1 || o_y == -1) {
654 7c7bbaee 2023-05-27 aa unsigned int ui;
655 7c7bbaee 2023-05-27 aa int *xp, *yp;
657 15aae8ae 2023-05-28 aa xp = (o_x == -1) ? &o_x : &i;
658 15aae8ae 2023-05-28 aa yp = (o_y == -1) ? &o_y : &i;
660 7c7bbaee 2023-05-27 aa XQueryPointer(dpy, RootWindow(dpy, screen), &w, &w, xp, yp, &i,
664 15aae8ae 2023-05-28 aa if (!(first = selected = mkitems(&n))) {
666 15aae8ae 2023-05-28 aa die(1, "coulnd't create items list");
674 cb28fcb8 2023-05-26 aa /* NOTREACHED */