aewl
changeset 76:4bd49f404f10
proceeded with cleaning up, sorting functions, etc
author | Anselm R. Garbe <garbeam@wmii.de> |
---|---|
date | Sat, 15 Jul 2006 17:00:56 +0200 |
parents | f08271b7cb20 |
children | 38c8f7f7d401 |
files | client.c draw.c dwm.h event.c main.c tag.c util.c |
diffstat | 7 files changed, 541 insertions(+), 552 deletions(-) [+] |
line diff
1.1 --- a/client.c Sat Jul 15 16:30:50 2006 +0200 1.2 +++ b/client.c Sat Jul 15 17:00:56 2006 +0200 1.3 @@ -2,21 +2,14 @@ 1.4 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> 1.5 * See LICENSE file for license details. 1.6 */ 1.7 +#include "dwm.h" 1.8 1.9 #include <stdlib.h> 1.10 -#include <stdio.h> 1.11 #include <string.h> 1.12 #include <X11/Xatom.h> 1.13 #include <X11/Xutil.h> 1.14 1.15 -#include "dwm.h" 1.16 - 1.17 -void 1.18 -ban(Client *c) 1.19 -{ 1.20 - XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); 1.21 - XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); 1.22 -} 1.23 +/* static functions */ 1.24 1.25 static void 1.26 resizetitle(Client *c) 1.27 @@ -35,84 +28,19 @@ 1.28 XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th); 1.29 } 1.30 1.31 -void 1.32 -settitle(Client *c) 1.33 +static int 1.34 +xerrordummy(Display *dsply, XErrorEvent *ee) 1.35 { 1.36 - XTextProperty name; 1.37 - int n; 1.38 - char **list = NULL; 1.39 - 1.40 - name.nitems = 0; 1.41 - c->name[0] = 0; 1.42 - XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]); 1.43 - if(!name.nitems) 1.44 - XGetWMName(dpy, c->win, &name); 1.45 - if(!name.nitems) 1.46 - return; 1.47 - if(name.encoding == XA_STRING) 1.48 - strncpy(c->name, (char *)name.value, sizeof(c->name)); 1.49 - else { 1.50 - if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success 1.51 - && n > 0 && *list) 1.52 - { 1.53 - strncpy(c->name, *list, sizeof(c->name)); 1.54 - XFreeStringList(list); 1.55 - } 1.56 - } 1.57 - XFree(name.value); 1.58 - resizetitle(c); 1.59 + return 0; 1.60 } 1.61 1.62 -void 1.63 -setsize(Client *c) 1.64 -{ 1.65 - XSizeHints size; 1.66 - long msize; 1.67 - if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags) 1.68 - size.flags = PSize; 1.69 - c->flags = size.flags; 1.70 - if(c->flags & PBaseSize) { 1.71 - c->basew = size.base_width; 1.72 - c->baseh = size.base_height; 1.73 - } 1.74 - else 1.75 - c->basew = c->baseh = 0; 1.76 - if(c->flags & PResizeInc) { 1.77 - c->incw = size.width_inc; 1.78 - c->inch = size.height_inc; 1.79 - } 1.80 - else 1.81 - c->incw = c->inch = 0; 1.82 - if(c->flags & PMaxSize) { 1.83 - c->maxw = size.max_width; 1.84 - c->maxh = size.max_height; 1.85 - } 1.86 - else 1.87 - c->maxw = c->maxh = 0; 1.88 - if(c->flags & PMinSize) { 1.89 - c->minw = size.min_width; 1.90 - c->minh = size.min_height; 1.91 - } 1.92 - else 1.93 - c->minw = c->minh = 0; 1.94 - if(c->flags & PWinGravity) 1.95 - c->grav = size.win_gravity; 1.96 - else 1.97 - c->grav = NorthWestGravity; 1.98 -} 1.99 +/* extern functions */ 1.100 1.101 void 1.102 -higher(Client *c) 1.103 +ban(Client *c) 1.104 { 1.105 - XRaiseWindow(dpy, c->win); 1.106 - XRaiseWindow(dpy, c->title); 1.107 -} 1.108 - 1.109 -void 1.110 -lower(Client *c) 1.111 -{ 1.112 - XLowerWindow(dpy, c->title); 1.113 - XLowerWindow(dpy, c->win); 1.114 + XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); 1.115 + XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty); 1.116 } 1.117 1.118 void 1.119 @@ -132,6 +60,137 @@ 1.120 } 1.121 1.122 void 1.123 +focusnext(Arg *arg) 1.124 +{ 1.125 + Client *c; 1.126 + 1.127 + if(!sel) 1.128 + return; 1.129 + 1.130 + if(!(c = getnext(sel->next))) 1.131 + c = getnext(clients); 1.132 + if(c) { 1.133 + higher(c); 1.134 + c->revert = sel; 1.135 + focus(c); 1.136 + } 1.137 +} 1.138 + 1.139 +void 1.140 +focusprev(Arg *arg) 1.141 +{ 1.142 + Client *c; 1.143 + 1.144 + if(!sel) 1.145 + return; 1.146 + 1.147 + if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { 1.148 + higher(c); 1.149 + focus(c); 1.150 + } 1.151 +} 1.152 + 1.153 +Client * 1.154 +getclient(Window w) 1.155 +{ 1.156 + Client *c; 1.157 + for(c = clients; c; c = c->next) 1.158 + if(c->win == w) 1.159 + return c; 1.160 + return NULL; 1.161 +} 1.162 + 1.163 +Client * 1.164 +getctitle(Window w) 1.165 +{ 1.166 + Client *c; 1.167 + for(c = clients; c; c = c->next) 1.168 + if(c->title == w) 1.169 + return c; 1.170 + return NULL; 1.171 +} 1.172 + 1.173 +void 1.174 +gravitate(Client *c, Bool invert) 1.175 +{ 1.176 + int dx = 0, dy = 0; 1.177 + 1.178 + switch(c->grav) { 1.179 + case StaticGravity: 1.180 + case NorthWestGravity: 1.181 + case NorthGravity: 1.182 + case NorthEastGravity: 1.183 + dy = c->border; 1.184 + break; 1.185 + case EastGravity: 1.186 + case CenterGravity: 1.187 + case WestGravity: 1.188 + dy = -(c->h / 2) + c->border; 1.189 + break; 1.190 + case SouthEastGravity: 1.191 + case SouthGravity: 1.192 + case SouthWestGravity: 1.193 + dy = -c->h; 1.194 + break; 1.195 + default: 1.196 + break; 1.197 + } 1.198 + 1.199 + switch (c->grav) { 1.200 + case StaticGravity: 1.201 + case NorthWestGravity: 1.202 + case WestGravity: 1.203 + case SouthWestGravity: 1.204 + dx = c->border; 1.205 + break; 1.206 + case NorthGravity: 1.207 + case CenterGravity: 1.208 + case SouthGravity: 1.209 + dx = -(c->w / 2) + c->border; 1.210 + break; 1.211 + case NorthEastGravity: 1.212 + case EastGravity: 1.213 + case SouthEastGravity: 1.214 + dx = -(c->w + c->border); 1.215 + break; 1.216 + default: 1.217 + break; 1.218 + } 1.219 + 1.220 + if(invert) { 1.221 + dx = -dx; 1.222 + dy = -dy; 1.223 + } 1.224 + c->x += dx; 1.225 + c->y += dy; 1.226 +} 1.227 + 1.228 +void 1.229 +higher(Client *c) 1.230 +{ 1.231 + XRaiseWindow(dpy, c->win); 1.232 + XRaiseWindow(dpy, c->title); 1.233 +} 1.234 + 1.235 +void 1.236 +killclient(Arg *arg) 1.237 +{ 1.238 + if(!sel) 1.239 + return; 1.240 + if(sel->proto & WM_PROTOCOL_DELWIN) 1.241 + sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); 1.242 + else 1.243 + XKillClient(dpy, sel->win); 1.244 +} 1.245 + 1.246 +void 1.247 +lower(Client *c) 1.248 +{ 1.249 + XLowerWindow(dpy, c->title); 1.250 + XLowerWindow(dpy, c->win); 1.251 +} 1.252 + 1.253 +void 1.254 manage(Window w, XWindowAttributes *wa) 1.255 { 1.256 Client *c, **l; 1.257 @@ -195,61 +254,18 @@ 1.258 } 1.259 1.260 void 1.261 -gravitate(Client *c, Bool invert) 1.262 +maximize(Arg *arg) 1.263 { 1.264 - int dx = 0, dy = 0; 1.265 - 1.266 - switch(c->grav) { 1.267 - case StaticGravity: 1.268 - case NorthWestGravity: 1.269 - case NorthGravity: 1.270 - case NorthEastGravity: 1.271 - dy = c->border; 1.272 - break; 1.273 - case EastGravity: 1.274 - case CenterGravity: 1.275 - case WestGravity: 1.276 - dy = -(c->h / 2) + c->border; 1.277 - break; 1.278 - case SouthEastGravity: 1.279 - case SouthGravity: 1.280 - case SouthWestGravity: 1.281 - dy = -c->h; 1.282 - break; 1.283 - default: 1.284 - break; 1.285 - } 1.286 - 1.287 - switch (c->grav) { 1.288 - case StaticGravity: 1.289 - case NorthWestGravity: 1.290 - case WestGravity: 1.291 - case SouthWestGravity: 1.292 - dx = c->border; 1.293 - break; 1.294 - case NorthGravity: 1.295 - case CenterGravity: 1.296 - case SouthGravity: 1.297 - dx = -(c->w / 2) + c->border; 1.298 - break; 1.299 - case NorthEastGravity: 1.300 - case EastGravity: 1.301 - case SouthEastGravity: 1.302 - dx = -(c->w + c->border); 1.303 - break; 1.304 - default: 1.305 - break; 1.306 - } 1.307 - 1.308 - if(invert) { 1.309 - dx = -dx; 1.310 - dy = -dy; 1.311 - } 1.312 - c->x += dx; 1.313 - c->y += dy; 1.314 + if(!sel) 1.315 + return; 1.316 + sel->x = sx; 1.317 + sel->y = sy + bh; 1.318 + sel->w = sw - 2 * sel->border; 1.319 + sel->h = sh - 2 * sel->border - bh; 1.320 + higher(sel); 1.321 + resize(sel, False); 1.322 } 1.323 1.324 - 1.325 void 1.326 resize(Client *c, Bool inc) 1.327 { 1.328 @@ -290,10 +306,70 @@ 1.329 XFlush(dpy); 1.330 } 1.331 1.332 -static int 1.333 -xerrordummy(Display *dsply, XErrorEvent *ee) 1.334 +void 1.335 +setsize(Client *c) 1.336 { 1.337 - return 0; 1.338 + XSizeHints size; 1.339 + long msize; 1.340 + if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags) 1.341 + size.flags = PSize; 1.342 + c->flags = size.flags; 1.343 + if(c->flags & PBaseSize) { 1.344 + c->basew = size.base_width; 1.345 + c->baseh = size.base_height; 1.346 + } 1.347 + else 1.348 + c->basew = c->baseh = 0; 1.349 + if(c->flags & PResizeInc) { 1.350 + c->incw = size.width_inc; 1.351 + c->inch = size.height_inc; 1.352 + } 1.353 + else 1.354 + c->incw = c->inch = 0; 1.355 + if(c->flags & PMaxSize) { 1.356 + c->maxw = size.max_width; 1.357 + c->maxh = size.max_height; 1.358 + } 1.359 + else 1.360 + c->maxw = c->maxh = 0; 1.361 + if(c->flags & PMinSize) { 1.362 + c->minw = size.min_width; 1.363 + c->minh = size.min_height; 1.364 + } 1.365 + else 1.366 + c->minw = c->minh = 0; 1.367 + if(c->flags & PWinGravity) 1.368 + c->grav = size.win_gravity; 1.369 + else 1.370 + c->grav = NorthWestGravity; 1.371 +} 1.372 + 1.373 +void 1.374 +settitle(Client *c) 1.375 +{ 1.376 + XTextProperty name; 1.377 + int n; 1.378 + char **list = NULL; 1.379 + 1.380 + name.nitems = 0; 1.381 + c->name[0] = 0; 1.382 + XGetTextProperty(dpy, c->win, &name, net_atom[NetWMName]); 1.383 + if(!name.nitems) 1.384 + XGetWMName(dpy, c->win, &name); 1.385 + if(!name.nitems) 1.386 + return; 1.387 + if(name.encoding == XA_STRING) 1.388 + strncpy(c->name, (char *)name.value, sizeof(c->name)); 1.389 + else { 1.390 + if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success 1.391 + && n > 0 && *list) 1.392 + { 1.393 + strncpy(c->name, *list, sizeof(c->name)); 1.394 + XFreeStringList(list); 1.395 + } 1.396 + } 1.397 + XFree(name.value); 1.398 + resizetitle(c); 1.399 } 1.400 1.401 void 1.402 @@ -325,26 +401,6 @@ 1.403 focus(sel); 1.404 } 1.405 1.406 -Client * 1.407 -getctitle(Window w) 1.408 -{ 1.409 - Client *c; 1.410 - for(c = clients; c; c = c->next) 1.411 - if(c->title == w) 1.412 - return c; 1.413 - return NULL; 1.414 -} 1.415 - 1.416 -Client * 1.417 -getclient(Window w) 1.418 -{ 1.419 - Client *c; 1.420 - for(c = clients; c; c = c->next) 1.421 - if(c->win == w) 1.422 - return c; 1.423 - return NULL; 1.424 -} 1.425 - 1.426 void 1.427 zoom(Arg *arg) 1.428 { 1.429 @@ -366,58 +422,3 @@ 1.430 arrange(NULL); 1.431 focus(sel); 1.432 } 1.433 - 1.434 -void 1.435 -maximize(Arg *arg) 1.436 -{ 1.437 - if(!sel) 1.438 - return; 1.439 - sel->x = sx; 1.440 - sel->y = sy + bh; 1.441 - sel->w = sw - 2 * sel->border; 1.442 - sel->h = sh - 2 * sel->border - bh; 1.443 - higher(sel); 1.444 - resize(sel, False); 1.445 -} 1.446 - 1.447 -void 1.448 -focusprev(Arg *arg) 1.449 -{ 1.450 - Client *c; 1.451 - 1.452 - if(!sel) 1.453 - return; 1.454 - 1.455 - if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) { 1.456 - higher(c); 1.457 - focus(c); 1.458 - } 1.459 -} 1.460 - 1.461 -void 1.462 -focusnext(Arg *arg) 1.463 -{ 1.464 - Client *c; 1.465 - 1.466 - if(!sel) 1.467 - return; 1.468 - 1.469 - if(!(c = getnext(sel->next))) 1.470 - c = getnext(clients); 1.471 - if(c) { 1.472 - higher(c); 1.473 - c->revert = sel; 1.474 - focus(c); 1.475 - } 1.476 -} 1.477 - 1.478 -void 1.479 -killclient(Arg *arg) 1.480 -{ 1.481 - if(!sel) 1.482 - return; 1.483 - if(sel->proto & WM_PROTOCOL_DELWIN) 1.484 - sendevent(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]); 1.485 - else 1.486 - XKillClient(dpy, sel->win); 1.487 -}
2.1 --- a/draw.c Sat Jul 15 16:30:50 2006 +0200 2.2 +++ b/draw.c Sat Jul 15 17:00:56 2006 +0200 2.3 @@ -2,13 +2,34 @@ 2.4 * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> 2.5 * See LICENSE file for license details. 2.6 */ 2.7 +#include "dwm.h" 2.8 2.9 #include <stdio.h> 2.10 #include <string.h> 2.11 - 2.12 #include <X11/Xlocale.h> 2.13 2.14 -#include "dwm.h" 2.15 +/* static functions */ 2.16 + 2.17 +static void 2.18 +drawborder(void) 2.19 +{ 2.20 + XPoint points[5]; 2.21 + XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); 2.22 + XSetForeground(dpy, dc.gc, dc.border); 2.23 + points[0].x = dc.x; 2.24 + points[0].y = dc.y; 2.25 + points[1].x = dc.w - 1; 2.26 + points[1].y = 0; 2.27 + points[2].x = 0; 2.28 + points[2].y = dc.h - 1; 2.29 + points[3].x = -(dc.w - 1); 2.30 + points[3].y = 0; 2.31 + points[4].x = 0; 2.32 + points[4].y = -(dc.h - 1); 2.33 + XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); 2.34 +} 2.35 + 2.36 +/* extern functions */ 2.37 2.38 void 2.39 drawall() 2.40 @@ -53,59 +74,6 @@ 2.41 } 2.42 2.43 void 2.44 -drawtitle(Client *c) 2.45 -{ 2.46 - int i; 2.47 - Bool istile = arrange == dotile; 2.48 - 2.49 - if(c == sel) { 2.50 - drawstatus(); 2.51 - XUnmapWindow(dpy, c->title); 2.52 - XSetWindowBorder(dpy, c->win, dc.fg); 2.53 - return; 2.54 - } 2.55 - 2.56 - XSetWindowBorder(dpy, c->win, dc.bg); 2.57 - XMapWindow(dpy, c->title); 2.58 - 2.59 - dc.x = dc.y = 0; 2.60 - 2.61 - dc.w = 0; 2.62 - for(i = 0; i < TLast; i++) { 2.63 - if(c->tags[i]) { 2.64 - dc.x += dc.w; 2.65 - dc.w = textw(c->tags[i]); 2.66 - drawtext(c->tags[i], !istile, True); 2.67 - } 2.68 - } 2.69 - dc.x += dc.w; 2.70 - dc.w = textw(c->name); 2.71 - drawtext(c->name, !istile, True); 2.72 - XCopyArea(dpy, dc.drawable, c->title, dc.gc, 2.73 - 0, 0, c->tw, c->th, 0, 0); 2.74 - XFlush(dpy); 2.75 -} 2.76 - 2.77 -static void 2.78 -drawborder(void) 2.79 -{ 2.80 - XPoint points[5]; 2.81 - XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); 2.82 - XSetForeground(dpy, dc.gc, dc.border); 2.83 - points[0].x = dc.x; 2.84 - points[0].y = dc.y; 2.85 - points[1].x = dc.w - 1; 2.86 - points[1].y = 0; 2.87 - points[2].x = 0; 2.88 - points[2].y = dc.h - 1; 2.89 - points[3].x = -(dc.w - 1); 2.90 - points[3].y = 0; 2.91 - points[4].x = 0; 2.92 - points[4].y = -(dc.h - 1); 2.93 - XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious); 2.94 -} 2.95 - 2.96 -void 2.97 drawtext(const char *text, Bool invert, Bool border) 2.98 { 2.99 int x, y, w, h; 2.100 @@ -155,6 +123,40 @@ 2.101 } 2.102 } 2.103 2.104 +void 2.105 +drawtitle(Client *c) 2.106 +{ 2.107 + int i; 2.108 + Bool istile = arrange == dotile; 2.109 + 2.110 + if(c == sel) { 2.111 + drawstatus(); 2.112 + XUnmapWindow(dpy, c->title); 2.113 + XSetWindowBorder(dpy, c->win, dc.fg); 2.114 + return; 2.115 + } 2.116 + 2.117 + XSetWindowBorder(dpy, c->win, dc.bg); 2.118 + XMapWindow(dpy, c->title); 2.119 + 2.120 + dc.x = dc.y = 0; 2.121 + 2.122 + dc.w = 0; 2.123 + for(i = 0; i < TLast; i++) { 2.124 + if(c->tags[i]) { 2.125 + dc.x += dc.w; 2.126 + dc.w = textw(c->tags[i]); 2.127 + drawtext(c->tags[i], !istile, True); 2.128 + } 2.129 + } 2.130 + dc.x += dc.w; 2.131 + dc.w = textw(c->name); 2.132 + drawtext(c->name, !istile, True); 2.133 + XCopyArea(dpy, dc.drawable, c->title, dc.gc, 2.134 + 0, 0, c->tw, c->th, 0, 0); 2.135 + XFlush(dpy); 2.136 +} 2.137 + 2.138 unsigned long 2.139 getcolor(const char *colstr) 2.140 { 2.141 @@ -165,23 +167,6 @@ 2.142 return color.pixel; 2.143 } 2.144 2.145 -unsigned int 2.146 -textnw(char *text, unsigned int len) 2.147 -{ 2.148 - XRectangle r; 2.149 - if(dc.font.set) { 2.150 - XmbTextExtents(dc.font.set, text, len, NULL, &r); 2.151 - return r.width; 2.152 - } 2.153 - return XTextWidth(dc.font.xfont, text, len); 2.154 -} 2.155 - 2.156 -unsigned int 2.157 -textw(char *text) 2.158 -{ 2.159 - return textnw(text, strlen(text)) + dc.font.height; 2.160 -} 2.161 - 2.162 void 2.163 setfont(const char *fontstr) 2.164 { 2.165 @@ -232,3 +217,20 @@ 2.166 } 2.167 dc.font.height = dc.font.ascent + dc.font.descent; 2.168 } 2.169 + 2.170 +unsigned int 2.171 +textnw(char *text, unsigned int len) 2.172 +{ 2.173 + XRectangle r; 2.174 + if(dc.font.set) { 2.175 + XmbTextExtents(dc.font.set, text, len, NULL, &r); 2.176 + return r.width; 2.177 + } 2.178 + return XTextWidth(dc.font.xfont, text, len); 2.179 +} 2.180 + 2.181 +unsigned int 2.182 +textw(char *text) 2.183 +{ 2.184 + return textnw(text, strlen(text)) + dc.font.height; 2.185 +}
3.1 --- a/dwm.h Sat Jul 15 16:30:50 2006 +0200 3.2 +++ b/dwm.h Sat Jul 15 17:00:56 2006 +0200 3.3 @@ -104,53 +104,52 @@ 3.4 3.5 /* client.c */ 3.6 extern void ban(Client *c); 3.7 +extern void focus(Client *c); 3.8 +extern void focusnext(Arg *arg); 3.9 +extern void focusprev(Arg *arg); 3.10 +extern Client *getclient(Window w); 3.11 +extern Client *getctitle(Window w); 3.12 +extern void gravitate(Client *c, Bool invert); 3.13 +extern void higher(Client *c); 3.14 +extern void killclient(Arg *arg); 3.15 +extern void lower(Client *c); 3.16 extern void manage(Window w, XWindowAttributes *wa); 3.17 -extern void unmanage(Client *c); 3.18 -extern Client *getclient(Window w); 3.19 -extern void focus(Client *c); 3.20 -extern void settitle(Client *c); 3.21 +extern void maximize(Arg *arg); 3.22 extern void resize(Client *c, Bool inc); 3.23 extern void setsize(Client *c); 3.24 -extern Client *getctitle(Window w); 3.25 -extern void higher(Client *c); 3.26 -extern void lower(Client *c); 3.27 -extern void gravitate(Client *c, Bool invert); 3.28 +extern void settitle(Client *c); 3.29 +extern void unmanage(Client *c); 3.30 extern void zoom(Arg *arg); 3.31 -extern void maximize(Arg *arg); 3.32 -extern void focusprev(Arg *arg); 3.33 -extern void focusnext(Arg *arg); 3.34 -extern void killclient(Arg *arg); 3.35 3.36 /* draw.c */ 3.37 extern void drawall(); 3.38 extern void drawstatus(); 3.39 +extern void drawtext(const char *text, Bool invert, Bool border); 3.40 extern void drawtitle(Client *c); 3.41 -extern void drawtext(const char *text, Bool invert, Bool border); 3.42 extern unsigned long getcolor(const char *colstr); 3.43 extern void setfont(const char *fontstr); 3.44 extern unsigned int textnw(char *text, unsigned int len); 3.45 extern unsigned int textw(char *text); 3.46 -extern unsigned int texth(void); 3.47 3.48 /* event.c */ 3.49 extern void grabkeys(); 3.50 3.51 /* main.c */ 3.52 +extern int getproto(Window w); 3.53 extern void quit(Arg *arg); 3.54 +extern void sendevent(Window w, Atom a, long value); 3.55 extern int xerror(Display *dsply, XErrorEvent *ee); 3.56 -extern void sendevent(Window w, Atom a, long value); 3.57 -extern int getproto(Window w); 3.58 3.59 /* tag.c */ 3.60 -extern Client *getnext(Client *c); 3.61 -extern void settags(Client *c); 3.62 +extern void appendtag(Arg *arg); 3.63 extern void dofloat(Arg *arg); 3.64 extern void dotile(Arg *arg); 3.65 +extern Client *getnext(Client *c); 3.66 +extern void replacetag(Arg *arg); 3.67 +extern void settags(Client *c); 3.68 extern void view(Arg *arg); 3.69 -extern void appendtag(Arg *arg); 3.70 -extern void replacetag(Arg *arg); 3.71 3.72 /* util.c */ 3.73 +extern void *emallocz(unsigned int size); 3.74 extern void eprint(const char *errstr, ...); 3.75 -extern void *emallocz(unsigned int size); 3.76 extern void spawn(Arg *arg);
4.1 --- a/event.c Sat Jul 15 16:30:50 2006 +0200 4.2 +++ b/event.c Sat Jul 15 17:00:56 2006 +0200 4.3 @@ -2,17 +2,12 @@ 4.4 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> 4.5 * See LICENSE file for license details. 4.6 */ 4.7 +#include "dwm.h" 4.8 4.9 -#include <fcntl.h> 4.10 -#include <stdio.h> 4.11 #include <stdlib.h> 4.12 -#include <string.h> 4.13 -#include <unistd.h> 4.14 #include <X11/keysym.h> 4.15 #include <X11/Xatom.h> 4.16 4.17 -#include "dwm.h" 4.18 - 4.19 #define ButtonMask (ButtonPressMask | ButtonReleaseMask) 4.20 #define MouseMask (ButtonMask | PointerMotionMask) 4.21 4.22 @@ -54,130 +49,10 @@ 4.23 4.24 /********** CUSTOMIZE **********/ 4.25 4.26 -/* local functions */ 4.27 -static void buttonpress(XEvent *e); 4.28 -static void configurerequest(XEvent *e); 4.29 -static void destroynotify(XEvent *e); 4.30 -static void enternotify(XEvent *e); 4.31 -static void leavenotify(XEvent *e); 4.32 -static void expose(XEvent *e); 4.33 -static void keypress(XEvent *e); 4.34 -static void maprequest(XEvent *e); 4.35 -static void propertynotify(XEvent *e); 4.36 -static void unmapnotify(XEvent *e); 4.37 +/* static functions */ 4.38 4.39 -void (*handler[LASTEvent]) (XEvent *) = { 4.40 - [ButtonPress] = buttonpress, 4.41 - [ConfigureRequest] = configurerequest, 4.42 - [DestroyNotify] = destroynotify, 4.43 - [EnterNotify] = enternotify, 4.44 - [LeaveNotify] = leavenotify, 4.45 - [Expose] = expose, 4.46 - [KeyPress] = keypress, 4.47 - [MapRequest] = maprequest, 4.48 - [PropertyNotify] = propertynotify, 4.49 - [UnmapNotify] = unmapnotify 4.50 -}; 4.51 - 4.52 -void 4.53 -grabkeys() 4.54 -{ 4.55 - static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; 4.56 - unsigned int i; 4.57 - KeyCode code; 4.58 - 4.59 - for(i = 0; i < len; i++) { 4.60 - code = XKeysymToKeycode(dpy, key[i].keysym); 4.61 - XUngrabKey(dpy, code, key[i].mod, root); 4.62 - XGrabKey(dpy, code, key[i].mod, root, True, 4.63 - GrabModeAsync, GrabModeAsync); 4.64 - } 4.65 -} 4.66 - 4.67 -static void 4.68 -keypress(XEvent *e) 4.69 -{ 4.70 - XKeyEvent *ev = &e->xkey; 4.71 - static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; 4.72 - unsigned int i; 4.73 - KeySym keysym; 4.74 - 4.75 - keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); 4.76 - for(i = 0; i < len; i++) 4.77 - if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { 4.78 - if(key[i].func) 4.79 - key[i].func(&key[i].arg); 4.80 - return; 4.81 - } 4.82 -} 4.83 - 4.84 -static void 4.85 -resizemouse(Client *c) 4.86 -{ 4.87 - XEvent ev; 4.88 - int ocx, ocy; 4.89 - 4.90 - ocx = c->x; 4.91 - ocy = c->y; 4.92 - if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, 4.93 - None, cursor[CurResize], CurrentTime) != GrabSuccess) 4.94 - return; 4.95 - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h); 4.96 - for(;;) { 4.97 - XMaskEvent(dpy, MouseMask | ExposureMask, &ev); 4.98 - switch(ev.type) { 4.99 - default: break; 4.100 - case Expose: 4.101 - handler[Expose](&ev); 4.102 - break; 4.103 - case MotionNotify: 4.104 - XFlush(dpy); 4.105 - c->w = abs(ocx - ev.xmotion.x); 4.106 - c->h = abs(ocy - ev.xmotion.y); 4.107 - c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w; 4.108 - c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h; 4.109 - resize(c, True); 4.110 - break; 4.111 - case ButtonRelease: 4.112 - XUngrabPointer(dpy, CurrentTime); 4.113 - return; 4.114 - } 4.115 - } 4.116 -} 4.117 - 4.118 -static void 4.119 -movemouse(Client *c) 4.120 -{ 4.121 - XEvent ev; 4.122 - int x1, y1, ocx, ocy, di; 4.123 - unsigned int dui; 4.124 - Window dummy; 4.125 - 4.126 - ocx = c->x; 4.127 - ocy = c->y; 4.128 - if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, 4.129 - None, cursor[CurMove], CurrentTime) != GrabSuccess) 4.130 - return; 4.131 - XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); 4.132 - for(;;) { 4.133 - XMaskEvent(dpy, MouseMask | ExposureMask, &ev); 4.134 - switch (ev.type) { 4.135 - default: break; 4.136 - case Expose: 4.137 - handler[Expose](&ev); 4.138 - break; 4.139 - case MotionNotify: 4.140 - XFlush(dpy); 4.141 - c->x = ocx + (ev.xmotion.x - x1); 4.142 - c->y = ocy + (ev.xmotion.y - y1); 4.143 - resize(c, False); 4.144 - break; 4.145 - case ButtonRelease: 4.146 - XUngrabPointer(dpy, CurrentTime); 4.147 - return; 4.148 - } 4.149 - } 4.150 -} 4.151 +static void movemouse(Client *c); 4.152 +static void resizemouse(Client *c); 4.153 4.154 static void 4.155 buttonpress(XEvent *e) 4.156 @@ -280,15 +155,6 @@ 4.157 } 4.158 4.159 static void 4.160 -leavenotify(XEvent *e) 4.161 -{ 4.162 - XCrossingEvent *ev = &e->xcrossing; 4.163 - 4.164 - if((ev->window == root) && !ev->same_screen) 4.165 - issel = True; 4.166 -} 4.167 - 4.168 -static void 4.169 expose(XEvent *e) 4.170 { 4.171 XExposeEvent *ev = &e->xexpose; 4.172 @@ -303,6 +169,32 @@ 4.173 } 4.174 4.175 static void 4.176 +keypress(XEvent *e) 4.177 +{ 4.178 + XKeyEvent *ev = &e->xkey; 4.179 + static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; 4.180 + unsigned int i; 4.181 + KeySym keysym; 4.182 + 4.183 + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); 4.184 + for(i = 0; i < len; i++) 4.185 + if((keysym == key[i].keysym) && (key[i].mod == ev->state)) { 4.186 + if(key[i].func) 4.187 + key[i].func(&key[i].arg); 4.188 + return; 4.189 + } 4.190 +} 4.191 + 4.192 +static void 4.193 +leavenotify(XEvent *e) 4.194 +{ 4.195 + XCrossingEvent *ev = &e->xcrossing; 4.196 + 4.197 + if((ev->window == root) && !ev->same_screen) 4.198 + issel = True; 4.199 +} 4.200 + 4.201 +static void 4.202 maprequest(XEvent *e) 4.203 { 4.204 XMapRequestEvent *ev = &e->xmaprequest; 4.205 @@ -322,6 +214,40 @@ 4.206 } 4.207 4.208 static void 4.209 +movemouse(Client *c) 4.210 +{ 4.211 + XEvent ev; 4.212 + int x1, y1, ocx, ocy, di; 4.213 + unsigned int dui; 4.214 + Window dummy; 4.215 + 4.216 + ocx = c->x; 4.217 + ocy = c->y; 4.218 + if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, 4.219 + None, cursor[CurMove], CurrentTime) != GrabSuccess) 4.220 + return; 4.221 + XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); 4.222 + for(;;) { 4.223 + XMaskEvent(dpy, MouseMask | ExposureMask, &ev); 4.224 + switch (ev.type) { 4.225 + default: break; 4.226 + case Expose: 4.227 + handler[Expose](&ev); 4.228 + break; 4.229 + case MotionNotify: 4.230 + XFlush(dpy); 4.231 + c->x = ocx + (ev.xmotion.x - x1); 4.232 + c->y = ocy + (ev.xmotion.y - y1); 4.233 + resize(c, False); 4.234 + break; 4.235 + case ButtonRelease: 4.236 + XUngrabPointer(dpy, CurrentTime); 4.237 + return; 4.238 + } 4.239 + } 4.240 +} 4.241 + 4.242 +static void 4.243 propertynotify(XEvent *e) 4.244 { 4.245 XPropertyEvent *ev = &e->xproperty; 4.246 @@ -355,6 +281,40 @@ 4.247 } 4.248 4.249 static void 4.250 +resizemouse(Client *c) 4.251 +{ 4.252 + XEvent ev; 4.253 + int ocx, ocy; 4.254 + 4.255 + ocx = c->x; 4.256 + ocy = c->y; 4.257 + if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync, 4.258 + None, cursor[CurResize], CurrentTime) != GrabSuccess) 4.259 + return; 4.260 + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h); 4.261 + for(;;) { 4.262 + XMaskEvent(dpy, MouseMask | ExposureMask, &ev); 4.263 + switch(ev.type) { 4.264 + default: break; 4.265 + case Expose: 4.266 + handler[Expose](&ev); 4.267 + break; 4.268 + case MotionNotify: 4.269 + XFlush(dpy); 4.270 + c->w = abs(ocx - ev.xmotion.x); 4.271 + c->h = abs(ocy - ev.xmotion.y); 4.272 + c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w; 4.273 + c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h; 4.274 + resize(c, True); 4.275 + break; 4.276 + case ButtonRelease: 4.277 + XUngrabPointer(dpy, CurrentTime); 4.278 + return; 4.279 + } 4.280 + } 4.281 +} 4.282 + 4.283 +static void 4.284 unmapnotify(XEvent *e) 4.285 { 4.286 Client *c; 4.287 @@ -363,3 +323,33 @@ 4.288 if((c = getclient(ev->window))) 4.289 unmanage(c); 4.290 } 4.291 + 4.292 +/* extern functions */ 4.293 + 4.294 +void (*handler[LASTEvent]) (XEvent *) = { 4.295 + [ButtonPress] = buttonpress, 4.296 + [ConfigureRequest] = configurerequest, 4.297 + [DestroyNotify] = destroynotify, 4.298 + [EnterNotify] = enternotify, 4.299 + [LeaveNotify] = leavenotify, 4.300 + [Expose] = expose, 4.301 + [KeyPress] = keypress, 4.302 + [MapRequest] = maprequest, 4.303 + [PropertyNotify] = propertynotify, 4.304 + [UnmapNotify] = unmapnotify 4.305 +}; 4.306 + 4.307 +void 4.308 +grabkeys() 4.309 +{ 4.310 + static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0; 4.311 + unsigned int i; 4.312 + KeyCode code; 4.313 + 4.314 + for(i = 0; i < len; i++) { 4.315 + code = XKeysymToKeycode(dpy, key[i].keysym); 4.316 + XUngrabKey(dpy, code, key[i].mod, root); 4.317 + XGrabKey(dpy, code, key[i].mod, root, True, 4.318 + GrabModeAsync, GrabModeAsync); 4.319 + } 4.320 +}
5.1 --- a/main.c Sat Jul 15 16:30:50 2006 +0200 5.2 +++ b/main.c Sat Jul 15 17:00:56 2006 +0200 5.3 @@ -3,31 +3,17 @@ 5.4 * See LICENSE file for license details. 5.5 */ 5.6 5.7 +#include "dwm.h" 5.8 + 5.9 #include <errno.h> 5.10 -#include <stdarg.h> 5.11 #include <stdio.h> 5.12 #include <stdlib.h> 5.13 #include <string.h> 5.14 #include <unistd.h> 5.15 - 5.16 #include <X11/cursorfont.h> 5.17 #include <X11/Xatom.h> 5.18 #include <X11/Xproto.h> 5.19 5.20 -#include "dwm.h" 5.21 - 5.22 -/********** CUSTOMIZE **********/ 5.23 - 5.24 -char *tags[TLast] = { 5.25 - [Tscratch] = "scratch", 5.26 - [Tdev] = "dev", 5.27 - [Twww] = "www", 5.28 - [Twork] = "work", 5.29 -}; 5.30 - 5.31 -/********** CUSTOMIZE **********/ 5.32 - 5.33 -/* X structs */ 5.34 Display *dpy; 5.35 Window root, barwin; 5.36 Atom wm_atom[WMLast], net_atom[NetLast]; 5.37 @@ -48,8 +34,17 @@ 5.38 "dwm-" VERSION ", (C)opyright MMVI Anselm R. Garbe\n"; 5.39 static int (*xerrorxlib)(Display *, XErrorEvent *); 5.40 5.41 +/* static functions */ 5.42 + 5.43 static void 5.44 -usage() { eprint("usage: dwm [-v]\n"); } 5.45 +cleanup() 5.46 +{ 5.47 + while(sel) { 5.48 + resize(sel, True); 5.49 + unmanage(sel); 5.50 + } 5.51 + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); 5.52 +} 5.53 5.54 static void 5.55 scan() 5.56 @@ -73,22 +68,6 @@ 5.57 XFree(wins); 5.58 } 5.59 5.60 -static void 5.61 -cleanup() 5.62 -{ 5.63 - while(sel) { 5.64 - resize(sel, True); 5.65 - unmanage(sel); 5.66 - } 5.67 - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); 5.68 -} 5.69 - 5.70 -void 5.71 -quit(Arg *arg) 5.72 -{ 5.73 - running = False; 5.74 -} 5.75 - 5.76 static int 5.77 win_property(Window w, Atom a, Atom t, long l, unsigned char **prop) 5.78 { 5.79 @@ -109,6 +88,19 @@ 5.80 return res; 5.81 } 5.82 5.83 +/* 5.84 + * Startup Error handler to check if another window manager 5.85 + * is already running. 5.86 + */ 5.87 +static int 5.88 +xerrorstart(Display *dsply, XErrorEvent *ee) 5.89 +{ 5.90 + otherwm = True; 5.91 + return -1; 5.92 +} 5.93 + 5.94 +/* extern functions */ 5.95 + 5.96 int 5.97 getproto(Window w) 5.98 { 5.99 @@ -144,15 +136,10 @@ 5.100 XFlush(dpy); 5.101 } 5.102 5.103 -/* 5.104 - * Startup Error handler to check if another window manager 5.105 - * is already running. 5.106 - */ 5.107 -static int 5.108 -xerrorstart(Display *dsply, XErrorEvent *ee) 5.109 +void 5.110 +quit(Arg *arg) 5.111 { 5.112 - otherwm = True; 5.113 - return -1; 5.114 + running = False; 5.115 } 5.116 5.117 /* 5.118 @@ -201,7 +188,7 @@ 5.119 exit(0); 5.120 break; 5.121 default: 5.122 - usage(); 5.123 + eprint("usage: dwm [-v]\n"); 5.124 break; 5.125 } 5.126 }
6.1 --- a/tag.c Sat Jul 15 16:30:50 2006 +0200 6.2 +++ b/tag.c Sat Jul 15 17:00:56 2006 +0200 6.3 @@ -2,71 +2,39 @@ 6.4 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> 6.5 * See LICENSE file for license details. 6.6 */ 6.7 +#include "dwm.h" 6.8 6.9 -#include <stdlib.h> 6.10 -#include <stdio.h> 6.11 #include <string.h> 6.12 -#include <X11/Xatom.h> 6.13 #include <X11/Xutil.h> 6.14 6.15 -#include "dwm.h" 6.16 +/********** CUSTOMIZE **********/ 6.17 + 6.18 +char *tags[TLast] = { 6.19 + [Tscratch] = "scratch", 6.20 + [Tdev] = "dev", 6.21 + [Twww] = "www", 6.22 + [Twork] = "work", 6.23 +}; 6.24 6.25 static Rule rule[] = { 6.26 /* class instance tags dofloat */ 6.27 { "Firefox-bin", "Gecko", { [Twww] = "www" }, False }, 6.28 }; 6.29 6.30 +/********** CUSTOMIZE **********/ 6.31 + 6.32 +/* extern functions */ 6.33 + 6.34 void (*arrange)(Arg *) = dotile; 6.35 6.36 -Client * 6.37 -getnext(Client *c) 6.38 +void 6.39 +appendtag(Arg *arg) 6.40 { 6.41 - for(; c && !c->tags[tsel]; c = c->next); 6.42 - return c; 6.43 -} 6.44 + if(!sel) 6.45 + return; 6.46 6.47 -void 6.48 -settags(Client *c) 6.49 -{ 6.50 - XClassHint ch; 6.51 - static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; 6.52 - unsigned int i, j; 6.53 - Bool matched = False; 6.54 - 6.55 - if(!len) { 6.56 - c->tags[tsel] = tags[tsel]; 6.57 - return; 6.58 - } 6.59 - 6.60 - if(XGetClassHint(dpy, c->win, &ch)) { 6.61 - if(ch.res_class && ch.res_name) { 6.62 - for(i = 0; i < len; i++) 6.63 - if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class)) 6.64 - && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) 6.65 - { 6.66 - for(j = 0; j < TLast; j++) 6.67 - c->tags[j] = rule[i].tags[j]; 6.68 - c->dofloat = rule[i].dofloat; 6.69 - matched = True; 6.70 - break; 6.71 - } 6.72 - } 6.73 - if(ch.res_class) 6.74 - XFree(ch.res_class); 6.75 - if(ch.res_name) 6.76 - XFree(ch.res_name); 6.77 - } 6.78 - 6.79 - if(!matched) 6.80 - c->tags[tsel] = tags[tsel]; 6.81 -} 6.82 - 6.83 -void 6.84 -view(Arg *arg) 6.85 -{ 6.86 - tsel = arg->i; 6.87 + sel->tags[arg->i] = tags[arg->i]; 6.88 arrange(NULL); 6.89 - drawall(); 6.90 } 6.91 6.92 void 6.93 @@ -147,14 +115,11 @@ 6.94 drawall(); 6.95 } 6.96 6.97 -void 6.98 -appendtag(Arg *arg) 6.99 +Client * 6.100 +getnext(Client *c) 6.101 { 6.102 - if(!sel) 6.103 - return; 6.104 - 6.105 - sel->tags[arg->i] = tags[arg->i]; 6.106 - arrange(NULL); 6.107 + for(; c && !c->tags[tsel]; c = c->next); 6.108 + return c; 6.109 } 6.110 6.111 void 6.112 @@ -169,3 +134,46 @@ 6.113 appendtag(arg); 6.114 } 6.115 6.116 +void 6.117 +settags(Client *c) 6.118 +{ 6.119 + XClassHint ch; 6.120 + static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; 6.121 + unsigned int i, j; 6.122 + Bool matched = False; 6.123 + 6.124 + if(!len) { 6.125 + c->tags[tsel] = tags[tsel]; 6.126 + return; 6.127 + } 6.128 + 6.129 + if(XGetClassHint(dpy, c->win, &ch)) { 6.130 + if(ch.res_class && ch.res_name) { 6.131 + for(i = 0; i < len; i++) 6.132 + if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class)) 6.133 + && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) 6.134 + { 6.135 + for(j = 0; j < TLast; j++) 6.136 + c->tags[j] = rule[i].tags[j]; 6.137 + c->dofloat = rule[i].dofloat; 6.138 + matched = True; 6.139 + break; 6.140 + } 6.141 + } 6.142 + if(ch.res_class) 6.143 + XFree(ch.res_class); 6.144 + if(ch.res_name) 6.145 + XFree(ch.res_name); 6.146 + } 6.147 + 6.148 + if(!matched) 6.149 + c->tags[tsel] = tags[tsel]; 6.150 +} 6.151 + 6.152 +void 6.153 +view(Arg *arg) 6.154 +{ 6.155 + tsel = arg->i; 6.156 + arrange(NULL); 6.157 + drawall(); 6.158 +}
7.1 --- a/util.c Sat Jul 15 16:30:50 2006 +0200 7.2 +++ b/util.c Sat Jul 15 17:00:56 2006 +0200 7.3 @@ -2,24 +2,15 @@ 7.4 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> 7.5 * See LICENSE file for license details. 7.6 */ 7.7 +#include "dwm.h" 7.8 7.9 #include <stdarg.h> 7.10 #include <stdio.h> 7.11 #include <stdlib.h> 7.12 -#include <sys/types.h> 7.13 #include <sys/wait.h> 7.14 #include <unistd.h> 7.15 7.16 -#include "dwm.h" 7.17 - 7.18 -void 7.19 -eprint(const char *errstr, ...) { 7.20 - va_list ap; 7.21 - va_start(ap, errstr); 7.22 - vfprintf(stderr, errstr, ap); 7.23 - va_end(ap); 7.24 - exit(1); 7.25 -} 7.26 +/* static functions */ 7.27 7.28 static void 7.29 bad_malloc(unsigned int size) 7.30 @@ -29,6 +20,8 @@ 7.31 exit(1); 7.32 } 7.33 7.34 +/* extern functions */ 7.35 + 7.36 void * 7.37 emallocz(unsigned int size) 7.38 { 7.39 @@ -39,6 +32,15 @@ 7.40 } 7.41 7.42 void 7.43 +eprint(const char *errstr, ...) { 7.44 + va_list ap; 7.45 + va_start(ap, errstr); 7.46 + vfprintf(stderr, errstr, ap); 7.47 + va_end(ap); 7.48 + exit(1); 7.49 +} 7.50 + 7.51 +void 7.52 spawn(Arg *arg) 7.53 { 7.54 char **argv = (char **)arg->argv;