os: Add CryptoAPI as a choice of SHA1 implementation
[xserver/hramrach.git] / randr / rrxinerama.c
blobaa8a61eee1d0428d88b41ed5ca2d742210b70493
1 /*
2 * Copyright © 2006 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
23 * This Xinerama implementation comes from the SiS driver which has
24 * the following notice:
26 /*
27 * SiS driver main code
29 * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 * 1) Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2) Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3) The name of the author may not be used to endorse or promote products
40 * derived from this software without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
44 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
45 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
46 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
48 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
49 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
51 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 * Author: Thomas Winischhofer <thomas@winischhofer.net>
54 * - driver entirely rewritten since 2001, only basic structure taken from
55 * old code (except sis_dri.c, sis_shadow.c, sis_accel.c and parts of
56 * sis_dga.c; these were mostly taken over; sis_dri.c was changed for
57 * new versions of the DRI layer)
59 * This notice covers the entire driver code unless indicated otherwise.
61 * Formerly based on code which was
62 * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
63 * Written by:
64 * Alan Hourihane <alanh@fairlite.demon.co.uk>,
65 * Mike Chapman <mike@paranoia.com>,
66 * Juanjo Santamarta <santamarta@ctv.es>,
67 * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
68 * David Thomas <davtom@dream.org.uk>.
71 #include "randrstr.h"
72 #include "swaprep.h"
73 #include <X11/extensions/panoramiXproto.h>
74 #include "protocol-versions.h"
76 /* Xinerama is not multi-screen capable; just report about screen 0 */
77 #define RR_XINERAMA_SCREEN 0
79 static int ProcRRXineramaQueryVersion(ClientPtr client);
80 static int ProcRRXineramaGetState(ClientPtr client);
81 static int ProcRRXineramaGetScreenCount(ClientPtr client);
82 static int ProcRRXineramaGetScreenSize(ClientPtr client);
83 static int ProcRRXineramaIsActive(ClientPtr client);
84 static int ProcRRXineramaQueryScreens(ClientPtr client);
85 static int SProcRRXineramaDispatch(ClientPtr client);
87 /* Proc */
89 int
90 ProcRRXineramaQueryVersion(ClientPtr client)
92 xPanoramiXQueryVersionReply rep;
94 REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
95 rep.type = X_Reply;
96 rep.length = 0;
97 rep.sequenceNumber = client->sequence;
98 rep.majorVersion = SERVER_RRXINERAMA_MAJOR_VERSION;
99 rep.minorVersion = SERVER_RRXINERAMA_MINOR_VERSION;
100 if (client->swapped) {
101 swaps(&rep.sequenceNumber);
102 swapl(&rep.length);
103 swaps(&rep.majorVersion);
104 swaps(&rep.minorVersion);
106 WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *) &rep);
107 return Success;
111 ProcRRXineramaGetState(ClientPtr client)
113 REQUEST(xPanoramiXGetStateReq);
114 WindowPtr pWin;
115 xPanoramiXGetStateReply rep;
116 register int rc;
117 ScreenPtr pScreen;
118 rrScrPrivPtr pScrPriv;
119 Bool active = FALSE;
121 REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
122 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
123 if (rc != Success)
124 return rc;
126 pScreen = pWin->drawable.pScreen;
127 pScrPriv = rrGetScrPriv(pScreen);
128 if (pScrPriv) {
129 /* XXX do we need more than this? */
130 active = TRUE;
133 rep.type = X_Reply;
134 rep.length = 0;
135 rep.sequenceNumber = client->sequence;
136 rep.state = active;
137 rep.window = stuff->window;
138 if (client->swapped) {
139 swaps(&rep.sequenceNumber);
140 swapl(&rep.length);
141 swapl(&rep.window);
143 WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *) &rep);
144 return Success;
147 static Bool
148 RRXineramaCrtcActive(RRCrtcPtr crtc)
150 return crtc->mode != NULL && crtc->numOutputs > 0;
153 static int
154 RRXineramaScreenCount(ScreenPtr pScreen)
156 int i, n;
158 n = 0;
159 if (rrGetScrPriv(pScreen)) {
160 rrScrPriv(pScreen);
161 for (i = 0; i < pScrPriv->numCrtcs; i++)
162 if (RRXineramaCrtcActive(pScrPriv->crtcs[i]))
163 n++;
165 return n;
168 static Bool
169 RRXineramaScreenActive(ScreenPtr pScreen)
171 return RRXineramaScreenCount(pScreen) > 0;
175 ProcRRXineramaGetScreenCount(ClientPtr client)
177 REQUEST(xPanoramiXGetScreenCountReq);
178 WindowPtr pWin;
179 xPanoramiXGetScreenCountReply rep;
180 register int rc;
182 REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
183 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
184 if (rc != Success)
185 return rc;
187 rep.type = X_Reply;
188 rep.length = 0;
189 rep.sequenceNumber = client->sequence;
190 rep.ScreenCount = RRXineramaScreenCount(pWin->drawable.pScreen);
191 rep.window = stuff->window;
192 if (client->swapped) {
193 swaps(&rep.sequenceNumber);
194 swapl(&rep.length);
195 swapl(&rep.window);
197 WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *) &rep);
198 return Success;
202 ProcRRXineramaGetScreenSize(ClientPtr client)
204 REQUEST(xPanoramiXGetScreenSizeReq);
205 WindowPtr pWin, pRoot;
206 ScreenPtr pScreen;
207 xPanoramiXGetScreenSizeReply rep;
208 register int rc;
210 REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
211 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
212 if (rc != Success)
213 return rc;
215 pScreen = pWin->drawable.pScreen;
216 pRoot = pScreen->root;
218 rep.type = X_Reply;
219 rep.length = 0;
220 rep.sequenceNumber = client->sequence;
221 rep.width = pRoot->drawable.width;
222 rep.height = pRoot->drawable.height;
223 rep.window = stuff->window;
224 rep.screen = stuff->screen;
225 if (client->swapped) {
226 swaps(&rep.sequenceNumber);
227 swapl(&rep.length);
228 swapl(&rep.width);
229 swapl(&rep.height);
230 swapl(&rep.window);
231 swapl(&rep.screen);
233 WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *) &rep);
234 return Success;
238 ProcRRXineramaIsActive(ClientPtr client)
240 xXineramaIsActiveReply rep;
242 REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
244 memset(&rep, 0, sizeof(xXineramaIsActiveReply));
245 rep.type = X_Reply;
246 rep.length = 0;
247 rep.sequenceNumber = client->sequence;
248 rep.state = RRXineramaScreenActive(screenInfo.screens[RR_XINERAMA_SCREEN]);
249 if (client->swapped) {
250 swaps(&rep.sequenceNumber);
251 swapl(&rep.length);
252 swapl(&rep.state);
254 WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
255 return Success;
258 static void
259 RRXineramaWriteCrtc(ClientPtr client, RRCrtcPtr crtc)
261 xXineramaScreenInfo scratch;
263 if (RRXineramaCrtcActive(crtc)) {
264 ScreenPtr pScreen = crtc->pScreen;
265 rrScrPrivPtr pScrPriv = rrGetScrPriv(pScreen);
266 BoxRec panned_area;
268 /* Check to see if crtc is panned and return the full area when applicable. */
269 if (pScrPriv && pScrPriv->rrGetPanning &&
270 pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL, NULL) &&
271 (panned_area.x2 > panned_area.x1) &&
272 (panned_area.y2 > panned_area.y1)) {
273 scratch.x_org = panned_area.x1;
274 scratch.y_org = panned_area.y1;
275 scratch.width = panned_area.x2 - panned_area.x1;
276 scratch.height = panned_area.y2 - panned_area.y1;
278 else {
279 int width, height;
281 RRCrtcGetScanoutSize(crtc, &width, &height);
282 scratch.x_org = crtc->x;
283 scratch.y_org = crtc->y;
284 scratch.width = width;
285 scratch.height = height;
287 if (client->swapped) {
288 swaps(&scratch.x_org);
289 swaps(&scratch.y_org);
290 swaps(&scratch.width);
291 swaps(&scratch.height);
293 WriteToClient(client, sz_XineramaScreenInfo, &scratch);
298 ProcRRXineramaQueryScreens(ClientPtr client)
300 xXineramaQueryScreensReply rep;
301 ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN];
303 REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
305 if (RRXineramaScreenActive(pScreen))
306 RRGetInfo(pScreen, FALSE);
308 rep.type = X_Reply;
309 rep.sequenceNumber = client->sequence;
310 rep.number = RRXineramaScreenCount(pScreen);
311 rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo);
312 if (client->swapped) {
313 swaps(&rep.sequenceNumber);
314 swapl(&rep.length);
315 swapl(&rep.number);
317 WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *) &rep);
319 if (rep.number) {
320 rrScrPriv(pScreen);
321 int i;
322 int has_primary = 0;
324 if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
325 has_primary = 1;
326 RRXineramaWriteCrtc(client, pScrPriv->primaryOutput->crtc);
329 for (i = 0; i < pScrPriv->numCrtcs; i++) {
330 if (has_primary &&
331 pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i]) {
332 has_primary = 0;
333 continue;
335 RRXineramaWriteCrtc(client, pScrPriv->crtcs[i]);
339 return Success;
342 static int
343 ProcRRXineramaDispatch(ClientPtr client)
345 REQUEST(xReq);
346 switch (stuff->data) {
347 case X_PanoramiXQueryVersion:
348 return ProcRRXineramaQueryVersion(client);
349 case X_PanoramiXGetState:
350 return ProcRRXineramaGetState(client);
351 case X_PanoramiXGetScreenCount:
352 return ProcRRXineramaGetScreenCount(client);
353 case X_PanoramiXGetScreenSize:
354 return ProcRRXineramaGetScreenSize(client);
355 case X_XineramaIsActive:
356 return ProcRRXineramaIsActive(client);
357 case X_XineramaQueryScreens:
358 return ProcRRXineramaQueryScreens(client);
360 return BadRequest;
363 /* SProc */
365 static int
366 SProcRRXineramaQueryVersion(ClientPtr client)
368 REQUEST(xPanoramiXQueryVersionReq);
369 swaps(&stuff->length);
370 REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
371 return ProcRRXineramaQueryVersion(client);
374 static int
375 SProcRRXineramaGetState(ClientPtr client)
377 REQUEST(xPanoramiXGetStateReq);
378 swaps(&stuff->length);
379 REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
380 swapl(&stuff->window);
381 return ProcRRXineramaGetState(client);
384 static int
385 SProcRRXineramaGetScreenCount(ClientPtr client)
387 REQUEST(xPanoramiXGetScreenCountReq);
388 swaps(&stuff->length);
389 REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
390 swapl(&stuff->window);
391 return ProcRRXineramaGetScreenCount(client);
394 static int
395 SProcRRXineramaGetScreenSize(ClientPtr client)
397 REQUEST(xPanoramiXGetScreenSizeReq);
398 swaps(&stuff->length);
399 REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
400 swapl(&stuff->window);
401 swapl(&stuff->screen);
402 return ProcRRXineramaGetScreenSize(client);
405 static int
406 SProcRRXineramaIsActive(ClientPtr client)
408 REQUEST(xXineramaIsActiveReq);
409 swaps(&stuff->length);
410 REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
411 return ProcRRXineramaIsActive(client);
414 static int
415 SProcRRXineramaQueryScreens(ClientPtr client)
417 REQUEST(xXineramaQueryScreensReq);
418 swaps(&stuff->length);
419 REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
420 return ProcRRXineramaQueryScreens(client);
424 SProcRRXineramaDispatch(ClientPtr client)
426 REQUEST(xReq);
427 switch (stuff->data) {
428 case X_PanoramiXQueryVersion:
429 return SProcRRXineramaQueryVersion(client);
430 case X_PanoramiXGetState:
431 return SProcRRXineramaGetState(client);
432 case X_PanoramiXGetScreenCount:
433 return SProcRRXineramaGetScreenCount(client);
434 case X_PanoramiXGetScreenSize:
435 return SProcRRXineramaGetScreenSize(client);
436 case X_XineramaIsActive:
437 return SProcRRXineramaIsActive(client);
438 case X_XineramaQueryScreens:
439 return SProcRRXineramaQueryScreens(client);
441 return BadRequest;
444 void
445 RRXineramaExtensionInit(void)
447 #ifdef PANORAMIX
448 if (!noPanoramiXExtension)
449 return;
450 #endif
453 * Xinerama isn't capable enough to have multiple protocol screens each
454 * with their own output geometry. So if there's more than one protocol
455 * screen, just don't even try.
457 if (screenInfo.numScreens > 1)
458 return;
460 (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
461 ProcRRXineramaDispatch,
462 SProcRRXineramaDispatch, NULL, StandardMinorOpcode);