diff --git a/Makefile b/Makefile index 0d48614..9a5edb9 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ include config.mk SRC = svkbd.c -OBJ = ${SRC:.c=.o} +LAYOUTS = en de arrows all: options svkbd @@ -15,29 +15,32 @@ options: @echo "CC = ${CC}" @echo "LAYOUT = ${LAYOUT}" -.c.o: - @echo CC $< - @${CC} ${CPPFLAGS} -c ${CFLAGS} $< - -${OBJ}: config.h config.mk - -config.h: +config.h: config.mk @echo creating $@ from config.def.h @cp config.def.h $@ -svkbd: ${OBJ} + +svkbd: svkbd.en + @echo CP $@ + @cp $< $@ + +svkbd.%: layout.%.h config.h ${SRC} + @echo creating layout.h from $< + @cp $< layout.h @echo CC -o $@ - @${CC} -o $@ ${OBJ} ${LDFLAGS} + @${CC} -o $@ ${SRC} ${LDFLAGS} ${CFLAGS} clean: @echo cleaning - @rm -f svkbd ${OBJ} svkbd-${VERSION}.tar.gz + @for i in ${LAYOUTS}; do rm svkbd.$$i 2> /dev/null; done; true + @rm -f svkbd ${OBJ} svkbd-${VERSION}.tar.gz 2> /dev/null; true dist: clean @echo creating dist tarball @mkdir -p svkbd-${VERSION} - @cp -R LICENSE Makefile README config.def.h config.mk \ - ${SRC} layouts svkbd-${VERSION} + @cp LICENSE Makefile README config.def.h config.mk \ + ${SRC} svkbd-${VERSION} + @for i in ${LAYOUTS}; do cp layout.$$i.h svkbd.${VERSION} || exit 1; done @tar -cf svkbd-${VERSION}.tar svkbd-${VERSION} @gzip svkbd-${VERSION}.tar @rm -rf svkbd-${VERSION} diff --git a/config.def.h b/config.def.h index c85a928..63640e7 100644 --- a/config.def.h +++ b/config.def.h @@ -1,3 +1,4 @@ +static const Bool wmborder = True; static const char font[] = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; static const char normbgcolor[] = "#cccccc"; static const char normfgcolor[] = "#000000"; @@ -5,4 +6,3 @@ static const char hovbgcolor[] = "#ffffff"; static const char hovfgcolor[] = "#000000"; static const char pressbgcolor[] = "#0000cc"; static const char pressfgcolor[] = "#ffffff"; - diff --git a/config.mk b/config.mk index fe83be3..77026a7 100644 --- a/config.mk +++ b/config.mk @@ -1,7 +1,7 @@ # svkbd version VERSION = 0.1 -LAYOUT?=def +LAYOUT ?= en # Customize below to fit your system @@ -18,7 +18,6 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -lXtst # flags CPPFLAGS = -DVERSION=\"${VERSION}\" \ - -DCONFIGLAYOUT_H=\"layout.${LAYOUT}.h\" \ ${XINERAMAFLAGS} CFLAGS = -g -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -g ${LIBS} diff --git a/svkbd.c b/svkbd.c index ec79be7..7b72332 100644 --- a/svkbd.c +++ b/svkbd.c @@ -20,6 +20,7 @@ /* enums */ enum { ColFG, ColBG, ColLast }; +enum { NetWMWindowType, NetLast }; /* typedefs */ typedef unsigned int uint; @@ -57,6 +58,7 @@ static void buttonpress(XEvent *e); static void buttonrelease(XEvent *e); static void cleanup(void); static void configurenotify(XEvent *e); +static void countrows(); static void unmapnotify(XEvent *e); static void die(const char *errstr, ...); static void drawkeyboard(void); @@ -83,13 +85,18 @@ static void (*handler[LASTEvent]) (XEvent *) = { [Expose] = expose, [LeaveNotify] = leavenotify, }; +static Atom netatom[NetLast]; static Display *dpy; static DC dc; static Window root, win; static Bool running = True; static KeySym pressedmod = 0; +static int rows, ww = 0, wh = 0, wx = 0, wy = 0; +static char *name = "svkbd"; +static char *wintype = "_NET_WM_WINDOW_TYPE_TOOLBAR"; /* configuration, allows nested code to access above variables */ #include "config.h" +#include "layout.h" void buttonpress(XEvent *e) { @@ -142,6 +149,15 @@ configurenotify(XEvent *e) { } } +void +countrows() { + int i = 0; + + for(i = 0, rows = 1; i < LENGTH(keys); i++) + if(keys[i].keysym == 0) + rows++; +} + void die(const char *errstr, ...) { va_list ap; @@ -308,30 +324,32 @@ run(void) { void setup(void) { - int i; - XWMHints *wmh; XSetWindowAttributes wa; + XTextProperty str; + XClassHint *ch; + int i, sh, sw; + XWMHints *wmh; /* init screen */ screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); initfont(font); - /* init appearance */ - if (!ww) - ww = DisplayWidth(dpy, screen); - if (ww < 0) - ww = DisplayWidth(dpy, screen) / (ww * -1); - - if (wh < 0) - wh = DisplayHeight(dpy, screen) / (wh * -1); - - if (wy < 0) - wy = DisplayHeight(dpy, screen) + wy; - - if (wx < 0) - wx = DisplayWidth(dpy, screen) + wx; + /* init atoms */ + netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + /* init appearance */ + countrows(); + if(!ww) + ww = sw - wx; + if(!wx) + wx = 0; + if(!wh) + wh = sh * rows / 32; + if(!wy) + wy = sh - wh; dc.norm[ColBG] = getcolor(normbgcolor); dc.norm[ColFG] = getcolor(normfgcolor); dc.press[ColBG] = getcolor(pressbgcolor); @@ -343,7 +361,7 @@ setup(void) { for(i = 0; i < LENGTH(keys); i++) keys[i].pressed = 0; - wa.override_redirect = True; + wa.override_redirect = !wmborder; wa.border_pixel = dc.norm[ColFG]; wa.background_pixel = dc.norm[ColBG]; win = XCreateWindow(dpy, root, wx, wy, ww, wh, 0, @@ -351,11 +369,27 @@ setup(void) { CWOverrideRedirect | CWBorderPixel | CWBackingPixel, &wa); XSelectInput(dpy, win, StructureNotifyMask|ButtonReleaseMask| ButtonPressMask|ExposureMask|LeaveWindowMask); + wmh = XAllocWMHints(); wmh->input = False; wmh->flags = InputHint; XSetWMHints(dpy, win, wmh); + XStringListToTextProperty(&name, 1, &str); + ch = XAllocClassHint(); + ch->res_class = name; + ch->res_name = name; + + XSetWMProperties(dpy, win, &str, &str, NULL, 0, NULL, wmh, + ch); + + XFree(ch); XFree(wmh); + XFree(str.value); + + XStringListToTextProperty(&wintype, 1, &str); + XSetTextProperty(dpy, win, &str, netatom[NetWMWindowType]); + XFree(str.value); + XMapRaised(dpy, win); updatekeys(); drawkeyboard(); @@ -399,12 +433,9 @@ unpress() { void updatekeys() { - int rows, i, j; + int i, j; int x = 0, y = 0, h, base; - for(i = 0, rows = 1; i < LENGTH(keys); i++) - if(keys[i].keysym == 0) - rows++; h = wh / rows; for(i = 0; i < LENGTH(keys); i++, rows--) { for(j = i, base = 0; j < LENGTH(keys) && keys[j].keysym != 0; j++) @@ -441,27 +472,25 @@ main(int argc, char *argv[]) { die("svkbd-"VERSION", © 2006-2010 svkbd engineers," " see LICENSE for details\n"); } - if(!strcmp(argv[i], "-wh")) { - wh = atoi(argv[i+1]); - i++; - continue; - } - if(!strcmp(argv[i], "-ww")) { - ww = atoi(argv[i+1]); - i++; - continue; - } - if(!strcmp(argv[i], "-wx")) { - wx = atoi(argv[i+1]); - i++; - continue; - } - if(!strcmp(argv[i], "-wy")) { - wy = atoi(argv[i+1]); - i++; - continue; + else if(argv[i][0] == '-' && argv[i][1] == 'w') { + switch(i >= argc - 1 ? 0 : argv[i][2]) { + case 'h': + wh = atoi(argv[i+1]); + break; + case 'w': + ww = atoi(argv[i+1]); + break; + case 'x': + wx = atoi(argv[i+1]); + break; + case 'y': + wy = atoi(argv[i+1]); + break; + default: + usage(argv[0]); + } } - if(!strcmp(argv[i], "-h")) + else if(!strcmp(argv[i], "-h")) usage(argv[0]); }