diff options
| author | Anselm R. Garbe <garbeam@wmii.de> | 2006-07-10 16:38:18 +0200 | 
|---|---|---|
| committer | Anselm R. Garbe <garbeam@wmii.de> | 2006-07-10 16:38:18 +0200 | 
| commit | 1076f2b6b3d3751d5d5db6fcb9ac8c247e04e893 (patch) | |
| tree | a00e708e8a396f1836b29671939e9921c682465e | |
| download | dwm-1076f2b6b3d3751d5d5db6fcb9ac8c247e04e893.tar.gz | |
initial import
| -rw-r--r-- | LICENSE | 21 | ||||
| -rw-r--r-- | Makefile | 23 | ||||
| -rw-r--r-- | README | 40 | ||||
| -rw-r--r-- | config.mk | 29 | ||||
| -rw-r--r-- | gridwm.1 | 16 | ||||
| -rw-r--r-- | wm.c | 264 | ||||
| -rw-r--r-- | wm.h | 57 | 
7 files changed, 450 insertions, 0 deletions
| @@ -0,0 +1,21 @@ +MIT/X Consortium License + +(C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the  +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in  +all copies or substantial portions of the Software.  + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL  +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING  +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER  +DEALINGS IN THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fff5ee1 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +# gridwm - grid window manager +#   (C)opyright MMVI Anselm R. Garbe + +include config.mk + +SRC      = wm.c +OBJ      = ${SRC:.c=.o} + +all: gridwm +	@echo finished + +.c.o: +	@echo CC $< +	@${CC} -c ${CFLAGS} $< + +${OBJ}: wm.h + +gridwm: ${OBJ} +	@echo LD $@ +	@${CC} -o $@ ${OBJ} ${X11LDFLAGS} + +clean: +	rm -f gridwm *.o @@ -0,0 +1,40 @@ +gridwm +------ + +gridwm is an automatic X11 window manager which arranges all windows in a grid. + + +Requirements +------------ +In order to build gridwm you need the Xlib header files. + + +Installation +------------ +Edit config.mk to match your local setup. gridwm is installed into +the /usr/local namespace by default. + +Afterwards enter the following command to build and install gridwm (if +necessary as root): + +    make clean install + + +Running gridwm +-------------- +Add the following line to your .xinitrc to start gridwm using startx: + +    exec gridwm + +In order to connect gridwm to a specific display, make sure that +the DISPLAY environment variable is set correctly, e.g.: + +    DISPLAY=foo.bar:1 exec wmii + +This will start gridwm on display :1 of the host foo.bar. + + +Configuration +------------- +The configuration of gridwm is done by customizing the config.h +source file. diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..8fc41d7 --- /dev/null +++ b/config.mk @@ -0,0 +1,29 @@ +# Customize to fit your system + +# paths +PREFIX = /usr/local +CONFPREFIX = ${PREFIX}/etc +MANPREFIX = ${PREFIX}/share/man + +X11INC = /usr/X11R6/include +X11LIB = /usr/X11R6/lib + +VERSION = 0.0 + +# includes and libs +LIBS = -L${PREFIX}/lib -L/usr/lib -lc +X11LIBS = -L${X11LIB} -lX11 + +# Linux/BSD +CFLAGS = -g -Wall -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \ +	-DVERSION=\"${VERSION}\" +LDFLAGS = -g ${LIBS} +X11LDFLAGS = ${LDFLAGS} ${X11LIBS} + +# Solaris +#CFLAGS = -fast -xtarget=ultra ${INCLUDES} -DVERSION=\"${VERSION}\" +#LIBS += -lnsl -lsocket + +AR = ar cr +CC = cc +RANLIB = ranlib diff --git a/gridwm.1 b/gridwm.1 new file mode 100644 index 0000000..02a6b6a --- /dev/null +++ b/gridwm.1 @@ -0,0 +1,16 @@ +.TH GRIDWM 1 gridwm-0.0 +.SH NAME +gridwm \- grid window manager +.SH SYNOPSIS +.B gridwm +.RB [ \-v ] +.SH DESCRIPTION +.SS Overview +.B gridwm +is an automatic window manager for X11. +.SS Options +.TP +.B \-v +prints version information to stdout, then exits. +.SH SEE ALSO +.BR gridmenu (1) @@ -0,0 +1,264 @@ +/* + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +#include <X11/cursorfont.h> +#include <X11/Xatom.h> +#include <X11/Xproto.h> + +#include "wm.h" + +Display *dpy; +Window root; +XRectangle rect; +int screen, sel_screen; +Atom wm_atom[WMLast]; +Atom net_atom[NetLast]; +Cursor cursor[CurLast]; +unsigned int kmask, numlock_mask; +Pixmap pmap; + +enum { WM_PROTOCOL_DELWIN = 1 }; + +static Bool other_wm_running; +static int (*x_error_handler) (Display *, XErrorEvent *); +static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; + +static void +usage() +{ +	fputs("usage: gridwm [-v]\n", stderr); +	exit(1); +} + +void +error(char *errstr, ...) { +	va_list ap; +	va_start(ap, errstr); +	vfprintf(stderr, errstr, ap); +	va_end(ap); +	exit(1); +} + +static void +scan_wins() +{ +	unsigned int i, num; +	Window *wins; +	XWindowAttributes wa; +	Window d1, d2; + +	if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { +		for(i = 0; i < num; i++) { +			if(!XGetWindowAttributes(dpy, wins[i], &wa)) +				continue; +			if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) +				continue; +			if(wa.map_state == IsViewable) +				/*manage*/; +		} +	} +	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(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; +} + +/* + * 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(). + */ +static int +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, "gridwm: fatal error: request code=%d, error code=%d\n", +			error->request_code, error->error_code); +	return x_error_handler(dpy, error); /* may call 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 = True; +	return -1; +} + +static void +init_lock_keys() +{ +	XModifierKeymap *modmap; +	KeyCode numlock; +	int i; +	static int masks[] = { +		ShiftMask, LockMask, ControlMask, Mod1Mask, +		Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask +	}; + +	numlock_mask = 0; +	modmap = XGetModifierMapping(dpy); +	numlock = XKeysymToKeycode(dpy, XStringToKeysym("Num_Lock")); + +	if(modmap && modmap->max_keypermod > 0) { +		int max = (sizeof(masks) / sizeof(int)) * modmap->max_keypermod; +		for(i = 0; i < max; i++) +			if(numlock && (modmap->modifiermap[i] == numlock)) +				numlock_mask = masks[i / modmap->max_keypermod]; +	} +	XFreeModifiermap(modmap); + +	kmask = 255 & ~(numlock_mask | LockMask); +} + +static void +cleanup() +{ +	/* +	Client *c; +	for(c=client; c; c=c->next) +		reparent_client(c, root, c->sel->rect.x, c->sel->rect.y); +	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); +	*/ +} + +int +main(int argc, char *argv[]) +{ +	int i; +	XSetWindowAttributes wa; +	unsigned int mask; +	Window w; + +	/* 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; +		default: +			usage(); +			break; +		} +	} + +	dpy = XOpenDisplay(0); +	if(!dpy) +		error("gridwm: cannot connect X server\n"); + +	screen = DefaultScreen(dpy); +	root = RootWindow(dpy, screen); + +	/* check if another WM is already running */ +	other_wm_running = False; +	XSetErrorHandler(startup_error_handler); +	/* this causes an error if some other WM is running */ +	XSelectInput(dpy, root, SubstructureRedirectMask); +	XSync(dpy, False); + +	if(other_wm_running) +		error("gridwm: another window manager is already running\n"); + +	rect.x = rect.y = 0; +	rect.width = DisplayWidth(dpy, screen); +	rect.height = DisplayHeight(dpy, screen); +	sel_screen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask); + +	XSetErrorHandler(0); +	x_error_handler = XSetErrorHandler(error_handler); + +	/* init atoms */ +	wm_atom[WMState] = XInternAtom(dpy, "WM_STATE", False); +	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); +	wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); +	net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); +	net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + +	XChangeProperty(dpy, root, net_atom[NetSupported], XA_ATOM, 32, +			PropModeReplace, (unsigned char *) net_atom, NetLast); + + +	/* init cursors */ +	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr); +	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing); +	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur); + +	init_lock_keys(); + +	pmap = XCreatePixmap(dpy, root, rect.width, rect.height, +			DefaultDepth(dpy, screen)); + +	wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask; +	wa.cursor = cursor[CurNormal]; +	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); + +	scan_wins(); + +	cleanup(); +	XCloseDisplay(dpy); + +	return 0; +} @@ -0,0 +1,57 @@ +/* + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> + * See LICENSE file for license details. + */ + +#include <X11/Xlib.h> +#include <X11/Xutil.h> + +/* WM atoms */ +enum { WMState, WMProtocols, WMDelete, WMLast }; + +/* NET atoms */ +enum { NetSupported, NetWMName, NetLast }; + +/* Cursor */ +enum { CurNormal, CurResize, CurMove, CurInput, CurLast }; + +/* Rects */ +enum { RFloat, RGrid, RLast }; + +typedef struct Client Client; +typedef struct Tag Tag; + +struct Client { +	Tag *tag; +	char name[256]; +	int proto; +	Window win; +	Window trans; +	Window title; +	GC gc; +	XSizeHints size; +	XRectangle r[RLast]; +	Client *next; +	Client *tnext; +	Client *tprev; +}; + +struct Tag { +	char name[256]; +	Client *clients; +	Client *sel; +	XRectangle r; +}; + +extern Display *dpy; +extern Window root; +extern XRectangle rect; +extern int screen, sel_screen; +extern unsigned int kmask, numlock_mask; +extern Atom wm_atom[WMLast]; +extern Atom net_atom[NetLast]; +extern Cursor cursor[CurLast]; +extern Pixmap pmap; + +/* wm.c */ +extern void error(char *errstr, ...); | 
