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*
getdiv(Divide *** dp)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
mapdiv(Divide * d)43 mapdiv(Divide *d) {
44 mapwin(d->w);
45 }
46
47 static void
unmapdiv(Divide * d)48 unmapdiv(Divide *d) {
49 unmapwin(d->w);
50 }
51
52 void
div_set(Divide * d,int x)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
drawimg(Image * img,Color cbg,Color cborder,Divide * d)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
drawdiv(Divide * d)94 drawdiv(Divide *d) {
95
96 fill(divmask, divmask->r, (Color){0});
97 drawimg(divmask, (Color){1}, (Color){1}, 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
update_imgs(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
div_update_all(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 void
bdown_event(Window * w,XButtonEvent * e)167 bdown_event(Window *w, XButtonEvent *e) {
168 Divide *d;
169
170 USED(e);
171
172 d = w->aux;
173 mouse_resizecol(d);
174 }
175
176 static void
expose_event(Window * w,XExposeEvent * e)177 expose_event(Window *w, XExposeEvent *e) {
178 Divide *d;
179
180 USED(e);
181
182 d = w->aux;
183 drawdiv(d);
184 }
185
186 static Handlers handlers = {
187 .bdown = bdown_event,
188 .expose = expose_event,
189 };
190
191