commit f72c098ecf1768a06e48d92c9c3e44999e557acb
parent 9945dcce024292aa13903299af587c9a0e4900cf
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Thu, 8 Jun 2006 10:54:19 +0200
merged Kris' changes
Diffstat:
| LICENSE | | | 1 | + |
| cmd/wm/area.c | | | 220 | +++++++++++++++++++++++++++++++++++++++---------------------------------------- |
| cmd/wm/bar.c | | | 124 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
| cmd/wm/client.c | | | 259 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
| cmd/wm/column.c | | | 161 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
| cmd/wm/event.c | | | 30 | +++++++++++++++--------------- |
| cmd/wm/frame.c | | | 93 | ++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------- |
| cmd/wm/fs.c | | | 622 | ++++++++++++++++++++++++++++++++++++++----------------------------------------- |
| cmd/wm/key.c | | | 111 | ++++++++++++++++++++++++++++++++----------------------------------------------- |
| cmd/wm/mouse.c | | | 24 | +++++++++++++----------- |
| cmd/wm/rule.c | | | 24 | +++++++++--------------- |
| cmd/wm/view.c | | | 351 | +++++++++++++++++++++++++++++++++++++------------------------------------------ |
| cmd/wm/wm.c | | | 25 | ++++++++++--------------- |
| cmd/wm/wm.h | | | 129 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
| cmd/wm/wmii | | | 4 | ++-- |
| libcext/Makefile | | | 2 | +- |
| libcext/assert.c | | | 10 | ++++++++++ |
| libcext/cext.h | | | 4 | ++++ |
| libixp/ixp.h | | | 20 | +++++--------------- |
| libixp/server.c | | | 66 | ++++++++++++++++++++++++++++++------------------------------------ |
20 files changed, 1120 insertions(+), 1160 deletions(-)
diff --git a/LICENSE b/LICENSE
@@ -3,6 +3,7 @@ MIT/X Consortium License
(C)opyright MMIII-MMVI Anselm R. Garbe <garbeam at wmii dot de>
(C)opyright MMV-MMVI Georg Neis <gn at wmii dot de>
(C)opyright MMVI Sander van Dijk <sander at wmii dot de>
+(C)opyright MMVI Kris Maglione <bsdaemon at comcast dot net>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
diff --git a/cmd/wm/area.c b/cmd/wm/area.c
@@ -4,35 +4,33 @@
*/
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include "wm.h"
-static Vector *
-vector_of_areas(AreaVector *av)
-{
- return (Vector *) av;
-}
-
Area *
-create_area(View *v, unsigned int pos, unsigned int w)
+create_area(View *v, Area *pos, unsigned int w)
{
static unsigned short id = 1;
- Area *a = nil;
+ unsigned int area_size;
+ Area *a, **p = pos ? &pos->next : &v->area;
+
+ for(area_size = 0, a=v->area; a; a=a->next, area_size++);
if(!w) {
- if(v->area.size > 1)
- w = rect.width / v->area.size - 1;
+ if(area_size > 1)
+ w = rect.width / area_size - 1;
else
w = rect.width;
}
if(w < MIN_COLWIDTH)
w = MIN_COLWIDTH;
- if(v->area.size >= 2 && (v->area.size - 1) * MIN_COLWIDTH + w > rect.width)
+ if(area_size >= 2 && (area_size - 1) * MIN_COLWIDTH + w > rect.width)
return nil;
- if(v->area.size > 1)
+ if(area_size > 1)
scale_view(v, rect.width - w);
a = cext_emallocz(sizeof(Area));
a->view = v;
@@ -41,92 +39,80 @@ create_area(View *v, unsigned int pos, unsigned int w)
a->rect.height = rect.height - brect.height;
a->mode = def.colmode;
a->rect.width = w;
- cext_vattachat(vector_of_areas(&v->area), a, pos);
- v->sel = pos;
+ a->frame = nil;
+ a->sel = nil;
+
+ a->next = *p;
+ *p = a;
+
+ v->sel = a;
return a;
}
void
destroy_area(Area *a)
{
- unsigned int i;
+ Client *c;
+ Area *t;
View *v = a->view;
- if(a->frame.size) {
+ if(a->frame) {
fprintf(stderr, "%s", "wmiiwm: fatal, destroying non-empty area\n");
exit(1);
}
- if(a->frame.data)
- free(a->frame.data);
- if(v->revert == idx_of_area(a))
- v->revert = 0;
- for(i = 0; i < client.size; i++)
- if(client.data[i]->revert == a)
- client.data[i]->revert = 0;
- cext_vdetach(vector_of_areas(&v->area), a);
- if(v->sel > 1)
- v->sel--;
- free(a);
-}
-int
-idx_of_area(Area *a)
-{
- int i;
- View *v = a->view;
- for(i = 0; i < v->area.size; i++)
- if(v->area.data[i] == a)
- return i;
- return -1;
-}
+ if(v->revert == a)
+ v->revert = nil;
-int
-idx_of_area_id(View *v, unsigned short id)
-{
- int i;
- for(i = 0; i < v->area.size; i++)
- if(v->area.data[i]->id == id)
- return i;
- return -1;
+ for(c=client; c; c=c->next)
+ if(c->revert == a)
+ c->revert = nil;
+
+ for(t=v->area; t && t->next != a; t=t->next);
+ if(t) {
+ t->next = a->next;
+ if(v->sel == a)
+ v->sel = t;
+ }
+ free(a);
}
void
select_area(Area *a, char *arg)
{
Area *new;
+ unsigned int i;
View *v = a->view;
- int i = idx_of_area(a);
- if(i == -1)
- return;
- if(i)
- v->revert = i;
+ v->revert = a;
if(!strncmp(arg, "toggle", 7)) {
- if(i)
- i = 0;
- else if(v->revert > 0 && v->revert < v->area.size)
- i = v->revert;
+ if(a != v->area)
+ new = v->area;
+ else if(v->revert && v->revert != v->area)
+ new = v->revert;
else
- i = 1;
+ new = v->area->next;
} else if(!strncmp(arg, "prev", 5)) {
- if(i <= 1)
+ if(a == v->area)
return;
- else
- i--;
+ for(new=v->area->next;
+ new && new->next != a;
+ new=new->next);
+ if(!new)
+ new=v->area->next;
} else if(!strncmp(arg, "next", 5)) {
- if(i > 0 && (i + 1 < v->area.size))
- i++;
- else
+ if(a == v->area)
return;
+ new = a->next ? a->next : a;
}
else {
if(sscanf(arg, "%d", &i) != 1)
return;
+ for(new=view->area; i && new->next; new=new->next, i--);
}
- new = v->area.data[i];
- if(new->frame.size)
- focus_client(new->frame.data[new->sel]->client, True);
- v->sel = i;
+ if(new->sel)
+ focus_client(new->sel->client, True);
+ v->sel = new;
draw_clients();
}
@@ -144,11 +130,12 @@ place_client(Area *a, Client *c)
{
static unsigned int mx, my;
static Bool *field = nil;
+ Frame *fr;
Bool fit = False;
BlitzAlign align = CENTER;
- unsigned int i, j, k, x, y, maxx, maxy, dx, dy, cx, cy, diff, num = 0;
+ unsigned int i, j, x, y, maxx, maxy, dx, dy, cx, cy, diff, num = 0;
XPoint p1 = {0, 0}, p2 = {0, 0};
- Frame *f = c->frame.data[c->sel];
+ Frame *f = c->sel;
int snap = rect.height / 66;
XRectangle *rects;
@@ -173,8 +160,7 @@ place_client(Area *a, Client *c)
dx = rect.width / mx;
dy = rect.height / my;
- for(k = 0; k < a->frame.size; k++) {
- Frame *fr = a->frame.data[k];
+ for(fr=a->frame; fr; fr=fr->anext) {
if(fr == f) {
cx = f->rect.width / dx;
cy = f->rect.height / dy;
@@ -240,27 +226,28 @@ void
attach_to_area(Area *a, Client *c, Bool send)
{
View *v = a->view;
- unsigned int h = 0, aidx = idx_of_area(a);
+ unsigned int h = 0, i;
Frame *f;
+ for(f=a->frame, i=1; f; f=f->anext, i++);
- c->floating = !aidx;
- if(aidx) {
- h = a->rect.height / (a->frame.size + 1);
- if(a->frame.size)
+ c->floating = (a == v->area);
+ if(!c->floating) {
+ h = a->rect.height / i;
+ if(a->frame)
scale_column(a, a->rect.height - h);
}
- if(!send && aidx) { /* column */
+ if(!send && !c->floating) { /* column */
unsigned int w = newcolw_of_view(v);
- if(v->area.data[1]->frame.size && w) {
- a = new_column(v, v->area.size, w);
+ if(v->area->next->frame && w) {
+ a = new_column(v, a, w);
arrange_view(v);
}
}
f = create_frame(a, c);
- if(aidx) { /* column */
+ if(!c->floating) { /* column */
f->rect.height = h;
arrange_column(a, False);
}
@@ -274,56 +261,67 @@ void
detach_from_area(Area *a, Client *c)
{
View *v = a->view;
- int i;
+ Frame *f;
- for(i = 0; i < c->frame.size; i++)
- if(c->frame.data[i]->area == a) {
- destroy_frame(c->frame.data[i]);
- break;
- }
+ for(f=c->frame; f && f->area != a; f=f->cnext);
+ if(f)
+ destroy_frame(f);
- i = idx_of_area(a);
- if(i && a->frame.size)
- arrange_column(a, False);
- else {
- if(i) {
- if(v->area.size > 2)
+ if(a != a->view->area) {
+ if(a->frame)
+ arrange_column(a, False);
+ else {
+ if(v->area->next->next)
destroy_area(a);
- else if(!a->frame.size && v->area.data[0]->frame.size)
- v->sel = 0; /* focus floating area if it contains something */
+ else if(!a->frame && v->area->frame)
+ v->sel = v->area; /* focus floating area if it contains something */
arrange_view(v);
}
- else if(!i && !a->frame.size) {
- if(c->trans) {
- /* focus area of transient, if possible */
- Client *cl = client_of_win(c->trans);
- if(cl && cl->frame.size) {
- a = cl->frame.data[cl->sel]->area;
- if(a->view == v)
- v->sel = idx_of_area(a);
- }
+ }
+ else if(!a->frame) {
+ if(c->trans) {
+ /* focus area of transient, if possible */
+ Client *cl = client_of_win(c->trans);
+ if(cl && cl->frame) {
+ a = cl->sel->area;
+ if(a->view == v)
+ v->sel = a;
}
- else if(v->area.data[1]->frame.size)
- v->sel = 1; /* focus first col as fallback */
}
+ else if(v->area->next->frame)
+ v->sel = v->area->next; /* focus first col as fallback */
}
}
Bool
is_of_area(Area *a, Client *c)
{
- unsigned int i;
- for(i = 0; i < a->frame.size; i++)
- if(a->frame.data[i]->client == c)
+ Frame *f;
+ for(f=a->frame; f; f=f->anext)
+ if(f->client == c)
return True;
return False;
}
+int
+idx_of_area(Area *a)
+{
+ Area *t;
+ int i = 0;
+ for(t=a->view->area; t && t != a; t=t->next, i++);
+ return t ? i : -1;
+}
+
+Area *
+area_of_id(View *v, unsigned short id)
+{
+ Area *a;
+ for(a=v->area; a && a->id != id; a=a->next);
+ return a;
+}
+
Client *
sel_client_of_area(Area *a)
{
- if(a) {
- return (a->frame.size) ? a->frame.data[a->sel]->client : nil;
- }
- return nil;
+ return a && a->sel ? a->sel->client : nil;
}
diff --git a/cmd/wm/bar.c b/cmd/wm/bar.c
@@ -8,43 +8,44 @@
#include "wm.h"
-static int
-comp_bar(const void *b1, const void *b2)
-{
- Bar *bb1 = *(Bar **)b1;
- Bar *bb2 = *(Bar **)b2;
- return strcmp(bb1->name, bb2->name);
-}
-
-static Vector *
-vector_of_bars(BarVector *bv)
-{
- return (Vector *) bv;
-}
+Bar *free_bars = nil;
Bar *
-create_bar(char *name, Bool intern)
+create_bar(char *name)
{
static unsigned int id = 1;
- Bar *b = bar_of_name(name);
-
+ Bar **i, *b = bar_of_name(name);;
if(b)
return b;
- b = cext_emallocz(sizeof(Bar));
+
+ if(free_bars) {
+ b = free_bars;
+ free_bars = b->next;
+ }
+ else
+ b = cext_emallocz(sizeof(Bar));
+
b->id = id++;
cext_strlcpy(b->name, name, sizeof(b->name));
- cext_strlcpy(b->colstr, def.selcolor, sizeof(b->colstr));
+ cext_strlcpy(b->colstr, def.normcolor, sizeof(b->colstr));
b->color = def.norm;
- cext_vattach(vector_of_bars(&bar), b);
- qsort(bar.data, bar.size, sizeof(Bar *), comp_bar);
+
+ for(i=&bar; *i && (strcmp((*i)->name, name) < 0); i=&(*i)->next);
+ b->next = *i;
+ *i = b;
+
return b;
}
void
destroy_bar(Bar *b)
{
- cext_vdetach(vector_of_bars(&bar), b);
- free(b);
+ Bar **i;
+ for(i=&bar; *i && *i != b; i=&(*i)->next);
+ *i = b->next;
+
+ b->next = free_bars;
+ free_bars = b;
}
unsigned int
@@ -57,7 +58,10 @@ height_of_bar()
void
resize_bar()
{
- unsigned int i, j;
+ View *v;
+ Area *a;
+ Frame *f;
+
brect = rect;
brect.height = height_of_bar();
brect.y = rect.height - brect.height;
@@ -68,14 +72,13 @@ resize_bar()
DefaultDepth(dpy, screen));
XSync(dpy, False);
draw_bar();
- for(i = 0; i < view.size; i++) {
- for(j = 1; j < view.data[i]->area.size; j++) {
- Area *a = view.data[i]->area.data[j];
+
+ for(v=view; v; v=v->next) {
+ for(a = v->area; a; a=a->next) {
a->rect.height = rect.height - brect.height;
arrange_column(a, False);
}
- for(j = 0; j < view.data[i]->area.data[0]->frame.size; j++) {
- Frame *f = view.data[i]->area.data[0]->frame.data[j];
+ for(f=v->area->frame; f; f=f->anext) {
resize_client(f->client, &f->rect, False);
}
}
@@ -84,7 +87,8 @@ resize_bar()
void
draw_bar()
{
- unsigned int i = 0, w = 0;
+ unsigned int i = 0, w = 0, size = 0;
+ Bar *exp = nil;
BlitzDraw d = { 0 };
Bar *b = nil;
@@ -98,11 +102,10 @@ draw_bar()
blitz_drawlabel(dpy, &d);
blitz_drawborder(dpy, &d);
- if(!bar.size)
+ if(!bar)
goto MapBar;
- for(i = 0; (i < bar.size) && (w < brect.width); i++) {
- b = bar.data[i];
+ for(b=bar; b && (w < brect.width); b=b->next, size++) {
b->rect.x = 0;
b->rect.y = 0;
b->rect.width = brect.height;
@@ -112,26 +115,27 @@ draw_bar()
w += b->rect.width;
}
- if(i != bar.size) { /* give all bars same width */
- w = brect.width / bar.size;
- for(i = 0; i < bar.size; i++) {
- b = bar.data[i];
+ if(b) { /* give all bars same width */
+ for(; b; b=b->next, size++);
+ w = brect.width / size;
+ for(b=bar; b; b=b->next) {
b->rect.x = i * w;
b->rect.width = w;
}
}
else { /* expand bar properly */
- bar.data[bar.size - 1]->rect.width += (brect.width - w);
- for(i = 1; i < bar.size; i++)
- bar.data[i]->rect.x = bar.data[i - 1]->rect.x + bar.data[i - 1]->rect.width;
+ for(exp = bar; exp && exp->next; exp=exp->next);
+ if(exp)
+ exp->rect.width += (brect.width - w);
+ for(b=bar; b->next; b=b->next)
+ b->next->rect.x = b->rect.x + b->rect.width;
}
- for(i = 0; i < bar.size; i++) {
- b = bar.data[i];
+ for(b=bar; b; b=b->next) {
d.color = b->color;
d.rect = b->rect;
d.data = b->data;
- if(i == bar.size - 1)
+ if(b == exp)
d.align = EAST;
else
d.align = CENTER;
@@ -143,35 +147,21 @@ MapBar:
XSync(dpy, False);
}
-int
-idx_of_bar(Bar *b)
-{
- int i;
- for(i = 0; i < bar.size; i++)
- if(bar.data[i] == b)
- return i;
- return -1;
-}
-
-int
-idx_of_bar_id(unsigned short id)
-{
- int i;
- for(i = 0; i < bar.size; i++)
- if(bar.data[i]->id == id)
- return i;
- return -1;
-}
-
Bar *
bar_of_name(const char *name)
{
static char buf[256];
- unsigned int i;
+ Bar *b;
cext_strlcpy(buf, name, sizeof(buf));
- for(i = 0; i < bar.size; i++)
- if(!strncmp(bar.data[i]->name, name, sizeof(bar.data[i]->name)))
- return bar.data[i];
- return nil;
+ for(b=bar; b && strncmp(b->name, name, sizeof(b->name)); b=b->next);
+ return b;
+}
+
+Bar *
+bar_of_id(unsigned short id)
+{
+ Bar *b;
+ for(b=bar; b && b->id != id; b=b->next);
+ return b;
}
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -11,12 +11,6 @@
#define CLIENT_MASK (StructureNotifyMask | PropertyChangeMask | EnterWindowMask)
-static Vector *
-vector_of_clients(ClientVector *cv)
-{
- return (Vector *) cv;
-}
-
static void
update_client_name(Client *c)
{
@@ -58,9 +52,10 @@ update_client_name(Client *c)
Client *
create_client(Window w, XWindowAttributes *wa)
{
- Client *c = (Client *) cext_emallocz(sizeof(Client));
+ Client **t, *c = (Client *) cext_emallocz(sizeof(Client));
XSetWindowAttributes fwa;
long msize;
+ unsigned int i;
static unsigned int id = 1;
static char buf[256];
@@ -97,8 +92,12 @@ create_client(Window w, XWindowAttributes *wa)
CWOverrideRedirect | CWBackPixmap | CWEventMask, &fwa);
c->gc = XCreateGC(dpy, c->framewin, 0, 0);
XSync(dpy, False);
- cext_vattach(vector_of_clients(&client), c);
- snprintf(buf, sizeof(buf), "CreateClient %d\n", client.size - 1);
+
+ for(t=&client, i=0; *t; t=&(*t)->next, i++);
+ c->next = *t; /* *t == nil */
+ *t = c;
+
+ snprintf(buf, sizeof(buf), "CreateClient %d\n", i);
write_event(buf);
return c;
}
@@ -130,15 +129,14 @@ void
focus_client(Client *c, Bool restack)
{
Client *old = sel_client();
- Frame *f = c->frame.data[c->sel];
+ Frame *f = c->sel;
Client *old_in_area = sel_client_of_area(f->area);
View *v = f->area->view;
- int i = idx_of_area(f->area);
static char buf[256];
- v->sel = i;
- f->area->sel = idx_of_frame(f);
- c->floating = !i;
+ v->sel = f->area;
+ f->area->sel = f;
+ c->floating = (f->area == v->area);
if(restack)
restack_view(v);
else {
@@ -147,7 +145,7 @@ focus_client(Client *c, Bool restack)
update_client_grab(c, True);
}
- if(i > 0 && f->area->mode == Colstack)
+ if(!c->floating && f->area->mode == Colstack)
arrange_column(f->area, False);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
if(old && old != old_in_area && old != c)
@@ -156,7 +154,7 @@ focus_client(Client *c, Bool restack)
draw_client(old_in_area);
draw_client(c);
XSync(dpy, False);
- snprintf(buf, sizeof(buf), "ClientFocus %d\n", idx_of_client_id(c->id));
+ snprintf(buf, sizeof(buf), "ClientFocus %d\n", idx_of_client(c));
write_event(buf);
}
@@ -190,7 +188,7 @@ void
configure_client(Client *c)
{
XConfigureEvent e;
- Frame *f = c->frame.data[c->sel];
+ Frame *f = c->sel;
e.type = ConfigureNotify;
e.event = c->win;
e.window = c->win;
@@ -263,7 +261,7 @@ prop_client(Client *c, XPropertyEvent *e)
}
if(e->atom == XA_WM_NAME || e->atom == net_atom[NetWMName]) {
update_client_name(c);
- if(c->frame.size)
+ if(c->frame)
draw_client(c);
}
}
@@ -272,16 +270,18 @@ void
draw_client(Client *c)
{
BlitzDraw d = { 0 };
- Frame *f;
+ Frame *f, *t;
char buf[256];
int fidx;
- unsigned int w;
+ unsigned int w, size;
- if(!c->frame.size)
+ if(!c->frame)
return; /* might not have been attached atm */
- f = c->frame.data[c->sel];
- fidx = idx_of_frame(f);
+ f = c->sel;
+ for(fidx=0, t=f->area->frame; t && t != f; t=t->anext, fidx++);
+ for(size=fidx; t; t=t->anext, size++);
+
d.drawable = c->framewin;
d.font = blitzfont;
d.gc = c->gc;
@@ -307,15 +307,15 @@ draw_client(Client *c)
/* mode bar */
d.align = CENTER;
snprintf(buf, sizeof(buf), "%s%d/%d",
- /* if */ !idx_of_area(f->area) ? "~" : "",
- fidx + 1, f->area->frame.size);
+ /* if */ (f->area == f->area->view->area) ? "~" : "",
+ fidx + 1, size);
w = d.rect.width = d.rect.height + blitz_textwidth(dpy, &blitzfont, buf);
if(w > f->rect.width)
return;
d.rect.x = f->rect.width - d.rect.width;
d.data = buf;
- if(f->area->sel == fidx)
+ if(f->area->sel == f)
d.color = def.sel;
else
d.color = def.norm;
@@ -428,7 +428,7 @@ manage_client(Client *c)
map_client(c);
XMapWindow(dpy, c->framewin);
XSync(dpy, False);
- if(c->frame.data[c->sel]->area->view == view.data[sel])
+ if(c->sel->area->view == sel)
focus_client(c, False);
flush_masked_events(EnterWindowMask);
}
@@ -442,25 +442,32 @@ dummy_error_handler(Display *dpy, XErrorEvent *error)
void
destroy_client(Client *c)
{
- unsigned int i;
+ View *v;
+ Client *tc;
XGrabServer(dpy);
XSetErrorHandler(dummy_error_handler);
- if(c->frame.size) {
- c->rect.x = c->frame.data[c->sel]->rect.x;
- c->rect.y = c->frame.data[c->sel]->rect.y;
+ if(c->frame) {
+ c->rect.x = c->sel->rect.x;
+ c->rect.y = c->sel->rect.y;
}
- for(i = 0; i < view.size; i++)
- detach_from_view(view.data[i], c);
+ for(v=view; v; v=v->next)
+ detach_from_view(v, c);
unmap_client(c);
reparent_client(c, root, c->rect.x, c->rect.y);
XFreeGC(dpy, c->gc);
XDestroyWindow(dpy, c->framewin);
- cext_vdetach(vector_of_clients(&client), c);
+ if(c==client)
+ client = c->next;
+ else {
+ for(tc=client; tc && tc->next != c; tc=tc->next);
+ if(tc)
+ tc->next = c->next;
+ }
update_views();
free(c);
@@ -473,18 +480,18 @@ destroy_client(Client *c)
Client *
sel_client()
{
- return view.size ? sel_client_of_view(view.data[sel]) : nil;
+ return sel && sel->sel->sel ? sel->sel->sel->client : nil;
}
void
-match_sizehints(Client *c, XRectangle *r, int aidx, BlitzAlign sticky)
+match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky)
{
XSizeHints *s = &c->size;
unsigned int dx = 2 * def.border;
unsigned int dy = def.border + height_of_bar();
unsigned int hdiff, wdiff;
- if(!aidx && (s->flags & PMinSize)) {
+ if(floating && (s->flags & PMinSize)) {
if(r->width < s->min_width + dx) {
wdiff = (s->min_width + dx) - r->width;
r->width += wdiff;
@@ -498,7 +505,7 @@ match_sizehints(Client *c, XRectangle *r, int aidx, BlitzAlign sticky)
r->y -= hdiff;
}
}
- if(!aidx && (s->flags & PMaxSize)) {
+ if(floating && (s->flags & PMaxSize)) {
if(r->width > s->max_width + dx) {
wdiff = r->width - (s->max_width + dx);
r->width -= wdiff;
@@ -546,9 +553,8 @@ match_sizehints(Client *c, XRectangle *r, int aidx, BlitzAlign sticky)
void
resize_client(Client *c, XRectangle *r, Bool ignore_xcall)
{
- Frame *f = c->frame.data[c->sel];
- int fidx = idx_of_frame(f);
- int aidx = idx_of_area(f->area);
+ Frame *f = c->sel;
+ Bool floating = (f->area == f->area->view->area);
BlitzAlign stickycorner = 0;;
if(f->rect.x != r->x && f->rect.x + f->rect.width == r->x + r->width)
stickycorner |= EAST;
@@ -560,18 +566,18 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall)
stickycorner |= NORTH;
f->rect = *r;
- if((f->area->mode != Colstack) || (f->area->sel == fidx))
- match_sizehints(c, &c->frame.data[c->sel]->rect, aidx, stickycorner);
+ if((f->area->mode != Colstack) || (f->area->sel == f))
+ match_sizehints(c, &c->sel->rect, floating, stickycorner);
if(!ignore_xcall) {
- if(!aidx &&
+ if(floating &&
(c->rect.width >= rect.width) &&
(c->rect.height >= rect.height))
{
f->rect.x = -def.border;
f->rect.y = -height_of_bar();
}
- if(f->area->view == view.data[sel])
+ if(f->area->view == sel)
XMoveResizeWindow(dpy, c->framewin, f->rect.x,
f->rect.y, f->rect.width, f->rect.height);
else
@@ -581,7 +587,7 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall)
c->rect.x = def.border;
c->rect.y = height_of_bar();
- if((f->area->sel == fidx) || (f->area->mode != Colstack)) {
+ if((f->area->sel == f) || (f->area->mode != Colstack)) {
c->rect.width = f->rect.width - 2 * def.border;
c->rect.height = f->rect.height - def.border - height_of_bar();
}
@@ -593,47 +599,42 @@ resize_client(Client *c, XRectangle *r, Bool ignore_xcall)
void
select_client(Client *c, char *arg)
{
- Frame *f = c->frame.data[c->sel];
+ unsigned int i;
+ Frame *f = c->sel, *r;
Area *a = f->area;
- int i = idx_of_frame(f);
- if(i == -1)
- return;
- if(!strncmp(arg, "prev", 5)) {
- if(!i)
- i = a->frame.size - 1;
- else
- i--;
- } else if(!strncmp(arg, "next", 5)) {
- if(i + 1 < a->frame.size)
- i++;
- else
- i = 0;
- }
+
+ if(!strncmp(arg, "prev", 5))
+ for(r=a->frame; r->anext && r->anext != f; r=r->anext);
+ else if(!strncmp(arg, "next", 5))
+ r = f->anext ? f->anext : a->frame;
else {
if(sscanf(arg, "%d", &i) != 1)
return;
+ for(r=a->frame; i && r->anext; r=r->anext, i--);
}
- focus_client(a->frame.data[i]->client, True);
+ focus_client(r->client, True);
flush_masked_events(EnterWindowMask);
}
void
newcol_client(Client *c, char *arg)
{
- Frame *f = c->frame.data[c->sel];
+ Frame *f = c->sel;
Area *to, *a = f->area;
View *v = a->view;
- int i = idx_of_area(a);
- if(i < 1)
+ if(a == v->area)
+ return;
+ if(!f->anext && f == a->frame)
return;
if(!strncmp(arg, "prev", 5)) {
- to = new_column(v, i, 0);
+ for(to=v->area; to && to->next != a; to=to->next);
+ to = new_column(v, to, 0);
send_to_area(to, a, c);
}
else if(!strncmp(arg, "next", 5)) {
- to = new_column(v, i + 1, 0);
+ to = new_column(v, a, 0);
send_to_area(to, a, c);
}
else
@@ -644,7 +645,7 @@ newcol_client(Client *c, char *arg)
void
move_client(Client *c, char *arg)
{
- Frame *f = c->frame.data[c->sel];
+ Frame *f = c->sel;
XRectangle new = f->rect;
int x, y;
@@ -661,7 +662,7 @@ move_client(Client *c, char *arg)
void
size_client(Client *c, char *arg)
{
- Frame *f = c->frame.data[c->sel];
+ Frame *f = c->sel;
XRectangle new = f->rect;
int w, h;
@@ -669,7 +670,7 @@ size_client(Client *c, char *arg)
return;
new.width += w;
new.height += h;
- if(idx_of_area(f->area))
+ if(f->area != f->area->view->area)
resize_column(f->client, &new, nil);
else
resize_client(f->client, &new, False);
@@ -678,7 +679,7 @@ size_client(Client *c, char *arg)
void
send_client(Client *c, char *arg)
{
- Frame *f = c->frame.data[c->sel];
+ Frame *f = c->sel, *tf;
Area *to, *a = f->area;
View *v = a->view;
int i = idx_of_area(a), j = idx_of_frame(f);
@@ -687,56 +688,54 @@ send_client(Client *c, char *arg)
return;
if(i && !strncmp(arg, "prev", 5)) {
- if(i > 1)
- to = v->area.data[i - 1];
- else if(a->frame.size > 1)
- to = new_column(v, 1, 0);
- else
+ if(a == v->area)
+ return;
+ for(to=v->area->next; to && a != to->next; to=to->next);
+ if(!to && (f->anext || f != a->frame))
+ to=new_column(v, v->area, 0);
+ if(!to)
return;
send_to_area(to, a, c);
}
else if(i && !strncmp(arg, "next", 5)) {
- if(i < v->area.size - 1)
- to = v->area.data[i + 1];
- else if(a->frame.size > 1)
- to = new_column(v, v->area.size, 0);
- else
+ if(a == v->area)
+ return;
+ if(!(to = a->next) && (f->anext || f!= a->frame))
+ to = new_column(v, a, 0);
+ if(!to)
return;
send_to_area(to, a, c);
}
else if(!strncmp(arg, "toggle", 7)) {
- if(i)
- to = v->area.data[0];
- else if(c->revert && c->revert != v->area.data[0])
+ if(a != v->area)
+ to = v->area;
+ else if(c->revert && c->revert != v->area)
to = c->revert;
else
- to = v->area.data[1];
+ to = v->area->next;
send_to_area(to, a, c);
}
else if(i && !strncmp(arg, "up", 3)) {
- if(j)
- i = j - 1;
- else
+ for(tf=a->frame; tf && tf->anext != f; tf=tf->anext);
+ if(!tf)
return;
- a->frame.data[j] = a->frame.data[i];
- a->frame.data[i] = f;
+ remove_frame(f);
+ insert_frame(tf, f, True);
arrange_column(a, False);
focus_client(c, True);
}
else if(i && !strncmp(arg, "down", 5)) {
- if(j + 1 < a->frame.size)
- i = j + 1;
- else
+ if(!f->anext)
return;
- a->frame.data[j] = a->frame.data[i];
- a->frame.data[i] = f;
+ remove_frame(f);
+ insert_frame(f->anext, f, False);
arrange_column(a, False);
focus_client(c, True);
}
else if(i) {
if(sscanf(arg, "%d", &j) != 1)
return;
- to = v->area.data[j];
+ for(to=v->area; to && j; to=to->next, j--);
send_to_area(to, a, c);
}
else
@@ -747,14 +746,13 @@ send_client(Client *c, char *arg)
void
resize_all_clients()
{
- unsigned int i;
- for(i = 0; i < client.size; i++) {
- Client *c = client.data[i];
- if(c->frame.size && c->frame.data[c->sel]->area) {
- if(idx_of_area(c->frame.data[c->sel]->area))
- resize_column(c, &c->frame.data[c->sel]->rect, nil);
+ Client *c;
+ for(c = client; c; c=c->next) {
+ if(c->frame && c->sel->area) {
+ if(idx_of_area(c->sel->area))
+ resize_column(c, &c->sel->rect, nil);
else
- resize_client(c, &c->frame.data[c->sel]->rect, False);
+ resize_client(c, &c->sel->rect, False);
}
}
flush_masked_events(EnterWindowMask);
@@ -764,48 +762,57 @@ resize_all_clients()
void
focus(Client *c, Bool restack)
{
- Frame *f = c->frame.size ? c->frame.data[c->sel] : nil;
+ Frame *f = c->sel;
View *v;
if(!f)
return;
v = f->area->view;
- if(view.data[sel] != v)
+ if(sel != v)
focus_view(v);
focus_client(c, restack);
}
+Client *
+client_of_id(unsigned short id)
+{
+ Client *c;
+ for(c=client; c && c->id != id; c=c->next);
+ return c;
+}
+
int
-idx_of_client_id(unsigned short id)
+idx_of_client(Client *c)
{
- int i;
- for(i = 0; i < client.size; i++)
- if(client.data[i]->id == id)
- return i;
- return -1;
+ Client *cl;
+ int i = 0;
+ for(cl=client; cl && cl != c; cl=cl->next, i++);
+ return cl ? i : -1;
}
Client *
client_of_win(Window w)
{
- unsigned int i;
+ Client *c;
- for(i = 0; (i < client.size) && client.data[i]; i++)
- if(client.data[i]->win == w)
- return client.data[i];
- return nil;
+ for(c=client; c && c->win != w; c=c->next);
+ return c;
+}
+
+Client *
+selected_client()
+{
+ return sel && sel->sel->sel ? sel->sel->sel->client : nil;
}
void
draw_clients()
{
- unsigned int i;
- for(i = 0; i < client.size; i++) {
- Client *c = client.data[i];
- if(c->frame.size && (c->frame.data[c->sel]->area->view == view.data[sel]))
+ Client *c;
+ for(c=client; c; c=c->next)
+ if(c->sel && (c->sel->area->view == sel))
draw_client(c);
- }
}
static Bool
@@ -834,8 +841,8 @@ apply_tags(Client *c, const char *tags)
if(!strncmp(toks[i], "~", 2))
c->floating = True;
else if(!strncmp(toks[i], "!", 2)) {
- if(view.size)
- apply[j++] = view.data[sel]->name;
+ if(view)
+ apply[j++] = sel->name;
else
apply[j++] = "nil";
}
@@ -857,15 +864,13 @@ apply_tags(Client *c, const char *tags)
static void
match_tags(Client *c, const char *prop)
{
- unsigned int i;
+ Rule *r;
regmatch_t tmpregm;
- for(i = 0; i < trule.size; i++) {
- Rule *r = trule.data[i];
+ for(r=trule; r; r=r->next)
if(!regexec(&r->regex, prop, 1, &tmpregm, 0))
if(!strlen(c->tags) || !strncmp(c->tags, "nil", 4))
apply_tags(c, r->value);
- }
}
void
diff --git a/cmd/wm/column.c b/cmd/wm/column.c
@@ -35,22 +35,24 @@ column_mode_of_str(char *arg)
static void
relax_column(Area *a)
{
- unsigned int i, yoff, h;
+ unsigned int frame_size, yoff, h;
+ Frame *f;
int hdiff;
Bool fallthrough = False;
- if(!a->frame.size)
+ if(!a->frame)
return;
+ for(f=a->frame, frame_size=0; f; f=f->anext, frame_size++);
+
switch(a->mode) {
case Coldefault:
- h = a->rect.height;
- h /= a->frame.size;
+ h = a->rect.height / frame_size;
if(h < 2 * height_of_bar())
fallthrough = True;
break;
case Colstack:
- h = a->rect.height - (a->frame.size - 1) * height_of_bar();
+ h = a->rect.height - frame_size * height_of_bar();
if(h < 3 * height_of_bar())
fallthrough = True;
default:
@@ -59,8 +61,7 @@ relax_column(Area *a)
}
if(fallthrough) {
- for(i = 0; i < a->frame.size; i++) {
- Frame *f = a->frame.data[i];
+ for(f=a->frame; f; f=f->anext) {
f->rect.x = a->rect.x + (a->rect.width - f->rect.width) / 2;
f->rect.y = a->rect.y + (a->rect.height - f->rect.height) / 2;
resize_client(f->client, &f->rect, False);
@@ -70,8 +71,7 @@ relax_column(Area *a)
/* some relaxing from potential increment gaps */
h = 0;
- for(i = 0; i < a->frame.size; i++) {
- Frame *f = a->frame.data[i];
+ for(f=a->frame; f; f=f->anext) {
if(a->mode == Colmax) {
if(h < f->rect.height)
h = f->rect.height;
@@ -84,8 +84,7 @@ relax_column(Area *a)
if((a->mode == Coldefault) && (hdiff > 0)) {
int hx;
for(hx = 1; hx < hdiff; hx++)
- for(i = 0; (hx < hdiff) && (i < a->frame.size); i++) {
- Frame *f = a->frame.data[i];
+ for(f=a->frame; f && (hx < hdiff); f=f->anext) {
unsigned int tmp = f->rect.height;
f->rect.height += hx;
resize_client(f->client, &f->rect, True);
@@ -95,10 +94,9 @@ relax_column(Area *a)
if(hdiff < 0)
hdiff = 0;
- hdiff /= a->frame.size;
+ hdiff /= frame_size;
yoff = a->rect.y + hdiff / 2;
- for(i = 0; i < a->frame.size; i++) {
- Frame *f = a->frame.data[i];
+ for(f=a->frame; f; f=f->anext) {
f->rect.x = a->rect.x + (a->rect.width - f->rect.width) / 2;
f->rect.y = yoff;
if(a->mode != Colmax)
@@ -110,37 +108,37 @@ relax_column(Area *a)
void
scale_column(Area *a, float h)
{
- unsigned int i, yoff;
+ unsigned int yoff, frame_size = 0;
+ Frame *f;
unsigned int min_height = 2 * height_of_bar();
float scale, dy = 0;
int hdiff;
- if(!a->frame.size)
+ if(!a->frame)
return;
- for(i = 0; i < a->frame.size; i++)
- dy += a->frame.data[i]->rect.height;
+ for(f=a->frame; f; f=f->anext, frame_size++)
+ dy += f->rect.height;
+
scale = h / dy;
yoff = 0;
- for(i = 0; i < a->frame.size; i++) {
- Frame *f = a->frame.data[i];
+ for(f=a->frame; f; f=f->anext) {
f->rect.height *= scale;
- if(i == a->frame.size - 1)
+ if(!f->anext)
f->rect.height = h - yoff;
yoff += f->rect.height;
}
/* min_height can only be respected when there is enough space; the caller should guarantee this */
- if(a->frame.size * min_height > h)
+ if(frame_size * min_height > h)
return;
yoff = 0;
- for(i = 0; i < a->frame.size; i++) {
- Frame *f = a->frame.data[i];
+ for(f=a->frame; f; f=f->anext, frame_size--) {
if(f->rect.height < min_height)
f->rect.height = min_height;
- else if((hdiff = yoff + f->rect.height - h + (a->frame.size - i) * min_height) > 0)
+ else if((hdiff = yoff + f->rect.height - h + frame_size * min_height) > 0)
f->rect.height -= hdiff;
- if(i == a->frame.size - 1)
+ if(!f->anext)
f->rect.height = h - yoff;
yoff += f->rect.height;
}
@@ -149,24 +147,26 @@ scale_column(Area *a, float h)
void
arrange_column(Area *a, Bool dirty)
{
- unsigned int i, yoff = a->rect.y, h;
+ unsigned int num_frames = 0, yoff = a->rect.y, h;
+ Frame *f;
unsigned int min_height = 2 * height_of_bar();
- if(!a->frame.size)
+ if(!a->frame)
return;
+ for(f=a->frame; f; f=f->anext, num_frames++);
+
switch(a->mode) {
case Coldefault:
- h = a->rect.height / a->frame.size;
+ h = a->rect.height / num_frames;
if(h < min_height)
goto Fallthrough;
if(dirty) {
- for(i = 0; i < a->frame.size; i++)
- a->frame.data[i]->rect.height = h;
+ for(f=a->frame; f; f=f->anext)
+ f->rect.height = h;
}
scale_column(a, a->rect.height);
- for(i = 0; i < a->frame.size; i++) {
- Frame *f = a->frame.data[i];
+ for(f=a->frame; f; f=f->anext) {
f->rect.x = a->rect.x;
f->rect.y = yoff;
f->rect.width = a->rect.width;
@@ -175,14 +175,13 @@ arrange_column(Area *a, Bool dirty)
}
break;
case Colstack:
- h = a->rect.height - (a->frame.size - 1) * height_of_bar();
+ h = a->rect.height - num_frames * height_of_bar();
if(h < 3 * height_of_bar())
goto Fallthrough;
- for(i = 0; i < a->frame.size; i++) {
- Frame *f = a->frame.data[i];
+ for(f=a->frame; f; f=f->anext) {
f->rect = a->rect;
f->rect.y = yoff;
- if(i == a->sel)
+ if(f == a->sel)
f->rect.height = h;
else
f->rect.height = height_of_bar();
@@ -192,8 +191,7 @@ arrange_column(Area *a, Bool dirty)
break;
Fallthrough:
case Colmax:
- for(i = 0; i < a->frame.size; i++) {
- Frame *f = a->frame.data[i];
+ for(f=a->frame; f; f=f->anext) {
f->rect = a->rect;
resize_client(f->client, &f->rect, True);
}
@@ -209,10 +207,9 @@ Fallthrough:
static void
match_horiz(Area *a, XRectangle *r)
{
- unsigned int i;
+ Frame *f;
- for(i = 0; i < a->frame.size; i++) {
- Frame *f = a->frame.data[i];
+ for(f=a->frame; f; f=f->anext) {
f->rect.x = r->x;
f->rect.width = r->width;
resize_client(f->client, &f->rect, False);
@@ -226,17 +223,14 @@ drop_resize(Frame *f, XRectangle *new)
Area *west = nil, *east = nil, *a = f->area;
View *v = a->view;
Frame *north = nil, *south = nil;
- unsigned int i;
unsigned int min_height = 2 * height_of_bar();
- for(i = 1; (i < v->area.size) && (v->area.data[i] != a); i++);
+ for(west=v->area->next; west && west->next != a; west=west->next);
/* first managed area is indexed 1, thus (i > 1) ? ... */
- west = (i > 1) ? v->area.data[i - 1] : nil;
- east = i + 1 < v->area.size ? v->area.data[i + 1] : nil;
+ east = (west && west->next && west->next->next) ? west->next->next : nil;
- for(i = 0; (i < a->frame.size) && (a->frame.data[i] != f); i++);
- north = i ? a->frame.data[i - 1] : nil;
- south = i + 1 < a->frame.size ? a->frame.data[i + 1] : nil;
+ for(north=a->frame; north && north->anext != f; north=north->anext);
+ south = (north && north->anext && north->anext->anext) ? north->anext->anext : nil;
/* validate (and trim if necessary) horizontal resize */
if(new->width < MIN_COLWIDTH) {
@@ -329,22 +323,18 @@ AfterVertical:
static Frame *
frame_of_point(XPoint *pt)
{
- unsigned int i, j;
Frame *f = nil;
- View *v = view.size ? view.data[sel] : nil;
+ Area *a;
+ View *v = sel;
if(!v)
return nil;
- for(i = 1; (i < v->area.size) &&
- !blitz_ispointinrect(pt->x, pt->y, &v->area.data[i]->rect); i++);
- if(i < v->area.size) {
- Area *a = v->area.data[i];
- for(j = 0; j < a->frame.size &&
- !blitz_ispointinrect(pt->x, pt->y, &a->frame.data[j]->rect); j++);
- if(j < a->frame.size)
- f = a->frame.data[j];
- }
+ for(a=v->area->next; a && !blitz_ispointinrect(pt->x, pt->y, &a->rect);
+ a=a->next);
+ if(a)
+ for(f=a->frame; f && !blitz_ispointinrect(pt->x, pt->y, &f->rect);
+ f=f->anext);
return f;
}
@@ -353,60 +343,57 @@ drop_move(Frame *f, XRectangle *new, XPoint *pt)
{
Area *tgt = nil, *src = f->area;
View *v = src->view;
- unsigned int i;
- int fidx;
- Frame *ft;
+ Frame *ft, *tf;
if(!pt)
return;
- for(i = 1; (i < v->area.size) &&
- !blitz_ispointinrect(pt->x, pt->y, &v->area.data[i]->rect); i++);
- if(i < v->area.size) {
+ for(tgt=v->area->next; tgt && !blitz_ispointinrect(pt->x, pt->y, &tgt->rect);
+ tgt=tgt->next);
+ if(tgt) {
if(pt->x <= 5) {
- if(src->frame.size > 1 || idx_of_area(src) != 1) {
- tgt = new_column(v, 1, 0);
+ if((src->frame && src->frame->anext) || (src != v->area->next)) {
+ tgt = new_column(v, v->area->next, 0);
send_to_area(tgt, src, f->client);
}
}
else if(pt->x >= rect.width - 5) {
- if(src->frame.size > 1 || idx_of_area(src) != v->area.size - 1) {
- tgt = new_column(v, v->area.size, 0);
+ if((src->frame && src->frame->anext) || src->next) {
+ for(tgt=src; tgt->next; tgt=tgt->next);
+ tgt = new_column(v, tgt, 0);
send_to_area(tgt, src, f->client);
}
}
- else if(src != (tgt = v->area.data[i])) {
+ else if(src != tgt) {
Client *c = f->client;
Bool before;
if(!(ft = frame_of_point(pt)) || (f == ft))
return;
- fidx = idx_of_frame(ft);
before = pt->y < (ft->rect.y + ft->rect.height / 2);
send_to_area(tgt, src, c);
- f = c->frame.data[c->sel];
- cext_vdetach(vector_of_frames(&tgt->frame), f);
+ f = c->sel;
+ remove_frame(f);
if(before)
- cext_vattachat(vector_of_frames(&tgt->frame), f, fidx);
+ insert_frame(tf, f, True);
else
- cext_vattachat(vector_of_frames(&tgt->frame), f, fidx + 1);
+ insert_frame(ft, f, False);
- tgt->sel = idx_of_frame(f);
+ tgt->sel = f;
arrange_column(tgt, False);
}
- else {
+ else { /* !tgt */
if(!(ft = frame_of_point(pt)) || (f == ft))
return;
- cext_vdetach(vector_of_frames(&tgt->frame), f);
- fidx = idx_of_frame(ft);
+ remove_frame(f);
if(pt->y < (ft->rect.y + ft->rect.height / 2))
- cext_vattachat(vector_of_frames(&tgt->frame), f, fidx);
+ insert_frame(tf, f, True);
else
- cext_vattachat(vector_of_frames(&tgt->frame), f, fidx + 1);
+ insert_frame(ft, f, False);
- tgt->sel = idx_of_frame(f);
+ tgt->sel = f;
arrange_column(tgt, False);
}
}
@@ -415,7 +402,7 @@ drop_move(Frame *f, XRectangle *new, XPoint *pt)
void
resize_column(Client *c, XRectangle *r, XPoint *pt)
{
- Frame *f = c->frame.data[c->sel];
+ Frame *f = c->sel;
if((f->rect.width == r->width) && (f->rect.height == r->height))
drop_move(f, r, pt);
else
@@ -423,9 +410,9 @@ resize_column(Client *c, XRectangle *r, XPoint *pt)
}
Area *
-new_column(View *v, unsigned int pos, unsigned int w) {
- Area *a;
- if(!(a = create_area(v, pos, w)))
+new_column(View *v, Area *pos, unsigned int w) {
+ Area *a = create_area(v, pos, w);
+ if(!a)
return nil;
arrange_view(v);
return a;
diff --git a/cmd/wm/event.c b/cmd/wm/event.c
@@ -67,21 +67,21 @@ static void
handle_buttonrelease(XEvent *e)
{
Client *c;
+ Bar *b;
XButtonPressedEvent *ev = &e->xbutton;
static char buf[32];
if(ev->window == barwin) {
- unsigned int i;
- for(i = 0; i < bar.size; i++)
- if(blitz_ispointinrect(ev->x, ev->y, &bar.data[i]->rect)) {
+ for(b=bar; b; b=b->next)
+ if(blitz_ispointinrect(ev->x, ev->y, &b->rect)) {
snprintf(buf, sizeof(buf), "BarClick %s %d\n",
- bar.data[i]->name, ev->button);
+ b->name, ev->button);
write_event(buf);
return;
}
}
- else if((c = frame_of_win(ev->window)) && c->frame.size) {
+ else if((c = frame_of_win(ev->window)) && c->frame) {
snprintf(buf, sizeof(buf), "ClientClick %d %d\n",
- idx_of_client_id(c->id), ev->button);
+ idx_of_client(c), ev->button);
write_event(buf);
}
}
@@ -121,10 +121,10 @@ handle_configurerequest(XEvent *e)
c = client_of_win(ev->window);
ev->value_mask &= ~CWSibling;
if(c) {
- if(c->frame.size && !idx_of_area(c->frame.data[c->sel]->area)) {
+ if(c->frame && c->sel->area == c->sel->area->view->area) {
gravitate_client(c, True);
- if(c->frame.size) {
+ if(c->frame) {
if(ev->value_mask & CWX)
c->rect.x = ev->x;
if(ev->value_mask & CWY)
@@ -139,8 +139,8 @@ handle_configurerequest(XEvent *e)
gravitate_client(c, False);
- if(c->frame.size) {
- Frame *f = c->frame.data[c->sel];
+ if(c->frame) {
+ Frame *f = c->sel;
if(c->rect.width >= rect.width && c->rect.height >= rect.height) {
f->rect.y = wc.y = -height_of_bar();
f->rect.x = wc.x = -def.border;
@@ -155,7 +155,7 @@ handle_configurerequest(XEvent *e)
wc.border_width = 1;
wc.sibling = None;
wc.stack_mode = ev->detail;
- if(f->area->view != view.data[sel])
+ if(f->area->view != sel)
wc.x += 2 * rect.width;
XConfigureWindow(dpy, c->framewin, ev->value_mask, &wc);
configure_client(c);
@@ -168,7 +168,7 @@ handle_configurerequest(XEvent *e)
wc.width = ev->width;
wc.height = ev->height;
- if(c && c->frame.size) {
+ if(c && c->frame) {
wc.x = def.border;
wc.y = height_of_bar();
wc.width = c->rect.width;
@@ -204,11 +204,11 @@ handle_enternotify(XEvent *e)
return;
if((c = client_of_win(ev->window))) {
- Client *old = sel_client_of_view(view.data[sel]);
- Frame *f = c->frame.data[c->sel];
+ Client *old = selected_client();
+ Frame *f = c->sel;
Area *a = f->area;
if(a->mode == Colmax)
- c = a->frame.data[a->sel]->client;
+ c = a->sel->client;
if(c != old)
focus(c, False);
}
diff --git a/cmd/wm/frame.c b/cmd/wm/frame.c
@@ -7,17 +7,13 @@
#include "wm.h"
-Vector *
-vector_of_frames(FrameVector *fv)
-{
- return (Vector *) fv;
-}
-
Frame *
create_frame(Area *a, Client *c)
{
static unsigned short id = 1;
Frame *f = cext_emallocz(sizeof(Frame));
+ Frame **fa = a->sel ? &a->sel->anext : &a->frame;
+ Frame **fc = c->sel ? &c->sel->cnext : &c->frame;
f->id = id++;
f->area = a;
@@ -25,55 +21,84 @@ create_frame(Area *a, Client *c)
f->rect = c->rect;
f->rect.width += 2 * def.border;
f->rect.height += def.border + height_of_bar();
- cext_vattach(vector_of_frames(&c->frame), f);
- a->sel = a->frame.size ? a->sel + 1 : 0;
- cext_vattachat(vector_of_frames(&a->frame), f, a->sel);
- c->sel = c->frame.size - 1;
+ a->sel = f;
+ c->sel = f;
+
+ f->anext = *fa;
+ *fa = f;
+ f->cnext = *fc;
+ *fc = f;
+
return f;
}
void
+remove_frame(Frame *f)
+{
+ Area *a = f->area;
+ Frame **ft = &a->frame;
+ for(; *ft && *ft != f; ft=&(*ft)->anext);
+ cext_assert(*ft == f);
+ *ft = f->anext;
+}
+
+void
+insert_frame(Frame *pos, Frame *f, Bool before)
+{
+ Area *a = f->area;
+ if(before) {
+ Frame *ft;
+ for(ft=a->frame; ft && ft->anext != pos; ft=ft->anext);
+ pos=ft;
+ }
+ Frame **p = pos ? &pos->anext : &a->frame;
+ f->anext = *p;
+ *p = f;
+}
+
+void
destroy_frame(Frame *f)
{
Client *c = f->client;
Area *a = f->area;
+ Frame **ft, *pr = nil;
+
+ for(ft=&c->frame; *ft && *ft != f; pr = *ft, ft=&(*ft)->cnext);
+ cext_assert(*ft == f);
+ *ft = f->cnext;
+ if(c->sel == f)
+ c->sel = pr ? pr : *ft;
+
+ for(ft=&a->frame; *ft && *ft != f; pr = *ft, ft=&(*ft)->anext);
+ cext_assert(*ft == f);
+ *ft = f->anext;
+ if(a->sel == f)
+ a->sel = pr ? pr : *ft;
- cext_vdetach(vector_of_frames(&c->frame), f);
- cext_vdetach(vector_of_frames(&a->frame), f);
free(f);
- if(c->sel > 0)
- c->sel--;
- if(a->sel > 0)
- a->sel--;
}
-int
-idx_of_frame_id(Area *a, unsigned short id)
+Frame *
+frame_of_id(Area *a, unsigned short id)
{
- int i;
- for(i = 0; i < a->frame.size; i++)
- if(a->frame.data[i]->id == id)
- return i;
- return -1;
+ Frame *f;
+ for(f=a->frame; f && f->id != id; f=f->anext);
+ return f;
}
int
idx_of_frame(Frame *f)
{
- int i;
- Area *a = f->area;
- for(i = 0; i < a->frame.size; i++)
- if(a->frame.data[i] == f)
- return i;
- return -1;
+ Frame *t;
+ int i = 0;
+ for(t=f->area->frame; t && t != f; t=t->anext);
+ return t ? i : -1;
}
Client *
frame_of_win(Window w)
{
- unsigned int i;
- for(i = 0; (i < client.size) && client.data[i]; i++)
- if(client.data[i]->framewin == w)
- return client.data[i];
- return nil;
+ Client *c;
+ for(c=client; c && c->framewin != w; c=c->next);
+ return c;
}
diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c
@@ -3,6 +3,7 @@
* See LICENSE file for license details.
*/
+#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -52,7 +53,6 @@ enum { WMII_IOUNIT = 2048 };
* /ctl FsFctl command interface (root)
* /tag FsDtag
* /tag/X/ FsDview
- * /tag/X/ FsDview
* /tag/X/ctl FsFctl command interface (tag)
* /tag/X/name FsFname current view name
* /tag/X/index FsFindex current view name
@@ -68,11 +68,13 @@ enum { WMII_IOUNIT = 2048 };
* /tag/X/1/geom FsFgeom geometry of client
* /tag/X/1/ctl FsFctl command interface (client)
*/
-
-Qid root_qid;
+const char *dirnames[] = {
+};
/* IXP stuff */
+PackedQid root_qid;
+
/*
* Qid->path is calculated related to the index of the associated structure.
* i1 is associated to tag, key, global client, or bar
@@ -80,74 +82,46 @@ Qid root_qid;
* i3 is associated to client
* ie /view/sel/ctl is i1id = sel tag id, i2id = sel area id , i3id = 0 (no id)
*/
-unsigned long long
-pack_qpath(unsigned char type, unsigned short i1id, unsigned short i2id, unsigned short i3id)
-{
- return ((unsigned long long) type << 48) | ((unsigned long long) i1id << 32)
- | ((unsigned long long) i2id << 16) | (unsigned long long) i3id;
-}
static unsigned char
-unpack_type(unsigned long long path)
-{
- return (path >> 48) & 0xff;
-}
-
-static unsigned short
-unpack_i1id(unsigned long long path)
-{
- return (path >> 32) & 0xffff;
-}
-
-static unsigned short
-unpack_i2id(unsigned long long path)
-{
- return (path >> 16) & 0xffff;
-}
-
-static unsigned short
-unpack_i3id(unsigned long long path)
+dir_of_qid(PackedQid wqid[IXP_MAX_WELEM], unsigned short qsel)
{
- return path & 0xffff;
+ return qsel ? wqid[qsel - 1].ptype : FsDroot;
}
-static unsigned char
-dir_of_qid(Qid wqid[IXP_MAX_WELEM], unsigned short qsel)
-{
- return qsel ? unpack_type(wqid[qsel - 1].path) : FsDroot;
-}
-
-static void
-unpack_qpath(Qid wqid[IXP_MAX_WELEM], unsigned short qsel,
+static Bool
+unpack_qpath(PackedQid wqid[IXP_MAX_WELEM], unsigned short qsel,
unsigned char *type, int *i1, int *i2, int *i3)
{
- unsigned short i1id = unpack_i1id(wqid[qsel].path);
- unsigned short i2id = unpack_i2id(wqid[qsel].path);
- unsigned short i3id = unpack_i3id(wqid[qsel].path);
- *type = unpack_type(wqid[qsel].path);
+ *type = wqid[qsel].ptype;
- if(i1id) {
+ if(wqid[qsel].i1id) {
unsigned char dir_type = dir_of_qid(wqid, qsel);
if((dir_type == FsDGclient) || (dir_type == FsDclients))
- *i1 = idx_of_client_id(i1id);
+ *i1 = (int)client_of_id(wqid[qsel].i1id);
else {
switch(*type) {
case FsFdata:
case FsFcolors:
- case FsDbar: *i1 = idx_of_bar_id(i1id); break;
- default: *i1 = idx_of_view_id(i1id); break;
+ case FsDbar: *i1 = (int)bar_of_id(wqid[qsel].i1id); break;
+ default: *i1 = (int)view_of_id(wqid[qsel].i1id); break;
}
}
- if(i2id && (*i1 != -1)) {
- *i2 = idx_of_area_id(view.data[*i1], i2id);
- if(i3id && (*i2 != -1))
- *i3 = idx_of_frame_id(view.data[*i1]->area.data[*i2], i3id);
+ if(!*i1)
+ return False;
+ if(wqid[qsel].i2id) {
+ if(!(*i2 = (int)area_of_id(VIEW(*i1), wqid[qsel].i2id)))
+ return False;
+ if(wqid[qsel].i3id)
+ if(!(*i3 = (int)frame_of_id(AREA(*i2), wqid[qsel].i3id)))
+ return False;
}
}
+ return True;
}
static char *
-name_of_qid(Qid wqid[IXP_MAX_WELEM], unsigned short qsel)
+name_of_qid(PackedQid wqid[IXP_MAX_WELEM], unsigned short qsel)
{
unsigned char dir_type, type;
int i1 = -1, i2 = -1, i3 = -1;
@@ -165,33 +139,33 @@ name_of_qid(Qid wqid[IXP_MAX_WELEM], unsigned short qsel)
case FsDview:
if(dir_type != FsDtag)
return nil;
- if(i1 == sel)
+ if(VIEW(i1) == sel)
return "sel";
- return view.data[i1]->name;
+ return VIEW(i1)->name;
break;
case FsDbar:
- if(i1 == -1)
+ if(!i1)
return nil;
- return bar.data[i1]->name;
+ return BAR(i1)->name;
break;
case FsDarea:
- if(i1 == -1 || i2 == -1)
+ if(!i1 || !i2)
return nil;
- if(view.data[i1]->sel == i2)
+ if(VIEW(i1)->sel == AREA(i2))
return "sel";
snprintf(buf, sizeof(buf), "%u", i2);
return buf;
break;
case FsDGclient:
- if(i1 == -1)
+ if(!i1)
return nil;
- snprintf(buf, sizeof(buf), "%u", i1);
+ snprintf(buf, sizeof(buf), "%u", idx_of_client(CLIENT(i1)));
return buf;
break;
case FsDclient:
- if(i1 == -1 || i2 == -1 || i3 == -1)
+ if(!i2 || !i3)
return nil;
- if(view.data[i1]->area.data[i2]->sel == i3)
+ if(AREA(i2)->sel == FRAME(i3))
return "sel";
snprintf(buf, sizeof(buf), "%u", i3);
return buf;
@@ -205,32 +179,32 @@ name_of_qid(Qid wqid[IXP_MAX_WELEM], unsigned short qsel)
case FsFkeys: return "keys"; break;
case FsFcolors: return "colors"; break;
case FsFdata:
- if(i1 == -1)
+ if(!i1)
return nil;
return "data";
break;
case FsFctl: return "ctl"; break;
case FsFborder: return "border"; break;
case FsFgeom:
- if((dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1))
+ if((dir_type == FsDclient) && (!i1 || !i2 || !i3))
return nil;
- else if(i1 == -1)
+ else if(!i1)
return nil;
return "geom";
break;
case FsFtags:
- if((dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1))
+ if((dir_type == FsDclient) && (!i1 || !i2 || !i3))
return nil;
- else if((dir_type == FsDGclient) && (i1 == -1))
+ else if((dir_type == FsDGclient) && !i1)
return nil;
return "tags";
break;
case FsFprops:
case FsFindex:
case FsFname:
- if((dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1))
+ if((dir_type == FsDclient) && (!i1 || !i2 || !i3))
return nil;
- else if(i1 == -1)
+ else if(!i1)
return nil;
switch(type) {
case FsFname:
@@ -247,7 +221,7 @@ name_of_qid(Qid wqid[IXP_MAX_WELEM], unsigned short qsel)
}
break;
case FsFmode:
- if((dir_type == FsDarea) && (i1 == -1 || i2 == -1))
+ if((dir_type == FsDarea) && (!i1 || !i2))
return nil;
return "mode";
break;
@@ -258,7 +232,7 @@ name_of_qid(Qid wqid[IXP_MAX_WELEM], unsigned short qsel)
}
static unsigned char
-type_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
+type_of_name(PackedQid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
{
unsigned char dir_type;
int i1 = -1, i2 = -1, i3 = -1;
@@ -333,12 +307,14 @@ dyndir:
return FsLast;
}
-static Qid *
-qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
+static PackedQid *
+qid_of_name(PackedQid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
{
int i1 = -1, i2 = -1, i3 = -1, i;
unsigned char dir_type, type;
- static Qid new;
+ Client *c;
+ static PackedQid new;
+ memset(&new, 0, sizeof(PackedQid));
unpack_qpath(wqid, qsel, &dir_type, &i1, &i2, &i3);
type = type_of_name(wqid, qsel, name);
@@ -353,58 +329,64 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
case FsDbars:
if(dir_type != FsDroot)
return nil;
- new.type = IXP_QTDIR;
- new.path = pack_qpath(type, 0, 0, 0);
+ new.type= IXP_QTDIR;
+ new.ptype= type;
break;
case FsDview:
- if((dir_type != FsDtag) || !view.size)
+ if((dir_type != FsDtag) || !view)
return nil;
- new.type = IXP_QTDIR;
- if(!strncmp(name, "sel", 4))
- new.path = pack_qpath(FsDview, view.data[sel]->id, 0, 0);
- else {
- View *v;
- if(!(v = view_of_name(name)))
- return nil;
- new.path = pack_qpath(FsDview, v->id, 0, 0);
- }
+ View *v = strncmp(name, "sel", 4) ? view_of_name(name) : sel;
+ if(!v)
+ return nil;
+ new.type= IXP_QTDIR;
+ new.ptype= FsDview;
+ new.i1id= v->id;
break;
case FsDarea:
- if(i1 == -1 || dir_type != FsDview)
+ if(!i1 || dir_type != FsDview)
return nil;
{
- View *p = view.data[i1];
- new.type = IXP_QTDIR;
+ View *p = VIEW(i1);
+ new.type= IXP_QTDIR;
+ new.ptype= FsDarea;
+ new.i1id= p->id;
if(!strncmp(name, "sel", 4)) {
- new.path = pack_qpath(FsDarea, p->id, p->area.data[p->sel]->id, 0);
+ new.i2id= p->sel->id;
}
else {
+ Area *a;
if(sscanf(name, "%d", &i) != 1)
return nil;
- if(i >= p->area.size)
+ for(a=p->area; i && a; a=a->next, i--);
+ if(!a)
return nil;
- new.path = pack_qpath(FsDarea, p->id, p->area.data[i]->id, 0);
+ new.i2id= a->id;
}
}
break;
case FsDclient:
- if(i1 == -1 || i2 == -1 || dir_type != FsDarea)
+ if(!i1 || !i2 || dir_type != FsDarea)
return nil;
{
- View *p = view.data[i1];
- Area *a = p->area.data[i2];
- new.type = IXP_QTDIR;
+ View *p = VIEW(i1);
+ Area *a = AREA(i2);
+ new.type= IXP_QTDIR;
+ new.ptype= FsDclient;
+ new.i1id= p->id;
+ new.i2id= a->id;
if(!strncmp(name, "sel", 4)) {
- if(!a->frame.size)
+ if(!a->frame)
return nil;
- new.path = pack_qpath(FsDclient, p->id, a->id, a->frame.data[a->sel]->id);
+ new.i3id= a->sel->id;
}
else {
+ Frame *f;
if(sscanf(name, "%d", &i) != 1)
return nil;
- if(i >= a->frame.size)
+ for(f=a->frame; f && i; f=f->anext, i--);
+ if(i)
return nil;
- new.path = pack_qpath(FsDclient, p->id, a->id, a->frame.data[i]->id);
+ new.i3id= f->id;
}
}
break;
@@ -413,9 +395,12 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
return nil;
if(sscanf(name, "%d", &i) != 1)
return nil;
- if(i >= client.size)
+ for(c=client; i && c; c=c->next, i--);
+ if(i)
return nil;
- new.path = pack_qpath(FsDGclient, client.data[i]->id, 0, 0);
+ new.type= IXP_QTDIR;
+ new.ptype= FsDGclient;
+ new.i1id= c->id;
break;
case FsDbar:
if(dir_type != FsDbars)
@@ -424,18 +409,19 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
Bar *l;
if(!(l = bar_of_name(name)))
return nil;
- new.type = IXP_QTDIR;
- new.path = pack_qpath(FsDbar, l->id, 0, 0);
+ new.type= IXP_QTDIR;
+ new.ptype= FsDbar;
+ new.i1id= l->id;
}
break;
case FsFdata:
case FsFcolors:
- if((i1 == -1) || (dir_type != FsDbar))
+ if(!i1 || (dir_type != FsDbar))
return nil;
goto Mkfile;
break;
case FsFmode:
- if((dir_type == FsDarea) && (i1 == -1 || i2 == -1))
+ if((dir_type == FsDarea) && (!i1 || !i2))
return nil;
goto Mkfile;
break;
@@ -448,9 +434,9 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
if(dir_type == FsDroot)
return nil;
case FsFtags:
- if((dir_type == FsDclient) && ((i1 == -1 || i2 == -1 || i3 == -1)))
+ if((dir_type == FsDclient) && ((!i1 || !i2 || !i3)))
return nil;
- else if((dir_type == FsDGclient) && (i1 == -1))
+ else if((dir_type == FsDGclient) && !i1)
return nil;
goto Mkfile;
break;
@@ -467,9 +453,9 @@ qid_of_name(Qid wqid[IXP_MAX_WELEM], unsigned short qsel, char *name)
case FsFctl:
case FsFevent:
Mkfile:
+ new = wqid[qsel];
new.type = IXP_QTFILE;
- new.path = pack_qpath(type, unpack_i1id(wqid[qsel].path), unpack_i2id(wqid[qsel].path),
- unpack_i3id(wqid[qsel].path));
+ new.ptype = type;
break;
default:
return nil;
@@ -479,10 +465,10 @@ Mkfile:
}
static unsigned int
-pack_stat(Stat *stat, Qid wqid[IXP_MAX_WELEM], unsigned short qsel,
+pack_stat(Stat *stat, PackedQid wqid[IXP_MAX_WELEM], unsigned short qsel,
char *name, unsigned long long length, unsigned int mode)
{
- Qid *qid;
+ PackedQid *qid;
stat->mode = mode;
stat->atime = stat->mtime = time(0);
cext_strlcpy(stat->uid, getenv("USER"), sizeof(stat->uid));
@@ -492,13 +478,13 @@ pack_stat(Stat *stat, Qid wqid[IXP_MAX_WELEM], unsigned short qsel,
cext_strlcpy(stat->name, name, sizeof(stat->name));
stat->length = length;
if((qid = qid_of_name(wqid, qsel ? qsel - 1 : 0, name)))
- stat->qid = *qid;
+ stat->qid = qid->qid;
return ixp_sizeof_stat(stat);
}
static unsigned int
-stat_of_name(Stat *stat, char *name, Qid wqid[IXP_MAX_WELEM], unsigned short qsel)
+stat_of_name(Stat *stat, char *name, PackedQid wqid[IXP_MAX_WELEM], unsigned short qsel)
{
unsigned char dir_type, type;
int i1 = 0, i2 = 0, i3 = 0;
@@ -506,8 +492,7 @@ stat_of_name(Stat *stat, char *name, Qid wqid[IXP_MAX_WELEM], unsigned short qse
XRectangle fr;
Frame *f;
- unpack_qpath(wqid, qsel, &dir_type, &i1, &i2, &i3);
- if((i1 == -1) || (i2 == -1) || (i3 == -1))
+ if(!unpack_qpath(wqid, qsel, &dir_type, &i1, &i2, &i3))
return 0;
type = type_of_name(wqid, qsel, name);
@@ -538,27 +523,27 @@ stat_of_name(Stat *stat, char *name, Qid wqid[IXP_MAX_WELEM], unsigned short qse
break;
case FsFgeom:
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;
+ fr = FRAME(i3)->rect;
+ else if(CLIENT(i1)->frame)
+ fr = CLIENT(i1)->sel->rect;
else
- fr = client.data[i1]->rect;
+ fr = CLIENT(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 FsFprops:
if(dir_type == FsDclient) {
- f = view.data[i1]->area.data[i2]->frame.data[i3];
+ f = FRAME(i3);
return pack_stat(stat, wqid, qsel, name, strlen(f->client->props), IXP_DMREAD);
}
else
- return pack_stat(stat, wqid, qsel, name, strlen(client.data[i1]->props), IXP_DMREAD);
+ return pack_stat(stat, wqid, qsel, name, strlen(CLIENT(i1)->props), IXP_DMREAD);
break;
case FsFindex:
switch(dir_type) {
case FsDclient:
- f = view.data[i1]->area.data[i2]->frame.data[i3];
- snprintf(buf, sizeof(buf), "%d", idx_of_client_id(f->client->id));
+ f = FRAME(i3);
+ snprintf(buf, sizeof(buf), "%d", idx_of_client(f->client));
break;
case FsDarea:
snprintf(buf, sizeof(buf), "%d", i2);
@@ -571,24 +556,24 @@ stat_of_name(Stat *stat, char *name, Qid wqid[IXP_MAX_WELEM], unsigned short qse
break;
case FsFname:
if(dir_type == FsDclient) {
- f = view.data[i1]->area.data[i2]->frame.data[i3];
+ f = FRAME(i3);
return pack_stat(stat, wqid, qsel, name, strlen(f->client->name), IXP_DMREAD);
}
else if(dir_type == FsDview)
return pack_stat(stat, wqid, qsel, name,
- view.size ? strlen(view.data[i1]->name) : 0, IXP_DMREAD);
+ view ? strlen(VIEW(i1)->name) : 0, IXP_DMREAD);
else
- return pack_stat(stat, wqid, qsel, name, strlen(client.data[i1]->name), IXP_DMREAD);
+ return pack_stat(stat, wqid, qsel, name, strlen(CLIENT(i1)->name), IXP_DMREAD);
break;
case FsFtags:
switch(dir_type) {
case FsDclient:
- f = view.data[i1]->area.data[i2]->frame.data[i3];
+ f = FRAME(i3);
return pack_stat(stat, wqid, qsel, name, strlen(f->client->tags), IXP_DMREAD | IXP_DMWRITE);
break;
case FsDGclient:
return pack_stat(stat, wqid, qsel,
- name, strlen(client.data[i1]->tags), IXP_DMREAD | IXP_DMWRITE);
+ name, strlen(CLIENT(i1)->tags), IXP_DMREAD | IXP_DMWRITE);
break;
default:
break;
@@ -596,11 +581,11 @@ stat_of_name(Stat *stat, char *name, Qid wqid[IXP_MAX_WELEM], unsigned short qse
break;
case FsFdata:
return pack_stat(stat, wqid, qsel, name,
- (i1 == bar.size) ? 0 : strlen(bar.data[i1]->data), IXP_DMREAD | IXP_DMWRITE);
+ !BAR(i1)->next ? 0 : strlen(BAR(i1)->data), IXP_DMREAD | IXP_DMWRITE);
break;
case FsFmode:
return pack_stat(stat, wqid, qsel, name,
- strlen(str_of_column_mode(view.data[i1]->area.data[i2]->mode)),
+ strlen(str_of_column_mode(AREA(i2)->mode)),
IXP_DMREAD | IXP_DMWRITE);
break;
case FsFcolors:
@@ -625,6 +610,25 @@ stat_of_name(Stat *stat, char *name, Qid wqid[IXP_MAX_WELEM], unsigned short qse
return 0;
}
+static unsigned int
+stat_of_names(unsigned char **p, PackedQid wqid[IXP_MAX_WELEM], unsigned short qsel, ...)
+{
+ va_list ap;
+ char *str;
+ unsigned int n = 0;
+ Stat stat;
+
+ va_start(ap, qsel);
+
+ while((str = va_arg(ap, char *))) {
+ n += stat_of_name(&stat, str, wqid, qsel);
+ *p = ixp_pack_stat(*p, &stat);
+ }
+
+ va_end(ap);
+ return n;
+}
+
static char *
xversion(IXPConn *c, Fcall *fcall)
{
@@ -641,8 +645,9 @@ static char *
xattach(IXPConn *c, Fcall *fcall)
{
IXPMap *new = cext_emallocz(sizeof(IXPMap));
- cext_vattach(ixp_vector_of_maps(&c->map), new);
- new->wqid[0] = root_qid;
+ new->next=c->map;
+ c->map=new;
+ new->wqid[0] = root_qid.qid;
new->nwqid = 1;
new->fid = fcall->fid;
fcall->id = RATTACH;
@@ -656,7 +661,7 @@ xwalk(IXPConn *c, Fcall *fcall)
{
IXPMap *m;
unsigned int qsel, nwqid;
- Qid wqid[IXP_MAX_WELEM], *qid;
+ PackedQid wqid[IXP_MAX_WELEM], *qid;
if(!(m = ixp_server_fid2map(c, fcall->fid)))
return Enofile;
@@ -664,7 +669,7 @@ xwalk(IXPConn *c, Fcall *fcall)
return Efidinuse;
for(qsel = 0; qsel < m->nwqid; qsel++)
- wqid[qsel] = m->wqid[qsel];
+ wqid[qsel].qid = m->wqid[qsel];
if(qsel)
qsel--;
for(nwqid = 0; nwqid < fcall->nwname; nwqid++) {
@@ -681,7 +686,7 @@ xwalk(IXPConn *c, Fcall *fcall)
break;
qsel++;
}
- fcall->wqid[nwqid] = wqid[qsel] = *qid;
+ fcall->wqid[nwqid] = wqid[qsel].qid = qid->qid;
}
if(fcall->nwname && !nwqid)
@@ -692,10 +697,11 @@ xwalk(IXPConn *c, Fcall *fcall)
unsigned int i;
if(fcall->fid != fcall->newfid) {
m = cext_emallocz(sizeof(IXPMap));
- cext_vattach(ixp_vector_of_maps(&c->map), m);
+ m->next=c->map;
+ c->map=m;
}
for(i = 0; i <= qsel; i++)
- m->wqid[i] = wqid[i];
+ m->wqid[i] = wqid[i].qid;
m->nwqid = qsel + 1;
m->sel = qsel;
m->fid = fcall->newfid;
@@ -710,7 +716,7 @@ static char *
xcreate(IXPConn *c, Fcall *fcall)
{
IXPMap *m = ixp_server_fid2map(c, fcall->fid);
- Qid *qid;
+ PackedQid *qid = (PackedQid *)&m->wqid[m->sel];
unsigned char type;
if(!(fcall->mode | IXP_OWRITE))
@@ -719,18 +725,21 @@ xcreate(IXPConn *c, Fcall *fcall)
return Enofile;
if(!strncmp(fcall->name, ".", 2) || !strncmp(fcall->name, "..", 3))
return "illegal file name";
- type = unpack_type(m->wqid[m->sel].path);
+
+ type = qid->ptype;
switch(type) {
case FsDbars:
- create_bar(fcall->name, False);
+ create_bar(fcall->name);
break;
default:
return Enofile;
break;
}
- if(!(qid = qid_of_name(m->wqid, m->sel, fcall->name)))
+
+ if(!(qid = qid_of_name((PackedQid *)&m->wqid, m->sel, fcall->name)))
return Enofile;
- m->wqid[m->nwqid++] = fcall->qid = *qid;
+
+ m->wqid[m->nwqid++] = fcall->qid = qid->qid;
m->sel++;
fcall->id = RCREATE;
fcall->iounit = WMII_IOUNIT;
@@ -758,24 +767,29 @@ xopen(IXPConn *c, Fcall *fcall)
static char *
xremove(IXPConn *c, Fcall *fcall)
{
- IXPMap *m = ixp_server_fid2map(c, fcall->fid);
+ IXPMap *t, *m = ixp_server_fid2map(c, fcall->fid);
unsigned char type;
int i1 = 0, i2 = 0, i3 = 0;
if(!m)
return Enofile;
- unpack_qpath(m->wqid, m->sel, &type, &i1, &i2, &i3);
- if((i1 == -1) || (i2 == -1) || (i3 == -1))
+ if(!unpack_qpath((PackedQid *)&m->wqid, m->sel, &type, &i1, &i2, &i3))
return Enofile;
if(type != FsDbar)
return Enoperm;
/* clunk */
- cext_vdetach(ixp_vector_of_maps(&c->map), m);
+ if(c->map == m)
+ c->map = m->next;
+ else {
+ for(t=c->map; t && t->next != m; t=t->next);
+ if(t)
+ t->next = m->next;
+ }
free(m);
switch(type) {
case FsDbar:
{
- Bar *b = bar.data[i1];
+ Bar *b = BAR(i1);
destroy_bar(b);
draw_bar();
}
@@ -793,6 +807,12 @@ xread(IXPConn *c, Fcall *fcall)
{
Stat stat;
IXPMap *m = ixp_server_fid2map(c, fcall->fid);
+ PackedQid *pwqid = (PackedQid *)&m->wqid;
+ View *v;
+ Frame *f;
+ Area *a;
+ Client *cl;
+ Bar *b;
int i1 = 0, i2 = 0, i3 = 0;
unsigned int i, len;
unsigned char dir_type, type, *p = fcall->data;
@@ -801,10 +821,9 @@ xread(IXPConn *c, Fcall *fcall)
if(!m)
return Enofile;
- unpack_qpath(m->wqid, m->sel, &type, &i1, &i2, &i3);
- if((i1 == -1) || (i2 == -1) || (i3 == -1))
+ if(!unpack_qpath(pwqid, m->sel, &type, &i1, &i2, &i3))
return Enofile;
- dir_type = dir_of_qid(m->wqid, m->sel);
+ dir_type = dir_of_qid(pwqid, m->sel);
fcall->count = 0;
if(fcall->offset) {
@@ -812,17 +831,17 @@ xread(IXPConn *c, Fcall *fcall)
case FsDtag:
/* jump to offset */
len = 0;
- if(view.size)
- len += stat_of_name(&stat, "sel", m->wqid, m->sel);
- for(i = 0; i < view.size; i++) {
- len += stat_of_name(&stat, view.data[i]->name, m->wqid, m->sel);
+ if(view)
+ len += stat_of_name(&stat, "sel", pwqid, m->sel);
+ for(v=view; v; v=v->next) {
+ len += stat_of_name(&stat, v->name, pwqid, m->sel);
if(len <= fcall->offset)
continue;
break;
}
/* offset found, proceeding */
- for(; i < view.size; i++) {
- len = stat_of_name(&stat, view.data[i]->name, m->wqid, m->sel);
+ for(; v; v=v->next) {
+ len = stat_of_name(&stat, v->name, pwqid, m->sel);
if(fcall->count + len > fcall->iounit)
break;
fcall->count += len;
@@ -832,17 +851,17 @@ xread(IXPConn *c, Fcall *fcall)
case FsDclients:
/* jump to offset */
len = 0;
- for(i = 0; i < client.size; i++) {
+ for(cl=client, i=0; cl; cl=cl->next, i++) {
snprintf(buf, sizeof(buf), "%u", i);
- len += stat_of_name(&stat, buf, m->wqid, m->sel);
+ len += stat_of_name(&stat, buf, pwqid, m->sel);
if(len <= fcall->offset)
continue;
break;
}
/* offset found, proceeding */
- for(; i < client.size; i++) {
+ for(; cl; cl=cl->next, i++) {
snprintf(buf, sizeof(buf), "%u", i);
- len = stat_of_name(&stat, buf, m->wqid, m->sel);
+ len = stat_of_name(&stat, buf, pwqid, m->sel);
if(fcall->count + len > fcall->iounit)
break;
fcall->count += len;
@@ -852,15 +871,15 @@ xread(IXPConn *c, Fcall *fcall)
case FsDbars:
/* jump to offset */
len = 0;
- for(i = 0; i < bar.size; i++) {
- len += stat_of_name(&stat, bar.data[i]->name, m->wqid, m->sel);
+ for(b=bar; b; b=b->next) {
+ len += stat_of_name(&stat, b->name, pwqid, m->sel);
if(len <= fcall->offset)
continue;
break;
}
/* offset found, proceeding */
- for(; i < bar.size; i++) {
- len = stat_of_name(&stat, bar.data[i]->name, m->wqid, m->sel);
+ for(; b; b=b->next) {
+ len = stat_of_name(&stat, b->name, pwqid, m->sel);
if(fcall->count + len > fcall->iounit)
break;
fcall->count += len;
@@ -870,22 +889,22 @@ xread(IXPConn *c, Fcall *fcall)
case FsDview:
/* jump to offset */
len = 0;
- if(view.size) {
- len = stat_of_name(&stat, "name", m->wqid, m->sel);
- len += stat_of_name(&stat, "ctl", m->wqid, m->sel);
- if(view.data[i1]->area.size)
- len += stat_of_name(&stat, "sel", m->wqid, m->sel);
- for(i = 0; i < view.data[i1]->area.size; i++) {
+ if(view) {
+ len = stat_of_name(&stat, "name", pwqid, m->sel);
+ len += stat_of_name(&stat, "ctl", pwqid, m->sel);
+ if(VIEW(i1)->area)
+ len += stat_of_name(&stat, "sel", pwqid, m->sel);
+ for(a=VIEW(i1)->area, i=0; a; a=a->next, i++) {
snprintf(buf, sizeof(buf), "%u", i);
- len += stat_of_name(&stat, buf, m->wqid, m->sel);
+ len += stat_of_name(&stat, buf, pwqid, m->sel);
if(len <= fcall->offset)
continue;
break;
}
/* offset found, proceeding */
- for(; i < view.data[i1]->area.size; i++) {
+ for(; a; a=a->next, i++) {
snprintf(buf, sizeof(buf), "%u", i);
- len = stat_of_name(&stat, buf, m->wqid, m->sel);
+ len = stat_of_name(&stat, buf, pwqid, m->sel);
if(fcall->count + len > fcall->iounit)
break;
fcall->count += len;
@@ -895,23 +914,23 @@ xread(IXPConn *c, Fcall *fcall)
break;
case FsDarea:
/* jump to offset */
- len = stat_of_name(&stat, "ctl", m->wqid, m->sel);
- len += stat_of_name(&stat, "index", m->wqid, m->sel);
+ len = stat_of_name(&stat, "ctl", pwqid, m->sel);
+ len += stat_of_name(&stat, "index", pwqid, m->sel);
if(i2)
- len += stat_of_name(&stat, "mode", m->wqid, m->sel);
- if(view.data[i1]->area.data[i2]->frame.size)
- len += stat_of_name(&stat, "sel", m->wqid, m->sel);
- for(i = 0; i < view.data[i1]->area.data[i2]->frame.size; i++) {
+ len += stat_of_name(&stat, "mode", pwqid, m->sel);
+ if(AREA(i2)->frame)
+ len += stat_of_name(&stat, "sel", pwqid, m->sel);
+ for(f=AREA(i2)->frame, i=0; f; f=f->anext, i++) {
snprintf(buf, sizeof(buf), "%u", i);
- len += stat_of_name(&stat, buf, m->wqid, m->sel);
+ len += stat_of_name(&stat, buf, pwqid, m->sel);
if(len <= fcall->offset)
continue;
break;
}
/* offset found, proceeding */
- for(; i < view.data[i1]->area.data[i2]->frame.size; i++) {
+ for(; f; f=f->anext, i++) {
snprintf(buf, sizeof(buf), "%u", i);
- len = stat_of_name(&stat, buf, m->wqid, m->sel);
+ len = stat_of_name(&stat, buf, pwqid, m->sel);
if(fcall->count + len > fcall->iounit)
break;
fcall->count += len;
@@ -972,30 +991,20 @@ xread(IXPConn *c, Fcall *fcall)
else {
switch (type) {
case FsDroot:
- fcall->count = stat_of_name(&stat, "ctl", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "event", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "def", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "bar", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- if(view.size) {
- fcall->count += stat_of_name(&stat, "tag", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
+ fcall->count = stat_of_names(&p, pwqid, m->sel, "ctl", "event", "def", "bar", nil);
+ if(view) {
+ fcall->count += stat_of_names(&p, pwqid, m->sel, "tag", nil);
}
- if(client.size) {
- fcall->count += stat_of_name(&stat, "client", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
+ if(client) {
+ fcall->count += stat_of_names(&p, pwqid, m->sel, "client", nil);
}
break;
case FsDtag:
- if(view.size) {
- fcall->count = stat_of_name(&stat, "sel", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
+ if(view) {
+ fcall->count += stat_of_names(&p, pwqid, m->sel, "sel", nil);
}
- for(i = 0; i < view.size; i++) {
- len = stat_of_name(&stat, view.data[i]->name, m->wqid, m->sel);
+ for(v=view; v; v=v->next) {
+ len = stat_of_name(&stat, v->name, pwqid, m->sel);
if(fcall->count + len > fcall->iounit)
break;
fcall->count += len;
@@ -1003,9 +1012,9 @@ xread(IXPConn *c, Fcall *fcall)
}
break;
case FsDclients:
- for(i = 0; i < client.size; i++) {
+ for(cl=client, i=0; cl; cl=cl->next, i++) {
snprintf(buf, sizeof(buf), "%u", i);
- len = stat_of_name(&stat, buf, m->wqid, m->sel);
+ len = stat_of_name(&stat, buf, pwqid, m->sel);
if(fcall->count + len > fcall->iounit)
break;
fcall->count += len;
@@ -1013,8 +1022,8 @@ xread(IXPConn *c, Fcall *fcall)
}
break;
case FsDbars:
- for(i = 0; i < bar.size; i++) {
- len = stat_of_name(&stat, bar.data[i]->name, m->wqid, m->sel);
+ for(b=bar; b; b=b->next) {
+ len = stat_of_name(&stat, b->name, pwqid, m->sel);
if(fcall->count + len > fcall->iounit)
break;
fcall->count += len;
@@ -1022,44 +1031,23 @@ xread(IXPConn *c, Fcall *fcall)
}
break;
case FsDbar:
- if(i1 >= bar.size)
+ if(!i1)
return Enofile;
- fcall->count = stat_of_name(&stat, "colors", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "data", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
+ fcall->count = stat_of_names(&p, pwqid, m->sel, "colors", "data", nil);
break;
case FsDdef:
- fcall->count = stat_of_name(&stat, "border", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "selcolors", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "normcolors", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "font", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "keys", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "tagrules", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "grabmod", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "colrules", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
+ fcall->count = stat_of_names(&p, pwqid, m->sel, "border", "selcolors",
+ "normcolors", "font", "keys", "tagrules", "grabmod", "colrules", nil);
break;
case FsDview:
- if(view.size) {
- fcall->count = stat_of_name(&stat, "name", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "ctl", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- if(view.data[i1]->area.size) {
- fcall->count += stat_of_name(&stat, "sel", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
+ if(view) {
+ fcall->count = stat_of_names(&p, pwqid, m->sel, "name", "ctl", nil);
+ if(VIEW(i1)->area) {
+ fcall->count += stat_of_names(&p, pwqid, m->sel, "sel", nil);
}
- for(i = 0; i < view.data[i1]->area.size; i++) {
+ for(a=VIEW(i1)->area, i=0; a; a=a->next, i++) {
snprintf(buf, sizeof(buf), "%u", i);
- len = stat_of_name(&stat, buf, m->wqid, m->sel);
+ len = stat_of_name(&stat, buf, pwqid, m->sel);
if(fcall->count + len > fcall->iounit)
break;
fcall->count += len;
@@ -1068,21 +1056,16 @@ xread(IXPConn *c, Fcall *fcall)
}
break;
case FsDarea:
- fcall->count = stat_of_name(&stat, "ctl", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "index", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
+ fcall->count = stat_of_names(&p, pwqid, m->sel, "ctl", "index", nil);
if(i2) {
- fcall->count += stat_of_name(&stat, "mode", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
+ fcall->count += stat_of_names(&p, pwqid, m->sel, "mode", nil);
}
- if(view.data[i1]->area.data[i2]->frame.size) {
- fcall->count += stat_of_name(&stat, "sel", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
+ if(AREA(i2)->frame) {
+ fcall->count += stat_of_names(&p, pwqid, m->sel, "sel", nil);
}
- for(i = 0; i < view.data[i1]->area.data[i2]->frame.size; i++) {
+ for(f=AREA(i2)->frame, i=0; f; f=f->anext, i++) {
snprintf(buf, sizeof(buf), "%u", i);
- len = stat_of_name(&stat, buf, m->wqid, m->sel);
+ len = stat_of_name(&stat, buf, pwqid, m->sel);
if(fcall->count + len > fcall->iounit)
break;
fcall->count += len;
@@ -1091,18 +1074,8 @@ xread(IXPConn *c, Fcall *fcall)
break;
case FsDGclient:
case FsDclient:
- fcall->count = stat_of_name(&stat, "props", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "name", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "index", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "tags", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "geom", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
- fcall->count += stat_of_name(&stat, "ctl", m->wqid, m->sel);
- p = ixp_pack_stat(p, &stat);
+ fcall->count = stat_of_names(&p, pwqid, m->sel, "props", "name",
+ "indes", "tags", "geom", "ctl", nil);
break;
case FsFctl:
return Enoperm;
@@ -1119,30 +1092,30 @@ xread(IXPConn *c, Fcall *fcall)
break;
case FsFgeom:
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;
+ fr = FRAME(i3)->rect;
+ else if(CLIENT(i1)->frame)
+ fr = CLIENT(i1)->sel->rect;
else
- fr = client.data[i1]->rect;
+ fr = CLIENT(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;
case FsFprops:
if(dir_type == FsDclient) {
- if((fcall->count = strlen(view.data[i1]->area.data[i2]->frame.data[i3]->client->props)))
- memcpy(p, view.data[i1]->area.data[i2]->frame.data[i3]->client->props, fcall->count);
+ if((fcall->count = strlen(FRAME(i3)->client->props)))
+ memcpy(p, FRAME(i3)->client->props, fcall->count);
}
else {
- if((fcall->count = strlen(client.data[i1]->props)))
- memcpy(p, client.data[i1]->props, fcall->count);
+ if((fcall->count = strlen(CLIENT(i1)->props)))
+ memcpy(p, CLIENT(i1)->props, fcall->count);
}
break;
case FsFindex:
switch(dir_type) {
case FsDclient:
snprintf(buf, sizeof(buf), "%d",
- idx_of_client_id(view.data[i1]->area.data[i2]->frame.data[i3]->client->id));
+ idx_of_client(FRAME(i3)->client));
break;
case FsDarea:
snprintf(buf, sizeof(buf), "%d", i2);
@@ -1156,46 +1129,46 @@ xread(IXPConn *c, Fcall *fcall)
break;
case FsFname:
if(dir_type == FsDclient) {
- if((fcall->count = strlen(view.data[i1]->area.data[i2]->frame.data[i3]->client->name)))
- memcpy(p, view.data[i1]->area.data[i2]->frame.data[i3]->client->name, fcall->count);
+ if((fcall->count = strlen(FRAME(i3)->client->name)))
+ memcpy(p, FRAME(i3)->client->name, fcall->count);
}
else if(dir_type == FsDview) {
- if((fcall->count = strlen(view.data[i1]->name)))
- memcpy(p, view.data[i1]->name, fcall->count);
+ if((fcall->count = strlen(VIEW(i1)->name)))
+ memcpy(p, VIEW(i1)->name, fcall->count);
}
else {
- if((fcall->count = strlen(client.data[i1]->name)))
- memcpy(p, client.data[i1]->name, fcall->count);
+ if((fcall->count = strlen(CLIENT(i1)->name)))
+ memcpy(p, CLIENT(i1)->name, fcall->count);
}
break;
case FsFtags:
switch(dir_type) {
case FsDclient:
{
- Client *c = view.data[i1]->area.data[i2]->frame.data[i3]->client;
+ Client *c = FRAME(i3)->client;
if((fcall->count = strlen(c->tags)))
memcpy(p, c->tags, fcall->count);
}
break;
case FsDGclient:
- if((fcall->count = strlen(client.data[i1]->tags)))
- memcpy(p, client.data[i1]->tags, fcall->count);
+ if((fcall->count = strlen(CLIENT(i1)->tags)))
+ memcpy(p, CLIENT(i1)->tags, fcall->count);
break;
default:
break;
}
break;
case FsFdata:
- if(i1 >= bar.size)
+ if(!i1)
return Enofile;
- if((fcall->count = strlen(bar.data[i1]->data)))
- memcpy(p, bar.data[i1]->data, fcall->count);
+ if((fcall->count = strlen(BAR(i1)->data)))
+ memcpy(p, BAR(i1)->data, fcall->count);
break;
case FsFcolors:
- if(i1 >= bar.size)
+ if(!i1)
return Enofile;
- if((fcall->count = strlen(bar.data[i1]->colstr)))
- memcpy(p, bar.data[i1]->colstr, fcall->count);
+ if((fcall->count = strlen(BAR(i1)->colstr)))
+ memcpy(p, BAR(i1)->colstr, fcall->count);
break;
case FsFselcolors:
if((fcall->count = strlen(def.selcolor)))
@@ -1242,7 +1215,7 @@ xread(IXPConn *c, Fcall *fcall)
break;
case FsFmode:
snprintf(buf, sizeof(buf), "%s",
- str_of_column_mode(view.data[i1]->area.data[i2]->mode));
+ str_of_column_mode(AREA(i2)->mode));
fcall->count = strlen(buf);
memcpy(p, buf, fcall->count);
break;
@@ -1264,9 +1237,9 @@ xstat(IXPConn *c, Fcall *fcall)
if(!m)
return Enofile;
- if(!(name = name_of_qid(m->wqid, m->sel)))
+ if(!(name = name_of_qid((PackedQid *)&m->wqid, m->sel)))
return Enofile;
- if(!stat_of_name(&fcall->stat, name, m->wqid, m->sel ? m->sel - 1 : 0))
+ if(!stat_of_name(&fcall->stat, name, (PackedQid *)&m->wqid, m->sel ? m->sel - 1 : 0))
return Enofile;
fcall->id = RSTAT;
ixp_server_respond_fcall(c, fcall);
@@ -1286,10 +1259,9 @@ xwrite(IXPConn *c, Fcall *fcall)
if(!m)
return Enofile;
- unpack_qpath(m->wqid, m->sel, &type, &i1, &i2, &i3);
- if((i1 == -1) || (i2 == -1) || (i3 == -1))
+ if(!unpack_qpath((PackedQid *)&m->wqid, m->sel, &type, &i1, &i2, &i3))
return Enofile;
- dir_type = dir_of_qid(m->wqid, m->sel);
+ dir_type = dir_of_qid((PackedQid *)&m->wqid, m->sel);
switch(type) {
case FsFctl:
@@ -1308,24 +1280,23 @@ xwrite(IXPConn *c, Fcall *fcall)
break;
case FsDview:
if(!strncmp(buf, "select ", 7)) {
- if(view.size)
- select_area(view.data[i1]->area.data[view.data[i1]->sel],
- &buf[7]);
+ if(view)
+ select_area(VIEW(i1)->sel, &buf[7]);
}
else
return Enocommand;
break;
case FsDarea:
if(!strncmp(buf, "select ", 7)) {
- Area *a = view.data[i1]->area.data[i2];
- if(a->frame.size)
- select_client(a->frame.data[a->sel]->client, &buf[7]);
+ Area *a = AREA(i2);
+ if(a->frame)
+ select_client(a->sel->client, &buf[7]);
}
else
return Enocommand;
break;
case FsDclient:
- f = view.data[i1]->area.data[i2]->frame.data[i3];
+ f = FRAME(i3);
if(!strncmp(buf, "kill", 5))
kill_client(f->client);
else if(!strncmp(buf, "newcol ", 7))
@@ -1341,7 +1312,7 @@ xwrite(IXPConn *c, Fcall *fcall)
break;
case FsDGclient:
if(!strncmp(buf, "kill", 5))
- kill_client(client.data[i1]);
+ kill_client(CLIENT(i1));
else
return Enocommand;
break;
@@ -1368,28 +1339,28 @@ xwrite(IXPConn *c, Fcall *fcall)
buf[fcall->count] = 0;
cext_trim(buf, " \t/");
if(dir_type == FsDclient)
- cl = view.data[i1]->area.data[i2]->frame.data[i3]->client;
+ cl = FRAME(i3)->client;
else
- cl = client.data[i1];
+ cl = CLIENT(i1);
apply_tags(cl, buf);
update_views();
draw_client(cl);
break;
case FsFdata:
len = fcall->count;
- if(len >= sizeof(bar.data[i1]->data))
- len = sizeof(bar.data[i1]->data) - 1;
- memcpy(bar.data[i1]->data, fcall->data, len);
- bar.data[i1]->data[len] = 0;
+ if(len >= sizeof(BAR(i1)->data))
+ len = sizeof(BAR(i1)->data) - 1;
+ memcpy(BAR(i1)->data, fcall->data, len);
+ BAR(i1)->data[len] = 0;
draw_bar();
break;
case FsFcolors:
- if((i1 >= bar.size) || (fcall->count != 23) || (fcall->data[0] != '#')
+ if(!i1 || (fcall->count != 23) || (fcall->data[0] != '#')
|| (fcall->data[8] != '#') || (fcall->data[16] != '#'))
return Ebadvalue;
- memcpy(bar.data[i1]->colstr, fcall->data, fcall->count);
- bar.data[i1]->colstr[fcall->count] = 0;
- blitz_loadcolor(dpy, &bar.data[i1]->color, screen, bar.data[i1]->colstr);
+ memcpy(BAR(i1)->colstr, fcall->data, fcall->count);
+ BAR(i1)->colstr[fcall->count] = 0;
+ blitz_loadcolor(dpy, &BAR(i1)->color, screen, BAR(i1)->colstr);
draw_bar();
break;
case FsFselcolors:
@@ -1459,7 +1430,7 @@ xwrite(IXPConn *c, Fcall *fcall)
buf[fcall->count] = 0;
if(dir_type == FsDclient) {
XRectangle new;
- f = view.data[i1]->area.data[i2]->frame.data[i3];
+ f = FRAME(i3);
new = f->rect;
blitz_strtorect(&new, buf);
if(new.width == 0)
@@ -1485,8 +1456,8 @@ xwrite(IXPConn *c, Fcall *fcall)
return Ebadvalue;
cext_strlcpy(def.grabmod, buf, sizeof(def.grabmod));
def.mod = mod;
- if(view.size)
- restack_view(view.data[sel]);
+ if(view)
+ restack_view(sel);
}
break;
case FsFfont:
@@ -1500,15 +1471,15 @@ xwrite(IXPConn *c, Fcall *fcall)
case FsFmode:
if(fcall->count >= sizeof(buf))
return Ebadvalue;
- if(dir_type == FsDarea && !i2)
+ if(dir_type == FsDarea && AREA(i2) == AREA(i2)->view->area)
return Enofile;
memcpy(buf, fcall->data, fcall->count);
buf[fcall->count] = 0;
if((i = column_mode_of_str(buf)) == -1)
return Ebadvalue;
- view.data[i1]->area.data[i2]->mode = i;
- arrange_column(view.data[i1]->area.data[i2], True);
- restack_view(view.data[i1]);
+ AREA(i2)->mode = i;
+ arrange_column(AREA(i2), True);
+ restack_view(VIEW(i1));
draw_clients();
break;
case FsFevent:
@@ -1532,25 +1503,31 @@ xwrite(IXPConn *c, Fcall *fcall)
static char *
xclunk(IXPConn *c, Fcall *fcall)
{
- IXPMap *m = ixp_server_fid2map(c, fcall->fid);
+ IXPMap *t, *m = ixp_server_fid2map(c, fcall->fid);
+ Client *cl;
unsigned char type;
if(!m)
return Enofile;
- type = unpack_type(m->wqid[m->sel].path);
+ type = ((PackedQid *)&m->wqid[m->sel])->ptype;
if(type == FsFkeys)
update_keys();
else if(type == FsFtagrules) {
- unsigned int i;
update_rules(&trule, def.tagrules);
- for(i = 0; i < client.size; i++)
- apply_rules(client.data[i]);
+ for(cl=client; cl; cl=cl->next)
+ apply_rules(cl);
update_views();
}
else if(type == FsFcolrules) {
update_rules(&vrule, def.colrules);
}
- cext_vdetach(ixp_vector_of_maps(&c->map), m);
+ if(c->map == m)
+ c->map = m->next;
+ else {
+ for(t=c->map; t && t->next != m; t=t->next);
+ if(t)
+ t->next = m->next;
+ }
free(m);
fcall->id = RCLUNK;
ixp_server_respond_fcall(c, fcall);
@@ -1587,10 +1564,9 @@ do_fcall(IXPConn *c)
void
write_event(char *event)
{
- unsigned int i = 0;
+ IXPConn *c;
- for(i = 0; i < srv.conn.size; i++) {
- IXPConn *c = srv.conn.data[i];
+ for(c=srv.conn; c; c=c->next) {
if(c->is_pending) {
/* pending reads on /event only, no qid checking */
IXPMap *m = ixp_server_fid2map(c, c->pending.fid);
@@ -1598,7 +1574,7 @@ write_event(char *event)
if(ixp_server_respond_error(c, &c->pending, Enofile))
return;
}
- else if(unpack_type(m->wqid[m->sel].path) == FsFevent) {
+ else if(((PackedQid *)&m->wqid[m->sel])->ptype == FsFevent) {
/* pending reads on /event only, no qid checking */
c->pending.count = strlen(event);
memcpy(c->pending.data, event, c->pending.count);
diff --git a/cmd/wm/key.c b/cmd/wm/key.c
@@ -85,17 +85,9 @@ ungrab_key(Key *k)
static Key *
name2key(const char *name)
{
- unsigned int i;
- for(i = 0; i < key.size; i++)
- if(!strncmp(key.data[i]->name, name, sizeof(key.data[i]->name)))
- return key.data[i];
- return nil;
-}
-
-static Vector *
-key2vector(KeyVector *kv)
-{
- return (Vector *) kv;
+ Key *k;
+ for(k=key; k && strncmp(k->name, name, sizeof(k->name)); k=k->lnext);
+ return k;
}
static Key *
@@ -134,24 +126,13 @@ get_key(const char *name)
}
if(r) {
r->id = id++;
- cext_vattach(key2vector(&key), r);
+ r->lnext = key;
+ key = r;
}
return r;
}
-void
-destroy_key(Key *k)
-{
- Key *n;
- cext_vdetach(key2vector(&key), k);
- while(k) {
- n = k->next;
- free(k);
- k = n;
- }
-}
-
static void
next_keystroke(unsigned long *mod, KeyCode *keyCode)
{
@@ -187,89 +168,87 @@ emulate_key_press(unsigned long mod, KeyCode key)
XSync(dpy, False);
}
-static KeyVector
-match_keys(KeyVector kv, unsigned long mod, KeyCode keycode, Bool seq)
+static Key *
+match_keys(Key *k, unsigned long mod, KeyCode keycode, Bool seq)
{
- KeyVector result = {0};
- unsigned int i = 0;
- for(i = 0; i < kv.size; i++) {
- Key *k = kv.data[i];
+ Key *ret = nil, *next;
+ for(next = k->tnext; k; (k=next) && (next=k->tnext)) {
if(seq)
k = k->next;
- if(k && (k->mod == mod) && (k->key == keycode))
- cext_vattach(key2vector(&result), k);
+ if(k && (k->mod == mod) && (k->key == keycode)) {
+ k->tnext = ret;
+ ret = k;
+ }
}
- return result;
+ return ret;
}
static void
-handle_key_seq(Window w, KeyVector done)
+handle_key_seq(Window w, Key *done)
{
unsigned long mod;
KeyCode key;
- KeyVector found = {0};
+ Key *found;
char buf[128];
next_keystroke(&mod, &key);
found = match_keys(done, mod, key, True);
- if((done.data[0]->mod == mod) && (done.data[0]->key == key))
+ if((done->mod == mod) && (done->key == key))
emulate_key_press(mod, key); /* double key */
else {
- switch(found.size) {
- case 0:
+ if(!found) {
XBell(dpy, 0);
- break; /* grabbed but not found */
- case 1:
- if(!found.data[0]->next) {
- snprintf(buf, sizeof(buf), "Key %s\n", found.data[0]->name);
- write_event(buf);
- break;
- }
- default:
- handle_key_seq(w, found);
- break;
+ } /* grabbed but not found */
+ else if(!found->tnext && !found->next) {
+ snprintf(buf, sizeof(buf), "Key %s\n", found->name);
+ write_event(buf);
}
+ else
+ handle_key_seq(w, found);
}
- free(found.data);
}
void
handle_key(Window w, unsigned long mod, KeyCode keycode)
{
+ Key *k;
char buf[128];
- KeyVector found = match_keys(key, mod, keycode, False);
- switch(found.size) {
- case 0:
+
+ for(k=key; k; k->tnext=k->lnext, k=k->lnext);
+ Key *found = match_keys(key, mod, keycode, False);
+
+ if(!found) {
XBell(dpy, 0);
- break; /* grabbed but not found */
- case 1:
- if(!found.data[0]->next) {
- snprintf(buf, sizeof(buf), "Key %s\n", found.data[0]->name);
- write_event(buf);
- break;
- }
- default:
+ } /* grabbed but not found */
+ else if(!found->tnext && !found->next) {
+ snprintf(buf, sizeof(buf), "Key %s\n", found->name);
+ write_event(buf);
+ }
+ else {
XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
handle_key_seq(w, found);
XUngrabKeyboard(dpy, CurrentTime);
XSync(dpy, False);
- break;
}
- free(found.data);
}
void
update_keys()
{
- Key *k;
+ Key *k, *n;
char *l, *p;
init_lock_keys();
- while(key.size) {
- ungrab_key(key.data[0]);
- destroy_key(key.data[0]);
+ while((k = key)) {
+ key = key->lnext;
+ ungrab_key(k);
+
+ while((n = k)) {
+ k = k->next;
+ free(n);
+ }
}
for(l = p = def.keys; p && *p;) {
diff --git a/cmd/wm/mouse.c b/cmd/wm/mouse.c
@@ -111,8 +111,8 @@ snap_rect(XRectangle *rects, int num, XRectangle *current,
BlitzAlign *mask, int snap)
{
SnapArgs a = { rects, num, 0, 0, 0, 0, *mask, nil };
- BlitzAlign ret;
int dx = snap + 1, dy = snap + 1;
+ BlitzAlign ret;
a.x1 = current->x;
a.x2 = current->x + current->width;
@@ -140,11 +140,13 @@ snap_rect(XRectangle *rects, int num, XRectangle *current,
rect_morph_xy(current, abs(dx) <= snap ? dx : 0,
abs(dy) <= snap ? dy : 0, mask);
+
ret = *mask;
if(abs(dx) <= snap)
ret ^= EAST|WEST;
if(abs(dy) <= snap)
ret ^= NORTH|SOUTH;
+
return ret ^ CENTER;
}
@@ -176,10 +178,10 @@ do_mouse_resize(Client *c, BlitzAlign align)
Window dummy;
XEvent ev;
unsigned int num = 0, di;
- Frame *f = c->frame.data[c->sel];
- int aidx = idx_of_area(f->area);
- int snap = aidx ? 0 : rect.height / 66;
- XRectangle *rects = aidx ? nil : rects_of_view(f->area->view, &num);
+ Frame *f = c->sel;
+ Bool floating = (f->area == f->area->view->area);
+ int snap = floating ? rect.height / 66 : 0;
+ XRectangle *rects = floating ? rects_of_view(f->area->view, &num) : nil;
XRectangle frect = f->rect, ofrect;
XRectangle origin = frect;
XPoint pt;
@@ -188,7 +190,7 @@ do_mouse_resize(Client *c, BlitzAlign align)
rx = (float)ox / frect.width;
ry = (float)oy / frect.height;
- if (!aidx || align != CENTER) {
+ if (floating || align != CENTER) {
px = ox = frect.width / 2;
py = oy = frect.height / 2;
if(align&NORTH)
@@ -218,7 +220,7 @@ do_mouse_resize(Client *c, BlitzAlign align)
switch (ev.type) {
case ButtonRelease:
draw_xor_border(&frect);
- if(aidx)
+ if(!floating)
resize_column(c, &frect, (align == CENTER) ? &pt : nil);
else
resize_client(c, &frect, False);
@@ -235,20 +237,20 @@ do_mouse_resize(Client *c, BlitzAlign align)
case MotionNotify:
ofrect = frect;
+ pt.x = ev.xmotion.x;
+ pt.y = ev.xmotion.y;
XTranslateCoordinates(dpy, c->framewin, root, ev.xmotion.x,
ev.xmotion.y, &px, &py, &dummy);
- pt.x = px;
- pt.y = py;
rect_morph_xy(&origin, px-ox, py-oy, &align);
frect=origin;
ox=px; oy=py;
- if(!aidx)
+ if(floating)
grav = snap_rect(rects, num, &frect, &align, snap);
else
grav = align ^ CENTER;
- match_sizehints(c, &frect, aidx, grav);
+ match_sizehints(c, &frect, floating, grav);
draw_xor_border(&ofrect);
draw_xor_border(&frect);
diff --git a/cmd/wm/rule.c b/cmd/wm/rule.c
@@ -16,25 +16,19 @@ enum {
VALUE
};
-static Vector *
-vector_of_rules(RuleVector *rv)
-{
- return (Vector *) rv;
-}
-
void
-update_rules(RuleVector *rule, const char *data)
+update_rules(Rule **rule, const char *data)
{
int mode = IGNORE;
+ Rule *rul;
char *p, *r = nil, *v = nil, regex[256], value[256];
if(!data || !strlen(data))
return;
- while(rule->size) {
- Rule *rul = rule->data[0];
+ while((rul = *rule)) {
+ *rule = rul->next;
regfree(&rul->regex);
- cext_vdetach(vector_of_rules(rule), rul);
free(rul);
}
@@ -63,15 +57,15 @@ update_rules(RuleVector *rule, const char *data)
break;
case VALUE:
if(*p == '\n' || *p == 0) {
- Rule *rul = cext_emallocz(sizeof(Rule));
+ *rule = cext_emallocz(sizeof(Rule));
*v = 0;
cext_trim(value, " \t/");
- if(!regcomp(&rul->regex, regex, 0)) {
- cext_strlcpy(rul->value, value, sizeof(rul->value));
- cext_vattach(vector_of_rules(rule), rul);
+ if(!regcomp(&(*rule)->regex, regex, 0)) {
+ cext_strlcpy((*rule)->value, value, sizeof(rul->value));
+ rule = &(*rule)->next;
}
else
- free(rul);
+ free(*rule);
mode = IGNORE;
}
else {
diff --git a/cmd/wm/view.c b/cmd/wm/view.c
@@ -4,96 +4,79 @@
*/
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include "wm.h"
-static Vector *
-vector_of_views(ViewVector *vv)
-{
- return (Vector *) vv;
-}
+static char buf[256];
-static int
-comp_view_name(const void *v1, const void *v2)
+static void
+assign_sel_view(View *v)
{
- View *vv1 = *(View **)v1;
- View *vv2 = *(View **)v2;
- return strcmp(vv1->name, vv2->name);
+ if(sel && sel != v) {
+ snprintf(buf, sizeof(buf), "UnfocusTag %s\n", sel->name);
+ write_event(buf);
+ }
+ sel = v;
+ snprintf(buf, sizeof(buf), "FocusTag %s\n", sel->name);
+ write_event(buf);
}
-static View *
+View *
create_view(const char *name)
{
static unsigned short id = 1;
- static char buf[256];
- View *v = cext_emallocz(sizeof(View));
+ View **i, *v = cext_emallocz(sizeof(View));
v->id = id++;
cext_strlcpy(v->name, name, sizeof(v->name));
- create_area(v, v->area.size, 0);
- create_area(v, v->area.size, 0);
- cext_vattach(vector_of_views(&view), v);
- qsort(view.data, view.size, sizeof(View *), comp_view_name);
- snprintf(buf, sizeof(buf), "CreateTag %s\n", name);
- write_event(buf);
- return v;
-}
+ create_area(v, nil, 0);
+ create_area(v, v->area, 0);
-static void
-assign_sel_view(View *v)
-{
- static char buf[256];
- int i = idx_of_view(v);
+ for(i=&view; *i && (strcmp((*i)->name, name) < 0); i=&(*i)->next);
+ v->next = *i;
+ *i = v;
- i = idx_of_view(v);
- if(sel < view.size && i != sel) {
- snprintf(buf, sizeof(buf), "UnfocusTag %s\n", view.data[sel]->name);
- write_event(buf);
- }
- snprintf(buf, sizeof(buf), "FocusTag %s\n", v->name);
+ snprintf(buf, sizeof(buf), "CreateTag %s\n", v->name);
write_event(buf);
- sel = i;
+ if(!sel)
+ assign_sel_view(v);
+
+ return v;
}
-static void
+void
destroy_view(View *v)
{
- static char buf[256];
- while(v->area.size)
- destroy_area(v->area.data[0]);
+ Area *a;
+ View **i;
+
+ for(a=v->area; a; a=a->next)
+ destroy_area(a);
+
+ for(i=&view; *i && *i != v; i=&(*i)->next);
+ *i = v->next;
+
+ if(sel == v)
+ for(sel=view; sel && sel->next != *i; sel=sel->next);
- cext_vdetach(vector_of_views(&view), v);
- if(sel >= view.size && view.size)
- assign_sel_view(view.data[0]);
snprintf(buf, sizeof(buf), "DestroyTag %s\n", v->name);
write_event(buf);
free(v);
}
-int
-idx_of_view(View *v)
-{
- int i;
- for(i = 0; i < view.size; i++)
- if(v == view.data[i])
- return i;
- return -1;
-}
-
static void
update_frame_selectors(View *v)
{
- unsigned int i, j;
+ Client *c;
+ Frame *f;
/* select correct frames of clients */
- for(i = 0; i < client.size; i++) {
- Client *c = client.data[i];
- for(j = 0; j < c->frame.size; j++)
- if(c->frame.data[j]->area->view == v) {
- c->sel = j;
- break;
- }
+ for(c=client; c; c=c->next) {
+ for(f=c->frame; f && f->area->view != v; f=f->cnext);
+ if(f)
+ c->sel = f;
}
}
@@ -101,7 +84,8 @@ void
focus_view(View *v)
{
Client *c;
- unsigned int i;
+
+ cext_assert(v);
XGrabServer(dpy);
assign_sel_view(v);
@@ -109,19 +93,21 @@ focus_view(View *v)
update_frame_selectors(v);
/* gives all(!) clients proper geometry (for use of different tags) */
- for(i = 0; i < client.size; i++)
- if(client.data[i]->frame.size) {
- Frame *f = client.data[i]->frame.data[client.data[i]->sel];
- if(f->area->view == v) {
- XMoveWindow(dpy, client.data[i]->framewin, f->rect.x, f->rect.y);
- resize_client(client.data[i], &f->rect, False);
+ for(c=client; c; c=c->next)
+ if(c->sel) {
+ Frame *f = c->sel;
+ if(f && f->area->view == v) {
+ XMoveWindow(dpy, c->framewin, f->rect.x, f->rect.y);
+ resize_client(c, &f->rect, False);
}
else
- XMoveWindow(dpy, client.data[i]->framewin,
+ XMoveWindow(dpy, c->framewin,
2 * rect.width + f->rect.x, f->rect.y);
}
- if((c = sel_client_of_view(v)))
+
+ if((c = selected_client()))
focus_client(c, True);
+
draw_clients();
XSync(dpy, False);
XUngrabServer(dpy);
@@ -132,40 +118,32 @@ XRectangle *
rects_of_view(View *v, unsigned int *num)
{
XRectangle *result = nil;
- unsigned int i;
+ Frame *f;
- *num = v->area.data[0]->frame.size + 2;
+ *num = 2;
+ for(f=v->area->frame; f; f=f->anext, (*num)++);
- if(*num) {
- result = cext_emallocz(*num * sizeof(XRectangle));
- for(i = 0; i < v->area.data[0]->frame.size; i++)
- result[i] = v->area.data[0]->frame.data[i]->rect;
- result[*num - 1] = rect;
- result[*num - 2] = brect;
- }
- return result;
+ result = cext_emallocz(*num * sizeof(XRectangle));
+ for(f=v->area->frame; f; f=f->anext)
+ *(result++) = f->rect;
+ *(result++) = rect;
+ *(result++) = brect;
+ return (result - *num);
}
-int
-idx_of_view_id(unsigned short id)
-{
- int i;
- for(i = 0; i < view.size; i++)
- if(view.data[i]->id == id)
- return i;
- return -1;
+View *
+view_of_id(unsigned short id) {
+ View *v;
+ for(v = view; v && v->id != id; v=v->next);
+ return v;
}
View *
view_of_name(const char *name)
{
- unsigned int i;
-
- for(i = 0; i < view.size; i++)
- if(!strncmp(view.data[i]->name, name, strlen(name))
- && !strncmp(view.data[i]->name, name, strlen(view.data[i]->name)))
- return view.data[i];
- return nil;
+ View *v;
+ for(v = view; v && strcmp(v->name, name); v=v->next);
+ return v;
}
static View *
@@ -183,16 +161,16 @@ select_view(const char *arg)
cext_trim(buf, " \t+");
if(!strlen(buf))
return;
- focus_view(get_view(arg));
+ assign_sel_view(get_view(arg));
update_views(); /* performs focus_view */
}
static Bool
is_of_view(View *v, Client *c)
{
- unsigned int i;
- for(i = 0; i < v->area.size; i++)
- if(is_of_area(v->area.data[i], c))
+ Area *a;
+ for(a=v->area; a; a=a->next)
+ if(is_of_area(a, c))
return True;
return False;
}
@@ -200,11 +178,11 @@ is_of_view(View *v, Client *c)
void
detach_from_view(View *v, Client *c)
{
- unsigned int i;
+ Area *a;
- for(i = 0; i < v->area.size; i++) {
- if(is_of_area(v->area.data[i], c)) {
- detach_from_area(v->area.data[i], c);
+ for(a=v->area; a; a=a->next) {
+ if(is_of_area(a, c)) {
+ detach_from_area(a, c);
XMoveWindow(dpy, c->framewin, 2 * rect.width, 0);
}
}
@@ -219,46 +197,39 @@ attach_to_view(View *v, Client *c)
if(c->trans || c->floating || c->fixedsize
|| (c->rect.width == rect.width && c->rect.height == rect.height))
- a = v->area.data[0];
+ a = v->area;
else
- a = v->area.data[v->sel];
+ a = v->sel;
attach_to_area(a, c, False);
- v->sel = idx_of_area(a);
-}
-
-Client *
-sel_client_of_view(View *v)
-{
- if(v) {
- Area *a = v->area.size ? v->area.data[v->sel] : nil;
- return sel_client_of_area(a);
- }
- return nil;
+ v->sel = a;
}
void
restack_view(View *v)
{
- unsigned int i, n = 0;
- int j;
+ Area *a;
+ Frame *f;
+ Client *c;
+ unsigned int n=0, i=0;
static Window *wins = nil;
static unsigned int winssz = 0;
- if(client.size > winssz) {
- winssz = 2 * client.size;
+ for(c=client; c; c=c->next, i++);
+ if(i > winssz) {
+ winssz = 2 * i;
wins = realloc(wins, sizeof(Window) * winssz);
}
- for(i = 0; i < v->area.size; i++) {
- Area *a = v->area.data[i];
- if(a->frame.size) {
- wins[n++] = a->frame.data[a->sel]->client->framewin;
- for(j = a->frame.size - 1; j >= 0; j--) {
- Client *c = a->frame.data[j]->client;
- update_client_grab(c, (v->sel == i) && (a->sel == j));
- if(j == a->sel)
- continue;
- wins[n++] = c->framewin;
+ for(a=v->area; a; a=a->next) {
+ if(a->frame) {
+ wins[n++] = a->sel->client->framewin;
+ for(f=a->frame; f; f=f->anext, f != a->sel && n++);
+ i=n;
+ for(f=a->frame; f; f=f->anext) {
+ Client *c = f->client;
+ update_client_grab(c, (v->sel == a) && (a->sel == f));
+ if(f != a->sel)
+ wins[--i] = c->framewin;
}
}
}
@@ -270,36 +241,35 @@ restack_view(View *v)
void
scale_view(View *v, float w)
{
- unsigned int i, xoff;
+ unsigned int xoff, i=0;
+ Area *a;
float scale, dx = 0;
int wdiff = 0;
- if(v->area.size == 1)
+ if(!v->area->next)
return;
- for(i = 1; i < v->area.size; i++)
- dx += v->area.data[i]->rect.width;
+ for(a=v->area->next; a; a=a->next, i++)
+ dx += a->rect.width;
scale = w / dx;
xoff = 0;
- for(i = 1; i < v->area.size; i++) {
- Area *a = v->area.data[i];
+ for(a=v->area->next; a; a=a->next) {
a->rect.width *= scale;
- if(i == v->area.size - 1)
+ if(!a->next)
a->rect.width = w - xoff;
xoff += a->rect.width;
}
/* MIN_COLWIDTH can only be respected when there is enough space; the caller should guarantee this */
- if((v->area.size - 1) * MIN_COLWIDTH > w)
+ if(i * MIN_COLWIDTH > w)
return;
xoff = 0;
- for(i = 1; i < v->area.size; i++) {
- Area *a = v->area.data[i];
+ for(a=v->area->next; a; a=a->next, i--) {
if(a->rect.width < MIN_COLWIDTH)
a->rect.width = MIN_COLWIDTH;
- else if((wdiff = xoff + a->rect.width - w + (v->area.size - 1 - i) * MIN_COLWIDTH) > 0)
+ else if((wdiff = xoff + a->rect.width - w + i * MIN_COLWIDTH) > 0)
a->rect.width -= wdiff;
- if(i == v->area.size - 1)
+ if(!a->next)
a->rect.width = w - xoff;
xoff += a->rect.width;
}
@@ -308,14 +278,14 @@ scale_view(View *v, float w)
void
arrange_view(View *v)
{
- unsigned int i, xoff = 0;
+ unsigned int xoff = 0;
+ Area *a;
- if(v->area.size == 1)
+ if(!v->area->next)
return;
scale_view(v, rect.width);
- for(i = 1; i < v->area.size; i++) {
- Area *a = v->area.data[i];
+ for(a=v->area->next; a; a=a->next) {
a->rect.x = xoff;
a->rect.y = 0;
a->rect.height = rect.height - brect.height;
@@ -327,6 +297,8 @@ arrange_view(View *v)
static void
update_client_views(Client *c)
{
+ static ViewLink *free_view_links = nil;
+ ViewLink *v;
char buf[256];
char *toks[16];
unsigned int i, n;
@@ -334,19 +306,32 @@ update_client_views(Client *c)
cext_strlcpy(buf, c->tags, sizeof(buf));
n = cext_tokenize(toks, 16, buf, '+');
- while(c->view.size)
- cext_vdetach(vector_of_views(&c->view), c->view.data[0]);
+ while((v = c->views)) {
+ c->views = v->next;
+ v->next = free_view_links;
+ free_view_links = v;
+ }
- for(i = 0; i < n; i++)
- cext_vattach(vector_of_views(&c->view), get_view(toks[i]));
+ for(i = 0; i < n; i++) {
+ if(free_view_links) {
+ v = free_view_links;
+ free_view_links = v->next;
+ }
+ else
+ v = cext_emallocz(sizeof(ViewLink));
+
+ v->next = c->views;
+ c->views = v;
+ v->view = get_view(toks[i]);
+ }
}
static Bool
is_view_of(Client *c, View *v)
{
- unsigned int i;
- for(i = 0; i < c->view.size; i++)
- if(c->view.data[i] == v)
+ ViewLink *l;
+ for(l=c->views; l; l=l->next)
+ if(l->view == v)
return True;
return False;
}
@@ -354,74 +339,66 @@ is_view_of(Client *c, View *v)
static Bool
is_empty(View *v)
{
- unsigned int i;
- for(i = 0; i < v->area.size; i++)
- if(v->area.data[i]->frame.size)
+ Area *a;
+ for(a=v->area; a; a=a->next)
+ if(a->frame)
return False;
return True;
}
-static View *
-next_empty_view(View *ignore)
-{
- unsigned int i;
- for(i = 0; i < view.size; i++)
- if((view.data[i] != ignore) && is_empty(view.data[i]))
- return view.data[i];
- return nil;
-}
-
void
update_views()
{
- unsigned int i, j;
- View *v, *old = view.size ? view.data[sel] : nil;
-
- for(i = 0; i < client.size; i++)
- update_client_views(client.data[i]);
-
- for(i = 0; i < client.size; i++) {
- Client *c = client.data[i];
- for(j = 0; j < view.size; j++) {
- View *vw = view.data[j];
- update_frame_selectors(vw);
- if(is_view_of(c, vw)) {
- if(!is_of_view(vw, c))
- attach_to_view(vw, c);
+ View **i, *v, *old = sel;
+ Client *c;
+
+ for(c=client; c; c=c->next)
+ update_client_views(c);
+
+ for(c=client; c; c=c->next) {
+ for(v=view; v; v=v->next) {
+ update_frame_selectors(v);
+ if(is_view_of(c, v)) {
+ if(!is_of_view(v, c))
+ attach_to_view(v, c);
}
else {
- if(is_of_view(vw, c))
- detach_from_view(vw, c);
+ if(is_of_view(v, c))
+ detach_from_view(v, c);
}
}
}
if(old && !strncmp(old->name, "nil", 4))
old = nil;
- while((v = next_empty_view(old)))
- destroy_view(v);
+
+ for(i=&view; *i; *i && (i=&(*i)->next))
+ if((*i != old) && is_empty(*i))
+ destroy_view(*i);
if(old)
focus_view(old);
- else if(view.size)
- focus_view(view.data[sel]);
+ else if(sel)
+ focus_view(sel);
}
unsigned int
newcolw_of_view(View *v)
{
+ Rule *r;
+ Area *a;
unsigned int i, n;
regmatch_t tmpregm;
- for(i = 0; i < vrule.size; i++) {
- Rule *r = vrule.data[i];
+ for(r=vrule; r; r=r->next) {
if(!regexec(&r->regex, v->name, 1, &tmpregm, 0)) {
char buf[256];
char *toks[16];
cext_strlcpy(buf, r->value, sizeof(buf));
n = cext_tokenize(toks, 16, buf, '+');
- if(n && n > v->area.size - 1) {
- if(sscanf(toks[v->area.size - 1], "%u", &n) == 1)
+ for(a=v->area, i=0; a; a=a->next, i--);
+ if(n && n > i - 1) {
+ if(sscanf(toks[i - 1], "%u", &n) == 1)
return (rect.width * n) / 100;
}
break;
diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c
@@ -197,12 +197,9 @@ startup_error_handler(Display * dpy, XErrorEvent * error)
static void
cleanup()
{
- unsigned int i;
- for(i = 0; i<client.size; i++) {
- Client *c = client.data[i];
- Frame *cf = c->frame.data[c->sel];
- reparent_client(c, root, cf->rect.x, cf->rect.y);
- }
+ Client *c;
+ for(c=client; c; c=c->next)
+ reparent_client(c, root, c->sel->rect.x, c->sel->rect.y);
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
}
@@ -278,23 +275,21 @@ main(int argc, char *argv[])
/* IXP server */
ixp_server_open_conn(&srv, i, new_ixp_conn, ixp_server_close_conn);
- root_qid.dir_type = FsDroot;
+ root_qid.qid.dir_type = FsDroot;
root_qid.type = IXP_QTDIR;
root_qid.version = 0;
- root_qid.path = pack_qpath(FsDroot, 0, 0, 0);
+ root_qid.ptype = FsDroot;
/* X server */
ixp_server_open_conn(&srv, ConnectionNumber(dpy), check_x_event, nil);
init_x_event_handler();
- view.size = client.size = sel = 0;
- view.data = nil;
- client.data = nil;
+ view = nil;
+ client = nil;
+ sel = nil;
+ bar = nil;
+ key = nil;
- key.data = nil;
- key.size = 0;
- bar.data = nil;
- bar.size = 0;
def.colrules = nil;
def.colrulessz = 0;
def.tagrules = nil;
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -79,75 +79,92 @@ enum { MIN_COLWIDTH = 64 };
enum { WM_PROTOCOL_DELWIN = 1 };
typedef struct View View;
+#define VIEW(p) ((View *)(p))
typedef struct Area Area;
+#define AREA(p) ((Area *)(p))
typedef struct Frame Frame;
+#define FRAME(p) ((Frame *)(p))
typedef struct Client Client;
+#define CLIENT(p) ((Client *)(p))
-VECTOR(AreaVector, Area *);
struct View {
+ View *next;
char name[256];
unsigned short id;
- AreaVector area;
- unsigned int sel;
- unsigned int revert;
+ Area *area;
+ Area *sel;
+ Area *revert;
+};
+
+typedef struct ViewLink ViewLink;
+struct ViewLink {
+ ViewLink *next;
+ View *view;
};
-VECTOR(FrameVector, Frame *);
struct Area {
- unsigned short id;
- FrameVector frame;
+ Area *next;
+ Frame *frame;
+ Frame *sel;
View *view;
- unsigned int sel;
+ unsigned short id;
int mode;
XRectangle rect;
};
struct Frame {
+ Frame *cnext;
+ Frame *anext;
Area *area;
unsigned short id;
XRectangle rect;
Client *client;
};
-VECTOR(ViewVector, View *);
struct Client {
- unsigned short id;
+ Client *next;
+ ViewLink *views;
+ Area *revert;
+ Frame *frame;
+ Frame *sel;
char name[256];
char tags[256];
- ViewVector view;
char props[512];
- int proto;
+ unsigned short id;
unsigned int border;
+ int proto;
Bool floating;
Bool fixedsize;
Window win;
Window trans;
+ Window framewin;
XRectangle rect;
XSizeHints size;
- Window framewin;
GC gc;
- FrameVector frame;
- unsigned int sel;
- Area *revert;
};
typedef struct Key Key;
struct Key {
+ Key *next;
+ Key *lnext;
+ Key *tnext;
unsigned short id;
char name[128];
unsigned long mod;
KeyCode key;
- Key *next;
};
-typedef struct {
+#define BAR(p) ((Bar *)(p))
+typedef struct Bar Bar;
+struct Bar {
+ Bar *next;
char name[256];
- unsigned short id;
char data[256];
char colstr[24];
+ unsigned short id;
BlitzColor color;
XRectangle rect;
-} Bar;
+};
/* default values */
typedef struct {
@@ -169,23 +186,37 @@ typedef struct {
int colmode;
} Default;
-/* global variables */
-VECTOR(ClientVector, Client *);
-VECTOR(KeyVector, Key *);
-VECTOR(BarVector, Bar *);
-
typedef struct {
+ union {
+ Qid qid;
+ struct {
+ unsigned char type;
+ unsigned int version;
+ unsigned char ptype;
+ unsigned short i1id;
+ unsigned short i2id;
+ unsigned short i3id;
+ };
+ };
+} PackedQid;
+
+/* global variables */
+typedef struct Rule Rule;
+struct Rule {
+ Rule *next;
regex_t regex;
char value[256];
-} Rule;
-VECTOR(RuleVector, Rule *);
+};
/* global variables */
-ViewVector view;
-unsigned int sel;
-ClientVector client;
-KeyVector key;
-BarVector bar;
+View *view;
+Client *client;
+Key *key;
+Bar *bar;
+Rule *trule;
+Rule *vrule;
+
+View *sel;
Display *dpy;
int screen;
Window root;
@@ -197,7 +228,7 @@ Window barwin;
GC bargc;
GC xorgc;
XRectangle brect;
-Qid root_qid;
+PackedQid root_qid;
Default def;
Atom wm_atom[WMLast];
Atom net_atom[NetLast];
@@ -205,31 +236,28 @@ Cursor cursor[CurLast];
unsigned int valid_mask;
unsigned int num_lock_mask;
void (*handler[LASTEvent]) (XEvent *);
-RuleVector trule;
-RuleVector vrule;
/* area.c */
-Area *create_area(View *v, unsigned int pos, unsigned int w);
+Area *create_area(View *v, Area *pos, unsigned int w);
void destroy_area(Area *a);
-int idx_of_area(Area *a);
-int idx_of_area_id(View *t, unsigned short id);
+Area *area_of_id(View *t, unsigned short id);
void select_area(Area *a, char *arg);
void send_to_area(Area *to, Area *from, Client *c);
void attach_to_area(Area *a, Client *c, Bool send);
void detach_from_area(Area *a, Client *c);
Bool is_of_area(Area *a, Client *c);
+int idx_of_area(Area *a);
Client *sel_client_of_area(Area *a);
/* bar.c */
-Bar *create_bar(char *name, Bool intern);
+Bar *create_bar(char *name);
void destroy_bar(Bar *b);
void draw_bar();
-int idx_of_bar_id(unsigned short id);
+Bar *bar_of_id(unsigned short id);
void resize_bar();
unsigned int height_of_bar();
Bar *bar_of_name(const char *name);
-int idx_of_bar(Bar *b);
/* client.c */
Client *create_client(Window w, XWindowAttributes *wa);
@@ -245,17 +273,20 @@ void reparent_client(Client *c, Window w, int x, int y);
void manage_client(Client *c);
void focus_client(Client *c, Bool restack);
void focus(Client *c, Bool restack);
-void match_sizehints(Client *c, XRectangle *r, int aidx, BlitzAlign sticky);
void resize_client(Client *c, XRectangle *r, Bool ignore_xcall);
void select_client(Client *c, char *arg);
+Client *selected_client();
+void match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky);
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();
+Client *client_of_id(unsigned short id);
int idx_of_client_id(unsigned short id);
Client *client_of_win(Window w);
+int idx_of_client(Client *c);
void draw_clients();
void update_client_grab(Client *c, Bool is_sel);
void apply_rules(Client *c);
@@ -267,7 +298,7 @@ void scale_column(Area *a, float h);
void resize_column(Client *c, XRectangle *r, XPoint *pt);
int column_mode_of_str(char *arg);
char *str_of_column_mode(int mode);
-Area *new_column(View *v, unsigned int pos, unsigned int w);
+Area *new_column(View *v, Area *pos, unsigned int w);
/* event.c */
void init_x_event_handler();
@@ -275,11 +306,12 @@ void check_x_event(IXPConn *c);
unsigned int flush_masked_events(long even_mask);
/* frame.c */
-Vector *vector_of_frames(FrameVector *fv);
Frame *create_frame(Area *a, Client *c);
void destroy_frame(Frame *f);
-int idx_of_frame_id(Area *a, unsigned short id);
+void remove_frame(Frame *f);
+void insert_frame(Frame *pos, Frame *f, Bool before);
int idx_of_frame(Frame *f);
+Frame *frame_of_id(Area *a, unsigned short id);
Client *frame_of_win(Window w);
/* fs.c */
@@ -302,21 +334,22 @@ BlitzAlign snap_rect(XRectangle *rects, int num, XRectangle *current,
BlitzAlign *mask, int snap);
/* rule.c */
-void update_rules(RuleVector *rule, const char *data);
+void update_rules(Rule **rule, const char *data);
/* view.c */
void arrange_view(View *v);
void scale_view(View *v, float w);
+View *create_view(const char *name);
void focus_view(View *v);
XRectangle *rects_of_view(View *v, unsigned int *num);
-int idx_of_view_id(unsigned short id);
+View *view_of_id(unsigned short id);
void select_view(const char *arg);
-int idx_of_view(View *v);
void detach_from_view(View *v, Client *c);
void attach_to_view(View *v, Client *c);
Client *sel_client_of_view(View *v);
void restack_view(View *v);
View *view_of_name(const char *name);
+void destroy_view(View *v);
void update_views();
unsigned int newcolw_of_view(View *v);
diff --git a/cmd/wm/wmii b/cmd/wm/wmii
@@ -5,9 +5,9 @@ wmiiwm -c || exit 1
OLD_PATH="$PATH" export OLD_PATH
PATH="$HOME/.wmii-4:CONFPREFIX/wmii-4:$PATH" export PATH
-WMII_ADDRESS=unix!/tmp/ns.$USER.${DISPLAY%.0}/wmii export WMII_ADDRESS
+WMII_ADDRESS=unix!/tmp/ns.$USER.$DISPLAY/wmii export WMII_ADDRESS
-mkdir -m 700 /tmp/ns.$USER.$DISPLAY 2>/dev/null
+mkdir -m 700 /tmp/ns.$USER.${DISPLAY%.0} 2>/dev/null
wmiiwm -a $WMII_ADDRESS &
wmiiwmpid=$!
mkdir $HOME/.wmii-4 2>/dev/null && welcome &
diff --git a/libcext/Makefile b/libcext/Makefile
@@ -3,7 +3,7 @@
include ../config.mk
-SRC = emallocz.c estrdup.c strlcat.c strlcpy.c tokenize.c trim.c vector.c
+SRC = assert.c emallocz.c estrdup.c strlcat.c strlcpy.c tokenize.c trim.c vector.c
OBJ = ${SRC:.c=.o}
diff --git a/libcext/assert.c b/libcext/assert.c
@@ -0,0 +1,10 @@
+/* Public Domain */
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+cext_failed_assert(char *a, char *file, int line)
+{
+ fprintf(stderr, "Assertion \"%s\" failed at %s:%d\n", a, file, line);
+ exit(1);
+}
diff --git a/libcext/cext.h b/libcext/cext.h
@@ -38,3 +38,7 @@ VECTOR(Vector, void *);
void cext_vattach(Vector *v, void *p);
void cext_vattachat(Vector *v, void *p, unsigned int pos);
void cext_vdetach(Vector *v, void *p);
+
+/* assert.c */
+#define cext_assert(a) if(!(a)) cext_failed_assert(#a, __FILE__, __LINE__)
+void cext_failed_assert(char *a, char *file, int line);
diff --git a/libixp/ixp.h b/libixp/ixp.h
@@ -60,7 +60,7 @@ enum {
IXP_DMTMP = 0x04000000, /* mode bit for non-backed-up file */
IXP_DMREAD = 0x4<<6, /* mode bit for read permission */
IXP_DMWRITE = 0x2<<6, /* mode bit for write permission */
- IXP_DMEXEC = 0x1<<6 /* mode bit for execute permission */
+ IXP_DMEXEC = 0x1<<6 /* mode bit for execute permission */
};
/* modes */
@@ -147,36 +147,27 @@ typedef struct IXPConn IXPConn;
typedef struct IXPMap IXPMap;
struct IXPMap {
+ IXPMap *next;
unsigned int fid;
unsigned short sel;
unsigned short nwqid;
Qid wqid[IXP_MAX_WELEM];
};
-
-typedef struct {
- unsigned int size;
- IXPMap **data;
-} MapVector;
-
struct IXPConn {
+ IXPConn *next;
int fd;
IXPServer *srv;
void (*read) (IXPConn *);
void (*close) (IXPConn *);
- MapVector map;
+ IXPMap *map;
Fcall pending;
int is_pending;
};
-typedef struct {
- unsigned int size;
- IXPConn **data;
-} ConnVector;
-
struct IXPServer {
int running;
- ConnVector conn;
+ IXPConn *conn;
int maxfd;
fd_set rd;
};
@@ -249,7 +240,6 @@ unsigned int ixp_server_receive_fcall(IXPConn *c, Fcall *fcall);
int ixp_server_respond_fcall(IXPConn *c, Fcall *fcall);
int ixp_server_respond_error(IXPConn *c, Fcall *fcall, char *errstr);
void ixp_server_close(IXPServer *s);
-Vector *ixp_vector_of_maps(MapVector *mv);
/* socket.c */
int ixp_connect_sock(char *address);
diff --git a/libixp/server.c b/libixp/server.c
@@ -18,18 +18,6 @@
static unsigned char *msg[IXP_MAX_MSG];
-static Vector *
-vector_of_conns(ConnVector *cv)
-{
- return (Vector *) cv;
-}
-
-Vector *
-ixp_vector_of_maps(MapVector *mv)
-{
- return (Vector *) mv;
-}
-
IXPConn *ixp_server_open_conn(IXPServer *s, int fd, void (*read)(IXPConn *c),
void (*close)(IXPConn *c))
{
@@ -38,7 +26,8 @@ IXPConn *ixp_server_open_conn(IXPServer *s, int fd, void (*read)(IXPConn *c),
c->srv = s;
c->read = read;
c->close = close;
- cext_vattach(vector_of_conns(&s->conn), c);
+ c->next = s->conn;
+ s->conn = c;
return c;
}
@@ -46,10 +35,17 @@ void
ixp_server_close_conn(IXPConn *c)
{
IXPServer *s = c->srv;
- cext_vdetach(vector_of_conns(&s->conn), c);
- while(c->map.size) {
- IXPMap *m = c->map.data[0];
- cext_vdetach(ixp_vector_of_maps(&c->map), m);
+ IXPConn *tc;
+ IXPMap *m;
+ if(s->conn == c)
+ s->conn = c->next;
+ else {
+ for(tc=s->conn; tc && tc->next != c; tc=tc->next);
+ if(tc)
+ tc->next = c->next;
+ }
+ while((m = c->map)) {
+ c->map = m->next;
free(m);
}
shutdown(c->fd, SHUT_RDWR);
@@ -60,24 +56,24 @@ ixp_server_close_conn(IXPConn *c)
static void
prepare_select(IXPServer *s)
{
- int i;
+ IXPConn *c;
FD_ZERO(&s->rd);
- for(i = 0; i < s->conn.size; i++) {
- if(s->maxfd < s->conn.data[i]->fd)
- s->maxfd = s->conn.data[i]->fd;
- if(s->conn.data[i]->read)
- FD_SET(s->conn.data[i]->fd, &s->rd);
+ for(c=s->conn; c; c=c->next) {
+ if(s->maxfd < c->fd)
+ s->maxfd = c->fd;
+ if(c->read)
+ FD_SET(c->fd, &s->rd);
}
}
static void
handle_conns(IXPServer *s)
{
- int i;
- for(i = 0; i < s->conn.size; i++)
- if(FD_ISSET(s->conn.data[i]->fd, &s->rd) && s->conn.data[i]->read)
+ IXPConn *c;
+ for(c=s->conn; c; c=c->next)
+ if(FD_ISSET(c->fd, &s->rd) && c->read)
/* call read handler */
- s->conn.data[i]->read(s->conn.data[i]);
+ c->read(c);
}
char *
@@ -104,11 +100,9 @@ ixp_server_loop(IXPServer *s)
IXPMap *
ixp_server_fid2map(IXPConn *c, unsigned int fid)
{
- unsigned int i;
- for(i = 0; i < c->map.size; i++)
- if(c->map.data[i]->fid == fid)
- return c->map.data[i];
- return nil;
+ IXPMap *m;
+ for(m=c->map; m && m->fid != fid; m=m->next);
+ return m;
}
unsigned int
@@ -155,8 +149,8 @@ ixp_server_respond_error(IXPConn *c, Fcall *fcall, char *errstr)
void
ixp_server_close(IXPServer *s)
{
- unsigned int i;
- for(i = 0; i < s->conn.size; i++)
- if(s->conn.data[i]->close)
- s->conn.data[i]->close(s->conn.data[i]);
+ IXPConn *c;
+ for(c=s->conn; c; c=c->next)
+ if(c->close)
+ c->close(c);
}