rio: add xshove program

This commit is contained in:
Russ Cox 2008-01-31 20:56:23 -05:00
parent 9daa3ca74e
commit f73497bbaf
4 changed files with 298 additions and 3 deletions

View file

@ -1,7 +1,7 @@
<$PLAN9/src/mkhdr <$PLAN9/src/mkhdr
<|sh ../devdraw/mkwsysrules.sh # for X11 <|sh ../devdraw/mkwsysrules.sh # for X11
OFILES=\ RIOFILES=\
client.$O\ client.$O\
color.$O\ color.$O\
cursor.$O\ cursor.$O\
@ -16,7 +16,7 @@ OFILES=\
CFLAGS=$CFLAGS -DDEBUG CFLAGS=$CFLAGS -DDEBUG
HFILES=dat.h fns.h HFILES=dat.h fns.h
TARG=rio TARG=rio xshove
# need to add lib64 when it exists (on x86-64), but # need to add lib64 when it exists (on x86-64), but
# Darwin complains about the nonexistant directory # Darwin complains about the nonexistant directory
@ -27,6 +27,8 @@ LDFLAGS=-L$X11/lib$L64/ -lXext -lX11
<|sh mkriorules.sh <|sh mkriorules.sh
$O.rio: $RIOFILES
CFLAGS=$CFLAGS -DSHAPE -DDEBUG_EV -DDEBUG CFLAGS=$CFLAGS -DSHAPE -DDEBUG_EV -DDEBUG
$O.xevents: xevents.$O printevent.$O $O.xevents: xevents.$O printevent.$O
@ -35,3 +37,7 @@ $O.xevents: xevents.$O printevent.$O
xevents.$O printevent.$O: printevent.h xevents.$O printevent.$O: printevent.h
error.$O: showevent/ShowEvent.c error.$O: showevent/ShowEvent.c
$O.xshove: xshove.$O
$LD -o $O.xshove xshove.$O -lX11

View file

@ -3,4 +3,4 @@ if [ "x$WSYSTYPE" = xnowsys ]; then
echo ' #' echo ' #'
exit 0 exit 0
fi fi
cat $PLAN9/src/mkone cat $PLAN9/src/mkmany

0
src/cmd/rio/rio.c Normal file
View file

289
src/cmd/rio/xshove.c Normal file
View file

@ -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;
}