wmii

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

commit ca016a504b60bd6d4460f19084391c9396bfc1b0
parent a829af6746bab86423766688a4748707f83cd0b6
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Wed,  8 Mar 2006 16:52:05 +0100

added class.c to provide a sane class/instance handling for clients


Diffstat:
cmd/wm/Makefile | 2+-
cmd/wm/class.c | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cmd/wm/fs.c | 53++++++++++++++++++++++++++++++++++++++++++++++++-----
cmd/wm/wm.c | 2++
cmd/wm/wm.h | 20++++++++++++++++++++
5 files changed, 159 insertions(+), 6 deletions(-)

diff --git a/cmd/wm/Makefile b/cmd/wm/Makefile @@ -9,7 +9,7 @@ LDFLAGS += -L../../liblitz -llitz -L../../libixp -lixp -L../../libcext -lcext # Solaris # LDFLAGS += -lsocket -SRC = area.c bar.c fs.c frame.c wm.c kb.c client.c event.c mouse.c tag.c +SRC = area.c bar.c class.c fs.c frame.c wm.c kb.c client.c event.c mouse.c tag.c OBJ = ${SRC:.c=.o} all: wmiiwm diff --git a/cmd/wm/class.c b/cmd/wm/class.c @@ -0,0 +1,88 @@ +/* + * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <string.h> +#include <stdlib.h> + +#include "wm.h" + +TClass * +alloc_class(char *name, char *tags) +{ + TClass *tc; + char buf[256]; + char *p; + static unsigned int id = 1; + + cext_strlcpy(buf, name, sizeof(buf)); + if(!(p = strchr(name, ':'))) + return nil; + + 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++; + + return tc; +} + +void +destroy_class(TClass *tclass) +{ + cext_array_detach((void **)class, tclass, &classsz); + nclass--; + free(tclass); +} + +int +classid2index(unsigned short id) +{ + int i; + for(i = 0; i < nclass; i++) + if(class[i]->id == id) + return i; + 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) +{ + char buf[256]; + char *p; + + cext_strlcpy(buf, name, sizeof(buf)); + if(!(p = strchr(name, ':'))) + return nil; + + *p = 0; + p++; + return classinst2class(buf, p); +} + +TClass * +client2class(Client *c) +{ + return classinst2class(c->class, c->instance); +} diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c @@ -49,6 +49,8 @@ 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> + * /class FsDclass class namespace to define client-specific tags + * /class/class:inst FsFclasstag * /clients/ FsDclients * /clients/1/ FsDGclient see /X/X/X/ namespace below * /event FsFevent @@ -59,9 +61,9 @@ static char Enocommand[] = "command not supported"; * /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/sel/ FsDclient * /ws/1/1/name FsFname name of client + * /ws/1/1/class FsFclass class:instance of client * /ws/1/1/tags FsFtags tag of client * /ws/1/1/geom FsFgeom geometry of client * /ws/1/1/ctl FsFctl command interface (client) @@ -74,10 +76,10 @@ const char *err; /** * Qid->path is calculated related to the index of the associated structure. - * i1 is associated to tag, key or label + * i1 is associated to tag, key, global client, class or label * i2 is associated to area * i3 is associated to client - * ie /sel/sel/ctl is i1id = sel tag id, i2id = sel area id , i3id = 0 (no id) + * ie /ws/sel/ctl is i1id = sel tag id, i2id = sel area id , i3id = 0 (no id) */ unsigned long long mkqpath(unsigned char type, unsigned short i1id, unsigned short i2id, unsigned short i3id) @@ -124,6 +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 FsFdata: case FsFcolors: case FsDlabel: *i1 = lid2index(i1id); break; @@ -152,6 +155,7 @@ qid2name(Qid *qid) case FsDroot: return "/"; break; case FsDdef: return "def"; break; case FsDkeys: return "keys"; break; + case FsDclass: return "class"; break; case FsDtags: return "tags"; break; case FsDclients: return "clients"; break; case FsDbar: return "bar"; break; @@ -222,6 +226,13 @@ qid2name(Qid *qid) return nil; return "geom"; break; + case FsFclass: + if((qid->dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1)) + return nil; + else if(i1 == -1) + return nil; + return "class"; + break; case FsFname: if((qid->dir_type == FsDclient) && (i1 == -1 || i2 == -1 || i3 == -1)) return nil; @@ -274,6 +285,12 @@ name2type(char *name, unsigned char dir_type) return FsDbar; if(!strncmp(name, "def", 4)) return FsDdef; + if(!strncmp(name, "class", 6)) { + if(dir_type == FsDroot) + return FsDclass; + else + return FsFclass; + } if(!strncmp(name, "keys", 5)) return FsDkeys; if(!strncmp(name, "ctl", 4)) @@ -341,6 +358,7 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) *new = root_qid; break; case FsDdef: + case FsDclass: case FsDkeys: case FsDtags: case FsDclients: @@ -441,6 +459,7 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) new->path = mkqpath(type, qpath_i1id(dir->path), qpath_i2id(dir->path), qpath_i3id(dir->path)); break; case FsFgeom: + case FsFclass: case FsFname: case FsFtags: if((dir_type == FsDclient) && ((dir_i1 == -1 || dir_i2 == -1 || dir_i3 == -1))) @@ -601,6 +620,7 @@ type2stat(Stat *stat, char *wname, Qid *dir) case FsDws: case FsDdef: case FsDkeys: + case FsDclass: case FsDtags: case FsDclients: case FsDbar: @@ -635,6 +655,15 @@ type2stat(Stat *stat, char *wname, Qid *dir) snprintf(buf, sizeof(buf), "%d", def.snap); return mkstat(stat, dir, wname, strlen(buf), DMREAD | DMWRITE); break; + case FsFclass: + if(dir_type == FsDclient) { + f = tag[dir_i1]->area[dir_i2]->frame[dir_i3]; + snprintf(buf, sizeof(buf), "%s:%s", f->client->class, f->client->instance); + } + else + snprintf(buf, sizeof(buf), "%s:%s", client[dir_i1]->class, client[dir_i1]->instance); + return mkstat(stat, dir, wname, strlen(buf), DMREAD); + break; case FsFname: if(dir_type == FsDclient) { f = tag[dir_i1]->area[dir_i2]->frame[dir_i3]; @@ -901,6 +930,8 @@ xread(IXPConn *c, Fcall *fcall) p = ixp_enc_stat(p, &stat); fcall->count += type2stat(&stat, "clients", &m->qid); p = ixp_enc_stat(p, &stat); + fcall->count += type2stat(&stat, "class", &m->qid); + p = ixp_enc_stat(p, &stat); fcall->count += type2stat(&stat, "ws", &m->qid); p = ixp_enc_stat(p, &stat); break; @@ -1003,7 +1034,9 @@ xread(IXPConn *c, Fcall *fcall) break; case FsDGclient: case FsDclient: - fcall->count = type2stat(&stat, "name", &m->qid); + fcall->count = type2stat(&stat, "class", &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, "tags", &m->qid); p = ixp_enc_stat(p, &stat); @@ -1044,6 +1077,16 @@ xread(IXPConn *c, Fcall *fcall) fcall->count = strlen(buf); memcpy(p, buf, fcall->count); break; + case FsFclass: + if(m->qid.dir_type == FsDclient) { + f = tag[i1]->area[i2]->frame[i3]; + snprintf(buf, sizeof(buf), "%s:%s", f->client->class, f->client->instance); + } + else + snprintf(buf, sizeof(buf), "%s:%s", client[i1]->class, client[i1]->instance); + fcall->count = strlen(buf); + memcpy(p, buf, fcall->count); + break; case FsFname: if(m->qid.dir_type == FsDclient) { if((fcall->count = strlen(tag[i1]->area[i2]->frame[i3]->client->name))) diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c @@ -315,6 +315,8 @@ main(int argc, char *argv[]) keysz = nkey = 0; label = nil; nlabel = labelsz = iexpand = 0; + class = nil; + nclass = classsz = 0; def.font = strdup(BLITZ_FONT); def.border = DEF_BORDER; diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -49,6 +49,7 @@ enum { FsDarea, FsDclients, FsDclient, + FsDclass, FsDGclient, FsDkeys, FsDtags, @@ -68,6 +69,8 @@ enum { FsFevent, FsFctl, FsFname, + FsFclass, + FsFclasstag, FsFtags, FsFtag, FsFmode @@ -134,6 +137,13 @@ struct Client { unsigned int nframe; }; +typedef struct { + unsigned short id; + char class[128]; + char instance[128]; + char tags[256]; +} TClass; + typedef struct Key Key; struct Key { unsigned short id; @@ -181,6 +191,9 @@ unsigned int iexpand; char **ctag; unsigned int nctag; unsigned int ctagsz; +TClass **class; +unsigned int nclass; +unsigned int classsz; Display *dpy; IXPServer *ixps; @@ -227,6 +240,13 @@ int lid2index(unsigned short id); void update_bar_geometry(); unsigned int bar_height(); +/* class.c */ +TClass *alloc_class(char *name, char *tags); +void destroy_class(TClass *tclass); +int classid2index(unsigned short id); +TClass *name2class(char *name); +TClass *client2class(Client *c); + /* client.c */ Client *alloc_client(Window w, XWindowAttributes *wa); void destroy_client(Client *c);