rio: add xshove program
This commit is contained in:
parent
9daa3ca74e
commit
f73497bbaf
4 changed files with 298 additions and 3 deletions
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
0
src/cmd/rio/rio.c
Normal file
289
src/cmd/rio/xshove.c
Normal file
289
src/cmd/rio/xshove.c
Normal 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;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue