wmii

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

commit 0309ac76c416c45ad74e18afbaf2270585cd6ca9
parent ca016a504b60bd6d4460f19084391c9396bfc1b0
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Wed,  8 Mar 2006 17:45:16 +0100

implemented /class namespace, which you can use to provide hints to the wm how to tag a specific class:instance of a client, ie echo -n ~gimp|wmiir create /class/Gimp:*, you can read the class:instance info ie via: wmiir read /ws/sel/sel/class


Diffstat:
cmd/wm/class.c | 48++++++++++++++++++++++++++----------------------
cmd/wm/fs.c | 308+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
cmd/wm/kb.c | 4++--
cmd/wm/wm.h | 8++++----
4 files changed, 225 insertions(+), 143 deletions(-)

diff --git a/cmd/wm/class.c b/cmd/wm/class.c @@ -8,8 +8,24 @@ #include "wm.h" +static TClass * +classinst2class(char *sclass, char *sinst) +{ + unsigned int i; + for(i = 0; i < nclass; i++) { + TClass *tc = class[i]; + if((!strncmp(tc->class, sclass, sizeof(tc->class)) || + !strncmp(tc->class, "*", sizeof(tc->class))) + && + (!strncmp(tc->instance, sinst, sizeof(tc->instance)) || + !strncmp(tc->instance, "*", sizeof(tc->instance)))) + return tc; + } + return nil; +} + TClass * -alloc_class(char *name, char *tags) +get_class(const char *name) { TClass *tc; char buf[256]; @@ -17,15 +33,19 @@ alloc_class(char *name, char *tags) static unsigned int id = 1; cext_strlcpy(buf, name, sizeof(buf)); - if(!(p = strchr(name, ':'))) + if(!(p = strchr(buf, ':'))) return nil; + *p = 0; + p++; + + if((tc = classinst2class(buf, p))) + return tc; + tc = cext_emallocz(sizeof(TClass)); tc->id = id++; cext_strlcpy(tc->class, buf, sizeof(tc->class)); cext_strlcpy(tc->instance, p, sizeof(tc->instance)); - cext_strlcpy(tc->tags, tags, sizeof(tc->tags)); - class = (TClass **)cext_array_attach((void **)class, tc, sizeof(TClass *), &classsz); nclass++; @@ -50,30 +70,14 @@ classid2index(unsigned short id) return -1; } -static TClass * -classinst2class(char *sclass, char *sinst) -{ - unsigned int i; - for(i = 0; i < nclass; i++) { - TClass *tc = class[i]; - if((!strncmp(tc->class, sclass, sizeof(tc->class)) || - !strncmp(tc->class, "*", sizeof(tc->class))) - && - (!strncmp(tc->instance, sinst, sizeof(tc->instance)) || - !strncmp(tc->instance, "*", sizeof(tc->instance)))) - return tc; - } - return nil; -} - TClass * -name2class(char *name) +name2class(const char *name) { char buf[256]; char *p; cext_strlcpy(buf, name, sizeof(buf)); - if(!(p = strchr(name, ':'))) + if(!(p = strchr(buf, ':'))) return nil; *p = 0; diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c @@ -126,7 +126,7 @@ decode_qpath(Qid *qid, unsigned char *type, int *i1, int *i2, int *i3) else { switch(*type) { case FsFkey: *i1 = kid2index(i1id); break; - case FsFclass: *i1 = classid2index(i1id); break; + case FsFclasstag: *i1 = classid2index(i1id); break; case FsFdata: case FsFcolors: case FsDlabel: *i1 = lid2index(i1id); break; @@ -147,7 +147,7 @@ qid2name(Qid *qid) { unsigned char type; int i1 = -1, i2 = -1, i3 = -1; - static char buf[32]; + static char buf[256]; decode_qpath(qid, &type, &i1, &i2, &i3); @@ -253,6 +253,12 @@ qid2name(Qid *qid) return "mode"; break; case FsFevent: return "event"; break; + case FsFclasstag: + if(i1 == -1) + return nil; + snprintf(buf, sizeof(buf), "%s:%s", class[i1]->class, class[i1]->instance); + return buf; + break; case FsFkey: if(i1 == -1) return nil; @@ -262,7 +268,7 @@ qid2name(Qid *qid) } } -static int +static unsigned char name2type(char *name, unsigned char dir_type) { unsigned int i; @@ -323,6 +329,8 @@ name2type(char *name, unsigned char dir_type) return FsFtag; if(has_ctag(name) && (dir_type == FsDtags)) return FsFtag; + if((dir_type == FsDclass) && name2class(name)) + return FsFclasstag; if((dir_type == FsDkeys) && name2key(name)) return FsFkey; if(!strncmp(name, "sel", 4)) @@ -345,8 +353,8 @@ static int mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) { unsigned char dir_type; - int dir_i1 = -1, dir_i2 = -1, dir_i3 = -1; - int type, i; + int dir_i1 = -1, dir_i2 = -1, dir_i3 = -1, i; + unsigned char type; decode_qpath(dir, &dir_type, &dir_i1, &dir_i2, &dir_i3); type = name2type(wname, dir_type); @@ -434,6 +442,17 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) return -1; new->path = mkqpath(FsDGclient, client[i]->id, 0, 0); break; + case FsFclasstag: + if(dir_type != FsDclass) + return -1; + { + TClass *tc; + if(!(tc = name2class(wname))) + return -1; + new->type = IXP_QTFILE; + new->path = mkqpath(FsFclasstag, tc->id, 0, 0); + } + break; case FsFkey: if(dir_type != FsDkeys) return -1; @@ -478,112 +497,6 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) return 0; } -static char * -xversion(IXPConn *c, Fcall *fcall) -{ - if(strncmp(fcall->version, IXP_VERSION, strlen(IXP_VERSION))) - return E9pversion; - else if(fcall->maxmsg > IXP_MAX_MSG) - fcall->maxmsg = IXP_MAX_MSG; - fcall->id = RVERSION; - ixp_server_respond_fcall(c, fcall); - return nil; -} - -static char * -xattach(IXPConn *c, Fcall *fcall) -{ - IXPMap *new = cext_emallocz(sizeof(IXPMap)); - new->qid = root_qid; - new->fid = fcall->fid; - c->map = (IXPMap **)cext_array_attach((void **)c->map, new, - sizeof(IXPMap *), &c->mapsz); - fcall->id = RATTACH; - fcall->qid = root_qid; - ixp_server_respond_fcall(c, fcall); - return nil; -} - -static char * -xwalk(IXPConn *c, Fcall *fcall) -{ - unsigned short nwqid = 0; - Qid dir = root_qid; - IXPMap *m; - - /*fprintf(stderr, "wm: xwalk: fid=%d\n", fcall->fid);*/ - if(!(m = ixp_server_fid2map(c, fcall->fid))) - return Enofid; - /*fprintf(stderr, "wm: xwalk1: fid=%d\n", fcall->fid);*/ - if(fcall->fid != fcall->newfid && (ixp_server_fid2map(c, fcall->newfid))) - return Enofid; - if(fcall->nwname) { - dir = m->qid; - for(nwqid = 0; (nwqid < fcall->nwname) - && !mkqid(&dir, fcall->wname[nwqid], &fcall->wqid[nwqid], True); nwqid++) - { - dir = fcall->wqid[nwqid]; - } - if(!nwqid) { - fprintf(stderr, "%s", "xwalk: no such file\n"); - return Enofile; - } - } - /* a fid will only be valid, if the walk was complete */ - if(nwqid == fcall->nwname) { - /*fprintf(stderr, "wm: xwalk4: newfid=%d\n", fcall->newfid);*/ - if(fcall->fid != fcall->newfid) { - m = cext_emallocz(sizeof(IXPMap)); - c->map = (IXPMap **)cext_array_attach((void **)c->map, m, - sizeof(IXPMap *), &c->mapsz); - } - m->qid = dir; - m->fid = fcall->newfid; - } - fcall->id = RWALK; - fcall->nwqid = nwqid; - ixp_server_respond_fcall(c, fcall); - return nil; -} - -static char * -xcreate(IXPConn *c, Fcall *fcall) -{ - IXPMap *m = ixp_server_fid2map(c, fcall->fid); - - if(!(fcall->mode | IXP_OWRITE)) - return Enomode; - if(!m) - return Enofid; - if(!strncmp(fcall->name, ".", 2) || !strncmp(fcall->name, "..", 3)) - return "illegal file name"; - if(qpath_type(m->qid.path) != FsDkeys) - return Enoperm; - grab_key(create_key(fcall->name)); - mkqid(&m->qid, fcall->name, &m->qid, False); - fcall->id = RCREATE; - fcall->qid = m->qid; - fcall->iounit = WMII_IOUNIT; - ixp_server_respond_fcall(c, fcall); - return nil; -} - -static char * -xopen(IXPConn *c, Fcall *fcall) -{ - IXPMap *m = ixp_server_fid2map(c, fcall->fid); - - if(!m) - return Enofid; - if(!(fcall->mode | IXP_OREAD) && !(fcall->mode | IXP_OWRITE)) - return Enomode; - fcall->id = ROPEN; - fcall->qid = m->qid; - fcall->iounit = WMII_IOUNIT; - ixp_server_respond_fcall(c, fcall); - return nil; -} - static unsigned int mkstat(Stat *stat, Qid *dir, char *name, unsigned long long length, unsigned int mode) { @@ -602,10 +515,9 @@ mkstat(Stat *stat, Qid *dir, char *name, unsigned long long length, unsigned int static unsigned int type2stat(Stat *stat, char *wname, Qid *dir) { - unsigned char dir_type; + unsigned char dir_type, type; int dir_i1 = 0, dir_i2 = 0, dir_i3 = 0; - int type; - char buf[32]; + char buf[256]; Frame *f; decode_qpath(dir, &dir_type, &dir_i1, &dir_i2, &dir_i3); @@ -685,6 +597,9 @@ type2stat(Stat *stat, char *wname, Qid *dir) return mkstat(stat, dir, wname, strlen(def.tag), DMREAD | DMWRITE); return mkstat(stat, dir, wname, 0, 0); break; + case FsFclasstag: + return mkstat(stat, dir, wname, strlen(class[dir_i1]->tags), DMREAD | DMWRITE); + break; case FsFkey: return mkstat(stat, dir, wname, 0, DMWRITE); break; @@ -710,6 +625,122 @@ type2stat(Stat *stat, char *wname, Qid *dir) } static char * +xversion(IXPConn *c, Fcall *fcall) +{ + if(strncmp(fcall->version, IXP_VERSION, strlen(IXP_VERSION))) + return E9pversion; + else if(fcall->maxmsg > IXP_MAX_MSG) + fcall->maxmsg = IXP_MAX_MSG; + fcall->id = RVERSION; + ixp_server_respond_fcall(c, fcall); + return nil; +} + +static char * +xattach(IXPConn *c, Fcall *fcall) +{ + IXPMap *new = cext_emallocz(sizeof(IXPMap)); + new->qid = root_qid; + new->fid = fcall->fid; + c->map = (IXPMap **)cext_array_attach((void **)c->map, new, + sizeof(IXPMap *), &c->mapsz); + fcall->id = RATTACH; + fcall->qid = root_qid; + ixp_server_respond_fcall(c, fcall); + return nil; +} + +static char * +xwalk(IXPConn *c, Fcall *fcall) +{ + unsigned short nwqid = 0; + Qid dir = root_qid; + IXPMap *m; + + /*fprintf(stderr, "wm: xwalk: fid=%d\n", fcall->fid);*/ + if(!(m = ixp_server_fid2map(c, fcall->fid))) + return Enofid; + /*fprintf(stderr, "wm: xwalk1: fid=%d\n", fcall->fid);*/ + if(fcall->fid != fcall->newfid && (ixp_server_fid2map(c, fcall->newfid))) + return Enofid; + if(fcall->nwname) { + dir = m->qid; + for(nwqid = 0; (nwqid < fcall->nwname) + && !mkqid(&dir, fcall->wname[nwqid], &fcall->wqid[nwqid], True); nwqid++) + { + dir = fcall->wqid[nwqid]; + } + if(!nwqid) { + fprintf(stderr, "%s", "xwalk: no such file\n"); + return Enofile; + } + } + /* a fid will only be valid, if the walk was complete */ + if(nwqid == fcall->nwname) { + /*fprintf(stderr, "wm: xwalk4: newfid=%d\n", fcall->newfid);*/ + if(fcall->fid != fcall->newfid) { + m = cext_emallocz(sizeof(IXPMap)); + c->map = (IXPMap **)cext_array_attach((void **)c->map, m, + sizeof(IXPMap *), &c->mapsz); + } + m->qid = dir; + m->fid = fcall->newfid; + } + fcall->id = RWALK; + fcall->nwqid = nwqid; + ixp_server_respond_fcall(c, fcall); + return nil; +} + +static char * +xcreate(IXPConn *c, Fcall *fcall) +{ + IXPMap *m = ixp_server_fid2map(c, fcall->fid); + unsigned char type; + + if(!(fcall->mode | IXP_OWRITE)) + return Enomode; + if(!m) + return Enofid; + if(!strncmp(fcall->name, ".", 2) || !strncmp(fcall->name, "..", 3)) + return "illegal file name"; + type = qpath_type(m->qid.path); + switch(type) { + case FsDkeys: + grab_key(get_key(fcall->name)); + break; + case FsDclass: + get_class(fcall->name); + break; + default: + return Enoperm; + break; + } + mkqid(&m->qid, fcall->name, &m->qid, False); + fcall->qid = m->qid; + fcall->id = RCREATE; + fcall->iounit = WMII_IOUNIT; + ixp_server_respond_fcall(c, fcall); + return nil; +} + +static char * +xopen(IXPConn *c, Fcall *fcall) +{ + IXPMap *m = ixp_server_fid2map(c, fcall->fid); + + if(!m) + return Enofid; + if(!(fcall->mode | IXP_OREAD) && !(fcall->mode | IXP_OWRITE)) + return Enomode; + fcall->id = ROPEN; + fcall->qid = m->qid; + fcall->iounit = WMII_IOUNIT; + ixp_server_respond_fcall(c, fcall); + return nil; +} + +static char * xremove(IXPConn *c, Fcall *fcall) { IXPMap *m = ixp_server_fid2map(c, fcall->fid); @@ -736,6 +767,12 @@ xremove(IXPConn *c, Fcall *fcall) draw_bar(); } break; + case FsFclasstag: + { + TClass *tc = class[i1]; + destroy_class(tc); + } + break; case FsFkey: { Key *k = key[i1]; @@ -759,7 +796,7 @@ xread(IXPConn *c, Fcall *fcall) IXPMap *m = ixp_server_fid2map(c, fcall->fid); unsigned char *p = fcall->data; unsigned int i, len; - char buf[32]; + char buf[256]; unsigned char type; int i1 = 0, i2 = 0, i3 = 0; Frame *f; @@ -791,6 +828,26 @@ xread(IXPConn *c, Fcall *fcall) p = ixp_enc_stat(p, &stat); } break; + case FsDclass: + /* jump to offset */ + len = 0; + for(i = 0; i < nclass; i++) { + snprintf(buf, sizeof(buf), "%s:%s", class[i]->class, class[i]->instance); + len += type2stat(&stat, buf, &m->qid); + if(len <= fcall->offset) + continue; + break; + } + /* offset found, proceeding */ + for(; i < nclass; i++) { + snprintf(buf, sizeof(buf), "%s:%s", class[i]->class, class[i]->instance); + 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: /* jump to offset */ len = 0; @@ -944,6 +1001,16 @@ xread(IXPConn *c, Fcall *fcall) p = ixp_enc_stat(p, &stat); } break; + case FsDclass: + for(i = 0; i < nclass; i++) { + snprintf(buf, sizeof(buf), "%s:%s", class[i]->class, class[i]->instance); + len = type2stat(&stat, buf, &m->qid); + if(fcall->count + len > fcall->iounit) + break; + fcall->count += len; + p = ixp_enc_stat(p, &stat); + } + break; case FsDclients: for(i = 0; i < nclient; i++) { snprintf(buf, sizeof(buf), "%u", i); @@ -1140,6 +1207,12 @@ xread(IXPConn *c, Fcall *fcall) if((fcall->count = strlen(def.font))) memcpy(p, def.font, fcall->count); break; + case FsFclasstag: + if(i1 >= nclass) + return Enofile; + if((fcall->count = strlen(class[i1]->tags))) + memcpy(p, class[i1]->tags, fcall->count); + break; case FsFmode: if(!i2) return Enofile; @@ -1373,6 +1446,11 @@ xwrite(IXPConn *c, Fcall *fcall) tag[i1]->area[i2]->mode = i; arrange_area(tag[i1]->area[i2]); break; + case FsFclasstag: + if(fcall->count > sizeof(class[i1]->tags)) + return "tags too long"; + memcpy(class[i1]->tags, fcall->data, fcall->count); + break; case FsFkey: break; default: diff --git a/cmd/wm/kb.c b/cmd/wm/kb.c @@ -87,7 +87,7 @@ ungrab_key(Key *k) } Key * -create_key(char *name) +get_key(const char *name) { char buf[128]; char *seq[8]; @@ -249,7 +249,7 @@ handle_key(Window w, unsigned long mod, KeyCode keycode) } Key * -name2key(char *name) +name2key(const char *name) { unsigned int i; for(i = 0; i < nkey; i++) diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -241,10 +241,10 @@ void update_bar_geometry(); unsigned int bar_height(); /* class.c */ -TClass *alloc_class(char *name, char *tags); +TClass *get_class(const char *name); void destroy_class(TClass *tclass); int classid2index(unsigned short id); -TClass *name2class(char *name); +TClass *name2class(const char *name); TClass *client2class(Client *c); /* client.c */ @@ -289,9 +289,9 @@ void new_ixp_conn(IXPConn *c); void handle_key(Window w, unsigned long mod, KeyCode keycode); void grab_key(Key *k); void ungrab_key(Key *k); -Key * name2key(char *name); +Key *name2key(const char *name); int kid2index(unsigned short id); -Key *create_key(char *name); +Key *get_key(const char *name); void destroy_key(Key *k); void init_lock_modifiers();