dwm-meillo
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 +}