commit dcc6e16302cc4af440b9fa4f90ec0f22077fdd71
parent 421ac8babfb960f6e98cdbd377ffddbe2a068c14
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Sun, 5 Mar 2006 16:48:14 +0100
fixed mkqid to prevent issue reported by bogon
Diffstat:
3 files changed, 136 insertions(+), 63 deletions(-)
diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c
@@ -48,27 +48,28 @@ static char Enocommand[] = "command not supported";
* /bar/1/colors FsFcolors <#RRGGBB> <#RRGGBB> <#RRGGBB>
* /event FsFevent
* /ctl FsFctl command interface (root)
- * /new/ FsDtag returns new tag
- * /sel/ FsDtag sel tag
- * /1/ FsDtag tag
- * /1/ctl FsFctl command interface (tag)
- * /1/sel/ FsDarea
- * /1/float/ FsDarea floating clients in area 0
- * /1/float/ctl FsFctl command interface (area)
- * /1/float/mode FsFmode col mode
- * /1/float/sel/ FsDclient
- * /1/float/1/ FsDclient
- * /1/float/1/name FsFname name of client
- * /1/float/1/geom FsFgeom geometry of client
- * /1/float/1/ctl FsFctl command interface (client)
- * /1/1/ FsDarea
- * /1/1/ctl FsFctl command interface (area)
- * /1/1/mode FsFmode col mode
- * /1/1/1/sel/ FsDclient
- * /1/1/1/1/ FsDclient
- * /1/1/1/name FsFname name of client
- * /1/1/1/geom FsFgeom geometry of client
- * /1/1/1/ctl FsFctl command interface (client)
+ * /ws/ FsDws returns new tag
+ * /ws/ FsDws tag
+ * /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/tag FsFtag tag 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
+ * /ws/1/1/sel/ FsDclient
+ * /ws/1/1/1/ FsDclient
+ * /ws/1/1/name FsFname name of client
+ * /ws/1/1/tag FsFtag tag of client
+ * /ws/1/1/geom FsFgeom geometry of client
+ * /ws/1/1/ctl FsFctl command interface (client)
*/
Qid root_qid;
@@ -128,13 +129,13 @@ decode_qpath(Qid *qid, unsigned char *type, int *i1, int *i2, int *i3)
case FsFdata:
case FsFcolors:
case FsDlabel: *i1 = lid2index(i1id); break;
- default: *i1 = pid2index(i1id); break;
+ default: *i1 = tid2index(i1id); break;
}
- if(i2id && (*i1 != -1)) {
+ if(i2id && (*i1 != -1)) {
*i2 = aid2index(tag[*i1], i2id);
- if(i3id && (*i2 != -1))
- *i3 = frid2index(tag[*i1]->area[*i2], i3id);
- }
+ if(i3id && (*i2 != -1))
+ *i3 = frid2index(tag[*i1]->area[*i2], i3id);
+ }
}
}
@@ -142,29 +143,33 @@ static char *
qid2name(Qid *qid)
{
unsigned char type;
- int i1 = 0, i2 = 0, i3 = 0;
+ int i1 = -1, i2 = -1, i3 = -1;
static char buf[32];
decode_qpath(qid, &type, &i1, &i2, &i3);
- if((i1 == -1) || (i2 == -1) || (i3 == -1))
- return 0;
switch(type) {
case FsDroot: return "/"; break;
case FsDdef: return "def"; break;
case FsDkeys: return "keys"; break;
case FsDbar: return "bar"; break;
- case FsDtag:
+ case FsDws:
+ if(i1 == -1)
+ return nil;
if(i1 == sel)
return "sel";
snprintf(buf, sizeof(buf), "%u", i1);
return buf;
break;
case FsDlabel:
+ if(i1 == -1)
+ return nil;
snprintf(buf, sizeof(buf), "%u", i1);
return buf;
break;
case FsDarea:
+ if(i1 == -1 || i2 == -1)
+ return nil;
if(!i2) {
if(i2 == tag[i1]->sel)
return "sel";
@@ -177,6 +182,8 @@ qid2name(Qid *qid)
return buf;
break;
case FsDclient:
+ if(i1 == -1 || i2 == -1 || i3 == -1)
+ return nil;
if(tag[i1]->area[i2]->sel == i3)
return "sel";
snprintf(buf, sizeof(buf), "%u", i3);
@@ -186,16 +193,45 @@ qid2name(Qid *qid)
case FsFnormcolors: return "normcolors"; break;
case FsFfont: return "font"; break;
case FsFcolors: return "colors"; break;
- case FsFdata: return "data"; break;
- case FsFexpand: return "expand"; break;
+ case FsFdata:
+ if(i1 == -1)
+ return nil;
+ return "data";
+ break;
+ case FsFexpand:
+ if(i1 == -1)
+ return nil;
+ return "expand";
+ break;
case FsFctl: return "ctl"; break;
case FsFborder: return "border"; break;
- case FsFsnap: return "border"; break;
- case FsFgeom: return "geometry"; break;
- case FsFname: return "name"; break;
- case FsFmode: return "mode"; break;
+ case FsFsnap: return "snap"; break;
+ case FsFgeom:
+ if(i1 == -1 || i2 == -1 || i3 == -1)
+ return nil;
+ return "geom";
+ break;
+ case FsFname:
+ if(i1 == -1 || i2 == -1 || i3 == -1)
+ return nil;
+ return "name";
+ break;
+ case FsFtag:
+ if(i1 == -1 || i2 == -1 || i3 == -1)
+ return nil;
+ return "tag";
+ break;
+ case FsFmode:
+ if(i1 == -1 || i2 == -1)
+ return nil;
+ return "mode";
+ break;
case FsFevent: return "event"; break;
- case FsFkey: return key[i1]->name; break;
+ case FsFkey:
+ if(i1 == -1)
+ return nil;
+ return key[i1]->name;
+ break;
default: return nil; break;
}
}
@@ -208,7 +244,7 @@ name2type(char *name, unsigned char dir_type)
return FsDroot;
if(!strncmp(name, "new", 4)) {
switch(dir_type) {
- case FsDroot: return FsDtag; break;
+ case FsDroot: return FsDws; break;
case FsDbar: return FsDlabel; break;
}
}
@@ -226,9 +262,11 @@ name2type(char *name, unsigned char dir_type)
return FsFsnap;
if(!strncmp(name, "name", 5))
return FsFname;
+ if(!strncmp(name, "tag", 4))
+ return FsFtag;
if(!strncmp(name, "border", 7))
return FsFborder;
- if(!strncmp(name, "geometry", 9))
+ if(!strncmp(name, "geom", 5))
return FsFgeom;
if(!strncmp(name, "expand", 7))
return FsFexpand;
@@ -254,9 +292,9 @@ name2type(char *name, unsigned char dir_type)
dyndir:
/*fprintf(stderr, "nametotype: dir_type = %d\n", dir_type);*/
switch(dir_type) {
- case FsDroot: return FsDtag; break;
+ case FsDroot: return FsDws; break;
case FsDbar: return FsDlabel; break;
- case FsDtag: return FsDarea; break;
+ case FsDws: return FsDarea; break;
case FsDarea: return FsDclient; break;
}
return -1;
@@ -266,12 +304,10 @@ static int
mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
{
unsigned char dir_type;
- int dir_i1 = 0, dir_i2 = 0, dir_i3 = 0;
+ int dir_i1 = -1, dir_i2 = -1, dir_i3 = -1;
int type, i;
decode_qpath(dir, &dir_type, &dir_i1, &dir_i2, &dir_i3);
- if((dir_i1 == -1) || (dir_i2 == -1) || (dir_i3 == -1))
- return -1;
type = name2type(wname, dir_type);
new->dir_type = dir_type;
@@ -298,7 +334,7 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
if(iswalk)
new->path = mkqpath(FsDlabel, new_label()->id, 0, 0);
else
- new->path = mkqpath(FsDlabel, 0,0 ,0);
+ new->path = mkqpath(FsDlabel, 0, 0 ,0);
}
else {
i = cext_strtonum(wname, 0, 0xffff, &err);
@@ -307,29 +343,31 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
new->path = mkqpath(FsDlabel, label[i]->id, 0, 0);
}
break;
- case FsDtag:
+ case FsDws:
new->type = IXP_QTDIR;
if(!strncmp(wname, "new", 4)) {
if(iswalk) {
Tag *p = alloc_tag();
- new->path = mkqpath(FsDtag, p->id, 0, 0);
+ new->path = mkqpath(FsDws, p->id, 0, 0);
}
else
- new->path = mkqpath(FsDtag, 0, 0, 0);
+ new->path = mkqpath(FsDws, 0, 0, 0);
}
else if(!strncmp(wname, "sel", 4)) {
if(!ntag)
return -1;
- new->path = mkqpath(FsDtag, tag[sel]->id, 0, 0);
+ new->path = mkqpath(FsDws, tag[sel]->id, 0, 0);
}
else {
i = cext_strtonum(wname, 0, 0xffff, &err);
if(err || (i >= ntag))
return -1;
- new->path = mkqpath(FsDtag, tag[i]->id, 0, 0);
+ new->path = mkqpath(FsDws, tag[i]->id, 0, 0);
}
break;
case FsDarea:
+ if(dir_i1 == -1)
+ return -1;
{
Tag *p = tag[dir_i1];
new->type = IXP_QTDIR;
@@ -345,6 +383,8 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
}
break;
case FsDclient:
+ if(dir_i1 == -1 || dir_i2 == -1)
+ return -1;
{
Tag *p = tag[dir_i1];
Area *a = p->area[dir_i2];
@@ -373,8 +413,25 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
break;
case FsFdata:
case FsFcolors:
- if((dir_type == FsDlabel) && (dir_i1 >= nlabel))
+ if((dir_type == FsDlabel) && (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));
+ break;
+ case FsFmode:
+ if(dir_i1 == -1 || dir_i2 == -1)
+ return -1;
+ new->type = IXP_QTFILE;
+ new->path = mkqpath(type, qpath_i1id(dir->path), qpath_i2id(dir->path), qpath_i3id(dir->path));
+ break;
+ case FsFgeom:
+ case FsFname:
+ case FsFtag:
+ if(dir_i1 == -1 || dir_i2 == -1 || dir_i3 == -1)
+ return -1;
+ new->type = IXP_QTFILE;
+ new->path = mkqpath(type, qpath_i1id(dir->path), qpath_i2id(dir->path), qpath_i3id(dir->path));
+ break;
default:
new->type = IXP_QTFILE;
new->path = mkqpath(type, qpath_i1id(dir->path), qpath_i2id(dir->path), qpath_i3id(dir->path));
@@ -521,7 +578,7 @@ type2stat(Stat *stat, char *wname, Qid *dir)
switch (type) {
case FsDclient:
case FsDarea:
- case FsDtag:
+ case FsDws:
case FsDdef:
case FsDkeys:
case FsDbar:
@@ -551,6 +608,10 @@ type2stat(Stat *stat, char *wname, Qid *dir)
f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
return mkstat(stat, dir, wname, strlen(f->client->name), DMREAD);
break;
+ case FsFtag:
+ f = tag[dir_i1]->area[dir_i2]->frame[dir_i3];
+ return mkstat(stat, dir, wname, strlen(f->client->tag), DMREAD | DMWRITE);
+ break;
case FsFkey:
return mkstat(stat, dir, wname, 0, DMWRITE);
break;
@@ -589,7 +650,7 @@ xremove(IXPConn *c, Fcall *fcall)
if((i1 == -1) || (i2 == -1) || (i3 == -1))
return Enofile;
switch(type) {
- case FsDtag:
+ case FsDws:
if((ret = destroy_tag(tag[i1])))
return ret;
break;
@@ -714,7 +775,7 @@ xread(IXPConn *c, Fcall *fcall)
p = ixp_enc_stat(p, &stat);
}
break;
- case FsDtag:
+ case FsDws:
/* jump to offset */
len = type2stat(&stat, "ctl", &m->qid);
for(i = 0; i < tag[i1]->narea; i++) {
@@ -847,7 +908,7 @@ xread(IXPConn *c, Fcall *fcall)
fcall->count += type2stat(&stat, "font", &m->qid);
p = ixp_enc_stat(p, &stat);
break;
- case FsDtag:
+ case FsDws:
fcall->count = type2stat(&stat, "ctl", &m->qid);
p = ixp_enc_stat(p, &stat);
for(i = 0; i < tag[i1]->narea; i++) {
@@ -881,11 +942,11 @@ xread(IXPConn *c, Fcall *fcall)
}
break;
case FsDclient:
- fcall->count = type2stat(&stat, "border", &m->qid);
- p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "name", &m->qid);
p = ixp_enc_stat(p, &stat);
- fcall->count += type2stat(&stat, "geometry", &m->qid);
+ fcall->count += type2stat(&stat, "tag", &m->qid);
+ p = ixp_enc_stat(p, &stat);
+ fcall->count += type2stat(&stat, "geom", &m->qid);
p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "ctl", &m->qid);
p = ixp_enc_stat(p, &stat);
@@ -919,6 +980,10 @@ xread(IXPConn *c, Fcall *fcall)
if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->name)))
memcpy(p, tag[i1]->area[i2]->frame[i3]->client->name, fcall->count);
break;
+ case FsFtag:
+ if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->tag)))
+ memcpy(p, tag[i1]->area[i2]->frame[i3]->client->tag, fcall->count);
+ break;
case FsFexpand:
snprintf(buf, sizeof(buf), "%u", iexpand);
fcall->count = strlen(buf);
@@ -1016,7 +1081,7 @@ xwrite(IXPConn *c, Fcall *fcall)
else
return Enocommand;
break;
- case FsDtag:
+ case FsDws:
if(!strncmp(buf, "select ", 7))
select_area(tag[i1]->area[tag[i1]->sel], &buf[7]);
break;
@@ -1061,6 +1126,13 @@ xwrite(IXPConn *c, Fcall *fcall)
def.border = i;
resize_all_clients();
break;
+ case FsFtag:
+ f = tag[i1]->area[i2]->frame[i3];
+ if(fcall->count > sizeof(f->client->tag))
+ return "tag value too long";
+ memcpy(f->client->tag, fcall->data, fcall->count);
+ /* TODO: update_tags */
+ break;
case FsFgeom:
f = tag[i1]->area[i2]->frame[i3];
if(fcall->count > sizeof(buf))
diff --git a/cmd/wm/tag.c b/cmd/wm/tag.c
@@ -120,7 +120,7 @@ rectangles(unsigned int *num)
}
int
-pid2index(unsigned short id)
+tid2index(unsigned short id)
{
int i;
for(i = 0; i < ntag; i++)
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -53,7 +53,7 @@ enum {
enum {
FsDroot,
FsDdef,
- FsDtag,
+ FsDws,
FsDarea,
FsDclient,
FsDkeys,
@@ -73,6 +73,7 @@ enum {
FsFevent,
FsFctl,
FsFname,
+ FsFtag,
FsFmode
};
@@ -117,7 +118,7 @@ struct Frame {
struct Client {
char name[256];
- char tags[256];
+ char tag[256];
int proto;
unsigned int border;
Bool destroyed;
@@ -284,7 +285,7 @@ Tag *alloc_tag();
char *destroy_tag(Tag *t);
void focus_tag(Tag *t);
XRectangle *rectangles(unsigned int *num);
-int pid2index(unsigned short id);
+int tid2index(unsigned short id);
void select_tag(char *arg);
int tag2index(Tag *t);