X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;ds=sidebyside;f=dmenu.c;h=cff3e65a9f067007c468e452411976f03a7303ae;hb=2b92c95230fbbdcf47f701d9cc4fd133a7972fae;hp=c4b79081a835b09572ad10597358ce57dfca8a7c;hpb=3a60b19514705f7f61908fd727d2e69565ee1947;p=dmenu.git diff --git a/dmenu.c b/dmenu.c index c4b7908..cff3e65 100644 --- a/dmenu.c +++ b/dmenu.c @@ -25,8 +25,8 @@ struct Item { static void appenditem(Item *item, Item **list, Item **last); static void calcoffsets(void); +static char *cistrstr(const char *s, const char *sub); static void drawmenu(void); -static char *fstrstr(const char *s, const char *sub); static void grabkeyboard(void); static void insert(const char *str, ssize_t n); static void keypress(XKeyEvent *ev); @@ -36,13 +36,12 @@ static void paste(void); static void readstdin(void); static void run(void); static void setup(void); +static void usage(void); static char text[BUFSIZ] = ""; static int bh, mw, mh; -static int inputw; +static int inputw, promptw; static int lines = 0; -static int monitor = -1; -static int promptw; static size_t cursor = 0; static const char *font = NULL; static const char *prompt = NULL; @@ -61,6 +60,7 @@ static Item *prev, *curr, *next, *sel; static Window win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; +static char *(*fstrstr)(const char *, const char *) = strstr; int main(int argc, char *argv[]) { @@ -70,22 +70,22 @@ main(int argc, char *argv[]) { for(i = 1; i < argc; i++) /* single flags */ if(!strcmp(argv[i], "-v")) { - fputs("dmenu-"VERSION", © 2006-2011 dmenu engineers, see LICENSE for details\n", stdout); + puts("dmenu-"VERSION", © 2006-2011 dmenu engineers, see LICENSE for details"); exit(EXIT_SUCCESS); } else if(!strcmp(argv[i], "-b")) topbar = False; else if(!strcmp(argv[i], "-f")) fast = True; - else if(!strcmp(argv[i], "-i")) + else if(!strcmp(argv[i], "-i")) { fstrncmp = strncasecmp; + fstrstr = cistrstr; + } else if(i+1 == argc) - goto usage; + usage(); /* double flags */ else if(!strcmp(argv[i], "-l")) lines = atoi(argv[++i]); - else if(!strcmp(argv[i], "-m")) - monitor = atoi(argv[++i]); else if(!strcmp(argv[i], "-p")) prompt = argv[++i]; else if(!strcmp(argv[i], "-fn")) @@ -99,7 +99,7 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-sf")) selfgcolor = argv[++i]; else - goto usage; + usage(); dc = initdc(); initfont(dc, font); @@ -114,12 +114,8 @@ main(int argc, char *argv[]) { } setup(); run(); - return EXIT_FAILURE; -usage: - fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - return EXIT_FAILURE; + return EXIT_FAILURE; /* unreachable */ } void @@ -128,6 +124,7 @@ appenditem(Item *item, Item **list, Item **last) { *list = item; else (*last)->right = item; + item->left = *last; item->right = NULL; *last = item; @@ -150,6 +147,16 @@ calcoffsets(void) { break; } +char * +cistrstr(const char *s, const char *sub) { + size_t len; + + for(len = strlen(sub); *s; s++) + if(!strncasecmp(s, sub, len)) + return (char *)s; + return NULL; +} + void drawmenu(void) { int curpos; @@ -195,16 +202,6 @@ drawmenu(void) { mapdc(dc, win, mw, mh); } -char * -fstrstr(const char *s, const char *sub) { - size_t len; - - for(len = strlen(sub); *s; s++) - if(!fstrncmp(s, sub, len)) - return (char *)s; - return NULL; -} - void grabkeyboard(void) { int i; @@ -226,7 +223,7 @@ insert(const char *str, ssize_t n) { if(n > 0) memcpy(&text[cursor], str, n); cursor += n; - match(n > 0); + match(n > 0 && text[cursor] == '\0'); } void @@ -240,57 +237,37 @@ keypress(XKeyEvent *ev) { XConvertCase(ksym, &lower, &upper); switch(lower) { - default: - return; - case XK_a: - ksym = XK_Home; - break; - case XK_b: - ksym = XK_Left; - break; - case XK_c: - ksym = XK_Escape; - break; - case XK_d: - ksym = XK_Delete; - break; - case XK_e: - ksym = XK_End; - break; - case XK_f: - ksym = XK_Right; - break; - case XK_h: - ksym = XK_BackSpace; - break; - case XK_i: - ksym = XK_Tab; - break; - case XK_j: - ksym = XK_Return; - break; - case XK_k: /* delete right */ + case XK_a: ksym = XK_Home; break; + case XK_b: ksym = XK_Left; break; + case XK_c: ksym = XK_Escape; break; + case XK_d: ksym = XK_Delete; break; + case XK_e: ksym = XK_End; break; + case XK_f: ksym = XK_Right; break; + case XK_h: ksym = XK_BackSpace; break; + case XK_i: ksym = XK_Tab; break; + case XK_j: ksym = XK_Return; break; + case XK_m: ksym = XK_Return; break; + case XK_n: ksym = XK_Up; break; + case XK_p: ksym = XK_Down; break; + + case XK_k: /* delete right */ text[cursor] = '\0'; match(False); break; - case XK_n: - ksym = XK_Down; - break; - case XK_p: - ksym = XK_Up; - break; - case XK_u: /* delete left */ + case XK_u: /* delete left */ insert(NULL, 0 - cursor); break; - case XK_w: /* delete word */ + case XK_w: /* delete word */ while(cursor > 0 && text[nextrune(-1)] == ' ') insert(NULL, nextrune(-1) - cursor); while(cursor > 0 && text[nextrune(-1)] != ' ') insert(NULL, nextrune(-1) - cursor); break; - case XK_y: /* paste selection */ + case XK_y: /* paste selection */ XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); return; + default: + return; } } switch(ksym) { @@ -303,8 +280,9 @@ keypress(XKeyEvent *ev) { return; cursor = nextrune(+1); case XK_BackSpace: - if(cursor > 0) - insert(NULL, nextrune(-1) - cursor); + if(cursor == 0) + return; + insert(NULL, nextrune(-1) - cursor); break; case XK_End: if(text[cursor] != '\0') { @@ -336,8 +314,7 @@ keypress(XKeyEvent *ev) { cursor = nextrune(-1); break; } - else if(lines > 0) - return; + /* fallthrough */ case XK_Up: if(sel && sel->left && (sel = sel->left)->right == curr) { curr = prev; @@ -358,15 +335,14 @@ keypress(XKeyEvent *ev) { break; case XK_Return: case XK_KP_Enter: - fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); + puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); exit(EXIT_SUCCESS); case XK_Right: if(text[cursor] != '\0') { cursor = nextrune(+1); break; } - else if(lines > 0) - return; + /* fallthrough */ case XK_Down: if(sel && sel->right && (sel = sel->right) == next) { curr = next; @@ -452,7 +428,7 @@ readstdin(void) { char buf[sizeof text], *p, *maxstr = NULL; size_t i, max = 0, size = 0; - for(i = 0; fgets(buf, sizeof buf, stdin); items[++i].text = NULL) { + for(i = 0; fgets(buf, sizeof buf, stdin); i++) { if(i+1 >= size / sizeof *items) if(!(items = realloc(items, (size += BUFSIZ)))) eprintf("cannot realloc %u bytes:", size); @@ -463,6 +439,8 @@ readstdin(void) { if(strlen(items[i].text) > max) max = strlen(maxstr = items[i].text); } + if(items) + items[i].text = NULL; inputw = maxstr ? textw(dc, maxstr) : 0; } @@ -474,7 +452,7 @@ run(void) { switch(ev.type) { case Expose: if(ev.xexpose.count == 0) - drawmenu(); + mapdc(dc, win, mw, mh); break; case KeyPress: keypress(&ev.xkey); @@ -519,8 +497,7 @@ setup(void) { XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); for(i = 0; i < n-1; i++) - if((monitor == info[i].screen_number) - || (monitor < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) + 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 = info[i].y_org + (topbar ? 0 : info[i].height - mh); @@ -534,8 +511,8 @@ setup(void) { y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; mw = DisplayWidth(dc->dpy, screen); } - inputw = MIN(inputw, mw/3); promptw = prompt ? textw(dc, prompt) : 0; + inputw = MIN(inputw, mw/3); match(False); /* menu window */ @@ -551,3 +528,10 @@ setup(void) { resizedc(dc, mw, mh); drawmenu(); } + +void +usage(void) { + fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + exit(EXIT_FAILURE); +}