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