diff options
author | Russ Cox <rsc@swtch.com> | 2008-01-31 20:56:23 -0500 |
---|---|---|
committer | Russ Cox <rsc@swtch.com> | 2008-01-31 20:56:23 -0500 |
commit | f73497bbafecbedd367eaab16aaf37c701672be0 (patch) | |
tree | e2bb8dae3833c266b3b1e2f3cdcd068fa5d795d5 /src/cmd/rio | |
parent | 9daa3ca74ebd673d00ba52667c50fe4a0046d100 (diff) | |
download | plan9port-f73497bbafecbedd367eaab16aaf37c701672be0.tar.gz plan9port-f73497bbafecbedd367eaab16aaf37c701672be0.tar.bz2 plan9port-f73497bbafecbedd367eaab16aaf37c701672be0.zip |
rio: add xshove program
Diffstat (limited to 'src/cmd/rio')
-rw-r--r-- | src/cmd/rio/mkfile | 10 | ||||
-rw-r--r-- | src/cmd/rio/mkriorules.sh | 2 | ||||
-rw-r--r-- | src/cmd/rio/rio.c | 0 | ||||
-rw-r--r-- | src/cmd/rio/xshove.c | 289 |
4 files changed, 298 insertions, 3 deletions
diff --git a/src/cmd/rio/mkfile b/src/cmd/rio/mkfile index 135226d3..e5426865 100644 --- a/src/cmd/rio/mkfile +++ b/src/cmd/rio/mkfile @@ -1,7 +1,7 @@ <$PLAN9/src/mkhdr <|sh ../devdraw/mkwsysrules.sh # for X11 -OFILES=\ +RIOFILES=\ client.$O\ color.$O\ cursor.$O\ @@ -16,7 +16,7 @@ OFILES=\ CFLAGS=$CFLAGS -DDEBUG HFILES=dat.h fns.h -TARG=rio +TARG=rio xshove # need to add lib64 when it exists (on x86-64), but # Darwin complains about the nonexistant directory @@ -27,6 +27,8 @@ LDFLAGS=-L$X11/lib$L64/ -lXext -lX11 <|sh mkriorules.sh +$O.rio: $RIOFILES + CFLAGS=$CFLAGS -DSHAPE -DDEBUG_EV -DDEBUG $O.xevents: xevents.$O printevent.$O @@ -35,3 +37,7 @@ $O.xevents: xevents.$O printevent.$O xevents.$O printevent.$O: printevent.h error.$O: showevent/ShowEvent.c + +$O.xshove: xshove.$O + $LD -o $O.xshove xshove.$O -lX11 + diff --git a/src/cmd/rio/mkriorules.sh b/src/cmd/rio/mkriorules.sh index 0b25d2e2..6918d991 100644 --- a/src/cmd/rio/mkriorules.sh +++ b/src/cmd/rio/mkriorules.sh @@ -3,4 +3,4 @@ if [ "x$WSYSTYPE" = xnowsys ]; then echo ' #' exit 0 fi -cat $PLAN9/src/mkone
\ No newline at end of file +cat $PLAN9/src/mkmany diff --git a/src/cmd/rio/rio.c b/src/cmd/rio/rio.c new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/src/cmd/rio/rio.c diff --git a/src/cmd/rio/xshove.c b/src/cmd/rio/xshove.c new file mode 100644 index 00000000..1b1c7fa5 --- /dev/null +++ b/src/cmd/rio/xshove.c @@ -0,0 +1,289 @@ +#include <u.h> +#include <X11/X.h> +#include <X11/Xatom.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <libc.h> +#include <ctype.h> + +AUTOLIB(X11); + +typedef struct Rectangle Rectangle; +struct Rectangle +{ + struct { + int x; + int y; + } min, max; +}; +#define Dx(r) ((r).max.x - (r).min.x) +#define Dy(r) ((r).max.y - (r).min.y) + +typedef struct Win Win; +struct Win +{ + Window xw; + int x; + int y; + int dx; + int dy; + char *class; + char *instance; + char *name; + char *iconname; +}; + +Display *dpy; +Window root; + +Win *w; +int nw; + +void getinfo(void); +void listwindows(void); +int parsewinsize(char*, Rectangle*, int*); +void shove(char*, char*); + +void +usage(void) +{ + fprint(2, "usage: xshove window rectangle\n" + " or xshove\n" + "window can be a window ID or a program name\n" + "rectangle is a p9p window spec (see intro(1))\n"); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + int screen; + + screen = 0; + ARGBEGIN{ + case 's': + screen = atoi(EARGF(usage())); + break; + default: + usage(); + break; + }ARGEND + + dpy = XOpenDisplay(""); + if(dpy == nil) + sysfatal("open display: %r"); + + root = RootWindow(dpy, screen); + getinfo(); + + if(argc == 0){ + listwindows(); + exits(0); + } + if(argc != 2) + usage(); + shove(argv[0], argv[1]); + exits(0); +} + +char* +getproperty(Window w, Atom a) +{ + uchar *p; + int fmt; + Atom type; + ulong n, dummy; + + n = 100; + p = nil; + XGetWindowProperty(dpy, w, a, 0, 100L, 0, + AnyPropertyType, &type, &fmt, + &n, &dummy, &p); + if(p == nil || *p == 0) + return nil; + return strdup((char*)p); +} + +Window +findname(Window w) +{ + int i; + uint nxwin; + Window dw1, dw2, *xwin; + + if(getproperty(w, XA_WM_NAME)) + return w; + if(!XQueryTree(dpy, w, &dw1, &dw2, &xwin, &nxwin)) + return 0; + for(i=0; i<nxwin; i++) + if((w = findname(xwin[i])) != 0) + return w; + return 0; +} + +void +getinfo(void) +{ + int i; + uint nxwin; + Window dw1, dw2, *xwin; + XClassHint class; + XWindowAttributes attr; + + if(!XQueryTree(dpy, root, &dw1, &dw2, &xwin, &nxwin)) + return; + w = mallocz(nxwin*sizeof w[0], 1); + if(w == 0) + sysfatal("malloc: %r"); + + Win *ww = w; + for(i=0; i<nxwin; i++){ + memset(&attr, 0, sizeof attr); + xwin[i] = findname(xwin[i]); + if(xwin[i] == 0) + continue; + XGetWindowAttributes(dpy, xwin[i], &attr); + if(attr.width <= 0 || attr.override_redirect || attr.map_state != IsViewable) + continue; + ww->xw = xwin[i]; + ww->x = attr.x; + ww->y = attr.y; + ww->dx = attr.width; + ww->dy = attr.height; + XTranslateCoordinates(dpy, ww->xw, root, 0, 0, &ww->x, &ww->y, &dw1); + if(XGetClassHint(dpy, ww->xw, &class)){ + ww->class = strdup(class.res_class); + ww->instance = strdup(class.res_name); + } + ww->iconname = getproperty(ww->xw, XA_WM_ICON_NAME); + ww->name = getproperty(ww->xw, XA_WM_NAME); + ww++; + } + nw = ww - w; +} + +void +listwindows(void) +{ + int i; + + for(i=0; i<nw; i++){ + Win *ww = &w[i]; + char rect[50]; + snprint(rect, sizeof rect, "%d,%d,%d,%d", ww->x, ww->y, ww->x+ww->dx, ww->y+ww->dy); + print("%08x %-20s %-10s %s\n", + (uint)ww->xw, + rect, + ww->instance, + ww->class); + } +} + +void +shove(char *name, char *geom) +{ + int i; + int havemin; + Rectangle r; + + if(parsewinsize(geom, &r, &havemin) < 0) + sysfatal("bad window spec: %s", name); + + for(i=0; i<nw; i++){ + Win *ww = &w[i]; + if(ww->instance && strstr(ww->instance, name) + || ww->class && strstr(ww->class, name)){ + int value_mask; + XWindowChanges e; + + memset(&e, 0, sizeof e); + e.width = Dx(r); + e.height = Dy(r); + value_mask = CWWidth | CWHeight; + if(havemin){ + e.x = r.min.x; + e.y = r.min.y; + value_mask |= CWX | CWY; + } + XConfigureWindow(dpy, ww->xw, value_mask, &e); + XFlush(dpy); + } + } +} + +int +parsewinsize(char *s, Rectangle *r, int *havemin) +{ + char c, *os; + int i, j, k, l; + + os = s; + *havemin = 0; + memset(r, 0, sizeof *r); + if(!isdigit((uchar)*s)) + goto oops; + i = strtol(s, &s, 0); + if(*s == 'x'){ + s++; + if(!isdigit((uchar)*s)) + goto oops; + j = strtol(s, &s, 0); + r->max.x = i; + r->max.y = j; + if(*s == 0) + return 0; + if(*s != '@') + goto oops; + + s++; + if(!isdigit((uchar)*s)) + goto oops; + i = strtol(s, &s, 0); + if(*s != ',' && *s != ' ') + goto oops; + s++; + if(!isdigit((uchar)*s)) + goto oops; + j = strtol(s, &s, 0); + if(*s != 0) + goto oops; + r->min.x += i; + r->max.x += i; + r->min.y += j; + r->max.y += j; + *havemin = 1; + return 0; + } + + c = *s; + if(c != ' ' && c != ',') + goto oops; + s++; + if(!isdigit((uchar)*s)) + goto oops; + j = strtol(s, &s, 0); + if(*s != c) + goto oops; + s++; + if(!isdigit((uchar)*s)) + goto oops; + k = strtol(s, &s, 0); + if(*s != c) + goto oops; + s++; + if(!isdigit((uchar)*s)) + goto oops; + l = strtol(s, &s, 0); + if(*s != 0) + goto oops; + r->min.x = i; + r->min.y = j; + r->max.x = k; + r->max.y = l; + *havemin = 1; + return 0; + +oops: + werrstr("bad syntax in window size '%s'", os); + return -1; +} |