aewl

diff main.c @ 43:989178822938

changed default colors
author Anselm R. Garbe <garbeam@wmii.de>
date Thu, 13 Jul 2006 11:43:05 +0200
parents wm.c@cd30cce52b78
children 466591c2f967
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/main.c	Thu Jul 13 11:43:05 2006 +0200
     1.3 @@ -0,0 +1,274 @@
     1.4 +/*
     1.5 + * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
     1.6 + * See LICENSE file for license details.
     1.7 + */
     1.8 +
     1.9 +#include <stdarg.h>
    1.10 +#include <stdio.h>
    1.11 +#include <stdlib.h>
    1.12 +
    1.13 +#include <X11/cursorfont.h>
    1.14 +#include <X11/Xatom.h>
    1.15 +#include <X11/Xproto.h>
    1.16 +
    1.17 +#include "dwm.h"
    1.18 +
    1.19 +/********** CUSTOMIZE **********/
    1.20 +
    1.21 +char *tags[TLast] = {
    1.22 +	[Tscratch] = "scratch",
    1.23 +	[Tdev] = "dev",
    1.24 +	[Tirc] = "irc",
    1.25 +	[Twww] = "www",
    1.26 +	[Twork] = "work",
    1.27 +};
    1.28 +
    1.29 +/********** CUSTOMIZE **********/
    1.30 +
    1.31 +/* X structs */
    1.32 +Display *dpy;
    1.33 +Window root, barwin;
    1.34 +Atom wm_atom[WMLast], net_atom[NetLast];
    1.35 +Cursor cursor[CurLast];
    1.36 +Bool running = True;
    1.37 +Bool issel;
    1.38 +
    1.39 +char stext[1024];
    1.40 +int tsel = Tdev; /* default tag */
    1.41 +int screen, sx, sy, sw, sh, th;
    1.42 +
    1.43 +DC dc = {0};
    1.44 +Client *clients = NULL;
    1.45 +Client *stack = NULL;
    1.46 +
    1.47 +static Bool other_wm_running;
    1.48 +static const char version[] =
    1.49 +	"dwm - " VERSION ", (C)opyright MMVI Anselm R. Garbe\n";
    1.50 +static int (*x_error_handler) (Display *, XErrorEvent *);
    1.51 +
    1.52 +static void
    1.53 +usage() {	error("usage: dwm [-v]\n"); }
    1.54 +
    1.55 +static void
    1.56 +scan_wins()
    1.57 +{
    1.58 +	unsigned int i, num;
    1.59 +	Window *wins;
    1.60 +	XWindowAttributes wa;
    1.61 +	Window d1, d2;
    1.62 +
    1.63 +	if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
    1.64 +		for(i = 0; i < num; i++) {
    1.65 +			if(!XGetWindowAttributes(dpy, wins[i], &wa))
    1.66 +				continue;
    1.67 +			if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
    1.68 +				continue;
    1.69 +			if(wa.map_state == IsViewable)
    1.70 +				manage(wins[i], &wa);
    1.71 +		}
    1.72 +	}
    1.73 +	if(wins)
    1.74 +		XFree(wins);
    1.75 +}
    1.76 +
    1.77 +static int
    1.78 +win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
    1.79 +{
    1.80 +	Atom real;
    1.81 +	int format;
    1.82 +	unsigned long res, extra;
    1.83 +	int status;
    1.84 +
    1.85 +	status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format,
    1.86 +			&res, &extra, prop);
    1.87 +
    1.88 +	if(status != Success || *prop == 0) {
    1.89 +		return 0;
    1.90 +	}
    1.91 +	if(res == 0) {
    1.92 +		free((void *) *prop);
    1.93 +	}
    1.94 +	return res;
    1.95 +}
    1.96 +
    1.97 +int
    1.98 +win_proto(Window w)
    1.99 +{
   1.100 +	unsigned char *protocols;
   1.101 +	long res;
   1.102 +	int protos = 0;
   1.103 +	int i;
   1.104 +
   1.105 +	res = win_property(w, wm_atom[WMProtocols], XA_ATOM, 20L, &protocols);
   1.106 +	if(res <= 0) {
   1.107 +		return protos;
   1.108 +	}
   1.109 +	for(i = 0; i < res; i++) {
   1.110 +		if(protocols[i] == wm_atom[WMDelete])
   1.111 +			protos |= WM_PROTOCOL_DELWIN;
   1.112 +	}
   1.113 +	free((char *) protocols);
   1.114 +	return protos;
   1.115 +}
   1.116 +
   1.117 +void
   1.118 +send_message(Window w, Atom a, long value)
   1.119 +{
   1.120 +	XEvent e;
   1.121 +
   1.122 +	e.type = ClientMessage;
   1.123 +	e.xclient.window = w;
   1.124 +	e.xclient.message_type = a;
   1.125 +	e.xclient.format = 32;
   1.126 +	e.xclient.data.l[0] = value;
   1.127 +	e.xclient.data.l[1] = CurrentTime;
   1.128 +	XSendEvent(dpy, w, False, NoEventMask, &e);
   1.129 +	XFlush(dpy);
   1.130 +}
   1.131 +
   1.132 +/*
   1.133 + * There's no way to check accesses to destroyed windows, thus
   1.134 + * those cases are ignored (especially on UnmapNotify's).
   1.135 + * Other types of errors call Xlib's default error handler, which
   1.136 + * calls exit().
   1.137 + */
   1.138 +int
   1.139 +error_handler(Display *dpy, XErrorEvent *error)
   1.140 +{
   1.141 +	if(error->error_code == BadWindow
   1.142 +			|| (error->request_code == X_SetInputFocus
   1.143 +				&& error->error_code == BadMatch)
   1.144 +			|| (error->request_code == X_PolyText8
   1.145 +				&& error->error_code == BadDrawable)
   1.146 +			|| (error->request_code == X_PolyFillRectangle
   1.147 +				&& error->error_code == BadDrawable)
   1.148 +			|| (error->request_code == X_PolySegment
   1.149 +				&& error->error_code == BadDrawable)
   1.150 +			|| (error->request_code == X_ConfigureWindow
   1.151 +				&& error->error_code == BadMatch)
   1.152 +			|| (error->request_code == X_GrabKey
   1.153 +				&& error->error_code == BadAccess))
   1.154 +		return 0;
   1.155 +	fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
   1.156 +			error->request_code, error->error_code);
   1.157 +	return x_error_handler(dpy, error); /* may call exit() */
   1.158 +}
   1.159 +
   1.160 +/*
   1.161 + * Startup Error handler to check if another window manager
   1.162 + * is already running.
   1.163 + */
   1.164 +static int
   1.165 +startup_error_handler(Display *dpy, XErrorEvent *error)
   1.166 +{
   1.167 +	other_wm_running = True;
   1.168 +	return -1;
   1.169 +}
   1.170 +
   1.171 +static void
   1.172 +cleanup()
   1.173 +{
   1.174 +	while(clients)
   1.175 +		unmanage(clients);
   1.176 +	XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
   1.177 +}
   1.178 +
   1.179 +void
   1.180 +quit(void *aux)
   1.181 +{
   1.182 +	running = False;
   1.183 +}
   1.184 +
   1.185 +int
   1.186 +main(int argc, char *argv[])
   1.187 +{
   1.188 +	int i;
   1.189 +	XSetWindowAttributes wa;
   1.190 +	unsigned int mask;
   1.191 +	Window w;
   1.192 +	XEvent ev;
   1.193 +
   1.194 +	/* command line args */
   1.195 +	for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
   1.196 +		switch (argv[i][1]) {
   1.197 +		case 'v':
   1.198 +			fprintf(stdout, "%s", version);
   1.199 +			exit(0);
   1.200 +			break;
   1.201 +		default:
   1.202 +			usage();
   1.203 +			break;
   1.204 +		}
   1.205 +	}
   1.206 +
   1.207 +	dpy = XOpenDisplay(0);
   1.208 +	if(!dpy)
   1.209 +		error("dwm: cannot connect X server\n");
   1.210 +
   1.211 +	screen = DefaultScreen(dpy);
   1.212 +	root = RootWindow(dpy, screen);
   1.213 +
   1.214 +	/* check if another WM is already running */
   1.215 +	other_wm_running = False;
   1.216 +	XSetErrorHandler(startup_error_handler);
   1.217 +	/* this causes an error if some other WM is running */
   1.218 +	XSelectInput(dpy, root, SubstructureRedirectMask);
   1.219 +	XFlush(dpy);
   1.220 +
   1.221 +	if(other_wm_running)
   1.222 +		error("dwm: another window manager is already running\n");
   1.223 +
   1.224 +	sx = sy = 0;
   1.225 +	sw = DisplayWidth(dpy, screen);
   1.226 +	sh = DisplayHeight(dpy, screen);
   1.227 +	issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
   1.228 +
   1.229 +	XSetErrorHandler(0);
   1.230 +	x_error_handler = XSetErrorHandler(error_handler);
   1.231 +
   1.232 +	/* init atoms */
   1.233 +	wm_atom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
   1.234 +	wm_atom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
   1.235 +	net_atom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
   1.236 +	net_atom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
   1.237 +
   1.238 +	XChangeProperty(dpy, root, net_atom[NetSupported], XA_ATOM, 32,
   1.239 +			PropModeReplace, (unsigned char *) net_atom, NetLast);
   1.240 +
   1.241 +
   1.242 +	/* init cursors */
   1.243 +	cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
   1.244 +	cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
   1.245 +	cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
   1.246 +
   1.247 +	update_keys();
   1.248 +
   1.249 +	/* style */
   1.250 +	dc.bg = initcolor(BGCOLOR);
   1.251 +	dc.fg = initcolor(FGCOLOR);
   1.252 +	dc.border = initcolor(BORDERCOLOR);
   1.253 +	initfont(FONT);
   1.254 +
   1.255 +	th = dc.font.height + 4;
   1.256 +
   1.257 +	dc.drawable = XCreatePixmap(dpy, root, sw, th, DefaultDepth(dpy, screen));
   1.258 +	dc.gc = XCreateGC(dpy, root, 0, 0);
   1.259 +
   1.260 +	wa.event_mask = SubstructureRedirectMask | EnterWindowMask \
   1.261 +					| LeaveWindowMask;
   1.262 +	wa.cursor = cursor[CurNormal];
   1.263 +	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
   1.264 +
   1.265 +	scan_wins();
   1.266 +
   1.267 +	while(running) {
   1.268 +		XNextEvent(dpy, &ev);
   1.269 +		if(handler[ev.type])
   1.270 +			(handler[ev.type])(&ev); /* call handler */
   1.271 +	}
   1.272 +
   1.273 +	cleanup();
   1.274 +	XCloseDisplay(dpy);
   1.275 +
   1.276 +	return 0;
   1.277 +}