[hackers] [wmii] Significant changes:

From: Kris Maglione <jg_AT_suckless.org>
Date: Mon Jan 21 00:31:04 2008

changeset: 2233:17e5122b3d37
user: Kris Maglione <jg_AT_suckless.org>
date: Thu Jan 17 17:50:35 2008 -0500
summary: Significant changes:

diff -r b6315bae8a5d -r 17e5122b3d37 Makefile
--- a/Makefile Wed Jan 16 01:01:04 2008 -0500
+++ b/Makefile Thu Jan 17 17:50:35 2008 -0500
@@ -2,15 +2,16 @@ include ${ROOT}/mk/hdr.mk
 include ${ROOT}/mk/hdr.mk
 
 PDIRS = \
- cmd \
- rc \
+ cmd \
+ libwmii_hack \
+ rc \
         man
 
 DIRS = \
- libutf \
- libfmt \
- libbio \
- libregexp\
+ libbio \
+ libfmt \
+ libregexp \
+ libutf \
         ${PDIRS}
 
 config:
@@ -23,6 +24,5 @@ deb:
         dpkg-buildpackage -rfakeroot
 
 include ${ROOT}/mk/dir.mk
-include ${ROOT}/mk/common.mk
 INSTDIRS = ${PDIRS}
 
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/Makefile
--- a/cmd/Makefile Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/Makefile Thu Jan 17 17:50:35 2008 -0500
@@ -1,36 +1,39 @@ ROOT=..
 ROOT=..
-include ${ROOT}/mk/hdr.mk
-include ${ROOT}/mk/wmii.mk
+include $(ROOT)/mk/hdr.mk
+include $(ROOT)/mk/wmii.mk
 
-wmiir.c: ${ROOT}/mk/wmii.mk
+wmiir.c: $(ROOT)/mk/wmii.mk
 
 DIRS = wmii
-TARG = wmii9menu \
+TARG = wihack \
+ wmii.rc \
+ wmii9menu \
         wmii9rc \
         wmiiloop \
         wmiir \
         wmiistartrc
 
 OFILES = util.o
-FILTER = sed "s|CONFPREFIX|${ETC}|g; \
- s|CONFVERSION|${CONFVERSION}|g; \
- s|P9PATHS|${P9PATHS}|g; \
- s|AWKPATH|${AWKPATH}|g"
+FILTER = sed "s|CONFPREFIX|$(ETC)|g; \
+ s|CONFVERSION|$(CONFVERSION)|g; \
+ s|P9PATHS|$(P9PATHS)|g; \
+ s|LIBDIR|$(LIBDIR)|g; \
+ s|AWKPATH|$(AWKPATH)|g"
 
 LDFLAGS += -lfmt -lutf
-CFLAGS += ${INCX11} -DVERSION=\"${VERSION}\"
+CFLAGS += $(INCX11) -DVERSION=\"$(VERSION)\"
 
-include ${ROOT}/mk/many.mk
-include ${ROOT}/mk/dir.mk
+include $(ROOT)/mk/many.mk
+include $(ROOT)/mk/dir.mk
 
-OWMIIR=wmiir.o ${OFILES} ${LIBIXP}
-wmiir.O: ${OWMIIR}
- ${LINK} $@ ${STATIC} ${OWMIIR}
+OWMIIR=wmiir.o $(OFILES) $(LIBIXP)
+wmiir.O: $(OWMIIR)
+ $(LINK) $@ $(STATIC) $(OWMIIR)
 
-OMENU=menu.o wmii/x11.o ${OFILES} ${LIBIXP}
-menu.O: ${OMENU} dall
- ${LINK} $@ ${OMENU}
+OMENU=menu.o wmii/x11.o $(OFILES) $(LIBIXP)
+menu.O: $(OMENU) dall
+ $(LINK) $@ $(OMENU)
 
-wmii9menu.O: wmii9menu.o ${OFILES}
- ${LINK} $@ $*.o ${OFILES} ${LIBX11}
+wmii9menu.O: wmii9menu.o $(OFILES)
+ $(LINK) $@ $*.o $(OFILES) $(LIBX11)
 
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wihack.sh
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd/wihack.sh Thu Jan 17 17:50:35 2008 -0500
@@ -0,0 +1,43 @@
+#!/bin/sh -f
+
+usage() {
+ echo 1>&2 Usage: \
+ "$0 [-transient <window>] [-type <window_type>[,...]] [-tags <tags>] <command> [<arg> ...]"
+ exit 1
+}
+
+checkarg='[ ${#@} -gt 0 ] || usage'
+
+while [ ${#@} -gt 0 ]
+do
+ case $1 in
+ -transient)
+ shift; eval $checkarg
+ export WMII_HACK_TRANSIENT=$1
+ shift;;
+ -type)
+ shift; eval $checkarg
+ export WMII_HACK_TYPE=$1
+ shift;;
+ -tags)
+ shift; eval $checkarg
+ export WMII_HACK_TAGS=$1
+ shift;;
+ -*)
+ usage;;
+ *)
+ break;;
+ esac
+done
+
+eval $checkarg
+
+if [ ! -u "`which $1`" -a ! -g "`which $1`" ]
+then
+ export LD_PRELOAD=libwmii_hack.so
+ export LD_LIBRARY_PATH="LIBDIR${LD_LIBRARY_PATH:+:}${LD_LIBRARY_PATH}"
+else
+ unset WMII_HACK_TRANSIENT WMII_HACK_TYPE WMII_HACK_TAGS
+fi
+exec "$@"
+
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii.rc.rc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd/wmii.rc.rc Thu Jan 17 17:50:35 2008 -0500
@@ -0,0 +1,127 @@
+
+wmiiscript=$1
+wmiikeys=()
+
+echo Start $wmiiscript | wmiir write /event >[2]/dev/null \
+ || exit write
+
+if(~ $scriptname '')
+ scriptname=$wmiiscript
+
+# Blech.
+if(! test -x $PLAN9/bin/read)
+ fn read { sh -c 'read -r x || exit 1; echo $x' }
+
+fn wi_atexit {}
+fn sigexit {
+ wi_atexit
+}
+
+fn Event-Start {
+ if(~ $1 $wmiiscript)
+ exit
+}
+
+fn Event-Key { Key-$1 $1 }
+
+fn wi_fatal {
+ echo $scriptname: Fatal: $*
+ exit fatal
+}
+
+fn wi_notice {
+ xmessage $scriptname: Notice: $*
+}
+
+fn wi_readctl { wmiir read /ctl | sed -n 's/^'$1' (.*)/\1/p' }
+
+wmiifont=`{wi_readctl font}
+wmiinormcol=`{wi_readctl normcolors}
+wmiifocuscol=`{wi_readctl focuscolors}
+
+fn wi_menu {
+ dmenu -b -fn $wmiifont \
+ -nf $wmiinormcol(1) -nb $wmiinormcol(2) \
+ -sf $wmiifocuscol(1) -sb $wmiifocuscol(2)
+}
+
+fn wi_9menu {
+ wmii9menu -font `{echo $wmiifont | sed 's/,.*//'} \
+ -^(nf nb br)^$wmiinormcol \
+ -^(sf sb br)^$wmiifocuscol $*
+}
+
+fn wi_proglist {
+ /bin/ls -lL `{echo $* | sed 'y/:/ /'} >[2]/dev/null \
+ | awk '$1 ~ /^[^d].*x/ { print $NF }' \
+ | sort | uniq
+}
+
+fn wi_actions {
+ { wi_proglist $WMII_CONFPATH
+ wi_getfuns Action
+ } | sort | uniq
+}
+
+fn wi_script {
+ prog = `{@{path=$confpath whatis $1} |
+ grep -v '^fn|= ' || echo /dev/null}
+ shift; echo $prog $*
+}
+
+
+fn wi_initkeys {
+ ifs=() {
+ wmiikeys = `{wmiir read /keys} {
+ mykeys = `{comm -23 \
+ <{wi_getfuns Key | sort | uniq} \
+ <{echo $wmiikeys | sort | uniq}}
+ {echo $wmiikeys; wi_getfuns Key} \
+ | sort | uniq \
+ | wmiir write /keys
+ }
+ }
+ fn wi_atexit {
+ wi_cleankeys
+ }
+}
+
+fn wi_cleankeys {
+ ifs=() {
+ wmiikeys = `{wmiir read /keys} {
+ comm -23 <{echo $wmiikeys | sort | uniq} \
+ <{echo $mykeys} \
+ | wmiir write /keys
+ }
+ }
+}
+
+fn wi_runcmd { @{
+ rfork ns
+ path=$oldpath
+ if(~ $1 -t) {
+ shift
+ * = (wihack -tags `{wmiir read /tag/sel/ctl | sed 1q} $*)
+ }
+ eval exec $* &
+ }
+}
+
+fn wi_getfuns {
+ env | sed -n 's/^fn#'^$1^'-([^=]+).*/\1/p'
+}
+
+fn wi_tags {
+ wmiir ls /tag | sed 's,/,,; /^sel$/d'
+}
+
+fn wi_eventloop {
+ wi_initkeys
+
+ wmiir read /event |
+ while(*=`{read}) {
+ event = $1; shift
+ Event-$event $*
+ } >[2]/dev/null </dev/null
+}
+
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/Makefile
--- a/cmd/wmii/Makefile Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/Makefile Thu Jan 17 17:50:35 2008 -0500
@@ -9,7 +9,8 @@ HFILES= dat.h fns.h
 
 LIB = ${LIBIXP}
 LDFLAGS += -lm ${LIBX11} -lXext ${LIBICONV} -lregexp9 -lbio -lfmt -lutf
-CFLAGS += ${INCX11} ${INCICONV} -DVERSION=\"${VERSION}\"
+CFLAGS += ${INCX11} ${INCICONV} -DVERSION=\"${VERSION}\" \
+ -DIXP_NEEDAPI=86
 OBJ = area \
         bar \
         client \
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/area.c
--- a/cmd/wmii/area.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/area.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,5 +1,5 @@
 /* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
- * Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
@@ -32,6 +32,8 @@ area_name(Area *a) {
 area_name(Area *a) {
         static char buf[16];
         
+ if(a == nil)
+ return "<nil>";
         if(a->floating)
                 return "~";
         snprint(buf, sizeof(buf), "%d", area_idx(a));
@@ -130,11 +132,17 @@ area_destroy(Area *a) {
 
         idx = area_idx(a);
 
- if(a->prev)
+ if(a->prev && !a->prev->floating)
                 ta = a->prev;
         else
                 ta = a->next;
 
+ if(a == v->colsel)
+ v->colsel = ta;
+
+ /* Can only destroy the floating area when destroying a
+ * view---after destroying all columns.
+ */
         assert(a->prev || a->next == nil);
         if(a->prev)
                 a->prev->next = a->next;
@@ -142,8 +150,6 @@ area_destroy(Area *a) {
                 a->next->prev = a->prev;
 
         if(ta && v->sel == a) {
- if(ta->floating && ta->next)
- ta = ta->next;
                 area_focus(ta);
         }
         event("DestroyArea %d\n", idx);
@@ -187,7 +193,7 @@ area_setsel(Area *a, Frame *f) {
 
 void
 area_attach(Area *a, Frame *f) {
- uint n_frame;
+ uint nframe;
         Frame *ft;
         Client *c;
 
@@ -195,15 +201,15 @@ area_attach(Area *a, Frame *f) {
 
         f->area = a;
 
- n_frame = 0;
+ nframe = 0;
         for(ft=a->frame; ft; ft=ft->anext)
- n_frame++;
- n_frame = max(n_frame, 1);
+ nframe++;
+ nframe = max(nframe, 1);
 
         c->floating = a->floating;
         if(!a->floating) {
                 f->r = a->r;
- f->r.max.y = Dy(a->r) / n_frame;
+ f->r.max.y = Dy(a->r) / nframe;
         }
 
         frame_insert(a->sel, f);
@@ -237,13 +243,6 @@ area_detach(Frame *f) {
 
         pr = f->aprev;
         frame_remove(f);
-
- if(a->sel == f) {
- if(!pr)
- pr = a->frame;
- if(pr)
- area_setsel(a, pr);
- }
 
         if(!a->floating) {
                 if(a->frame)
@@ -255,16 +254,19 @@ area_detach(Frame *f) {
                                 area_focus(v->area);
                         view_arrange(v);
                 }
- }else if(!a->frame) {
- if(c->trans || (c->w.ewmh.type & (TypeDialog|TypeSplash)))
- if(v->oldsel) {
- area_focus(v->oldsel);
- return;
- }
- if(v->area->next->frame)
- area_focus(v->area->next);
+ }else if(v->oldsel)
+ area_focus(v->oldsel);
+ else if(!a->frame) {
+ if(v->colsel->frame)
+ area_focus(v->colsel);
         }else
                 assert(a->sel);
+
+ if(a->sel == f) {
+ if(!pr)
+ pr = a->frame;
+ area_setsel(a, pr);
+ }
 }
 
 static void
@@ -421,6 +423,8 @@ area_focus(Area *a) {
                 return;
 
         v->sel = a;
+ if(!a->floating)
+ v->colsel = a;
 
         if((old_a) && (a->floating != old_a->floating))
                 v->revert = old_a;
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/bar.c
--- a/cmd/wmii/bar.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/bar.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,5 +1,5 @@
 /* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
- * Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/client.c
--- a/cmd/wmii/client.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/client.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,5 +1,5 @@
 /* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
- * Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
@@ -157,11 +157,10 @@ void
 void
 client_manage(Client *c) {
         Client *trans;
+ Frame *f;
         char *tags;
 
- tags = gettextproperty(&c->w, "_WMII_TAGS");
- if(tags == nil)
- tags = gettextproperty(&c->w, "_WIN_TAGS");
+ tags = getprop_string(&c->w, "_WMII_TAGS");
 
         trans = win2client(c->trans);
         if(trans == nil && c->group)
@@ -181,15 +180,23 @@ client_manage(Client *c) {
         if(!starting)
                 view_update_all();
 
- if(c->sel->view == screen->sel)
- if(!(c->w.ewmh.type & TypeSplash))
- if(!c->group || c->group->ref == 1
- || selclient() && selclient()->group == c->group)
+ bool newgroup = !c->group
+ || c->group->ref == 1
+ || selclient() && (selclient()->group == c->group);
+
+ f = c->sel;
+ if((f->view == screen->sel)
+ && (!(c->w.ewmh.type & TypeSplash))
+ && newgroup) {
+ if(f->area != f->view->sel)
+ f->view->oldsel = f->view->sel;
                 focus(c, false);
+ }
         else {
                 frame_restack(c->sel, c->sel->area->sel);
                 view_restack(c->sel->view);
         }
+
         flushenterevents();
 }
 
@@ -206,8 +213,6 @@ client_destroy(Client *c) {
         char *dummy;
         Client **tc;
         bool hide;
-
- Dprint(DGeneric, "client.c:client_destroy(%p) %s\n", c, c->name);
 
         unmapwin(c->framewin);
 
@@ -509,15 +514,17 @@ client_sendmessage(Client *c, char *name
         e.message_type = xatom(name);
         e.format = 32;
         e.data.l[0] = xatom(value);
- e.data.l[1] = CurrentTime;
+ e.data.l[1] = xtime;
         sendevent(&c->w, false, NoEventMask, (XEvent*)&e);
         sync();
 }
 
 void
-client_kill(Client * c) {
- if(c->proto & WM_PROTOCOL_DELWIN)
+client_kill(Client *c, bool nice) {
+ if(nice && (c->proto & ProtoDelete)) {
                 client_sendmessage(c, "WM_PROTOCOLS", "WM_DELETE_WINDOW");
+ ewmh_pingclient(c);
+ }
         else
                 XKillClient(display, c->w.w);
 }
@@ -617,9 +624,9 @@ client_updatename(Client *c) {
 
         c->name[0] = '\0';
 
- str = gettextproperty(&c->w, "_NET_WM_NAME");
+ str = getprop_string(&c->w, "_NET_WM_NAME");
         if(str == nil)
- str = gettextproperty(&c->w, "WM_NAME");
+ str = getprop_string(&c->w, "WM_NAME");
         if(str)
                 utflcpy(c->name, str, sizeof(c->name));
         free(str);
@@ -702,7 +709,7 @@ client_prop(Client *c, Atom a) {
                 }
                 break;
         case XA_WM_CLASS:
- n = gettextlistproperty(&c->w, "WM_CLASS", &class);
+ n = getprop_textlist(&c->w, "WM_CLASS", &class);
                 snprint(c->props, sizeof(c->props), "%s:%s:",
                                 (n > 0 ? class[0] : "<nil>"),
                                 (n > 1 ? class[1] : "<nil>"));
@@ -775,7 +782,8 @@ enter_event(Window *w, XCrossingEvent *e
                         focus(c, false);
                 }
                 client_setcursor(c, cursor[CurNormal]);
- }else Dprint(DGeneric, "enter_notify(c[NotifyInferior]) => %s\n", c->name);
+ }else
+ Dprint(DGeneric, "enter_notify(c[NotifyInferior]) => %s\n", c->name);
 }
 
 static void
@@ -857,38 +865,6 @@ static Handlers handlers = {
 };
 
 /* Other */
-#if 0 /* Not used at the moment */
-void
-newcol_client(Client *c, char *arg) {
- Frame *f;
- Area *to, *a;
- View *v;
-
- f = c->sel;
- a = f->area;
- v = f->view;
-
- if(a->floating)
- return;
- if((f->anext == nil) && (f->aprev == nil))
- return;
-
- if(!strncmp(arg, "prev", 5)) {
- for(to=v->area; to; to=to->next)
- if(to->next == a) break;
- to = column_new(v, to, 0);
- area_moveto(to, f);
- }
- else if(!strncmp(arg, "next", 5)) {
- to = column_new(v, a, 0);
- area_moveto(to, f);
- }
- else
- return;
- flushenterevents();
-}
-#endif
-
 void
 client_setviews(Client *c, char **tags) {
         Frame **fp, *f;
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/column.c
--- a/cmd/wmii/column.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/column.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,5 +1,5 @@
 /* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
- * Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/dat.h
--- a/cmd/wmii/dat.h Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/dat.h Thu Jan 17 17:50:35 2008 -0500
@@ -1,4 +1,4 @@
-/* © 2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
+/* Copyright ©2007-2008 Kris Maglione <jg_AT_suckless.org>
  * See LICENSE file for license details.
  */
 
@@ -20,6 +20,10 @@
 #define FOCUSCOLORS "#ffffff #335577 #447799"
 #define NORMCOLORS "#222222 #eeeeee #666666"
 
+enum {
+ PingTime = 10000,
+};
+
 enum EWMHType {
         TypeDesktop = 1<<0,
         TypeDock = 1<<1,
@@ -56,7 +60,12 @@ enum {
 
 enum {
         NCOL = 16,
- WM_PROTOCOL_DELWIN = 1,
+};
+
+enum Protocols {
+ ProtoDelete = 1<<0,
+ ProtoTakeFocus = 1<<1,
+ ProtoPing = 1<<2,
 };
 
 enum DebugOpt {
@@ -122,7 +131,7 @@ struct Client {
         char tags[256];
         char props[512];
         uint border;
- int proto;
+ long proto;
         char floating;
         char fixedsize;
         char fullscreen;
@@ -213,6 +222,7 @@ struct View {
         ushort id;
         Area* area;
         Area* sel;
+ Area* colsel;
         Area* oldsel;
         Area* revert;
 };
@@ -293,6 +303,7 @@ EXTERN char* user;
 EXTERN char* user;
 EXTERN char* execstr;
 EXTERN int debug;
+EXTERN long xtime;
 
 #define Debug(x) if(debug&(x))
 #define Dprint(x, ...) BLOCK( Debug(x) fprint(2, __VA_ARGS__) )
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/event.c
--- a/cmd/wmii/event.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/event.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,4 +1,4 @@
-/* Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+/* Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
@@ -135,6 +135,7 @@ enternotify(XEvent *e) {
         Window *w;
 
         ev = &e->xcrossing;
+ xtime = ev->time;
         if(ev->mode != NotifyNormal)
                 return;
 
@@ -151,6 +152,7 @@ leavenotify(XEvent *e) {
         XCrossingEvent *ev;
 
         ev = &e->xcrossing;
+ xtime = ev->time;
         if((ev->window == scr.root.w) && !ev->same_screen) {
                 sel_screen = True;
                 frame_draw_all();
@@ -247,6 +249,7 @@ keypress(XEvent *e) {
         XKeyEvent *ev;
 
         ev = &e->xkey;
+ xtime = ev->time;
         ev->state &= valid_mask;
         if(ev->window == scr.root.w)
                 kpress(scr.root.w, ev->state, (KeyCode) ev->keycode);
@@ -286,6 +289,7 @@ motionnotify(XEvent *e) {
         Window *w;
 
         ev = &e->xmotion;
+ xtime = ev->time;
         if((w = findwin(ev->window)))
                 handle(w, motion, ev);
 }
@@ -296,6 +300,7 @@ propertynotify(XEvent *e) {
         Window *w;
 
         ev = &e->xproperty;
+ xtime = ev->time;
         if((w = findwin(ev->window)))
                 handle(w, property, ev);
 }
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/ewmh.c
--- a/cmd/wmii/ewmh.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/ewmh.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,4 +1,4 @@
-/* Copyright ©2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+/* Copyright ©2007-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
@@ -17,6 +17,22 @@ Window *ewmhwin;
 #define STATE(x) xatom(State(x))
 #define TYPE(x) xatom(Type(x))
 
+static void
+senemessage(Window *w, char *name, char *value, long l2, long l3, long l4) {
+ XClientMessageEvent e;
+
+ e.type = ClientMessage;
+ e.window = w->w;
+ e.message_type = xatom(name);
+ e.format = 32;
+ e.data.l[0] = xatom(value);
+ e.data.l[1] = xtime;
+ e.data.l[2] = l2;
+ e.data.l[3] = l3;
+ e.data.l[4] = l4;
+ sendevent(w, false, NoEventMask, (XEvent*)&e);
+}
+
 void
 ewmh_init(void) {
         WinAttr wa;
@@ -28,10 +44,8 @@ ewmh_init(void) {
                 InputOnly, &wa, 0);
 
         win[0] = ewmhwin->w;
- changeprop_long(&scr.root, Net("SUPPORTING_WM_CHECK"), "WINDOW",
- win, 1);
- changeprop_long(ewmhwin, Net("SUPPORTING_WM_CHECK"), "WINDOW",
- win, 1);
+ changeprop_long(&scr.root, Net("SUPPORTING_WM_CHECK"), "WINDOW", win, 1);
+ changeprop_long(ewmhwin, Net("SUPPORTING_WM_CHECK"), "WINDOW", win, 1);
         changeprop_string(ewmhwin, Net("WM_NAME"), myname);
         changeprop_long(&scr.root, Net("DESKTOP_VIEWPORT"), "CARDINAL",
                 (long[]){0, 0}, 2);
@@ -123,7 +137,39 @@ ewmh_initclient(Client *c) {
 
 void
 ewmh_destroyclient(Client *c) {
+ Ewmh *e;
+
         ewmh_updateclientlist();
+
+ e = &c->w.ewmh;
+ if(e->timer)
+ ixp_unsettimer(&srv, e->timer);
+}
+
+static void
+pingtimeout(long id, void *v) {
+ Client *c;
+
+ c = v;
+ event("Unresponsive %C\n", c);
+ c->w.ewmh.ping = 0;
+ c->w.ewmh.timer = 0;
+}
+
+void
+ewmh_pingclient(Client *c) {
+ Ewmh *e;
+
+ if(!(c->proto & ProtoPing))
+ return;
+
+ e = &c->w.ewmh;
+ if(e->ping)
+ return;
+
+ senemessage(&c->w, "WM_PROTOCOLS", Net("WM_PING"), c->w.w, 0, 0);
+ e->ping = xtime++;
+ e->timer = ixp_settimer(&srv, PingTime, pingtimeout, c);
 }
 
 void
@@ -135,13 +181,37 @@ ewmh_prop(Client *c, Atom a) {
                 ewmh_getstrut(c);
 }
 
+typedef struct Prop Prop;
+struct Prop {
+ char* name;
+ long mask;
+ Atom atom;
+};
+
+static long
+getmask(Prop *props, long *vals, int n) {
+ Prop *p;
+ long ret;
+
+ if(props[0].atom == 0)
+ for(p=props; p->name; p++)
+ p->atom = xatom(p->name);
+
+ ret = 0;
+ while(n--) {
+ Dprint(DEwmh, "\tvals[%d] = \"%A\"\n", n, vals[n]);
+ for(p=props; p->name; p++)
+ if(p->atom == vals[n]) {
+ ret |= p->mask;
+ break;
+ }
+ }
+ return ret;
+}
+
 void
 ewmh_getwintype(Client *c) {
- struct {
- char* name;
- long mask;
- Atom atom;
- } static pairs[] = {
+ static Prop props[] = {
                 {Type("DESKTOP"), TypeDesktop},
                 {Type("DOCK"), TypeDock},
                 {Type("TOOLBAR"), TypeToolbar},
@@ -151,39 +221,40 @@ ewmh_getwintype(Client *c) {
                 {Type("DIALOG"), TypeDialog},
                 {Type("NORMAL"), TypeNormal},
                 {0, }
- }, *pair;
- Atom actual, atom;
+ };
         long *types;
- long mask;
- ulong n;
- int i;
-
- if(!pairs[0].atom)
- for(pair=pairs; pair->name; pair++)
- pair->atom = xatom(pair->name);
-
- n = getproperty(&c->w, Net("WM_WINDOW_TYPE"), "ATOM", &actual,
- 0L, (void*)&types, nelem(types));
-
- Dprint(DEwmh, "ewmh_getwintype(%C) actual = %A; n = %d\n", c, actual, n);
- if(actual != xatom("ATOM"))
- return;
-
- mask = 0;
- for(i=0; i < n; i++) {
- atom = types[i];
- Dprint(DEwmh, "\ttypes[%d] = \"%A\"\n", i, types[i], types[i]);
- for(pair=pairs; pair->name; pair++)
- if(pair->atom == atom) {
- mask |= pair->mask;
- break;
- }
- }
+ long n, mask;
+
+ n = getprop_long(&c->w, Net("WM_WINDOW_TYPE"), "ATOM",
+ 0L, &types, 16);
+ Dprint(DEwmh, "ewmh_getwintype(%C) n = %ld\n", c, n);
+ mask = getmask(props, types, n);
+ free(types);
+
         c->w.ewmh.type = mask;
         if(mask & TypeDock) {
                 c->borderless = 1;
                 c->titleless = 1;
         }
+}
+
+long
+ewmh_protocols(Window *w) {
+ static Prop props[] = {
+ {"WM_DELETE_WINDOW", ProtoDelete},
+ {"WM_TAKE_FOCUS", ProtoTakeFocus},
+ {Net("WM_PING"), ProtoPing},
+ {0, }
+ };
+ long *protos;
+ long n, mask;
+
+ n = getprop_long(w, "WM_PROTOCOLS", "ATOM",
+ 0L, &protos, 16);
+ Dprint(DEwmh, "ewmh_protocols(%W) n = %ld\n", w, n);
+ mask = getmask(props, protos, n);
+ free(protos);
+ return mask;
 }
 
 void
@@ -293,6 +364,26 @@ ewmh_clientmessage(XClientMessageEvent *
                 if(i == 0)
                         view_select(v->name);
                 return 1;
+ }else
+ if(msg == xatom("WM_PROTOCOLS")) {
+ Dprint(DEwmh, "\t%A\n", l[0]);
+ if(l[0] == NET("WM_PING")) {
+ if(e->format != 32)
+ return -1;
+ if(e->window != scr.root.w)
+ return -1;
+ c = win2client(l[2]);
+ if(c == nil)
+ return 1;
+ Dprint(DEwmh, "\tclient = [%C]\"%s\"\n", c, clientname(c));
+ Dprint(DEwmh, "\ttimer = %ld, ping = %ld\n",
+ c->w.ewmh.timer, c->w.ewmh.ping);
+ if(c->w.ewmh.timer)
+ ixp_unsettimer(&srv, c->w.ewmh.timer);
+ c->w.ewmh.timer = 0;
+ c->w.ewmh.ping = 0;
+ return 1;
+ }
         }
 
         return 0;
@@ -335,7 +426,6 @@ ewmh_updatestate(Client *c) {
         if(c->urgent)
                 state[i++] = STATE("DEMANDS_ATTENTION");
 
- assert(i < nelem(state)); /* Can't happen. */
         if(i > 0)
                 changeprop_long(&c->w, Net("WM_STATE"), "ATOM", state, i);
         else
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/fns.h
--- a/cmd/wmii/fns.h Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/fns.h Thu Jan 17 17:50:35 2008 -0500
@@ -1,4 +1,4 @@
-/* © 2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
+/* Copyright ©2007-2008 Kris Maglione <jg_AT_suckless.org>
  * See LICENSE file for license details.
  */
 
@@ -75,7 +75,7 @@ Client* client_create(XWindow, XWindowAt
 Client* client_create(XWindow, XWindowAttributes*);
 void client_destroy(Client*);
 void client_focus(Client*);
-void client_kill(Client*);
+void client_kill(Client*, bool);
 void client_manage(Client*);
 void client_map(Client*);
 void client_prop(Client*, Atom);
@@ -121,7 +121,9 @@ void ewmh_getwintype(Client*);
 void ewmh_getwintype(Client*);
 void ewmh_init(void);
 void ewmh_initclient(Client*);
+void ewmh_pingclient(Client*);
 void ewmh_prop(Client*, Atom);
+long ewmh_protocols(Window*);
 void ewmh_updateclient(Client*);
 void ewmh_updateclientlist(void);
 void ewmh_updateclients(void);
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/frame.c
--- a/cmd/wmii/frame.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/frame.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,4 +1,4 @@
-/* Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+/* Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
@@ -106,16 +106,17 @@ frame_restack(Frame *f, Frame *above) {
         if(f->snext)
                 f->snext->sprev = f->sprev;
 
- f->snext = a->stack;
         f->sprev = above;
- if(above == nil)
+ if(above == nil) {
+ f->snext = a->stack;
                 a->stack = f;
- else
+ }
+ else {
                 f->snext = above->snext;
+ above->snext = f;
+ }
         if(f->snext)
                 f->snext->sprev = f;
- if(f->sprev)
- f->sprev->snext = f;
 
         return true;
 }
@@ -403,11 +404,10 @@ frame_focus(Frame *f) {
         old_f = old_a->sel;
         a->sel = f;
 
- if(a != old_a) {
- if(c->trans || (c->w.ewmh.type & (TypeDialog|TypeSplash)))
- v->oldsel = v->sel;
+ if(a != old_a)
                 area_focus(f->area);
- }
+ if(old_a != v->oldsel && f != old_f)
+ v->oldsel = nil;
 
         if(v != screen->sel || a != v->sel)
                 return;
@@ -429,6 +429,7 @@ frame_draw(Frame *f) {
         Rectangle r, fr;
         CTuple *col;
         Frame *tf;
+ uint w;
 
         if(f->view != screen->sel)
                 return;
@@ -483,15 +484,24 @@ frame_draw(Frame *f) {
         r.max.x = fr.max.x;
         r.min.y = 0;
         r.max.y = labelh(def.font);
- drawstring(screen->ibuf, def.font, r, WEST,
+ if(f->client->floating)
+ r.max.x -= Dx(f->grabbox);
+ w = drawstring(screen->ibuf, def.font, r, WEST,
                         f->client->name, col->fg);
+
+ if(f->client->floating) {
+ r.min.x = r.min.x + w + 10;
+ r.max.x = f->titlebar.max.x + 1;
+ r.min.y = f->grabbox.min.y;
+ r.max.y = f->grabbox.max.y;
+ border(screen->ibuf, r, 1, col->border);
+ }
 
         /* Why? Because some non-ICCCM-compliant apps feel the need to
          * change the background properties of all of their ancestor windows
- * in order to implement pseudo-transparency. Lovely, no?
+ * in order to implement pseudo-transparency.
          * What's more, the designers of X11 felt that it would be unfair to
          * implementers to make it possible to detect, or forbid, such changes.
- * This is why we love X11 so.
          */
         XSetWindowBackgroundPixmap(display, f->client->framewin->w, None);
 
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/fs.c
--- a/cmd/wmii/fs.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/fs.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,4 +1,4 @@
-/* Copyright ©2006 Kris Maglione <fbsdaemon at gmail dot com>
+/* Copyright ©2006-2008 Kris Maglione <fbsdaemon at gmail dot com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/geom.c
--- a/cmd/wmii/geom.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/geom.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,4 +1,4 @@
-/* Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+/* Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/main.c
--- a/cmd/wmii/main.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/main.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,5 +1,5 @@
 /* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
- * Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #define EXTERN
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/message.c
--- a/cmd/wmii/message.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/message.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,4 +1,4 @@
-/* Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+/* Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
@@ -38,6 +38,7 @@ enum {
         LSELCOLORS,
         LSELECT,
         LSEND,
+ LSLAY,
         LSWAP,
         LTOGGLE,
         LUP,
@@ -66,6 +67,7 @@ char *symtab[] = {
         "selcolors",
         "select",
         "send",
+ "slay",
         "swap",
         "toggle",
         "up",
@@ -274,7 +276,10 @@ message_client(Client *c, IxpMsg *m) {
                 fullscreen(c, i);
                 break;
         case LKILL:
- client_kill(c);
+ client_kill(c, true);
+ break;
+ case LSLAY:
+ client_kill(c, false);
                 break;
         case LURGENT:
                 i = gettoggle(m);
@@ -573,7 +578,7 @@ msg_selectframe(Frame *f, IxpMsg *m, int
         SET(fp);
         switch(sym) {
         case LUP:
- for(fp = a->frame; fp->anext; fp = fp->anext)
+ for(fp=a->frame; fp->anext; fp=fp->anext)
                         if(fp->anext == f) break;
                 break;
         case LDOWN:
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/mouse.c
--- a/cmd/wmii/mouse.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/mouse.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,4 +1,4 @@
-/* Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+/* Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/rule.c
--- a/cmd/wmii/rule.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/rule.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,5 +1,4 @@
-/*
- * Copyright ©2006 Anselm R. Garbe <garbeam at gmail dot com>
+/* Copyright ©2006 Anselm R. Garbe <garbeam at gmail dot com>
  * See LICENSE file for license details.
  */
 
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/view.c
--- a/cmd/wmii/view.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/view.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,5 +1,5 @@
 /* Copyright ©2004-2006 Anselm R. Garbe <garbeam at gmail dot com>
- * Copyright ©2006-2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * Copyright ©2006-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #include "dat.h"
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii/x11.c
--- a/cmd/wmii/x11.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii/x11.c Thu Jan 17 17:50:35 2008 -0500
@@ -1,4 +1,4 @@
-/* Copyright ©2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+/* Copyright ©2007-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
  * See LICENSE file for license details.
  */
 #define _X11_VISIBLE
@@ -25,8 +25,9 @@ Window *const pointerwin = (Window*)&_po
 Window *const pointerwin = (Window*)&_pointerwin;
 
 static Map wmap, amap;
-static MapEnt *wbucket[137];
-static MapEnt *abucket[137];
+static MapEnt* wbucket[137];
+static MapEnt* abucket[137];
+
 
 /* Rectangles/Points */
 XRectangle
@@ -334,25 +335,9 @@ findwin(XWindow w) {
         return nil;
 }
 
-uint
+long
 winprotocols(Window *w) {
- Atom *protocols;
- Atom delete;
- int i, n, protos;
-
- n = getprop_long(w, "WM_PROTOCOLS", "ATOM", 0L, (long**)&protocols, 20L);
- if(n == 0)
- return 0;
-
- protos = 0;
- delete = xatom("WM_DELETE_WINDOW");
- for(i = 0; i < n; i++) {
- if(protocols[i] == delete)
- protos |= WM_PROTOCOL_DELWIN;
- }
-
- free(protocols);
- return protos;
+ return ewmh_protocols(w);
 }
 
 /* Shape */
@@ -431,7 +416,7 @@ drawline(Image *dst, Point p1, Point p2,
         XDrawLine(display, dst->image, dst->gc, p1.x, p1.y, p2.x, p2.y);
 }
 
-void
+uint
 drawstring(Image *dst, Font *font,
                 Rectangle r, Align align,
                 char *text, ulong col) {
@@ -491,6 +476,7 @@ drawstring(Image *dst, Font *font,
 
 done:
         free(buf);
+ return w;
 }
 
 void
@@ -751,7 +737,7 @@ strlistdup(char *list[], int n) {
 }
 
 int
-gettextlistproperty(Window *w, char *name, char **ret[]) {
+getprop_textlist(Window *w, char *name, char **ret[]) {
         XTextProperty prop;
         char **list;
         int n;
@@ -769,13 +755,13 @@ gettextlistproperty(Window *w, char *nam
 }
 
 char*
-gettextproperty(Window *w, char *name) {
+getprop_string(Window *w, char *name) {
         char **list, *str;
         int n;
 
         str = nil;
 
- n = gettextlistproperty(w, name, &list);
+ n = getprop_textlist(w, name, &list);
         if(n > 0)
                 str = estrdup(*list);
         freestringlist(list);
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmii9rc.sh
--- a/cmd/wmii9rc.sh Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmii9rc.sh Thu Jan 17 17:50:35 2008 -0500
@@ -1,7 +1,7 @@
 #!/bin/sh -f
 RC=""
 IFS=:
-for i in "$PLAN9" `echo P9PATHS`; do
+for i in "$PLAN9" `echo "P9PATHS"`; do
         if [ -d "$i" -a -x "$i/bin/rc" ]; then
                 export PLAN9="$i"
                 RC="$i/bin/rc"
@@ -9,7 +9,7 @@ for i in "$PLAN9" `echo P9PATHS`; do
         fi
 done
 
-if [ -n "$RC" ]; then
+if [ -z "$RC" ]; then
         exit 1
 fi
 
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmiir.c
--- a/cmd/wmiir.c Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmiir.c Thu Jan 17 17:50:35 2008 -0500
@@ -239,7 +239,7 @@ xls(int argc, char *argv[]) {
         Stat *stat;
         IxpCFid *fid;
         char *file;
- uchar *buf;
+ char *buf;
         int lflag, dflag, count, nstat, mstat, i;
 
         lflag = dflag = 0;
diff -r b6315bae8a5d -r 17e5122b3d37 cmd/wmiistartrc.sh
--- a/cmd/wmiistartrc.sh Wed Jan 16 01:01:04 2008 -0500
+++ b/cmd/wmiistartrc.sh Thu Jan 17 17:50:35 2008 -0500
@@ -3,15 +3,16 @@
 
 export home="$HOME"
 lconf="$home/.wmii-CONFVERSION"
-gconf="CONFPREFIX/.wmii-CONFVERSION"
+gconf="CONFPREFIX/wmii-CONFVERSION"
 
-export WMII_CONFPATH="$conf:$gconf"
+export WMII_CONFPATH="$lconf:$gconf"
 export POSIXLY_CORRECT=gnu_hippies
 
+which="`which which`"
 if wmii9rc; then
- WMIIRC=`PATH="$WMII_CONFPATH:$PATH" which rc.wmii`
+ WMIIRC=`PATH="$WMII_CONFPATH:$PATH" $which rc.wmii`
 else
- WMIIRC=`PATH="$WMII_CONFPATH:$PATH" which wmiirc`
+ WMIIRC=`PATH="$WMII_CONFPATH:$PATH" $which wmiirc`
 fi
 
 mkdir $conf 2>/dev/null && $gconf/welcome &
diff -r b6315bae8a5d -r 17e5122b3d37 config.mk
--- a/config.mk Wed Jan 16 01:01:04 2008 -0500
+++ b/config.mk Thu Jan 17 17:50:35 2008 -0500
@@ -2,38 +2,39 @@
 
 # paths
 PREFIX = /usr/local
-BIN = ${PREFIX}/bin
-MAN = ${PREFIX}/share/man
-ETC = ${PREFIX}/etc
-LIBDIR = ${PREFIX}/lib
-INCLUDE = ${PREFIX}/include
+ BIN = $(PREFIX)/bin
+ MAN = $(PREFIX)/share/man
+ ETC = $(PREFIX)/etc
+ LIBDIR = $(PREFIX)/lib
+ INCLUDE = $(PREFIX)/include
 
 # Includes and libs
-INCPATH = .:${ROOT}/include:${INCLUDE}:/usr/include
-LIBS = -L/usr/lib -lc -L${ROOT}/lib
+INCPATH = .:$(ROOT)/include:$(INCLUDE):/usr/include
+LIBS = -L/usr/lib -lc -L$(ROOT)/lib
 
 # Flags
-include ${ROOT}/mk/gcc.mk
-CFLAGS += ${DEBUGCFLAGS} -DIXPlint
-LDFLAGS += -g ${LIBS}
+include $(ROOT)/mk/gcc.mk
+CFLAGS += $(DEBUGCFLAGS)
+LDFLAGS += -g $(LIBS)
+SOLDFLAGS += $(LDFLAGS)
 STATIC = -static
-MKDEP = cpp -M
 
-# Compiler
+# Compiler, Linker. Linker should usually *not* be ld.
 CC = cc -c
-# Linker (Under normal circumstances, this should *not* be 'ld')
 LD = cc
 # Archiver
 AR = ar crs
 
 AWKPATH = $$(which awk)
-P9PATHS = ${PLAN9}:"'$${HOME}/plan9'":/usr/local/plan9:/usr/local/9:/opt/plan9:/opt/9:/usr/plan9:/usr/9
+P9PATHS = ${PLAN9}:"'$$(HOME)/plan9'":/usr/local/plan9:/usr/local/9:/opt/plan9:/opt/9:/usr/plan9:/usr/9
 
 INCX11 = -I/usr/X11R6/include
 LIBX11 = -L/usr/X11R6/lib -lX11
 LIBICONV = # Leave blank if your libc includes iconv (glibc does)
-LIBIXP = ${ROOT}/libixp/libixp.a
-LIBIXP = ${LIBDIR}/libixp.a
+LIBIXP = $(ROOT)/libixp/libixp.a
+LIBIXP = $(LIBDIR)/libixp.a
+
+# Operating System Configurations
 
 # *BSD
 #LIBICONV = -liconv
@@ -41,8 +42,7 @@ LIBIXP = ${LIBDIR}/libixp.a
 #STATIC = # Darwon doesn't like static linking
 
 # Solaris
-#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
-#LDFLAGS = ${LIBS} -R${PREFIX}/lib
-#LDFLAGS += -lsocket -lnsl
+#CFLAGS = -fast $(INCS)
+#LDFLAGS = $(LIBS) -R$(PREFIX)/lib -lsocket -lnsl
 #CFLAGS += -xtarget=ultra
 
diff -r b6315bae8a5d -r 17e5122b3d37 include/util.h
--- a/include/util.h Wed Jan 16 01:01:04 2008 -0500
+++ b/include/util.h Thu Jan 17 17:50:35 2008 -0500
@@ -1,3 +1,6 @@
+/* Copyright ©2007-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * See LICENSE file for license details.
+ */
 #define nil ((void*)0)
 #define nelem(ary) (sizeof(ary) / sizeof(*ary))
 
diff -r b6315bae8a5d -r 17e5122b3d37 include/x11.h
--- a/include/x11.h Wed Jan 16 01:01:04 2008 -0500
+++ b/include/x11.h Thu Jan 17 17:50:35 2008 -0500
@@ -1,3 +1,6 @@
+/* Copyright ©2007-2008 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * See LICENSE file for license details.
+ */
 #define Window XWindow
 #define Font XFont
 #define Screen XScreen
@@ -53,7 +56,9 @@ struct Rectangle {
 };
 
 struct Ewmh {
- long type;
+ long type;
+ long ping;
+ long timer;
 };
 
 struct Window {
@@ -157,8 +162,6 @@ XRectangle XRect(Rectangle r);
                 (uchar*)(data), n)
 
 /* x11.c */
-Window *createwindow(Window *parent, Rectangle, int depth, uint class, WinAttr*, int valuemask);
-char *gettextproperty(Window*, char*);
 Point addpt(Point, Point);
 Image* allocimage(int w, int h, int depth);
 void border(Image *dst, Rectangle, int w, ulong col);
@@ -169,12 +172,13 @@ void changeprop_textlist(Window*, char*,
 void changeprop_textlist(Window*, char*, char*, char*[]);
 void changeproperty(Window*, char*, char*, int width, uchar*, int);
 void copyimage(Image*, Rectangle, Image*, Point);
+Window* createwindow(Window *parent, Rectangle, int depth, uint class, WinAttr*, int valuemask);
 void delproperty(Window*, char*);
 void destroywindow(Window*);
 Point divpt(Point, Point);
 void drawline(Image*, Point, Point, int cap, int w, ulong col);
 void drawpoly(Image*, Point*, int, int cap, int w, ulong col);
-void drawstring(Image*, Font*, Rectangle, Align, char*, ulong col);
+uint drawstring(Image*, Font*, Rectangle, Align, char*, ulong col);
 int eqpt(Point, Point);
 int eqrect(Rectangle, Rectangle);
 void fill(Image*, Rectangle, ulong col);
@@ -184,8 +188,9 @@ void freeimage(Image *);
 void freeimage(Image *);
 void freestringlist(char**);
 ulong getprop_long(Window*, char*, char*, ulong, long**, ulong);
+char* getprop_string(Window*, char*);
+int getprop_textlist(Window *w, char *name, char **ret[]);
 ulong getproperty(Window*, char *prop, char *type, Atom *actual, ulong offset, uchar **ret, ulong length);
-int gettextlistproperty(Window *w, char *name, char **ret[]);
 int grabpointer(Window*, Window *confine, Cursor, int mask);
 void initdisplay(void);
 KeyCode keycode(char*);
@@ -207,8 +212,8 @@ void sethints(Window*);
 void sethints(Window*);
 void setshapemask(Window *dst, Image *src, Point);
 void setwinattr(Window*, WinAttr*, int valmask);
+char** strlistdup(char**, int);
 Point subpt(Point, Point);
-char** strlistdup(char**, int);
 void sync(void);
 uint textwidth(Font*, char*);
 uint textwidth_l(Font*, char*, uint len);
@@ -217,13 +222,13 @@ int unmapwin(Window*);
 int unmapwin(Window*);
 void warppointer(Point);
 Window* window(XWindow);
-uint winprotocols(Window*);
+long winprotocols(Window*);
 Atom xatom(char*);
-Handlers* sethandler(Window*, Handlers*);
 XRectangle XRect(Rectangle);
 Rectangle gravitate(Rectangle dst, Rectangle src, Point grav);
 Rectangle insetrect(Rectangle, int);
 Rectangle rectaddpt(Rectangle, Point);
 Rectangle rectsubpt(Rectangle, Point);
+Handlers* sethandler(Window*, Handlers*);
 Rectangle sizehint(WinHints*, Rectangle);
 
diff -r b6315bae8a5d -r 17e5122b3d37 libfmt/fmtvprint.c
--- a/libfmt/fmtvprint.c Wed Jan 16 01:01:04 2008 -0500
+++ b/libfmt/fmtvprint.c Thu Jan 17 17:50:35 2008 -0500
@@ -24,7 +24,7 @@
  * but ignore any width flags
  */
 int
-fmtvprint(Fmt *f, const char *fmt, va_list args)
+fmtvprint(Fmt *f, const char *fmt, va_list args)
 {
         va_list va;
         int n;
diff -r b6315bae8a5d -r 17e5122b3d37 libwmii_hack/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libwmii_hack/Makefile Thu Jan 17 17:50:35 2008 -0500
@@ -0,0 +1,14 @@
+ROOT= ..
+include ${ROOT}/mk/hdr.mk
+
+hack.o hack.o_pic: util.c x11.c hack.h x11.h
+
+CFLAGS += $(INCX11)
+
+TARG = libwmii_hack
+OBJ = hack
+# util \
+# x11
+
+include ${ROOT}/mk/so.mk
+
diff -r b6315bae8a5d -r 17e5122b3d37 libwmii_hack/hack.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libwmii_hack/hack.c Thu Jan 17 17:50:35 2008 -0500
@@ -0,0 +1,132 @@
+/* Copyright ©2008 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * See LICENSE file for license details.
+ */
+#include "hack.h"
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "util.c"
+#include "x11.c"
+
+enum {
+ Timeout = 10000,
+};
+
+static void* xlib;
+
+static long transient;
+static Atom types[32];
+static long ntypes;
+static char* tags[32];
+static long ntags;
+static long pid;
+static char hostname[256];
+static long nmsec;
+
+typedef Window (*mapfn)(Display*, Window);
+
+static Window (*mapwindow)(Display*, Window);
+static Window (*mapraised)(Display*, Window);
+
+static long
+msec(void) {
+ struct timeval tv;
+
+ if(!gettimeofday(&tv, 0))
+ return 0;
+ return tv.tv_sec*1000 + tv.tv_usec/1000;
+}
+
+static void
+init(Display *d) { /* Hrm... assumes one display... */
+ char *toks[nelem(types)];
+ char *s, *p;
+ long n;
+ int i;
+
+ xlib = dlopen("libX11.so", RTLD_GLOBAL | RTLD_LAZY);
+ if(xlib == nil)
+ return;
+ mapwindow = (mapfn)(uintptr_t)dlsym(xlib, "XMapWindow");
+ mapraised = (mapfn)(uintptr_t)dlsym(xlib, "XMapRaised");
+
+ unsetenv("LD_PRELOAD");
+
+ if((s = getenv("WMII_HACK_TRANSIENT"))) {
+ if(getlong(s, &n))
+ transient = n;
+ unsetenv("WMII_HACK_TRANSIENT");
+ }
+ if((s = getenv("WMII_HACK_TYPE"))) {
+ s = strdup(s);
+ unsetenv("WMII_HACK_TYPE");
+
+ n = tokenize(toks, nelem(toks), s, ',');
+ for(i=0; i < n; i++) {
+ for(p=toks[i]; *p; p++)
+ if(*p >= 'a' && *p <= 'z')
+ *p += 'A' - 'a';
+ toks[i] = smprint("_NET_WM_WINDOW_TYPE_%s", toks[i]);
+ }
+ XInternAtoms(d, toks, n, False, types);
+ ntypes = n;
+ for(i=0; i < n; i++)
+ free(toks[i]);
+ free(s);
+ }
+ if((s = getenv("WMII_HACK_TAGS"))) {
+ s = strdup(s);
+ unsetenv("WMII_HACK_TAGS");
+
+ n = tokenize(toks, nelem(toks)-1, s, '+');
+ for(i=0; i < n; i++)
+ tags[i] = strdup(toks[i]);
+ ntags = n;
+ free(s);
+ }
+
+ pid = getpid();
+ gethostname(hostname, sizeof hostname);
+}
+
+static void
+setprops(Display *d, Window w) {
+
+ if(!xlib)
+ init(d);
+
+ changeprop_long(d, w, "_NET_WM_PID", "CARDINAL", &pid, 1);
+ changeprop_string(d, w, "_NET_WM_CLIENT_MACHINE", hostname);
+
+ /* Kludge. */
+ if(nmsec == 0)
+ nmsec = msec();
+ if(msec() > nmsec + Timeout)
+ return;
+
+ if(transient)
+ changeprop_long(d, w, "WM_TRANSIENT_FOR", "WINDOW", &transient, 1);
+ if(ntypes)
+ changeprop_long(d, w, "_NET_WM_WINDOW_TYPE", "ATOM", (long*)types, ntypes);
+ if(ntags)
+ changeprop_textlist(d, w, "_WMII_TAGS", "UTF8_STRING", tags);
+}
+
+int
+XMapWindow(Display *d, Window w) {
+
+ setprops(d, w);
+ return mapwindow(d, w);
+}
+
+int
+XMapRaised(Display *d, Window w) {
+
+ setprops(d, w);
+ return mapraised(d, w);
+}
+
diff -r b6315bae8a5d -r 17e5122b3d37 libwmii_hack/hack.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libwmii_hack/hack.h Thu Jan 17 17:50:35 2008 -0500
@@ -0,0 +1,28 @@
+
+typedef unsigned long ulong;
+typedef unsigned int uint;
+typedef unsigned char uchar;
+
+#define _XOPEN_SOURCE 600
+#define IXP_P9_STRUCTS
+#define IXP_NO_P9_
+#include <assert.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <x11.h>
+#include <X11/Xlib.h>
+
+#define strdup my_strdup
+
+static int getlong(const char*, long*);
+static uint tokenize(char*[], uint, char*, char);
+static char* smprint(const char*, ...);
+static char* vsmprint(const char*, va_list);
+static char* strdup(const char*);
+
+#define nil ((void*)0)
+#define nelem(ary) (sizeof(ary) / sizeof(*ary))
+
diff -r b6315bae8a5d -r 17e5122b3d37 libwmii_hack/util.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libwmii_hack/util.c Thu Jan 17 17:50:35 2008 -0500
@@ -0,0 +1,101 @@
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#define strbcmp(str, const) (strncmp((str), (const), sizeof(const)-1))
+static int
+getbase(const char **s) {
+ const char *p;
+
+ p = *s;
+ if(!strbcmp(p, "0x")) {
+ *s += 2;
+ return 16;
+ }
+ if(isdigit(p[0])) {
+ if(p[1] == 'r') {
+ *s += 2;
+ return p[0] - '0';
+ }
+ if(isdigit(p[1]) && p[2] == 'r') {
+ *s += 3;
+ return 10*(p[0]-'0') + (p[1]-'0');
+ }
+ }
+ if(p[0] == '0') {
+ *s += 1;
+ return 8;
+ }
+ return 10;
+}
+
+static int
+getlong(const char *s, long *ret) {
+ const char *end;
+ char *rend;
+ int base;
+
+ end = s+strlen(s);
+ base = getbase(&s);
+
+ *ret = strtol(s, &rend, base);
+ return (end == rend);
+}
+
+static uint
+tokenize(char *res[], uint reslen, char *str, char delim) {
+ char *s;
+ uint i;
+
+ i = 0;
+ s = str;
+ while(i < reslen && *s) {
+ while(*s == delim)
+ *(s++) = '\0';
+ if(*s)
+ res[i++] = s;
+ while(*s && *s != delim)
+ s++;
+ }
+ return i;
+}
+
+static char*
+vsmprint(const char *fmt, va_list ap) {
+ va_list al;
+ char *buf = "";
+ int n;
+
+ va_copy(al, ap);
+ n = vsnprintf(buf, 0, fmt, al);
+ va_end(al);
+
+ buf = malloc(++n);
+ if(buf)
+ vsnprintf(buf, n, fmt, ap);
+ return buf;
+}
+
+static char*
+smprint(const char *fmt, ...) {
+ va_list ap;
+ char *ret;
+
+ va_start(ap, fmt);
+ ret = vsmprint(fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+static char*
+strdup(const char *s) {
+ char *ret;
+ int len;
+
+ len = strlen(s)+1;
+ ret = malloc(len);
+ if(ret)
+ memcpy(ret, s, len);
+ return ret;
+}
+
diff -r b6315bae8a5d -r 17e5122b3d37 libwmii_hack/x11.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libwmii_hack/x11.c Thu Jan 17 17:50:35 2008 -0500
@@ -0,0 +1,193 @@
+/* Copyright ©2007 Kris Maglione <fbsdaemon_AT_gmail.com>
+ * See LICENSE file for license details.
+ */
+#include <assert.h>
+
+/* Misc */
+static Atom
+xatom(Display *display, char *name) {
+ /* Blech. I don't trust Xlib's cacheing.
+ MapEnt *e;
+
+ e = hash_get(&amap, name, 1);
+ if(e->val == nil)
+ e->val = (void*)XInternAtom(display, name, False);
+ return (Atom)e->val;
+ */
+ return XInternAtom(display, name, False);
+}
+/* Properties */
+#if 0
+static void
+delproperty(Display *display, Window w, char *prop) {
+ XDeleteProperty(display, w, xatom(display, prop));
+}
+#endif
+
+static void
+changeproperty(Display *display, Window w, char *prop, char *type, int width, uchar data[], int n) {
+ XChangeProperty(display, w, xatom(display, prop), xatom(display, type), width, PropModeReplace, data, n);
+}
+
+static void
+changeprop_string(Display *display, Window w, char *prop, char *string) {
+ changeprop_char(display, w, prop, "UTF8_STRING", string, strlen(string));
+}
+
+static void
+changeprop_char(Display *display, Window w, char *prop, char *type, char data[], int len) {
+ changeproperty(display, w, prop, type, 8, (uchar*)data, len);
+}
+
+#if 0
+static void
+changeprop_short(Display *display, Window w, char *prop, char *type, short data[], int len) {
+ changeproperty(display, w, prop, type, 16, (uchar*)data, len);
+}
+#endif
+
+static void
+changeprop_long(Display *display, Window w, char *prop, char *type, long data[], int len) {
+ changeproperty(display, w, prop, type, 32, (uchar*)data, len);
+}
+
+static void
+changeprop_textlist(Display *display, Window w, char *prop, char *type, char *data[]) {
+ char **p, *s, *t;
+ int len, n;
+
+ len = 0;
+ for(p=data; *p; p++)
+ len += strlen(*p) + 1;
+ s = malloc(len);
+ if(s == nil)
+ return;
+ t = s;
+ for(p=data; *p; p++) {
+ n = strlen(*p) + 1;
+ memcpy(t, *p, n);
+ t += n;
+ }
+ changeprop_char(display, w, prop, type, s, len);
+ free(s);
+}
+
+#if 0
+static void
+freestringlist(char *list[]) {
+ XFreeStringList(list);
+}
+#endif
+
+#if 0
+static ulong
+getprop(Display *display, Window w, char *prop, char *type, Atom *actual, int *format, ulong offset, uchar **ret, ulong length) {
+ Atom typea;
+ ulong n, extra;
+ int status;
+
+ typea = (type ? xatom(display, type) : 0L);
+
+ status = XGetWindowProperty(display, w,
+ xatom(display, prop), offset, length, False /* delete */,
+ typea, actual, format, &n, &extra, ret);
+
+ if(status != Success) {
+ *ret = nil;
+ return 0;
+ }
+ if(n == 0) {
+ free(*ret);
+ *ret = nil;
+ }
+ return n;
+}
+#endif
+
+#if 0
+static ulong
+getproperty(Display *display, Window w, char *prop, char *type, Atom *actual, ulong offset, uchar **ret, ulong length) {
+ int format;
+
+ return getprop(display, w, prop, type, actual, &format, offset, ret, length);
+}
+#endif
+
+#if 0
+static ulong
+getprop_long(Display *display, Window w, char *prop, char *type, ulong offset, long **ret, ulong length) {
+ Atom actual;
+ ulong n;
+ int format;
+
+ n = getprop(display, w, prop, type, &actual, &format, offset, (uchar**)ret, length);
+ if(n == 0 || format == 32 && xatom(display, type) == actual)
+ return n;
+ free(*ret);
+ *ret = 0;
+ return 0;
+}
+#endif
+
+#ifdef notdef
+static char**
+strlistdup(char *list[], int n) {
+ char **p, *q;
+ int i, m;
+
+ for(i=0, m=0; i < n; i++)
+ m += strlen(list[i])+1;
+
+ p = malloc((n+1)*sizeof(char*) + m);
+ if(p == nil)
+ return nil;
+ q = (char*)&p[n+1];
+
+ for(i=0; i < n; i++) {
+ p[i] = q;
+ m = strlen(list[i])+1;
+ memcpy(q, list[i], m);
+ q += m;
+ }
+ p[n] = nil;
+ return p;
+}
+#endif
+
+#if 0
+static int
+getprop_textlist(Display *display, Window w, char *name, char **ret[]) {
+ XTextProperty prop;
+ char **list;
+ int n;
+
+ *ret = nil;
+ n = 0;
+
+ XGetTextProperty(display, w, &prop, xatom(display, name));
+ if(prop.nitems > 0) {
+ if(Xutf8TextPropertyToTextList(display, &prop, &list, &n) == Success)
+ *ret = list;
+ XFree(prop.value);
+ }
+ return n;
+}
+#endif
+
+#if 0
+static char*
+getprop_string(Display *display, Window w, char *name) {
+ char **list, *str;
+ int n;
+
+ str = nil;
+
+ n = getprop_textlist(display, w, name, &list);
+ if(n > 0)
+ str = strdup(*list);
+ freestringlist(list);
+
+ return str;
+}
+#endif
+
diff -r b6315bae8a5d -r 17e5122b3d37 libwmii_hack/x11.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libwmii_hack/x11.h Thu Jan 17 17:50:35 2008 -0500
@@ -0,0 +1,18 @@
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+
+static void changeprop_char(Display*, Window, char*, char*, char[], int);
+static void changeprop_long(Display*, Window, char*, char*, long[], int);
+/* static void changeprop_short(Display*, Window, char*, char*, short[], int); */
+static void changeprop_string(Display*, Window, char*, char*);
+static void changeprop_textlist(Display*, Window, char*, char*, char*[]);
+static void changeproperty(Display*, Window, char*, char*, int width, uchar*, int);
+/* static void delproperty(Display*, Window, char*); */
+/* static void freestringlist(char**); */
+/* static ulong getprop_long(Display*, Window, char*, char*, ulong, long**, ulong); */
+/* static char* getprop_string(Display*, Window, char*); */
+/* static int getprop_textlist(Display*, Window, char*, char**[]); */
+/* static ulong getproperty(Display*, Window, char*, char*, Atom*, ulong, uchar**, ulong); */
+static Atom xatom(Display*, char*);
+
diff -r b6315bae8a5d -r 17e5122b3d37 man/Makefile
--- a/man/Makefile Wed Jan 16 01:01:04 2008 -0500
+++ b/man/Makefile Thu Jan 17 17:50:35 2008 -0500
@@ -11,3 +11,4 @@ FILTER = sed "s|CONFPREFIX|${ETC}|g; \
               s|AWKPATH|${AWKPATH}|g"
 
 include ${ROOT}/mk/man.mk
+
diff -r b6315bae8a5d -r 17e5122b3d37 mk/common.mk
--- a/mk/common.mk Wed Jan 16 01:01:04 2008 -0500
+++ b/mk/common.mk Thu Jan 17 17:50:35 2008 -0500
@@ -2,9 +2,9 @@ all:
 
 install: all
 
-MANDIRS=${MAN}/man1
+MANDIRS=$(MAN)/man1
 mkdirs:
- for i in ${BIN} ${ETC} ${LIBDIR} ${MANDIRS} ${INCLUDE} ${DIRS}; do \
+ for i in $(BIN) $(ETC) $(LIBDIR) $(MANDIRS) $(INCLUDE) $(DIRS); do \
                 test -d $$i || echo MKDIR $$i; \
                 mkdir -pm 0755 $$i; \
         done
@@ -15,6 +15,6 @@ cleandep:
 
 DEP:=${shell if test -f .depend;then echo .depend;else echo /dev/null; fi}
 DEP!=echo /dev/null
-include ${DEP}
+include $(DEP)
 
 .PHONY: all options clean dist install uninstall depend cleandep
diff -r b6315bae8a5d -r 17e5122b3d37 mk/dir.mk
--- a/mk/dir.mk Wed Jan 16 01:01:04 2008 -0500
+++ b/mk/dir.mk Thu Jan 17 17:50:35 2008 -0500
@@ -3,21 +3,21 @@ MKSUBDIR = targ=$@; \
                 if [ ! -d $$i ]; then \
                         echo Skipping nonexistent directory: $$i 1>&2; \
                 else \
- echo MAKE $${targ\#d} ${BASE}$$i/; \
- (cd $$i && ${MAKE} BASE="${BASE}$$i/" $${targ\#d}) || exit $?; \
+ echo MAKE $${targ\#d} $(BASE)$$i/; \
+ (cd $$i && $(MAKE) BASE="$(BASE)$$i/" $${targ\#d}) || exit $?; \
                 fi; \
         done
 
 dall:
- dirs="${DIRS}"; ${MKSUBDIR}
+ dirs="$(DIRS)"; $(MKSUBDIR)
 dclean:
- dirs="${DIRS}"; ${MKSUBDIR}
+ dirs="$(DIRS)"; $(MKSUBDIR)
 dinstall:
- dirs="${INSTDIRS}"; ${MKSUBDIR}
+ dirs="$(INSTDIRS)"; $(MKSUBDIR)
 duninstall:
- dirs="${INSTDIRS}"; ${MKSUBDIR}
+ dirs="$(INSTDIRS)"; $(MKSUBDIR)
 ddepend:
- dirs="${DIRS}"; ${MKSUBDIR}
+ dirs="$(DIRS)"; $(MKSUBDIR)
 
 all: dall
 clean: dclean
@@ -25,5 +25,5 @@ uninstall: duninstall
 uninstall: duninstall
 depend: ddepend
 
-INSTDIRS = ${DIRS}
+INSTDIRS = $(DIRS)
 
diff -r b6315bae8a5d -r 17e5122b3d37 mk/gcc.mk
--- a/mk/gcc.mk Wed Jan 16 01:01:04 2008 -0500
+++ b/mk/gcc.mk Thu Jan 17 17:50:35 2008 -0500
@@ -5,7 +5,8 @@ DEBUGCFLAGS = \
         -fno-inline \
         -fno-omit-frame-pointer \
         -fno-optimize-sibling-calls \
- -fno-unroll-loops
+ -fno-unroll-loops \
+ -DIXPlint
 CFLAGS += \
         -std=c99 \
         -pedantic \
@@ -22,3 +23,7 @@ CFLAGS += \
         -Wreturn-type \
         -Wstrict-prototypes \
         -Wtrigraphs
+MKDEP = cpp -M
+SOCFLAGS += -fPIC
+SOLDFLAGS += -shared -soname $(SONAME)
+
diff -r b6315bae8a5d -r 17e5122b3d37 mk/hdr.mk
--- a/mk/hdr.mk Wed Jan 16 01:01:04 2008 -0500
+++ b/mk/hdr.mk Thu Jan 17 17:50:35 2008 -0500
@@ -1,65 +1,69 @@
 .SILENT:
-.SUFFIXES: .O .o .c .sh .rc .awk .1 .depend .install .uninstall .clean
+.SUFFIXES: .O .o .o_pic .c .sh .rc .so .awk .1 .depend .install .uninstall .clean
 all:
 
 .c.depend:
         echo MKDEP $<
- ${MKDEP} ${CFLAGS} $< >>.depend
+ $(MKDEP) $(CFLAGS) $< >>.depend
 
 .sh.depend .rc.depend .1.depend .awk.depend:
         :
 
 .c.o:
- ${COMPILE} $@ $<
+ $(COMPILE) $@ $<
+
+.c.o_pic:
+ $(COMPILEPIC) $@ $<
 
 .o.O:
- ${LINK} $@ $<
+ $(LINK) $@ $<
 
 .c.O:
- ${COMPILE} $@ $<
- ${LINK} $@ $<
+ ${COMPILE} ${<:.c=.o} $<
+ ${LINK} $@ ${<:.c=.o}
+
 
 .rc.O .sh.O .awk.O:
- echo FILTER ${BASE}$<
- ${FILTER} $< >$@
+ echo FILTER $(BASE)$<
+ $(FILTER) $< >$@
         chmod 0755 $@
 
 .O.install:
- echo INSTALL ${BASE}$*
- cp -f $< ${BIN}/$*
- chmod 0755 ${BIN}/$*
+ echo INSTALL $$($(CLEANNAME) $(BASE)$*)
+ cp -f $< $(BIN)/$*
+ chmod 0755 $(BIN)/$*
 .O.uninstall:
- echo UNINSTALL ${BASE}$*
- rm -f ${BIN}/$*
+ echo UNINSTALL $$($(CLEANNAME) $(BASE)$*)
+ rm -f $(BIN)/$*
 
-.a.install:
- echo INSTALL ${BASE}$<
- cp -f $< ${LIBDIR}/$<
- chmod 0644 ${LIBDIR}/$<
-.a.uninstall:
- echo UNINSTALL ${BASE}$<
- rm -f ${LIBDIR}/$<
+.a.install .so.install:
+ echo INSTALL $$($(CLEANNAME) $(BASE)$<)
+ cp -f $< $(LIBDIR)/$<
+ chmod 0644 $(LIBDIR)/$<
+.a.uninstall .so.uninstall:
+ echo UNINSTALL $$($(CLEANNAME) $(BASE)$<)
+ rm -f $(LIBDIR)/$<
 
 .h.install:
- echo INSTALL ${BASE}$<
- cp -f $< ${INCLUDE}/$<
- chmod 0644 ${INCLUDE}/$<
+ echo INSTALL $$($(CLEANNAME) $(BASE)$<)
+ cp -f $< $(INCLUDE)/$<
+ chmod 0644 $(INCLUDE)/$<
 .h.uninstall:
- echo UNINSTALL ${BASE}$<
- rm -f ${INCLUDE}/$<
+ echo UNINSTALL $$($(CLEANNAME) $(BASE)$<)
+ rm -f $(INCLUDE)/$<
 
 .1.install:
- echo INSTALL man $*'(1)'
- ${FILTER} $< >${MAN}/man1/$<
- chmod 0644 ${MAN}/man1/$<
+ echo INSTALL man $$($(CLEANNAME) $*'(1)')
+ $(FILTER) $< >$(MAN)/man1/$<
+ chmod 0644 $(MAN)/man1/$<
 .1.uninstall:
- echo UNINSTALL man $*'(1)'
- rm -f ${MAN}/man1/$<
+ echo UNINSTALL man $$($(CLEANNAME) $*'(1)')
+ rm -f $(MAN)/man1/$<
 
 .O.clean:
         rm -f $< || true 2>/dev/null
         rm -f $*.o || true 2>/dev/null
-.o.clean:
+.o.clean .o_pic.clean:
         rm -f $< || true 2>/dev/null
 
 printinstall:
@@ -69,9 +73,13 @@ depend: cleandep
 depend: cleandep
 
 FILTER = cat
-COMPILE= CC="${CC}" CFLAGS="${CFLAGS}" ${ROOT}/util/compile
-LINK= LD="${LD}" LDFLAGS="${LDFLAGS}" ${ROOT}/util/link
+COMPILE= CC="$(CC)" CFLAGS="$(CFLAGS)" $(ROOT)/util/compile
+COMPILEPIC= CC="$(CC)" CFLAGS="$(CFLAGS) $(SOCFLAGS)" $(ROOT)/util/compile
+LINK= LD="$(LD)" LDFLAGS="$(LDFLAGS)" $(ROOT)/util/link
+LINKSO= LD="$(LD)" LDFLAGS="$(SOLDFLAGS)" $(ROOT)/util/link
+CLEANNAME=$(ROOT)/util/cleanname
 
-include ${ROOT}/config.mk
-CFLAGS += -I$$(echo ${INCPATH}|sed 's/:/ -I/g')
+include $(ROOT)/config.mk
+CFLAGS += -I$$(echo $(INCPATH)|sed 's/:/ -I/g')
+include $(ROOT)/mk/common.mk
 
diff -r b6315bae8a5d -r 17e5122b3d37 mk/lib.mk
--- a/mk/lib.mk Wed Jan 16 01:01:04 2008 -0500
+++ b/mk/lib.mk Thu Jan 17 17:50:35 2008 -0500
@@ -1,25 +1,30 @@ LIB = ${ROOT}/lib/${TARG}.a
-LIB = ${ROOT}/lib/${TARG}.a
+PTARG = $(ROOT)/lib/$(TARG)
+LIB = $(PTARG).a
 OFILES = ${OBJ:=.o}
 
-all: ${HFILES} ${LIB}
+all: $(HFILES) $(LIB)
 
-install: ${TARG}.install
-uninstall: ${TARG}.uninstall
+install: $(PTARG).install
+uninstall: $(PTARG).uninstall
 clean: libclean
 depend: ${OBJ:=.depend}
 
 libclean:
- for i in ${LIB} ${OFILES}; do \
+ for i in $(LIB) $(OFILES); do \
                 rm -f $$i; \
         done 2>/dev/null || true
 
 printinstall:
         echo 'Install directories:'
- echo ' Lib: ${LIBDIR}'
+ echo ' Lib: $(LIBDIR)'
 
-${LIB}: ${OFILES}
- echo AR $$($(ROOT)/util/cleanname $(BASE)/$@)
- mkdir ${ROOT}/lib 2>/dev/null || true
- ${AR} $@ ${OFILES}
+$(LIB): $(OFILES)
+ echo AR $$($(CLEANNAME) $(BASE)/$@)
+ mkdir $(ROOT)/lib 2>/dev/null || true
+ $(AR) $@ $(OFILES)
 
-include ${ROOT}/mk/common.mk
+SOMKSH=case "$(MAKESO)" in 1|[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) echo $(ROOT)/mk/so.mk;; *) echo /dev/null;; esac
+SOMK:=${shell $(SOMKSH)}
+SOMK!=$(SOMKSH)
+include $(SOMK)
+
diff -r b6315bae8a5d -r 17e5122b3d37 mk/man.mk
--- a/mk/man.mk Wed Jan 16 01:01:04 2008 -0500
+++ b/mk/man.mk Thu Jan 17 17:50:35 2008 -0500
@@ -3,6 +3,5 @@ uninstall: ${TARG:.1=.uninstall}
 
 printinstall:
         echo 'Install directories:'
- echo ' Man: ${MAN}'
+ echo ' Man: $(MAN)'
 
-include ${ROOT}/mk/common.mk
diff -r b6315bae8a5d -r 17e5122b3d37 mk/many.mk
--- a/mk/many.mk Wed Jan 16 01:01:04 2008 -0500
+++ b/mk/many.mk Thu Jan 17 17:50:35 2008 -0500
@@ -1,6 +1,6 @@ PROGS = ${TARG:=.O}
 PROGS = ${TARG:=.O}
 
-all: ${OFILES} ${PROGS}
+all: $(OFILES) $(PROGS)
 
 install: ${TARG:=.install}
 uninstall: ${TARG:=.uninstall}
@@ -9,12 +9,10 @@ clean: manyclean
 
 printinstall:
         echo 'Install directories:'
- echo ' Bin: ${BIN}'
+ echo ' Bin: $(BIN)'
 
 manyclean:
- for i in ${TARG:=.o} ${TARG:=.O} ${OFILES}; do \
+ for i in ${TARG:=.o} ${TARG:=.O} $(OFILES); do \
                 rm -f $$i; \
         done 2>/dev/null || true
 
-include ${ROOT}/mk/common.mk
-
diff -r b6315bae8a5d -r 17e5122b3d37 mk/one.mk
--- a/mk/one.mk Wed Jan 16 01:01:04 2008 -0500
+++ b/mk/one.mk Thu Jan 17 17:50:35 2008 -0500
@@ -1,25 +1,24 @@ PROG = ${TARG}.O
-PROG = ${TARG}.O
+PROG = $(TARG).O
 OFILES = ${OBJ:=.o}
 
-all: ${PROG}
+all: $(PROG)
 
-install: ${TARG}.install
-uninstall: ${TARG}.uninstall
+install: $(TARG).install
+uninstall: $(TARG).uninstall
 clean: oneclean
 depend: ${OBJ:=.depend}
 
 printinstall:
         echo 'Install directories:'
- echo ' Bin: ${BIN}'
+ echo ' Bin: $(BIN)'
 
 oneclean:
- for i in ${PROG} ${OFILES}; do \
+ for i in $(PROG) $(OFILES); do \
                 rm -f $$i; \
         done 2>/dev/null || true
 
-${OFILES}: ${HFILES}
+$(OFILES): $(HFILES)
 
-${PROG}: ${OFILES} ${LIB}
- ${LINK} $@ ${OFILES} ${LIB}
+$(PROG): $(OFILES) $(LIB)
+ $(LINK) $@ $(OFILES) $(LIB)
 
-include ${ROOT}/mk/common.mk
diff -r b6315bae8a5d -r 17e5122b3d37 mk/so.mk
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mk/so.mk Thu Jan 17 17:50:35 2008 -0500
@@ -0,0 +1,27 @@
+SOPTARG = $(ROOT)/lib/$(TARG)
+SO = $(PTARG).so
+SONAME = $(TARG).so
+OFILES_PIC = ${OBJ:=.o_pic}
+
+all: $(HFILES) $(SO)
+
+install: $(SOPTARG).install
+uninstall: $(SOPTARG).uninstall
+clean: soclean
+depend: ${OBJ:=.depend}
+
+soclean:
+ for i in $(SO) $(OFILES_PIC); do \
+ rm -f $$i; \
+ done 2>/dev/null || true
+
+printsoinstall:
+ echo 'Install directories:'
+ echo ' Lib: $(LIBDIR)'
+
+printinstall: printsoinstall
+
+$(SO): $(OFILES_PIC)
+ mkdir $(ROOT)/lib 2>/dev/null || true
+ $(LINKSO) $@ $(OFILES_PIC)
+
diff -r b6315bae8a5d -r 17e5122b3d37 rc/rc.wmii.rc
--- a/rc/rc.wmii.rc Wed Jan 16 01:01:04 2008 -0500
+++ b/rc/rc.wmii.rc Thu Jan 17 17:50:35 2008 -0500
@@ -59,8 +59,19 @@ fn Event-UrgentTag { shift; wmiir xwrite
 fn Event-UrgentTag { shift; wmiir xwrite /lbar/$"* '*'$"* }
 fn Event-NotUrgentTag { shift; wmiir xwrite /lbar/$"* $"* }
 
+fn Event-Unresponsive {
+ client = $1; shift
+ @{
+ msg = 'The following client is not responding. What would you like to do?'
+ resp = `{wihack -transient $client \
+ xmessage -nearmouse -buttons Kill,Wait -print \
+ $msg $nl '' `{wmiir read /client/sel/label}}
+ if(~ $resp Kill)
+ wmiir xwrite /client/$client/ctl slay
+ }&
+}
+
 fn Event-LeftBarClick { shift; wmiir xwrite /ctl view $* }
-
 fn Event-ClientMouseDown {
         client = $1; button = $2
         if(~ $button 3) {
@@ -156,7 +167,7 @@ key $MODKEY-Shift-c || fn $key { wmiir x
 key $MODKEY-Shift-c || fn $key { wmiir xwrite /client/sel/ctl kill }
 
 key $MODKEY-a || fn $key { Action `{wi_actions | wi_menu} & }
-key $MODKEY-p || fn $key { ifs=() { wi_runcmd `{wi_menu <$progs_file} & } }
+key $MODKEY-p || fn $key { ifs=() { wi_runcmd -t `{wi_menu <$progs_file} & } }
 key $MODKEY-Return || fn $key { wi_runcmd $WMII_TERM & }
 
 key $MODKEY-t || fn $key { wmiir xwrite /ctl view `{wi_tags | wi_menu} & }
diff -r b6315bae8a5d -r 17e5122b3d37 rc/sh.wmii
--- a/rc/sh.wmii Wed Jan 16 01:01:04 2008 -0500
+++ b/rc/sh.wmii Thu Jan 17 17:50:35 2008 -0500
@@ -174,7 +174,7 @@ Key $MODKEY-Control-t {
 Key $MODKEY-Control-t {
         if { ~ `{wc -l /keys} 0 1} {
                 initkeys
- grabmod $MODKEY >/ctl
+ echo grabmod $MODKEY >/ctl
         } {
                 echo $MODKEY-Control-t >/keys
                 echo grabmod Mod3 >/ctl
diff -r b6315bae8a5d -r 17e5122b3d37 util/genconfig
--- a/util/genconfig Wed Jan 16 01:01:04 2008 -0500
+++ b/util/genconfig Thu Jan 17 17:50:35 2008 -0500
@@ -100,14 +100,17 @@ INCPATH="$INCPATH:/usr/local/include:/op
 
 oifs="$IFS"
 IFS=:
-findinc INCX11 X11/Xlib.h $INCPATH /usr/X11R6/include /usr/x11/include /usr/x11/include /usr/X11/include \
+findinc INCX11 X11/Xlib.h $INCPATH \
+ /usr/X11R6/include /usr/x11/include /usr/x11/include /usr/X11/include \
         /usr/openwin/include /opt/x11/include /opt/X11/include
 findinc INCICONV iconv.h $INCPATH
 
-findlib LIBX11 X11 $libs /usr/X11R6/lib /usr/X11/lib /usr/openwin/lib /usr/x11/lib /opt/X11 /opt/x11 \
- /usr/local/lib /opt/local/lib
+findlib LIBX11 X11 $libs \
+ /usr/X11R6/lib /usr/X11/lib /usr/openwin/lib /usr/x11/lib \
+ /opt/X11 /opt/x11 /usr/local/lib /opt/local/lib
 findlib LIBICONV iconv $libs
-findlib LIBIXP ixp ${ROOT}/libixp $libs
+findlib LIBIXP ixp "$ROOT/lib" $libs
+[ -e "$ROOT/libixp" ] && LIBIXP="$ROOT/lib/libixp.a"
 LIBIXP=$(echo "$LIBIXP"|sed 's,^-L\([^ ]*\) -l\([^ ]*\)$,\1/lib\2.a,')
 IFS="$oifs"
 
@@ -115,6 +118,12 @@ echo Library paths...
 echo Library paths...
 prompt INCX11 Compiler flags to find X11 includes
 prompt LIBX11 Linker flags to link against libX11
+# Yuck...
+if nm -D `ldd /bin/sh | awk '$1 ~ /^libc\.so/ {print $3}'` |
+ awk '$2 == "T" && $3 == "iconv" {exit 0}; END {exit 1}'
+then
+ echo "Your system's libc appears to contain iconv"
+fi
 prompt LIBICONV Linker flags to link agains libiconv '(may be left blank if iconv is part of your system libc)'
 prompt INCICONV Compiler flags to find iconv.h
 prompt LIBIXP Path to libixp.a
diff -r b6315bae8a5d -r 17e5122b3d37 util/link
--- a/util/link Wed Jan 16 01:01:04 2008 -0500
+++ b/util/link Thu Jan 17 17:50:35 2008 -0500
@@ -9,7 +9,7 @@ for i
 for i
 do
         case "$i" in
- *.[ao])
+ *.[ao]|*.o_pic)
                 ofiles="$ofiles $i"
                 ;;
         *)
Received on Mon Jan 21 2008 - 00:31:04 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 15:59:03 UTC