wmii

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

commit 8a663e24d9773cb992f6ca7e5c72811e6b646835
parent 13a12b6a7d08ae5aadb66782f5e8c7a0b5312c6a
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Thu,  9 Feb 2006 22:48:01 +0100

removed much unnecessary stuff, merged bar into wm (still not working)


Diffstat:
Makefile | 6+++---
cmd/Makefile | 28+++++-----------------------
cmd/wm/Makefile | 10+++++-----
cmd/wm/bar.c | 103+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cmd/wm/client.c | 18+++++++++++++++++-
cmd/wm/event.c | 17++++++++++++++---
cmd/wm/fs.c | 221+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
cmd/wm/wm.c | 56+++++++++++++++++++++++++++++++++++++++++++++++++++-----
cmd/wm/wm.h | 63++++++++++++++++++++++++++++++++++++++++++++++++---------------
libwmii/ixp.c | 50--------------------------------------------------
10 files changed, 451 insertions(+), 121 deletions(-)

diff --git a/Makefile b/Makefile @@ -3,13 +3,13 @@ include config.mk -SUBDIRS = libcext liblitz libixp libwmii cmd +SUBDIRS = libcext liblitz libixp cmd -BIN = cmd/wm/wmii cmd/wm/wmiiwm cmd/wmiibar cmd/wmiifs \ +BIN = cmd/wm/wmii cmd/wm/wmiiwm cmd/wmiibar \ cmd/wmiiplumb cmd/wmiir cmd/wmiiwarp #cmd/wmiimenu cmd/wmiiplumb cmd/wmiir cmd/wmiiwarp -MAN1 = cmd/wm/wmii.1 cmd/wm/wmiiwm.1 cmd/wmiibar.1 cmd/wmiifs.1 \ +MAN1 = cmd/wm/wmii.1 cmd/wm/wmiiwm.1 cmd/wmiibar.1 \ cmd/wmiimenu.1 cmd/wmiir.1 all: diff --git a/cmd/Makefile b/cmd/Makefile @@ -3,11 +3,8 @@ include ../config.mk -CFLAGS += -I../liblitz -I../libixp -I../libwmii -I../libcext -LDFLAGS += -L../liblitz -llitz -L../libwmii -lwmii -L../libixp -lixp -L../libcext -lcext - -SRC_bar = wmiibar.c -OBJ_bar = ${SRC_bar:.c=.o} +CFLAGS += -I../liblitz -I../libixp -I../libcext +LDFLAGS += -L../liblitz -llitz -L../libixp -lixp -L../libcext -lcext SRC_menu = wmiimenu.c OBJ_menu = ${SRC_menu:.c=.o} @@ -15,29 +12,20 @@ OBJ_menu = ${SRC_menu:.c=.o} SRC_r = wmiir.c OBJ_r = ${SRC_r:.c=.o} -SRC_fs = wmiifs.c -OBJ_fs = ${SRC_fs:.c=.o} - SRC_plumb = wmiiplumb.c OBJ_plumb = ${SRC_plumb:.c=.o} SRC_warp = wmiiwarp.c OBJ_warp = ${SRC_warp:.c=.o} -#all: wmiibar wmiimenu wmiir wmiifs wmiiplumb wmiiwarp -all: wmiifs wmiibar wmiir wmiiplumb wmiiwarp +#all: wmiimenu wmiir wmiiplumb wmiiwarp +all: wmiir wmiiplumb wmiiwarp @echo built wmii commands .c.o: @echo CC $< @${CC} -c ${CFLAGS} $< -wmiibar: ${OBJ_bar} - @echo LD $@ - @${CC} -o $@ ${OBJ_bar} ${LDFLAGS} -# Solaris -# @${CC} -o $@ ${OBJ_bar} ${LDFLAGS} -lsocket - wmiimenu: ${OBJ_menu} @echo LD $@ @${CC} -o $@ ${OBJ_menu} ${LDFLAGS} @@ -52,12 +40,6 @@ wmiir: ${OBJ_r} # @${CC} -o $@ ${OBJ_r} -g -static -L${PREFIX}/lib -L/usr/lib -lc \ # -L../libixp -lixp -L../libcext -lcext -lsocket -wmiifs: ${OBJ_fs} - @echo LD $@ - @${CC} -o $@ ${OBJ_fs} ${LDFLAGS} -# Solaris -# @${CC} -o $@ ${OBJ_fs} ${LDFLAGS} -lsocket - wmiiplumb: ${OBJ_plumb} @echo LD $@ @${CC} -o $@ ${OBJ_plumb} ${LDFLAGS} @@ -67,4 +49,4 @@ wmiiwarp: ${OBJ_warp} @${CC} -o $@ ${OBJ_warp} ${LDFLAGS} clean: - rm -f wmiibar wmiimenu wmiir wmiiplumb wmiifs wmiiwarp *.o + rm -f wmiimenu wmiir wmiiplumb wmiiwarp *.o diff --git a/cmd/wm/Makefile b/cmd/wm/Makefile @@ -3,14 +3,14 @@ include ../../config.mk -CFLAGS += -I../../liblitz -I../../libixp -I../../libwmii \ - -I../../libcext -LDFLAGS += -L../../liblitz -llitz -L../../libwmii -lwmii \ - -L../../libixp -lixp -L../../libcext -lcext +CFLAGS += -I../../liblitz -I../../libixp -I../../libcext +LDFLAGS += -L../../liblitz -llitz -L../../libixp -lixp -L../../libcext -lcext + # Solaris # LDFLAGS += -lsocket -SRC = area.c fs.c wm.c kb.c client.c event.c mouse.c page.c column.c +SRC = area.c bar.c fs.c wm.c kb.c client.c event.c mouse.c page.c\ + column.c spawn.c OBJ = ${SRC:.c=.o} all: wmiiwm diff --git a/cmd/wm/bar.c b/cmd/wm/bar.c @@ -0,0 +1,103 @@ +/* + * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <string.h> + +#include "wm.h" + +Item * +new_item() +{ + static unsigned int id = 1; + Item *it = cext_emallocz(sizeof(Item)); + it->id = id++; + cext_strlcpy(it->colstr, def.selcolor, sizeof(it->colstr)); + it->color = def.sel; + item = (Item **)cext_array_attach((void **)item, it, sizeof(Item *), &itemsz); + nitem++; + return it; +} + +void +detach_item(Item *it) +{ + cext_array_detach((void **)item, it, &itemsz); + nitem--; +} + +void +draw_bar() +{ + size_t i; + unsigned int w = 0; + Draw d = { 0 }; + + d.align = WEST; + d.gc = gcbar; + d.drawable = pmapbar; + d.rect = brect; + d.rect.y = 0; + d.font = xfont; + + if(!nitem) { /* /default only */ + d.color = def.sel; + blitz_drawlabel(dpy, &d); + } + else { + for(i = 0; i < nitem; i++) { + Item *it = item[i]; + it->rect.x = it->rect.y = 0; + it->rect.height = brect.height; + if(i == iexpand) + continue; + it->rect.width = brect.height; + 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 = 0; i < nitem; i++) { + item[i]->rect.x = i * w; + item[i]->rect.width = w; + } + i--; + item[i]->rect.width = brect.width - item[i]->rect.x; + } + else { + item[iexpand]->rect.width = brect.width - w; + for(i = 1; i < nitem; i++) + item[i]->rect.x = item[i - 1]->rect.x + item[i - 1]->rect.width; + } + + for(i = 0; i < nitem; i++) { + d.color = item[i]->color; + 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, pmapbar, winbar, gcbar, 0, 0, brect.width, brect.height, 0, 0); + XSync(dpy, False); +} + +int +index_of_bar_id(unsigned short id) +{ + int i; + for(i = 0; i < nitem; i++) + if(item[i]->id == id) + return i; + return -1; +} diff --git a/cmd/wm/client.c b/cmd/wm/client.c @@ -174,11 +174,26 @@ configure_client(Client * c) XSync(dpy, False); } +static void +send_client_message(Window w, Atom a, long value) +{ + XEvent e; + e.type = ClientMessage; + e.xclient.window = w; + e.xclient.message_type = a; + e.xclient.format = 32; + e.xclient.data.l[0] = value; + e.xclient.data.l[1] = CurrentTime; + + XSendEvent(dpy, w, False, NoEventMask, &e); + XSync(dpy, False); +} + void close_client(Client * c) { if(c->proto & PROTO_DEL) - wmii_send_message(dpy, c->win, wm_protocols, wm_delete); + send_client_message(c->win, wm_protocols, wm_delete); else XKillClient(dpy, c->win); } @@ -543,3 +558,4 @@ index_of_client_id(Area *a, unsigned short id) return i; return -1; } + diff --git a/cmd/wm/event.c b/cmd/wm/event.c @@ -64,7 +64,15 @@ handle_buttonpress(XEvent *e) XButtonPressedEvent *ev = &e->xbutton; Align align; static char buf[32]; - if((c = win_to_frame(ev->window))) { + if(ev->window == winbar) { + size_t i; + for(i = 0; i < nitem; i++) + if(blitz_ispointinrect(ev->x, ev->y, &item[i]->rect)) { + snprintf(buf, sizeof(buf), "L%d B%d\n", i, ev->button); + do_pend_fcall(buf); + } + } + else if((c = win_to_frame(ev->window))) { if(ev->button == Button1) { if(sel_client() != c) { focus_client(c); @@ -184,9 +192,12 @@ handle_destroynotify(XEvent *e) static void handle_expose(XEvent *e) { + XExposeEvent *ev = &e->xexpose; static Client *c; - if(e->xexpose.count == 0) { - if((c = win_to_frame(e->xbutton.window))) + if(ev->count == 0) { + if(ev->window == winbar) + draw_bar(); + else if((c = win_to_frame(ev->window))) draw_client(c); } } diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c @@ -13,13 +13,20 @@ #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 "wm.h" +static char E9pversion[] = "9P version not supported"; +static char Enoperm[] = "permission denied"; +static char Enofid[] = "fid not found"; +static char Enofile[] = "file not found"; +static char Enomode[] = "mode not supported"; +static char Enofunc[] = "function not supported"; +static char Enocommand[] = "command not supported"; + /* * filesystem specification * / Droot @@ -31,6 +38,12 @@ * /keys/ Dkeys * /keys/grab Fgrab interface to grab shortcuts * /keys/foo Fkey + * /bar/ Dbar + * /bar/expand Fexpand id of expandable label + * /bar/new/ Ditem + * /bar/1/ Ditem + * /bar/1/data Fdata <arbitrary data which gets displayed> + * /bar/1/color Fcolor <#RRGGBB> <#RRGGBB> <#RRGGBB> * /event Fevent * /ctl Fctl command interface (root) * /new/ Dpage returns new page @@ -116,12 +129,17 @@ qid_to_name(Qid *qid) case Droot: return "/"; break; case Ddef: return "def"; break; case Dkeys: return "keys"; break; + case Dbar: return "bar"; break; case Dpage: if(pg == sel) return "sel"; snprintf(buf, sizeof(buf), "%u", pg + 1); return buf; break; + case Ditem: + snprintf(buf, sizeof(buf), "%u", pg + 1); + return buf; + break; case Darea: if(!area) { if(page[pg]->sel) @@ -140,6 +158,9 @@ qid_to_name(Qid *qid) snprintf(buf, sizeof(buf), "%u", cl + 1); return buf; break; + case Fcolor: return "color"; break; + case Fdata: return "data"; break; + case Fexpand: return "expand"; break; case Fctl: return "ctl"; break; case Fborder: return "border"; break; case Fsnap: return "border"; break; @@ -163,9 +184,13 @@ name_to_type(char *name, unsigned char dtyp) if(!strncmp(name, "new", 4)) { if(dtyp == Droot) return Dpage; - else if(dtyp == Dpage) + if(dtyp == Dbar) + return Ditem; + if(dtyp == Dpage) return Darea; } + if(!strncmp(name, "bar", 4)) + return Dbar; if(!strncmp(name, "def", 4)) return Ddef; if(!strncmp(name, "keys", 5)) @@ -188,6 +213,12 @@ name_to_type(char *name, unsigned char dtyp) return Finc; if(!strncmp(name, "geometry", 9)) return Fgeom; + if(!strncmp(name, "expand", 7)) + return Fexpand; + if(!strncmp(name, "color", 6)) + return Fcolor; + if(!strncmp(name, "data", 5)) + return Fdata; if(key_of_name(name)) return Fkey; if(!strncmp(name, "sel", 4)) @@ -199,6 +230,7 @@ dyndir: /*fprintf(stderr, "nametotype: dtyp = %d\n", dtyp);*/ switch(dtyp) { case Droot: return Dpage; break; + case Dbar: return Ditem; break; case Dpage: return Darea; break; case Darea: return Dclient; break; } @@ -239,6 +271,27 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) new->type = IXP_QTDIR; new->path = mkqpath(Dkeys, 0, 0, 0); break; + case Dbar: + new->type = IXP_QTDIR; + new->path = mkqpath(Dbar, 0, 0, 0); + break; + case Ditem: + new->type = IXP_QTDIR; + if(!strncmp(wname, "new", 4)) { + /*fprintf(stderr, "mkqid iswalk=%d, wname=%s\n", iswalk, wname);*/ + if(iswalk) + new->path = mkqpath(Ditem, new_item()->id, 0, 0); + else + new->path = mkqpath(Ditem, 0,0 ,0); + } + else { + i = cext_strtonum(wname, 1, 0xffff, &err); + if(err || (i - 1 >= nitem)) + return -1; + new->path = mkqpath(Ditem, item[i - 1]->id, 0, 0); + } + break; + case Dpage: new->type = IXP_QTDIR; if(!strncmp(wname, "new", 4)) { @@ -318,6 +371,10 @@ mkqid(Qid *dir, char *wname, Qid *new, Bool iswalk) new->path = mkqpath(Fkey, k->id, 0, 0); } break; + case Fdata: + case Fcolor: + if(dpgid >= nitem) + return -1; default: new->type = IXP_QTFILE; new->path = mkqpath(type, dpgid, daid, dcid); @@ -463,6 +520,7 @@ type_to_stat(Stat *stat, char *name, Qid *dir) case Dpage: case Ddef: case Dkeys: + case Dbar: case Droot: return mkstat(stat, dir, name, 0, DMDIR | DMREAD | DMEXEC); break; @@ -508,11 +566,50 @@ type_to_stat(Stat *stat, char *name, Qid *dir) case Fkey: return mkstat(stat, dir, name, 0, 0); break; + case Fexpand: + snprintf(buf, sizeof(buf), "%u", iexpand + 1); + return mkstat(stat, dir, name, strlen(buf), DMREAD | DMWRITE); + break; + case Fdata: + return mkstat(stat, dir, name, (dpg == nitem) ? 0 : strlen(item[dpg]->data), DMREAD | DMWRITE); + break; + case Fcolor: + return mkstat(stat, dir, name, 23, DMREAD | DMWRITE); + break; } return 0; } static char * +xremove(IXPConn *c, Fcall *fcall) +{ + IXPMap *m = ixp_server_fid2map(c, fcall->fid); + unsigned short id = qpath_pgid(m->qid.path); + int i; + + if(!m) + return Enofid; + if(id && ((i = index_of_page_id(id)) == -1)) + return Enofile; + if((qpath_type(m->qid.path) == Ditem) && (i < nitem)) { + Item *it = item[i]; + /* clunk */ + cext_array_detach((void **)c->map, m, &c->mapsz); + free(m); + /* now detach the item */ + detach_item(it); + free(it); + if(iexpand >= nitem) + iexpand = 0; + draw_bar(); + fcall->id = RREMOVE; + ixp_server_respond_fcall(c, fcall); + return nil; + } + return Enoperm; +} + +static char * xread(IXPConn *c, Fcall *fcall) { Stat stat; @@ -546,6 +643,8 @@ xread(IXPConn *c, Fcall *fcall) len = type_to_stat(&stat, "ctl", &m->qid); len += type_to_stat(&stat, "event", &m->qid); len += type_to_stat(&stat, "default", &m->qid); + len += type_to_stat(&stat, "keys", &m->qid); + len += type_to_stat(&stat, "bar", &m->qid); len += type_to_stat(&stat, "new", &m->qid); for(i = 0; i < npage; i++) { if(i == sel) @@ -590,6 +689,27 @@ xread(IXPConn *c, Fcall *fcall) p = ixp_enc_stat(p, &stat); } break; + case Dbar: + /* jump to offset */ + len = type_to_stat(&stat, "expand", &m->qid); + len += type_to_stat(&stat, "new", &m->qid); + for(i = 0; i < nitem; i++) { + snprintf(buf, sizeof(buf), "%u", i + 1); + len += type_to_stat(&stat, buf, &m->qid); + if(len <= fcall->offset) + continue; + break; + } + /* offset found, proceeding */ + for(; i < nitem; i++) { + snprintf(buf, sizeof(buf), "%u", i + 1); + len = type_to_stat(&stat, buf, &m->qid); + if(fcall->count + len > fcall->iounit) + break; + fcall->count += len; + p = ixp_enc_stat(p, &stat); + } + break; case Dpage: /* jump to offset */ len = type_to_stat(&stat, "ctl", &m->qid); @@ -661,6 +781,10 @@ xread(IXPConn *c, Fcall *fcall) p = ixp_enc_stat(p, &stat); fcall->count += type_to_stat(&stat, "default", &m->qid); p = ixp_enc_stat(p, &stat); + fcall->count += type_to_stat(&stat, "keys", &m->qid); + p = ixp_enc_stat(p, &stat); + fcall->count += type_to_stat(&stat, "bar", &m->qid); + p = ixp_enc_stat(p, &stat); fcall->count += type_to_stat(&stat, "new", &m->qid); p = ixp_enc_stat(p, &stat); for(i = 0; i < npage; i++) { @@ -687,13 +811,29 @@ xread(IXPConn *c, Fcall *fcall) p = ixp_enc_stat(p, &stat); } break; - case Ddef: - fcall->count = type_to_stat(&stat, "font", &m->qid); + case Dbar: + fcall->count = type_to_stat(&stat, "expand", &m->qid); + p = ixp_enc_stat(p, &stat); + fcall->count += type_to_stat(&stat, "new", &m->qid); p = ixp_enc_stat(p, &stat); - fcall->count += type_to_stat(&stat, "selcolor", &m->qid); + for(i = 0; i < nitem; i++) { + snprintf(buf, sizeof(buf), "%u", i + 1); + len = type_to_stat(&stat, buf, &m->qid); + if(fcall->count + len > fcall->iounit) + break; + fcall->count += len; + p = ixp_enc_stat(p, &stat); + } + break; + case Ditem: + if(i >= nitem) + return Enofile; + fcall->count = type_to_stat(&stat, "color", &m->qid); p = ixp_enc_stat(p, &stat); - fcall->count += type_to_stat(&stat, "normcolor", &m->qid); + fcall->count += type_to_stat(&stat, "data", &m->qid); p = ixp_enc_stat(p, &stat); + break; + case Ddef: fcall->count += type_to_stat(&stat, "border", &m->qid); p = ixp_enc_stat(p, &stat); fcall->count += type_to_stat(&stat, "bar", &m->qid); @@ -704,7 +844,6 @@ xread(IXPConn *c, Fcall *fcall) p = ixp_enc_stat(p, &stat); break; case Dpage: - /*fprintf(stderr, "XXXXXXXXXX p->narea=%d\n", page[pg]->narea);*/ fcall->count = type_to_stat(&stat, "ctl", &m->qid); p = ixp_enc_stat(p, &stat); fcall->count += type_to_stat(&stat, "new", &m->qid); @@ -800,6 +939,23 @@ xread(IXPConn *c, Fcall *fcall) if((fcall->count = strlen(page[pg]->area[area]->client[cl]->name))) memcpy(p, page[pg]->area[area]->client[cl]->name, fcall->count); break; + case Fexpand: + snprintf(buf, sizeof(buf), "%u", iexpand + 1); + fcall->count = strlen(buf); + memcpy(p, buf, fcall->count); + break; + case Fdata: + if(pg >= nitem) + return Enofile; + if((fcall->count = strlen(item[pg]->data))) + memcpy(p, item[pg]->data, fcall->count); + break; + case Fcolor: + if(pg >= nitem) + return Enofile; + if((fcall->count = strlen(item[pg]->colstr))) + memcpy(p, item[pg]->colstr, fcall->count); + break; default: return "invalid read"; break; @@ -950,7 +1106,6 @@ xwrite(IXPConn *c, Fcall *fcall) static char last[2048]; /* iounit */ char fcallbuf[2048], tmp[2048]; /* iounit */ char *p1, *p2; - Key *k; if(!fcall->offset) { while(nkey) { Key *k = key[0]; @@ -970,10 +1125,7 @@ xwrite(IXPConn *c, Fcall *fcall) memcpy(tmp, p1, lastcount - (p1 - last)); memcpy(tmp + (lastcount - (p1 - last)), p2, p2 - fcallbuf); tmp[(lastcount - (p1 - last)) + (p2 - fcallbuf)] = 0; - k = create_key(tmp); - key = (Key **)cext_array_attach((void **)key, k, sizeof(Key *), &keysz); - nkey++; - grab_key(k); + grab_key(create_key(tmp)); } else p2 = fcallbuf; @@ -984,10 +1136,7 @@ xwrite(IXPConn *c, Fcall *fcall) if(!p1) return "cannot grab, no \n supplied"; *p1 = 0; - k = create_key(p2); - key = (Key **)cext_array_attach((void **)key, k, sizeof(Key *), &keysz); - nkey++; - grab_key(k); + grab_key(create_key(p2)); *p1 = '\n'; p2 = ++p1; } @@ -995,6 +1144,45 @@ xwrite(IXPConn *c, Fcall *fcall) memcpy(last, fcall->data, fcall->count); } break; + case Fexpand: + { + const char *err; + if(fcall->count && fcall->count < 16) { + memcpy(buf, fcall->data, fcall->count); + buf[fcall->count] = 0; + i = (unsigned short) cext_strtonum(buf, 1, 0xffff, &err); + if(!err && (pg - 1 < nitem)) { + iexpand = pg - 1; + draw_bar(); + break; + } + } + } + return Enofile; + break; + case Fdata: + { + unsigned int len = fcall->count; + if(pg >= nitem) + return Enofile; + if(len >= sizeof(item[pg]->data)) + len = sizeof(item[pg]->data) - 1; + memcpy(item[pg]->data, fcall->data, len); + item[pg]->data[len] = 0; + draw_bar(); + } + break; + case Fcolor: + if((pg >= nitem) || (fcall->count != 23) + || (fcall->data[0] != '#') || (fcall->data[8] != '#') + || (fcall->data[16] != '#') + ) + return "wrong color format"; + memcpy(item[pg]->colstr, fcall->data, fcall->count); + item[pg]->colstr[fcall->count] = 0; + blitz_loadcolor(dpy, screen, item[pg]->colstr, &item[pg]->color); + draw_bar(); + break; default: return "invalid write"; break; @@ -1032,6 +1220,7 @@ do_fcall(IXPConn *c) case TATTACH: errstr = xattach(c, &fcall); break; case TWALK: errstr = xwalk(c, &fcall); break; case TOPEN: errstr = xopen(c, &fcall); break; + case TREMOVE: errstr = xremove(c, &fcall); break; case TREAD: errstr = xread(c, &fcall); break; case TWRITE: errstr = xwrite(c, &fcall); break; case TCLUNK: errstr = xclunk(c, &fcall); break; diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c @@ -394,6 +394,27 @@ scan_wins() XFree(wins); } +static int +win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) +{ + Atom real; + int format; + unsigned long res, extra; + int status; + + status = + XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format, + &res, &extra, prop); + + if(status != Success || *prop == 0) { + return 0; + } + if(res == 0) { + free((void *) *prop); + } + return res; +} + int win_proto(Window w) { @@ -402,8 +423,7 @@ win_proto(Window w) int protos = 0; int i; - res = - wmii_property(dpy, w, wm_protocols, XA_ATOM, 20L, + res = win_property(w, wm_protocols, XA_ATOM, 20L, ((unsigned char **) &protocols)); if(res <= 0) { return protos; @@ -425,8 +445,8 @@ win_state(Window w) int res; long *prop = 0; - if(wmii_property - (dpy, w, wm_state, wm_state, 2L, ((unsigned char **) &prop)) > 0) { + if(win_property(w, wm_state, wm_state, 2L, + ((unsigned char **) &prop)) > 0) { res = (int) *prop; free((long *) prop); } else { @@ -561,6 +581,7 @@ main(int argc, char *argv[]) int i; int checkwm = 0; char *address = nil, *errstr; + XSetWindowAttributes wa; /* command line args */ if(argc > 1) { @@ -638,6 +659,11 @@ main(int argc, char *argv[]) client = det = nil; aq = nil; + key = nil; + keysz = nkey = 0; + item = nil; + nitem = itemsz = iexpand = 0; + def.font = strdup(BLITZ_FONT); def.border = DEF_BORDER; def.snap = DEF_SNAP; @@ -650,9 +676,29 @@ main(int argc, char *argv[]) init_atoms(); init_cursors(); xfont = blitz_getfont(dpy, def.font); - wmii_init_lock_modifiers(dpy, &valid_mask, &num_lock_mask); + init_lock_modifiers(); init_screen(); scan_wins(); + + wa.override_redirect = 1; + wa.background_pixmap = ParentRelative; + wa.event_mask = ExposureMask | ButtonPressMask + | SubstructureRedirectMask | SubstructureNotifyMask; + brect = rect; + brect.height = xfont->ascent + xfont->descent + 4; + brect.y = rect.height - brect.height; + winbar = XCreateWindow(dpy, RootWindow(dpy, screen), brect.x, brect.y, + brect.width, brect.height, 0, DefaultDepth(dpy, screen), + CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + + XDefineCursor(dpy, winbar, XCreateFontCursor(dpy, XC_left_ptr)); + XSync(dpy, False); + + gcbar = XCreateGC(dpy, winbar, 0, 0); + + pmapbar = XCreatePixmap(dpy, winbar, brect.width, brect.height, + DefaultDepth(dpy, screen)); /* main event loop */ errstr = ixp_server_loop(&srv); if(errstr) diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h @@ -7,7 +7,8 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> -#include "wmii.h" +#include "ixp.h" +#include "blitz.h" /* array indexes of EWMH window properties */ /* TODO: set / react */ @@ -25,6 +26,11 @@ enum { Darea, Dclient, Dkeys, + Dbar, + Ditem, + Fexpand, + Fdata, /* data to display */ + Fcolor, Fkey, Fgrab, Fborder, @@ -105,6 +111,27 @@ struct Key { Key *next; }; +typedef struct { + unsigned short id; + char data[256]; + char colstr[24]; + Color color; + XRectangle rect; +} Item; + +/* default values */ +typedef struct { + char selcolor[24]; + char normcolor[24]; + char *font; + Bool bar; + Bool inc; + Color sel; + Color norm; + unsigned int border; + unsigned int snap; +} Default; + /* global variables */ Page **page; size_t npage; @@ -121,6 +148,10 @@ size_t clientsz; Key **key; size_t keysz; size_t nkey; +Item **item; +size_t nitem; +size_t itemsz; +size_t iexpand; Display *dpy; IXPServer *ixps; @@ -132,19 +163,11 @@ XFontStruct *xfont; GC gc_xor; GC gc_transient; IXPServer srv; - -/* default values */ -typedef struct { - char selcolor[24]; - char normcolor[24]; - char *font; - Bool bar; - Bool inc; - Color sel; - Color norm; - unsigned int border; - unsigned int snap; -} Default; +Pixmap pmapbar; +Window winbar; +GC gcbar; +XRectangle brect; +Qid root_qid; Default def; @@ -176,6 +199,12 @@ void destroy_area(Area *a); int index_of_area(Page *p, Area *a); int index_of_area_id(Page *p, unsigned short id); +/* bar.c */ +Item *new_item(); +void detach_item(Item *it); +void draw_bar(); +int index_of_item_id(unsigned short id); + /* client.c */ Client *alloc_client(Window w, XWindowAttributes *wa); void destroy_client(Client * c); @@ -212,9 +241,10 @@ void handle_key(Window w, unsigned long mod, KeyCode keycode); void grab_key(Key *k); void ungrab_key(Key *k); Key * key_of_name(char *name); -int index_of_id(unsigned short id); +int index_of_key_id(unsigned short id); Key *create_key(char *name); void destroy_key(Key *k); +void init_lock_modifiers(); /* mouse.c */ void mouse_resize(Client *c, Align align); @@ -233,6 +263,9 @@ void focus_page(Page *p); XRectangle *rectangles(unsigned int *num); int index_of_page_id(unsigned short id); +/* spawn.c */ +void spawn(char *cmd); + /* column.c */ void arrange_page(Page *p); void arrange_column(Page *p, Area *col); diff --git a/libwmii/ixp.c b/libwmii/ixp.c @@ -1,50 +0,0 @@ -/* - * (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 "wmii.h" - -/* default handler */ - -char * -wmii_ixp_version(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; -} - -char * -wmii_ixp_attach(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; -} - -char * -wmii_ixp_clunk(IXPConn *c, Fcall *fcall) -{ - IXPMap *m = ixp_server_fid2map(c, fcall->fid); - - if(!m) - return Enofid; - cext_array_detach((void **)c->map, m, &c->mapsz); - free(m); - fcall->id = RCLUNK; - ixp_server_respond_fcall(c, fcall); - return nil; -}