commit fbacdbcf94ea04e914678fb7937c4c50ef02fd15
parent e4e85ed3a0c13b8944182c235229db82684a60d7
Author: Anselm R. Garbe <arg@suckless.org>
Date: Fri, 20 Oct 2006 10:07:55 +0200
renamed wm.h into wmii.h
Diffstat:
| Makefile | | | 6 | +++--- |
| area.c | | | 2 | +- |
| bar.c | | | 2 | +- |
| client.c | | | 2 | +- |
| column.c | | | 2 | +- |
| draw.c | | | 2 | +- |
| event.c | | | 2 | +- |
| frame.c | | | 2 | +- |
| fs.c | | | 2 | +- |
| geom.c | | | 2 | +- |
| key.c | | | 2 | +- |
| mouse.c | | | 2 | +- |
| rule.c | | | 2 | +- |
| view.c | | | 2 | +- |
| wm.c | | | 359 | ------------------------------------------------------------------------------- |
| wm.h | | | 383 | ------------------------------------------------------------------------------- |
| wmii.c | | | 359 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| wmii.h | | | 383 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
18 files changed, 758 insertions(+), 758 deletions(-)
diff --git a/Makefile b/Makefile
@@ -4,7 +4,7 @@
include config.mk
SRC = area.c bar.c client.c column.c draw.c event.c \
- frame.c fs.c geom.c key.c mouse.c rule.c view.c wm.c
+ frame.c fs.c geom.c key.c mouse.c rule.c view.c wmii.c
OBJ = ${SRC:.c=.o}
all: options wmiiwm
@@ -20,7 +20,7 @@ options:
@echo CC $<
@${CC} -c ${CFLAGS} $<
-${OBJ}: wm.h config.mk
+${OBJ}: wmii.h config.mk
wmiiwm: ${OBJ}
@echo LD $@
@@ -35,7 +35,7 @@ dist: clean
@echo creating dist tarball
@mkdir -p wmii-${VERSION}
@cp -R LICENSE Makefile README wmii config.mk rc \
- wmii.1 wmiiwm.1 wm.h ${SRC} wmii-${VERSION}
+ wmii.1 wmiiwm.1 wmii.h ${SRC} wmii-${VERSION}
@tar -cf wmii-${VERSION}.tar wmii-${VERSION}
@gzip wmii-${VERSION}.tar
@rm -rf wmii-${VERSION}
diff --git a/area.c b/area.c
@@ -1,7 +1,7 @@
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
diff --git a/bar.c b/bar.c
@@ -1,7 +1,7 @@
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <math.h>
#include <string.h>
#include <stdlib.h>
diff --git a/client.c b/client.c
@@ -1,7 +1,7 @@
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
diff --git a/column.c b/column.c
@@ -1,7 +1,7 @@
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <stdlib.h>
#include <string.h>
diff --git a/draw.c b/draw.c
@@ -1,7 +1,7 @@
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/event.c b/event.c
@@ -1,7 +1,7 @@
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
diff --git a/frame.c b/frame.c
@@ -1,7 +1,7 @@
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <stdlib.h>
#include <string.h>
diff --git a/fs.c b/fs.c
@@ -1,7 +1,7 @@
/* (C)opyright MMVI Kris Maglione <fbsdaemon at gmail dot com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
diff --git a/geom.c b/geom.c
@@ -1,7 +1,7 @@
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <math.h>
Bool
diff --git a/key.c b/key.c
@@ -1,7 +1,7 @@
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <string.h>
#include <stdlib.h>
#include <X11/Xlib.h>
diff --git a/mouse.c b/mouse.c
@@ -2,7 +2,7 @@
* (C)opyright MMVI Kris Maglione <fbsdaemon@gmail.com>
* See LICENSE file for license details.
*/
-#include "wm.h"
+#include "wmii.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
diff --git a/rule.c b/rule.c
@@ -6,7 +6,7 @@
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
-#include "wm.h"
+#include "wmii.h"
/* basic rule matching language /regex/ -> value
* regex might contain POSIX regex syntax defined in regex(3) */
diff --git a/view.c b/view.c
@@ -7,7 +7,7 @@
#include <stdio.h>
#include <string.h>
-#include "wm.h"
+#include "wmii.h"
static Bool
is_empty(View *v) {
diff --git a/wm.c b/wm.c
@@ -1,359 +0,0 @@
-/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-#include "wm.h"
-#include <errno.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <X11/cursorfont.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-#include <X11/Xproto.h>
-
-static int other_wm_running;
-static int (*x_error_handler) (Display *, XErrorEvent *);
-static char version[] = "wmiiwm - " VERSION ", (C)opyright MMIV-MMVI Anselm R. Garbe\n";
-
-static void
-usage() {
- fputs("usage: wmiiwm -a <address> [-r <wmiirc>] [-v]\n", stderr);
- exit(1);
-}
-
-static void
-scan_wins() {
- int i;
- unsigned int num;
- Window *wins;
- XWindowAttributes wa;
- Window d1, d2;
-
- if(XQueryTree(blz.dpy, blz.root, &d1, &d2, &wins, &num)) {
- for(i = 0; i < num; i++) {
- if(!XGetWindowAttributes(blz.dpy, wins[i], &wa))
- continue;
- if(wa.override_redirect || XGetTransientForHint(blz.dpy, wins[i], &d1))
- continue;
- if(wa.map_state == IsViewable)
- manage_client(create_client(wins[i], &wa));
- }
- }
- if(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(blz.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) {
- Atom *protocols;
- long res;
- int protos = 0;
- int i;
-
- res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L,
- ((unsigned char **) &protocols));
- if(res <= 0) {
- return protos;
- }
- for(i = 0; i < res; i++) {
- if(protocols[i] == wm_atom[WMDelete])
- protos |= WM_PROTOCOL_DELWIN;
- }
- free((char *) protocols);
- return protos;
-}
-
-
-static void
-init_atoms() {
- wm_atom[WMProtocols] = XInternAtom(blz.dpy, "WM_PROTOCOLS", False);
- wm_atom[WMDelete] = XInternAtom(blz.dpy, "WM_DELETE_WINDOW", False);
- net_atom[NetSupported] = XInternAtom(blz.dpy, "_NET_SUPPORTED", False);
- net_atom[NetWMName] = XInternAtom(blz.dpy, "_NET_WM_NAME", False);
- tags_atom = XInternAtom(blz.dpy, "_WIN_TAGS", False);
- XChangeProperty(blz.dpy, blz.root, net_atom[NetSupported], XA_ATOM, 32,
- PropModeReplace, (unsigned char *) net_atom, NetLast);
-}
-
-static void
-init_cursors() {
- cursor[CurNormal] = XCreateFontCursor(blz.dpy, XC_left_ptr);
- cursor[CurResize] = XCreateFontCursor(blz.dpy, XC_sizing);
- cursor[CurMove] = XCreateFontCursor(blz.dpy, XC_fleur);
- cursor[CurInput] = XCreateFontCursor(blz.dpy, XC_xterm);
-}
-
-static void
-init_screen(WMScreen *screen) {
- Window w;
- int ret;
- unsigned mask;
- XGCValues gcv;
-
- gcv.subwindow_mode = IncludeInferiors;
- gcv.function = GXxor;
- gcv.foreground = def.selcolor.bg;
- gcv.plane_mask = AllPlanes;
- gcv.graphics_exposures = False;
- xorgc = XCreateGC(blz.dpy, blz.root, GCForeground | GCGraphicsExposures |
- GCFunction | GCSubwindowMode | GCPlaneMask, &gcv);
- screen->rect.x = screen->rect.y = 0;
- screen->rect.width = DisplayWidth(blz.dpy, blz.screen);
- screen->rect.height = DisplayHeight(blz.dpy, blz.screen);
- def.snap = screen->rect.height / 63;
- sel_screen = XQueryPointer(blz.dpy, blz.root, &w, &w, &ret, &ret, &ret, &ret, &mask);
-}
-
-/*
- * There's no way to check accesses to destroyed windows, thus
- * those cases are ignored (especially on UnmapNotify's).
- * Other types of errors call Xlib's default error handler, which
- * calls exit().
- */
-int
-wmii_error_handler(Display *dpy, XErrorEvent *error) {
- if(error->error_code == BadWindow
- || (error->request_code == X_SetInputFocus
- && error->error_code == BadMatch)
- || (error->request_code == X_PolyText8
- && error->error_code == BadDrawable)
- || (error->request_code == X_PolyFillRectangle
- && error->error_code == BadDrawable)
- || (error->request_code == X_PolySegment
- && error->error_code == BadDrawable)
- || (error->request_code == X_ConfigureWindow
- && error->error_code == BadMatch)
- || (error->request_code == X_GrabKey
- && error->error_code == BadAccess))
- return 0;
- fprintf(stderr, "wmiiwm: fatal error: Xrequest code=%d, Xerror code=%d\n",
- error->request_code, error->error_code);
- return x_error_handler(blz.dpy, error); /* calls exit() */
-}
-
-/*
- * Startup Error handler to check if another window manager
- * is already running.
- */
-static int
-startup_error_handler(Display * dpy, XErrorEvent * error) {
- other_wm_running = 1;
- return -1;
-}
-
-static void
-cleanup() {
- Client *c;
-
- for(c=client; c; c=c->next)
- reparent_client(c, blz.root, c->sel->rect.x, c->sel->rect.y);
- XSetInputFocus(blz.dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
- XSync(blz.dpy, False);
-}
-
-int
-main(int argc, char *argv[]) {
- int i;
- char *address = NULL, *wmiirc = NULL, *namespace, *errstr;
- WMScreen *s;
- struct passwd *passwd;
- XSetWindowAttributes wa;
-
- /* command line args */
- for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
- switch (argv[i][1]) {
- case 'v':
- fprintf(stdout, "%s", version);
- exit(0);
- break;
- case 'a':
- if(i + 1 < argc)
- address = argv[++i];
- else
- usage();
- break;
- case 'r':
- if(i + 1 < argc)
- wmiirc = argv[++i];
- else
- usage();
- break;
- default:
- usage();
- break;
- }
- }
- starting = True;
- blz.dpy = XOpenDisplay(0);
- if(!blz.dpy)
- ixp_eprint("wmiiwm: cannot open dpy\n");
- blz.screen = DefaultScreen(blz.dpy);
- blz.root = RootWindow(blz.dpy, blz.screen);
- /* check if another WM is already running */
- other_wm_running = 0;
- XSetErrorHandler(startup_error_handler);
- /* this causes an error if some other WM is running */
- XSelectInput(blz.dpy, blz.root, SubstructureRedirectMask | EnterWindowMask);
- XSync(blz.dpy, False);
- if(other_wm_running)
- ixp_eprint("wmiiwm: another window manager is already running\n");
- if(!address)
- usage();
- /* Check namespace permissions */
- if(!strncmp(address, "unix!", 5)) {
- struct stat st;
- namespace = ixp_estrdup(&address[5]);
- for(i = strlen(namespace) - 1; i >= 0; i--)
- if(namespace[i] == '/') break;
- namespace[i+1] = '\0';
- if(stat(namespace, &st))
- ixp_eprint("wmiiwm: can't stat namespace directory \"%s\": %s\n",
- namespace, strerror(errno));
- if(getuid() != st.st_uid)
- ixp_eprint("wmiiwm: namespace directory \"%s\" exists, but is not owned by you",
- namespace);
- if(st.st_mode & 077)
- ixp_eprint("wmiiwm: namespace directory \"%s\" exists, "
- "but has group or world permissions",
- namespace);
- free(namespace);
- }
- XSetErrorHandler(0);
- x_error_handler = XSetErrorHandler(wmii_error_handler);
- errstr = NULL;
- i = ixp_create_sock(address, &errstr);
- if(i < 0)
- ixp_eprint("wmiiwm: fatal: %s\n", errstr);
-
- /* start wmiirc */
- if(wmiirc) {
- int name_len = strlen(wmiirc) + 6;
- char execstr[name_len];
- switch(fork()) {
- case 0:
- if(setsid() == -1)
- ixp_eprint("wmiim: can't setsid: %s\n", strerror(errno));
- close(i);
- close(ConnectionNumber(blz.dpy));
- snprintf(execstr, name_len, "exec %s", wmiirc);
- execl("/bin/sh", "sh", "-c", execstr, NULL);
- ixp_eprint("wmiiwm: can't exec \"%s\": %s\n", wmiirc, strerror(errno));
- case -1:
- perror("wmiiwm: cannot fork wmiirc");
- default:
- break;
- }
- }
-
- /* IXP server */
- ixp_server_open_conn(&srv, i, &p9srv, serve_9pcon, NULL);
- /* X server */
- ixp_server_open_conn(&srv, ConnectionNumber(blz.dpy), NULL, check_x_event, NULL);
- view = NULL;
- client = NULL;
- key = NULL;
- passwd = getpwuid(getuid());
- user = ixp_estrdup(passwd->pw_name);
- def.colrules.string = NULL;
- def.colrules.size = 0;
- def.tagrules.string = NULL;
- def.tagrules.size = 0;
- def.keys = NULL;
- def.keyssz = 0;
- def.font.fontstr = ixp_estrdup(BLITZ_FONT);
- def.border = 2;
- def.colmode = Coldefault;
- strncpy(def.selcolor.colstr, BLITZ_SELCOLORS, sizeof(def.selcolor.colstr));
- loadcolor(&blz, &def.selcolor);
- strncpy(def.normcolor.colstr, BLITZ_NORMCOLORS, sizeof(def.normcolor.colstr));
- loadcolor(&blz, &def.normcolor);
- strncpy(def.bcolor[0].colstr, BLITZ_B1COLORS, sizeof(def.bcolor[0].colstr));
- strncpy(def.bcolor[1].colstr, BLITZ_B2COLORS, sizeof(def.bcolor[1].colstr));
- strncpy(def.bcolor[2].colstr, BLITZ_B3COLORS, sizeof(def.bcolor[2].colstr));
- loadcolor(&blz, &def.bcolor[0]);
- loadcolor(&blz, &def.bcolor[1]);
- loadcolor(&blz, &def.bcolor[2]);
- strncpy(def.grabmod, "Mod1", sizeof(def.grabmod));
- def.mod = Mod1Mask;
- init_atoms();
- init_cursors();
- loadfont(&blz, &def.font);
- init_lock_keys();
- num_screens = 1;
- screens = ixp_emallocz(num_screens * sizeof(*screens));
- for(i = 0; i < num_screens; i++) {
- s = &screens[i];
- s->lbar = NULL;
- s->rbar = NULL;
- s->sel = NULL;
- init_screen(s);
- pmap = XCreatePixmap(blz.dpy, blz.root, s->rect.width, s->rect.height,
- DefaultDepth(blz.dpy, blz.screen));
- wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
- wa.cursor = cursor[CurNormal];
- XChangeWindowAttributes(blz.dpy, blz.root, CWEventMask | CWCursor, &wa);
- wa.override_redirect = 1;
- wa.background_pixmap = ParentRelative;
- wa.event_mask = ExposureMask | ButtonReleaseMask
- | SubstructureRedirectMask | SubstructureNotifyMask;
- s->brect = s->rect;
- s->brect.height = labelh(&def.font);
- s->brect.y = s->rect.height - s->brect.height;
- s->barwin = XCreateWindow(blz.dpy, RootWindow(blz.dpy, blz.screen),
- s->brect.x, s->brect.y,
- s->brect.width, s->brect.height, 0,
- DefaultDepth(blz.dpy, blz.screen),
- CopyFromParent, DefaultVisual(blz.dpy, blz.screen),
- CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
- XSync(blz.dpy, False);
- s->bbrush.blitz = &blz;
- s->bbrush.gc = XCreateGC(blz.dpy, s->barwin, 0, 0);
- s->bbrush.drawable = pmap;
- s->bbrush.rect = s->brect;
- s->bbrush.rect.x = 0;
- s->bbrush.rect.y = 0;
- s->bbrush.color = def.normcolor;
- s->bbrush.font = &def.font;
- s->bbrush.border = True;
- draw_bar(s);
- XMapRaised(blz.dpy, s->barwin);
- }
-
- screen = &screens[0];
- scan_wins();
- update_views();
- starting = False;
-
- /* main event loop */
- errstr = ixp_server_loop(&srv);
- if(errstr)
- fprintf(stderr, "wmii: fatal: %s\n", errstr);
- cleanup();
- XCloseDisplay(blz.dpy);
- ixp_server_close(&srv);
- return errstr ? 1 : 0;
-}
diff --git a/wm.h b/wm.h
@@ -1,383 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <stdio.h>
-#include <regex.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xlocale.h>
-
-#include <ixp.h>
-
-#define BLITZ_FONT "fixed"
-#define BLITZ_SELCOLORS "#ffffff #335577 #447799"
-#define BLITZ_NORMCOLORS "#222222 #eeeeee #666666"
-#define BLITZ_B1COLORS "#000000 #00ffff #000000"
-#define BLITZ_B2COLORS "#000000 #ff0000 #000000"
-#define BLITZ_B3COLORS "#000000 #00ff00 #000000"
-
-typedef struct Blitz Blitz;
-typedef enum BlitzAlign BlitzAlign;
-typedef struct BlitzColor BlitzColor;
-typedef struct BlitzFont BlitzFont;
-typedef struct BlitzBrush BlitzBrush;
-typedef struct BlitzInput BlitzInput;
-
-struct Blitz {
- Display *dpy;
- int screen;
- Window root;
-};
-
-enum BlitzAlign {
- NORTH = 0x01,
- EAST = 0x02,
- SOUTH = 0x04,
- WEST = 0x08,
- NEAST = NORTH | EAST,
- NWEST = NORTH | WEST,
- SEAST = SOUTH | EAST,
- SWEST = SOUTH | WEST,
- CENTER = NEAST | SWEST
-};
-
-struct BlitzColor {
- unsigned long bg;
- unsigned long fg;
- unsigned long border;
- char colstr[24]; /* #RRGGBB #RRGGBB #RRGGBB */
-};
-
-struct BlitzFont {
- XFontStruct *xfont;
- XFontSet set;
- int ascent;
- int descent;
- unsigned int height;
- char *fontstr;
-};
-
-struct BlitzBrush {
- Blitz *blitz;
- Drawable drawable;
- GC gc;
- Bool border;
- BlitzColor color;
- BlitzAlign align;
- BlitzFont *font;
- XRectangle rect; /* relative rect */
-};
-
-/* WM atoms */
-enum { WMProtocols, WMDelete, WMLast };
-
-/* NET atoms */
-enum { NetSupported, NetWMName, NetLast };
-
-/* Column modes */
-enum { Coldefault, Colstack, Colmax };
-
-/* Cursor */
-enum { CurNormal, CurResize, CurMove, CurInput, CurLast };
-
-enum { NCOL = 16 };
-enum { WM_PROTOCOL_DELWIN = 1 };
-
-/* Data Structures */
-typedef struct View View;
-typedef struct Area Area;
-typedef struct Frame Frame;
-typedef struct Client Client;
-typedef struct Key Key;
-typedef struct Bar Bar;
-typedef struct Rule Rule;
-typedef struct Ruleset Ruleset;
-typedef struct WMScreen WMScreen;
-
-struct View {
- View *next;
- char name[256];
- unsigned short id;
- Area *area;
- Area *sel;
- Area *revert;
-};
-
-struct Area {
- Area *next;
- Frame *frame;
- Frame *sel;
- View *view;
- Bool floating;
- unsigned short id;
- int mode;
- XRectangle rect;
-};
-
-struct Frame {
- Frame *cnext;
- Frame *anext;
- View *view;
- Area *area;
- unsigned short id;
- XRectangle rect;
- XRectangle revert;
- Client *client;
- Bool collapsed;
- BlitzBrush tile;
- BlitzBrush grabbox;
- BlitzBrush titlebar;
-};
-
-struct Client {
- Client *next;
- Area *revert;
- Frame *frame;
- Frame *sel;
- char name[256];
- char tags[256];
- char props[512];
- unsigned short id;
- unsigned int border;
- int proto;
- Bool floating;
- Bool fixedsize;
- Window win;
- Window trans;
- Window framewin;
- XRectangle rect;
- XSizeHints size;
- GC gc;
-};
-
-struct Key {
- Key *next;
- Key *lnext;
- Key *tnext;
- unsigned short id;
- char name[128];
- unsigned long mod;
- KeyCode key;
-};
-
-struct Bar {
- Bar *next;
- Bar *smaller;
- char buf[280];
- char text[256];
- char name[256];
- unsigned short id;
- BlitzBrush brush;
-};
-
-struct Rule {
- Rule *next;
- regex_t regex;
- char value[256];
-};
-
-struct Ruleset {
- Rule *rule;
- char *string;
- unsigned int size;
-};
-
-/* global variables */
-struct {
- BlitzColor selcolor;
- BlitzColor normcolor;
- BlitzColor bcolor[3];
- BlitzFont font;
- unsigned int border;
- unsigned int snap;
- char *keys;
- unsigned int keyssz;
- Ruleset tagrules;
- Ruleset colrules;
- char grabmod[5];
- unsigned long mod;
- int colmode;
-} def;
-
-struct WMScreen {
- Bar *lbar;
- Bar *rbar;
- View *sel;
- Window barwin;
-
- XRectangle rect;
- XRectangle brect;
- BlitzBrush bbrush;
-} *screens, *screen;
-
-Client *client;
-View *view;
-Key *key;
-
-enum { BUFFER_SIZE = 8092 };
-char buffer[BUFFER_SIZE];
-
-/* IXP */
-IXPServer srv;
-P9Srv p9srv;
-
-/* X11 */
-unsigned int num_screens;
-Blitz blz;
-GC xorgc;
-char *user;
-Atom wm_atom[WMLast];
-Atom net_atom[NetLast];
-Atom tags_atom;
-Cursor cursor[CurLast];
-unsigned int valid_mask;
-unsigned int num_lock_mask;
-Bool sel_screen;
-Pixmap pmap;
-void (*handler[LASTEvent]) (XEvent *);
-
-/* Misc */
-Bool starting;
-
-/* wm.c */
-extern char *message_root(char *message);
-
-/* area.c */
-extern Area *create_area(View *v, Area *pos, unsigned int w);
-extern void destroy_area(Area *a);
-extern Area *area_of_id(View *t, unsigned short id);
-extern char *select_area(Area *a, char *arg);
-extern void send_to_area(Area *to, Area *from, Frame *f);
-extern void attach_to_area(Area *a, Frame *f, Bool send);
-extern void detach_from_area(Area *a, Frame *f);
-extern Client *sel_client_of_area(Area *a);
-
-/* bar.c */
-extern Bar *create_bar(Bar **b_link, char *name);
-extern void destroy_bar(Bar **b_link, Bar *b);
-extern void draw_bar(WMScreen *s);
-extern void resize_bar();
-extern Bar *bar_of_name(Bar *b_link, const char *name);
-
-/* client.c */
-extern Client *create_client(Window w, XWindowAttributes *wa);
-extern void destroy_client(Client *c);
-extern void configure_client(Client *c);
-extern void prop_client(Client *c, XPropertyEvent *e);
-extern void kill_client(Client *c);
-extern void gravitate_client(Client *c, Bool invert);
-extern void unmap_client(Client *c);
-extern void map_client(Client *c);
-extern void reparent_client(Client *c, Window w, int x, int y);
-extern void manage_client(Client *c);
-extern void focus_client(Client *c, Bool restack);
-extern void focus(Client *c, Bool restack);
-extern void resize_client(Client *c, XRectangle *r, Bool ignore_xcall);
-extern void match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky);
-extern char *send_client(Frame *f, char *arg);
-extern char * message_client(Client *c, char *message);
-extern void move_client(Client *c, char *arg);
-extern void size_client(Client *c, char *arg);
-extern void newcol_client(Client *c, char *arg);
-extern Client *sel_client();
-extern Frame *frame_of_win(Window w);
-extern Client *client_of_win(Window w);
-extern int idx_of_client(Client *c);
-extern void update_client_grab(Client *c, Bool is_sel);
-extern void apply_rules(Client *c);
-extern void apply_tags(Client *c, const char *tags);
-
-/* column.c */
-extern void arrange_column(Area *a, Bool dirty);
-extern void scale_column(Area *a, float h);
-extern void resize_column(Client *c, XRectangle *r, XPoint *pt);
-extern int column_mode_of_str(char *arg);
-extern char *str_of_column_mode(int mode);
-extern Area *new_column(View *v, Area *pos, unsigned int w);
-
-/* draw.c */
-extern int loadcolor(Blitz *blitz, BlitzColor *c);
-extern void draw_label(BlitzBrush *b, char *text);
-extern void draw_tile(BlitzBrush *b);
-
-extern void drawbg(Display *dpy, Drawable drawable, GC gc,
- XRectangle rect, BlitzColor c, Bool border);
-extern void drawcursor(Display *dpy, Drawable drawable, GC gc,
- int x, int y, unsigned int h, BlitzColor c);
-extern unsigned int textwidth(BlitzFont *font, char *text);
-extern unsigned int textwidth_l(BlitzFont *font, char *text, unsigned int len);
-extern void loadfont(Blitz *blitz, BlitzFont *font);
-extern unsigned int labelh(BlitzFont *font);
-
-/* event.c */
-extern void check_x_event(IXPConn *c);
-extern unsigned int flush_masked_events(long even_mask);
-
-/* frame.c */
-extern Frame *create_frame(Client *c, View *v);
-extern void remove_frame(Frame *f);
-extern void insert_frame(Frame *pos, Frame *f, Bool before);
-extern void draw_frame(Frame *f);
-extern void draw_frames();
-extern void update_frame_widget_colors(Frame *f);
-
-/* fs.c */
-extern void fs_attach(P9Req *r);
-extern void fs_clunk(P9Req *r);
-extern void fs_create(P9Req *r);
-extern void fs_flush(P9Req *r);
-extern void fs_freefid(Fid *f);
-extern void fs_open(P9Req *r);
-extern void fs_read(P9Req *r);
-extern void fs_remove(P9Req *r);
-extern void fs_stat(P9Req *r);
-extern void fs_walk(P9Req *r);
-extern void fs_write(P9Req *r);
-extern void write_event(char *format, ...);
-
-/* geom.c */
-extern Bool ispointinrect(int x, int y, XRectangle * r);
-extern BlitzAlign quadofcoord(XRectangle *rect, int x, int y);
-extern int strtorect(XRectangle *r, const char *val);
-
-/* key.c */
-extern void kpress(Window w, unsigned long mod, KeyCode keycode);
-extern void update_keys();
-extern void init_lock_keys();
-extern unsigned long mod_key_of_str(char *val);
-
-/* mouse.c */
-extern void do_mouse_resize(Client *c,BlitzAlign align);
-extern void grab_mouse(Window w, unsigned long mod, unsigned int button);
-extern void ungrab_mouse(Window w, unsigned long mod, unsigned int button);
-extern BlitzAlign snap_rect(XRectangle *rects, int num, XRectangle *current,
- BlitzAlign *mask, int snap);
-
-/* rule.c */
-extern void update_rules(Rule **rule, const char *data);
-extern void trim(char *str, const char *chars);
-
-/* view.c */
-extern void arrange_view(View *v);
-extern void scale_view(View *v, float w);
-extern View *get_view(const char *name);
-extern View *create_view(const char *name);
-extern void focus_view(WMScreen *s, View *v);
-extern void update_client_views(Client *c, char **tags);
-extern XRectangle *rects_of_view(View *v, unsigned int *num);
-extern View *view_of_id(unsigned short id);
-extern void select_view(const char *arg);
-extern void attach_to_view(View *v, Frame *f);
-extern Client *sel_client_of_view(View *v);
-extern char *message_view(View *v, char *message);
-extern void restack_view(View *v);
-extern unsigned char *view_index(View *v);
-extern void destroy_view(View *v);
-extern void update_views();
-extern unsigned int newcolw_of_view(View *v);
-
-/* wm.c */
-extern int wmii_error_handler(Display *dpy, XErrorEvent *error);
-extern int win_proto(Window w);
diff --git a/wmii.c b/wmii.c
@@ -0,0 +1,359 @@
+/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
+ * See LICENSE file for license details.
+ */
+#include "wmii.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <X11/cursorfont.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include <X11/Xproto.h>
+
+static int other_wm_running;
+static int (*x_error_handler) (Display *, XErrorEvent *);
+static char version[] = "wmiiwm - " VERSION ", (C)opyright MMIV-MMVI Anselm R. Garbe\n";
+
+static void
+usage() {
+ fputs("usage: wmiiwm -a <address> [-r <wmiirc>] [-v]\n", stderr);
+ exit(1);
+}
+
+static void
+scan_wins() {
+ int i;
+ unsigned int num;
+ Window *wins;
+ XWindowAttributes wa;
+ Window d1, d2;
+
+ if(XQueryTree(blz.dpy, blz.root, &d1, &d2, &wins, &num)) {
+ for(i = 0; i < num; i++) {
+ if(!XGetWindowAttributes(blz.dpy, wins[i], &wa))
+ continue;
+ if(wa.override_redirect || XGetTransientForHint(blz.dpy, wins[i], &d1))
+ continue;
+ if(wa.map_state == IsViewable)
+ manage_client(create_client(wins[i], &wa));
+ }
+ }
+ if(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(blz.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) {
+ Atom *protocols;
+ long res;
+ int protos = 0;
+ int i;
+
+ res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L,
+ ((unsigned char **) &protocols));
+ if(res <= 0) {
+ return protos;
+ }
+ for(i = 0; i < res; i++) {
+ if(protocols[i] == wm_atom[WMDelete])
+ protos |= WM_PROTOCOL_DELWIN;
+ }
+ free((char *) protocols);
+ return protos;
+}
+
+
+static void
+init_atoms() {
+ wm_atom[WMProtocols] = XInternAtom(blz.dpy, "WM_PROTOCOLS", False);
+ wm_atom[WMDelete] = XInternAtom(blz.dpy, "WM_DELETE_WINDOW", False);
+ net_atom[NetSupported] = XInternAtom(blz.dpy, "_NET_SUPPORTED", False);
+ net_atom[NetWMName] = XInternAtom(blz.dpy, "_NET_WM_NAME", False);
+ tags_atom = XInternAtom(blz.dpy, "_WIN_TAGS", False);
+ XChangeProperty(blz.dpy, blz.root, net_atom[NetSupported], XA_ATOM, 32,
+ PropModeReplace, (unsigned char *) net_atom, NetLast);
+}
+
+static void
+init_cursors() {
+ cursor[CurNormal] = XCreateFontCursor(blz.dpy, XC_left_ptr);
+ cursor[CurResize] = XCreateFontCursor(blz.dpy, XC_sizing);
+ cursor[CurMove] = XCreateFontCursor(blz.dpy, XC_fleur);
+ cursor[CurInput] = XCreateFontCursor(blz.dpy, XC_xterm);
+}
+
+static void
+init_screen(WMScreen *screen) {
+ Window w;
+ int ret;
+ unsigned mask;
+ XGCValues gcv;
+
+ gcv.subwindow_mode = IncludeInferiors;
+ gcv.function = GXxor;
+ gcv.foreground = def.selcolor.bg;
+ gcv.plane_mask = AllPlanes;
+ gcv.graphics_exposures = False;
+ xorgc = XCreateGC(blz.dpy, blz.root, GCForeground | GCGraphicsExposures |
+ GCFunction | GCSubwindowMode | GCPlaneMask, &gcv);
+ screen->rect.x = screen->rect.y = 0;
+ screen->rect.width = DisplayWidth(blz.dpy, blz.screen);
+ screen->rect.height = DisplayHeight(blz.dpy, blz.screen);
+ def.snap = screen->rect.height / 63;
+ sel_screen = XQueryPointer(blz.dpy, blz.root, &w, &w, &ret, &ret, &ret, &ret, &mask);
+}
+
+/*
+ * There's no way to check accesses to destroyed windows, thus
+ * those cases are ignored (especially on UnmapNotify's).
+ * Other types of errors call Xlib's default error handler, which
+ * calls exit().
+ */
+int
+wmii_error_handler(Display *dpy, XErrorEvent *error) {
+ if(error->error_code == BadWindow
+ || (error->request_code == X_SetInputFocus
+ && error->error_code == BadMatch)
+ || (error->request_code == X_PolyText8
+ && error->error_code == BadDrawable)
+ || (error->request_code == X_PolyFillRectangle
+ && error->error_code == BadDrawable)
+ || (error->request_code == X_PolySegment
+ && error->error_code == BadDrawable)
+ || (error->request_code == X_ConfigureWindow
+ && error->error_code == BadMatch)
+ || (error->request_code == X_GrabKey
+ && error->error_code == BadAccess))
+ return 0;
+ fprintf(stderr, "wmiiwm: fatal error: Xrequest code=%d, Xerror code=%d\n",
+ error->request_code, error->error_code);
+ return x_error_handler(blz.dpy, error); /* calls exit() */
+}
+
+/*
+ * Startup Error handler to check if another window manager
+ * is already running.
+ */
+static int
+startup_error_handler(Display * dpy, XErrorEvent * error) {
+ other_wm_running = 1;
+ return -1;
+}
+
+static void
+cleanup() {
+ Client *c;
+
+ for(c=client; c; c=c->next)
+ reparent_client(c, blz.root, c->sel->rect.x, c->sel->rect.y);
+ XSetInputFocus(blz.dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
+ XSync(blz.dpy, False);
+}
+
+int
+main(int argc, char *argv[]) {
+ int i;
+ char *address = NULL, *wmiirc = NULL, *namespace, *errstr;
+ WMScreen *s;
+ struct passwd *passwd;
+ XSetWindowAttributes wa;
+
+ /* command line args */
+ for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
+ switch (argv[i][1]) {
+ case 'v':
+ fprintf(stdout, "%s", version);
+ exit(0);
+ break;
+ case 'a':
+ if(i + 1 < argc)
+ address = argv[++i];
+ else
+ usage();
+ break;
+ case 'r':
+ if(i + 1 < argc)
+ wmiirc = argv[++i];
+ else
+ usage();
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+ starting = True;
+ blz.dpy = XOpenDisplay(0);
+ if(!blz.dpy)
+ ixp_eprint("wmiiwm: cannot open dpy\n");
+ blz.screen = DefaultScreen(blz.dpy);
+ blz.root = RootWindow(blz.dpy, blz.screen);
+ /* check if another WM is already running */
+ other_wm_running = 0;
+ XSetErrorHandler(startup_error_handler);
+ /* this causes an error if some other WM is running */
+ XSelectInput(blz.dpy, blz.root, SubstructureRedirectMask | EnterWindowMask);
+ XSync(blz.dpy, False);
+ if(other_wm_running)
+ ixp_eprint("wmiiwm: another window manager is already running\n");
+ if(!address)
+ usage();
+ /* Check namespace permissions */
+ if(!strncmp(address, "unix!", 5)) {
+ struct stat st;
+ namespace = ixp_estrdup(&address[5]);
+ for(i = strlen(namespace) - 1; i >= 0; i--)
+ if(namespace[i] == '/') break;
+ namespace[i+1] = '\0';
+ if(stat(namespace, &st))
+ ixp_eprint("wmiiwm: can't stat namespace directory \"%s\": %s\n",
+ namespace, strerror(errno));
+ if(getuid() != st.st_uid)
+ ixp_eprint("wmiiwm: namespace directory \"%s\" exists, but is not owned by you",
+ namespace);
+ if(st.st_mode & 077)
+ ixp_eprint("wmiiwm: namespace directory \"%s\" exists, "
+ "but has group or world permissions",
+ namespace);
+ free(namespace);
+ }
+ XSetErrorHandler(0);
+ x_error_handler = XSetErrorHandler(wmii_error_handler);
+ errstr = NULL;
+ i = ixp_create_sock(address, &errstr);
+ if(i < 0)
+ ixp_eprint("wmiiwm: fatal: %s\n", errstr);
+
+ /* start wmiirc */
+ if(wmiirc) {
+ int name_len = strlen(wmiirc) + 6;
+ char execstr[name_len];
+ switch(fork()) {
+ case 0:
+ if(setsid() == -1)
+ ixp_eprint("wmiim: can't setsid: %s\n", strerror(errno));
+ close(i);
+ close(ConnectionNumber(blz.dpy));
+ snprintf(execstr, name_len, "exec %s", wmiirc);
+ execl("/bin/sh", "sh", "-c", execstr, NULL);
+ ixp_eprint("wmiiwm: can't exec \"%s\": %s\n", wmiirc, strerror(errno));
+ case -1:
+ perror("wmiiwm: cannot fork wmiirc");
+ default:
+ break;
+ }
+ }
+
+ /* IXP server */
+ ixp_server_open_conn(&srv, i, &p9srv, serve_9pcon, NULL);
+ /* X server */
+ ixp_server_open_conn(&srv, ConnectionNumber(blz.dpy), NULL, check_x_event, NULL);
+ view = NULL;
+ client = NULL;
+ key = NULL;
+ passwd = getpwuid(getuid());
+ user = ixp_estrdup(passwd->pw_name);
+ def.colrules.string = NULL;
+ def.colrules.size = 0;
+ def.tagrules.string = NULL;
+ def.tagrules.size = 0;
+ def.keys = NULL;
+ def.keyssz = 0;
+ def.font.fontstr = ixp_estrdup(BLITZ_FONT);
+ def.border = 2;
+ def.colmode = Coldefault;
+ strncpy(def.selcolor.colstr, BLITZ_SELCOLORS, sizeof(def.selcolor.colstr));
+ loadcolor(&blz, &def.selcolor);
+ strncpy(def.normcolor.colstr, BLITZ_NORMCOLORS, sizeof(def.normcolor.colstr));
+ loadcolor(&blz, &def.normcolor);
+ strncpy(def.bcolor[0].colstr, BLITZ_B1COLORS, sizeof(def.bcolor[0].colstr));
+ strncpy(def.bcolor[1].colstr, BLITZ_B2COLORS, sizeof(def.bcolor[1].colstr));
+ strncpy(def.bcolor[2].colstr, BLITZ_B3COLORS, sizeof(def.bcolor[2].colstr));
+ loadcolor(&blz, &def.bcolor[0]);
+ loadcolor(&blz, &def.bcolor[1]);
+ loadcolor(&blz, &def.bcolor[2]);
+ strncpy(def.grabmod, "Mod1", sizeof(def.grabmod));
+ def.mod = Mod1Mask;
+ init_atoms();
+ init_cursors();
+ loadfont(&blz, &def.font);
+ init_lock_keys();
+ num_screens = 1;
+ screens = ixp_emallocz(num_screens * sizeof(*screens));
+ for(i = 0; i < num_screens; i++) {
+ s = &screens[i];
+ s->lbar = NULL;
+ s->rbar = NULL;
+ s->sel = NULL;
+ init_screen(s);
+ pmap = XCreatePixmap(blz.dpy, blz.root, s->rect.width, s->rect.height,
+ DefaultDepth(blz.dpy, blz.screen));
+ wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
+ wa.cursor = cursor[CurNormal];
+ XChangeWindowAttributes(blz.dpy, blz.root, CWEventMask | CWCursor, &wa);
+ wa.override_redirect = 1;
+ wa.background_pixmap = ParentRelative;
+ wa.event_mask = ExposureMask | ButtonReleaseMask
+ | SubstructureRedirectMask | SubstructureNotifyMask;
+ s->brect = s->rect;
+ s->brect.height = labelh(&def.font);
+ s->brect.y = s->rect.height - s->brect.height;
+ s->barwin = XCreateWindow(blz.dpy, RootWindow(blz.dpy, blz.screen),
+ s->brect.x, s->brect.y,
+ s->brect.width, s->brect.height, 0,
+ DefaultDepth(blz.dpy, blz.screen),
+ CopyFromParent, DefaultVisual(blz.dpy, blz.screen),
+ CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
+ XSync(blz.dpy, False);
+ s->bbrush.blitz = &blz;
+ s->bbrush.gc = XCreateGC(blz.dpy, s->barwin, 0, 0);
+ s->bbrush.drawable = pmap;
+ s->bbrush.rect = s->brect;
+ s->bbrush.rect.x = 0;
+ s->bbrush.rect.y = 0;
+ s->bbrush.color = def.normcolor;
+ s->bbrush.font = &def.font;
+ s->bbrush.border = True;
+ draw_bar(s);
+ XMapRaised(blz.dpy, s->barwin);
+ }
+
+ screen = &screens[0];
+ scan_wins();
+ update_views();
+ starting = False;
+
+ /* main event loop */
+ errstr = ixp_server_loop(&srv);
+ if(errstr)
+ fprintf(stderr, "wmii: fatal: %s\n", errstr);
+ cleanup();
+ XCloseDisplay(blz.dpy);
+ ixp_server_close(&srv);
+ return errstr ? 1 : 0;
+}
diff --git a/wmii.h b/wmii.h
@@ -0,0 +1,383 @@
+/*
+ * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
+ * See LICENSE file for license details.
+ */
+
+#include <stdio.h>
+#include <regex.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xlocale.h>
+
+#include <ixp.h>
+
+#define BLITZ_FONT "fixed"
+#define BLITZ_SELCOLORS "#ffffff #335577 #447799"
+#define BLITZ_NORMCOLORS "#222222 #eeeeee #666666"
+#define BLITZ_B1COLORS "#000000 #00ffff #000000"
+#define BLITZ_B2COLORS "#000000 #ff0000 #000000"
+#define BLITZ_B3COLORS "#000000 #00ff00 #000000"
+
+typedef struct Blitz Blitz;
+typedef enum BlitzAlign BlitzAlign;
+typedef struct BlitzColor BlitzColor;
+typedef struct BlitzFont BlitzFont;
+typedef struct BlitzBrush BlitzBrush;
+typedef struct BlitzInput BlitzInput;
+
+struct Blitz {
+ Display *dpy;
+ int screen;
+ Window root;
+};
+
+enum BlitzAlign {
+ NORTH = 0x01,
+ EAST = 0x02,
+ SOUTH = 0x04,
+ WEST = 0x08,
+ NEAST = NORTH | EAST,
+ NWEST = NORTH | WEST,
+ SEAST = SOUTH | EAST,
+ SWEST = SOUTH | WEST,
+ CENTER = NEAST | SWEST
+};
+
+struct BlitzColor {
+ unsigned long bg;
+ unsigned long fg;
+ unsigned long border;
+ char colstr[24]; /* #RRGGBB #RRGGBB #RRGGBB */
+};
+
+struct BlitzFont {
+ XFontStruct *xfont;
+ XFontSet set;
+ int ascent;
+ int descent;
+ unsigned int height;
+ char *fontstr;
+};
+
+struct BlitzBrush {
+ Blitz *blitz;
+ Drawable drawable;
+ GC gc;
+ Bool border;
+ BlitzColor color;
+ BlitzAlign align;
+ BlitzFont *font;
+ XRectangle rect; /* relative rect */
+};
+
+/* WM atoms */
+enum { WMProtocols, WMDelete, WMLast };
+
+/* NET atoms */
+enum { NetSupported, NetWMName, NetLast };
+
+/* Column modes */
+enum { Coldefault, Colstack, Colmax };
+
+/* Cursor */
+enum { CurNormal, CurResize, CurMove, CurInput, CurLast };
+
+enum { NCOL = 16 };
+enum { WM_PROTOCOL_DELWIN = 1 };
+
+/* Data Structures */
+typedef struct View View;
+typedef struct Area Area;
+typedef struct Frame Frame;
+typedef struct Client Client;
+typedef struct Key Key;
+typedef struct Bar Bar;
+typedef struct Rule Rule;
+typedef struct Ruleset Ruleset;
+typedef struct WMScreen WMScreen;
+
+struct View {
+ View *next;
+ char name[256];
+ unsigned short id;
+ Area *area;
+ Area *sel;
+ Area *revert;
+};
+
+struct Area {
+ Area *next;
+ Frame *frame;
+ Frame *sel;
+ View *view;
+ Bool floating;
+ unsigned short id;
+ int mode;
+ XRectangle rect;
+};
+
+struct Frame {
+ Frame *cnext;
+ Frame *anext;
+ View *view;
+ Area *area;
+ unsigned short id;
+ XRectangle rect;
+ XRectangle revert;
+ Client *client;
+ Bool collapsed;
+ BlitzBrush tile;
+ BlitzBrush grabbox;
+ BlitzBrush titlebar;
+};
+
+struct Client {
+ Client *next;
+ Area *revert;
+ Frame *frame;
+ Frame *sel;
+ char name[256];
+ char tags[256];
+ char props[512];
+ unsigned short id;
+ unsigned int border;
+ int proto;
+ Bool floating;
+ Bool fixedsize;
+ Window win;
+ Window trans;
+ Window framewin;
+ XRectangle rect;
+ XSizeHints size;
+ GC gc;
+};
+
+struct Key {
+ Key *next;
+ Key *lnext;
+ Key *tnext;
+ unsigned short id;
+ char name[128];
+ unsigned long mod;
+ KeyCode key;
+};
+
+struct Bar {
+ Bar *next;
+ Bar *smaller;
+ char buf[280];
+ char text[256];
+ char name[256];
+ unsigned short id;
+ BlitzBrush brush;
+};
+
+struct Rule {
+ Rule *next;
+ regex_t regex;
+ char value[256];
+};
+
+struct Ruleset {
+ Rule *rule;
+ char *string;
+ unsigned int size;
+};
+
+/* global variables */
+struct {
+ BlitzColor selcolor;
+ BlitzColor normcolor;
+ BlitzColor bcolor[3];
+ BlitzFont font;
+ unsigned int border;
+ unsigned int snap;
+ char *keys;
+ unsigned int keyssz;
+ Ruleset tagrules;
+ Ruleset colrules;
+ char grabmod[5];
+ unsigned long mod;
+ int colmode;
+} def;
+
+struct WMScreen {
+ Bar *lbar;
+ Bar *rbar;
+ View *sel;
+ Window barwin;
+
+ XRectangle rect;
+ XRectangle brect;
+ BlitzBrush bbrush;
+} *screens, *screen;
+
+Client *client;
+View *view;
+Key *key;
+
+enum { BUFFER_SIZE = 8092 };
+char buffer[BUFFER_SIZE];
+
+/* IXP */
+IXPServer srv;
+P9Srv p9srv;
+
+/* X11 */
+unsigned int num_screens;
+Blitz blz;
+GC xorgc;
+char *user;
+Atom wm_atom[WMLast];
+Atom net_atom[NetLast];
+Atom tags_atom;
+Cursor cursor[CurLast];
+unsigned int valid_mask;
+unsigned int num_lock_mask;
+Bool sel_screen;
+Pixmap pmap;
+void (*handler[LASTEvent]) (XEvent *);
+
+/* Misc */
+Bool starting;
+
+/* wm.c */
+extern char *message_root(char *message);
+
+/* area.c */
+extern Area *create_area(View *v, Area *pos, unsigned int w);
+extern void destroy_area(Area *a);
+extern Area *area_of_id(View *t, unsigned short id);
+extern char *select_area(Area *a, char *arg);
+extern void send_to_area(Area *to, Area *from, Frame *f);
+extern void attach_to_area(Area *a, Frame *f, Bool send);
+extern void detach_from_area(Area *a, Frame *f);
+extern Client *sel_client_of_area(Area *a);
+
+/* bar.c */
+extern Bar *create_bar(Bar **b_link, char *name);
+extern void destroy_bar(Bar **b_link, Bar *b);
+extern void draw_bar(WMScreen *s);
+extern void resize_bar();
+extern Bar *bar_of_name(Bar *b_link, const char *name);
+
+/* client.c */
+extern Client *create_client(Window w, XWindowAttributes *wa);
+extern void destroy_client(Client *c);
+extern void configure_client(Client *c);
+extern void prop_client(Client *c, XPropertyEvent *e);
+extern void kill_client(Client *c);
+extern void gravitate_client(Client *c, Bool invert);
+extern void unmap_client(Client *c);
+extern void map_client(Client *c);
+extern void reparent_client(Client *c, Window w, int x, int y);
+extern void manage_client(Client *c);
+extern void focus_client(Client *c, Bool restack);
+extern void focus(Client *c, Bool restack);
+extern void resize_client(Client *c, XRectangle *r, Bool ignore_xcall);
+extern void match_sizehints(Client *c, XRectangle *r, Bool floating, BlitzAlign sticky);
+extern char *send_client(Frame *f, char *arg);
+extern char * message_client(Client *c, char *message);
+extern void move_client(Client *c, char *arg);
+extern void size_client(Client *c, char *arg);
+extern void newcol_client(Client *c, char *arg);
+extern Client *sel_client();
+extern Frame *frame_of_win(Window w);
+extern Client *client_of_win(Window w);
+extern int idx_of_client(Client *c);
+extern void update_client_grab(Client *c, Bool is_sel);
+extern void apply_rules(Client *c);
+extern void apply_tags(Client *c, const char *tags);
+
+/* column.c */
+extern void arrange_column(Area *a, Bool dirty);
+extern void scale_column(Area *a, float h);
+extern void resize_column(Client *c, XRectangle *r, XPoint *pt);
+extern int column_mode_of_str(char *arg);
+extern char *str_of_column_mode(int mode);
+extern Area *new_column(View *v, Area *pos, unsigned int w);
+
+/* draw.c */
+extern int loadcolor(Blitz *blitz, BlitzColor *c);
+extern void draw_label(BlitzBrush *b, char *text);
+extern void draw_tile(BlitzBrush *b);
+
+extern void drawbg(Display *dpy, Drawable drawable, GC gc,
+ XRectangle rect, BlitzColor c, Bool border);
+extern void drawcursor(Display *dpy, Drawable drawable, GC gc,
+ int x, int y, unsigned int h, BlitzColor c);
+extern unsigned int textwidth(BlitzFont *font, char *text);
+extern unsigned int textwidth_l(BlitzFont *font, char *text, unsigned int len);
+extern void loadfont(Blitz *blitz, BlitzFont *font);
+extern unsigned int labelh(BlitzFont *font);
+
+/* event.c */
+extern void check_x_event(IXPConn *c);
+extern unsigned int flush_masked_events(long even_mask);
+
+/* frame.c */
+extern Frame *create_frame(Client *c, View *v);
+extern void remove_frame(Frame *f);
+extern void insert_frame(Frame *pos, Frame *f, Bool before);
+extern void draw_frame(Frame *f);
+extern void draw_frames();
+extern void update_frame_widget_colors(Frame *f);
+
+/* fs.c */
+extern void fs_attach(P9Req *r);
+extern void fs_clunk(P9Req *r);
+extern void fs_create(P9Req *r);
+extern void fs_flush(P9Req *r);
+extern void fs_freefid(Fid *f);
+extern void fs_open(P9Req *r);
+extern void fs_read(P9Req *r);
+extern void fs_remove(P9Req *r);
+extern void fs_stat(P9Req *r);
+extern void fs_walk(P9Req *r);
+extern void fs_write(P9Req *r);
+extern void write_event(char *format, ...);
+
+/* geom.c */
+extern Bool ispointinrect(int x, int y, XRectangle * r);
+extern BlitzAlign quadofcoord(XRectangle *rect, int x, int y);
+extern int strtorect(XRectangle *r, const char *val);
+
+/* key.c */
+extern void kpress(Window w, unsigned long mod, KeyCode keycode);
+extern void update_keys();
+extern void init_lock_keys();
+extern unsigned long mod_key_of_str(char *val);
+
+/* mouse.c */
+extern void do_mouse_resize(Client *c,BlitzAlign align);
+extern void grab_mouse(Window w, unsigned long mod, unsigned int button);
+extern void ungrab_mouse(Window w, unsigned long mod, unsigned int button);
+extern BlitzAlign snap_rect(XRectangle *rects, int num, XRectangle *current,
+ BlitzAlign *mask, int snap);
+
+/* rule.c */
+extern void update_rules(Rule **rule, const char *data);
+extern void trim(char *str, const char *chars);
+
+/* view.c */
+extern void arrange_view(View *v);
+extern void scale_view(View *v, float w);
+extern View *get_view(const char *name);
+extern View *create_view(const char *name);
+extern void focus_view(WMScreen *s, View *v);
+extern void update_client_views(Client *c, char **tags);
+extern XRectangle *rects_of_view(View *v, unsigned int *num);
+extern View *view_of_id(unsigned short id);
+extern void select_view(const char *arg);
+extern void attach_to_view(View *v, Frame *f);
+extern Client *sel_client_of_view(View *v);
+extern char *message_view(View *v, char *message);
+extern void restack_view(View *v);
+extern unsigned char *view_index(View *v);
+extern void destroy_view(View *v);
+extern void update_views();
+extern unsigned int newcolw_of_view(View *v);
+
+/* wm.c */
+extern int wmii_error_handler(Display *dpy, XErrorEvent *error);
+extern int win_proto(Window w);