commit 86077a19c1e78c688250573904d445189b69ca56
parent 8028d87a4be51d97a6d2def290ba159bb2bdd1af
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Tue, 7 Mar 2006 17:22:36 +0100
implemented /client namespace
Diffstat:
3 files changed, 172 insertions(+), 47 deletions(-)
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -17,7 +17,9 @@ alloc_client(Window w, XWindowAttributes *wa)
Client *c = (Client *) cext_emallocz(sizeof(Client));
XSetWindowAttributes fwa;
long msize;
+ static unsigned int id = 1;
+ c->id = id++;
c->win = w;
c->rect.x = wa->x;
c->rect.y = wa->y;
@@ -547,3 +549,13 @@ focus(Client *c)
focus_tag(t);
focus_client(c);
}
+
+int
+cid2index(unsigned short id)
+{
+ int i;
+ for(i = 0; i < nclient; i++)
+ if(client[i]->id == id)
+ return i;
+ return -1;
+}
diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c
@@ -49,20 +49,13 @@ static char Enocommand[] = "command not supported";
* /bar/1/ FsDlabel
* /bar/1/data FsFdata <arbitrary data which gets displayed>
* /bar/1/colors FsFcolors <#RRGGBB> <#RRGGBB> <#RRGGBB>
+ * /clients/ FsDclients
+ * /clients/1/ FsDGclient see /X/X/X/ namespace below
* /event FsFevent
* /ctl FsFctl command interface (root)
* /ws/ FsDws ws
* /ws/ctl FsFctl command interface (tag)
* /ws/sel/ FsDarea
- * /ws/float/ FsDarea floating clients in area 0
- * /ws/float/ctl FsFctl command interface (area)
- * /ws/float/mode FsFmode col mode
- * /ws/float/sel/ FsDclient
- * /ws/float/1/ FsDclient
- * /ws/float/1/name FsFname name of client
- * /ws/float/1/tags FsFtags tags of client
- * /ws/float/1/geom FsFgeom geometry of client
- * /ws/float/1/ctl FsFctl command interface (client)
* /ws/1/ FsDarea
* /ws/1/ctl FsFctl command interface (area)
* /ws/1/mode FsFmode col mode
@@ -126,12 +119,17 @@ decode_qpath(Qid *qid, unsigned char *type, int *i1, int *i2, int *i3)
*type = qpath_type(qid->path);
if(i1id) {
- switch(*type) {
- case FsFkey: *i1 = kid2index(i1id); break;
- case FsFdata:
- case FsFcolors:
- case FsDlabel: *i1 = lid2index(i1id); break;
- default: *i1 = tid2index(i1id); break;
+ if(qid->dir_type == FsDGclient || qid->dir_type == FsDclients)
+ *i1 = cid2index(i1id);
+ else {
+ switch(*type) {
+ case FsFkey: *i1 = kid2index(i1id); break;
+ case FsFdata:
+ case FsFcolors:
+ case FsDlabel: *i1 = lid2index(i1id); break;
+ break;
+ default: *i1 = tid2index(i1id); break;
+ }
}
if(i2id && (*i1 != -1)) {
*i2 = aid2index(tag[*i1], i2id);
@@ -155,6 +153,7 @@ qid2name(Qid *qid)
case FsDdef: return "def"; break;
case FsDkeys: return "keys"; break;
case FsDtags: return "tags"; break;
+ case FsDclients: return "clients"; break;
case FsDbar: return "bar"; break;
case FsDws: return "ws"; break;
case FsDlabel:
@@ -177,6 +176,12 @@ qid2name(Qid *qid)
snprintf(buf, sizeof(buf), "%u", i2);
return buf;
break;
+ case FsDGclient:
+ if(i1 == -1)
+ return nil;
+ snprintf(buf, sizeof(buf), "%u", i1);
+ return buf;
+ break;
case FsDclient:
if(i1 == -1 || i2 == -1 || i3 == -1)
return nil;
@@ -203,17 +208,23 @@ qid2name(Qid *qid)
case FsFborder: return "border"; break;
case FsFsnap: return "snap"; break;
case FsFgeom:
- if(i1 == -1 || i2 == -1 || i3 == -1)
+ if((qid->dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1))
+ return nil;
+ else if(i1 == -1)
return nil;
return "geom";
break;
case FsFname:
- if(i1 == -1 || i2 == -1 || i3 == -1)
+ if((qid->dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1))
+ return nil;
+ else if(i1 == -1)
return nil;
return "name";
break;
case FsFtags:
- if(i1 == -1 || i2 == -1 || i3 == -1)
+ if((qid->dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1))
+ return nil;
+ else if(i1 == -1)
return nil;
return "tags";
break;
@@ -243,9 +254,12 @@ name2type(char *name, unsigned char dir_type)
if(!strncmp(name, "tags", 5)) {
switch(dir_type) {
case FsDroot: return FsDtags; break;
+ case FsDGclient:
case FsDclient: return FsFtags; break;
}
}
+ if(!strncmp(name, "clients", 8))
+ return FsDclients;
if(!strncmp(name, "ws", 3))
return FsDws;
if(!strncmp(name, "bar", 4))
@@ -280,8 +294,6 @@ name2type(char *name, unsigned char dir_type)
return FsFdata;
if(!strncmp(name, "mode", 5))
return FsFmode;
- if(!strncmp(name, "tag", 4))
- return FsFtag;
if(has_ctag(name) && (dir_type == FsDtags))
return FsFtag;
if(name2key(name))
@@ -296,6 +308,7 @@ dyndir:
switch(dir_type) {
case FsDbar: return FsDlabel; break;
case FsDws: return FsDarea; break;
+ case FsDclients: return FsDGclient; break;
case FsDarea: return FsDclient; break;
}
return -1;
@@ -320,6 +333,7 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
case FsDdef:
case FsDkeys:
case FsDtags:
+ case FsDclients:
case FsDbar:
new->type = IXP_QTDIR;
new->path = mkqpath(type, 0, 0, 0);
@@ -380,6 +394,12 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
}
}
break;
+ case FsDGclient:
+ i = cext_strtonum(wname, 0, 0xffff, &err);
+ if(err || (i >= nclient))
+ return -1;
+ new->path = mkqpath(FsDGclient, client[i]->id, 0, 0);
+ break;
case FsFkey:
{
Key *k;
@@ -405,7 +425,9 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
case FsFgeom:
case FsFname:
case FsFtags:
- if(dir_i1 == -1 || dir_i2 == -1 || dir_i3 == -1)
+ if((dir_type == FsDclient) && (dir_i1 == -1 || dir_i2 == -1 || dir_i3 == -1))
+ return -1;
+ else if(dir_i1 == -1)
return -1;
new->type = IXP_QTFILE;
new->path = mkqpath(type, qpath_i1id(dir->path), qpath_i2id(dir->path), qpath_i3id(dir->path));
@@ -555,17 +577,21 @@ type2stat(Stat *stat, char *wname, Qid *dir)
switch (type) {
case FsDclient:
+ case FsDGclient:
case FsDarea:
case FsDws:
case FsDdef:
case FsDkeys:
case FsDtags:
+ case FsDclients:
case FsDbar:
case FsDlabel:
case FsDroot:
return mkstat(stat, dir, wname, 0, DMDIR | DMREAD | DMEXEC);
break;
case FsFctl:
+ return mkstat(stat, dir, wname, 0, DMWRITE);
+ break;
case FsFevent:
return mkstat(stat, dir, wname, 0, DMREAD);
break;
@@ -574,9 +600,16 @@ type2stat(Stat *stat, char *wname, Qid *dir)
return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE);
break;
case FsFgeom:
- f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
- snprintf(buf, sizeof(buf), "%d %d %d %d", f->rect.x, f->rect.y,
- f->rect.width, f->rect.height);
+ if(dir_type == FsDclient) {
+ f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
+ snprintf(buf, sizeof(buf), "%d %d %d %d", f->rect.x, f->rect.y,
+ f->rect.width, f->rect.height);
+ }
+ else {
+ Client *c = client[dir_i1];
+ snprintf(buf, sizeof(buf), "%d %d %d %d", c->rect.x, c->rect.y,
+ c->rect.width, c->rect.height);
+ }
return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE);
break;
case FsFsnap:
@@ -584,12 +617,20 @@ type2stat(Stat *stat, char *wname, Qid *dir)
return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE);
break;
case FsFname:
- f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
- return mkstat(stat, dir, wname, strlen(f->client->name), DMREAD);
+ if(dir_type == FsDclient) {
+ f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
+ return mkstat(stat, dir, wname, strlen(f->client->name), DMREAD);
+ }
+ else
+ return mkstat(stat, dir, wname, strlen(client[dir_i1]->name), DMREAD);
break;
case FsFtags:
- f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
- return mkstat(stat, dir, wname, strlen(f->client->tags), DMREAD | DMWRITE);
+ if(dir_type == FsDclient) {
+ f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
+ return mkstat(stat, dir, wname, strlen(f->client->tags), DMREAD | DMWRITE);
+ }
+ else
+ return mkstat(stat, dir, wname, strlen(client[dir_i1]->tags), DMREAD | DMWRITE);
break;
case FsFtag:
if(dir_type == FsDdef)
@@ -720,6 +761,26 @@ xread(IXPConn *c, Fcall *fcall)
p = ixp_enc_stat(p, &stat);
}
break;
+ case FsDclients:
+ /* jump to offset */
+ len = 0;
+ for(i = 0; i < nclient; i++) {
+ snprintf(buf, sizeof(buf), "%u", i);
+ len += type2stat(&stat, buf, &m->qid);
+ if(len <= fcall->offset)
+ continue;
+ break;
+ }
+ /* offset found, proceeding */
+ for(; i < nclient; i++) {
+ snprintf(buf, sizeof(buf), "%u", i);
+ len = type2stat(&stat, buf, &m->qid);
+ if(fcall->count + len > fcall->iounit)
+ break;
+ fcall->count += len;
+ p = ixp_enc_stat(p, &stat);
+ }
+ break;
case FsDbar:
/* jump to offset */
len = type2stat(&stat, "expand", &m->qid);
@@ -819,6 +880,8 @@ xread(IXPConn *c, Fcall *fcall)
p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "tags", &m->qid);
p = ixp_enc_stat(p, &stat);
+ fcall->count += type2stat(&stat, "clients", &m->qid);
+ p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "ws", &m->qid);
p = ixp_enc_stat(p, &stat);
break;
@@ -831,6 +894,16 @@ xread(IXPConn *c, Fcall *fcall)
p = ixp_enc_stat(p, &stat);
}
break;
+ case FsDclients:
+ for(i = 0; i < nclient; i++) {
+ snprintf(buf, sizeof(buf), "%u", i);
+ len = type2stat(&stat, buf, &m->qid);
+ if(fcall->count + len > fcall->iounit)
+ break;
+ fcall->count += len;
+ p = ixp_enc_stat(p, &stat);
+ }
+ break;
case FsDtags:
for(i = 0; i < nctag; i++) {
len = type2stat(&stat, ctag[i], &m->qid);
@@ -909,8 +982,9 @@ xread(IXPConn *c, Fcall *fcall)
p = ixp_enc_stat(p, &stat);
}
break;
+ case FsDGclient:
case FsDclient:
- fcall->count += type2stat(&stat, "name", &m->qid);
+ fcall->count = type2stat(&stat, "name", &m->qid);
p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "tags", &m->qid);
p = ixp_enc_stat(p, &stat);
@@ -933,9 +1007,16 @@ xread(IXPConn *c, Fcall *fcall)
memcpy(p, buf, fcall->count);
break;
case FsFgeom:
- f = tag[i1]->area[i2]->frame[i3];
- snprintf(buf, sizeof(buf), "%d %d %d %d", f->rect.x, f->rect.y,
- f->rect.width, f->rect.height);
+ if(m->qid.dir_type == FsDclient) {
+ f = tag[i1]->area[i2]->frame[i3];
+ snprintf(buf, sizeof(buf), "%d %d %d %d", f->rect.x, f->rect.y,
+ f->rect.width, f->rect.height);
+ }
+ else {
+ Client *c = client[i1];
+ snprintf(buf, sizeof(buf), "%d %d %d %d", c->rect.x, c->rect.y,
+ c->rect.width, c->rect.height);
+ }
fcall->count = strlen(buf);
memcpy(p, buf, fcall->count);
break;
@@ -945,12 +1026,24 @@ xread(IXPConn *c, Fcall *fcall)
memcpy(p, buf, fcall->count);
break;
case FsFname:
- if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->name)))
- memcpy(p, tag[i1]->area[i2]->frame[i3]->client->name, fcall->count);
+ if(m->qid.dir_type == FsDclient) {
+ if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->name)))
+ memcpy(p, tag[i1]->area[i2]->frame[i3]->client->name, fcall->count);
+ }
+ else {
+ if((fcall->count = strlen(client[i1]->name)))
+ memcpy(p, client[i1]->name, fcall->count);
+ }
break;
case FsFtags:
- if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->tags)))
- memcpy(p, tag[i1]->area[i2]->frame[i3]->client->tags, fcall->count);
+ if(m->qid.dir_type == FsDclient) {
+ if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->tags)))
+ memcpy(p, tag[i1]->area[i2]->frame[i3]->client->tags, fcall->count);
+ }
+ else {
+ if((fcall->count = strlen(client[i1]->tags)))
+ memcpy(p, client[i1]->tags, fcall->count);
+ }
break;
case FsFexpand:
snprintf(buf, sizeof(buf), "%u", iexpand);
@@ -1033,7 +1126,7 @@ xwrite(IXPConn *c, Fcall *fcall)
if((i1 == -1) || (i2 == -1) || (i3 == -1))
return Enofile;
- switch (qpath_type(m->qid.path)) {
+ switch(type) {
case FsFctl:
if(fcall->count > sizeof(buf) - 1)
return Enocommand;
@@ -1071,6 +1164,12 @@ xwrite(IXPConn *c, Fcall *fcall)
else if(!strncmp(buf, "sendtoarea ", 11))
sendtoarea_client(f->client, &buf[11]);
break;
+ case FsDGclient:
+ if(!strncmp(buf, "kill", 5))
+ kill_client(client[i1]);
+ else if(!strncmp(buf, "sendtoarea ", 11))
+ sendtoarea_client(client[i1], &buf[11]);
+ break;
default:
break;
}
@@ -1097,21 +1196,31 @@ xwrite(IXPConn *c, Fcall *fcall)
resize_all_clients();
break;
case FsFtags:
- f = tag[i1]->area[i2]->frame[i3];
- if(fcall->count > sizeof(f->client->tags))
- return "tags value too long";
- memcpy(f->client->tags, fcall->data, fcall->count);
- f->client->tags[fcall->count] = 0;
+ if(m->qid.dir_type == FsDclient) {
+ f = tag[i1]->area[i2]->frame[i3];
+ if(fcall->count > sizeof(f->client->tags))
+ return "tags value too long";
+ memcpy(f->client->tags, fcall->data, fcall->count);
+ f->client->tags[fcall->count] = 0;
+ }
+ else {
+ if(fcall->count > sizeof(client[i1]->tags))
+ return "tags value too long";
+ memcpy(client[i1]->tags, fcall->data, fcall->count);
+ client[i1]->tags[fcall->count] = 0;
+ }
update_ctags();
break;
case FsFgeom:
- f = tag[i1]->area[i2]->frame[i3];
if(fcall->count > sizeof(buf))
return "geometry values out of range";
memcpy(buf, fcall->data, fcall->count);
buf[fcall->count] = 0;
- blitz_strtorect(&rect, &f->rect, buf);
- resize_client(f->client, &f->rect, 0, False);
+ if(m->qid.dir_type == FsDclient) {
+ f = tag[i1]->area[i2]->frame[i3];
+ blitz_strtorect(&rect, &f->rect, buf);
+ resize_client(f->client, &f->rect, 0, False);
+ }
break;
case FsFexpand:
{
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -47,7 +47,9 @@ enum {
FsDdef,
FsDws,
FsDarea,
+ FsDclients,
FsDclient,
+ FsDGclient,
FsDkeys,
FsDtags,
FsDbar,
@@ -111,6 +113,7 @@ struct Frame {
};
struct Client {
+ unsigned short id;
char name[256];
char tags[256];
int proto;
@@ -234,7 +237,6 @@ void unmap_client(Client *c);
void map_client(Client *c);
void reparent_client(Client *c, Window w, int x, int y);
void attach_client(Client *c);
-void attach_totag(Tag *t, Client *c);
void detach_client(Client *c, Bool unmap);
Client *sel_client();
Client *sel_client_of_tag(Tag *t);
@@ -247,7 +249,7 @@ void select_client(Client *c, char *arg);
void sendtoarea_client(Client *c, char *arg);
void resize_all_clients();
void focus(Client *c);
-void detach_fromtag(Tag *t, Client *c, Bool unmap);
+int cid2index(unsigned short id);
/* event.c */
void init_x_event_handler();
@@ -291,6 +293,8 @@ int tag2index(Tag *t);
Bool has_ctag(char *tag);
void update_ctags();
Bool clientoftag(Tag *t, Client *c);
+void detach_fromtag(Tag *t, Client *c, Bool unmap);
+void attach_totag(Tag *t, Client *c);
/* wm.c */
void scan_wins();