+#if 0
+Rect* screen_area_all_monitors(guint desktop)
+{
+ guint i;
+ Rect *a;
+
+ a = screen_area_monitor(desktop, 0);
+
+ /* combine all the monitors together */
+ for (i = 1; i < screen_num_monitors; ++i) {
+ Rect *m = screen_area_monitor(desktop, i);
+ gint l, r, t, b;
+
+ l = MIN(RECT_LEFT(*a), RECT_LEFT(*m));
+ t = MIN(RECT_TOP(*a), RECT_TOP(*m));
+ r = MAX(RECT_RIGHT(*a), RECT_RIGHT(*m));
+ b = MAX(RECT_BOTTOM(*a), RECT_BOTTOM(*m));
+
+ RECT_SET(*a, l, t, r - l + 1, b - t + 1);
+
+ g_free(m);
+ }
+
+ return a;
+}
+#endif
+
+#define STRUT_LEFT_IN_SEARCH(s, search) \
+ (RANGES_INTERSECT(search->y, search->height, \
+ s->left_start, s->left_end - s->left_start + 1))
+#define STRUT_RIGHT_IN_SEARCH(s, search) \
+ (RANGES_INTERSECT(search->y, search->height, \
+ s->right_start, s->right_end - s->right_start + 1))
+#define STRUT_TOP_IN_SEARCH(s, search) \
+ (RANGES_INTERSECT(search->x, search->width, \
+ s->top_start, s->top_end - s->top_start + 1))
+#define STRUT_BOTTOM_IN_SEARCH(s, search) \
+ (RANGES_INTERSECT(search->x, search->width, \
+ s->bottom_start, s->bottom_end - s->bottom_start + 1))
+
+#define STRUT_LEFT_IGNORE(s, us, search) \
+ (head == SCREEN_AREA_ALL_MONITORS && us && \
+ RECT_LEFT(monitor_area[i]) + s->left > RECT_LEFT(*search))
+#define STRUT_RIGHT_IGNORE(s, us, search) \
+ (head == SCREEN_AREA_ALL_MONITORS && us && \
+ RECT_RIGHT(monitor_area[i]) - s->right < RECT_RIGHT(*search))
+#define STRUT_TOP_IGNORE(s, us, search) \
+ (head == SCREEN_AREA_ALL_MONITORS && us && \
+ RECT_TOP(monitor_area[i]) + s->top > RECT_TOP(*search))
+#define STRUT_BOTTOM_IGNORE(s, us, search) \
+ (head == SCREEN_AREA_ALL_MONITORS && us && \
+ RECT_BOTTOM(monitor_area[i]) - s->bottom < RECT_BOTTOM(*search))
+
+Rect* screen_area(guint desktop, guint head, Rect *search)
+{
+ Rect *a;
+ GSList *it;
+ gint l, r, t, b;
+ guint i, d;
+ gboolean us = search != NULL; /* user provided search */
+
+ g_assert(desktop < screen_num_desktops || desktop == DESKTOP_ALL);
+ g_assert(head < screen_num_monitors || head == SCREEN_AREA_ONE_MONITOR ||
+ head == SCREEN_AREA_ALL_MONITORS);
+ g_assert(!(head == SCREEN_AREA_ONE_MONITOR && search == NULL));
+
+ /* find any struts for this monitor
+ which will be affecting the search area.
+ */
+
+ /* search everything if search is null */
+ if (!search) {
+ if (head < screen_num_monitors) search = &monitor_area[head];
+ else search = &monitor_area[screen_num_monitors];
+ }
+ if (head == SCREEN_AREA_ONE_MONITOR) head = screen_find_monitor(search);
+
+ /* al is "all left" meaning the furthest left you can get, l is our
+ "working left" meaning our current strut edge which we're calculating
+ */
+
+ /* only include monitors which the search area lines up with */
+ if (RECT_INTERSECTS_RECT(monitor_area[screen_num_monitors], *search)) {
+ l = RECT_RIGHT(monitor_area[screen_num_monitors]);
+ t = RECT_BOTTOM(monitor_area[screen_num_monitors]);
+ r = RECT_LEFT(monitor_area[screen_num_monitors]);
+ b = RECT_TOP(monitor_area[screen_num_monitors]);
+ for (i = 0; i < screen_num_monitors; ++i) {
+ /* add the monitor if applicable */
+ if (RANGES_INTERSECT(search->x, search->width,
+ monitor_area[i].x, monitor_area[i].width))
+ {
+ t = MIN(t, RECT_TOP(monitor_area[i]));
+ b = MAX(b, RECT_BOTTOM(monitor_area[i]));
+ }
+ if (RANGES_INTERSECT(search->y, search->height,
+ monitor_area[i].y, monitor_area[i].height))
+ {
+ l = MIN(l, RECT_LEFT(monitor_area[i]));
+ r = MAX(r, RECT_RIGHT(monitor_area[i]));
+ }
+ }
+ } else {
+ l = RECT_LEFT(monitor_area[screen_num_monitors]);
+ t = RECT_TOP(monitor_area[screen_num_monitors]);
+ r = RECT_RIGHT(monitor_area[screen_num_monitors]);
+ b = RECT_BOTTOM(monitor_area[screen_num_monitors]);
+ }
+
+ for (d = 0; d < screen_num_desktops; ++d) {
+ if (d != desktop && desktop != DESKTOP_ALL) continue;
+
+ for (i = 0; i < screen_num_monitors; ++i) {
+ if (head != SCREEN_AREA_ALL_MONITORS && head != i) continue;
+
+ for (it = struts_left; it; it = g_slist_next(it)) {
+ ObScreenStrut *s = it->data;
+ if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
+ STRUT_LEFT_IN_SEARCH(s->strut, search) &&
+ !STRUT_LEFT_IGNORE(s->strut, us, search))
+ l = MAX(l, RECT_LEFT(monitor_area[screen_num_monitors])
+ + s->strut->left);
+ }
+ for (it = struts_top; it; it = g_slist_next(it)) {
+ ObScreenStrut *s = it->data;
+ if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
+ STRUT_TOP_IN_SEARCH(s->strut, search) &&
+ !STRUT_TOP_IGNORE(s->strut, us, search))
+ t = MAX(t, RECT_TOP(monitor_area[screen_num_monitors])
+ + s->strut->top);
+ }
+ for (it = struts_right; it; it = g_slist_next(it)) {
+ ObScreenStrut *s = it->data;
+ if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
+ STRUT_RIGHT_IN_SEARCH(s->strut, search) &&
+ !STRUT_RIGHT_IGNORE(s->strut, us, search))
+ r = MIN(r, RECT_RIGHT(monitor_area[screen_num_monitors])
+ - s->strut->right);
+ }
+ for (it = struts_bottom; it; it = g_slist_next(it)) {
+ ObScreenStrut *s = it->data;
+ if ((s->desktop == d || s->desktop == DESKTOP_ALL) &&
+ STRUT_BOTTOM_IN_SEARCH(s->strut, search) &&
+ !STRUT_BOTTOM_IGNORE(s->strut, us, search))
+ b = MIN(b, RECT_BOTTOM(monitor_area[screen_num_monitors])
+ - s->strut->bottom);
+ }
+
+ /* limit to this monitor */
+ if (head == i) {
+ l = MAX(l, RECT_LEFT(monitor_area[i]));
+ t = MAX(t, RECT_TOP(monitor_area[i]));
+ r = MIN(r, RECT_RIGHT(monitor_area[i]));
+ b = MIN(b, RECT_BOTTOM(monitor_area[i]));
+ }
+ }
+ }
+
+ a = g_slice_new(Rect);
+ a->x = l;
+ a->y = t;
+ a->width = r - l + 1;
+ a->height = b - t + 1;
+ return a;
+}
+
+guint screen_find_monitor(const Rect *search)
+{
+ guint i;
+ guint most = screen_num_monitors;
+ guint mostv = 0;
+
+ for (i = 0; i < screen_num_monitors; ++i) {
+ const Rect *area = screen_physical_area_monitor(i);
+ if (RECT_INTERSECTS_RECT(*area, *search)) {
+ Rect r;
+ guint v;
+
+ RECT_SET_INTERSECTION(r, *area, *search);
+ v = r.width * r.height;
+
+ if (v > mostv) {
+ mostv = v;
+ most = i;
+ }
+ }
+ }
+ return most;
+}
+
+const Rect* screen_physical_area_all_monitors(void)
+{
+ return screen_physical_area_monitor(screen_num_monitors);
+}
+
+const Rect* screen_physical_area_monitor(guint head)
+{
+ g_assert(head <= screen_num_monitors);
+
+ return &monitor_area[head];
+}
+
+gboolean screen_physical_area_monitor_contains(guint head, Rect *search)
+{
+ g_assert(head <= screen_num_monitors);
+ g_assert(search);
+ return RECT_INTERSECTS_RECT(monitor_area[head], *search);
+}
+
+guint screen_monitor_active(void)