X-Git-Url: https://jasonwoof.com/gitweb/?p=dwm.git;a=blobdiff_plain;f=main.c;h=5551e6ed283e76f71d97086e7ddd9e2121a595a3;hp=3453b5985a15832ec89b70a763daa290599f566f;hb=d934296476be7345842fec1a2630d1752c704078;hpb=e9c49ddd7a021e99dc2e7518736211ab5bc8cf2c diff --git a/main.c b/main.c index 3453b59..5551e6e 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,9 @@ -/* (C)opyright MMVI-MMVII Anselm R. Garbe - * See LICENSE file for license details. - */ - +/* © 2006-2007 Anselm R. Garbe + * © 2006-2007 Sander van Dijk + * © 2006-2007 Jukka Salmi + * © 2007 Premysl Hruby + * © 2007 Szabolcs Nagy + * See LICENSE file for license details. */ #include "dwm.h" #include #include @@ -18,10 +20,9 @@ /* extern */ char stext[256]; -int bh, bmw, screen, sx, sy, sw, sh, wax, way, waw, wah; -unsigned int ntags, numlockmask; +int screen, sx, sy, sw, sh, wax, way, waw, wah; +unsigned int bh, bpos, ntags, numlockmask; Atom wmatom[WMLast], netatom[NetLast]; -Bool running = True; Bool *seltag; Bool selscreen = True; Client *clients = NULL; @@ -36,6 +37,7 @@ Window root, barwin; static int (*xerrorxlib)(Display *, XErrorEvent *); static Bool otherwm, readin; +static Bool running = True; static void cleanup(void) { @@ -61,76 +63,8 @@ cleanup(void) { free(seltag); } -static unsigned int -textnw(const char *text, unsigned int len) { - XRectangle r; - - if(dc.font.set) { - XmbTextExtents(dc.font.set, text, len, NULL, &r); - return r.width; - } - return XTextWidth(dc.font.xfont, text, len); -} - -static void -drawtext(const char *text, unsigned long col[ColLast], Bool filledsquare, Bool emptysquare) { - int x, y, w, h; - static char buf[256]; - unsigned int len, olen; - XGCValues gcv; - XRectangle r = { dc.x, dc.y, dc.w, dc.h }; - - XSetForeground(dpy, dc.gc, col[ColBG]); - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - if(!text) - return; - w = 0; - olen = len = strlen(text); - if(len >= sizeof buf) - len = sizeof buf - 1; - memcpy(buf, text, len); - buf[len] = 0; - h = dc.font.ascent + dc.font.descent; - y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent; - x = dc.x + (h / 2); - /* shorten text if necessary */ - while(len && (w = textnw(buf, len)) > dc.w - h) - buf[--len] = 0; - if(len < olen) { - if(len > 1) - buf[len - 1] = '.'; - if(len > 2) - buf[len - 2] = '.'; - if(len > 3) - buf[len - 3] = '.'; - } - if(w > dc.w) - return; /* too long */ - gcv.foreground = col[ColFG]; - if(dc.font.set) { - XChangeGC(dpy, dc.gc, GCForeground, &gcv); - XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); - } - else { - gcv.font = dc.font.xfont->fid; - XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv); - XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); - } - x = (h + 2) / 4; - r.x = dc.x + 1; - r.y = dc.y + 1; - if(filledsquare) { - r.width = r.height = x + 1; - XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); - } - else if(emptysquare) { - r.width = r.height = x; - XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1); - } -} - static unsigned long -getcolor(const char *colstr) { +initcolor(const char *colstr) { Colormap cmap = DefaultColormap(dpy, screen); XColor color; @@ -139,38 +73,8 @@ getcolor(const char *colstr) { return color.pixel; } -static Bool -isoccupied(unsigned int t) { - Client *c; - - for(c = clients; c; c = c->next) - if(c->tags[t]) - return True; - return False; -} - -static void -scan(void) { - unsigned int i, num; - Window *wins, d1, d2; - XWindowAttributes wa; - - wins = NULL; - if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { - for(i = 0; i < num; i++) { - if(!XGetWindowAttributes(dpy, wins[i], &wa) - || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) - continue; - if(wa.map_state == IsViewable) - manage(wins[i], &wa); - } - } - if(wins) - XFree(wins); -} - static void -setfont(const char *fontstr) { +initfont(const char *fontstr) { char *def, **missing; int i, n; @@ -180,7 +84,7 @@ setfont(const char *fontstr) { dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); if(missing) { while(n--) - fprintf(stderr, "missing fontset: %s\n", missing[n]); + fprintf(stderr, "dwm: missing fontset: %s\n", missing[n]); XFreeStringList(missing); } if(dc.font.set) { @@ -211,6 +115,26 @@ setfont(const char *fontstr) { } static void +scan(void) { + unsigned int i, num; + Window *wins, d1, d2; + XWindowAttributes wa; + + wins = NULL; + if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { + for(i = 0; i < num; i++) { + if(!XGetWindowAttributes(dpy, wins[i], &wa) + || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) + continue; + if(wa.map_state == IsViewable) + manage(wins[i], &wa); + } + } + if(wins) + XFree(wins); +} + +static void setup(void) { int i, j; unsigned int mask; @@ -242,47 +166,47 @@ setup(void) { XFreeModifiermap(modmap); /* select for events */ wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask - | EnterWindowMask | LeaveWindowMask; + | EnterWindowMask | LeaveWindowMask | StructureNotifyMask; wa.cursor = cursor[CurNormal]; XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); + XSelectInput(dpy, root, wa.event_mask); grabkeys(); - compileregexps(); + compileregs(); for(ntags = 0; tags[ntags]; ntags++); seltag = emallocz(sizeof(Bool) * ntags); seltag[0] = True; /* style */ - dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR); - dc.norm[ColBG] = getcolor(NORMBGCOLOR); - dc.norm[ColFG] = getcolor(NORMFGCOLOR); - dc.sel[ColBorder] = getcolor(SELBORDERCOLOR); - dc.sel[ColBG] = getcolor(SELBGCOLOR); - dc.sel[ColFG] = getcolor(SELFGCOLOR); - setfont(FONT); + dc.norm[ColBorder] = initcolor(NORMBORDERCOLOR); + dc.norm[ColBG] = initcolor(NORMBGCOLOR); + dc.norm[ColFG] = initcolor(NORMFGCOLOR); + dc.sel[ColBorder] = initcolor(SELBORDERCOLOR); + dc.sel[ColBG] = initcolor(SELBGCOLOR); + dc.sel[ColFG] = initcolor(SELFGCOLOR); + initfont(FONT); /* geometry */ sx = sy = 0; sw = DisplayWidth(dpy, screen); sh = DisplayHeight(dpy, screen); - bmw = textw(TILESYMBOL) > textw(FLOATSYMBOL) ? textw(TILESYMBOL) : textw(FLOATSYMBOL); + initlayouts(); /* bar */ dc.h = bh = dc.font.height + 2; wa.override_redirect = 1; wa.background_pixmap = ParentRelative; wa.event_mask = ButtonPressMask | ExposureMask; - barwin = XCreateWindow(dpy, root, sx, sy + (TOPBAR ? 0 : sh - bh), sw, bh, 0, + barwin = XCreateWindow(dpy, root, sx, sy, sw, bh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); XDefineCursor(dpy, barwin, cursor[CurNormal]); + bpos = BARPOS; + updatebarpos(); XMapRaised(dpy, barwin); strcpy(stext, "dwm-"VERSION); - /* windowarea */ - wax = sx; - way = sy + (TOPBAR ? bh : 0); - wah = sh - bh; - waw = sw; /* pixmap for everything */ dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); dc.gc = XCreateGC(dpy, root, 0, 0); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); + if(!dc.font.set) + XSetFont(dpy, dc.gc, dc.font.xfont->fid); /* multihead support */ selscreen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask); } @@ -300,58 +224,34 @@ xerrorstart(Display *dsply, XErrorEvent *ee) { /* extern */ void -drawstatus(void) { - int i, x; - - dc.x = dc.y = 0; - for(i = 0; i < ntags; i++) { - dc.w = textw(tags[i]); - if(seltag[i]) - drawtext(tags[i], dc.sel, sel && sel->tags[i], isoccupied(i)); - else - drawtext(tags[i], dc.norm, sel && sel->tags[i], isoccupied(i)); - dc.x += dc.w; - } - dc.w = bmw; - drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.norm, False, False); - x = dc.x + dc.w; - dc.w = textw(stext); - dc.x = sw - dc.w; - if(dc.x < x) { - dc.x = x; - dc.w = sw - x; - } - drawtext(stext, dc.norm, False, False); - if((dc.w = dc.x - x) > bh) { - dc.x = x; - drawtext(sel ? sel->name : NULL, sel ? dc.sel : dc.norm, False, False); - } - XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0); - XSync(dpy, False); +quit(const char *arg) { + readin = running = False; } void -sendevent(Window w, Atom a, long value) { - XEvent e; +updatebarpos(void) { + XEvent ev; - e.type = ClientMessage; - e.xclient.window = w; - e.xclient.message_type = a; - e.xclient.format = 32; - e.xclient.data.l[0] = value; - e.xclient.data.l[1] = CurrentTime; - XSendEvent(dpy, w, False, NoEventMask, &e); + wax = sx; + way = sy; + wah = sh; + waw = sw; + switch(bpos) { + default: + wah -= bh; + way += bh; + XMoveWindow(dpy, barwin, sx, sy); + break; + case BarBot: + wah -= bh; + XMoveWindow(dpy, barwin, sx, sy + wah); + break; + case BarOff: + XMoveWindow(dpy, barwin, sx, sy - bh); + break; + } XSync(dpy, False); -} - -unsigned int -textw(const char *text) { - return textnw(text, strlen(text)) + dc.font.height; -} - -void -quit(Arg *arg) { - readin = running = False; + while(XCheckMaskEvent(dpy, EnterWindowMask, &ev)); } /* There's no way to check accesses to destroyed windows, thus those cases are @@ -381,15 +281,12 @@ main(int argc, char *argv[]) { fd_set rd; XEvent ev; - if(argc == 2 && !strncmp("-v", argv[1], 3)) { - fputs("dwm-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n", stdout); - exit(EXIT_SUCCESS); - } + if(argc == 2 && !strcmp("-v", argv[1])) + eprint("dwm-"VERSION", © 2006-2007 A. R. Garbe, S. van Dijk, J. Salmi, P. Hruby, S. Nagy\n"); else if(argc != 1) eprint("usage: dwm [-v]\n"); setlocale(LC_CTYPE, ""); - dpy = XOpenDisplay(0); - if(!dpy) + if(!(dpy = XOpenDisplay(0))) eprint("dwm: cannot open display\n"); xfd = ConnectionNumber(dpy); screen = DefaultScreen(dpy); @@ -442,12 +339,11 @@ main(int argc, char *argv[]) { } drawstatus(); } - if(FD_ISSET(xfd, &rd)) - while(XPending(dpy)) { - XNextEvent(dpy, &ev); - if(handler[ev.type]) - (handler[ev.type])(&ev); /* call handler */ - } + while(XPending(dpy)) { + XNextEvent(dpy, &ev); + if(handler[ev.type]) + (handler[ev.type])(&ev); /* call handler */ + } } cleanup(); XCloseDisplay(dpy);