X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=dinput.c;h=4bbc7bc891a27cd7b91cb9e983b969f797190a50;hb=115c01b74ebd57382679bec5c6e1ff5604370cbf;hp=39889b31b393f7e7bedf2d52b129bd51e295430b;hpb=96c65400ccdcb76cf20ec7721920f944e6b490ec;p=dmenu.git diff --git a/dinput.c b/dinput.c index 39889b3..4bbc7bc 100644 --- a/dinput.c +++ b/dinput.c @@ -1,105 +1,52 @@ /* See LICENSE file for copyright and license details. */ #include #include -#include #include #include #include -#include -#include #include #include #include -#ifdef XINERAMA -#include -#endif - -/* macros */ -#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)) -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define IS_UTF8_1ST_CHAR(c) ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) +#include "dmenu.h" /* forward declarations */ static void cleanup(void); -static void drawcursor(void); -static void drawinput(void); -static Bool grabkeyboard(void); -static void kpress(XKeyEvent * e); -static void run(void); -static void setup(Bool topbar); - -#include "config.h" -#include "draw.h" /* variables */ -static char *prompt = NULL; -static char text[4096]; -static int promptw = 0; -static int ret = 0; -static int screen; -static unsigned int cursor = 0; -static unsigned int numlockmask = 0; -static unsigned int mw, mh; -static Bool running = True; -static DC dc; -static Display *dpy; -static Window win, parent; +static size_t cursor = 0; void cleanup(void) { cleanupdraw(&dc); XDestroyWindow(dpy, win); XUngrabKeyboard(dpy, CurrentTime); + XCloseDisplay(dpy); } void -drawcursor(void) { - XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; - - r.x += textnw(&dc, text, cursor) + dc.font.height / 2; - - XSetForeground(dpy, dc.gc, dc.norm[ColFG]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); -} - -void -drawinput(void) +drawbar(void) { dc.x = 0; dc.y = 0; dc.w = mw; dc.h = mh; - drawtext(&dc, NULL, dc.norm); + drawbox(&dc, normcol); /* print prompt? */ if(prompt) { dc.w = promptw; - drawtext(&dc, prompt, dc.sel); + drawbox(&dc, selcol); + drawtext(&dc, prompt, selcol); dc.x += dc.w; } dc.w = mw - dc.x; - drawtext(&dc, *text ? text : NULL, dc.norm); - drawcursor(); - XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); - XFlush(dpy); -} - -Bool -grabkeyboard(void) { - unsigned int len; - - for(len = 1000; len; len--) { - if(XGrabKeyboard(dpy, parent, True, GrabModeAsync, GrabModeAsync, CurrentTime) - == GrabSuccess) - break; - usleep(1000); - } - return len > 0; + drawtext(&dc, text, normcol); + drawline(&dc, textnw(&dc, text, cursor) + dc.font.height/2, 2, 1, + dc.font.height-2, normcol); + commitdraw(&dc, win); } void -kpress(XKeyEvent * e) { +kpress(XKeyEvent *e) { char buf[sizeof text]; int num; unsigned int i, len; @@ -139,6 +86,7 @@ kpress(XKeyEvent * e) { ksym = XK_BackSpace; break; case XK_j: + case XK_m: ksym = XK_Return; break; case XK_k: @@ -200,9 +148,7 @@ kpress(XKeyEvent * e) { cursor = len; break; case XK_Escape: - ret = 1; - running = False; - return; + exit(EXIT_FAILURE); case XK_Home: cursor = 0; break; @@ -214,125 +160,29 @@ kpress(XKeyEvent * e) { case XK_Return: fprintf(stdout, "%s", text); fflush(stdout); - running = False; - return; + exit(EXIT_SUCCESS); case XK_Right: if(cursor == len) return; while(cursor++ < len && !IS_UTF8_1ST_CHAR(text[cursor])); break; } - drawinput(); -} - -void -run(void) { - XEvent ev; - - /* main event loop */ - while(running && !XNextEvent(dpy, &ev)) - switch (ev.type) { - case KeyPress: - kpress(&ev.xkey); - break; - case Expose: - if(ev.xexpose.count == 0) - drawinput(); - break; - case VisibilityNotify: - if (ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dpy, win); - break; - } -} - -void -setup(Bool topbar) { - int i, j, x, y; -#if XINERAMA - int n; - XineramaScreenInfo *info = NULL; -#endif - XModifierKeymap *modmap; - XSetWindowAttributes wa; - XWindowAttributes pwa; - - /* 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; - dc.norm[ColBG] = getcolor(&dc, normbgcolor); - dc.norm[ColFG] = getcolor(&dc, normfgcolor); - dc.sel[ColBG] = getcolor(&dc, selbgcolor); - dc.sel[ColFG] = getcolor(&dc, selfgcolor); - initfont(&dc, font); - fprintf(stderr, "dc.font.xfont: %u\n", (size_t)dc.font.xfont); - - /* input window */ - wa.override_redirect = True; - wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; - - /* input window geometry */ - mh = dc.font.height + 2; -#if XINERAMA - if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { - i = 0; - if(n > 1) { - int di; - unsigned int dui; - Window dummy; - if(XQueryPointer(dpy, parent, &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 - { - XGetWindowAttributes(dpy, parent, &pwa); - x = 0; - y = topbar ? 0 : pwa.height - mh; - mw = pwa.width; - } - - win = XCreateWindow(dpy, parent, 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); - cursor = strlen(text); - XMapRaised(dpy, win); + drawbar(); } int main(int argc, char *argv[]) { unsigned int i; - Bool topbar = True; /* command line args */ - progname = argv[0]; + progname = "dinput"; for(i = 1; i < argc; i++) - if(!strcmp(argv[i], "-b")) + if(!strcmp(argv[i], "-i")) + ; /* ignore flag */ + else if(!strcmp(argv[i], "-b")) topbar = False; - else if(!strcmp(argv[i], "-e")) { - if(++i < argc) parent = atoi(argv[i]); - } + else if(!strcmp(argv[i], "-l")) + i++; /* ignore flag */ else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; } @@ -351,27 +201,30 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-sf")) { if(++i < argc) selfgcolor = argv[i]; } - else if(!strcmp(argv[i], "-v")) - eprint("dinput-"VERSION", © 2006-2010 dinput engineers, see LICENSE for details\n"); - else if(!*text) + else if(!strcmp(argv[i], "-v")) { + printf("dinput-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n"); + exit(EXIT_SUCCESS); + } + else if(!*text) { strncpy(text, argv[i], sizeof text); - else - eprint("usage: dinput [-b] [-e ] [-fn ] [-nb ] [-nf ]\n" - " [-p ] [-sb ] [-sf ] [-v] []\n"); + cursor = strlen(text); + } + else { + fputs("usage: dinput [-b] [-fn ] [-nb ] [-nf ]\n" + " [-p ] [-sb ] [-sf ] [-v] []\n", stderr); + exit(EXIT_FAILURE); + } if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) fprintf(stderr, "dinput: warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL))) eprint("cannot open display\n"); + if(atexit(&cleanup) != 0) + eprint("cannot register cleanup\n"); screen = DefaultScreen(dpy); - if(!parent) - parent = RootWindow(dpy, screen); + root = RootWindow(dpy, screen); - running = grabkeyboard(); - setup(topbar); - drawinput(); - XSync(dpy, False); + grabkeyboard(); + setup(0); run(); - cleanup(); - XCloseDisplay(dpy); - return ret; + return 0; }