commit 460620d711951e644ed451a03258641119fe2593
parent 06f4d727e656f5037bd647425788b495e417c578
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Sun, 29 Jan 2006 22:11:14 +0200
removed old wmiibar, now wmiibar2 is wmiibar
Diffstat:
| cmd/Makefile | | | 12 | +----------- |
| cmd/wmiibar.c | | | 1340 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------- |
| cmd/wmiibar2.c | | | 1084 | ------------------------------------------------------------------------------- |
3 files changed, 926 insertions(+), 1510 deletions(-)
diff --git a/cmd/Makefile b/cmd/Makefile
@@ -12,9 +12,6 @@ LDFLAGS2 += ${LIBS} -L../liblitz -llitz -L../libixp2 -lixp \
SRC_bar = wmiibar.c
OBJ_bar = ${SRC_bar:.c=.o}
-SRC_bar2 = wmiibar2.c
-OBJ_bar2 = ${SRC_bar2:.c=.o}
-
SRC_menu = wmiimenu.c
OBJ_menu = ${SRC_menu:.c=.o}
@@ -45,14 +42,7 @@ all: wmiibar wmiibar2 wmiimenu wmiir wmiir2 wmiifs wmiikeys wmiiplumb wmiiwarp
wmiibar: ${OBJ_bar}
@echo LD $@
- @${CC} -o $@ ${OBJ_bar} ${LDFLAGS}
-# Solaris
-# @${CC} -o $@ ${OBJ_bar} ${LDFLAGS} -lsocket
-
-
-wmiibar2: ${OBJ_bar2}
- @echo LD $@
- @${CC} -o $@ ${OBJ_bar2} ${LDFLAGS2}
+ @${CC} -o $@ ${OBJ_bar} ${LDFLAGS2}
# Solaris
# @${CC} -o $@ ${OBJ_bar2} ${LDFLAGS2} -lsocket
diff --git a/cmd/wmiibar.c b/cmd/wmiibar.c
@@ -9,69 +9,84 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
-#include <X11/Xlib.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
#include <X11/Xatom.h>
#include <X11/cursorfont.h>
#include <X11/Xproto.h>
#include <X11/Xutil.h>
+#include <sys/socket.h>
-#include "wmii.h"
-
-/* array indexes for file pointers */
-typedef enum {
- B_CTL,
- B_NEW,
- B_EXPANDABLE,
- B_GEOMETRY,
- B_FONT,
- B_FG_COLOR,
- B_BORDER_COLOR,
- B_BG_COLOR,
- B_EVENT_RESIZE,
- B_LAST
-} BarIndexes;
-
-typedef struct Item Item;
-struct Item {
- File *root;
- Draw d;
- Item *next;
+#include "../libixp2/ixp.h"
+#include "blitz.h"
+
+/*
+ * filesystem specification
+ * / Droot
+ * /display Fdisplay 'north', 'south', 'none'
+ * /font Ffont <xlib font name>
+ * /event Fevent
+ * /expand Fexpand id of expandable label
+ * /ctl Fctl command interface
+ * /new Dnew returns content of new item
+ * /default/ Ditem
+ * /default/color Fcolor <#RRGGBB> <#RRGGBB> <#RRGGBB>
+ * /1/ Ditem
+ * /1/data Fdata <arbitrary data which gets displayed>
+ * /1/color Fcolor <#RRGGBB> <#RRGGBB> <#RRGGBB>
+ */
+
+/* 8-bit qid.path.type */
+enum {
+ Droot,
+ Ditem,
+ Fctl,
+ Fdisplay,
+ Ffont,
+ Fexpand,
+ Fevent,
+ Fdata, /* data to display */
+ Fcolor
};
-static unsigned int id = 1;
-static IXPServer *ixps = 0;
+typedef struct {
+ char data[256];
+ char color[24];
+ unsigned long fg;
+ unsigned long bg;
+ unsigned long border;
+ XRectangle rect;
+} Item;
+
+static char E9pversion[] = "9P version not supported";
+static char Enoperm[] = "permission denied";
+static char Enofid[] = "fid not assigned";
+static char Enofile[] = "file not found";
+static char Enomode[] = "mode not supported";
+static char Enofunc[] = "function not supported";
+
+static unsigned char *msg[IXP_MAX_MSG];
+char *errstr = 0;
+static size_t nitem = 0;
+static size_t itemsz = 0;
+static size_t iexpand = 0;
+static Item **item = 0;
+static char *address = nil;
+static pid_t mypid = 0;
+static IXPServer srv = { 0 };
+static Qid root_qid;
static Display *dpy;
+static int screen_num;
+static char *font = nil;
+static Align align = CENTER;
+static XFontStruct *xfont;
static GC gc;
static Window win;
-static XRectangle rect;
-static XRectangle brect;
-static int screen_num;
-static Bool displayed = False;
-static char *sockfile = nil;
-static File *file[B_LAST];
-static Item *items = nil;
-static size_t nitems = 0;
+static XRectangle brect, rect;
static Pixmap pmap;
-static XFontStruct *font;
-static Align align = SOUTH;
-
-static Draw zero_draw = { 0 };
-
-static void draw_bar(void *obj, char *arg);
-static void quit(void *obj, char *arg);
-static void display(void *obj, char *arg);
-static void reset(void *obj, char *arg);
-static void xdestroy(void *obj, char *arg);
-static void handle_after_write(IXPServer * s, File * f);
-
-static Action acttbl[] = {
- {"quit", quit},
- {"display", display},
- {"update", draw_bar},
- {"reset", reset},
- {"destroy", xdestroy},
- {0, 0}
-};
+
+static void do_pend_fcall(char *event);
static char *version[] = {
"wmiibar - window manager improved bar - " VERSION "\n"
@@ -81,399 +96,883 @@ static char *version[] = {
static void
usage()
{
- fprintf(stderr, "%s",
- "usage: wmiibar -s <socket file> [-v]\n"
- " -s socket file\n" " -v version info\n");
+ fprintf(stderr, "%s %d",
+ "usage: wmiibar -a <server address> [-v]\n"
+ " -a server address \n"
+ " -v version info\n", 0);
exit(1);
}
-/**
- * <path>/data "<txt value>"
- * <path>/fgcolor "#RRGGBBAA"
- * <path>/bgcolor "#RRGGBBAA"
- * <path>/bordercolor "#RRGGBBAA"
- * <path>/b1press "<command>"
- * <path>/b2press "<command>"
- * <path>/b3press "<command>"
- * <path>/b4press "<command>"
- * <path>/b5press "<command>"
- */
-static void
-create_label(char *path)
+static int
+dummy_error_handler(Display * dpy, XErrorEvent * err)
{
- File *f;
- char buf[MAX_BUF];
- int i;
+ return 0;
+}
- snprintf(buf, MAX_BUF, "%s/data", path);
- f = ixp_create(ixps, buf);
- f->after_write = handle_after_write;
- snprintf(buf, MAX_BUF, "%s/fgcolor", path);
- wmii_create_ixpfile(ixps, buf, file[B_FG_COLOR]->content);
- snprintf(buf, MAX_BUF, "%s/bgcolor", path);
- wmii_create_ixpfile(ixps, buf, file[B_BG_COLOR]->content);
- snprintf(buf, MAX_BUF, "%s/bordercolor", path);
- wmii_create_ixpfile(ixps, buf, file[B_BORDER_COLOR]->content);
- for(i = 1; i < 6; i++) { /* 5 buttons events */
- snprintf(buf, MAX_BUF, "%s/b%dpress", path, i);
- ixp_create(ixps, buf);
- }
+static void
+new_item()
+{
+ Item *it = cext_emallocz(sizeof(Item));
+ if(nitem > 0) {
+ cext_strlcpy(it->color, item[0]->color, sizeof(it->color));
+ it->fg = item[0]->fg;
+ it->bg = item[0]->bg;
+ it->border = item[0]->border;
+ }
+ item = (Item **)cext_array_attach((void **)item, it, sizeof(Item *), &itemsz);
+ nitem++;
}
static void
-xdestroy(void *obj, char *arg)
+detach_item(Item *it)
{
- char buf[512];
- if(!arg)
- return;
- snprintf(buf, sizeof(buf), "/%s", arg);
- ixps->remove(ixps, buf);
- draw_bar(0, 0);
+ cext_array_detach((void **)item, it, &itemsz);
+ nitem--;
}
static void
-reset(void *obj, char *arg)
+draw()
{
- int i;
- char buf[512];
- for(i = 1; i <= id; i++) {
- snprintf(buf, sizeof(buf), "/%d", i);
- ixps->remove(ixps, buf);
- }
- id = 1;
- draw_bar(0, 0);
+ size_t i;
+ unsigned int w = 0;
+ Draw d = { 0 };
+
+ d.gc = gc;
+ d.drawable = pmap;
+ d.rect = brect;
+ d.rect.y = 0;
+ d.font = xfont;
+
+ if(nitem == 1) { /* /default only */
+ d.fg = item[0]->fg;
+ d.bg = item[0]->bg;
+ d.border = item[0]->border;
+ blitz_drawlabel(dpy, &d);
+ }
+ else {
+ if(!iexpand)
+ iexpand = nitem - 1;
+ for(i = 1; i < nitem; i++) {
+ Item *it = item[i];
+ it->rect.x = it->rect.y = 0;
+ it->rect.width = it->rect.height = brect.height;
+ if(i == iexpand)
+ continue;
+ if(strlen(it->data)) {
+ if(!strncmp(it->data, "%m:", 3))
+ it->rect.width = brect.height / 2;
+ else
+ it->rect.width += XTextWidth(xfont, it->data, strlen(it->data));
+ }
+ w += it->rect.width;
+ }
+ if(w >= brect.width) {
+ /* failsafe mode, give all labels same width */
+ w = brect.width / nitem;
+ for(i = 1; i < nitem; i++)
+ item[i]->rect.width = w;
+ i--;
+ item[i]->rect.width = brect.width - ((i - 1) * w);
+ } else
+ item[iexpand]->rect.width = brect.width - w;
+ for(i = 1; i < nitem; i++) {
+ d.fg = item[i]->fg;
+ d.bg = item[i]->bg;
+ d.border = item[i]->border;
+ if(i > 1)
+ item[i]->rect.x = item[i - 1]->rect.x + item[i - 1]->rect.width;
+ d.rect = item[i]->rect;
+ d.data = item[i]->data;
+ if(d.data && !strncmp(d.data, "%m:", 3))
+ blitz_drawmeter(dpy, &d);
+ else
+ blitz_drawlabel(dpy, &d);
+ }
+ }
+ XCopyArea(dpy, pmap, win, gc, 0, 0, brect.width, brect.height, 0, 0);
+ XSync(dpy, False);
}
static void
-quit(void *obj, char *arg)
+update_color(Item *it)
{
- ixps->runlevel = SHUTDOWN;
+ it->fg = blitz_loadcolor(dpy, screen_num, &it->color[0]);
+ it->bg = blitz_loadcolor(dpy, screen_num, &it->color[8]);
+ it->border = blitz_loadcolor(dpy, screen_num, &it->color[16]);
}
static void
-display(void *obj, char *arg)
-{
- if(!arg)
- return;
- displayed = blitz_strtonum(arg, 0, 1);
- if(displayed) {
- XMapRaised(dpy, win);
- draw_bar(0, 0);
- } else {
- XUnmapWindow(dpy, win);
- XSync(dpy, False);
- }
+update_geometry()
+{
+ char buf[64];
+ brect = rect;
+ brect.height = xfont->ascent + xfont->descent + 4;
+ if(align == SOUTH)
+ brect.y = rect.height - brect.height;
+ XMoveResizeWindow(dpy, win, brect.x, brect.y, brect.width, brect.height);
+ XSync(dpy, False);
+ XFreePixmap(dpy, pmap);
+ pmap = XCreatePixmap(dpy, win, brect.width, brect.height,
+ DefaultDepth(dpy, screen_num));
+ XSync(dpy, False);
+ snprintf(buf, sizeof(buf), "NewGeometry %d %d %d %d\n", brect.x, brect.y, brect.width, brect.height);
+ do_pend_fcall(buf);
+ draw();
}
static void
-init_draw_label(char *path, Draw * d)
-{
- char buf[MAX_BUF];
- File *f;
-
- /* text stuff */
- snprintf(buf, MAX_BUF, "%s/data", path);
- f = ixp_walk(ixps, buf);
- d->data = f->content;
- /* style stuff */
- snprintf(buf, MAX_BUF, "%s/fgcolor", path);
- f = ixp_walk(ixps, buf);
- d->fg = blitz_loadcolor(dpy, screen_num, f->content);
- snprintf(buf, MAX_BUF, "%s/bgcolor", path);
- f = ixp_walk(ixps, buf);
- d->bg = blitz_loadcolor(dpy, screen_num, f->content);
- snprintf(buf, MAX_BUF, "%s/bordercolor", path);
- f = ixp_walk(ixps, buf);
- d->border = blitz_loadcolor(dpy, screen_num, f->content);
+handle_buttonpress(XButtonPressedEvent * e)
+{
+ size_t i;
+ char buf[32];
+ for(i = 0; i < nitem; i++)
+ if(blitz_ispointinrect(e->x, e->y, &item[i]->rect)) {
+ snprintf(buf, sizeof(buf), "Button%dPress %d\n", e->button, i);
+ do_pend_fcall(buf);
+ }
}
static void
-init_item(char *path, Item * i)
+check_x_event(IXPServer *s, IXPConn *c)
+{
+ XEvent e;
+
+ while(XPending(dpy)) {
+ XNextEvent(dpy, &e);
+ switch (e.type) {
+ case ButtonPress:
+ handle_buttonpress(&e.xbutton);
+ break;
+ case Expose:
+ if(e.xexpose.count == 0)
+ draw();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+/* IXP stuff */
+
+static unsigned long long
+mkqpath(unsigned char type, unsigned short item)
{
- i->d = zero_draw;
- i->root = ixp_walk(ixps, path);
- i->d.gc = gc;
- i->d.drawable = pmap;
- i->d.rect = brect;
- i->d.rect.y = 0;
- init_draw_label(path, &i->d);
+ return ((unsigned long long) item << 8) | (unsigned long long) type;
+}
+
+static unsigned char
+qpath_type(unsigned long long path)
+{
+ return path & 0xff;
+}
+
+static unsigned short
+qpath_item(unsigned long long path)
+{
+ return (path >> 8) & 0xffff;
+}
+
+static char *
+qid_to_name(Qid *qid)
+{
+ unsigned char type = qpath_type(qid->path);
+ unsigned short i = qpath_item(qid->path);
+ static char buf[32];
+
+ switch(type) {
+ case Droot: return "/"; break;
+ case Ditem:
+ if(!i)
+ return "default";
+ else if(i == nitem)
+ return "new";
+ snprintf(buf, sizeof(buf), "%u", i);
+ return buf;
+ break;
+ case Fctl: return "ctl"; break;
+ case Fdisplay: return "display"; break;
+ case Ffont: return "font"; break;
+ case Fexpand: return "expand"; break;
+ case Fdata: return "data"; break;
+ case Fevent: return "event"; break;
+ case Fcolor: return "color"; break;
+ default: return nil; break;
+ }
}
static int
-comp_str(const void *s1, const void *s2)
+name_to_type(char *name)
{
- return strcmp(*(char **) s1, *(char **) s2);
+ const char *err;
+ unsigned int i;
+ if(!name || !name[0] || !strncmp(name, "/", 2) || !strncmp(name, "..", 3))
+ return Droot;
+ if(!strncmp(name, "default", 8) || !strncmp(name, "new", 4))
+ return Ditem;
+ if(!strncmp(name, "ctl", 4))
+ return Fctl;
+ if(!strncmp(name, "display", 8))
+ return Fdisplay;
+ if(!strncmp(name, "font", 5))
+ return Ffont;
+ if(!strncmp(name, "expand", 7))
+ return Fexpand;
+ if(!strncmp(name, "data", 5))
+ return Fdata;
+ if(!strncmp(name, "event", 6))
+ return Fevent;
+ if(!strncmp(name, "color", 6))
+ return Fcolor;
+ i = (unsigned short) cext_strtonum(name, 1, 0xffff, &err);
+ if(!err && (i <= nitem))
+ return Ditem;
+ return -1;
}
-static void
-draw()
+static int
+mkqid(Qid *dir, char *wname, Qid *new)
{
- Item *i;
- unsigned int idx = 0, w = 0, xoff = 0;
- unsigned expandable = 0;
- char buf[32];
-
- if(!nitems)
- return;
-
- expandable = blitz_strtonum(file[B_EXPANDABLE]->content, 1, nitems + 1);
- snprintf(buf, sizeof(buf), "/%d", expandable);
- expandable--;
- if(!ixp_walk(ixps, buf))
- expandable = 0;
-
- /* precalc */
- for(i = items; i; i = i->next) {
- if(idx != expandable) {
- i->d.rect.width = brect.height;
- if(i->d.data) {
- if(!strncmp(i->d.data, "%m:", 3))
- /* meter */
- i->d.rect.width = brect.height / 2;
- else
- i->d.rect.width +=
- XTextWidth(font, i->d.data, strlen(i->d.data));
- }
- w += i->d.rect.width;
+ const char *err;
+ int type = name_to_type(wname);
+ unsigned short i = qpath_item(dir->path);
+
+ if((dir->type != IXP_QTDIR) || (type == -1))
+ return -1;
+
+ new->version = 0;
+ switch(type) {
+ case Droot:
+ new->type = IXP_QTDIR;
+ *new = root_qid;
+ break;
+ case Ditem:
+ new->type = IXP_QTDIR;
+ if(!strncmp(wname, "default", 8))
+ new->path = mkqpath(Ditem, 0);
+ else if(!strncmp(wname, "new", 4))
+ new->path = mkqpath(Ditem, nitem);
+ else {
+ unsigned short i = cext_strtonum(wname, 1, 0xffff, &err);
+ if(err || (i >= nitem))
+ return -1;
+ new->path = mkqpath(Ditem, i);
+ }
+ break;
+ case Fdata: /* note, Fdata needs to be before Fcolor, fallthrough */
+ if(!i)
+ return -1;
+ case Fcolor:
+ if(i > nitem)
+ return -1;
+ default:
+ new->type = IXP_QTFILE;
+ new->path = mkqpath(type, i);
+ break;
+ }
+ return 0;
+}
+
+static int
+xversion(IXPConn *c)
+{
+ if(strncmp(c->fcall->version, IXP_VERSION, strlen(IXP_VERSION))) {
+ errstr = E9pversion;
+ return -1;
+ } else if(c->fcall->maxmsg > IXP_MAX_MSG)
+ c->fcall->maxmsg = IXP_MAX_MSG;
+ c->fcall->id = RVERSION;
+ return 0;
+}
+
+static int
+xattach(IXPConn *c)
+{
+ IXPMap *new = cext_emallocz(sizeof(IXPMap));
+ new->qid = root_qid;
+ new->fid = c->fcall->fid;
+ c->map = (IXPMap **)cext_array_attach((void **)c->map, new,
+ sizeof(IXPMap *), &c->mapsz);
+ c->fcall->id = RATTACH;
+ c->fcall->qid = root_qid;
+ return 0;
+}
+
+static int
+xwalk(IXPConn *c)
+{
+ unsigned short nwqid = 0;
+ Qid dir = root_qid;
+ IXPMap *m;
+
+ if(!(m = ixp_server_fid2map(c, c->fcall->fid))) {
+ errstr = Enofid;
+ return -1;
+ }
+ if(c->fcall->fid != c->fcall->newfid
+ && (ixp_server_fid2map(c, c->fcall->newfid))) {
+ errstr = Enofid;
+ return -1;
+ }
+ if(c->fcall->nwname) {
+ dir = m->qid;
+ for(nwqid = 0; (nwqid < c->fcall->nwname)
+ && !mkqid(&dir, c->fcall->wname[nwqid], &c->fcall->wqid[nwqid]); nwqid++)
+ dir = c->fcall->wqid[nwqid];
+ if(!nwqid) {
+ errstr = Enofile;
+ return -1;
}
- idx++;
}
- if(w > brect.width) {
- /* failsafe mode, give all labels same width */
- w = brect.width / nitems;
- for(i = items; i && i->next; i = i->next)
- i->d.rect.width = w;
- i->d.rect.width = w;
- i->d.rect.width = brect.width - i->d.rect.x;
- } else {
- idx = 0;
- for(i = items; i && idx != expandable; i = i->next)
- idx++;
- i->d.rect.width = brect.width - w;
+ /* a fid will only be valid, if the walk was complete */
+ if(nwqid == c->fcall->nwname) {
+ if(c->fcall->fid != c->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 = c->fcall->newfid;
}
- for(i = items; i; i = i->next) {
- i->d.font = font;
- i->d.rect.x = xoff;
- xoff += i->d.rect.width;
- if(i->d.data && !strncmp(i->d.data, "%m:", 3))
- blitz_drawmeter(dpy, &i->d);
- else
- blitz_drawlabel(dpy, &i->d);
+ c->fcall->id = RWALK;
+ c->fcall->nwqid = nwqid;
+ return 0;
+}
+
+static int
+xopen(IXPConn *c)
+{
+ IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
+
+ if(!m) {
+ errstr = Enofid;
+ return -1;
}
- XCopyArea(dpy, pmap, win, gc, 0, 0, brect.width, brect.height, 0, 0);
- XSync(dpy, False);
+ if(!(c->fcall->mode | IXP_OREAD) && !(c->fcall->mode | IXP_OWRITE)) {
+ errstr = Enomode;
+ return -1;
+ }
+ c->fcall->id = ROPEN;
+ c->fcall->qid = m->qid;
+ c->fcall->iounit = c->fcall->maxmsg
+ - (sizeof(unsigned char) + sizeof(unsigned short) + 2 * sizeof(unsigned int));
+ return 0;
}
-static void
-draw_bar(void *obj, char *arg)
-{
- File *label = 0;
- unsigned int j = 0;
- Item *i, *it;
- char buf[512];
-
- if(!displayed)
- return;
- while((i = items)) {
- items = items->next;
- free(i);
+static unsigned int
+mkstat(Stat *stat, Qid *dir, char *name, unsigned long long length, unsigned int mode)
+{
+ stat->mode = mode;
+ stat->atime = stat->mtime = time(0);
+ cext_strlcpy(stat->uid, getenv("USER"), sizeof(stat->uid));
+ cext_strlcpy(stat->gid, getenv("USER"), sizeof(stat->gid));
+ cext_strlcpy(stat->muid, getenv("USER"), sizeof(stat->muid));
+
+ cext_strlcpy(stat->name, name, sizeof(stat->name));
+ stat->length = length;
+ mkqid(dir, name, &stat->qid);
+ return ixp_sizeof_stat(stat);
+}
+
+static unsigned int
+type_to_stat(Stat *stat, char *name, unsigned short i)
+{
+ int type = name_to_type(name);
+ Qid dir = {IXP_QTDIR, 0, mkqpath(Ditem, i)};
+ char buf[16];
+
+ switch (type) {
+ case Droot:
+ case Ditem:
+ return mkstat(stat, &root_qid, name, 0, DMDIR | DMREAD | DMEXEC);
+ break;
+ case Fctl:
+ return mkstat(stat, &root_qid, name, 0, DMWRITE);
+ break;
+ case Fdisplay:
+ if(align == SOUTH || align == NORTH)
+ return mkstat(stat, &root_qid, name, 6, DMREAD | DMWRITE);
+ else
+ return mkstat(stat, &root_qid, name, 5, DMREAD | DMWRITE);
+ break;
+ case Fevent:
+ return mkstat(stat, &root_qid, name, 0, DMREAD);
+ break;
+ case Ffont:
+ return mkstat(stat, &root_qid, name, strlen(font),
+ DMREAD | DMWRITE);
+ break;
+ case Fexpand:
+ snprintf(buf, sizeof(buf), "%u", iexpand);
+ return mkstat(stat, &root_qid, name, strlen(buf), DMREAD | DMWRITE);
+ break;
+ case Fdata:
+ if(i == nitem)
+ i = 0;
+ return mkstat(stat, &dir, name, strlen(item[i]->data),
+ DMREAD | DMWRITE);
+ break;
+ case Fcolor:
+ if(i == nitem)
+ i = 0;
+ return mkstat(stat, &dir, name, strlen(item[i]->color),
+ DMREAD | DMWRITE);
+ break;
+ default:
+ errstr = "invalid stat";
+ break;
}
- it = items = nil;
- snprintf(buf, sizeof(buf), "%s", "/1");
- label = ixp_walk(ixps, buf);
- if(!label) {
- Draw d = { 0 };
- /* default stuff */
- d.gc = gc;
- d.drawable = pmap;
- d.rect.width = brect.width;
- d.rect.height = brect.height;
- d.bg = blitz_loadcolor(dpy, screen_num, file[B_BG_COLOR]->content);
- d.fg = blitz_loadcolor(dpy, screen_num, file[B_FG_COLOR]->content);
- d.border =
- blitz_loadcolor(dpy, screen_num,
- file[B_BORDER_COLOR]->content);
- blitz_drawlabelnoborder(dpy, &d);
- } else {
- File *f;
- char **paths = 0;
- /*
- * take order into account, directory names are used in
- * alphabetical order
- */
- nitems = 0;
- for(f = label; f; f = f->next)
- nitems++;
- paths = cext_emallocz(sizeof(char *) * nitems);
- j = 0;
- for(f = label; f; f = f->next)
- paths[j++] = f->name;
- qsort(paths, nitems, sizeof(char *), comp_str);
- for(j = 0; j < nitems; j++) {
- snprintf(buf, sizeof(buf), "/%s", paths[j]);
- i = cext_emallocz(sizeof(Item));
- init_item(buf, i);
- if(!it)
- it = items = i;
- else {
- it->next = i;
- it = i;
- }
- }
- free(paths);
- draw();
+ return 0;
+}
+
+static int
+xremove(IXPConn *c)
+{
+ IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
+ unsigned short i;
+
+ if(!m) {
+ errstr = Enofid;
+ return -1;
}
+ i = qpath_item(m->qid.path);
+ if((qpath_type(m->qid.path) == Ditem) && i && (i < nitem)) {
+ Item *it = item[i];
+ detach_item(it);
+ free(it);
+ c->fcall->id = RREMOVE;
+ if(iexpand >= nitem)
+ iexpand = 0;
+ draw();
+ return 0;
+ }
+ errstr = Enoperm;
+ return -1;
}
-static Item *
-item_for_file(File * f)
+static int
+xread(IXPConn *c)
{
- Item *i;
- for(i = items; i; i = i->next) {
- if(f == i->root)
- return i;
+ Stat stat;
+ IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
+ unsigned char *p = c->fcall->data;
+ unsigned short i;
+ unsigned int len;
+ char buf[32];
+
+ if(!m) {
+ errstr = Enofid;
+ return -1;
}
- return nil;
+ i = qpath_item(m->qid.path);
+
+ c->fcall->count = 0;
+ if(c->fcall->offset) {
+ switch (qpath_type(m->qid.path)) {
+ case Droot:
+ /* jump to offset */
+ len = type_to_stat(&stat, "ctl", 0);
+ len += type_to_stat(&stat, "display", 0);
+ len += type_to_stat(&stat, "font", 0);
+ len += type_to_stat(&stat, "new", 0);
+ len += type_to_stat(&stat, "event", 0);
+ len += type_to_stat(&stat, "default", 0);
+ for(i = 1; i < nitem; i++) {
+ snprintf(buf, sizeof(buf), "%u", i);
+ len += type_to_stat(&stat, buf, i);
+ if(len < c->fcall->offset)
+ continue;
+ else
+ break;
+ }
+ /* offset found, proceeding */
+ for(; i < nitem; i++) {
+ snprintf(buf, sizeof(buf), "%u", i);
+ len = type_to_stat(&stat, buf, i);
+ if(c->fcall->count + len >= c->fcall->iounit)
+ break;
+ c->fcall->count += len;
+ p = ixp_enc_stat(p, &stat);
+ }
+ break;
+ case Fevent:
+ return 1;
+ break;
+ default:
+ break;
+ }
+ }
+ else {
+ switch (qpath_type(m->qid.path)) {
+ case Droot:
+ c->fcall->count = type_to_stat(&stat, "ctl", 0);
+ p = ixp_enc_stat(p, &stat);
+ c->fcall->count += type_to_stat(&stat, "display", 0);
+ p = ixp_enc_stat(p, &stat);
+ c->fcall->count += type_to_stat(&stat, "font", 0);
+ p = ixp_enc_stat(p, &stat);
+ c->fcall->count += type_to_stat(&stat, "new", 0);
+ p = ixp_enc_stat(p, &stat);
+ c->fcall->count += type_to_stat(&stat, "event", 0);
+ p = ixp_enc_stat(p, &stat);
+ c->fcall->count += type_to_stat(&stat, "default", 0);
+ p = ixp_enc_stat(p, &stat);
+ for(i = 1; i < nitem; i++) {
+ snprintf(buf, sizeof(buf), "%u", i);
+ len = type_to_stat(&stat, buf, i);
+ if(c->fcall->count + len >= c->fcall->iounit)
+ break;
+ c->fcall->count += len;
+ p = ixp_enc_stat(p, &stat);
+ }
+ break;
+ case Ditem:
+ if(i > nitem)
+ goto error_xread;
+ if(!i) {
+ c->fcall->count = type_to_stat(&stat, "color", i);
+ p = ixp_enc_stat(p, &stat);
+ break;
+ }
+ if(i == nitem)
+ new_item();
+ c->fcall->count = type_to_stat(&stat, "color", i);
+ p = ixp_enc_stat(p, &stat);
+ c->fcall->count += type_to_stat(&stat, "data", i);
+ p = ixp_enc_stat(p, &stat);
+ break;
+ case Fctl:
+ errstr = Enoperm;
+ return -1;
+ break;
+ case Fdisplay:
+ switch(align) {
+ case SOUTH:
+ memcpy(p, "south", 5);
+ c->fcall->count = 5;
+ break;
+ case NORTH:
+ memcpy(p, "north", 5);
+ c->fcall->count = 5;
+ break;
+ default:
+ memcpy(p, "none", 4);
+ c->fcall->count = 4;
+ break;
+ }
+ break;
+ case Ffont:
+ if((c->fcall->count = strlen(font)))
+ memcpy(p, font, c->fcall->count);
+ break;
+ case Fexpand:
+ snprintf(buf, sizeof(buf), "%u", iexpand);
+ c->fcall->count = strlen(buf);
+ memcpy(p, buf, c->fcall->count);
+ break;
+ case Fevent:
+ return 1;
+ break;
+ case Fdata:
+ if(i == nitem)
+ new_item();
+ if(i >= nitem)
+ goto error_xread;
+ if((c->fcall->count = strlen(item[i]->data)))
+ memcpy(p, item[i]->data, c->fcall->count);
+ break;
+ case Fcolor:
+ if(i == nitem)
+ new_item();
+ if(i >= nitem)
+ goto error_xread;
+ if((c->fcall->count = strlen(item[i]->color)))
+ memcpy(p, item[i]->color, c->fcall->count);
+ break;
+ default:
+ error_xread:
+ if(!errstr)
+ errstr = "invalid read";
+ return -1;
+ break;
+ }
+ }
+ c->fcall->id = RREAD;
+ return 0;
}
-static void
-handle_buttonpress(XButtonPressedEvent * e)
+static int
+xstat(IXPConn *c)
{
- Item *i;
- File *p;
- char buf[MAX_BUF];
- char path[512];
- for(i = items; i; i = i->next)
- if(blitz_ispointinrect(e->x, e->y, &i->d.rect)) {
- path[0] = 0;
- wmii_get_ixppath(i->root, path, sizeof(path));
- snprintf(buf, MAX_BUF, "%s/b%upress", path, e->button);
- if((p = ixp_walk(ixps, buf)))
- if(p->content)
- wmii_spawn(dpy, p->content);
- return;
- }
+ IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
+ char *name;
+
+ if(!m) {
+ errstr = Enofid;
+ return -1;
+ }
+
+ name = qid_to_name(&m->qid);
+ if(!type_to_stat(&c->fcall->stat, name, qpath_item(m->qid.path)))
+ return -1;
+ c->fcall->id = RSTAT;
+ return 0;
}
-static void
-check_event(Connection * e)
+static int
+xwrite(IXPConn *c)
{
- XEvent ev;
+ char buf[256];
+ IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
+ unsigned short i;
- while(XPending(dpy)) {
- XNextEvent(dpy, &ev);
- switch (ev.type) {
- case ButtonPress:
- handle_buttonpress(&ev.xbutton);
- break;
- case Expose:
- if(ev.xexpose.count == 0) {
- /* XRaiseWindow(dpy, win); */
- draw_bar(0, 0);
- }
- break;
- default:
- break;
- }
+ if(!m) {
+ errstr = Enofid;
+ return -1;
}
+
+ i = qpath_item(m->qid.path);
+ switch (qpath_type(m->qid.path)) {
+ case Fctl:
+ if(c->fcall->count == 5) {
+ memcpy(buf, c->fcall->data, 4);
+ buf[4] = 0;
+ if(!strncmp(buf, "quit", 5)) {
+ srv.running = 0;
+ break;
+ }
+ }
+ errstr = "command not supported";
+ return -1;
+ break;
+ case Fdisplay:
+ if(c->fcall->count != 6 && c->fcall->count != 5)
+ goto error_xwrite;
+ memcpy(buf, c->fcall->data, c->fcall->count);
+ buf[c->fcall->count] = 0;
+ if(blitz_strtoalign(&align, buf) == -1)
+ goto error_xwrite;
+ update_geometry();
+ if(align == NORTH || align == SOUTH) {
+ XMapRaised(dpy, win);
+ draw();
+ }
+ else
+ XUnmapWindow(dpy, win);
+ XSync(dpy, False);
+ break;
+ case Ffont:
+ if(font)
+ free(font);
+ font = cext_emallocz(c->fcall->count + 1);
+ memcpy(font, c->fcall->data, c->fcall->count);
+ xfont = blitz_getfont(dpy, font);
+ update_geometry();
+ break;
+ case Fexpand:
+ {
+ const char *err;
+ if(c->fcall->count && c->fcall->count < 16) {
+ memcpy(buf, c->fcall->data, c->fcall->count);
+ buf[c->fcall->count] = 0;
+ i = (unsigned short) cext_strtonum(buf, 1, 0xffff, &err);
+ if(i < nitem) {
+ iexpand = i;
+ draw();
+ break;
+ }
+ }
+ }
+ errstr = "item not found";
+ return -1;
+ break;
+ case Fdata:
+ {
+ unsigned int len = c->fcall->count;
+ if(i == nitem)
+ new_item();
+ if(!i || (i >= nitem))
+ goto error_xwrite;
+ if(len >= sizeof(item[i]->data))
+ len = sizeof(item[i]->data) - 1;
+ memcpy(item[i]->data, c->fcall->data, len);
+ item[i]->data[len] = 0;
+ draw();
+ }
+ break;
+ case Fcolor:
+ if(i == nitem)
+ new_item();
+ if((i >= nitem) || (c->fcall->count != 24)
+ || (c->fcall->data[0] != '#') || (c->fcall->data[8] != '#')
+ || (c->fcall->data[16] != '#'))
+ {
+ errstr = "wrong color format";
+ goto error_xwrite;
+ }
+ memcpy(item[i]->color, c->fcall->data, c->fcall->count);
+ item[i]->color[c->fcall->count] = 0;
+ update_color(item[i]);
+ draw();
+ break;
+ default:
+error_xwrite:
+ if(!errstr)
+ errstr = "invalid write";
+ return -1;
+ break;
+ }
+ c->fcall->id = RWRITE;
+ return 0;
+}
+
+static int
+xclunk(IXPConn *c)
+{
+ IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
+
+ if(!m) {
+ errstr = Enofid;
+ return -1;
+ }
+ cext_array_detach((void **)c->map, m, &c->mapsz);
+ free(m);
+ c->fcall->id = RCLUNK;
+ return 0;
}
static void
-update_geometry()
+close_ixp_conn(IXPServer *s, IXPConn *c)
{
- brect = rect;
- brect.height = font->ascent + font->descent + 4;
- if(align == SOUTH)
- brect.y = rect.height - brect.height;
- XMoveResizeWindow(dpy, win, brect.x, brect.y, brect.width,
- brect.height);
- XSync(dpy, False);
- XFreePixmap(dpy, pmap);
- pmap =
- XCreatePixmap(dpy, win, brect.width, brect.height,
- DefaultDepth(dpy, screen_num));
- XSync(dpy, False);
- if(file[B_EVENT_RESIZE]->content)
- wmii_spawn(dpy, file[B_EVENT_RESIZE]->content);
+ size_t i;
+ cext_array_detach((void **)s->conn, c, &s->connsz);
+ if(c->map) {
+ for(i = 0; (i < c->mapsz) && c->map[i]; i++)
+ free(c->map[i]);
+ free(c->map);
+ }
+ if(c->pend) {
+ for(i = 0; (i < c->pendsz) && c->pend[i]; i++)
+ free(c->pend[i]);
+ free(c->pend);
+ }
+ shutdown(c->fd, SHUT_RDWR);
+ close(c->fd);
+ free(c);
}
static void
-handle_after_write(IXPServer * s, File * f)
+do_fcall(IXPServer *s, IXPConn *c)
{
- int i;
- size_t len;
- Item *item;
- char buf[512];
-
- buf[0] = 0;
- if(!strncmp(f->name, "data", 5)) {
- if((item = item_for_file(f->parent))) {
- wmii_get_ixppath(f->parent, buf, sizeof(buf));
- init_draw_label(buf, &item->d);
- draw();
- }
- } else if(file[B_GEOMETRY] == f) {
- if(f->content) {
- if(!strncmp(f->content, "south", 6))
- align = SOUTH;
- else if(!strncmp(f->content, "north", 6))
- align = NORTH;
- update_geometry();
- draw_bar(0, 0);
- }
- } else if(file[B_CTL] == f) {
- for(i = 0; acttbl[i].name; i++) {
- len = strlen(acttbl[i].name);
- if(!strncmp(acttbl[i].name, (char *) f->content, len)) {
- if(strlen(f->content) > len) {
- acttbl[i].func(0, &((char *) f->content)[len + 1]);
- } else {
- acttbl[i].func(0, 0);
- }
- break;
- }
- }
- } else if(file[B_FONT] == f) {
- XFreeFont(dpy, font);
- font = blitz_getfont(dpy, file[B_FONT]->content);
- update_geometry();
- draw_bar(0, 0);
- }
- check_event(0);
+ unsigned int msize;
+ int ret = -1;
+ errstr = 0;
+ if(!(msize = ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &errstr))) {
+ close_ixp_conn(s, c);
+ return;
+ }
+ if(!c->fcall)
+ c->fcall = cext_emallocz(sizeof(Fcall));
+ if((msize = ixp_msg_to_fcall(msg, IXP_MAX_MSG, c->fcall))) {
+ switch(c->fcall->id) {
+ case TVERSION: ret = xversion(c); break;
+ case TATTACH: ret = xattach(c); break;
+ case TWALK: ret = xwalk(c); break;
+ case TREMOVE: ret = xremove(c); break;
+ case TOPEN: ret = xopen(c); break;
+ case TREAD: ret = xread(c); break;
+ case TWRITE: ret = xwrite(c); break;
+ case TCLUNK: ret = xclunk(c); break;
+ case TSTAT: ret = xstat(c); break;
+ default:
+ break;
+ }
+ }
+ if(ret == -1) {
+ if(!errstr)
+ errstr = Enofunc;
+ c->fcall->id = RERROR;
+ cext_strlcpy(c->fcall->errstr, errstr, sizeof(c->fcall->errstr));
+ }
+ else if(ret == 1) {
+ c->pend = (Fcall **)cext_array_attach((void **)c->pend, c->fcall, sizeof(Fcall *), &c->pendsz);
+ c->fcall = nil;
+ return; /* response asynchroneously */
+ }
+ msize = ixp_fcall_to_msg(c->fcall, msg, IXP_MAX_MSG);
+ if(ixp_send_message(c->fd, msg, msize, &errstr) != msize)
+ close_ixp_conn(s, c);
+}
+
+static Fcall *
+pending(IXPConn *c, unsigned char id)
+{
+ size_t i;
+ for(i = 0; (i < c->pendsz) && c->pend[i]; i++)
+ if(c->pend[i]->id == id)
+ return c->pend[i];
+ return nil;
}
static void
-handle_before_read(IXPServer * s, File * f)
-{
- char buf[64];
- if(f == file[B_GEOMETRY]) {
- snprintf(buf, 64, "%d %d %d %d", brect.x, brect.y, brect.width,
- brect.height);
- if(f->content)
- free(f->content);
- f->content = cext_estrdup(buf);
- f->size = strlen(buf);
- } else if(f == file[B_NEW]) {
- snprintf(buf, sizeof(buf), "%d", id++);
- if(f->content)
- free(f->content);
- f->content = strdup(buf);
- f->size = strlen(buf);
- create_label(buf);
- draw_bar(0, 0);
- }
+do_pend_fcall(char *event)
+{
+ size_t i;
+ Fcall *fcall;
+ for(i = 0; (i < srv.connsz) && srv.conn[i]; i++) {
+ IXPConn *c = srv.conn[i];
+ /* all pending TREADs are on /event, so no qid checking necessary */
+ while((fcall = pending(c, TREAD))) {
+ IXPMap *m = ixp_server_fid2map(c, fcall->fid);
+ unsigned char *p = fcall->data;
+ unsigned int msize;
+
+ if(!m) {
+ errstr = Enofid;
+ fcall->id = RERROR;
+ }
+ else if(qpath_type(m->qid.path) == Fevent) {
+ fcall->count = strlen(event);
+ memcpy(p, event, fcall->count);
+ fcall->id = RREAD;
+ }
+ msize = ixp_fcall_to_msg(fcall, msg, IXP_MAX_MSG);
+ /* remove pending request */
+ cext_array_detach((void **)c->pend, fcall, &c->pendsz);
+ free(fcall);
+ if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) {
+ close_ixp_conn(&srv, c);
+ break;
+ }
+ }
+ }
}
-static int
-dummy_error_handler(Display * dpy, XErrorEvent * err)
+static void
+new_ixp_conn(IXPServer *s, IXPConn *c)
{
- return 0;
+ IXPConn *new;
+ int fd = ixp_accept_sock(c->fd);
+
+ if(fd >= 0) {
+ new = cext_emallocz(sizeof(IXPConn));
+ new->fd = fd;
+ new->read = do_fcall;
+ new->close = close_ixp_conn;
+ s->conn = (IXPConn **)cext_array_attach((void **)s->conn, new,
+ sizeof(IXPConn *), &s->connsz);
+ }
}
+
+/* main */
+
int
main(int argc, char *argv[])
{
int i;
+ IXPConn *c;
XSetWindowAttributes wa;
XGCValues gcv;
@@ -484,9 +983,9 @@ main(int argc, char *argv[])
fprintf(stdout, "%s", version[0]);
exit(0);
break;
- case 's':
+ case 'a':
if(i + 1 < argc)
- sockfile = argv[++i];
+ address = argv[++i];
else
usage();
break;
@@ -504,51 +1003,60 @@ main(int argc, char *argv[])
XSetErrorHandler(dummy_error_handler);
screen_num = DefaultScreen(dpy);
- ixps = wmii_setup_server(sockfile);
+ if(!address) {
+ fprintf(stderr, "%s\n", "wmiibar: no socket address provided");
+ exit(1);
+ }
+ i = ixp_create_sock(address, &errstr);
+ if(i < 0) {
+ fprintf(stderr, "wmiibar: fatal: %s\n", errstr);
+ exit(1);
+ }
+ /* IXP server */
+ c = cext_emallocz(sizeof(IXPConn));
+ c->fd = i;
+ c->read = new_ixp_conn;
+ c->close = close_ixp_conn;
+ srv.conn = (IXPConn **)cext_array_attach((void **)srv.conn, c,
+ sizeof(IXPConn *), &srv.connsz);
+ /* X server */
+ c = cext_emallocz(sizeof(IXPConn));
+ c->fd = ConnectionNumber(dpy);
+ c->read = check_x_event;
+ srv.conn = (IXPConn **)cext_array_attach((void **)srv.conn, c,
+ sizeof(IXPConn *), &srv.connsz);
- /* init */
- if(!(file[B_CTL] = ixp_create(ixps, "/ctl"))) {
- perror("wmiibar: cannot connect IXP server");
- exit(1);
- }
- file[B_CTL]->after_write = handle_after_write;
- file[B_NEW] = ixp_create(ixps, "/new");
- file[B_NEW]->before_read = handle_before_read;
- file[B_FONT] = wmii_create_ixpfile(ixps, "/font", BLITZ_FONT);
- file[B_FONT]->after_write = handle_after_write;
- font = blitz_getfont(dpy, file[B_FONT]->content);
- file[B_BG_COLOR] =
- wmii_create_ixpfile(ixps, "/bgcolor", BLITZ_NORM_BG_COLOR);
- file[B_FG_COLOR] =
- wmii_create_ixpfile(ixps, "/fgcolor", BLITZ_NORM_FG_COLOR);
- file[B_BORDER_COLOR] =
- wmii_create_ixpfile(ixps, "/bordercolor", BLITZ_NORM_BORDER_COLOR);
- file[B_GEOMETRY] = ixp_create(ixps, "/geometry");
- file[B_GEOMETRY]->before_read = handle_before_read;
- file[B_GEOMETRY]->after_write = handle_after_write;
- file[B_EXPANDABLE] = ixp_create(ixps, "/expandable");
- file[B_EVENT_RESIZE] = ixp_create(ixps, "/event/resize");
+ root_qid.type = IXP_QTDIR;
+ root_qid.version = 0;
+ root_qid.path = mkqpath(Droot, 0);
+
+ mypid = getpid();
+ /* default settings */
+ new_item();
+ cext_strlcpy(item[0]->color, BLITZ_SEL_COLOR, sizeof(item[0]->color));
+ update_color(item[0]);
+
+ /* X stuff */
+ font = strdup(BLITZ_FONT);
+ xfont = blitz_getfont(dpy, font);
wa.override_redirect = 1;
wa.background_pixmap = ParentRelative;
- wa.event_mask =
- ExposureMask | ButtonPressMask | SubstructureRedirectMask |
- SubstructureNotifyMask;
+ wa.event_mask = ExposureMask | ButtonPressMask
+ | SubstructureRedirectMask | SubstructureNotifyMask;
rect.x = rect.y = 0;
rect.width = DisplayWidth(dpy, screen_num);
rect.height = DisplayHeight(dpy, screen_num);
brect = rect;
- brect.height = font->ascent + font->descent + 4;
+ brect.height = xfont->ascent + xfont->descent + 4;
brect.y = rect.height - brect.height;
win = XCreateWindow(dpy, RootWindow(dpy, screen_num), brect.x, brect.y,
- brect.width, brect.height, 0, DefaultDepth(dpy,
- screen_num),
+ brect.width, brect.height, 0, DefaultDepth(dpy, screen_num),
CopyFromParent, DefaultVisual(dpy, screen_num),
- CWOverrideRedirect | CWBackPixmap | CWEventMask,
- &wa);
+ CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_left_ptr));
XSync(dpy, False);
@@ -556,17 +1064,19 @@ main(int argc, char *argv[])
gcv.graphics_exposures = False;
gc = XCreateGC(dpy, win, 0, 0);
- pmap =
- XCreatePixmap(dpy, win, brect.width, brect.height,
- DefaultDepth(dpy, screen_num));
+ pmap = XCreatePixmap(dpy, win, brect.width, brect.height,
+ DefaultDepth(dpy, screen_num));
- /* main event loop */
- run_server_with_fd_support(ixps, ConnectionNumber(dpy), check_event,
- 0);
- deinit_server(ixps);
- XFreePixmap(dpy, pmap);
- XFreeGC(dpy, gc);
- XCloseDisplay(dpy);
+ /* main loop */
+ errstr = ixp_server_loop(&srv);
- return 0;
+ if(errstr)
+ fprintf(stderr, "wmiibar: fatal: %s\n", errstr);
+
+ /* cleanup */
+ for(i = 0; (i < srv.connsz) && srv.conn[i]; i++)
+ if(srv.conn[i]->close)
+ srv.conn[i]->close(&srv, srv.conn[i]);
+
+ return errstr ? 1 : 0;
}
diff --git a/cmd/wmiibar2.c b/cmd/wmiibar2.c
@@ -1,1084 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include <X11/Xatom.h>
-#include <X11/cursorfont.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#include <sys/socket.h>
-
-#include "../libixp2/ixp.h"
-#include "blitz.h"
-
-/*
- * filesystem specification
- * / Droot
- * /display Fdisplay 'north', 'south', 'none'
- * /font Ffont <xlib font name>
- * /event Fevent
- * /expand Fexpand id of expandable label
- * /ctl Fctl command interface
- * /new Dnew returns content of new item
- * /default/ Ditem
- * /default/color Fcolor <#RRGGBB> <#RRGGBB> <#RRGGBB>
- * /1/ Ditem
- * /1/data Fdata <arbitrary data which gets displayed>
- * /1/color Fcolor <#RRGGBB> <#RRGGBB> <#RRGGBB>
- */
-
-/* 8-bit qid.path.type */
-enum {
- Droot,
- Ditem,
- Fctl,
- Fdisplay,
- Ffont,
- Fexpand,
- Fevent,
- Fdata, /* data to display */
- Fcolor
-};
-
-typedef struct {
- char data[256];
- char color[24];
- unsigned long fg;
- unsigned long bg;
- unsigned long border;
- XRectangle rect;
-} Item;
-
-static char E9pversion[] = "9P version not supported";
-static char Enoperm[] = "permission denied";
-static char Enofid[] = "fid not assigned";
-static char Enofile[] = "file not found";
-static char Enomode[] = "mode not supported";
-static char Enofunc[] = "function not supported";
-
-static unsigned char *msg[IXP_MAX_MSG];
-char *errstr = 0;
-static size_t nitem = 0;
-static size_t itemsz = 0;
-static size_t iexpand = 0;
-static Item **item = 0;
-static char *address = nil;
-static pid_t mypid = 0;
-static IXPServer srv = { 0 };
-static Qid root_qid;
-static Display *dpy;
-static int screen_num;
-static char *font = nil;
-static Align align = CENTER;
-static XFontStruct *xfont;
-static GC gc;
-static Window win;
-static XRectangle brect, rect;
-static Pixmap pmap;
-
-static void do_pend_fcall(char *event);
-
-static char *version[] = {
- "wmiibar - window manager improved bar - " VERSION "\n"
- " (C)opyright MMIV-MMVI Anselm R. Garbe\n", 0
-};
-
-static void
-usage()
-{
- fprintf(stderr, "%s %d",
- "usage: wmiibar -a <server address> [-v]\n"
- " -a server address \n"
- " -v version info\n", 0);
- exit(1);
-}
-
-static int
-dummy_error_handler(Display * dpy, XErrorEvent * err)
-{
- return 0;
-}
-
-static void
-new_item()
-{
- Item *it = cext_emallocz(sizeof(Item));
- if(nitem > 0) {
- cext_strlcpy(it->color, item[0]->color, sizeof(it->color));
- it->fg = item[0]->fg;
- it->bg = item[0]->bg;
- it->border = item[0]->border;
- }
- item = (Item **)cext_array_attach((void **)item, it, sizeof(Item *), &itemsz);
- nitem++;
-}
-
-static void
-detach_item(Item *it)
-{
- cext_array_detach((void **)item, it, &itemsz);
- nitem--;
-}
-
-static void
-draw()
-{
- size_t i;
- unsigned int w = 0;
- Draw d = { 0 };
-
- d.gc = gc;
- d.drawable = pmap;
- d.rect = brect;
- d.rect.y = 0;
- d.font = xfont;
-
- if(nitem == 1) { /* /default only */
- d.fg = item[0]->fg;
- d.bg = item[0]->bg;
- d.border = item[0]->border;
- blitz_drawlabel(dpy, &d);
- }
- else {
- if(!iexpand)
- iexpand = nitem - 1;
- for(i = 1; i < nitem; i++) {
- Item *it = item[i];
- it->rect.x = it->rect.y = 0;
- it->rect.width = it->rect.height = brect.height;
- if(i == iexpand)
- continue;
- if(strlen(it->data)) {
- if(!strncmp(it->data, "%m:", 3))
- it->rect.width = brect.height / 2;
- else
- it->rect.width += XTextWidth(xfont, it->data, strlen(it->data));
- }
- w += it->rect.width;
- }
- if(w >= brect.width) {
- /* failsafe mode, give all labels same width */
- w = brect.width / nitem;
- for(i = 1; i < nitem; i++)
- item[i]->rect.width = w;
- i--;
- item[i]->rect.width = brect.width - ((i - 1) * w);
- } else
- item[iexpand]->rect.width = brect.width - w;
- for(i = 1; i < nitem; i++) {
- d.fg = item[i]->fg;
- d.bg = item[i]->bg;
- d.border = item[i]->border;
- if(i > 1)
- item[i]->rect.x = item[i - 1]->rect.x + item[i - 1]->rect.width;
- d.rect = item[i]->rect;
- d.data = item[i]->data;
- if(d.data && !strncmp(d.data, "%m:", 3))
- blitz_drawmeter(dpy, &d);
- else
- blitz_drawlabel(dpy, &d);
- }
- }
- XCopyArea(dpy, pmap, win, gc, 0, 0, brect.width, brect.height, 0, 0);
- XSync(dpy, False);
-}
-
-static void
-update_color(Item *it)
-{
- it->fg = blitz_loadcolor(dpy, screen_num, &it->color[0]);
- it->bg = blitz_loadcolor(dpy, screen_num, &it->color[8]);
- it->border = blitz_loadcolor(dpy, screen_num, &it->color[16]);
-}
-
-static void
-update_geometry()
-{
- char buf[64];
- brect = rect;
- brect.height = xfont->ascent + xfont->descent + 4;
- if(align == SOUTH)
- brect.y = rect.height - brect.height;
- XMoveResizeWindow(dpy, win, brect.x, brect.y, brect.width, brect.height);
- XSync(dpy, False);
- XFreePixmap(dpy, pmap);
- pmap = XCreatePixmap(dpy, win, brect.width, brect.height,
- DefaultDepth(dpy, screen_num));
- XSync(dpy, False);
- snprintf(buf, sizeof(buf), "NewGeometry %d %d %d %d\n", brect.x, brect.y, brect.width, brect.height);
- do_pend_fcall(buf);
- draw();
-}
-
-static void
-handle_buttonpress(XButtonPressedEvent * e)
-{
- size_t i;
- char buf[32];
- for(i = 0; i < nitem; i++)
- if(blitz_ispointinrect(e->x, e->y, &item[i]->rect)) {
- snprintf(buf, sizeof(buf), "Button%dPress %d\n", e->button, i);
- do_pend_fcall(buf);
- }
-}
-
-static void
-check_x_event(IXPServer *s, IXPConn *c)
-{
- XEvent e;
-
- while(XPending(dpy)) {
- XNextEvent(dpy, &e);
- switch (e.type) {
- case ButtonPress:
- handle_buttonpress(&e.xbutton);
- break;
- case Expose:
- if(e.xexpose.count == 0)
- draw();
- break;
- default:
- break;
- }
- }
-}
-
-
-/* IXP stuff */
-
-static unsigned long long
-mkqpath(unsigned char type, unsigned short item)
-{
- return ((unsigned long long) item << 8) | (unsigned long long) type;
-}
-
-static unsigned char
-qpath_type(unsigned long long path)
-{
- return path & 0xff;
-}
-
-static unsigned short
-qpath_item(unsigned long long path)
-{
- return (path >> 8) & 0xffff;
-}
-
-static char *
-qid_to_name(Qid *qid)
-{
- unsigned char type = qpath_type(qid->path);
- unsigned short i = qpath_item(qid->path);
- static char buf[32];
-
- switch(type) {
- case Droot: return "/"; break;
- case Ditem:
- if(!i)
- return "default";
- else if(i == nitem)
- return "new";
- snprintf(buf, sizeof(buf), "%u", i);
- return buf;
- break;
- case Fctl: return "ctl"; break;
- case Fdisplay: return "display"; break;
- case Ffont: return "font"; break;
- case Fexpand: return "expand"; break;
- case Fdata: return "data"; break;
- case Fevent: return "event"; break;
- case Fcolor: return "color"; break;
- default: return nil; break;
- }
-}
-
-static int
-name_to_type(char *name)
-{
- const char *err;
- unsigned int i;
- if(!name || !name[0] || !strncmp(name, "/", 2) || !strncmp(name, "..", 3))
- return Droot;
- if(!strncmp(name, "default", 8) || !strncmp(name, "new", 4))
- return Ditem;
- if(!strncmp(name, "ctl", 4))
- return Fctl;
- if(!strncmp(name, "display", 8))
- return Fdisplay;
- if(!strncmp(name, "font", 5))
- return Ffont;
- if(!strncmp(name, "expand", 7))
- return Fexpand;
- if(!strncmp(name, "data", 5))
- return Fdata;
- if(!strncmp(name, "event", 6))
- return Fevent;
- if(!strncmp(name, "color", 6))
- return Fcolor;
- i = (unsigned short) cext_strtonum(name, 1, 0xffff, &err);
- if(!err && (i <= nitem))
- return Ditem;
- return -1;
-}
-
-static int
-mkqid(Qid *dir, char *wname, Qid *new)
-{
- const char *err;
- int type = name_to_type(wname);
- unsigned short i = qpath_item(dir->path);
-
- if((dir->type != IXP_QTDIR) || (type == -1))
- return -1;
-
- new->version = 0;
- switch(type) {
- case Droot:
- new->type = IXP_QTDIR;
- *new = root_qid;
- break;
- case Ditem:
- new->type = IXP_QTDIR;
- if(!strncmp(wname, "default", 8))
- new->path = mkqpath(Ditem, 0);
- else if(!strncmp(wname, "new", 4))
- new->path = mkqpath(Ditem, nitem);
- else {
- unsigned short i = cext_strtonum(wname, 1, 0xffff, &err);
- if(err || (i >= nitem))
- return -1;
- new->path = mkqpath(Ditem, i);
- }
- break;
- case Fdata: /* note, Fdata needs to be before Fcolor, fallthrough */
- if(!i)
- return -1;
- case Fcolor:
- if(i > nitem)
- return -1;
- default:
- new->type = IXP_QTFILE;
- new->path = mkqpath(type, i);
- break;
- }
- return 0;
-}
-
-static int
-xversion(IXPConn *c)
-{
- if(strncmp(c->fcall->version, IXP_VERSION, strlen(IXP_VERSION))) {
- errstr = E9pversion;
- return -1;
- } else if(c->fcall->maxmsg > IXP_MAX_MSG)
- c->fcall->maxmsg = IXP_MAX_MSG;
- c->fcall->id = RVERSION;
- return 0;
-}
-
-static int
-xattach(IXPConn *c)
-{
- IXPMap *new = cext_emallocz(sizeof(IXPMap));
- new->qid = root_qid;
- new->fid = c->fcall->fid;
- c->map = (IXPMap **)cext_array_attach((void **)c->map, new,
- sizeof(IXPMap *), &c->mapsz);
- c->fcall->id = RATTACH;
- c->fcall->qid = root_qid;
- return 0;
-}
-
-static int
-xwalk(IXPConn *c)
-{
- unsigned short nwqid = 0;
- Qid dir = root_qid;
- IXPMap *m;
-
- if(!(m = ixp_server_fid2map(c, c->fcall->fid))) {
- errstr = Enofid;
- return -1;
- }
- if(c->fcall->fid != c->fcall->newfid
- && (ixp_server_fid2map(c, c->fcall->newfid))) {
- errstr = Enofid;
- return -1;
- }
- if(c->fcall->nwname) {
- dir = m->qid;
- for(nwqid = 0; (nwqid < c->fcall->nwname)
- && !mkqid(&dir, c->fcall->wname[nwqid], &c->fcall->wqid[nwqid]); nwqid++)
- dir = c->fcall->wqid[nwqid];
- if(!nwqid) {
- errstr = Enofile;
- return -1;
- }
- }
- /* a fid will only be valid, if the walk was complete */
- if(nwqid == c->fcall->nwname) {
- if(c->fcall->fid != c->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 = c->fcall->newfid;
- }
- c->fcall->id = RWALK;
- c->fcall->nwqid = nwqid;
- return 0;
-}
-
-static int
-xopen(IXPConn *c)
-{
- IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
-
- if(!m) {
- errstr = Enofid;
- return -1;
- }
- if(!(c->fcall->mode | IXP_OREAD) && !(c->fcall->mode | IXP_OWRITE)) {
- errstr = Enomode;
- return -1;
- }
- c->fcall->id = ROPEN;
- c->fcall->qid = m->qid;
- c->fcall->iounit = c->fcall->maxmsg
- - (sizeof(unsigned char) + sizeof(unsigned short) + 2 * sizeof(unsigned int));
- return 0;
-}
-
-static unsigned int
-mkstat(Stat *stat, Qid *dir, char *name, unsigned long long length, unsigned int mode)
-{
- stat->mode = mode;
- stat->atime = stat->mtime = time(0);
- cext_strlcpy(stat->uid, getenv("USER"), sizeof(stat->uid));
- cext_strlcpy(stat->gid, getenv("USER"), sizeof(stat->gid));
- cext_strlcpy(stat->muid, getenv("USER"), sizeof(stat->muid));
-
- cext_strlcpy(stat->name, name, sizeof(stat->name));
- stat->length = length;
- mkqid(dir, name, &stat->qid);
- return ixp_sizeof_stat(stat);
-}
-
-static unsigned int
-type_to_stat(Stat *stat, char *name, unsigned short i)
-{
- int type = name_to_type(name);
- Qid dir = {IXP_QTDIR, 0, mkqpath(Ditem, i)};
-
- switch (type) {
- case Droot:
- case Ditem:
- return mkstat(stat, &root_qid, name, 0, DMDIR | DMREAD | DMEXEC);
- break;
- case Fctl:
- return mkstat(stat, &root_qid, name, 0, DMWRITE);
- break;
- case Fdisplay:
- if(align == SOUTH || align == NORTH)
- return mkstat(stat, &root_qid, name, 6, DMREAD | DMWRITE);
- else
- return mkstat(stat, &root_qid, name, 5, DMREAD | DMWRITE);
- break;
- case Fevent:
- return mkstat(stat, &root_qid, name, 0, DMREAD);
- break;
- case Ffont:
- return mkstat(stat, &root_qid, name, strlen(font),
- DMREAD | DMWRITE);
- break;
- case Fexpand:
- {
- char buf[16];
- snprintf(buf, sizeof(buf), "%u", iexpand);
- return mkstat(stat, &root_qid, name, strlen(buf), DMREAD | DMWRITE);
- }
- break;
- case Fdata:
- if(i == nitem)
- i = 0;
- return mkstat(stat, &dir, name, strlen(item[i]->data),
- DMREAD | DMWRITE);
- break;
- case Fcolor:
- if(i == nitem)
- i = 0;
- return mkstat(stat, &dir, name, strlen(item[i]->color),
- DMREAD | DMWRITE);
- break;
- default:
- errstr = "invalid stat";
- break;
- }
- return 0;
-}
-
-static int
-xremove(IXPConn *c)
-{
- IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
- unsigned short i;
-
- if(!m) {
- errstr = Enofid;
- return -1;
- }
- i = qpath_item(m->qid.path);
- if((qpath_type(m->qid.path) == Ditem) && i && (i < nitem)) {
- Item *it = item[i];
- detach_item(it);
- free(it);
- c->fcall->id = RREMOVE;
- if(iexpand >= nitem)
- iexpand = 0;
- draw();
- return 0;
- }
- errstr = Enoperm;
- return -1;
-}
-
-static int
-xread(IXPConn *c)
-{
- Stat stat;
- IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
- unsigned char *p = c->fcall->data;
- unsigned short i;
- unsigned int len;
- char buf[32];
-
- if(!m) {
- errstr = Enofid;
- return -1;
- }
- i = qpath_item(m->qid.path);
-
- c->fcall->count = 0;
- if(c->fcall->offset) {
- switch (qpath_type(m->qid.path)) {
- case Droot:
- /* jump to offset */
- len = type_to_stat(&stat, "ctl", 0);
- len += type_to_stat(&stat, "display", 0);
- len += type_to_stat(&stat, "font", 0);
- len += type_to_stat(&stat, "new", 0);
- len += type_to_stat(&stat, "event", 0);
- len += type_to_stat(&stat, "default", 0);
- for(i = 1; i < nitem; i++) {
- snprintf(buf, sizeof(buf), "%u", i);
- len += type_to_stat(&stat, buf, i);
- if(len < c->fcall->offset)
- continue;
- else
- break;
- }
- /* offset found, proceeding */
- for(; i < nitem; i++) {
- snprintf(buf, sizeof(buf), "%u", i);
- len = type_to_stat(&stat, buf, i);
- if(c->fcall->count + len >= c->fcall->iounit)
- break;
- c->fcall->count += len;
- p = ixp_enc_stat(p, &stat);
- }
- break;
- case Fevent:
- return 1;
- break;
- default:
- break;
- }
- }
- else {
- switch (qpath_type(m->qid.path)) {
- case Droot:
- c->fcall->count = type_to_stat(&stat, "ctl", 0);
- p = ixp_enc_stat(p, &stat);
- c->fcall->count += type_to_stat(&stat, "display", 0);
- p = ixp_enc_stat(p, &stat);
- c->fcall->count += type_to_stat(&stat, "font", 0);
- p = ixp_enc_stat(p, &stat);
- c->fcall->count += type_to_stat(&stat, "new", 0);
- p = ixp_enc_stat(p, &stat);
- c->fcall->count += type_to_stat(&stat, "event", 0);
- p = ixp_enc_stat(p, &stat);
- c->fcall->count += type_to_stat(&stat, "default", 0);
- p = ixp_enc_stat(p, &stat);
- for(i = 1; i < nitem; i++) {
- snprintf(buf, sizeof(buf), "%u", i);
- len = type_to_stat(&stat, buf, i);
- if(c->fcall->count + len >= c->fcall->iounit)
- break;
- c->fcall->count += len;
- p = ixp_enc_stat(p, &stat);
- }
- break;
- case Ditem:
- if(i > nitem)
- goto error_xread;
- if(!i) {
- c->fcall->count = type_to_stat(&stat, "color", i);
- p = ixp_enc_stat(p, &stat);
- break;
- }
- if(i == nitem)
- new_item();
- c->fcall->count = type_to_stat(&stat, "color", i);
- p = ixp_enc_stat(p, &stat);
- c->fcall->count += type_to_stat(&stat, "data", i);
- p = ixp_enc_stat(p, &stat);
- break;
- case Fctl:
- errstr = Enoperm;
- return -1;
- break;
- case Fdisplay:
- switch(align) {
- case SOUTH:
- memcpy(p, "south", 5);
- c->fcall->count = 5;
- break;
- case NORTH:
- memcpy(p, "north", 5);
- c->fcall->count = 5;
- break;
- default:
- memcpy(p, "none", 4);
- c->fcall->count = 4;
- break;
- }
- break;
- case Ffont:
- if((c->fcall->count = strlen(font)))
- memcpy(p, font, c->fcall->count);
- break;
- case Fexpand:
- snprintf(buf, sizeof(buf), "%u", iexpand);
- c->fcall->count = strlen(buf);
- memcpy(p, buf, c->fcall->count);
- break;
- case Fevent:
- return 1;
- break;
- case Fdata:
- if(i == nitem)
- new_item();
- if(i >= nitem)
- goto error_xread;
- if((c->fcall->count = strlen(item[i]->data)))
- memcpy(p, item[i]->data, c->fcall->count);
- break;
- case Fcolor:
- if(i == nitem)
- new_item();
- if(i >= nitem)
- goto error_xread;
- if((c->fcall->count = strlen(item[i]->color)))
- memcpy(p, item[i]->color, c->fcall->count);
- break;
- default:
- error_xread:
- if(!errstr)
- errstr = "invalid read";
- return -1;
- break;
- }
- }
- c->fcall->id = RREAD;
- return 0;
-}
-
-static int
-xstat(IXPConn *c)
-{
- IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
- char *name;
-
- if(!m) {
- errstr = Enofid;
- return -1;
- }
-
- name = qid_to_name(&m->qid);
- if(!type_to_stat(&c->fcall->stat, name, qpath_item(m->qid.path)))
- return -1;
- c->fcall->id = RSTAT;
- return 0;
-}
-
-static int
-xwrite(IXPConn *c)
-{
- char buf[256];
- IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
- unsigned short i;
-
- if(!m) {
- errstr = Enofid;
- return -1;
- }
-
- i = qpath_item(m->qid.path);
- switch (qpath_type(m->qid.path)) {
- case Fctl:
- if(c->fcall->count == 5) {
- memcpy(buf, c->fcall->data, 4);
- buf[4] = 0;
- if(!strncmp(buf, "quit", 5)) {
- srv.running = 0;
- break;
- }
- }
- errstr = "command not supported";
- return -1;
- break;
- case Fdisplay:
- if(c->fcall->count != 6 && c->fcall->count != 5)
- goto error_xwrite;
- memcpy(buf, c->fcall->data, c->fcall->count);
- buf[c->fcall->count] = 0;
- if(blitz_strtoalign(&align, buf) == -1)
- goto error_xwrite;
- update_geometry();
- if(align == NORTH || align == SOUTH) {
- XMapRaised(dpy, win);
- draw();
- }
- else
- XUnmapWindow(dpy, win);
- XSync(dpy, False);
- break;
- case Ffont:
- if(font)
- free(font);
- font = cext_emallocz(c->fcall->count + 1);
- memcpy(font, c->fcall->data, c->fcall->count);
- xfont = blitz_getfont(dpy, font);
- update_geometry();
- break;
- case Fexpand:
- {
- const char *err;
- if(c->fcall->count && c->fcall->count < 16) {
- memcpy(buf, c->fcall->data, c->fcall->count);
- buf[c->fcall->count] = 0;
- i = (unsigned short) cext_strtonum(buf, 1, 0xffff, &err);
- if(i < nitem) {
- iexpand = i;
- draw();
- break;
- }
- }
- }
- errstr = "item not found";
- return -1;
- break;
- case Fdata:
- {
- unsigned int len = c->fcall->count;
- if(i == nitem)
- new_item();
- if(!i || (i >= nitem))
- goto error_xwrite;
- if(len >= sizeof(item[i]->data))
- len = sizeof(item[i]->data) - 1;
- memcpy(item[i]->data, c->fcall->data, len);
- item[i]->data[len] = 0;
- draw();
- }
- break;
- case Fcolor:
- if(i == nitem)
- new_item();
- if((i >= nitem) || (c->fcall->count != 24)
- || (c->fcall->data[0] != '#') || (c->fcall->data[8] != '#')
- || (c->fcall->data[16] != '#'))
- {
- errstr = "wrong color format";
- goto error_xwrite;
- }
- memcpy(item[i]->color, c->fcall->data, c->fcall->count);
- item[i]->color[c->fcall->count] = 0;
- update_color(item[i]);
- draw();
- break;
- default:
-error_xwrite:
- if(!errstr)
- errstr = "invalid write";
- return -1;
- break;
- }
- c->fcall->id = RWRITE;
- return 0;
-}
-
-static int
-xclunk(IXPConn *c)
-{
- IXPMap *m = ixp_server_fid2map(c, c->fcall->fid);
-
- if(!m) {
- errstr = Enofid;
- return -1;
- }
- cext_array_detach((void **)c->map, m, &c->mapsz);
- free(m);
- c->fcall->id = RCLUNK;
- return 0;
-}
-
-static void
-close_ixp_conn(IXPServer *s, IXPConn *c)
-{
- size_t i;
- cext_array_detach((void **)s->conn, c, &s->connsz);
- if(c->map) {
- for(i = 0; (i < c->mapsz) && c->map[i]; i++)
- free(c->map[i]);
- free(c->map);
- }
- if(c->pend) {
- for(i = 0; (i < c->pendsz) && c->pend[i]; i++)
- free(c->pend[i]);
- free(c->pend);
- }
- shutdown(c->fd, SHUT_RDWR);
- close(c->fd);
- free(c);
-}
-
-static void
-do_fcall(IXPServer *s, IXPConn *c)
-{
- unsigned int msize;
- int ret = -1;
- errstr = 0;
- if(!(msize = ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &errstr))) {
- close_ixp_conn(s, c);
- return;
- }
- if(!c->fcall)
- c->fcall = cext_emallocz(sizeof(Fcall));
- if((msize = ixp_msg_to_fcall(msg, IXP_MAX_MSG, c->fcall))) {
- switch(c->fcall->id) {
- case TVERSION: ret = xversion(c); break;
- case TATTACH: ret = xattach(c); break;
- case TWALK: ret = xwalk(c); break;
- case TREMOVE: ret = xremove(c); break;
- case TOPEN: ret = xopen(c); break;
- case TREAD: ret = xread(c); break;
- case TWRITE: ret = xwrite(c); break;
- case TCLUNK: ret = xclunk(c); break;
- case TSTAT: ret = xstat(c); break;
- default:
- break;
- }
- }
- if(ret == -1) {
- if(!errstr)
- errstr = Enofunc;
- c->fcall->id = RERROR;
- cext_strlcpy(c->fcall->errstr, errstr, sizeof(c->fcall->errstr));
- }
- else if(ret == 1) {
- c->pend = (Fcall **)cext_array_attach((void **)c->pend, c->fcall, sizeof(Fcall *), &c->pendsz);
- c->fcall = nil;
- return; /* response asynchroneously */
- }
- msize = ixp_fcall_to_msg(c->fcall, msg, IXP_MAX_MSG);
- if(ixp_send_message(c->fd, msg, msize, &errstr) != msize)
- close_ixp_conn(s, c);
-}
-
-static Fcall *
-pending(IXPConn *c, unsigned char id)
-{
- size_t i;
- for(i = 0; (i < c->pendsz) && c->pend[i]; i++)
- if(c->pend[i]->id == id)
- return c->pend[i];
- return nil;
-}
-
-static void
-do_pend_fcall(char *event)
-{
- size_t i;
- Fcall *fcall;
- for(i = 0; (i < srv.connsz) && srv.conn[i]; i++) {
- IXPConn *c = srv.conn[i];
- /* all pending TREADs are on /event, so no qid checking necessary */
- while((fcall = pending(c, TREAD))) {
- IXPMap *m = ixp_server_fid2map(c, fcall->fid);
- unsigned char *p = fcall->data;
- unsigned int msize;
-
- if(!m) {
- errstr = Enofid;
- fcall->id = RERROR;
- }
- else if(qpath_type(m->qid.path) == Fevent) {
- fcall->count = strlen(event);
- memcpy(p, event, fcall->count);
- fcall->id = RREAD;
- }
- msize = ixp_fcall_to_msg(fcall, msg, IXP_MAX_MSG);
- /* remove pending request */
- cext_array_detach((void **)c->pend, fcall, &c->pendsz);
- free(fcall);
- if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) {
- close_ixp_conn(&srv, c);
- break;
- }
- }
- }
-}
-
-static void
-new_ixp_conn(IXPServer *s, IXPConn *c)
-{
- IXPConn *new;
- int fd = ixp_accept_sock(c->fd);
-
- if(fd >= 0) {
- new = cext_emallocz(sizeof(IXPConn));
- new->fd = fd;
- new->read = do_fcall;
- new->close = close_ixp_conn;
- s->conn = (IXPConn **)cext_array_attach((void **)s->conn, new,
- sizeof(IXPConn *), &s->connsz);
- }
-}
-
-
-/* main */
-
-int
-main(int argc, char *argv[])
-{
- int i;
- IXPConn *c;
- XSetWindowAttributes wa;
- XGCValues gcv;
-
- /* command line args */
- for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
- switch (argv[i][1]) {
- case 'v':
- fprintf(stdout, "%s", version[0]);
- exit(0);
- break;
- case 'a':
- if(i + 1 < argc)
- address = argv[++i];
- else
- usage();
- break;
- default:
- usage();
- break;
- }
- }
-
- dpy = XOpenDisplay(0);
- if(!dpy) {
- fprintf(stderr, "%s", "wmiibar: cannot open display\n");
- exit(1);
- }
- XSetErrorHandler(dummy_error_handler);
- screen_num = DefaultScreen(dpy);
-
- if(!address) {
- fprintf(stderr, "%s\n", "wmiibar: no socket address provided");
- exit(1);
- }
- i = ixp_create_sock(address, &errstr);
- if(i < 0) {
- fprintf(stderr, "wmiibar: fatal: %s\n", errstr);
- exit(1);
- }
-
- /* IXP server */
- c = cext_emallocz(sizeof(IXPConn));
- c->fd = i;
- c->read = new_ixp_conn;
- c->close = close_ixp_conn;
- srv.conn = (IXPConn **)cext_array_attach((void **)srv.conn, c,
- sizeof(IXPConn *), &srv.connsz);
- /* X server */
- c = cext_emallocz(sizeof(IXPConn));
- c->fd = ConnectionNumber(dpy);
- c->read = check_x_event;
- srv.conn = (IXPConn **)cext_array_attach((void **)srv.conn, c,
- sizeof(IXPConn *), &srv.connsz);
-
- root_qid.type = IXP_QTDIR;
- root_qid.version = 0;
- root_qid.path = mkqpath(Droot, 0);
-
- mypid = getpid();
-
- /* default settings */
- new_item();
- cext_strlcpy(item[0]->color, BLITZ_SEL_COLOR, sizeof(item[0]->color));
- update_color(item[0]);
-
- /* X stuff */
- font = strdup(BLITZ_FONT);
- xfont = blitz_getfont(dpy, font);
- wa.override_redirect = 1;
- wa.background_pixmap = ParentRelative;
- wa.event_mask = ExposureMask | ButtonPressMask
- | SubstructureRedirectMask | SubstructureNotifyMask;
-
- rect.x = rect.y = 0;
- rect.width = DisplayWidth(dpy, screen_num);
- rect.height = DisplayHeight(dpy, screen_num);
- brect = rect;
- brect.height = xfont->ascent + xfont->descent + 4;
- brect.y = rect.height - brect.height;
-
- win = XCreateWindow(dpy, RootWindow(dpy, screen_num), brect.x, brect.y,
- brect.width, brect.height, 0, DefaultDepth(dpy, screen_num),
- CopyFromParent, DefaultVisual(dpy, screen_num),
- CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
- XDefineCursor(dpy, win, XCreateFontCursor(dpy, XC_left_ptr));
- XSync(dpy, False);
-
- gcv.function = GXcopy;
- gcv.graphics_exposures = False;
- gc = XCreateGC(dpy, win, 0, 0);
-
- pmap = XCreatePixmap(dpy, win, brect.width, brect.height,
- DefaultDepth(dpy, screen_num));
-
- /* main loop */
- errstr = ixp_server_loop(&srv);
-
- if(errstr)
- fprintf(stderr, "wmiibar: fatal: %s\n", errstr);
-
- /* cleanup */
- for(i = 0; (i < srv.connsz) && srv.conn[i]; i++)
- if(srv.conn[i]->close)
- srv.conn[i]->close(&srv, srv.conn[i]);
-
- return errstr ? 1 : 0;
-}