Icon: Replace code by call to helper function in wIconCreateWithIconFile
[wmaker-crm.git] / src / xinerama.c
blob823df997054c712ea7a79642e601c28163440b81
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 along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "wconfig.h"
23 #include "xinerama.h"
25 #include "screen.h"
26 #include "window.h"
27 #include "framewin.h"
28 #include "funcs.h"
30 #ifdef XINERAMA
31 # ifdef SOLARIS_XINERAMA /* sucks */
32 # include <X11/extensions/xinerama.h>
33 # else
34 # include <X11/extensions/Xinerama.h>
35 # endif
36 #endif
38 void wInitXinerama(WScreen * scr)
40 scr->xine_info.primary_head = 0;
41 scr->xine_info.screens = NULL;
42 scr->xine_info.count = 0;
43 #ifdef XINERAMA
44 # ifdef SOLARIS_XINERAMA
45 if (XineramaGetState(dpy, scr->screen)) {
46 WXineramaInfo *info = &scr->xine_info;
47 XRectangle head[MAXFRAMEBUFFERS];
48 unsigned char hints[MAXFRAMEBUFFERS];
49 int i;
51 if (XineramaGetInfo(dpy, scr->screen, head, hints, &info->count)) {
53 info->screens = wmalloc(sizeof(WMRect) * (info->count + 1));
55 for (i = 0; i < info->count; i++) {
56 info->screens[i].pos.x = head[i].x;
57 info->screens[i].pos.y = head[i].y;
58 info->screens[i].size.width = head[i].width;
59 info->screens[i].size.height = head[i].height;
63 # else /* !SOLARIS_XINERAMA */
64 if (XineramaIsActive(dpy)) {
65 XineramaScreenInfo *xine_screens;
66 WXineramaInfo *info = &scr->xine_info;
67 int i;
69 xine_screens = XineramaQueryScreens(dpy, &info->count);
71 info->screens = wmalloc(sizeof(WMRect) * (info->count + 1));
73 for (i = 0; i < info->count; i++) {
74 info->screens[i].pos.x = xine_screens[i].x_org;
75 info->screens[i].pos.y = xine_screens[i].y_org;
76 info->screens[i].size.width = xine_screens[i].width;
77 info->screens[i].size.height = xine_screens[i].height;
79 XFree(xine_screens);
81 # endif /* !SOLARIS_XINERAMA */
82 #endif /* XINERAMA */
85 int wGetRectPlacementInfo(WScreen * scr, WMRect rect, int *flags)
87 int best;
88 unsigned long area, totalArea;
89 int i;
90 int rx = rect.pos.x;
91 int ry = rect.pos.y;
92 int rw = rect.size.width;
93 int rh = rect.size.height;
95 wassertrv(flags != NULL, 0);
97 best = -1;
98 area = 0;
99 totalArea = 0;
101 *flags = XFLAG_NONE;
103 if (scr->xine_info.count <= 1) {
104 unsigned long a;
106 a = calcIntersectionArea(rx, ry, rw, rh, 0, 0, scr->scr_width, scr->scr_height);
108 if (a == 0) {
109 *flags |= XFLAG_DEAD;
110 } else if (a != rw * rh) {
111 *flags |= XFLAG_PARTIAL;
114 return scr->xine_info.primary_head;
117 for (i = 0; i < wXineramaHeads(scr); i++) {
118 unsigned long a;
120 a = calcIntersectionArea(rx, ry, rw, rh,
121 scr->xine_info.screens[i].pos.x,
122 scr->xine_info.screens[i].pos.y,
123 scr->xine_info.screens[i].size.width,
124 scr->xine_info.screens[i].size.height);
126 totalArea += a;
127 if (a > area) {
128 if (best != -1)
129 *flags |= XFLAG_MULTIPLE;
130 area = a;
131 best = i;
135 if (best == -1) {
136 *flags |= XFLAG_DEAD;
137 best = wGetHeadForPointerLocation(scr);
138 } else if (totalArea != rw * rh)
139 *flags |= XFLAG_PARTIAL;
141 return best;
144 /* get the head that covers most of the rectangle */
145 int wGetHeadForRect(WScreen * scr, WMRect rect)
147 int best;
148 unsigned long area;
149 int i;
150 int rx = rect.pos.x;
151 int ry = rect.pos.y;
152 int rw = rect.size.width;
153 int rh = rect.size.height;
155 if (!scr->xine_info.count)
156 return scr->xine_info.primary_head;
158 best = -1;
159 area = 0;
161 for (i = 0; i < wXineramaHeads(scr); i++) {
162 unsigned long a;
164 a = calcIntersectionArea(rx, ry, rw, rh,
165 scr->xine_info.screens[i].pos.x,
166 scr->xine_info.screens[i].pos.y,
167 scr->xine_info.screens[i].size.width,
168 scr->xine_info.screens[i].size.height);
170 if (a > area) {
171 area = a;
172 best = i;
177 * in case rect is in dead space, return valid head
179 if (best == -1)
180 best = wGetHeadForPointerLocation(scr);
182 return best;
185 Bool wWindowTouchesHead(WWindow * wwin, int head)
187 WScreen *scr;
188 WMRect rect;
189 int a;
191 if (!wwin || !wwin->frame)
192 return False;
194 scr = wwin->screen_ptr;
195 rect = wGetRectForHead(scr, head);
196 a = calcIntersectionArea(wwin->frame_x, wwin->frame_y,
197 wwin->frame->core->width,
198 wwin->frame->core->height,
199 rect.pos.x, rect.pos.y, rect.size.width, rect.size.height);
201 return (a != 0);
204 int wGetHeadForWindow(WWindow * wwin)
206 WMRect rect;
208 if (wwin == NULL || wwin->frame == NULL)
209 return 0;
211 rect.pos.x = wwin->frame_x;
212 rect.pos.y = wwin->frame_y;
213 rect.size.width = wwin->frame->core->width;
214 rect.size.height = wwin->frame->core->height;
216 return wGetHeadForRect(wwin->screen_ptr, rect);
219 int wGetHeadForPoint(WScreen * scr, WMPoint point)
221 int i;
223 for (i = 0; i < scr->xine_info.count; i++) {
224 WMRect *rect = &scr->xine_info.screens[i];
226 if ((unsigned)(point.x - rect->pos.x) < rect->size.width &&
227 (unsigned)(point.y - rect->pos.y) < rect->size.height)
228 return i;
230 return scr->xine_info.primary_head;
233 int wGetHeadForPointerLocation(WScreen * scr)
235 WMPoint point;
236 Window bla;
237 int ble;
238 unsigned int blo;
240 if (!scr->xine_info.count)
241 return scr->xine_info.primary_head;
243 if (!XQueryPointer(dpy, scr->root_win, &bla, &bla, &point.x, &point.y, &ble, &ble, &blo))
244 return scr->xine_info.primary_head;
246 return wGetHeadForPoint(scr, point);
249 /* get the dimensions of the head */
250 WMRect wGetRectForHead(WScreen * scr, int head)
252 WMRect rect;
254 if (head < scr->xine_info.count) {
255 rect.pos.x = scr->xine_info.screens[head].pos.x;
256 rect.pos.y = scr->xine_info.screens[head].pos.y;
257 rect.size.width = scr->xine_info.screens[head].size.width;
258 rect.size.height = scr->xine_info.screens[head].size.height;
259 } else {
260 rect.pos.x = 0;
261 rect.pos.y = 0;
262 rect.size.width = scr->scr_width;
263 rect.size.height = scr->scr_height;
266 return rect;
269 WArea wGetUsableAreaForHead(WScreen * scr, int head, WArea * totalAreaPtr, Bool noicons)
271 WArea totalArea, usableArea;
272 WMRect rect = wGetRectForHead(scr, head);
274 totalArea.x1 = rect.pos.x;
275 totalArea.y1 = rect.pos.y;
276 totalArea.x2 = totalArea.x1 + rect.size.width;
277 totalArea.y2 = totalArea.y1 + rect.size.height;
279 if (totalAreaPtr != NULL)
280 *totalAreaPtr = totalArea;
282 if (head < wXineramaHeads(scr)) {
283 usableArea = noicons ? scr->totalUsableArea[head] : scr->usableArea[head];
284 } else
285 usableArea = totalArea;
287 return usableArea;
290 WMPoint wGetPointToCenterRectInHead(WScreen * scr, int head, int width, int height)
292 WMPoint p;
293 WMRect rect = wGetRectForHead(scr, head);
295 p.x = rect.pos.x + (rect.size.width - width) / 2;
296 p.y = rect.pos.y + (rect.size.height - height) / 2;
298 return p;