Cleanup includes of wcore.h, defaults.h and pixmap.h
[wmaker-crm.git] / src / xinerama.c
blob380a7550af203e1830457b84d8778557637509e9
1 /*
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,
19 * USA.
22 #include "wconfig.h"
24 #include "xinerama.h"
26 #include "screen.h"
27 #include "window.h"
28 #include "framewin.h"
29 #include "funcs.h"
31 #ifdef XINERAMA
32 # ifdef SOLARIS_XINERAMA /* sucks */
33 # include <X11/extensions/xinerama.h>
34 # else
35 # include <X11/extensions/Xinerama.h>
36 # endif
37 #endif
39 extern WPreferences wPreferences;
41 void wInitXinerama(WScreen * scr)
43 scr->xine_info.primary_head = 0;
44 scr->xine_info.screens = NULL;
45 scr->xine_info.count = 0;
46 #ifdef XINERAMA
47 # ifdef SOLARIS_XINERAMA
48 if (XineramaGetState(dpy, scr->screen)) {
49 WXineramaInfo *info = &scr->xine_info;
50 XRectangle head[MAXFRAMEBUFFERS];
51 unsigned char hints[MAXFRAMEBUFFERS];
52 int i;
54 if (XineramaGetInfo(dpy, scr->screen, head, hints, &info->count)) {
56 info->screens = wmalloc(sizeof(WMRect) * (info->count + 1));
58 for (i = 0; i < info->count; i++) {
59 info->screens[i].pos.x = head[i].x;
60 info->screens[i].pos.y = head[i].y;
61 info->screens[i].size.width = head[i].width;
62 info->screens[i].size.height = head[i].height;
66 # else /* !SOLARIS_XINERAMA */
67 if (XineramaIsActive(dpy)) {
68 XineramaScreenInfo *xine_screens;
69 WXineramaInfo *info = &scr->xine_info;
70 int i;
72 xine_screens = XineramaQueryScreens(dpy, &info->count);
74 info->screens = wmalloc(sizeof(WMRect) * (info->count + 1));
76 for (i = 0; i < info->count; i++) {
77 info->screens[i].pos.x = xine_screens[i].x_org;
78 info->screens[i].pos.y = xine_screens[i].y_org;
79 info->screens[i].size.width = xine_screens[i].width;
80 info->screens[i].size.height = xine_screens[i].height;
82 XFree(xine_screens);
84 # endif /* !SOLARIS_XINERAMA */
85 #endif /* XINERAMA */
88 int wGetRectPlacementInfo(WScreen * scr, WMRect rect, int *flags)
90 int best;
91 unsigned long area, totalArea;
92 int i;
93 int rx = rect.pos.x;
94 int ry = rect.pos.y;
95 int rw = rect.size.width;
96 int rh = rect.size.height;
98 wassertrv(flags != NULL, 0);
100 best = -1;
101 area = 0;
102 totalArea = 0;
104 *flags = XFLAG_NONE;
106 if (scr->xine_info.count <= 1) {
107 unsigned long a;
109 a = calcIntersectionArea(rx, ry, rw, rh, 0, 0, scr->scr_width, scr->scr_height);
111 if (a == 0) {
112 *flags |= XFLAG_DEAD;
113 } else if (a != rw * rh) {
114 *flags |= XFLAG_PARTIAL;
117 return scr->xine_info.primary_head;
120 for (i = 0; i < wXineramaHeads(scr); i++) {
121 unsigned long a;
123 a = calcIntersectionArea(rx, ry, rw, rh,
124 scr->xine_info.screens[i].pos.x,
125 scr->xine_info.screens[i].pos.y,
126 scr->xine_info.screens[i].size.width,
127 scr->xine_info.screens[i].size.height);
129 totalArea += a;
130 if (a > area) {
131 if (best != -1)
132 *flags |= XFLAG_MULTIPLE;
133 area = a;
134 best = i;
138 if (best == -1) {
139 *flags |= XFLAG_DEAD;
140 best = wGetHeadForPointerLocation(scr);
141 } else if (totalArea != rw * rh)
142 *flags |= XFLAG_PARTIAL;
144 return best;
147 /* get the head that covers most of the rectangle */
148 int wGetHeadForRect(WScreen * scr, WMRect rect)
150 int best;
151 unsigned long area;
152 int i;
153 int rx = rect.pos.x;
154 int ry = rect.pos.y;
155 int rw = rect.size.width;
156 int rh = rect.size.height;
158 if (!scr->xine_info.count)
159 return scr->xine_info.primary_head;
161 best = -1;
162 area = 0;
164 for (i = 0; i < wXineramaHeads(scr); i++) {
165 unsigned long a;
167 a = calcIntersectionArea(rx, ry, rw, rh,
168 scr->xine_info.screens[i].pos.x,
169 scr->xine_info.screens[i].pos.y,
170 scr->xine_info.screens[i].size.width,
171 scr->xine_info.screens[i].size.height);
173 if (a > area) {
174 area = a;
175 best = i;
180 * in case rect is in dead space, return valid head
182 if (best == -1)
183 best = wGetHeadForPointerLocation(scr);
185 return best;
188 Bool wWindowTouchesHead(WWindow * wwin, int head)
190 WScreen *scr;
191 WMRect rect;
192 int a;
194 if (!wwin || !wwin->frame)
195 return False;
197 scr = wwin->screen_ptr;
198 rect = wGetRectForHead(scr, head);
199 a = calcIntersectionArea(wwin->frame_x, wwin->frame_y,
200 wwin->frame->core->width,
201 wwin->frame->core->height,
202 rect.pos.x, rect.pos.y, rect.size.width, rect.size.height);
204 return (a != 0);
207 int wGetHeadForWindow(WWindow * wwin)
209 WMRect rect;
211 if (wwin == NULL || wwin->frame == NULL)
212 return 0;
214 rect.pos.x = wwin->frame_x;
215 rect.pos.y = wwin->frame_y;
216 rect.size.width = wwin->frame->core->width;
217 rect.size.height = wwin->frame->core->height;
219 return wGetHeadForRect(wwin->screen_ptr, rect);
222 int wGetHeadForPoint(WScreen * scr, WMPoint point)
224 int i;
226 for (i = 0; i < scr->xine_info.count; i++) {
227 WMRect *rect = &scr->xine_info.screens[i];
229 if ((unsigned)(point.x - rect->pos.x) < rect->size.width &&
230 (unsigned)(point.y - rect->pos.y) < rect->size.height)
231 return i;
233 return scr->xine_info.primary_head;
236 int wGetHeadForPointerLocation(WScreen * scr)
238 WMPoint point;
239 Window bla;
240 int ble;
241 unsigned int blo;
243 if (!scr->xine_info.count)
244 return scr->xine_info.primary_head;
246 if (!XQueryPointer(dpy, scr->root_win, &bla, &bla, &point.x, &point.y, &ble, &ble, &blo))
247 return scr->xine_info.primary_head;
249 return wGetHeadForPoint(scr, point);
252 /* get the dimensions of the head */
253 WMRect wGetRectForHead(WScreen * scr, int head)
255 WMRect rect;
257 if (head < scr->xine_info.count) {
258 rect.pos.x = scr->xine_info.screens[head].pos.x;
259 rect.pos.y = scr->xine_info.screens[head].pos.y;
260 rect.size.width = scr->xine_info.screens[head].size.width;
261 rect.size.height = scr->xine_info.screens[head].size.height;
262 } else {
263 rect.pos.x = 0;
264 rect.pos.y = 0;
265 rect.size.width = scr->scr_width;
266 rect.size.height = scr->scr_height;
269 return rect;
272 WArea wGetUsableAreaForHead(WScreen * scr, int head, WArea * totalAreaPtr, Bool noicons)
274 WArea totalArea, usableArea;
275 WMRect rect = wGetRectForHead(scr, head);
277 totalArea.x1 = rect.pos.x;
278 totalArea.y1 = rect.pos.y;
279 totalArea.x2 = totalArea.x1 + rect.size.width;
280 totalArea.y2 = totalArea.y1 + rect.size.height;
282 if (totalAreaPtr != NULL)
283 *totalAreaPtr = totalArea;
285 if (head < wXineramaHeads(scr)) {
286 usableArea = noicons ? scr->totalUsableArea[head] : scr->usableArea[head];
287 } else
288 usableArea = totalArea;
290 return usableArea;
293 WMPoint wGetPointToCenterRectInHead(WScreen * scr, int head, int width, int height)
295 WMPoint p;
296 WMRect rect = wGetRectForHead(scr, head);
298 p.x = rect.pos.x + (rect.size.width - width) / 2;
299 p.y = rect.pos.y + (rect.size.height - height) / 2;
301 return p;