trio: add xshove program - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit f73497bbafecbedd367eaab16aaf37c701672be0
 (DIR) parent 9daa3ca74ebd673d00ba52667c50fe4a0046d100
 (HTM) Author: Russ Cox <rsc@swtch.com>
       Date:   Thu, 31 Jan 2008 20:56:23 -0500
       
       rio: add xshove program
       
       Diffstat:
         M src/cmd/rio/mkfile                  |      10 ++++++++--
         M src/cmd/rio/mkriorules.sh           |       3 +--
         A src/cmd/rio/rio.c                   |       0 
         A src/cmd/rio/xshove.c                |     289 +++++++++++++++++++++++++++++++
       
       4 files changed, 298 insertions(+), 4 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/rio/mkfile b/src/cmd/rio/mkfile
       t@@ -1,7 +1,7 @@
        <$PLAN9/src/mkhdr
        <|sh ../devdraw/mkwsysrules.sh        # for X11
        
       -OFILES=\
       +RIOFILES=\
                client.$O\
                color.$O\
                cursor.$O\
       t@@ -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
       t@@ -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
       t@@ -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
       +
 (DIR) diff --git a/src/cmd/rio/mkriorules.sh b/src/cmd/rio/mkriorules.sh
       t@@ -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
 (DIR) diff --git a/src/cmd/rio/rio.c b/src/cmd/rio/rio.c
 (DIR) diff --git a/src/cmd/rio/xshove.c b/src/cmd/rio/xshove.c
       t@@ -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;
       +}