initial import 1076f2b6
Anselm R. Garbe · 2006-07-10 16:38 7 file(s) · +450 −0
LICENSE (added) +21 −0
1 +
MIT/X Consortium License
2 +
3 +
(C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
4 +
5 +
Permission is hereby granted, free of charge, to any person obtaining a
6 +
copy of this software and associated documentation files (the "Software"),
7 +
to deal in the Software without restriction, including without limitation
8 +
the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 +
and/or sell copies of the Software, and to permit persons to whom the 
10 +
Software is furnished to do so, subject to the following conditions:
11 +
12 +
The above copyright notice and this permission notice shall be included in 
13 +
all copies or substantial portions of the Software. 
14 +
15 +
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
16 +
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
17 +
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
18 +
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
19 +
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
20 +
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
21 +
DEALINGS IN THE SOFTWARE.
Makefile (added) +23 −0
1 +
# gridwm - grid window manager
2 +
#   (C)opyright MMVI Anselm R. Garbe
3 +
4 +
include config.mk
5 +
6 +
SRC      = wm.c
7 +
OBJ      = ${SRC:.c=.o}
8 +
9 +
all: gridwm
10 +
	@echo finished
11 +
12 +
.c.o:
13 +
	@echo CC $<
14 +
	@${CC} -c ${CFLAGS} $<
15 +
16 +
${OBJ}: wm.h
17 +
18 +
gridwm: ${OBJ}
19 +
	@echo LD $@
20 +
	@${CC} -o $@ ${OBJ} ${X11LDFLAGS}
21 +
22 +
clean:
23 +
	rm -f gridwm *.o
README (added) +40 −0
1 +
gridwm
2 +
------
3 +
4 +
gridwm is an automatic X11 window manager which arranges all windows in a grid.
5 +
6 +
7 +
Requirements
8 +
------------
9 +
In order to build gridwm you need the Xlib header files.
10 +
11 +
12 +
Installation
13 +
------------
14 +
Edit config.mk to match your local setup. gridwm is installed into
15 +
the /usr/local namespace by default.
16 +
17 +
Afterwards enter the following command to build and install gridwm (if
18 +
necessary as root):
19 +
20 +
    make clean install
21 +
22 +
23 +
Running gridwm
24 +
--------------
25 +
Add the following line to your .xinitrc to start gridwm using startx:
26 +
27 +
    exec gridwm
28 +
29 +
In order to connect gridwm to a specific display, make sure that
30 +
the DISPLAY environment variable is set correctly, e.g.:
31 +
32 +
    DISPLAY=foo.bar:1 exec wmii
33 +
34 +
This will start gridwm on display :1 of the host foo.bar.
35 +
36 +
37 +
Configuration
38 +
-------------
39 +
The configuration of gridwm is done by customizing the config.h
40 +
source file.
config.mk (added) +29 −0
1 +
# Customize to fit your system
2 +
3 +
# paths
4 +
PREFIX = /usr/local
5 +
CONFPREFIX = ${PREFIX}/etc
6 +
MANPREFIX = ${PREFIX}/share/man
7 +
8 +
X11INC = /usr/X11R6/include
9 +
X11LIB = /usr/X11R6/lib
10 +
11 +
VERSION = 0.0
12 +
13 +
# includes and libs
14 +
LIBS = -L${PREFIX}/lib -L/usr/lib -lc
15 +
X11LIBS = -L${X11LIB} -lX11
16 +
17 +
# Linux/BSD
18 +
CFLAGS = -g -Wall -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \
19 +
	-DVERSION=\"${VERSION}\"
20 +
LDFLAGS = -g ${LIBS}
21 +
X11LDFLAGS = ${LDFLAGS} ${X11LIBS}
22 +
23 +
# Solaris
24 +
#CFLAGS = -fast -xtarget=ultra ${INCLUDES} -DVERSION=\"${VERSION}\"
25 +
#LIBS += -lnsl -lsocket
26 +
27 +
AR = ar cr
28 +
CC = cc
29 +
RANLIB = ranlib
gridwm.1 (added) +16 −0
1 +
.TH GRIDWM 1 gridwm-0.0
2 +
.SH NAME
3 +
gridwm \- grid window manager
4 +
.SH SYNOPSIS
5 +
.B gridwm
6 +
.RB [ \-v ]
7 +
.SH DESCRIPTION
8 +
.SS Overview
9 +
.B gridwm
10 +
is an automatic window manager for X11.
11 +
.SS Options
12 +
.TP
13 +
.B \-v
14 +
prints version information to stdout, then exits.
15 +
.SH SEE ALSO
16 +
.BR gridmenu (1)
wm.c (added) +264 −0
1 +
/*
2 +
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
3 +
 * See LICENSE file for license details.
4 +
 */
5 +
6 +
#include <stdarg.h>
7 +
#include <stdio.h>
8 +
#include <stdlib.h>
9 +
10 +
#include <X11/cursorfont.h>
11 +
#include <X11/Xatom.h>
12 +
#include <X11/Xproto.h>
13 +
14 +
#include "wm.h"
15 +
16 +
Display *dpy;
17 +
Window root;
18 +
XRectangle rect;
19 +
int screen, sel_screen;
20 +
Atom wm_atom[WMLast];
21 +
Atom net_atom[NetLast];
22 +
Cursor cursor[CurLast];
23 +
unsigned int kmask, numlock_mask;
24 +
Pixmap pmap;
25 +
26 +
enum { WM_PROTOCOL_DELWIN = 1 };
27 +
28 +
static Bool other_wm_running;
29 +
static int (*x_error_handler) (Display *, XErrorEvent *);
30 +
static char version[] = "gridwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
31 +
32 +
static void
33 +
usage()
34 +
{
35 +
	fputs("usage: gridwm [-v]\n", stderr);
36 +
	exit(1);
37 +
}
38 +
39 +
void
40 +
error(char *errstr, ...) {
41 +
	va_list ap;
42 +
	va_start(ap, errstr);
43 +
	vfprintf(stderr, errstr, ap);
44 +
	va_end(ap);
45 +
	exit(1);
46 +
}
47 +
48 +
static void
49 +
scan_wins()
50 +
{
51 +
	unsigned int i, num;
52 +
	Window *wins;
53 +
	XWindowAttributes wa;
54 +
	Window d1, d2;
55 +
56 +
	if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
57 +
		for(i = 0; i < num; i++) {
58 +
			if(!XGetWindowAttributes(dpy, wins[i], &wa))
59 +
				continue;
60 +
			if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
61 +
				continue;
62 +
			if(wa.map_state == IsViewable)
63 +
				/*manage*/;
64 +
		}
65 +
	}
66 +
	if(wins)
67 +
		XFree(wins);
68 +
}
69 +
70 +
static int
71 +
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
72 +
{
73 +
	Atom real;
74 +
	int format;
75 +
	unsigned long res, extra;
76 +
	int status;
77 +
78 +
	status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format,
79 +
			&res, &extra, prop);
80 +
81 +
	if(status != Success || *prop == 0) {
82 +
		return 0;
83 +
	}
84 +
	if(res == 0) {
85 +
		free((void *) *prop);
86 +
	}
87 +
	return res;
88 +
}
89 +
90 +
int
91 +
win_proto(Window w)
92 +
{
93 +
	Atom *protocols;
94 +
	long res;
95 +
	int protos = 0;
96 +
	int i;
97 +
98 +
	res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L,
99 +
			((unsigned char **) &protocols));
100 +
	if(res <= 0) {
101 +
		return protos;
102 +
	}
103 +
	for(i = 0; i < res; i++) {
104 +
		if(protocols[i] == wm_atom[WMDelete])
105 +
			protos |= WM_PROTOCOL_DELWIN;
106 +
	}
107 +
	free((char *) protocols);
108 +
	return protos;
109 +
}
110 +
111 +
/*
112 +
 * There's no way to check accesses to destroyed windows, thus
113 +
 * those cases are ignored (especially on UnmapNotify's).
114 +
 * Other types of errors call Xlib's default error handler, which
115 +
 * calls exit().
116 +
 */
117 +
static int
118 +
error_handler(Display *dpy, XErrorEvent *error)
119 +
{
120 +
	if(error->error_code == BadWindow
121 +
			|| (error->request_code == X_SetInputFocus
122 +
				&& error->error_code == BadMatch)
123 +
			|| (error->request_code == X_PolyText8
124 +
				&& error->error_code == BadDrawable)
125 +
			|| (error->request_code == X_PolyFillRectangle
126 +
				&& error->error_code == BadDrawable)
127 +
			|| (error->request_code == X_PolySegment
128 +
				&& error->error_code == BadDrawable)
129 +
			|| (error->request_code == X_ConfigureWindow
130 +
				&& error->error_code == BadMatch)
131 +
			|| (error->request_code == X_GrabKey
132 +
				&& error->error_code == BadAccess))
133 +
		return 0;
134 +
	fprintf(stderr, "gridwm: fatal error: request code=%d, error code=%d\n",
135 +
			error->request_code, error->error_code);
136 +
	return x_error_handler(dpy, error); /* may call exit() */
137 +
}
138 +
139 +
/*
140 +
 * Startup Error handler to check if another window manager
141 +
 * is already running.
142 +
 */
143 +
static int
144 +
startup_error_handler(Display *dpy, XErrorEvent *error)
145 +
{
146 +
	other_wm_running = True;
147 +
	return -1;
148 +
}
149 +
150 +
static void
151 +
init_lock_keys()
152 +
{
153 +
	XModifierKeymap *modmap;
154 +
	KeyCode numlock;
155 +
	int i;
156 +
	static int masks[] = {
157 +
		ShiftMask, LockMask, ControlMask, Mod1Mask,
158 +
		Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
159 +
	};
160 +
161 +
	numlock_mask = 0;
162 +
	modmap = XGetModifierMapping(dpy);
163 +
	numlock = XKeysymToKeycode(dpy, XStringToKeysym("Num_Lock"));
164 +
165 +
	if(modmap && modmap->max_keypermod > 0) {
166 +
		int max = (sizeof(masks) / sizeof(int)) * modmap->max_keypermod;
167 +
		for(i = 0; i < max; i++)
168 +
			if(numlock && (modmap->modifiermap[i] == numlock))
169 +
				numlock_mask = masks[i / modmap->max_keypermod];
170 +
	}
171 +
	XFreeModifiermap(modmap);
172 +
173 +
	kmask = 255 & ~(numlock_mask | LockMask);
174 +
}
175 +
176 +
static void
177 +
cleanup()
178 +
{
179 +
	/*
180 +
	Client *c;
181 +
	for(c=client; c; c=c->next)
182 +
		reparent_client(c, root, c->sel->rect.x, c->sel->rect.y);
183 +
	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
184 +
	*/
185 +
}
186 +
187 +
int
188 +
main(int argc, char *argv[])
189 +
{
190 +
	int i;
191 +
	XSetWindowAttributes wa;
192 +
	unsigned int mask;
193 +
	Window w;
194 +
195 +
	/* command line args */
196 +
	for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
197 +
		switch (argv[i][1]) {
198 +
		case 'v':
199 +
			fprintf(stdout, "%s", version);
200 +
			exit(0);
201 +
			break;
202 +
		default:
203 +
			usage();
204 +
			break;
205 +
		}
206 +
	}
207 +
208 +
	dpy = XOpenDisplay(0);
209 +
	if(!dpy)
210 +
		error("gridwm: cannot connect X server\n");
211 +
212 +
	screen = DefaultScreen(dpy);
213 +
	root = RootWindow(dpy, screen);
214 +
215 +
	/* check if another WM is already running */
216 +
	other_wm_running = False;
217 +
	XSetErrorHandler(startup_error_handler);
218 +
	/* this causes an error if some other WM is running */
219 +
	XSelectInput(dpy, root, SubstructureRedirectMask);
220 +
	XSync(dpy, False);
221 +
222 +
	if(other_wm_running)
223 +
		error("gridwm: another window manager is already running\n");
224 +
225 +
	rect.x = rect.y = 0;
226 +
	rect.width = DisplayWidth(dpy, screen);
227 +
	rect.height = DisplayHeight(dpy, screen);
228 +
	sel_screen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
229 +
230 +
	XSetErrorHandler(0);
231 +
	x_error_handler = XSetErrorHandler(error_handler);
232 +
233 +
	/* init atoms */
234 +
	wm_atom[WMState] = XInternAtom(dpy, "WM_STATE", False);
235 +
	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
236 +
	wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
237 +
	net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
238 +
	net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
239 +
240 +
	XChangeProperty(dpy, root, net_atom[NetSupported], XA_ATOM, 32,
241 +
			PropModeReplace, (unsigned char *) net_atom, NetLast);
242 +
243 +
244 +
	/* init cursors */
245 +
	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
246 +
	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
247 +
	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
248 +
249 +
	init_lock_keys();
250 +
251 +
	pmap = XCreatePixmap(dpy, root, rect.width, rect.height,
252 +
			DefaultDepth(dpy, screen));
253 +
254 +
	wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
255 +
	wa.cursor = cursor[CurNormal];
256 +
	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
257 +
258 +
	scan_wins();
259 +
260 +
	cleanup();
261 +
	XCloseDisplay(dpy);
262 +
263 +
	return 0;
264 +
}
wm.h (added) +57 −0
1 +
/*
2 +
 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
3 +
 * See LICENSE file for license details.
4 +
 */
5 +
6 +
#include <X11/Xlib.h>
7 +
#include <X11/Xutil.h>
8 +
9 +
/* WM atoms */
10 +
enum { WMState, WMProtocols, WMDelete, WMLast };
11 +
12 +
/* NET atoms */
13 +
enum { NetSupported, NetWMName, NetLast };
14 +
15 +
/* Cursor */
16 +
enum { CurNormal, CurResize, CurMove, CurInput, CurLast };
17 +
18 +
/* Rects */
19 +
enum { RFloat, RGrid, RLast };
20 +
21 +
typedef struct Client Client;
22 +
typedef struct Tag Tag;
23 +
24 +
struct Client {
25 +
	Tag *tag;
26 +
	char name[256];
27 +
	int proto;
28 +
	Window win;
29 +
	Window trans;
30 +
	Window title;
31 +
	GC gc;
32 +
	XSizeHints size;
33 +
	XRectangle r[RLast];
34 +
	Client *next;
35 +
	Client *tnext;
36 +
	Client *tprev;
37 +
};
38 +
39 +
struct Tag {
40 +
	char name[256];
41 +
	Client *clients;
42 +
	Client *sel;
43 +
	XRectangle r;
44 +
};
45 +
46 +
extern Display *dpy;
47 +
extern Window root;
48 +
extern XRectangle rect;
49 +
extern int screen, sel_screen;
50 +
extern unsigned int kmask, numlock_mask;
51 +
extern Atom wm_atom[WMLast];
52 +
extern Atom net_atom[NetLast];
53 +
extern Cursor cursor[CurLast];
54 +
extern Pixmap pmap;
55 +
56 +
/* wm.c */
57 +
extern void error(char *errstr, ...);