X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=dinput.c;h=0d0adebc3ab9348ecb504a648fe977a33a3746da;hb=29e8faed6cf4b296382439651cf04596d276f080;hp=d8f2515922b1dbda51d5ba4dc8c1cb9f608ac0b4;hpb=2ec16d9cb2661c834e346b4cdef29449ddc2f29c;p=dmenu.git diff --git a/dinput.c b/dinput.c index d8f2515..0d0adeb 100644 --- a/dinput.c +++ b/dinput.c @@ -1,11 +1,9 @@ /* See LICENSE file for copyright and license details. */ #include #include -#include #include #include #include -#include #include #include #include @@ -13,9 +11,9 @@ #ifdef XINERAMA #include #endif +#include /* 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)) @@ -23,47 +21,35 @@ /* 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 grabkeyboard(void); +static void kpress(XKeyEvent *e); static void run(void); -static void setup(Bool topbar); +static void setup(void); #include "config.h" -#include "draw.h" /* variables */ static char *prompt = NULL; static char text[4096]; static int promptw = 0; -static int ret = 0; -static unsigned int cursor = 0; +static int screen; +static size_t cursor = 0; static unsigned int numlockmask = 0; -static Bool running = True; -static Window win; - -Display *dpy; -DC dc; -int screen; -unsigned int mw, mh; -Window parent; +static unsigned int mw, mh; +static unsigned long normcol[ColLast]; +static unsigned long selcol[ColLast]; +static Bool topbar = True; +static DC dc; +static Display *dpy; +static Window win, root; void cleanup(void) { - drawcleanup(); + cleanupdraw(&dc); XDestroyWindow(dpy, win); XUngrabKeyboard(dpy, CurrentTime); -} - -void -drawcursor(void) { - XRectangle r = { dc.x, dc.y + 2, 1, dc.font.height - 2 }; - - r.x += textnw(text, cursor) + dc.font.height / 2; - - XSetForeground(dpy, dc.gc, dc.norm[ColFG]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + XCloseDisplay(dpy); } void @@ -73,35 +59,34 @@ drawinput(void) 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; - drawtext(*text ? text : NULL, dc.norm); - drawcursor(); - XCopyArea(dpy, dc.drawable, win, dc.gc, 0, 0, mw, mh, 0, 0); - XFlush(dpy); + drawtext(&dc, text, normcol); + drawcursor(&dc, text, cursor, normcol); + commitdraw(&dc, win); } -Bool +void grabkeyboard(void) { unsigned int len; for(len = 1000; len; len--) { - if(XGrabKeyboard(dpy, parent, True, GrabModeAsync, GrabModeAsync, CurrentTime) + if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) - break; + return; usleep(1000); } - return len > 0; + exit(EXIT_FAILURE); } void -kpress(XKeyEvent * e) { +kpress(XKeyEvent *e) { char buf[sizeof text]; int num; unsigned int i, len; @@ -141,6 +126,7 @@ kpress(XKeyEvent * e) { ksym = XK_BackSpace; break; case XK_j: + case XK_m: ksym = XK_Return; break; case XK_k: @@ -164,7 +150,7 @@ kpress(XKeyEvent * e) { FILE *fp; char *s; if(!(fp = popen("sselp", "r"))) - eprint("dinput: cannot popen sselp\n"); + eprint("cannot popen sselp\n"); s = fgets(buf, sizeof buf, fp); pclose(fp); if(s == NULL) @@ -202,9 +188,7 @@ kpress(XKeyEvent * e) { cursor = len; break; case XK_Escape: - ret = 1; - running = False; - return; + exit(EXIT_FAILURE); case XK_Home: cursor = 0; break; @@ -216,8 +200,7 @@ 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; @@ -232,8 +215,9 @@ run(void) { XEvent ev; /* main event loop */ - while(running && !XNextEvent(dpy, &ev)) - switch (ev.type) { + XSync(dpy, False); + while(!XNextEvent(dpy, &ev)) + switch(ev.type) { case KeyPress: kpress(&ev.xkey); break; @@ -242,14 +226,15 @@ run(void) { drawinput(); break; case VisibilityNotify: - if (ev.xvisibility.state != VisibilityUnobscured) + if(ev.xvisibility.state != VisibilityUnobscured) XRaiseWindow(dpy, win); break; } + exit(EXIT_FAILURE); } void -setup(Bool topbar) { +setup(void) { int i, j, x, y; #if XINERAMA int n; @@ -257,7 +242,6 @@ setup(Bool topbar) { #endif XModifierKeymap *modmap; XSetWindowAttributes wa; - XWindowAttributes pwa; /* init modifier map */ modmap = XGetModifierMapping(dpy); @@ -269,23 +253,28 @@ setup(Bool topbar) { } 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 */ + /* input window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; - wa.event_mask = ExposureMask | ButtonPressMask | KeyPressMask | VisibilityChangeMask; + wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - /* menu window geometry */ - mh = (dc.font.height + 2); + /* input window geometry */ + mh = dc.font.height + 2; #if XINERAMA - if(parent == RootWindow(dpy, screen) && XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) { + if(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)) + 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; @@ -298,20 +287,19 @@ setup(Bool topbar) { else #endif { - XGetWindowAttributes(dpy, parent, &pwa); x = 0; - y = topbar ? 0 : pwa.height - mh; - mw = pwa.width; + y = topbar ? 0 : DisplayHeight(dpy, screen) - mh; + mw = DisplayWidth(dpy, screen); } - win = XCreateWindow(dpy, parent, x, y, mw, mh, 0, + win = XCreateWindow(dpy, root, x, y, mw, mh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - drawsetup(); + setupdraw(&dc, win); if(prompt) - promptw = MIN(textw(prompt), mw / 5); + promptw = MIN(textw(&dc, prompt), mw / 5); cursor = strlen(text); XMapRaised(dpy, win); } @@ -319,15 +307,16 @@ setup(Bool topbar) { int main(int argc, char *argv[]) { unsigned int i; - Bool topbar = True; /* command line args */ + 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]; } @@ -346,27 +335,28 @@ 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(!strcmp(argv[i], "-v")) { + printf("dinput-"VERSION", © 2006-2010 dinput 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"); + 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("dinput: cannot open display\n"); + 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(); run(); - cleanup(); - XCloseDisplay(dpy); - return ret; + return 0; }