X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=dmenu.c;h=a799f14300e7ad479c682c5c710bccd21ed99a11;hb=b95e61c9b7310deb452a5dfe404cc1a8f9930117;hp=2afcc4873aab202743b0694b691235d73ac72000;hpb=d2305e4b136b3bdfccf7de897a9f14583a1ca35a;p=dmenu.git diff --git a/dmenu.c b/dmenu.c index 2afcc48..a799f14 100644 --- a/dmenu.c +++ b/dmenu.c @@ -1,6 +1,6 @@ /* See LICENSE file for copyright and license details. */ +#define _BSD_SOURCE #include -#include #include #include #include @@ -15,18 +15,18 @@ #endif /* macros */ -#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) +#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) +#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) /* enums */ enum { ColFG, ColBG, ColLast }; /* typedefs */ -typedef unsigned int uint; -typedef unsigned long ulong; typedef struct { int x, y, w, h; - ulong norm[ColLast]; - ulong sel[ColLast]; + unsigned long norm[ColLast]; + unsigned long sel[ColLast]; Drawable drawable; GC gc; struct { @@ -51,10 +51,9 @@ static void calcoffsets(void); static char *cistrstr(const char *s, const char *sub); static void cleanup(void); static void drawmenu(void); -static void drawtext(const char *text, ulong col[ColLast]); -static void *emalloc(uint size); +static void drawtext(const char *text, unsigned long col[ColLast]); static void eprint(const char *errstr, ...); -static ulong getcolor(const char *colstr); +static unsigned long getcolor(const char *colstr); static Bool grabkeyboard(void); static void initfont(const char *fontstr); static void kpress(XKeyEvent * e); @@ -62,7 +61,7 @@ static void match(char *pattern); static void readstdin(void); static void run(void); static void setup(Bool topbar); -static int textnw(const char *text, uint len); +static int textnw(const char *text, unsigned int len); static int textw(const char *text); #include "config.h" @@ -75,8 +74,8 @@ static int cmdw = 0; static int promptw = 0; static int ret = 0; static int screen; -static uint mw, mh; -static uint numlockmask = 0; +static unsigned int mw, mh; +static unsigned int numlockmask = 0; static Bool running = True; static Display *dpy; static DC dc = {0}; @@ -104,7 +103,7 @@ appenditem(Item *i, Item **list, Item **last) { void calcoffsets(void) { int tw; - uint w; + unsigned int w; if(!curr) return; @@ -131,7 +130,7 @@ calcoffsets(void) { char * cistrstr(const char *s, const char *sub) { int c, csub; - uint len; + unsigned int len; if(!sub) return (char *)s; @@ -213,38 +212,26 @@ drawmenu(void) { } void -drawtext(const char *text, ulong col[ColLast]) { - int x, y, w, h; - static char buf[256]; - uint len, olen; +drawtext(const char *text, unsigned long col[ColLast]) { + int i, x, y, h, len, olen; + char buf[256]; XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XSetForeground(dpy, dc.gc, col[ColBG]); XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); if(!text) return; - w = 0; - olen = len = strlen(text); - if(len >= sizeof buf) - len = sizeof buf - 1; - memcpy(buf, text, len); - buf[len] = 0; + olen = strlen(text); h = dc.font.ascent + dc.font.descent; y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; x = dc.x + (h / 2); /* shorten text if necessary */ - while(len && (w = textnw(buf, len)) > dc.w - h) - buf[--len] = 0; - if(len < olen) { - if(len > 1) - buf[len - 1] = '.'; - if(len > 2) - buf[len - 2] = '.'; - if(len > 3) - buf[len - 3] = '.'; - } - if(w > dc.w) - return; /* too long */ + for(len = MIN(olen, sizeof buf); len && textnw(buf, len) > dc.w - h; len--); + if(!len) + return; + memcpy(buf, text, len); + if(len < olen) + for(i = len; i && i > len - 3; buf[--i] = '.'); XSetForeground(dpy, dc.gc, col[ColFG]); if(dc.font.set) XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); @@ -252,15 +239,6 @@ drawtext(const char *text, ulong col[ColLast]) { XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); } -void * -emalloc(uint size) { - void *res = malloc(size); - - if(!res) - eprint("fatal: could not malloc() %u bytes\n", size); - return res; -} - void eprint(const char *errstr, ...) { va_list ap; @@ -271,7 +249,7 @@ eprint(const char *errstr, ...) { exit(EXIT_FAILURE); } -ulong +unsigned long getcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); XColor color; @@ -283,7 +261,7 @@ getcolor(const char *colstr) { Bool grabkeyboard(void) { - uint len; + unsigned int len; for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) @@ -339,7 +317,7 @@ void kpress(XKeyEvent * e) { char buf[32]; int i, num; - uint len; + unsigned int len; KeySym ksym; len = strlen(text); @@ -477,11 +455,11 @@ kpress(XKeyEvent * e) { calcoffsets(); break; case XK_Return: - if((e->state & ShiftMask) && text) + if((e->state & ShiftMask) && *text) fprintf(stdout, "%s", text); else if(sel) fprintf(stdout, "%s", sel->text); - else if(text) + else if(*text) fprintf(stdout, "%s", text); fflush(stdout); running = False; @@ -507,7 +485,7 @@ kpress(XKeyEvent * e) { void match(char *pattern) { - uint plen; + unsigned int plen; Item *i, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; if(!pattern) @@ -549,7 +527,7 @@ match(char *pattern) { void readstdin(void) { char *p, buf[1024]; - uint len = 0, max = 0; + unsigned int len = 0, max = 0; Item *i, *new; i = 0; @@ -563,7 +541,8 @@ readstdin(void) { maxname = p; max = len; } - new = emalloc(sizeof(Item)); + if((new = (Item *)malloc(sizeof(Item))) == NULL) + eprint("fatal: could not malloc() %u bytes\n", sizeof(Item)); new->next = new->left = new->right = NULL; new->text = p; if(!i) @@ -596,11 +575,12 @@ run(void) { void setup(Bool topbar) { int i, j, x, y; - XModifierKeymap *modmap; - XSetWindowAttributes wa; #if XINERAMA + int n; XineramaScreenInfo *info = NULL; #endif + XModifierKeymap *modmap; + XSetWindowAttributes wa; /* init modifier map */ modmap = XGetModifierMapping(dpy); @@ -627,11 +607,20 @@ setup(Bool topbar) { /* menu window geometry */ mh = dc.font.height + 2; #if XINERAMA - if(XineramaIsActive(dpy)) { - info = XineramaQueryScreens(dpy, &i); - x = info[xidx].x_org; - y = topbar ? info[xidx].y_org : info[xidx].y_org + info[xidx].height - mh; - mw = info[xidx].width; + if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { + i = 0; + if(n > 1) { + int di; + unsigned int dui; + Window dummy; + if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui)) + for(i = 0; i < n; i++) + if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) + break; + } + x = info[i].x_org; + y = topbar ? info[i].y_org : info[i].y_org + info[i].height - mh; + mw = info[i].width; XFree(info); } else @@ -667,7 +656,7 @@ setup(Bool topbar) { } int -textnw(const char *text, uint len) { +textnw(const char *text, unsigned int len) { XRectangle r; if(dc.font.set) { @@ -684,7 +673,7 @@ textw(const char *text) { int main(int argc, char *argv[]) { - uint i; + unsigned int i; Bool topbar = True; /* command line args */ @@ -718,7 +707,8 @@ main(int argc, char *argv[]) { else eprint("usage: dmenu [-i] [-b] [-fn ] [-nb ] [-nf ]\n" " [-p ] [-sb ] [-sf ] [-v]\n"); - setlocale(LC_CTYPE, ""); + if(!XSupportsLocale()) + fprintf(stderr, "warning: no locale support\n"); if(!(dpy = XOpenDisplay(0))) eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy);