diff options
Diffstat (limited to 'xlnch.c')
-rw-r--r-- | xlnch.c | 144 |
1 files changed, 124 insertions, 20 deletions
@@ -26,6 +26,7 @@ #include <X11/Xos.h> #include <stdio.h> +#include <stdarg.h> #include <stdlib.h> #include <string.h> #include <ctype.h> @@ -35,6 +36,7 @@ #include <wordexp.h> +#define MAX(A, B) ((A) > (B) ? (A) : (B)) Display *dis; int screen; @@ -44,6 +46,90 @@ GC gc; Colormap cm; XColor red; +typedef struct { + unsigned int w, h; + Display *dis; + int screen; + Window root, win; + Drawable drawable; + GC gc; + // XftColor *scheme; +} Drw; +Drw drw; + +int w_width = 0; +int w_height = 0; + +void +die(const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + if (fmt[0] && fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } + + exit(1); +} + +void get_curson_pos(int *x, int *y) +{ + int win_x_return, win_y_return; + unsigned int mask_return; + Window root_return, child_return; + + XQueryPointer(drw.dis, drw.root, &root_return, &child_return, + x, y, &win_x_return, &win_y_return, &mask_return); +} + +void init() +{ + XWindowAttributes wa; + XSetWindowAttributes swa; + + drw.dis = XOpenDisplay(NULL); + drw.screen = DefaultScreen(drw.dis); + drw.root = RootWindow(drw.dis, drw.screen); + if (!XGetWindowAttributes(drw.dis, drw.root, &wa)) + die("could not get embedding window attributes: 0x%lx", drw.root); + + drw.w = wa.width; + drw.h = wa.height; + //drw.drawable = XCreatePixmap(drw.dis, drw.root, drw.w, drw.h, DefaultDepth(drw.dis, drw.screen)); + drw.gc = XCreateGC(drw.dis, drw.root, 0, NULL); + XSetLineAttributes(drw.dis, drw.gc, 1, LineSolid, CapButt, JoinMiter); + + swa.override_redirect = True; + swa.background_pixel = BlackPixel(drw.dis, drw.screen); + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; + + int x, y; + get_curson_pos(&x, &y); + + int height = 16 + (9 + 3)*w_height - 3 + 16, + width = 16 + w_width*9; + drw.win = XCreateWindow(drw.dis, drw.root, x, y, width, height, 0, + CopyFromParent, CopyFromParent, CopyFromParent, + CWOverrideRedirect | CWBackPixel | CWEventMask, &swa); + + printf("Window pos: {%d, %d}", x, y); + fflush(stdout); + + cm = DefaultColormap(drw.dis, drw.screen); + if (! XAllocNamedColor(drw.dis, cm, "red", &red, &red)) { + fprintf(stderr, "XAllocNamedColor - failed to allocated 'red' color.\n"); + exit(1); + } + XMapRaised(drw.dis, drw.win); + XRaiseWindow(drw.dis, drw.win); +} + void init_x() { /* get the colors black and white (see section for details) */ @@ -109,9 +195,9 @@ void init_x() void close_x() { - XFreeGC(dis, gc); - XDestroyWindow(dis,win); - XCloseDisplay(dis); + XFreeGC(drw.dis, drw.gc); + XDestroyWindow(drw.dis,drw.win); + XCloseDisplay(drw.dis); } @@ -154,6 +240,9 @@ int parse_line(char * line) lnch[idx].exits = 1; + if (line[0] == '#') + return 0; + if (line[0] == '&') { lnch[idx].exits = 0; line++; @@ -171,6 +260,9 @@ int parse_line(char * line) /* Get description */ token = strtok(NULL, delim); + if (!token) return 1; + + w_width = MAX((int) strlen(token), w_width); strcpy(lnch[idx].desc, token); line+=(strlen(token) + 1 ); // pass the decription, pass the `:` @@ -235,10 +327,10 @@ void grabfocus() int i, revertwin; for (i = 0; i < 100; ++i) { - XGetInputFocus(dis, &focuswin, &revertwin); - if (focuswin == win) + XGetInputFocus(drw.dis, &focuswin, &revertwin); + if (focuswin == drw.win) return; - XSetInputFocus(dis, win, RevertToParent, CurrentTime); + XSetInputFocus(drw.dis, drw.win, RevertToParent, CurrentTime); nanosleep(&ts, NULL); } printf("cannot grab focus\n"); @@ -251,7 +343,7 @@ void grabkeyboard() /* try to grab keyboard, we may have to wait for another process to ungrab */ for (i = 0; i < 1000; i++) { - if (XGrabKeyboard(dis, DefaultRootWindow(dis), True, GrabModeAsync, + if (XGrabKeyboard(drw.dis, drw.root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) return; nanosleep(&ts, NULL); @@ -265,17 +357,17 @@ void draw_text() int x = 10, y = 10; for (unsigned int i = 0; i < idx; i++) { if (lnch[i].exits) - XSetForeground(dis,gc,WhitePixel(dis,DefaultScreen(dis))); + XSetForeground(drw.dis,drw.gc,WhitePixel(drw.dis,drw.screen)); else - XSetForeground(dis,gc,red.pixel); + XSetForeground(drw.dis,drw.gc,red.pixel); sprintf(text, "%c: %s", lnch[i].key, lnch[i].desc); - XDrawString(dis,win,gc,x,y+=13, text, strlen(text)); + XDrawString(drw.dis,drw.win,drw.gc,x,y+=13, text, strlen(text)); } } void redraw() { - XClearWindow(dis, win); + XClearWindow(drw.dis, drw.win); draw_text(); } @@ -286,27 +378,33 @@ int main (int argc, char *argv[]) printf("xlnchrc format:\n[&]<key>:<description>:<command>\n"); return -1; } + FILE *f; - f = fopen(argv[1], "r"); - if (!f) { - printf("xlnchrc required\n"); - return -1; + if (!strcmp(argv[1], "-")) + f = stdin; + else { + f = fopen(argv[1], "r"); + /* printf("xlnchrc required\n"); */ + /* return -1; */ } while (fgets(buf, BUF_SIZE, f)) { trim(buf); parse_line(buf); + w_height++; } - fclose(f); + + if (f != stdin) fclose(f); XEvent event; /* the XEvent declaration !!! */ KeySym key; /* a dealie-bob to handle KeyPress Events */ char text[255]; /* a char buffer for KeyPress Events */ int rc; - init_x(); + init(); + // system("sleep 100"); grabkeyboard(); grabfocus(); @@ -315,13 +413,19 @@ int main (int argc, char *argv[]) /* get the next event and stuff it into our event variable. Note: only events we set the mask for are detected! */ - XNextEvent(dis, &event); + XNextEvent(drw.dis, &event); if (event.type==Expose && event.xexpose.count==0) { /* the window was exposed redraw it! */ redraw(); } + /* Keep window in view */ + if (event.type==VisibilityNotify && + event.xvisibility.state != VisibilityUnobscured) + XRaiseWindow(drw.dis, drw.win); + + if (event.type==KeyPress && XLookupString(&event.xkey,text,255,&key,0)==1) { /* use the XLookupString routine to convert the invent @@ -349,8 +453,8 @@ int main (int argc, char *argv[]) y=event.xbutton.y; strcpy(text,">>xlnch<<"); - XSetForeground(dis,gc,rand()%255); - XDrawString(dis,win,gc,x,y, text, strlen(text)); + XSetForeground(drw.dis,drw.gc,rand()%255); + XDrawString(drw.dis,drw.win,drw.gc,x,y, text, strlen(text)); } if (event.type==FocusIn) { |