- Updated WINGs/NEWS with info about hw the API changed how how things
[wmaker-crm.git] / src / xinerama.c
blob92d5330d0e31a57bc1d578c6b82fc0de1f1ed940
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 #ifdef XINERAMA
29 #include "xinerama.h"
31 #include "screen.h"
32 #include "window.h"
33 #include "framewin.h"
34 #include "wcore.h"
36 #include <X11/extensions/Xinerama.h>
39 void wInitXinerama(WScreen *scr)
41 scr->xine_screens = XineramaQueryScreens(dpy, &scr->xine_count);
43 scr->xine_primary_head = 0;
48 * intersect_rectangles-
49 * Calculate the rectangle that results from the intersection of
50 * 2 rectangles.
52 * Returns:
53 * 0 if the rectangles do not intersect, 1 otherwise.
56 typedef struct {
57 int x1, y1, x2, y2;
58 } _Rectangle;
60 int intersect_rectangles(_Rectangle *rect1,
61 _Rectangle *rect2,
62 _Rectangle *result)
64 if (rect1->x1 < rect2->x1)
65 result->x1 = rect2->x1;
66 else
67 result->x1 = rect1->x1;
69 if (rect1->x2 > rect2->x2)
70 result->x2 = rect2->x2;
71 else
72 result->x2 = rect1->x2;
74 if (rect1->y1 < rect2->y1)
75 result->y1 = rect2->y1;
76 else
77 result->y1 = rect1->y1;
79 if (rect1->y2 > rect2->y2)
80 result->y2 = rect2->y2;
81 else
82 result->y2 = rect1->y2;
84 if (result->x2 < result->x1)
85 return 0;
86 if (result->y2 < result->y1)
87 return 0;
89 return 1;
92 static int intersectArea(int x1, int y1, int w1, int h1,
93 int x2, int y2, int w2, int h2)
95 _Rectangle rect1, rect2, result;
97 rect1.x1 = x1;
98 rect1.y1 = y1;
99 rect1.x2 = x1+w1;
100 rect1.y2 = y1+h1;
102 rect2.x1 = x2;
103 rect2.y1 = y2;
104 rect2.x2 = x2+w2;
105 rect2.y2 = y2+h2;
107 if (intersect_rectangles(&rect1, &rect2, &result))
108 return (result.x2-result.x1)*(result.y2-result.y1);
109 else
110 return 0;
114 /* get the head that covers most of the rectangle */
115 int wGetHeadForRect(WScreen *scr, WMRect rect)
117 int best;
118 unsigned long area;
119 int i;
120 int rx = rect.pos.x;
121 int ry = rect.pos.y;
122 int rw = rect.size.width;
123 int rh = rect.size.height;
125 best = -1;
126 area = 0;
128 for (i = 0; i < scr->xine_count; i++) {
129 unsigned long a;
131 a = intersectArea(rx, ry, rw, rh,
132 scr->xine_screens[i].x_org,
133 scr->xine_screens[i].y_org,
134 scr->xine_screens[i].width,
135 scr->xine_screens[i].height);
137 if (a > area) {
138 area = a;
139 best = i;
143 return best;
147 int wGetHeadForWindow(WWindow *wwin)
149 WMRect rect;
151 rect.pos.x = wwin->frame_x;
152 rect.pos.y = wwin->frame_y;
153 rect.size.width = wwin->frame->core->width;
154 rect.size.height = wwin->frame->core->height;
156 return wGetHeadForRect(wwin->screen_ptr, rect);
160 int wGetHeadForPoint(WScreen *scr, WMPoint point)
162 int i;
164 for (i = 0; i < scr->xine_count; i++) {
165 int yy, xx;
167 xx = scr->xine_screens[i].x_org + scr->xine_screens[i].width;
168 yy = scr->xine_screens[i].y_org + scr->xine_screens[i].height;
169 if (point.x >= scr->xine_screens[i].x_org &&
170 point.y >= scr->xine_screens[i].y_org &&
171 point.x < xx && point.y < yy) {
172 return i;
176 return scr->xine_primary_head;
180 int wGetHeadForPointerLocation(WScreen *scr)
182 WMPoint point;
183 Window bla;
184 int ble;
185 unsigned int blo;
188 if (!XQueryPointer(dpy, scr->root_win, &bla, &bla,
189 &point.x, &point.y,
190 &ble, &ble,
191 &blo))
192 return scr->xine_primary_head;
194 return wGetHeadForPoint(scr, point);
197 /* get the dimensions of the head */
198 WMRect
199 wGetRectForHead(WScreen *scr, int head)
201 WMRect rect;
203 if (head < scr->xine_count) {
204 rect.pos.x = scr->xine_screens[head].x_org;
205 rect.pos.y = scr->xine_screens[head].y_org;
206 rect.size.width = scr->xine_screens[head].width;
207 rect.size.height = scr->xine_screens[head].height;
208 } else {
209 rect.pos.x = 0;
210 rect.pos.y = 0;
211 rect.size.width = scr->scr_width;
212 rect.size.height = scr->scr_height;
215 return rect;
219 WMRect
220 wGetUsableRectForHead(WScreen *scr, int head)
222 WMRect rect;
224 if (head < scr->xine_count) {
225 rect.pos.x = scr->xine_screens[head].x_org;
226 rect.pos.y = scr->xine_screens[head].y_org;
227 rect.size.width = scr->xine_screens[head].width;
228 rect.size.height = scr->xine_screens[head].height;
229 } else {
230 rect.pos.x = 0;
231 rect.pos.y = 0;
232 rect.size.width = scr->scr_width;
233 rect.size.height = scr->scr_height;
236 return rect;
239 #endif