static void calcoffsetsv(void);
static char *cistrstr(const char *s, const char *sub);
static void cleanup(void);
+static void dinput(void);
static void drawmenu(void);
static void drawmenuh(void);
static void drawmenuv(void);
static int cmdw = 0;
static int promptw = 0;
static int ret = 0;
+static int screen;
+static unsigned int lines = 0;
static unsigned int numlockmask = 0;
+static unsigned int mw, mh;
+static unsigned long normcol[ColLast];
+static unsigned long selcol[ColLast];
static Bool running = True;
+static DC dc;
+static Display *dpy;
static Item *allitems = NULL; /* first of all items */
static Item *item = NULL; /* first of pattern matching items */
static Item *sel = NULL;
static Item *next = NULL;
static Item *prev = NULL;
static Item *curr = NULL;
-static Window win;
+static Window win, parent;
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
static char *(*fstrstr)(const char *, const char *) = strstr;
-static unsigned int lines = 0;
static void (*calcoffsets)(void) = calcoffsetsh;
void
calcoffsetsh(void) {
unsigned int w;
- if(!curr)
- return;
- w = promptw + cmdw + 2 * spaceitem;
- for(next = curr; next && w < mw; next=next->right)
- w += MIN(textw(next->text), mw / 3);
- w = promptw + cmdw + 2 * spaceitem;
- for(prev = curr; prev && prev->left && w < mw; prev=prev->left)
- w += MIN(textw(prev->left->text), mw / 3);
+ w = promptw + cmdw + (2 * spaceitem);
+ for(next = curr; next; next = next->right)
+ if((w += MIN(textw(&dc, next->text), mw / 3)) > mw)
+ break;
+ w = promptw + cmdw + (2 * spaceitem);
+ for(prev = curr; prev && prev->left; prev = prev->left)
+ if((w += MIN(textw(&dc, prev->left->text), mw / 3)) > mw)
+ break;
}
void
calcoffsetsv(void) {
- unsigned int h;
+ unsigned int i;
- if(!curr)
- return;
- h = (dc.font.height + 2) * lines;
- for(next = curr; next && h > 0; next = next->right)
- h -= dc.font.height + 2;
- h = (dc.font.height + 2) * lines;
- for(prev = curr; prev && prev->left && h > 0; prev = prev->left)
- h -= dc.font.height + 2;
+ next = prev = curr;
+ for(i = 0; i < lines && next; i++)
+ next = next->right;
+ for(i = 0; i < lines && prev && prev->left; i++)
+ prev = prev->left;
}
char *
void
cleanup(void) {
- drawcleanup();
+ Item *itm;
+
+ while(allitems) {
+ itm = allitems->next;
+ free(allitems->text);
+ free(allitems);
+ allitems = itm;
+ }
+ cleanupdraw(&dc);
XDestroyWindow(dpy, win);
XUngrabKeyboard(dpy, CurrentTime);
}
+void
+dinput(void) {
+ cleanup();
+ execlp("dinput", "dinput", text, NULL); /* todo: argv */
+ eprint("cannot exec dinput\n");
+}
+
void
drawmenu(void) {
dc.x = 0;
dc.y = 0;
dc.w = mw;
dc.h = mh;
- drawtext(NULL, dc.norm);
+ drawtext(&dc, NULL, normcol);
/* print prompt? */
if(prompt) {
dc.w = promptw;
- drawtext(prompt, dc.sel);
+ drawtext(&dc, prompt, selcol);
dc.x += dc.w;
}
dc.w = mw - dc.x;
/* print command */
if(cmdw && item && lines == 0)
dc.w = cmdw;
- drawtext(*text ? text : NULL, dc.norm);
+ drawtext(&dc, *text ? text : NULL, normcol);
if(curr) {
if(lines > 0)
drawmenuv();
dc.x += cmdw;
dc.w = spaceitem;
- drawtext(curr->left ? "<" : NULL, dc.norm);
+ drawtext(&dc, curr->left ? "<" : NULL, normcol);
dc.x += dc.w;
for(i = curr; i != next; i=i->right) {
- dc.w = MIN(textw(i->text), mw / 3);
- drawtext(i->text, (sel == i) ? dc.sel : dc.norm);
+ dc.w = MIN(textw(&dc, i->text), mw / 3);
+ drawtext(&dc, i->text, (sel == i) ? selcol : normcol);
dc.x += dc.w;
}
dc.w = spaceitem;
dc.x = mw - dc.w;
- drawtext(next ? ">" : NULL, dc.norm);
+ drawtext(&dc, next ? ">" : NULL, normcol);
}
void
dc.h = dc.font.height + 2;
dc.y = dc.h;
for(i = curr; i != next; i=i->right) {
- drawtext(i->text, (sel == i) ? dc.sel : dc.norm);
+ drawtext(&dc, i->text, (sel == i) ? selcol : normcol);
dc.y += dc.h;
}
dc.h = mh - dc.y;
- drawtext(NULL, dc.norm);
+ drawtext(&dc, NULL, normcol);
}
Bool
match(text);
break;
case XK_x:
- execlp("dinput", "dinput", text, NULL); /* todo: argv */
- eprint("dmenu: cannot exec dinput:");
+ dinput();
break;
}
}
}
break;
case XK_Tab:
- if(!sel)
- return;
- strncpy(text, sel->text, sizeof text);
- match(text);
+ if(sel)
+ strncpy(text, sel->text, sizeof text);
+ dinput();
break;
}
drawmenu();
if(buf[len-1] == '\n')
buf[--len] = '\0';
if(!(p = strdup(buf)))
- eprint("dmenu: cannot strdup %u bytes\n", len);
+ eprint("cannot strdup %u bytes\n", len);
if((max = MAX(max, len)) == len)
maxname = p;
if(!(new = malloc(sizeof *new)))
- eprint("dmenu: cannot malloc %u bytes\n", sizeof *new);
+ eprint("cannot malloc %u bytes\n", sizeof *new);
new->next = new->left = new->right = NULL;
new->text = p;
if(!i)
}
XFreeModifiermap(modmap);
- initfont(font);
+ dc.dpy = dpy;
+ normcol[ColBG] = getcolor(&dc, normbgcolor);
+ normcol[ColFG] = getcolor(&dc, normfgcolor);
+ selcol[ColBG] = getcolor(&dc, selbgcolor);
+ selcol[ColFG] = getcolor(&dc, selfgcolor);
+ initfont(&dc, font);
/* menu window */
wa.override_redirect = True;
DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
- drawsetup();
+ setupdraw(&dc, win);
if(maxname)
- cmdw = MIN(textw(maxname), mw / 3);
+ cmdw = MIN(textw(&dc, maxname), mw / 3);
if(prompt)
- promptw = MIN(textw(prompt), mw / 5);
+ promptw = MIN(textw(&dc, prompt), mw / 5);
text[0] = '\0';
match(text);
XMapRaised(dpy, win);
Bool topbar = True;
/* command line args */
+ progname = argv[0];
for(i = 1; i < argc; i++)
if(!strcmp(argv[i], "-i")) {
fstrncmp = strncasecmp;
if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
fprintf(stderr, "dmenu: warning: no locale support\n");
if(!(dpy = XOpenDisplay(NULL)))
- eprint("dmenu: cannot open display\n");
+ eprint("cannot open display\n");
screen = DefaultScreen(dpy);
if(!parent)
parent = RootWindow(dpy, screen);