wmii

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

screen.c (4449B)


      1 /* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
      2  * See LICENSE file for license details.
      3  */
      4 #include "dat.h"
      5 #include <math.h>
      6 #include "fns.h"
      7 
      8 #ifdef notdef
      9 void
     10 mapscreens(void) {
     11 	WMScreen *s, *ss;
     12 	Rectangle r;
     13 	int i, j;
     14 
     15 #define frob(left, min, max, x, y) \
     16 	if(Dy(r) > 0) /* If they intersect at some point on this axis */        \
     17 	if(ss->r.min.x < s->r.min.x) {                                          \
     18 		if((!s->left)                                                   \
     19 		|| (abs(Dy(r)) < abs(s->left.max.x - s->min.x))) \
     20 			s->left = ss;                                           \
     21 	}
     22 
     23 	/* Variable hell? Certainly. */
     24 	for(i=0; i < nscreens; i++) {
     25 		s = screens[i];
     26 		for(j=0; j < nscreens; j++) {
     27 			if(i == j)
     28 				continue;
     29 			ss = screens[j];
     30 			r = rect_intersection(ss->r, s->r);
     31 			frob(left,   min, max, x, y);
     32 			frob(right,  max, min, x, y);
     33 			frob(atop,   min, max, y, x);
     34 			frob(below,  max, min, y, x);
     35 		}
     36 	}
     37 #undef frob
     38 }
     39 
     40 int	findscreen(Rectangle, int);
     41 int
     42 findscreen(Rectangle rect, int direction) {
     43 	Rectangle r;
     44 	WMScreen *ss, *s;
     45 	int best, i, j;
     46 
     47 	best = -1;
     48 #define frob(min, max, x, y)
     49 	if(Dy(r) > 0) /* If they intersect at some point on this axis */
     50 	if(ss->r.min.x < rect.min.x) {
     51 		if(best == -1
     52 		|| (abs(ss->r.max.x - rect.min.x) < abs(screens[best]->r.max.x - rect.min.x)))
     53 			best = s->idx;
     54 	}
     55 
     56 	/* Variable hell? Certainly. */
     57 	for(i=0; i < nscreens; i++) {
     58 		ss = screens[j];
     59 		r = rect_intersection(ss->r, rect);
     60 		switch(direction) {
     61 		default:
     62 			return -1;
     63 		case West:
     64 			frob(min, max, x, y);
     65 			break;
     66 		case East:
     67 			frob(max, min, x, y);
     68 			break;
     69 		case North:
     70 			frob(min, max, y, x);
     71 			break;
     72 		case South:
     73 			frob(max, min, y, x);
     74 			break;
     75 		}
     76 	}
     77 #undef frob
     78 }
     79 #endif
     80 
     81 static Rectangle
     82 leastthing(Rectangle rect, int direction, Vector_ptr *vec, Rectangle (*key)(void*)) {
     83 	Rectangle r;
     84 	int i, best, d;
     85 
     86 	SET(d);
     87 	SET(best);
     88 	for(i=0; i < vec->n; i++) {
     89 		r = key(vec->ary[i]);
     90 		switch(direction) {
     91 		case South: d =  r.min.y; break;
     92 		case North: d = -r.max.y; break;
     93 		case East:  d =  r.min.x; break;
     94 		case West:  d = -r.max.x; break;
     95 		}
     96 		if(i == 0 || d < best)
     97 			best = d;
     98 	}
     99 	switch(direction) {
    100 	case South: rect.min.y = rect.max.y =  best; break;
    101 	case North: rect.min.y = rect.max.y = -best; break;
    102 	case East:  rect.min.x = rect.max.x =  best; break;
    103 	case West:  rect.min.x = rect.max.x = -best; break;
    104 	}
    105 	return rect;
    106 }
    107 
    108 void*
    109 findthing(Rectangle rect, int direction, Vector_ptr *vec, Rectangle (*key)(void*), bool wrap) {
    110 	Rectangle isect;
    111 	Rectangle r, bestisect = {0,}, bestr = {0,};
    112 	void *best, *p;
    113 	int i, n;
    114 
    115 	best = nil;
    116 
    117 	/* For the record, I really hate these macros. */
    118 #define frob(min, max, LT, x, y) \
    119 	if(D##y(isect) > 0) /* If they intersect at some point on this axis */  \
    120 	if(r.min.x LT rect.min.x) {                                             \
    121 		n = abs(r.max.x - rect.min.x) - abs(bestr.max.x - rect.min.x);  \
    122 		if(best == nil                                                  \
    123 		|| n == 0 && D##y(isect) > D##y(bestisect)                      \
    124 		|| n < 0                                                        \
    125 		) {                                                             \
    126 			best = p;                                               \
    127 			bestr = r;                                              \
    128 			bestisect = isect;                                      \
    129 		}                                                               \
    130 	}
    131 
    132 	/* Variable hell? Certainly. */
    133 	for(i=0; i < vec->n; i++) {
    134 		p = vec->ary[i];
    135 		r = key(p);
    136 		isect = rect_intersection(rect, r);
    137 		switch(direction) {
    138 		default:
    139 			die("not reached");
    140 			/* Not reached */
    141 		case West:
    142 			frob(min, max, <, x, y);
    143 			break;
    144 		case East:
    145 			frob(max, min, >, x, y);
    146 			break;
    147 		case North:
    148 			frob(min, max, <, y, x);
    149 			break;
    150 		case South:
    151 			frob(max, min, >, y, x);
    152 			break;
    153 		}
    154 	}
    155 #undef frob
    156 	if(!best && wrap) {
    157 		r = leastthing(rect, direction, vec, key);
    158 		return findthing(r, direction, vec, key, false);
    159 	}
    160 	return best;
    161 }
    162 
    163 static int
    164 area(Rectangle r) {
    165 	return Dx(r) * Dy(r) *
    166 	       (Dx(r) < 0 && Dy(r) < 0 ? -1 : 1);
    167 }
    168 
    169 int
    170 ownerscreen(Rectangle r) {
    171 	Rectangle isect;
    172 	int s, a, best, besta;
    173 
    174 	SET(besta);
    175 	best = -1;
    176 	for(s=0; s < nscreens; s++) {
    177 		if(!screens[s]->showing)
    178 			continue;
    179 		isect = rect_intersection(r, screens[s]->r);
    180 		a = area(isect);
    181 		if(best < 0 || a > besta) {
    182 			besta = a;
    183 			best = s;
    184 		}
    185 	}
    186 	return best;
    187 }
    188