- Fixed Window Maker to compile with xinerama disabled.
[wmaker-crm.git] / src / xinerama.c
bloba7e3c47ad61f7e325d15bb948c10542275628325
1 /*
2 * Window Maker window manager
3 *
4 * Copyright (c) 1997-2001 Alfredo K. Kojima
5 *
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.
23 #include "wconfig.h"
26 #include "xinerama.h"
28 #include "screen.h"
29 #include "window.h"
30 #include "framewin.h"
31 #include "wcore.h"
32 #include "funcs.h"
34 #ifdef XINERAMA
35 #include <X11/extensions/Xinerama.h>
36 #endif
38 void
39 wInitXinerama(WScreen *scr)
41 scr->xine_primary_head = 0;
42 #ifdef XINERAMA
43 scr->xine_screens = XineramaQueryScreens(dpy, &scr->xine_count);
44 #else
45 scr->xine_count = 0;
46 #endif
50 int
51 wGetRectPlacementInfo(WScreen *scr, WMRect rect, int *flags)
53 int best;
54 unsigned long area, totalArea;
55 int i;
56 int rx = rect.pos.x;
57 int ry = rect.pos.y;
58 int rw = rect.size.width;
59 int rh = rect.size.height;
61 wassertrv(flags!=NULL, 0);
63 best = -1;
64 area = 0;
65 totalArea = 0;
67 *flags = XFLAG_NONE;
69 if (scr->xine_count <= 1) {
70 unsigned long a;
72 a = calcIntersectionArea(rx, ry, rw, rh,
73 0, 0, scr->scr_width, scr->scr_height);
75 if (a == 0) {
76 *flags |= XFLAG_DEAD;
77 } else if (a != rw*rh) {
78 *flags |= XFLAG_PARTIAL;
81 return scr->xine_primary_head;
84 #ifdef XINERAMA
85 for (i = 0; i < scr->xine_count; i++) {
86 unsigned long a;
88 a = calcIntersectionArea(rx, ry, rw, rh,
89 scr->xine_screens[i].x_org,
90 scr->xine_screens[i].y_org,
91 scr->xine_screens[i].width,
92 scr->xine_screens[i].height);
94 totalArea += a;
95 if (a > area) {
96 if ( best != -1)
97 *flags |= XFLAG_MULTIPLE;
98 area = a;
99 best = i;
103 if ( best == -1) {
104 *flags |= XFLAG_DEAD;
105 best = wGetHeadForPointerLocation(scr);
106 } else if ( totalArea != rw*rh)
107 *flags |= XFLAG_PARTIAL;
109 return best;
110 #endif
115 /* get the head that covers most of the rectangle */
117 wGetHeadForRect(WScreen *scr, WMRect rect)
119 #ifdef XINERAMA
120 int best;
121 unsigned long area;
122 int i;
123 int rx = rect.pos.x;
124 int ry = rect.pos.y;
125 int rw = rect.size.width;
126 int rh = rect.size.height;
128 if (!scr->xine_count)
129 return scr->xine_primary_head;
131 best = -1;
132 area = 0;
134 for (i = 0; i < scr->xine_count; i++) {
135 unsigned long a;
137 a = calcIntersectionArea(rx, ry, rw, rh,
138 scr->xine_screens[i].x_org,
139 scr->xine_screens[i].y_org,
140 scr->xine_screens[i].width,
141 scr->xine_screens[i].height);
143 if (a > area) {
144 area = a;
145 best = i;
150 * in case rect is in dead space, return valid head
152 if (best == -1)
153 best = wGetHeadForPointerLocation(scr);
155 return best;
156 #else /* !XINERAMA */
157 return scr->xine_primary_head;
158 #endif /* !XINERAMA */
163 wGetHeadForWindow(WWindow *wwin)
165 WMRect rect;
167 rect.pos.x = wwin->frame_x;
168 rect.pos.y = wwin->frame_y;
169 rect.size.width = wwin->frame->core->width;
170 rect.size.height = wwin->frame->core->height;
172 return wGetHeadForRect(wwin->screen_ptr, rect);
177 int wGetHeadForPoint(WScreen *scr, WMPoint point, int *flags)
179 int i;
181 // paranoia
182 if ( flags == NULL) {
183 static int tmp;
184 flags = &tmp;
186 *flags = XFLAG_NONE;
188 for (i = 0; i < scr->xine_count; i++) {
189 #if 0
190 int yy, xx;
192 xx = scr->xine_screens[i].x_org + scr->xine_screens[i].width;
193 yy = scr->xine_screens[i].y_org + scr->xine_screens[i].height;
194 if (point.x >= scr->xine_screens[i].x_org &&
195 point.y >= scr->xine_screens[i].y_org &&
196 point.x < xx && point.y < yy) {
197 return i;
199 #else
200 XineramaScreenInfo *xsi = &scr->xine_screens[i];
202 if ((unsigned)(point.x - xsi->x_org) < xsi->width &&
203 (unsigned)(point.y - xsi->y_org) < xsi->height)
204 return i;
205 #endif
208 *flags |= XFLAG_DEAD;
210 return scr->xine_primary_head;
217 wGetHeadForPoint(WScreen *scr, WMPoint point)
219 #ifdef XINERAMA
220 int i;
222 for (i = 0; i < scr->xine_count; i++) {
223 XineramaScreenInfo *xsi = &scr->xine_screens[i];
225 if ((unsigned)(point.x - xsi->x_org) < xsi->width &&
226 (unsigned)(point.y - xsi->y_org) < xsi->height)
227 return i;
229 #endif /* XINERAMA */
230 return scr->xine_primary_head;
235 wGetHeadForPointerLocation(WScreen *scr)
237 WMPoint point;
238 Window bla;
239 int ble;
240 unsigned int blo;
242 if (!scr->xine_count)
243 return scr->xine_primary_head;
245 if (!XQueryPointer(dpy, scr->root_win, &bla, &bla,
246 &point.x, &point.y,
247 &ble, &ble,
248 &blo))
249 return scr->xine_primary_head;
251 return wGetHeadForPoint(scr, point);
254 /* get the dimensions of the head */
255 WMRect
256 wGetRectForHead(WScreen *scr, int head)
258 WMRect rect;
260 #ifdef XINERAMA
261 if (head < scr->xine_count) {
262 rect.pos.x = scr->xine_screens[head].x_org;
263 rect.pos.y = scr->xine_screens[head].y_org;
264 rect.size.width = scr->xine_screens[head].width;
265 rect.size.height = scr->xine_screens[head].height;
266 } else
267 #endif /* XINERAMA */
269 rect.pos.x = 0;
270 rect.pos.y = 0;
271 rect.size.width = scr->scr_width;
272 rect.size.height = scr->scr_height;
275 return rect;
280 WArea
281 wGetUsableAreaForHead(WScreen *scr, int head, WArea *totalAreaPtr)
283 WArea totalArea, usableArea = scr->totalUsableArea;
284 WMRect rect = wGetRectForHead(scr, head);
286 totalArea.x1 = rect.pos.x;
287 totalArea.y1 = rect.pos.y;
288 totalArea.x2 = totalArea.x1 + rect.size.width;
289 totalArea.y2 = totalArea.y1 + rect.size.height;
291 if (totalAreaPtr != NULL) *totalAreaPtr = totalArea;
293 usableArea.x1 = WMAX(totalArea.x1, usableArea.x1);
294 usableArea.y1 = WMAX(totalArea.y1, usableArea.y1);
295 usableArea.x2 = WMIN(totalArea.x2, usableArea.x2);
296 usableArea.y2 = WMIN(totalArea.y2, usableArea.y2);
298 return usableArea;
302 WMPoint
303 wGetPointToCenterRectInHead(WScreen *scr, int head, int width, int height)
305 WMPoint p;
306 WMRect rect = wGetRectForHead(scr, head);
308 p.x = rect.pos.x + (rect.size.width - width)/2;
309 p.y = rect.pos.y + (rect.size.height - height)/2;
311 return p;