removed crappy blitz_strtorect, added move/size commands for client ctl, cleaned up liblitz/geometry somewhat

This commit is contained in:
Anselm R. Garbe 2006-05-26 14:16:19 +02:00
parent ef672bf5fe
commit 1e4b2bb061
8 changed files with 176 additions and 277 deletions

View File

@ -15,10 +15,6 @@
- make /foo/ -> bar+! -alike rules working
- /def/ncol defines num of columns which should be created by default if possible.
- wmiimenu -t <title> flag (add an additional line if -t is supplied)
- remove the geom syntax as it is now (with the +- stuff, and only
allowing explicit coordinates, instead additionally resize
+/-<w> +/-<h> and move +/-<x> +/-<y> actions are needed in the
associated ctl devices of clients.
- remove internal labels, now tagging seems easy and straightforward that they
THINK: We'll need CreateTag, DestroyTag, UnfocusTag, FocusTag and the
event loop in wmiirc must be before TAGGING can be externalized again

View File

@ -604,8 +604,93 @@ newcol_client(Client *c, char *arg)
flush_masked_events(EnterWindowMask);
}
static int
parse_int_arg(int *i, const char *ival)
{
int imult = 0, inum;
const char *errstr;
if(*ival == '-')
imult = -1;
else if(*ival == '+')
imult = 1;
inum = cext_strtonum(ival, -32765, 32765, &errstr);
if(errstr)
return -1;
if(inum < 0)
inum *= -1;
if(imult < 0)
*i -= inum;
else if(imult > 0)
*i += inum;
else
*i = inum;
return 0;
}
/* Parses "[+|-]<int> [+|-]<int>" and applies to the given vals */
static int
parse_mvsize_arg(int *i1, int *i2, const char *val)
{
char buf[64], *p;
int i;
cext_strlcpy(buf, val, sizeof(buf));
p = strchr(buf, ' ');
if(!p)
return -1;
*p = 0;
p++;
i = *i1;
if(parse_int_arg(&i, buf) == -1)
return -1;
*i1 = i;
i = *i2;
if(parse_int_arg(&i, buf) == -1)
return -1;
*i2 = i;
return 0;
}
void
move_client(Client *c, char *arg)
{
Frame *f = c->frame.data[c->sel];
XRectangle new = f->rect;
int x = new.x, y = new.y;
if(parse_mvsize_arg(&x, &y, arg) == -1)
return;
new.x = x;
new.y = y;
if(idx_of_area(f->area))
resize_column(f->client, &new, nil);
else
resize_client(f->client, &new, False);
}
void
size_client(Client *c, char *arg)
{
Frame *f = c->frame.data[c->sel];
XRectangle new = f->rect;
int w = new.width, h = new.height;
if(parse_mvsize_arg(&w, &h, arg) == -1)
return;
new.width = w;
new.height = h;
if(idx_of_area(f->area))
resize_column(f->client, &new, nil);
else
resize_client(f->client, &new, False);
}
void
send_client(Client *c, char *arg)
{
const char *errstr;
Frame *f = c->frame.data[c->sel];

View File

@ -104,7 +104,7 @@ handle_buttonpress(XEvent *e)
break;
case Button3:
{
BlitzAlign align = blitz_align_of_rect(&c->rect, ev->x, ev->y);
BlitzAlign align = blitz_quadofcoord(&c->rect, ev->x, ev->y);
if(align != CENTER)
do_mouse_resize(c, align);
else

View File

@ -71,7 +71,7 @@ enum { WMII_IOUNIT = 2048 };
*/
Qid root_qid;
const char *err;
static const char *errstr;
/* IXP stuff */
@ -325,8 +325,8 @@ type_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
return FsDview;
if(!strncmp(name, "sel", 4))
goto dyndir;
i = (unsigned short) cext_strtonum(name, 0, 0xffff, &err);
if(err)
i = (unsigned short) cext_strtonum(name, 0, 0xffff, &errstr);
if(errstr)
return FsLast;
dyndir:
switch(dir_type) {
@ -385,8 +385,8 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
new.path = pack_qpath(FsDarea, p->id, p->area.data[p->sel]->id, 0);
}
else {
i = cext_strtonum(name, 0, 0xffff, &err);
if(err || (i >= p->area.size))
i = cext_strtonum(name, 0, 0xffff, &errstr);
if(errstr || (i >= p->area.size))
return nil;
new.path = pack_qpath(FsDarea, p->id, p->area.data[i]->id, 0);
}
@ -405,8 +405,8 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
new.path = pack_qpath(FsDclient, p->id, a->id, a->frame.data[a->sel]->id);
}
else {
i = cext_strtonum(name, 0, 0xffff, &err);
if(err || (i >= a->frame.size))
i = cext_strtonum(name, 0, 0xffff, &errstr);
if(errstr || (i >= a->frame.size))
return nil;
new.path = pack_qpath(FsDclient, p->id, a->id, a->frame.data[i]->id);
}
@ -415,8 +415,8 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
case FsDGclient:
if(dir_type != FsDclients)
return nil;
i = cext_strtonum(name, 0, 0xffff, &err);
if(err || (i >= client.size))
i = cext_strtonum(name, 0, 0xffff, &errstr);
if(errstr || (i >= client.size))
return nil;
new.path = pack_qpath(FsDGclient, client.data[i]->id, 0, 0);
break;
@ -506,6 +506,7 @@ stat_of_name(Stat *stat, char *name, Qid wqid[IXP_MAX_WELEM], unsigned short qse
unsigned char dir_type, type;
int i1 = 0, i2 = 0, i3 = 0;
char buf[256];
XRectangle fr;
Frame *f;
unpack_qpath(wqid, qsel, &dir_type, &i1, &i2, &i3);
@ -539,16 +540,13 @@ stat_of_name(Stat *stat, char *name, Qid wqid[IXP_MAX_WELEM], unsigned short qse
return pack_stat(stat, wqid, qsel, name, strlen(buf), IXP_DMREAD | IXP_DMWRITE);
break;
case FsFgeom:
if(dir_type == FsDclient) {
f = view.data[i1]->area.data[i2]->frame.data[i3];
snprintf(buf, sizeof(buf), "%d %d %d %d", f->rect.x, f->rect.y,
f->rect.width, f->rect.height);
}
else {
Client *c = client.data[i1];
snprintf(buf, sizeof(buf), "%d %d %d %d", c->rect.x, c->rect.y,
c->rect.width, c->rect.height);
}
if(dir_type == FsDclient)
fr = view.data[i1]->area.data[i2]->frame.data[i3]->rect;
else if(client.data[i1]->frame.size)
fr = client.data[i1]->frame.data[client.data[i1]->sel]->rect;
else
fr = client.data[i1]->rect;
snprintf(buf, sizeof(buf), "%d %d %d %d", fr.x, fr.y, fr.width, fr.height);
return pack_stat(stat, wqid, qsel, name, strlen(buf), IXP_DMREAD | IXP_DMWRITE);
break;
case FsFclass:
@ -812,7 +810,7 @@ xread(IXPConn *c, Fcall *fcall)
unsigned int i, len;
unsigned char dir_type, type, *p = fcall->data;
char buf[256];
Frame *f;
XRectangle fr;
if(!m)
return Enofile;
@ -1121,16 +1119,13 @@ xread(IXPConn *c, Fcall *fcall)
memcpy(p, buf, fcall->count);
break;
case FsFgeom:
if(dir_type == FsDclient) {
f = view.data[i1]->area.data[i2]->frame.data[i3];
snprintf(buf, sizeof(buf), "%d %d %d %d", f->rect.x, f->rect.y,
f->rect.width, f->rect.height);
}
else {
Client *c = client.data[i1];
snprintf(buf, sizeof(buf), "%d %d %d %d", c->rect.x, c->rect.y,
c->rect.width, c->rect.height);
}
if(dir_type == FsDclient)
fr = view.data[i1]->area.data[i2]->frame.data[i3]->rect;
else if(client.data[i1]->frame.size)
fr = client.data[i1]->frame.data[client.data[i1]->sel]->rect;
else
fr = client.data[i1]->rect;
snprintf(buf, sizeof(buf), "%d %d %d %d", fr.x, fr.y, fr.width, fr.height);
fcall->count = strlen(buf);
memcpy(p, buf, fcall->count);
break;
@ -1315,9 +1310,13 @@ xwrite(IXPConn *c, Fcall *fcall)
return Enocommand;
break;
case FsDview:
if(!strncmp(buf, "select ", 7))
if(!strncmp(buf, "select ", 7)) {
if(view.size)
select_area(view.data[i1]->area.data[view.data[i1]->sel], &buf[7]);
select_area(view.data[i1]->area.data[view.data[i1]->sel],
&buf[7]);
}
else
return Enocommand;
break;
case FsDarea:
if(!strncmp(buf, "select ", 7)) {
@ -1325,6 +1324,8 @@ xwrite(IXPConn *c, Fcall *fcall)
if(a->frame.size)
select_client(a->frame.data[a->sel]->client, &buf[7]);
}
else
return Enocommand;
break;
case FsDclient:
f = view.data[i1]->area.data[i2]->frame.data[i3];
@ -1332,12 +1333,20 @@ xwrite(IXPConn *c, Fcall *fcall)
kill_client(f->client);
else if(!strncmp(buf, "newcol ", 7))
newcol_client(f->client, &buf[7]);
else if(!strncmp(buf, "send ", 5))
send_client(f->client, &buf[5]);
else if(!strncmp(buf, "move ", 5))
move_client(f->client, &buf[5]);
else if(!strncmp(buf, "size ", 5))
size_client(f->client, &buf[5]);
else
return Enocommand;
break;
case FsDGclient:
if(!strncmp(buf, "kill", 5))
kill_client(client.data[i1]);
else
return Enocommand;
break;
default:
break;
@ -1348,8 +1357,8 @@ xwrite(IXPConn *c, Fcall *fcall)
return Ebadvalue;
memcpy(buf, fcall->data, fcall->count);
buf[fcall->count] = 0;
i = cext_strtonum(buf, 0, 0xffff, &err);
if(err)
i = cext_strtonum(buf, 0, 0xffff, &errstr);
if(errstr)
return Ebadvalue;
def.border = i;
resize_all_clients();
@ -1370,22 +1379,6 @@ xwrite(IXPConn *c, Fcall *fcall)
update_views();
draw_client(cl);
break;
case FsFgeom:
if(fcall->count > sizeof(buf))
return Ebadvalue;
memcpy(buf, fcall->data, fcall->count);
buf[fcall->count] = 0;
if(dir_type == FsDclient) {
XRectangle new;
f = view.data[i1]->area.data[i2]->frame.data[i3];
new = f->rect;
blitz_strtorect(&rect, &new, buf);
if(i2)
resize_column(f->client, &new, nil);
else
resize_client(f->client, &new, False);
}
break;
case FsFdata:
len = fcall->count;
if(len >= sizeof(bar.data[i1]->data))
@ -1449,6 +1442,26 @@ xwrite(IXPConn *c, Fcall *fcall)
memcpy(def.rules + fcall->offset, fcall->data, fcall->count);
def.rules[fcall->offset + fcall->count] = 0;
break;
case FsFgeom:
if(fcall->count > sizeof(buf))
return Ebadvalue;
memcpy(buf, fcall->data, fcall->count);
buf[fcall->count] = 0;
if(dir_type == FsDclient) {
XRectangle new;
f = view.data[i1]->area.data[i2]->frame.data[i3];
new = f->rect;
blitz_strtorect(&new, buf);
if(new.width == 0)
new.width = rect.width;
if(new.height == 0)
new.height = rect.height;
if(i2)
resize_column(f->client, &new, nil);
else
resize_client(f->client, &new, False);
}
break;
case FsFgrabmod:
{
unsigned long mod;
@ -1471,8 +1484,8 @@ xwrite(IXPConn *c, Fcall *fcall)
return Ebadvalue;
memcpy(buf, fcall->data, fcall->count);
buf[fcall->count] = 0;
i = cext_strtonum(buf, 0, rect.width - MIN_COLWIDTH, &err);
if(err || (i && i < MIN_COLWIDTH))
i = cext_strtonum(buf, 0, rect.width - MIN_COLWIDTH, &errstr);
if(errstr || (i && i < MIN_COLWIDTH))
return Ebadvalue;
def.colw = i;
break;

View File

@ -237,7 +237,9 @@ void focus_client(Client *c, Bool restack);
void focus(Client *c, Bool restack);
void resize_client(Client *c, XRectangle *r, Bool ignore_xcall);
void select_client(Client *c, char *arg);
void send_client(Client *c, char *arg);
void move_client(Client *c, char *arg);
void size_client(Client *c, char *arg);
void newcol_client(Client *c, char *arg);
void resize_all_clients();
Client *sel_client();

View File

@ -65,9 +65,6 @@ void blitz_drawlabel(Display *dpy, BlitzDraw *d);
void blitz_drawborder(Display *dpy, BlitzDraw *d);
/* geometry.c */
BlitzAlign blitz_align_of_rect(XRectangle *rect, int x, int y);
int blitz_strtoalign(BlitzAlign *result, char *val);
int blitz_strtorect(XRectangle *root, XRectangle *r, char *val);
int blitz_strtorect(XRectangle *r, const char *val);
BlitzAlign blitz_quadofcoord(XRectangle *rect, int x, int y);
Bool blitz_ispointinrect(int x, int y, XRectangle *r);
int blitz_distance(XRectangle *origin, XRectangle *target);
void blitz_getbasegeometry(unsigned int size, unsigned int *cols, unsigned int *rows);

View File

@ -4,14 +4,14 @@
*/
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <cext.h>
#include "blitz.h"
BlitzAlign
blitz_align_of_rect(XRectangle *rect, int x, int y)
blitz_quadofcoord(XRectangle *rect, int x, int y)
{
int w = x <= rect->x + rect->width / 2;
int n = y <= rect->y + rect->height / 2;
@ -34,217 +34,23 @@ blitz_align_of_rect(XRectangle *rect, int x, int y)
return CENTER;
}
int blitz_strtoalign(BlitzAlign *result, char *val)
{
/*
* note, resize allows syntax like "east-20", this we cannot do
* include zero termination in strncmp checking!
*/
*result = CENTER;
if (!strncmp(val, "west", 4))
*result = WEST;
else if (!strncmp(val, "nwest", 5))
*result = NWEST;
else if (!strncmp(val, "north", 5))
*result = NORTH;
else if (!strncmp(val, "neast", 5))
*result = NEAST;
else if (!strncmp(val, "east", 4))
*result = EAST;
else if (!strncmp(val, "seast", 5))
*result = SEAST;
else if (!strncmp(val, "south", 5))
*result = SOUTH;
else if (!strncmp(val, "swest", 5))
*result = SWEST;
else if (!strncmp(val, "center", 6))
*result = CENTER;
else
return -1;
return 0;
}
/**
* Basic Syntax: <x> <y> <width> <height>
* Each component can be of following format:
* <...> = [+|-]0..n|<alignment>[[+|-]0..n]
*/
int blitz_strtorect(XRectangle *root, XRectangle *r, char *val)
{
const char *err;
char buf[64];
char *x, *y, *w, *h;
char *p;
int rx, ry, rw, rh, sx, sy, sw, sh;
if (!val)
return -1;
rx = r->x;
ry = r->y;
rw = r->width;
rh = r->height;
sx = sy = sw = sh = 0;
x = y = w = h = 0;
cext_strlcpy(buf, val, sizeof(buf));
x = strtok_r(buf, " ", &p);
if (x) {
y = strtok_r(0, " ", &p);
if (y) {
w = strtok_r(0, " ", &p);
if (w) {
h = strtok_r(0, "", &p);
}
}
}
if (x && (sx = (x[0] >= '0') && (x[0] <= '9')))
rx = cext_strtonum(x, 0, 65535, &err);
if (y && (sy = (y[0] >= '0') && (y[0] <= '9')))
ry = cext_strtonum(y, 0, 65535, &err);
if (w && (sw = (w[0] >= '0') && (w[0] <= '9')))
rw = cext_strtonum(w, 0, 65535, &err);
if (h && (sh = (h[0] >= '0') && (h[0] <= '9')))
rh = cext_strtonum(h, 0, 65535, &err);
if (!sx && !sw && x && w
&& x[0] != '-' && x[0] != '+' && w[0] != '-' && w[0] != '+') {
BlitzAlign ax, aw;
blitz_strtoalign(&ax, x);
blitz_strtoalign(&aw, w);
if ((ax == CENTER) && (aw == EAST)) {
rx = root->x + root->width / 2;
rw = root->width / 2;
} else {
rx = root->x;
if (aw == CENTER) {
rw = root->width / 2;
} else {
rw = root->width;
}
}
} else if (!sx && x && x[0] != '-' && x[0] != '+') {
BlitzAlign ax;
blitz_strtoalign(&ax, x);
if (ax == CENTER) {
rx = root->x + (root->width / 2) - (rw / 2);
} else if (ax == EAST) {
rx = root->x + root->width - rw;
} else {
rx = root->x;
}
} else if (!sw && w && w[0] != '-' && w[0] != '+') {
BlitzAlign aw;
blitz_strtoalign(&aw, w);
if (aw == CENTER) {
rw = (root->width / 2) - rx;
} else {
rw = root->width - rx;
}
}
if (!sy && !sh && y && h
&& y[0] != '-' && y[0] != '+' && h[0] != '-' && h[0] != '+') {
BlitzAlign ay, ah;
blitz_strtoalign(&ay, y);
blitz_strtoalign(&ah, h);
if ((ay == CENTER) && (ah == SOUTH)) {
ry = root->y + root->height / 2;
rh = root->height / 2;
} else {
ry = root->y;
if (ah == CENTER) {
rh = root->height / 2;
} else {
rh = root->height;
}
}
} else if (!sy && y && y[0] != '-' && y[0] != '+') {
BlitzAlign ay;
blitz_strtoalign(&ay, y);
if (ay == CENTER) {
ry = root->y + (root->height / 2) - (rh / 2);
} else if (ay == SOUTH) {
ry = root->y + root->height - rh;
} else {
ry = root->y;
}
} else if (!sh && h && h[0] != '-' && h[0] != '+') {
BlitzAlign ah;
blitz_strtoalign(&ah, h);
if (ah == CENTER) {
rh = (root->height / 2) - ry;
} else {
rh = root->height - ry;
}
}
/* now do final calculations */
if (x) {
p = strchr(x, '-');
if (p)
rx -= cext_strtonum(++p, 0, 65535, &err);
p = strchr(x, '+');
if (p)
rx += cext_strtonum(++p, 0, 65535, &err);
}
if (y) {
p = strchr(y, '-');
if (p)
ry -= cext_strtonum(++p, 0, 65535, &err);
p = strchr(y, '+');
if (p)
ry += cext_strtonum(++p, 0, 65535, &err);
}
if (w) {
p = strchr(w, '-');
if (p)
rw -= cext_strtonum(++p, 0, 65535, &err);
p = strchr(w, '+');
if (p)
rw += cext_strtonum(++p, 0, 65535, &err);
}
if (h) {
p = strchr(h, '-');
if (p)
rh -= cext_strtonum(++p, 0, 65535, &err);
p = strchr(h, '+');
if (p)
rh += cext_strtonum(++p, 0, 65535, &err);
}
if (rw < 1)
rw = 10;
if (rh < 1)
rh = 10;
r->x = rx;
r->y = ry;
r->width = rw;
r->height = rh;
return 0;
}
Bool blitz_ispointinrect(int x, int y, XRectangle * r)
{
return (x >= r->x) && (x <= r->x + r->width) && (y >= r->y) && (y <= r->y + r->height);
return (x >= r->x) && (x <= r->x + r->width)
&& (y >= r->y) && (y <= r->y + r->height);
}
int blitz_distance(XRectangle * origin, XRectangle * target)
/* Syntax: <x> <y> <width> <height> */
int blitz_strtorect(XRectangle *r, const char *val)
{
int ox = origin->x + origin->width / 2;
int oy = origin->y + origin->height / 2;
int tx = target->x + target->width / 2;
int ty = target->y + target->height / 2;
XRectangle new;
if (!val)
return -1;
return (int) sqrt((double) (((ox - tx) * (ox - tx)) + ((oy - ty) * (oy - ty))));
}
void blitz_getbasegeometry(unsigned int size, unsigned int *cols, unsigned int *rows)
{
float sq, dummy;
sq = sqrt(size);
if (modff(sq, &dummy) < 0.5)
*rows = floor(sq);
else
*rows = ceil(sq);
*cols = ((*rows) * (*rows)) < (size) ? *rows + 1 : *rows;
if(sscanf(val, "%hd %hd %hu %hu", &new.x, &new.y, &new.width, &new.height) != 4)
return -1;
*r = new;
return 0;
}

View File

@ -133,7 +133,7 @@ do
$MODKEY-m)
xwrite /tag/sel/sel/mode max;;
$MODKEY-f)
xwrite /tag/sel/0/sel/geom 0 0 east south;;
xwrite /tag/sel/0/sel/geom 0 0 0 0;;
$MODKEY-a)
PATH=$HOME/.wmii-4:CONFPREFIX/wmii-4:$PATH `proglist CONFPREFIX/wmii-4 $HOME/.wmii-4 | wmiimenu` &;;
$MODKEY-p)
@ -145,15 +145,15 @@ do
$MODKEY-Return)
xterm &;;
$MODKEY-Shift-$LEFT)
xwrite /tag/sel/sel/sel/ctl move prev;;
xwrite /tag/sel/sel/sel/ctl send prev;;
$MODKEY-Shift-$RIGHT)
xwrite /tag/sel/sel/sel/ctl move next;;
xwrite /tag/sel/sel/sel/ctl send next;;
$MODKEY-Shift-$DOWN)
xwrite /tag/sel/sel/sel/ctl move down;;
xwrite /tag/sel/sel/sel/ctl send down;;
$MODKEY-Shift-$UP)
xwrite /tag/sel/sel/sel/ctl move up;;
xwrite /tag/sel/sel/sel/ctl send up;;
$MODKEY-Shift-space)
xwrite /tag/sel/sel/sel/ctl move toggle;;
xwrite /tag/sel/sel/sel/ctl send toggle;;
$MODKEY-Shift-c)
xwrite /tag/sel/sel/sel/ctl kill;;
$MODKEY-Shift-t)