/* See LICENSE file for copyright and license details. */ #include #include #include #include #ifdef XINERAMA #include #endif #include "dmenu.h" /* variables */ char *prompt = NULL; char text[4096] = ""; int promptw = 0; int screen; unsigned int numlockmask = 0; unsigned int mw, mh; unsigned long normcol[ColLast]; unsigned long selcol[ColLast]; Bool topbar = True; DC dc; Display *dpy; Window win, root; void grabkeyboard(void) { unsigned int len; for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) return; usleep(1000); } exit(EXIT_FAILURE); } void run(void) { XEvent ev; /* main event loop */ XSync(dpy, False); while(!XNextEvent(dpy, &ev)) switch(ev.type) { case KeyPress: kpress(&ev.xkey); break; case Expose: if(ev.xexpose.count == 0) drawbar(); break; case VisibilityNotify: if(ev.xvisibility.state != VisibilityUnobscured) XRaiseWindow(dpy, win); break; } exit(EXIT_FAILURE); } void setup(unsigned int lines) { int i, j, x, y; #if XINERAMA int n; XineramaScreenInfo *info = NULL; #endif XModifierKeymap *modmap; XSetWindowAttributes wa; /* init modifier map */ modmap = XGetModifierMapping(dpy); for(i = 0; i < 8; i++) for(j = 0; j < modmap->max_keypermod; j++) { if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) numlockmask = (1 << i); } XFreeModifiermap(modmap); 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); /* input window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; /* input window geometry */ mh = (dc.font.height + 2) * (lines + 1); #if XINERAMA 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 #endif { x = 0; y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; mw = DisplayWidth(dpy, screen); } win = XCreateWindow(dpy, root, x, y, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); setupdraw(&dc, win); if(prompt) promptw = MIN(textw(&dc, prompt), mw / 5); XMapRaised(dpy, win); }