bar allows self-defined directories

This commit is contained in:
Anselm R. Garbe 2006-03-09 02:15:43 +01:00
parent a3cefb24b9
commit 407ed38930
6 changed files with 118 additions and 74 deletions

View File

@ -4,24 +4,40 @@
*/ */
#include <string.h> #include <string.h>
#include <stdlib.h>
#include "wm.h" #include "wm.h"
static int
comp_label(const void *l1, const void *l2)
{
Label *ll1 = (Label *)l1;
Label *ll2 = (Label *)l2;
return strcmp((const char *)ll1->name, (const char *)ll2->name);
}
Label * Label *
new_label() get_label(char *name)
{ {
static unsigned int id = 1; static unsigned int id = 1;
Label *l = cext_emallocz(sizeof(Label)); Label *l = name2label(name);
if(l)
return l;
l = cext_emallocz(sizeof(Label));
l->id = id++; l->id = id++;
cext_strlcpy(l->name, name, sizeof(l->name));
cext_strlcpy(l->colstr, def.selcolor, sizeof(l->colstr)); cext_strlcpy(l->colstr, def.selcolor, sizeof(l->colstr));
l->color = def.sel; l->color = def.sel;
label = (Label **)cext_array_attach((void **)label, l, sizeof(Label *), &labelsz); label = (Label **)cext_array_attach((void **)label, l, sizeof(Label *), &labelsz);
nlabel++; nlabel++;
qsort(label, nlabel, sizeof(Label *), comp_label);
return l; return l;
} }
void void
detach_label(Label *l) destroy_label(Label *l)
{ {
cext_array_detach((void **)label, l, &labelsz); cext_array_detach((void **)label, l, &labelsz);
nlabel--; nlabel--;
@ -118,6 +134,16 @@ draw_bar()
XSync(dpy, False); XSync(dpy, False);
} }
int
label2index(Label *l)
{
int i;
for(i = 0; i < nlabel; i++)
if(label[i] == l)
return i;
return -1;
}
int int
lid2index(unsigned short id) lid2index(unsigned short id)
{ {
@ -127,3 +153,16 @@ lid2index(unsigned short id)
return i; return i;
return -1; return -1;
} }
Label *
name2label(const char *name)
{
char buf[256];
unsigned int i;
cext_strlcpy(buf, name, sizeof(buf));
for(i = 0; i < nlabel; i++)
if(!strncmp(label[i]->name, name, sizeof(label[i]->name)))
return label[i];
return nil;
}

View File

@ -45,10 +45,9 @@ static char Enocommand[] = "command not supported";
* /tags/foo FsFtags * /tags/foo FsFtags
* /bar/ FsDbar * /bar/ FsDbar
* /bar/expand FsFexpand id of expandable label * /bar/expand FsFexpand id of expandable label
* /bar/new/ FsDlabel * /bar/lab/ FsDlabel
* /bar/1/ FsDlabel * /bar/lab/data FsFdata <arbitrary data which gets displayed>
* /bar/1/data FsFdata <arbitrary data which gets displayed> * /bar/lab/colors FsFcolors <#RRGGBB> <#RRGGBB> <#RRGGBB>
* /bar/1/colors FsFcolors <#RRGGBB> <#RRGGBB> <#RRGGBB>
* /class FsDclass class namespace to define client-specific tags * /class FsDclass class namespace to define client-specific tags
* /class/class:inst FsFclasstag * /class/class:inst FsFclasstag
* /clients/ FsDclients * /clients/ FsDclients
@ -130,7 +129,6 @@ decode_qpath(Qid *qid, unsigned char *type, int *i1, int *i2, int *i3)
case FsFdata: case FsFdata:
case FsFcolors: case FsFcolors:
case FsDlabel: *i1 = lid2index(i1id); break; case FsDlabel: *i1 = lid2index(i1id); break;
break;
default: *i1 = tid2index(i1id); break; default: *i1 = tid2index(i1id); break;
} }
} }
@ -171,8 +169,7 @@ qid2name(Qid *qid)
case FsDlabel: case FsDlabel:
if(i1 == -1) if(i1 == -1)
return nil; return nil;
snprintf(buf, sizeof(buf), "%u", i1); return label[i1]->name;
return buf;
break; break;
case FsDarea: case FsDarea:
if(i1 == -1 || i2 == -1) if(i1 == -1 || i2 == -1)
@ -274,8 +271,6 @@ name2type(char *name, unsigned char dir_type)
unsigned int i; unsigned int i;
if(!name || !name[0] || !strncmp(name, "/", 2) || !strncmp(name, "..", 3)) if(!name || !name[0] || !strncmp(name, "/", 2) || !strncmp(name, "..", 3))
return FsDroot; return FsDroot;
if(!strncmp(name, "new", 4) && (dir_type == FsDbar))
return FsDlabel;
if(!strncmp(name, "tags", 5)) { if(!strncmp(name, "tags", 5)) {
switch(dir_type) { switch(dir_type) {
case FsDroot: return FsDtags; break; case FsDroot: return FsDtags; break;
@ -329,6 +324,8 @@ name2type(char *name, unsigned char dir_type)
return FsFtag; return FsFtag;
if(has_tag(ctag, name, nctag) && (dir_type == FsDtags)) if(has_tag(ctag, name, nctag) && (dir_type == FsDtags))
return FsFtag; return FsFtag;
if((dir_type == FsDbar) && name2label(name))
return FsDlabel;
if((dir_type == FsDclass) && name2class(name)) if((dir_type == FsDclass) && name2class(name))
return FsFclasstag; return FsFclasstag;
if((dir_type == FsDkeys) && name2key(name)) if((dir_type == FsDkeys) && name2key(name))
@ -350,7 +347,7 @@ dyndir:
} }
static int static int
mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) mkqid(Qid *dir, char *wname, Qid *new)
{ {
unsigned char dir_type; unsigned char dir_type;
int dir_i1 = -1, dir_i2 = -1, dir_i3 = -1, i; int dir_i1 = -1, dir_i2 = -1, dir_i3 = -1, i;
@ -380,23 +377,6 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
new->type = IXP_QTDIR; new->type = IXP_QTDIR;
new->path = mkqpath(FsDws, ntag ? tag[sel]->id : 0, 0, 0); new->path = mkqpath(FsDws, ntag ? tag[sel]->id : 0, 0, 0);
break; break;
case FsDlabel:
if(dir_type != FsDbar)
return -1;
new->type = IXP_QTDIR;
if(!strncmp(wname, "new", 4)) {
if(iswalk)
new->path = mkqpath(FsDlabel, new_label()->id, 0, 0);
else
new->path = mkqpath(FsDlabel, 0, 0 ,0);
}
else {
i = cext_strtonum(wname, 0, 0xffff, &err);
if(err || (i >= nlabel))
return -1;
new->path = mkqpath(FsDlabel, label[i]->id, 0, 0);
}
break;
case FsDarea: case FsDarea:
if(dir_i1 == -1 || dir_type != FsDws) if(dir_i1 == -1 || dir_type != FsDws)
return -1; return -1;
@ -442,6 +422,17 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk)
return -1; return -1;
new->path = mkqpath(FsDGclient, client[i]->id, 0, 0); new->path = mkqpath(FsDGclient, client[i]->id, 0, 0);
break; break;
case FsDlabel:
if(dir_type != FsDbar)
return -1;
{
Label *l;
if(!(l = name2label(wname)))
return -1;
new->type = IXP_QTDIR;
new->path = mkqpath(FsDlabel, l->id, 0, 0);
}
break;
case FsFclasstag: case FsFclasstag:
if(dir_type != FsDclass) if(dir_type != FsDclass)
return -1; return -1;
@ -508,7 +499,7 @@ mkstat(Stat *stat, Qid *dir, char *name, unsigned long long length, unsigned int
cext_strlcpy(stat->name, name, sizeof(stat->name)); cext_strlcpy(stat->name, name, sizeof(stat->name));
stat->length = length; stat->length = length;
mkqid(dir, name, &stat->qid, False); mkqid(dir, name, &stat->qid);
return ixp_sizeof_stat(stat); return ixp_sizeof_stat(stat);
} }
@ -533,11 +524,11 @@ type2stat(Stat *stat, char *wname, Qid *dir)
case FsDdef: case FsDdef:
case FsDtags: case FsDtags:
case FsDclients: case FsDclients:
case FsDbar:
case FsDlabel: case FsDlabel:
case FsDroot: case FsDroot:
return mkstat(stat, dir, wname, 0, DMDIR | DMREAD | DMEXEC); return mkstat(stat, dir, wname, 0, DMDIR | DMREAD | DMEXEC);
break; break;
case FsDbar:
case FsDkeys: case FsDkeys:
case FsDclass: case FsDclass:
return mkstat(stat, dir, wname, 0, DMDIR | DMREAD | DMWRITE | DMEXEC); return mkstat(stat, dir, wname, 0, DMDIR | DMREAD | DMWRITE | DMEXEC);
@ -606,7 +597,7 @@ type2stat(Stat *stat, char *wname, Qid *dir)
return mkstat(stat, dir, wname, 0, DMWRITE); return mkstat(stat, dir, wname, 0, DMWRITE);
break; break;
case FsFexpand: case FsFexpand:
snprintf(buf, sizeof(buf), "%u", iexpand); snprintf(buf, sizeof(buf), "%s", iexpand >= nlabel ? "nil" : label[iexpand]->name);
return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE); return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE);
break; break;
case FsFdata: case FsFdata:
@ -659,16 +650,14 @@ xwalk(IXPConn *c, Fcall *fcall)
Qid dir = root_qid; Qid dir = root_qid;
IXPMap *m; IXPMap *m;
/*fprintf(stderr, "wm: xwalk: fid=%d\n", fcall->fid);*/
if(!(m = ixp_server_fid2map(c, fcall->fid))) if(!(m = ixp_server_fid2map(c, fcall->fid)))
return Enofid; return Enofid;
/*fprintf(stderr, "wm: xwalk1: fid=%d\n", fcall->fid);*/
if(fcall->fid != fcall->newfid && (ixp_server_fid2map(c, fcall->newfid))) if(fcall->fid != fcall->newfid && (ixp_server_fid2map(c, fcall->newfid)))
return Enofid; return Enofid;
if(fcall->nwname) { if(fcall->nwname) {
dir = m->qid; dir = m->qid;
for(nwqid = 0; (nwqid < fcall->nwname) for(nwqid = 0; (nwqid < fcall->nwname)
&& !mkqid(&dir, fcall->wname[nwqid], &fcall->wqid[nwqid], True); nwqid++) && !mkqid(&dir, fcall->wname[nwqid], &fcall->wqid[nwqid]); nwqid++)
{ {
dir = fcall->wqid[nwqid]; dir = fcall->wqid[nwqid];
} }
@ -679,7 +668,6 @@ xwalk(IXPConn *c, Fcall *fcall)
} }
/* a fid will only be valid, if the walk was complete */ /* a fid will only be valid, if the walk was complete */
if(nwqid == fcall->nwname) { if(nwqid == fcall->nwname) {
/*fprintf(stderr, "wm: xwalk4: newfid=%d\n", fcall->newfid);*/
if(fcall->fid != fcall->newfid) { if(fcall->fid != fcall->newfid) {
m = cext_emallocz(sizeof(IXPMap)); m = cext_emallocz(sizeof(IXPMap));
c->map = (IXPMap **)cext_array_attach((void **)c->map, m, c->map = (IXPMap **)cext_array_attach((void **)c->map, m,
@ -714,11 +702,16 @@ xcreate(IXPConn *c, Fcall *fcall)
case FsDclass: case FsDclass:
get_class(fcall->name); get_class(fcall->name);
break; break;
case FsDbar:
if(!strncmp(fcall->name, "expand", 7))
return "illegal file name";
get_label(fcall->name);
break;
default: default:
return Enoperm; return Enoperm;
break; break;
} }
mkqid(&m->qid, fcall->name, &m->qid, False); mkqid(&m->qid, fcall->name, &m->qid);
fcall->qid = m->qid; fcall->qid = m->qid;
fcall->id = RCREATE; fcall->id = RCREATE;
fcall->iounit = WMII_IOUNIT; fcall->iounit = WMII_IOUNIT;
@ -754,15 +747,17 @@ xremove(IXPConn *c, Fcall *fcall)
decode_qpath(&m->qid, &type, &i1, &i2, &i3); decode_qpath(&m->qid, &type, &i1, &i2, &i3);
if((i1 == -1) || (i2 == -1) || (i3 == -1)) if((i1 == -1) || (i2 == -1) || (i3 == -1))
return Enofile; return Enofile;
if(type != FsDlabel && type != FsFclasstag && type != FsFkey)
return Enoperm;
/* clunk */
cext_array_detach((void **)c->map, m, &c->mapsz);
free(m);
switch(type) { switch(type) {
case FsDlabel: case FsDlabel:
{ {
Label *l = label[i1]; Label *l = label[i1];
/* clunk */
cext_array_detach((void **)c->map, m, &c->mapsz);
free(m);
/* now detach the label */ /* now detach the label */
detach_label(l); destroy_label(l);
free(l); free(l);
if(iexpand >= nlabel) if(iexpand >= nlabel)
iexpand = 0; iexpand = 0;
@ -783,7 +778,6 @@ xremove(IXPConn *c, Fcall *fcall)
} }
break; break;
default: default:
return Enoperm;
break; break;
} }
fcall->id = RREMOVE; fcall->id = RREMOVE;
@ -891,18 +885,15 @@ xread(IXPConn *c, Fcall *fcall)
case FsDbar: case FsDbar:
/* jump to offset */ /* jump to offset */
len = type2stat(&stat, "expand", &m->qid); len = type2stat(&stat, "expand", &m->qid);
len += type2stat(&stat, "new", &m->qid);
for(i = 0; i < nlabel; i++) { for(i = 0; i < nlabel; i++) {
snprintf(buf, sizeof(buf), "%u", i); len += type2stat(&stat, label[i]->name, &m->qid);
len += type2stat(&stat, buf, &m->qid);
if(len <= fcall->offset) if(len <= fcall->offset)
continue; continue;
break; break;
} }
/* offset found, proceeding */ /* offset found, proceeding */
for(; i < nlabel; i++) { for(; i < nlabel; i++) {
snprintf(buf, sizeof(buf), "%u", i); len = type2stat(&stat, label[i]->name, &m->qid);
len = type2stat(&stat, buf, &m->qid);
if(fcall->count + len > fcall->iounit) if(fcall->count + len > fcall->iounit)
break; break;
fcall->count += len; fcall->count += len;
@ -1035,11 +1026,8 @@ xread(IXPConn *c, Fcall *fcall)
case FsDbar: case FsDbar:
fcall->count = type2stat(&stat, "expand", &m->qid); fcall->count = type2stat(&stat, "expand", &m->qid);
p = ixp_enc_stat(p, &stat); p = ixp_enc_stat(p, &stat);
fcall->count += type2stat(&stat, "new", &m->qid);
p = ixp_enc_stat(p, &stat);
for(i = 0; i < nlabel; i++) { for(i = 0; i < nlabel; i++) {
snprintf(buf, sizeof(buf), "%u", i); len = type2stat(&stat, label[i]->name, &m->qid);
len = type2stat(&stat, buf, &m->qid);
if(fcall->count + len > fcall->iounit) if(fcall->count + len > fcall->iounit)
break; break;
fcall->count += len; fcall->count += len;
@ -1177,9 +1165,8 @@ xread(IXPConn *c, Fcall *fcall)
} }
break; break;
case FsFexpand: case FsFexpand:
snprintf(buf, sizeof(buf), "%u", iexpand); fcall->count = strlen(iexpand >= nlabel ? "nil" : label[iexpand]->name);
fcall->count = strlen(buf); memcpy(p, iexpand >= nlabel ? "nil" : label[iexpand]->name, fcall->count);
memcpy(p, buf, fcall->count);
break; break;
case FsFdata: case FsFdata:
if(i1 >= nlabel) if(i1 >= nlabel)
@ -1361,13 +1348,12 @@ xwrite(IXPConn *c, Fcall *fcall)
break; break;
case FsFexpand: case FsFexpand:
{ {
const char *err; Label *l;
if(fcall->count && fcall->count < 16) { if(fcall->count && fcall->count < 16) {
memcpy(buf, fcall->data, fcall->count); memcpy(buf, fcall->data, fcall->count);
buf[fcall->count] = 0; buf[fcall->count] = 0;
i = (unsigned short) cext_strtonum(buf, 0, 0xffff, &err); if((l = name2label(buf))) {
if(!err && (i < nlabel)) { iexpand = label2index(l);
iexpand = i;
draw_bar(); draw_bar();
break; break;
} }

View File

@ -154,6 +154,7 @@ struct Key {
}; };
typedef struct { typedef struct {
char name[256];
unsigned short id; unsigned short id;
char data[256]; char data[256];
char colstr[24]; char colstr[24];
@ -233,12 +234,14 @@ char *mode2str(int mode);
Bool clientofarea(Area *a, Client *c); Bool clientofarea(Area *a, Client *c);
/* bar.c */ /* bar.c */
Label *new_label(); Label *get_label(char *name);
void detach_label(Label *l); void destroy_label(Label *l);
void draw_bar(); void draw_bar();
int lid2index(unsigned short id); int lid2index(unsigned short id);
void update_bar_geometry(); void update_bar_geometry();
unsigned int bar_height(); unsigned int bar_height();
Label *name2label(const char *name);
int label2index(Label *l);
/* class.c */ /* class.c */
TClass *get_class(const char *name); TClass *get_class(const char *name);

View File

@ -63,7 +63,6 @@ xcreate(char *file)
fprintf(stderr, "wmiir: cannot create file '%s': %s\n", p, c.errstr); fprintf(stderr, "wmiir: cannot create file '%s': %s\n", p, c.errstr);
return -1; return -1;
} }
write_data(fid);
return ixp_client_close(&c, fid); return ixp_client_close(&c, fid);
} }

View File

@ -12,12 +12,12 @@ xwrite() {
test -f $pidfile && kill `cat $pidfile` 2>/dev/null test -f $pidfile && kill `cat $pidfile` 2>/dev/null
echo $$ >$pidfile echo $$ >$pidfile
sleep 1 sleep 1
xwrite /bar/new/colors $WMII_NORMCOLORS wmiir create /bar/status
n=`wmiir read /bar | awk '/[0-9]+$/ {if($NF>max) max=$NF} END {print max}'` xwrite /bar/status/colors $WMII_NORMCOLORS
trap "wmiir remove /bar/$n 2>/dev/null; exit" 15 trap "wmiir remove /bar/status 2>/dev/null; exit" 15
while true while true
do do
xwrite /bar/$n/data `date` `uptime | sed 's/.*://; s/,//g'` || exit xwrite /bar/status/data `date` `uptime | sed 's/.*://; s/,//g'` || exit
sleep 1 sleep 1
done done

View File

@ -38,10 +38,9 @@ while wmiir remove /bar/0 2>/dev/null
do do
: :
done done
xwrite /bar/new/colors $WMII_NORMCOLORS wmiir create /bar/foo
xwrite /bar/new/colors $WMII_SELCOLORS xwrite /bar/foo/colors $WMII_SELCOLORS
xwrite /bar/0/data 1 xwrite /bar/expand foo
xwrite /bar/expand 1
# MISC # MISC
xsetroot -solid '#0b1014' xsetroot -solid '#0b1014'
@ -51,7 +50,7 @@ proglist $OLD_PATH >/tmp/ns.$USER.$DISPLAY/progs &
# SHORTCUTS # SHORTCUTS
while read key while read key
do do
echo -n | wmiir create /keys/$key wmiir create /keys/$key
done <<EOF done <<EOF
$MODKEY-Control-c $MODKEY-Control-c
$MODKEY-Control-w,y $MODKEY-Control-w,y
@ -71,7 +70,6 @@ $MODKEY-n
$MODKEY-m $MODKEY-m
$MODKEY-s $MODKEY-s
$MODKEY-equal $MODKEY-equal
$MODKEY-0
$MODKEY-1 $MODKEY-1
$MODKEY-2 $MODKEY-2
$MODKEY-3 $MODKEY-3
@ -81,7 +79,6 @@ $MODKEY-6
$MODKEY-7 $MODKEY-7
$MODKEY-8 $MODKEY-8
$MODKEY-9 $MODKEY-9
$MODKEY-Shift-0
$MODKEY-Shift-1 $MODKEY-Shift-1
$MODKEY-Shift-2 $MODKEY-Shift-2
$MODKEY-Shift-3 $MODKEY-Shift-3
@ -100,8 +97,28 @@ do
set -- $event set -- $event
type="$1"; shift type="$1"; shift
case "$type" in case "$type" in
NT)
wmiir create /bar/$1
xwrite /bar/$1/colors $WMII_NORMCOLORS
xwrite /bar/$1/data $1;;
RT)
wmiir remove /bar/$1;;
TF) TF)
xwrite /bar/0/data "$@";; if test -z "$old"
then
: # no old tag label
else
xwrite /bar/$old/data $old
fi
xwrite /bar/$1/data '*'$1
old=$1;;
LB)
if wmiir read /tags | awk "\$NF == $1 {exit 1}"
then
: # no tag label
else
xwrite /ctl select $1
fi;;
K) K)
case "$1" in case "$1" in
$MODKEY-Control-c) $MODKEY-Control-c)