aewl

changeset 0:491f34c11291

initial import
author Anselm R. Garbe <garbeam@wmii.de>
date Mon, 10 Jul 2006 16:38:18 +0200
parents
children f10194d4b76d
files LICENSE Makefile README config.mk gridwm.1 wm.c wm.h
diffstat 7 files changed, 450 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/LICENSE	Mon Jul 10 16:38:18 2006 +0200
     1.3 @@ -0,0 +1,21 @@
     1.4 +MIT/X Consortium License
     1.5 +
     1.6 +(C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     1.7 +
     1.8 +Permission is hereby granted, free of charge, to any person obtaining a
     1.9 +copy of this software and associated documentation files (the "Software"),
    1.10 +to deal in the Software without restriction, including without limitation
    1.11 +the rights to use, copy, modify, merge, publish, distribute, sublicense,
    1.12 +and/or sell copies of the Software, and to permit persons to whom the 
    1.13 +Software is furnished to do so, subject to the following conditions:
    1.14 +
    1.15 +The above copyright notice and this permission notice shall be included in 
    1.16 +all copies or substantial portions of the Software. 
    1.17 +
    1.18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
    1.19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
    1.20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
    1.21 +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
    1.22 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
    1.23 +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
    1.24 +DEALINGS IN THE SOFTWARE.
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/Makefile	Mon Jul 10 16:38:18 2006 +0200
     2.3 @@ -0,0 +1,23 @@
     2.4 +# gridwm - grid window manager
     2.5 +#   (C)opyright MMVI Anselm R. Garbe
     2.6 +
     2.7 +include config.mk
     2.8 +
     2.9 +SRC      = wm.c
    2.10 +OBJ      = ${SRC:.c=.o}
    2.11 +
    2.12 +all: gridwm
    2.13 +	@echo finished
    2.14 +
    2.15 +.c.o:
    2.16 +	@echo CC $<
    2.17 +	@${CC} -c ${CFLAGS} $<
    2.18 +
    2.19 +${OBJ}: wm.h
    2.20 +
    2.21 +gridwm: ${OBJ}
    2.22 +	@echo LD $@
    2.23 +	@${CC} -o $@ ${OBJ} ${X11LDFLAGS}
    2.24 +
    2.25 +clean:
    2.26 +	rm -f gridwm *.o
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/README	Mon Jul 10 16:38:18 2006 +0200
     3.3 @@ -0,0 +1,40 @@
     3.4 +gridwm
     3.5 +------
     3.6 +
     3.7 +gridwm is an automatic X11 window manager which arranges all windows in a grid.
     3.8 +
     3.9 +
    3.10 +Requirements
    3.11 +------------
    3.12 +In order to build gridwm you need the Xlib header files.
    3.13 +
    3.14 +
    3.15 +Installation
    3.16 +------------
    3.17 +Edit config.mk to match your local setup. gridwm is installed into
    3.18 +the /usr/local namespace by default.
    3.19 +
    3.20 +Afterwards enter the following command to build and install gridwm (if
    3.21 +necessary as root):
    3.22 +
    3.23 +    make clean install
    3.24 +
    3.25 +
    3.26 +Running gridwm
    3.27 +--------------
    3.28 +Add the following line to your .xinitrc to start gridwm using startx:
    3.29 +
    3.30 +    exec gridwm
    3.31 +
    3.32 +In order to connect gridwm to a specific display, make sure that
    3.33 +the DISPLAY environment variable is set correctly, e.g.:
    3.34 +
    3.35 +    DISPLAY=foo.bar:1 exec wmii
    3.36 +
    3.37 +This will start gridwm on display :1 of the host foo.bar.
    3.38 +
    3.39 +
    3.40 +Configuration
    3.41 +-------------
    3.42 +The configuration of gridwm is done by customizing the config.h
    3.43 +source file.
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/config.mk	Mon Jul 10 16:38:18 2006 +0200
     4.3 @@ -0,0 +1,29 @@
     4.4 +# Customize to fit your system
     4.5 +
     4.6 +# paths
     4.7 +PREFIX = /usr/local
     4.8 +CONFPREFIX = ${PREFIX}/etc
     4.9 +MANPREFIX = ${PREFIX}/share/man
    4.10 +
    4.11 +X11INC = /usr/X11R6/include
    4.12 +X11LIB = /usr/X11R6/lib
    4.13 +
    4.14 +VERSION = 0.0
    4.15 +
    4.16 +# includes and libs
    4.17 +LIBS = -L${PREFIX}/lib -L/usr/lib -lc
    4.18 +X11LIBS = -L${X11LIB} -lX11
    4.19 +
    4.20 +# Linux/BSD
    4.21 +CFLAGS = -g -Wall -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \
    4.22 +	-DVERSION=\"${VERSION}\"
    4.23 +LDFLAGS = -g ${LIBS}
    4.24 +X11LDFLAGS = ${LDFLAGS} ${X11LIBS}
    4.25 +
    4.26 +# Solaris
    4.27 +#CFLAGS = -fast -xtarget=ultra ${INCLUDES} -DVERSION=\"${VERSION}\"
    4.28 +#LIBS += -lnsl -lsocket
    4.29 +
    4.30 +AR = ar cr
    4.31 +CC = cc
    4.32 +RANLIB = ranlib
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/gridwm.1	Mon Jul 10 16:38:18 2006 +0200
     5.3 @@ -0,0 +1,16 @@
     5.4 +.TH GRIDWM 1 gridwm-0.0
     5.5 +.SH NAME
     5.6 +gridwm \- grid window manager
     5.7 +.SH SYNOPSIS
     5.8 +.B gridwm
     5.9 +.RB [ \-v ]
    5.10 +.SH DESCRIPTION
    5.11 +.SS Overview
    5.12 +.B gridwm
    5.13 +is an automatic window manager for X11.
    5.14 +.SS Options
    5.15 +.TP
    5.16 +.B \-v
    5.17 +prints version information to stdout, then exits.
    5.18 +.SH SEE ALSO
    5.19 +.BR gridmenu (1)
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/wm.c	Mon Jul 10 16:38:18 2006 +0200
     6.3 @@ -0,0 +1,264 @@
     6.4 +/*
     6.5 + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     6.6 + * See LICENSE file for license details.
     6.7 + */
     6.8 +
     6.9 +#include <stdarg.h>
    6.10 +#include <stdio.h>
    6.11 +#include <stdlib.h>
    6.12 +
    6.13 +#include <X11/cursorfont.h>
    6.14 +#include <X11/Xatom.h>
    6.15 +#include <X11/Xproto.h>
    6.16 +
    6.17 +#include "wm.h"
    6.18 +
    6.19 +Display *dpy;
    6.20 +Window root;
    6.21 +XRectangle rect;
    6.22 +int screen, sel_screen;
    6.23 +Atom wm_atom[WMLast];
    6.24 +Atom net_atom[NetLast];
    6.25 +Cursor cursor[CurLast];
    6.26 +unsigned int kmask, numlock_mask;
    6.27 +Pixmap pmap;
    6.28 +
    6.29 +enum { WM_PROTOCOL_DELWIN = 1 };
    6.30 +
    6.31 +static Bool other_wm_running;
    6.32 +static int (*x_error_handler) (Display *, XErrorEvent *);
    6.33 +static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
    6.34 +
    6.35 +static void
    6.36 +usage()
    6.37 +{
    6.38 +	fputs("usage: gridwm [-v]\n", stderr);
    6.39 +	exit(1);
    6.40 +}
    6.41 +
    6.42 +void
    6.43 +error(char *errstr, ...) {
    6.44 +	va_list ap;
    6.45 +	va_start(ap, errstr);
    6.46 +	vfprintf(stderr, errstr, ap);
    6.47 +	va_end(ap);
    6.48 +	exit(1);
    6.49 +}
    6.50 +
    6.51 +static void
    6.52 +scan_wins()
    6.53 +{
    6.54 +	unsigned int i, num;
    6.55 +	Window *wins;
    6.56 +	XWindowAttributes wa;
    6.57 +	Window d1, d2;
    6.58 +
    6.59 +	if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
    6.60 +		for(i = 0; i < num; i++) {
    6.61 +			if(!XGetWindowAttributes(dpy, wins[i], &wa))
    6.62 +				continue;
    6.63 +			if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
    6.64 +				continue;
    6.65 +			if(wa.map_state == IsViewable)
    6.66 +				/*manage*/;
    6.67 +		}
    6.68 +	}
    6.69 +	if(wins)
    6.70 +		XFree(wins);
    6.71 +}
    6.72 +
    6.73 +static int
    6.74 +win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
    6.75 +{
    6.76 +	Atom real;
    6.77 +	int format;
    6.78 +	unsigned long res, extra;
    6.79 +	int status;
    6.80 +
    6.81 +	status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format,
    6.82 +			&res, &extra, prop);
    6.83 +
    6.84 +	if(status != Success || *prop == 0) {
    6.85 +		return 0;
    6.86 +	}
    6.87 +	if(res == 0) {
    6.88 +		free((void *) *prop);
    6.89 +	}
    6.90 +	return res;
    6.91 +}
    6.92 +
    6.93 +int
    6.94 +win_proto(Window w)
    6.95 +{
    6.96 +	Atom *protocols;
    6.97 +	long res;
    6.98 +	int protos = 0;
    6.99 +	int i;
   6.100 +
   6.101 +	res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L,
   6.102 +			((unsigned char **) &protocols));
   6.103 +	if(res <= 0) {
   6.104 +		return protos;
   6.105 +	}
   6.106 +	for(i = 0; i < res; i++) {
   6.107 +		if(protocols[i] == wm_atom[WMDelete])
   6.108 +			protos |= WM_PROTOCOL_DELWIN;
   6.109 +	}
   6.110 +	free((char *) protocols);
   6.111 +	return protos;
   6.112 +}
   6.113 +
   6.114 +/*
   6.115 + * There's no way to check accesses to destroyed windows, thus
   6.116 + * those cases are ignored (especially on UnmapNotify's).
   6.117 + * Other types of errors call Xlib's default error handler, which
   6.118 + * calls exit().
   6.119 + */
   6.120 +static int
   6.121 +error_handler(Display *dpy, XErrorEvent *error)
   6.122 +{
   6.123 +	if(error->error_code == BadWindow
   6.124 +			|| (error->request_code == X_SetInputFocus
   6.125 +				&& error->error_code == BadMatch)
   6.126 +			|| (error->request_code == X_PolyText8
   6.127 +				&& error->error_code == BadDrawable)
   6.128 +			|| (error->request_code == X_PolyFillRectangle
   6.129 +				&& error->error_code == BadDrawable)
   6.130 +			|| (error->request_code == X_PolySegment
   6.131 +				&& error->error_code == BadDrawable)
   6.132 +			|| (error->request_code == X_ConfigureWindow
   6.133 +				&& error->error_code == BadMatch)
   6.134 +			|| (error->request_code == X_GrabKey
   6.135 +				&& error->error_code == BadAccess))
   6.136 +		return 0;
   6.137 +	fprintf(stderr, "gridwm: fatal error: request code=%d, error code=%d\n",
   6.138 +			error->request_code, error->error_code);
   6.139 +	return x_error_handler(dpy, error); /* may call exit() */
   6.140 +}
   6.141 +
   6.142 +/*
   6.143 + * Startup Error handler to check if another window manager
   6.144 + * is already running.
   6.145 + */
   6.146 +static int
   6.147 +startup_error_handler(Display *dpy, XErrorEvent *error)
   6.148 +{
   6.149 +	other_wm_running = True;
   6.150 +	return -1;
   6.151 +}
   6.152 +
   6.153 +static void
   6.154 +init_lock_keys()
   6.155 +{
   6.156 +	XModifierKeymap *modmap;
   6.157 +	KeyCode numlock;
   6.158 +	int i;
   6.159 +	static int masks[] = {
   6.160 +		ShiftMask, LockMask, ControlMask, Mod1Mask,
   6.161 +		Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
   6.162 +	};
   6.163 +
   6.164 +	numlock_mask = 0;
   6.165 +	modmap = XGetModifierMapping(dpy);
   6.166 +	numlock = XKeysymToKeycode(dpy, XStringToKeysym("Num_Lock"));
   6.167 +
   6.168 +	if(modmap && modmap->max_keypermod > 0) {
   6.169 +		int max = (sizeof(masks) / sizeof(int)) * modmap->max_keypermod;
   6.170 +		for(i = 0; i < max; i++)
   6.171 +			if(numlock && (modmap->modifiermap[i] == numlock))
   6.172 +				numlock_mask = masks[i / modmap->max_keypermod];
   6.173 +	}
   6.174 +	XFreeModifiermap(modmap);
   6.175 +
   6.176 +	kmask = 255 & ~(numlock_mask | LockMask);
   6.177 +}
   6.178 +
   6.179 +static void
   6.180 +cleanup()
   6.181 +{
   6.182 +	/*
   6.183 +	Client *c;
   6.184 +	for(c=client; c; c=c->next)
   6.185 +		reparent_client(c, root, c->sel->rect.x, c->sel->rect.y);
   6.186 +	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
   6.187 +	*/
   6.188 +}
   6.189 +
   6.190 +int
   6.191 +main(int argc, char *argv[])
   6.192 +{
   6.193 +	int i;
   6.194 +	XSetWindowAttributes wa;
   6.195 +	unsigned int mask;
   6.196 +	Window w;
   6.197 +
   6.198 +	/* command line args */
   6.199 +	for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
   6.200 +		switch (argv[i][1]) {
   6.201 +		case 'v':
   6.202 +			fprintf(stdout, "%s", version);
   6.203 +			exit(0);
   6.204 +			break;
   6.205 +		default:
   6.206 +			usage();
   6.207 +			break;
   6.208 +		}
   6.209 +	}
   6.210 +
   6.211 +	dpy = XOpenDisplay(0);
   6.212 +	if(!dpy)
   6.213 +		error("gridwm: cannot connect X server\n");
   6.214 +
   6.215 +	screen = DefaultScreen(dpy);
   6.216 +	root = RootWindow(dpy, screen);
   6.217 +
   6.218 +	/* check if another WM is already running */
   6.219 +	other_wm_running = False;
   6.220 +	XSetErrorHandler(startup_error_handler);
   6.221 +	/* this causes an error if some other WM is running */
   6.222 +	XSelectInput(dpy, root, SubstructureRedirectMask);
   6.223 +	XSync(dpy, False);
   6.224 +
   6.225 +	if(other_wm_running)
   6.226 +		error("gridwm: another window manager is already running\n");
   6.227 +
   6.228 +	rect.x = rect.y = 0;
   6.229 +	rect.width = DisplayWidth(dpy, screen);
   6.230 +	rect.height = DisplayHeight(dpy, screen);
   6.231 +	sel_screen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
   6.232 +
   6.233 +	XSetErrorHandler(0);
   6.234 +	x_error_handler = XSetErrorHandler(error_handler);
   6.235 +
   6.236 +	/* init atoms */
   6.237 +	wm_atom[WMState] = XInternAtom(dpy, "WM_STATE", False);
   6.238 +	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
   6.239 +	wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
   6.240 +	net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
   6.241 +	net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
   6.242 +
   6.243 +	XChangeProperty(dpy, root, net_atom[NetSupported], XA_ATOM, 32,
   6.244 +			PropModeReplace, (unsigned char *) net_atom, NetLast);
   6.245 +
   6.246 +
   6.247 +	/* init cursors */
   6.248 +	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
   6.249 +	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
   6.250 +	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
   6.251 +
   6.252 +	init_lock_keys();
   6.253 +
   6.254 +	pmap = XCreatePixmap(dpy, root, rect.width, rect.height,
   6.255 +			DefaultDepth(dpy, screen));
   6.256 +
   6.257 +	wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
   6.258 +	wa.cursor = cursor[CurNormal];
   6.259 +	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
   6.260 +
   6.261 +	scan_wins();
   6.262 +
   6.263 +	cleanup();
   6.264 +	XCloseDisplay(dpy);
   6.265 +
   6.266 +	return 0;
   6.267 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/wm.h	Mon Jul 10 16:38:18 2006 +0200
     7.3 @@ -0,0 +1,57 @@
     7.4 +/*
     7.5 + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     7.6 + * See LICENSE file for license details.
     7.7 + */
     7.8 +
     7.9 +#include <X11/Xlib.h>
    7.10 +#include <X11/Xutil.h>
    7.11 +
    7.12 +/* WM atoms */
    7.13 +enum { WMState, WMProtocols, WMDelete, WMLast };
    7.14 +
    7.15 +/* NET atoms */
    7.16 +enum { NetSupported, NetWMName, NetLast };
    7.17 +
    7.18 +/* Cursor */
    7.19 +enum { CurNormal, CurResize, CurMove, CurInput, CurLast };
    7.20 +
    7.21 +/* Rects */
    7.22 +enum { RFloat, RGrid, RLast };
    7.23 +
    7.24 +typedef struct Client Client;
    7.25 +typedef struct Tag Tag;
    7.26 +
    7.27 +struct Client {
    7.28 +	Tag *tag;
    7.29 +	char name[256];
    7.30 +	int proto;
    7.31 +	Window win;
    7.32 +	Window trans;
    7.33 +	Window title;
    7.34 +	GC gc;
    7.35 +	XSizeHints size;
    7.36 +	XRectangle r[RLast];
    7.37 +	Client *next;
    7.38 +	Client *tnext;
    7.39 +	Client *tprev;
    7.40 +};
    7.41 +
    7.42 +struct Tag {
    7.43 +	char name[256];
    7.44 +	Client *clients;
    7.45 +	Client *sel;
    7.46 +	XRectangle r;
    7.47 +};
    7.48 +
    7.49 +extern Display *dpy;
    7.50 +extern Window root;
    7.51 +extern XRectangle rect;
    7.52 +extern int screen, sel_screen;
    7.53 +extern unsigned int kmask, numlock_mask;
    7.54 +extern Atom wm_atom[WMLast];
    7.55 +extern Atom net_atom[NetLast];
    7.56 +extern Cursor cursor[CurLast];
    7.57 +extern Pixmap pmap;
    7.58 +
    7.59 +/* wm.c */
    7.60 +extern void error(char *errstr, ...);