aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rio
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2008-01-31 20:56:23 -0500
committerRuss Cox <rsc@swtch.com>2008-01-31 20:56:23 -0500
commitf73497bbafecbedd367eaab16aaf37c701672be0 (patch)
treee2bb8dae3833c266b3b1e2f3cdcd068fa5d795d5 /src/cmd/rio
parent9daa3ca74ebd673d00ba52667c50fe4a0046d100 (diff)
downloadplan9port-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/mkfile10
-rw-r--r--src/cmd/rio/mkriorules.sh2
-rw-r--r--src/cmd/rio/rio.c0
-rw-r--r--src/cmd/rio/xshove.c289
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;
+}