Change to the linux kernel coding style
[wmaker-crm.git] / src / xinerama.c
Commit [+]AuthorDateLineData
cf7859d1 kojima2002-02-16 04:53:33 +00001/*
2 * Window Maker window manager
6830b057 dan2004-10-12 21:28:27 +00003 *
5dbb770a kojima2003-06-04 18:57:03 +00004 * Copyright (c) 1997-2003 Alfredo K. Kojima
6830b057 dan2004-10-12 21:28:27 +00005 *
cf7859d1 kojima2002-02-16 04:53:33 +00006 * 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.
10 *
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.
15 *
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
6830b057 dan2004-10-12 21:28:27 +000018 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
cf7859d1 kojima2002-02-16 04:53:33 +000019 * USA.
20 */
21
cf7859d1 kojima2002-02-16 04:53:33 +000022#include "wconfig.h"
23
cf7859d1 kojima2002-02-16 04:53:33 +000024#include "xinerama.h"
25
26#include "screen.h"
27#include "window.h"
28#include "framewin.h"
29#include "wcore.h"
a10214a5 kojima2002-11-28 22:04:07 +000030#include "funcs.h"
cf7859d1 kojima2002-02-16 04:53:33 +000031
a10214a5 kojima2002-11-28 22:04:07 +000032#ifdef XINERAMA
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020033# ifdef SOLARIS_XINERAMA /* sucks */
ed0d234d kojima2003-06-04 20:40:00 +000034# include <X11/extensions/xinerama.h>
5dbb770a kojima2003-06-04 18:57:03 +000035# else
36# include <X11/extensions/Xinerama.h>
37# endif
a10214a5 kojima2002-11-28 22:04:07 +000038#endif
cf7859d1 kojima2002-02-16 04:53:33 +000039
27a396d7 dan2003-06-06 04:11:00 +000040extern WPreferences wPreferences;
5dbb770a kojima2003-06-04 18:57:03 +000041
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020042void wInitXinerama(WScreen * scr)
cf7859d1 kojima2002-02-16 04:53:33 +000043{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020044 scr->xine_info.primary_head = 0;
45 scr->xine_info.screens = NULL;
46 scr->xine_info.count = 0;
a10214a5 kojima2002-11-28 22:04:07 +000047#ifdef XINERAMA
5dbb770a kojima2003-06-04 18:57:03 +000048# ifdef SOLARIS_XINERAMA
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020049 if (XineramaGetState(dpy, scr->screen)) {
50 WXineramaInfo *info = &scr->xine_info;
51 XRectangle head[MAXFRAMEBUFFERS];
52 unsigned char hints[MAXFRAMEBUFFERS];
53 int i;
54
55 if (XineramaGetInfo(dpy, scr->screen, head, hints, &info->count)) {
56
57 info->screens = wmalloc(sizeof(WMRect) * (info->count + 1));
58
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;
64 }
65 }
66 }
67# else /* !SOLARIS_XINERAMA */
68 if (XineramaIsActive(dpy)) {
69 XineramaScreenInfo *xine_screens;
70 WXineramaInfo *info = &scr->xine_info;
71 int i;
72
73 xine_screens = XineramaQueryScreens(dpy, &info->count);
74
75 info->screens = wmalloc(sizeof(WMRect) * (info->count + 1));
76
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;
82 }
83 XFree(xine_screens);
84 }
85# endif /* !SOLARIS_XINERAMA */
86#endif /* XINERAMA */
cf7859d1 kojima2002-02-16 04:53:33 +000087}
88
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020089int wGetRectPlacementInfo(WScreen * scr, WMRect rect, int *flags)
cf7859d1 kojima2002-02-16 04:53:33 +000090{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020091 int best;
92 unsigned long area, totalArea;
93 int i;
94 int rx = rect.pos.x;
95 int ry = rect.pos.y;
96 int rw = rect.size.width;
97 int rh = rect.size.height;
98
99 wassertrv(flags != NULL, 0);
100
101 best = -1;
102 area = 0;
103 totalArea = 0;
104
105 *flags = XFLAG_NONE;
106
107 if (scr->xine_info.count <= 1) {
108 unsigned long a;
109
110 a = calcIntersectionArea(rx, ry, rw, rh, 0, 0, scr->scr_width, scr->scr_height);
111
112 if (a == 0) {
113 *flags |= XFLAG_DEAD;
114 } else if (a != rw * rh) {
115 *flags |= XFLAG_PARTIAL;
116 }
117
118 return scr->xine_info.primary_head;
119 }
120
121 for (i = 0; i < wXineramaHeads(scr); i++) {
122 unsigned long a;
123
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);
129
130 totalArea += a;
131 if (a > area) {
132 if (best != -1)
133 *flags |= XFLAG_MULTIPLE;
134 area = a;
135 best = i;
136 }
137 }
138
139 if (best == -1) {
140 *flags |= XFLAG_DEAD;
141 best = wGetHeadForPointerLocation(scr);
142 } else if (totalArea != rw * rh)
143 *flags |= XFLAG_PARTIAL;
144
145 return best;
cf7859d1 kojima2002-02-16 04:53:33 +0000146}
6830b057 dan2004-10-12 21:28:27 +0000147
cf7859d1 kojima2002-02-16 04:53:33 +0000148/* get the head that covers most of the rectangle */
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200149int wGetHeadForRect(WScreen * scr, WMRect rect)
cf7859d1 kojima2002-02-16 04:53:33 +0000150{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200151 int best;
152 unsigned long area;
153 int i;
154 int rx = rect.pos.x;
155 int ry = rect.pos.y;
156 int rw = rect.size.width;
157 int rh = rect.size.height;
158
159 if (!scr->xine_info.count)
160 return scr->xine_info.primary_head;
161
162 best = -1;
163 area = 0;
164
165 for (i = 0; i < wXineramaHeads(scr); i++) {
166 unsigned long a;
167
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);
173
174 if (a > area) {
175 area = a;
176 best = i;
177 }
178 }
179
180 /*
181 * in case rect is in dead space, return valid head
182 */
183 if (best == -1)
184 best = wGetHeadForPointerLocation(scr);
185
186 return best;
187}
cf7859d1 kojima2002-02-16 04:53:33 +0000188
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200189Bool wWindowTouchesHead(WWindow * wwin, int head)
190{
191 WScreen *scr;
192 WMRect rect;
193 int a;
a10214a5 kojima2002-11-28 22:04:07 +0000194
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200195 if (!wwin || !wwin->frame)
196 return False;
cf7859d1 kojima2002-02-16 04:53:33 +0000197
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200198 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);
cf7859d1 kojima2002-02-16 04:53:33 +0000204
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200205 return (a != 0);
27a396d7 dan2003-06-06 04:11:00 +0000206}
207
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200208int wGetHeadForWindow(WWindow * wwin)
cf7859d1 kojima2002-02-16 04:53:33 +0000209{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200210 WMRect rect;
cf7859d1 kojima2002-02-16 04:53:33 +0000211
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200212 if (wwin == NULL || wwin->frame == NULL)
213 return 0;
27a396d7 dan2003-06-06 04:11:00 +0000214
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200215 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;
cf7859d1 kojima2002-02-16 04:53:33 +0000219
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200220 return wGetHeadForRect(wwin->screen_ptr, rect);
cf7859d1 kojima2002-02-16 04:53:33 +0000221}
222
a10214a5 kojima2002-11-28 22:04:07 +0000223/*
193a6351 dan2004-10-23 03:30:03 +0000224int
225wGetHeadForPoint(WScreen *scr, WMPoint point, int *flags)
226{
227 int i;
228
229 // paranoia
230 if (flags == NULL) {
231 static int tmp;
232 flags = &tmp;
233 }
234 *flags = XFLAG_NONE;
235
236 for (i = 0; i < scr->xine_info.count; i++) {
237#if 0
238 int yy, xx;
239
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) {
245 return i;
246 }
247#else
248 XineramaScreenInfo *xsi = &scr->xine_info.screens[i];
249
250 if ((unsigned)(point.x - xsi->x_org) < xsi->width &&
251 (unsigned)(point.y - xsi->y_org) < xsi->height)
252 return i;
253#endif
254 }
255
256 *flags |= XFLAG_DEAD;
257
258 return scr->xine_primary_head;
259}
260*/
a10214a5 kojima2002-11-28 22:04:07 +0000261
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200262int wGetHeadForPoint(WScreen * scr, WMPoint point)
a10214a5 kojima2002-11-28 22:04:07 +0000263{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200264 int i;
a10214a5 kojima2002-11-28 22:04:07 +0000265
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200266 for (i = 0; i < scr->xine_info.count; i++) {
267 WMRect *rect = &scr->xine_info.screens[i];
a10214a5 kojima2002-11-28 22:04:07 +0000268
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200269 if ((unsigned)(point.x - rect->pos.x) < rect->size.width &&
270 (unsigned)(point.y - rect->pos.y) < rect->size.height)
271 return i;
272 }
273 return scr->xine_info.primary_head;
a10214a5 kojima2002-11-28 22:04:07 +0000274}
cf7859d1 kojima2002-02-16 04:53:33 +0000275
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200276int wGetHeadForPointerLocation(WScreen * scr)
cf7859d1 kojima2002-02-16 04:53:33 +0000277{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200278 WMPoint point;
279 Window bla;
280 int ble;
281 unsigned int blo;
cf7859d1 kojima2002-02-16 04:53:33 +0000282
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200283 if (!scr->xine_info.count)
284 return scr->xine_info.primary_head;
39d25088 dan2002-12-02 03:44:10 +0000285
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200286 if (!XQueryPointer(dpy, scr->root_win, &bla, &bla, &point.x, &point.y, &ble, &ble, &blo))
287 return scr->xine_info.primary_head;
cf7859d1 kojima2002-02-16 04:53:33 +0000288
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200289 return wGetHeadForPoint(scr, point);
cf7859d1 kojima2002-02-16 04:53:33 +0000290}
291
292/* get the dimensions of the head */
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200293WMRect wGetRectForHead(WScreen * scr, int head)
cf7859d1 kojima2002-02-16 04:53:33 +0000294{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200295 WMRect rect;
296
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;
302 } else {
303 rect.pos.x = 0;
304 rect.pos.y = 0;
305 rect.size.width = scr->scr_width;
306 rect.size.height = scr->scr_height;
307 }
308
309 return rect;
cf7859d1 kojima2002-02-16 04:53:33 +0000310}
311
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200312WArea wGetUsableAreaForHead(WScreen * scr, int head, WArea * totalAreaPtr, Bool noicons)
cf7859d1 kojima2002-02-16 04:53:33 +0000313{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200314 WArea totalArea, usableArea;
315 WMRect rect = wGetRectForHead(scr, head);
1e922744 dan2002-10-16 04:05:45 +0000316
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200317 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;
1e922744 dan2002-10-16 04:05:45 +0000321
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200322 if (totalAreaPtr != NULL)
323 *totalAreaPtr = totalArea;
a10214a5 kojima2002-11-28 22:04:07 +0000324
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200325 if (head < wXineramaHeads(scr)) {
326 usableArea = noicons ? scr->totalUsableArea[head] : scr->usableArea[head];
327 } else
328 usableArea = totalArea;
a10214a5 kojima2002-11-28 22:04:07 +0000329
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200330 return usableArea;
a10214a5 kojima2002-11-28 22:04:07 +0000331}
332
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200333WMPoint wGetPointToCenterRectInHead(WScreen * scr, int head, int width, int height)
a10214a5 kojima2002-11-28 22:04:07 +0000334{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200335 WMPoint p;
336 WMRect rect = wGetRectForHead(scr, head);
a10214a5 kojima2002-11-28 22:04:07 +0000337
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200338 p.x = rect.pos.x + (rect.size.width - width) / 2;
339 p.y = rect.pos.y + (rect.size.height - height) / 2;
a10214a5 kojima2002-11-28 22:04:07 +0000340
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200341 return p;
cf7859d1 kojima2002-02-16 04:53:33 +0000342}