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:
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);