wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit 1e4b2bb0614442c66039425f464f339dfea31392
parent ef672bf5fec47dcc997f924ef9cabb930d5b068a
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Fri, 26 May 2006 14:16:19 +0200

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


Diffstat:
TODO.wmii-4 | 4----
cmd/wm/client.c | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cmd/wm/event.c | 2+-
cmd/wm/fs.c | 117++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
cmd/wm/wm.h | 2++
liblitz/blitz.h | 7++-----
liblitz/geometry.c | 218+++++--------------------------------------------------------------------------
rc/wmiirc | 12++++++------
8 files changed, 173 insertions(+), 274 deletions(-)

diff --git a/TODO.wmii-4 b/TODO.wmii-4 @@ -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 diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -604,9 +604,94 @@ 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]; Area *to, *a = f->area; diff --git a/cmd/wm/event.c b/cmd/wm/event.c @@ -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 diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c @@ -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; diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -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(); diff --git a/liblitz/blitz.h b/liblitz/blitz.h @@ -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); diff --git a/liblitz/geometry.c b/liblitz/geometry.c @@ -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) +Bool blitz_ispointinrect(int x, int y, XRectangle * r) { - /* - * 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; + return (x >= r->x) && (x <= r->x + r->width) + && (y >= r->y) && (y <= r->y + r->height); } -/** - * 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; +/* Syntax: <x> <y> <width> <height> */ +int blitz_strtorect(XRectangle *r, const char *val) +{ + XRectangle new; 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(sscanf(val, "%hd %hd %hu %hu", &new.x, &new.y, &new.width, &new.height) != 4) + return -1; - if (rw < 1) - rw = 10; - if (rh < 1) - rh = 10; - r->x = rx; - r->y = ry; - r->width = rw; - r->height = rh; + *r = new; 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); -} - -int blitz_distance(XRectangle * origin, XRectangle * target) -{ - 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; - - 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; -} diff --git a/rc/wmiirc b/rc/wmiirc @@ -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)