wmii

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

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