wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

div.c (3262B)


      1 /* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
      2  * See LICENSE file for license details.
      3  */
      4 #include "dat.h"
      5 #include "fns.h"
      6 
      7 static Image*	divimg;
      8 static Image*	divmask;
      9 static CTuple	divcolor;
     10 static Handlers	handlers;
     11 
     12 static Divide*
     13 getdiv(Divide ***dp) {
     14 	WinAttr wa;
     15 	Divide *d;
     16 
     17 	if(**dp)
     18 		d = **dp;
     19 	else {
     20 		d = emallocz(sizeof *d);
     21 
     22 		wa.override_redirect = true;
     23 		wa.cursor = cursor[CurDHArrow];
     24 		wa.event_mask =
     25 			  ExposureMask
     26 			| EnterWindowMask
     27 			| ButtonPressMask
     28 			| ButtonReleaseMask;
     29 		d->w = createwindow(&scr.root, Rect(0, 0, 1, 1), scr.depth,
     30 				    InputOutput, &wa,
     31 			  CWOverrideRedirect
     32 			| CWEventMask
     33 			| CWCursor);
     34 		d->w->aux = d;
     35 		sethandler(d->w, &handlers);
     36 		**dp = d;
     37 	}
     38 	*dp = &d->next;
     39 	return d;
     40 }
     41 
     42 static void
     43 mapdiv(Divide *d) {
     44 	mapwin(d->w);
     45 }
     46 
     47 static void
     48 unmapdiv(Divide *d) {
     49 	unmapwin(d->w);
     50 }
     51 
     52 void
     53 div_set(Divide *d, int x) {
     54 	Rectangle r;
     55 	int scrn;
     56 
     57 	scrn = d->left ? d->left->screen : d->right->screen;
     58 
     59 	d->x = x;
     60 	r = rectaddpt(divimg->r, Pt(x - Dx(divimg->r)/2, 0));
     61 	r.min.y = selview->r[scrn].min.y;
     62 	r.max.y = selview->r[scrn].max.y;
     63 
     64 	reshapewin(d->w, r);
     65 	mapdiv(d);
     66 }
     67 
     68 static void
     69 drawimg(Image *img, Color cbg, Color cborder, Divide *d) {
     70 	Point pt[8];
     71 	int n, start, w;
     72 
     73 	w = Dx(img->r)/2;
     74 	n = 0;
     75 	pt[n++] = Pt(w,		0);
     76 	pt[n++] = Pt(0,		0);
     77 	pt[n++] = Pt(w - 1,	w - 1);
     78 
     79 	pt[n++] = Pt(w - 1,	Dy(img->r));
     80 	pt[n++] = Pt(w,		pt[n-1].y);
     81 
     82 	pt[n++] = Pt(w,		w - 1);
     83 	pt[n++] = Pt(2*w - 1,	0);
     84 	pt[n++] = Pt(w,		0);
     85 
     86 	start = d->left		? 0 : n/2;
     87 	n = d->right && d->left ? n : n/2;
     88 
     89 	fillpoly(img, pt + start, n, &cbg);
     90 	drawpoly(img, pt + start, n, CapNotLast, 1, &cborder);
     91 }
     92 
     93 static void
     94 drawdiv(Divide *d) {
     95 
     96 	fill(divmask, divmask->r, &(Color){0});
     97 	drawimg(divmask, (Color){~0,~0,~0}, (Color){~0,~0,~0}, d);
     98 	drawimg(divimg, divcolor.bg, divcolor.border, d);
     99 
    100 	copyimage(d->w, divimg->r, divimg, ZP);
    101 	setshapemask(d->w, divmask, ZP);
    102 }
    103 
    104 static void
    105 update_imgs(void) {
    106 	Divide *d;
    107 	int w, h;
    108 
    109 	w = 2 * (labelh(def.font) / 3);
    110 	w = max(w, 10);
    111 	/* XXX: Multihead. */
    112 	h = Dy(scr.rect);
    113 
    114 	if(divimg) {
    115 		if(w == Dx(divimg->r) && h == Dy(divimg->r)
    116 		&& !memcmp(&divcolor, &def.normcolor, sizeof divcolor))
    117 			return;
    118 		freeimage(divimg);
    119 		freeimage(divmask);
    120 	}
    121 
    122 	divimg = allocimage(w, h, scr.depth);
    123 	divmask = allocimage(w, h, 1);
    124 	divcolor = def.normcolor;
    125 
    126 	for(d = divs; d && d->w->mapped; d = d->next)
    127 		drawdiv(d);
    128 }
    129 
    130 void
    131 div_update_all(void) {
    132 	Divide **dp, *d;
    133 	Area *a, *ap;
    134 	View *v;
    135 	int s;
    136 
    137 	update_imgs();
    138 
    139 	v = selview;
    140 	dp = &divs;
    141 	ap = nil;
    142 	foreach_column(v, s, a) {
    143 		if(ap && ap->screen != s)
    144 			ap = nil;
    145 
    146 		d = getdiv(&dp);
    147 		d->left = ap;
    148 		d->right = a;
    149 		div_set(d, a->r.min.x);
    150 		drawdiv(d);
    151 		ap = a;
    152 
    153 		if(!a->next) {
    154 			d = getdiv(&dp);
    155 			d->left = a;
    156 			d->right = nil;
    157 			div_set(d, a->r.max.x);
    158 			drawdiv(d);
    159 		}
    160 	}
    161 	for(d = *dp; d; d = d->next)
    162 		unmapdiv(d);
    163 }
    164 
    165 /* Div Handlers */
    166 static bool
    167 bdown_event(Window *w, void *aux, XButtonEvent *e) {
    168 	Divide *d;
    169 
    170 	USED(e);
    171 
    172 	d = aux;
    173 	mouse_resizecol(d);
    174 	return false;
    175 }
    176 
    177 static bool
    178 expose_event(Window *w, void *aux, XExposeEvent *e) {
    179 	Divide *d;
    180 
    181 	USED(e);
    182 
    183 	d = aux;
    184 	drawdiv(d);
    185 	return false;
    186 }
    187 
    188 static Handlers handlers = {
    189 	.bdown = bdown_event,
    190 	.expose = expose_event,
    191 };
    192