2 * Window Maker window manager
4 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
33 # ifdef SOLARIS_XINERAMA /* sucks */
34 # include <X11/extensions/xinerama.h>
36 # include <X11/extensions/Xinerama.h>
40 extern WPreferences wPreferences;
42 void wInitXinerama(WScreen * scr)
44 scr->xine_info.primary_head = 0;
45 scr->xine_info.screens = NULL;
46 scr->xine_info.count = 0;
48 # ifdef SOLARIS_XINERAMA
49 if (XineramaGetState(dpy, scr->screen)) {
50 WXineramaInfo *info = &scr->xine_info;
51 XRectangle head[MAXFRAMEBUFFERS];
52 unsigned char hints[MAXFRAMEBUFFERS];
55 if (XineramaGetInfo(dpy, scr->screen, head, hints, &info->count)) {
57 info->screens = wmalloc(sizeof(WMRect) * (info->count + 1));
59 for (i = 0; i < info->count; i++) {
60 info->screens[i].pos.x = head[i].x;
61 info->screens[i].pos.y = head[i].y;
62 info->screens[i].size.width = head[i].width;
63 info->screens[i].size.height = head[i].height;
67 # else /* !SOLARIS_XINERAMA */
68 if (XineramaIsActive(dpy)) {
69 XineramaScreenInfo *xine_screens;
70 WXineramaInfo *info = &scr->xine_info;
73 xine_screens = XineramaQueryScreens(dpy, &info->count);
75 info->screens = wmalloc(sizeof(WMRect) * (info->count + 1));
77 for (i = 0; i < info->count; i++) {
78 info->screens[i].pos.x = xine_screens[i].x_org;
79 info->screens[i].pos.y = xine_screens[i].y_org;
80 info->screens[i].size.width = xine_screens[i].width;
81 info->screens[i].size.height = xine_screens[i].height;
85 # endif /* !SOLARIS_XINERAMA */
89 int wGetRectPlacementInfo(WScreen * scr, WMRect rect, int *flags)
92 unsigned long area, totalArea;
96 int rw = rect.size.width;
97 int rh = rect.size.height;
99 wassertrv(flags != NULL, 0);
107 if (scr->xine_info.count <= 1) {
110 a = calcIntersectionArea(rx, ry, rw, rh, 0, 0, scr->scr_width, scr->scr_height);
113 *flags |= XFLAG_DEAD;
114 } else if (a != rw * rh) {
115 *flags |= XFLAG_PARTIAL;
118 return scr->xine_info.primary_head;
121 for (i = 0; i < wXineramaHeads(scr); i++) {
124 a = calcIntersectionArea(rx, ry, rw, rh,
125 scr->xine_info.screens[i].pos.x,
126 scr->xine_info.screens[i].pos.y,
127 scr->xine_info.screens[i].size.width,
128 scr->xine_info.screens[i].size.height);
133 *flags |= XFLAG_MULTIPLE;
140 *flags |= XFLAG_DEAD;
141 best = wGetHeadForPointerLocation(scr);
142 } else if (totalArea != rw * rh)
143 *flags |= XFLAG_PARTIAL;
148 /* get the head that covers most of the rectangle */
149 int wGetHeadForRect(WScreen * scr, WMRect rect)
156 int rw = rect.size.width;
157 int rh = rect.size.height;
159 if (!scr->xine_info.count)
160 return scr->xine_info.primary_head;
165 for (i = 0; i < wXineramaHeads(scr); i++) {
168 a = calcIntersectionArea(rx, ry, rw, rh,
169 scr->xine_info.screens[i].pos.x,
170 scr->xine_info.screens[i].pos.y,
171 scr->xine_info.screens[i].size.width,
172 scr->xine_info.screens[i].size.height);
181 * in case rect is in dead space, return valid head
184 best = wGetHeadForPointerLocation(scr);
189 Bool wWindowTouchesHead(WWindow * wwin, int head)
195 if (!wwin || !wwin->frame)
198 scr = wwin->screen_ptr;
199 rect = wGetRectForHead(scr, head);
200 a = calcIntersectionArea(wwin->frame_x, wwin->frame_y,
201 wwin->frame->core->width,
202 wwin->frame->core->height,
203 rect.pos.x, rect.pos.y, rect.size.width, rect.size.height);
208 int wGetHeadForWindow(WWindow * wwin)
212 if (wwin == NULL || wwin->frame == NULL)
215 rect.pos.x = wwin->frame_x;
216 rect.pos.y = wwin->frame_y;
217 rect.size.width = wwin->frame->core->width;
218 rect.size.height = wwin->frame->core->height;
220 return wGetHeadForRect(wwin->screen_ptr, rect);
225 wGetHeadForPoint(WScreen *scr, WMPoint point, int *flags)
236 for (i = 0; i < scr->xine_info.count; i++) {
240 xx = scr->xine_info.screens[i].pos.x + scr->xine_info.screens[i].size.width;
241 yy = scr->xine_info.screens[i].pos.y + scr->xine_info.screens[i].size.height;
242 if (point.x >= scr->xine_info.screens[i].pos.x &&
243 point.y >= scr->xine_info.screens[i].pos.y &&
244 point.x < xx && point.y < yy) {
248 XineramaScreenInfo *xsi = &scr->xine_info.screens[i];
250 if ((unsigned)(point.x - xsi->x_org) < xsi->width &&
251 (unsigned)(point.y - xsi->y_org) < xsi->height)
256 *flags |= XFLAG_DEAD;
258 return scr->xine_primary_head;
262 int wGetHeadForPoint(WScreen * scr, WMPoint point)
266 for (i = 0; i < scr->xine_info.count; i++) {
267 WMRect *rect = &scr->xine_info.screens[i];
269 if ((unsigned)(point.x - rect->pos.x) < rect->size.width &&
270 (unsigned)(point.y - rect->pos.y) < rect->size.height)
273 return scr->xine_info.primary_head;
276 int wGetHeadForPointerLocation(WScreen * scr)
283 if (!scr->xine_info.count)
284 return scr->xine_info.primary_head;
286 if (!XQueryPointer(dpy, scr->root_win, &bla, &bla, &point.x, &point.y, &ble, &ble, &blo))
287 return scr->xine_info.primary_head;
289 return wGetHeadForPoint(scr, point);
292 /* get the dimensions of the head */
293 WMRect wGetRectForHead(WScreen * scr, int head)
297 if (head < scr->xine_info.count) {
298 rect.pos.x = scr->xine_info.screens[head].pos.x;
299 rect.pos.y = scr->xine_info.screens[head].pos.y;
300 rect.size.width = scr->xine_info.screens[head].size.width;
301 rect.size.height = scr->xine_info.screens[head].size.height;
305 rect.size.width = scr->scr_width;
306 rect.size.height = scr->scr_height;
312 WArea wGetUsableAreaForHead(WScreen * scr, int head, WArea * totalAreaPtr, Bool noicons)
314 WArea totalArea, usableArea;
315 WMRect rect = wGetRectForHead(scr, head);
317 totalArea.x1 = rect.pos.x;
318 totalArea.y1 = rect.pos.y;
319 totalArea.x2 = totalArea.x1 + rect.size.width;
320 totalArea.y2 = totalArea.y1 + rect.size.height;
322 if (totalAreaPtr != NULL)
323 *totalAreaPtr = totalArea;
325 if (head < wXineramaHeads(scr)) {
326 usableArea = noicons ? scr->totalUsableArea[head] : scr->usableArea[head];
328 usableArea = totalArea;
333 WMPoint wGetPointToCenterRectInHead(WScreen * scr, int head, int width, int height)
336 WMRect rect = wGetRectForHead(scr, head);
338 p.x = rect.pos.x + (rect.size.width - width) / 2;
339 p.y = rect.pos.y + (rect.size.height - height) / 2;