Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | |
5 | * copy of this software and associated documentation files (the "Software"), | |
6 | * to deal in the Software without restriction, including without limitation | |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
8 | * and/or sell copies of the Software, and to permit persons to whom the | |
9 | * Software is furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice (including the next | |
12 | * paragraph) shall be included in all copies or substantial portions of the | |
13 | * Software. | |
14 | * | |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
21 | * DEALINGS IN THE SOFTWARE. | |
22 | * | |
23 | * Copyright © 2003 Keith Packard | |
24 | * | |
25 | * Permission to use, copy, modify, distribute, and sell this software and its | |
26 | * documentation for any purpose is hereby granted without fee, provided that | |
27 | * the above copyright notice appear in all copies and that both that | |
28 | * copyright notice and this permission notice appear in supporting | |
29 | * documentation, and that the name of Keith Packard not be used in | |
30 | * advertising or publicity pertaining to distribution of the software without | |
31 | * specific, written prior permission. Keith Packard makes no | |
32 | * representations about the suitability of this software for any purpose. It | |
33 | * is provided "as is" without express or implied warranty. | |
34 | * | |
35 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
36 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
37 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
38 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |
39 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
40 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
41 | * PERFORMANCE OF THIS SOFTWARE. | |
42 | */ | |
43 | ||
44 | #ifdef HAVE_DIX_CONFIG_H | |
45 | #include <dix-config.h> | |
46 | #endif | |
47 | ||
48 | #include "compint.h" | |
49 | #include "xace.h" | |
50 | #include "protocol-versions.h" | |
51 | #include "extinit.h" | |
52 | ||
53 | static CARD8 CompositeReqCode; | |
54 | static DevPrivateKeyRec CompositeClientPrivateKeyRec; | |
55 | ||
56 | #define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec) | |
57 | RESTYPE CompositeClientWindowType; | |
58 | RESTYPE CompositeClientSubwindowsType; | |
59 | RESTYPE CompositeClientOverlayType; | |
60 | ||
61 | typedef struct _CompositeClient { | |
62 | int major_version; | |
63 | int minor_version; | |
64 | } CompositeClientRec, *CompositeClientPtr; | |
65 | ||
66 | #define GetCompositeClient(pClient) ((CompositeClientPtr) \ | |
67 | dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey)) | |
68 | ||
69 | static void | |
70 | CompositeClientCallback(CallbackListPtr *list, pointer closure, pointer data) | |
71 | { | |
72 | NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; | |
73 | ClientPtr pClient = clientinfo->client; | |
74 | CompositeClientPtr pCompositeClient = GetCompositeClient(pClient); | |
75 | ||
76 | pCompositeClient->major_version = 0; | |
77 | pCompositeClient->minor_version = 0; | |
78 | } | |
79 | ||
80 | static int | |
81 | FreeCompositeClientWindow(pointer value, XID ccwid) | |
82 | { | |
83 | WindowPtr pWin = value; | |
84 | ||
85 | compFreeClientWindow(pWin, ccwid); | |
86 | return Success; | |
87 | } | |
88 | ||
89 | static int | |
90 | FreeCompositeClientSubwindows(pointer value, XID ccwid) | |
91 | { | |
92 | WindowPtr pWin = value; | |
93 | ||
94 | compFreeClientSubwindows(pWin, ccwid); | |
95 | return Success; | |
96 | } | |
97 | ||
98 | static int | |
99 | FreeCompositeClientOverlay(pointer value, XID ccwid) | |
100 | { | |
101 | CompOverlayClientPtr pOc = (CompOverlayClientPtr) value; | |
102 | ||
103 | compFreeOverlayClient(pOc); | |
104 | return Success; | |
105 | } | |
106 | ||
107 | static int | |
108 | ProcCompositeQueryVersion(ClientPtr client) | |
109 | { | |
110 | CompositeClientPtr pCompositeClient = GetCompositeClient(client); | |
111 | xCompositeQueryVersionReply rep = { | |
112 | .type = X_Reply, | |
113 | .sequenceNumber = client->sequence, | |
114 | .length = 0 | |
115 | }; | |
116 | ||
117 | REQUEST(xCompositeQueryVersionReq); | |
118 | ||
119 | REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); | |
120 | if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) { | |
121 | rep.majorVersion = stuff->majorVersion; | |
122 | rep.minorVersion = stuff->minorVersion; | |
123 | } | |
124 | else { | |
125 | rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION; | |
126 | rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION; | |
127 | } | |
128 | pCompositeClient->major_version = rep.majorVersion; | |
129 | pCompositeClient->minor_version = rep.minorVersion; | |
130 | if (client->swapped) { | |
131 | swaps(&rep.sequenceNumber); | |
132 | swapl(&rep.length); | |
133 | swapl(&rep.majorVersion); | |
134 | swapl(&rep.minorVersion); | |
135 | } | |
136 | WriteToClient(client, sizeof(xCompositeQueryVersionReply), &rep); | |
137 | return Success; | |
138 | } | |
139 | ||
140 | #define VERIFY_WINDOW(pWindow, wid, client, mode) \ | |
141 | do { \ | |
142 | int err; \ | |
143 | err = dixLookupResourceByType((pointer *) &pWindow, wid, \ | |
144 | RT_WINDOW, client, mode); \ | |
145 | if (err != Success) { \ | |
146 | client->errorValue = wid; \ | |
147 | return err; \ | |
148 | } \ | |
149 | } while (0) | |
150 | ||
151 | static int | |
152 | ProcCompositeRedirectWindow(ClientPtr client) | |
153 | { | |
154 | WindowPtr pWin; | |
155 | ||
156 | REQUEST(xCompositeRedirectWindowReq); | |
157 | ||
158 | REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); | |
159 | VERIFY_WINDOW(pWin, stuff->window, client, | |
160 | DixSetAttrAccess | DixManageAccess | DixBlendAccess); | |
161 | ||
162 | return compRedirectWindow(client, pWin, stuff->update); | |
163 | } | |
164 | ||
165 | static int | |
166 | ProcCompositeRedirectSubwindows(ClientPtr client) | |
167 | { | |
168 | WindowPtr pWin; | |
169 | ||
170 | REQUEST(xCompositeRedirectSubwindowsReq); | |
171 | ||
172 | REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); | |
173 | VERIFY_WINDOW(pWin, stuff->window, client, | |
174 | DixSetAttrAccess | DixManageAccess | DixBlendAccess); | |
175 | ||
176 | return compRedirectSubwindows(client, pWin, stuff->update); | |
177 | } | |
178 | ||
179 | static int | |
180 | ProcCompositeUnredirectWindow(ClientPtr client) | |
181 | { | |
182 | WindowPtr pWin; | |
183 | ||
184 | REQUEST(xCompositeUnredirectWindowReq); | |
185 | ||
186 | REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); | |
187 | VERIFY_WINDOW(pWin, stuff->window, client, | |
188 | DixSetAttrAccess | DixManageAccess | DixBlendAccess); | |
189 | ||
190 | return compUnredirectWindow(client, pWin, stuff->update); | |
191 | } | |
192 | ||
193 | static int | |
194 | ProcCompositeUnredirectSubwindows(ClientPtr client) | |
195 | { | |
196 | WindowPtr pWin; | |
197 | ||
198 | REQUEST(xCompositeUnredirectSubwindowsReq); | |
199 | ||
200 | REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); | |
201 | VERIFY_WINDOW(pWin, stuff->window, client, | |
202 | DixSetAttrAccess | DixManageAccess | DixBlendAccess); | |
203 | ||
204 | return compUnredirectSubwindows(client, pWin, stuff->update); | |
205 | } | |
206 | ||
207 | static int | |
208 | ProcCompositeCreateRegionFromBorderClip(ClientPtr client) | |
209 | { | |
210 | WindowPtr pWin; | |
211 | CompWindowPtr cw; | |
212 | RegionPtr pBorderClip, pRegion; | |
213 | ||
214 | REQUEST(xCompositeCreateRegionFromBorderClipReq); | |
215 | ||
216 | REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); | |
217 | VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); | |
218 | LEGAL_NEW_RESOURCE(stuff->region, client); | |
219 | ||
220 | cw = GetCompWindow(pWin); | |
221 | if (cw) | |
222 | pBorderClip = &cw->borderClip; | |
223 | else | |
224 | pBorderClip = &pWin->borderClip; | |
225 | pRegion = XFixesRegionCopy(pBorderClip); | |
226 | if (!pRegion) | |
227 | return BadAlloc; | |
228 | RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y); | |
229 | ||
230 | if (!AddResource(stuff->region, RegionResType, (pointer) pRegion)) | |
231 | return BadAlloc; | |
232 | ||
233 | return Success; | |
234 | } | |
235 | ||
236 | static int | |
237 | ProcCompositeNameWindowPixmap(ClientPtr client) | |
238 | { | |
239 | WindowPtr pWin; | |
240 | CompWindowPtr cw; | |
241 | PixmapPtr pPixmap; | |
242 | int rc; | |
243 | ||
244 | REQUEST(xCompositeNameWindowPixmapReq); | |
245 | ||
246 | REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); | |
247 | VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); | |
248 | ||
249 | if (!pWin->viewable) | |
250 | return BadMatch; | |
251 | ||
252 | LEGAL_NEW_RESOURCE(stuff->pixmap, client); | |
253 | ||
254 | cw = GetCompWindow(pWin); | |
255 | if (!cw) | |
256 | return BadMatch; | |
257 | ||
258 | pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); | |
259 | if (!pPixmap) | |
260 | return BadMatch; | |
261 | ||
262 | /* security creation/labeling check */ | |
263 | rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, | |
264 | pPixmap, RT_WINDOW, pWin, DixCreateAccess); | |
265 | if (rc != Success) | |
266 | return rc; | |
267 | ||
268 | ++pPixmap->refcnt; | |
269 | ||
270 | if (!AddResource(stuff->pixmap, RT_PIXMAP, (pointer) pPixmap)) | |
271 | return BadAlloc; | |
272 | ||
273 | return Success; | |
274 | } | |
275 | ||
276 | static int | |
277 | ProcCompositeGetOverlayWindow(ClientPtr client) | |
278 | { | |
279 | REQUEST(xCompositeGetOverlayWindowReq); | |
280 | xCompositeGetOverlayWindowReply rep; | |
281 | WindowPtr pWin; | |
282 | ScreenPtr pScreen; | |
283 | CompScreenPtr cs; | |
284 | CompOverlayClientPtr pOc; | |
285 | int rc; | |
286 | ||
287 | REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); | |
288 | VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); | |
289 | pScreen = pWin->drawable.pScreen; | |
290 | ||
291 | /* | |
292 | * Create an OverlayClient structure to mark this client's | |
293 | * interest in the overlay window | |
294 | */ | |
295 | pOc = compCreateOverlayClient(pScreen, client); | |
296 | if (pOc == NULL) | |
297 | return BadAlloc; | |
298 | ||
299 | /* | |
300 | * Make sure the overlay window exists | |
301 | */ | |
302 | cs = GetCompScreen(pScreen); | |
303 | if (cs->pOverlayWin == NULL) | |
304 | if (!compCreateOverlayWindow(pScreen)) { | |
305 | FreeResource(pOc->resource, RT_NONE); | |
306 | return BadAlloc; | |
307 | } | |
308 | ||
309 | rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id, | |
310 | RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess); | |
311 | if (rc != Success) { | |
312 | FreeResource(pOc->resource, RT_NONE); | |
313 | return rc; | |
314 | } | |
315 | ||
316 | rep = (xCompositeGetOverlayWindowReply) { | |
317 | .type = X_Reply, | |
318 | .sequenceNumber = client->sequence, | |
319 | .length = 0, | |
320 | .overlayWin = cs->pOverlayWin->drawable.id | |
321 | }; | |
322 | ||
323 | if (client->swapped) { | |
324 | swaps(&rep.sequenceNumber); | |
325 | swapl(&rep.length); | |
326 | swapl(&rep.overlayWin); | |
327 | } | |
328 | WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep); | |
329 | ||
330 | return Success; | |
331 | } | |
332 | ||
333 | static int | |
334 | ProcCompositeReleaseOverlayWindow(ClientPtr client) | |
335 | { | |
336 | REQUEST(xCompositeReleaseOverlayWindowReq); | |
337 | WindowPtr pWin; | |
338 | ScreenPtr pScreen; | |
339 | CompOverlayClientPtr pOc; | |
340 | ||
341 | REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); | |
342 | VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess); | |
343 | pScreen = pWin->drawable.pScreen; | |
344 | ||
345 | /* | |
346 | * Has client queried a reference to the overlay window | |
347 | * on this screen? If not, generate an error. | |
348 | */ | |
349 | pOc = compFindOverlayClient(pWin->drawable.pScreen, client); | |
350 | if (pOc == NULL) | |
351 | return BadMatch; | |
352 | ||
353 | /* The delete function will free the client structure */ | |
354 | FreeResource(pOc->resource, RT_NONE); | |
355 | ||
356 | return Success; | |
357 | } | |
358 | ||
359 | static int (*ProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = { | |
360 | ProcCompositeQueryVersion, | |
361 | ProcCompositeRedirectWindow, | |
362 | ProcCompositeRedirectSubwindows, | |
363 | ProcCompositeUnredirectWindow, | |
364 | ProcCompositeUnredirectSubwindows, | |
365 | ProcCompositeCreateRegionFromBorderClip, | |
366 | ProcCompositeNameWindowPixmap, | |
367 | ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow,}; | |
368 | ||
369 | static int | |
370 | ProcCompositeDispatch(ClientPtr client) | |
371 | { | |
372 | REQUEST(xReq); | |
373 | ||
374 | if (stuff->data < CompositeNumberRequests) | |
375 | return (*ProcCompositeVector[stuff->data]) (client); | |
376 | else | |
377 | return BadRequest; | |
378 | } | |
379 | ||
380 | static int | |
381 | SProcCompositeQueryVersion(ClientPtr client) | |
382 | { | |
383 | REQUEST(xCompositeQueryVersionReq); | |
384 | ||
385 | swaps(&stuff->length); | |
386 | REQUEST_SIZE_MATCH(xCompositeQueryVersionReq); | |
387 | swapl(&stuff->majorVersion); | |
388 | swapl(&stuff->minorVersion); | |
389 | return (*ProcCompositeVector[stuff->compositeReqType]) (client); | |
390 | } | |
391 | ||
392 | static int | |
393 | SProcCompositeRedirectWindow(ClientPtr client) | |
394 | { | |
395 | REQUEST(xCompositeRedirectWindowReq); | |
396 | ||
397 | swaps(&stuff->length); | |
398 | REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); | |
399 | swapl(&stuff->window); | |
400 | return (*ProcCompositeVector[stuff->compositeReqType]) (client); | |
401 | } | |
402 | ||
403 | static int | |
404 | SProcCompositeRedirectSubwindows(ClientPtr client) | |
405 | { | |
406 | REQUEST(xCompositeRedirectSubwindowsReq); | |
407 | ||
408 | swaps(&stuff->length); | |
409 | REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); | |
410 | swapl(&stuff->window); | |
411 | return (*ProcCompositeVector[stuff->compositeReqType]) (client); | |
412 | } | |
413 | ||
414 | static int | |
415 | SProcCompositeUnredirectWindow(ClientPtr client) | |
416 | { | |
417 | REQUEST(xCompositeUnredirectWindowReq); | |
418 | ||
419 | swaps(&stuff->length); | |
420 | REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); | |
421 | swapl(&stuff->window); | |
422 | return (*ProcCompositeVector[stuff->compositeReqType]) (client); | |
423 | } | |
424 | ||
425 | static int | |
426 | SProcCompositeUnredirectSubwindows(ClientPtr client) | |
427 | { | |
428 | REQUEST(xCompositeUnredirectSubwindowsReq); | |
429 | ||
430 | swaps(&stuff->length); | |
431 | REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); | |
432 | swapl(&stuff->window); | |
433 | return (*ProcCompositeVector[stuff->compositeReqType]) (client); | |
434 | } | |
435 | ||
436 | static int | |
437 | SProcCompositeCreateRegionFromBorderClip(ClientPtr client) | |
438 | { | |
439 | REQUEST(xCompositeCreateRegionFromBorderClipReq); | |
440 | ||
441 | swaps(&stuff->length); | |
442 | REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq); | |
443 | swapl(&stuff->region); | |
444 | swapl(&stuff->window); | |
445 | return (*ProcCompositeVector[stuff->compositeReqType]) (client); | |
446 | } | |
447 | ||
448 | static int | |
449 | SProcCompositeNameWindowPixmap(ClientPtr client) | |
450 | { | |
451 | REQUEST(xCompositeNameWindowPixmapReq); | |
452 | ||
453 | swaps(&stuff->length); | |
454 | REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); | |
455 | swapl(&stuff->window); | |
456 | swapl(&stuff->pixmap); | |
457 | return (*ProcCompositeVector[stuff->compositeReqType]) (client); | |
458 | } | |
459 | ||
460 | static int | |
461 | SProcCompositeGetOverlayWindow(ClientPtr client) | |
462 | { | |
463 | REQUEST(xCompositeGetOverlayWindowReq); | |
464 | ||
465 | swaps(&stuff->length); | |
466 | REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); | |
467 | swapl(&stuff->window); | |
468 | return (*ProcCompositeVector[stuff->compositeReqType]) (client); | |
469 | } | |
470 | ||
471 | static int | |
472 | SProcCompositeReleaseOverlayWindow(ClientPtr client) | |
473 | { | |
474 | REQUEST(xCompositeReleaseOverlayWindowReq); | |
475 | ||
476 | swaps(&stuff->length); | |
477 | REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); | |
478 | swapl(&stuff->window); | |
479 | return (*ProcCompositeVector[stuff->compositeReqType]) (client); | |
480 | } | |
481 | ||
482 | static int (*SProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = { | |
483 | SProcCompositeQueryVersion, | |
484 | SProcCompositeRedirectWindow, | |
485 | SProcCompositeRedirectSubwindows, | |
486 | SProcCompositeUnredirectWindow, | |
487 | SProcCompositeUnredirectSubwindows, | |
488 | SProcCompositeCreateRegionFromBorderClip, | |
489 | SProcCompositeNameWindowPixmap, | |
490 | SProcCompositeGetOverlayWindow, SProcCompositeReleaseOverlayWindow,}; | |
491 | ||
492 | static int | |
493 | SProcCompositeDispatch(ClientPtr client) | |
494 | { | |
495 | REQUEST(xReq); | |
496 | ||
497 | if (stuff->data < CompositeNumberRequests) | |
498 | return (*SProcCompositeVector[stuff->data]) (client); | |
499 | else | |
500 | return BadRequest; | |
501 | } | |
502 | ||
503 | /** @see GetDefaultBytes */ | |
504 | static void | |
505 | GetCompositeClientWindowBytes(pointer value, XID id, ResourceSizePtr size) | |
506 | { | |
507 | WindowPtr window = value; | |
508 | ||
509 | /* Currently only pixmap bytes are reported to clients. */ | |
510 | size->resourceSize = 0; | |
511 | ||
512 | /* Calculate pixmap reference sizes. */ | |
513 | size->pixmapRefSize = 0; | |
514 | if (window->redirectDraw != RedirectDrawNone) | |
515 | { | |
516 | SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP); | |
517 | ResourceSizeRec pixmapSize = { 0, 0 }; | |
518 | ScreenPtr screen = window->drawable.pScreen; | |
519 | PixmapPtr pixmap = screen->GetWindowPixmap(window); | |
520 | pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize); | |
521 | size->pixmapRefSize += pixmapSize.pixmapRefSize; | |
522 | } | |
523 | } | |
524 | ||
525 | void | |
526 | CompositeExtensionInit(void) | |
527 | { | |
528 | ExtensionEntry *extEntry; | |
529 | int s; | |
530 | ||
531 | /* Assume initialization is going to fail */ | |
532 | noCompositeExtension = TRUE; | |
533 | ||
534 | for (s = 0; s < screenInfo.numScreens; s++) { | |
535 | ScreenPtr pScreen = screenInfo.screens[s]; | |
536 | VisualPtr vis; | |
537 | ||
538 | /* Composite on 8bpp pseudocolor root windows appears to fail, so | |
539 | * just disable it on anything pseudocolor for safety. | |
540 | */ | |
541 | for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++); | |
542 | if ((vis->class | DynamicClass) == PseudoColor) | |
543 | return; | |
544 | ||
545 | /* Ensure that Render is initialized, which is required for automatic | |
546 | * compositing. | |
547 | */ | |
548 | if (GetPictureScreenIfSet(pScreen) == NULL) | |
549 | return; | |
550 | } | |
551 | ||
552 | CompositeClientWindowType = CreateNewResourceType | |
553 | (FreeCompositeClientWindow, "CompositeClientWindow"); | |
554 | if (!CompositeClientWindowType) | |
555 | return; | |
556 | ||
557 | SetResourceTypeSizeFunc(CompositeClientWindowType, | |
558 | GetCompositeClientWindowBytes); | |
559 | ||
560 | CompositeClientSubwindowsType = CreateNewResourceType | |
561 | (FreeCompositeClientSubwindows, "CompositeClientSubwindows"); | |
562 | if (!CompositeClientSubwindowsType) | |
563 | return; | |
564 | ||
565 | CompositeClientOverlayType = CreateNewResourceType | |
566 | (FreeCompositeClientOverlay, "CompositeClientOverlay"); | |
567 | if (!CompositeClientOverlayType) | |
568 | return; | |
569 | ||
570 | if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT, | |
571 | sizeof(CompositeClientRec))) | |
572 | return; | |
573 | ||
574 | if (!AddCallback(&ClientStateCallback, CompositeClientCallback, 0)) | |
575 | return; | |
576 | ||
577 | for (s = 0; s < screenInfo.numScreens; s++) | |
578 | if (!compScreenInit(screenInfo.screens[s])) | |
579 | return; | |
580 | ||
581 | extEntry = AddExtension(COMPOSITE_NAME, 0, 0, | |
582 | ProcCompositeDispatch, SProcCompositeDispatch, | |
583 | NULL, StandardMinorOpcode); | |
584 | if (!extEntry) | |
585 | return; | |
586 | CompositeReqCode = (CARD8) extEntry->base; | |
587 | ||
588 | miRegisterRedirectBorderClipProc(compSetRedirectBorderClip, | |
589 | compGetRedirectBorderClip); | |
590 | ||
591 | /* Initialization succeeded */ | |
592 | noCompositeExtension = FALSE; | |
593 | } | |
594 | ||
595 | #ifdef PANORAMIX | |
596 | #include "panoramiXsrv.h" | |
597 | ||
598 | int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr); | |
599 | ||
600 | static int | |
601 | PanoramiXCompositeRedirectWindow(ClientPtr client) | |
602 | { | |
603 | PanoramiXRes *win; | |
604 | int rc = 0, j; | |
605 | ||
606 | REQUEST(xCompositeRedirectWindowReq); | |
607 | ||
608 | REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq); | |
609 | ||
610 | if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, | |
611 | client, DixUnknownAccess))) { | |
612 | client->errorValue = stuff->window; | |
613 | return rc; | |
614 | } | |
615 | ||
616 | FOR_NSCREENS_FORWARD(j) { | |
617 | stuff->window = win->info[j].id; | |
618 | rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); | |
619 | if (rc != Success) | |
620 | break; | |
621 | } | |
622 | ||
623 | return rc; | |
624 | } | |
625 | ||
626 | static int | |
627 | PanoramiXCompositeRedirectSubwindows(ClientPtr client) | |
628 | { | |
629 | PanoramiXRes *win; | |
630 | int rc = 0, j; | |
631 | ||
632 | REQUEST(xCompositeRedirectSubwindowsReq); | |
633 | ||
634 | REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq); | |
635 | ||
636 | if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, | |
637 | client, DixUnknownAccess))) { | |
638 | client->errorValue = stuff->window; | |
639 | return rc; | |
640 | } | |
641 | ||
642 | FOR_NSCREENS_FORWARD(j) { | |
643 | stuff->window = win->info[j].id; | |
644 | rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); | |
645 | if (rc != Success) | |
646 | break; | |
647 | } | |
648 | ||
649 | return rc; | |
650 | } | |
651 | ||
652 | static int | |
653 | PanoramiXCompositeUnredirectWindow(ClientPtr client) | |
654 | { | |
655 | PanoramiXRes *win; | |
656 | int rc = 0, j; | |
657 | ||
658 | REQUEST(xCompositeUnredirectWindowReq); | |
659 | ||
660 | REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq); | |
661 | ||
662 | if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, | |
663 | client, DixUnknownAccess))) { | |
664 | client->errorValue = stuff->window; | |
665 | return rc; | |
666 | } | |
667 | ||
668 | FOR_NSCREENS_FORWARD(j) { | |
669 | stuff->window = win->info[j].id; | |
670 | rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); | |
671 | if (rc != Success) | |
672 | break; | |
673 | } | |
674 | ||
675 | return rc; | |
676 | } | |
677 | ||
678 | static int | |
679 | PanoramiXCompositeUnredirectSubwindows(ClientPtr client) | |
680 | { | |
681 | PanoramiXRes *win; | |
682 | int rc = 0, j; | |
683 | ||
684 | REQUEST(xCompositeUnredirectSubwindowsReq); | |
685 | ||
686 | REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq); | |
687 | ||
688 | if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, | |
689 | client, DixUnknownAccess))) { | |
690 | client->errorValue = stuff->window; | |
691 | return rc; | |
692 | } | |
693 | ||
694 | FOR_NSCREENS_FORWARD(j) { | |
695 | stuff->window = win->info[j].id; | |
696 | rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client); | |
697 | if (rc != Success) | |
698 | break; | |
699 | } | |
700 | ||
701 | return rc; | |
702 | } | |
703 | ||
704 | static int | |
705 | PanoramiXCompositeNameWindowPixmap(ClientPtr client) | |
706 | { | |
707 | WindowPtr pWin; | |
708 | CompWindowPtr cw; | |
709 | PixmapPtr pPixmap; | |
710 | int rc; | |
711 | PanoramiXRes *win, *newPix; | |
712 | int i; | |
713 | ||
714 | REQUEST(xCompositeNameWindowPixmapReq); | |
715 | ||
716 | REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq); | |
717 | ||
718 | if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, | |
719 | client, DixUnknownAccess))) { | |
720 | client->errorValue = stuff->window; | |
721 | return rc; | |
722 | } | |
723 | ||
724 | LEGAL_NEW_RESOURCE(stuff->pixmap, client); | |
725 | ||
726 | if (!(newPix = malloc(sizeof(PanoramiXRes)))) | |
727 | return BadAlloc; | |
728 | ||
729 | newPix->type = XRT_PIXMAP; | |
730 | newPix->u.pix.shared = FALSE; | |
731 | panoramix_setup_ids(newPix, client, stuff->pixmap); | |
732 | ||
733 | FOR_NSCREENS(i) { | |
734 | rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, | |
735 | RT_WINDOW, client, DixGetAttrAccess); | |
736 | if (rc != Success) { | |
737 | client->errorValue = stuff->window; | |
738 | free(newPix); | |
739 | return rc; | |
740 | } | |
741 | ||
742 | if (!pWin->viewable) { | |
743 | free(newPix); | |
744 | return BadMatch; | |
745 | } | |
746 | ||
747 | cw = GetCompWindow(pWin); | |
748 | if (!cw) { | |
749 | free(newPix); | |
750 | return BadMatch; | |
751 | } | |
752 | ||
753 | pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); | |
754 | if (!pPixmap) { | |
755 | free(newPix); | |
756 | return BadMatch; | |
757 | } | |
758 | ||
759 | if (!AddResource(newPix->info[i].id, RT_PIXMAP, (pointer) pPixmap)) | |
760 | return BadAlloc; | |
761 | ||
762 | ++pPixmap->refcnt; | |
763 | } | |
764 | ||
765 | if (!AddResource(stuff->pixmap, XRT_PIXMAP, (pointer) newPix)) | |
766 | return BadAlloc; | |
767 | ||
768 | return Success; | |
769 | } | |
770 | ||
771 | static int | |
772 | PanoramiXCompositeGetOverlayWindow(ClientPtr client) | |
773 | { | |
774 | REQUEST(xCompositeGetOverlayWindowReq); | |
775 | xCompositeGetOverlayWindowReply rep; | |
776 | WindowPtr pWin; | |
777 | ScreenPtr pScreen; | |
778 | CompScreenPtr cs; | |
779 | CompOverlayClientPtr pOc; | |
780 | int rc; | |
781 | PanoramiXRes *win, *overlayWin = NULL; | |
782 | int i; | |
783 | ||
784 | REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq); | |
785 | ||
786 | if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, | |
787 | client, DixUnknownAccess))) { | |
788 | client->errorValue = stuff->window; | |
789 | return rc; | |
790 | } | |
791 | ||
792 | cs = GetCompScreen(screenInfo.screens[0]); | |
793 | if (!cs->pOverlayWin) { | |
794 | if (!(overlayWin = malloc(sizeof(PanoramiXRes)))) | |
795 | return BadAlloc; | |
796 | ||
797 | overlayWin->type = XRT_WINDOW; | |
798 | overlayWin->u.win.root = FALSE; | |
799 | } | |
800 | ||
801 | FOR_NSCREENS_BACKWARD(i) { | |
802 | rc = dixLookupResourceByType((pointer *) &pWin, win->info[i].id, | |
803 | RT_WINDOW, client, DixGetAttrAccess); | |
804 | if (rc != Success) { | |
805 | client->errorValue = stuff->window; | |
806 | free(overlayWin); | |
807 | return rc; | |
808 | } | |
809 | pScreen = pWin->drawable.pScreen; | |
810 | ||
811 | /* | |
812 | * Create an OverlayClient structure to mark this client's | |
813 | * interest in the overlay window | |
814 | */ | |
815 | pOc = compCreateOverlayClient(pScreen, client); | |
816 | if (pOc == NULL) { | |
817 | free(overlayWin); | |
818 | return BadAlloc; | |
819 | } | |
820 | ||
821 | /* | |
822 | * Make sure the overlay window exists | |
823 | */ | |
824 | cs = GetCompScreen(pScreen); | |
825 | if (cs->pOverlayWin == NULL) | |
826 | if (!compCreateOverlayWindow(pScreen)) { | |
827 | FreeResource(pOc->resource, RT_NONE); | |
828 | free(overlayWin); | |
829 | return BadAlloc; | |
830 | } | |
831 | ||
832 | rc = XaceHook(XACE_RESOURCE_ACCESS, client, | |
833 | cs->pOverlayWin->drawable.id, | |
834 | RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, | |
835 | DixGetAttrAccess); | |
836 | if (rc != Success) { | |
837 | FreeResource(pOc->resource, RT_NONE); | |
838 | free(overlayWin); | |
839 | return rc; | |
840 | } | |
841 | } | |
842 | ||
843 | if (overlayWin) { | |
844 | FOR_NSCREENS(i) { | |
845 | cs = GetCompScreen(screenInfo.screens[i]); | |
846 | overlayWin->info[i].id = cs->pOverlayWin->drawable.id; | |
847 | } | |
848 | ||
849 | AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin); | |
850 | } | |
851 | ||
852 | cs = GetCompScreen(screenInfo.screens[0]); | |
853 | ||
854 | rep = (xCompositeGetOverlayWindowReply) { | |
855 | .type = X_Reply, | |
856 | .sequenceNumber = client->sequence, | |
857 | .length = 0, | |
858 | .overlayWin = cs->pOverlayWin->drawable.id | |
859 | }; | |
860 | ||
861 | if (client->swapped) { | |
862 | swaps(&rep.sequenceNumber); | |
863 | swapl(&rep.length); | |
864 | swapl(&rep.overlayWin); | |
865 | } | |
866 | WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep); | |
867 | ||
868 | return Success; | |
869 | } | |
870 | ||
871 | static int | |
872 | PanoramiXCompositeReleaseOverlayWindow(ClientPtr client) | |
873 | { | |
874 | REQUEST(xCompositeReleaseOverlayWindowReq); | |
875 | WindowPtr pWin; | |
876 | ScreenPtr pScreen; | |
877 | CompOverlayClientPtr pOc; | |
878 | PanoramiXRes *win; | |
879 | int i, rc; | |
880 | ||
881 | REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq); | |
882 | ||
883 | if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW, | |
884 | client, DixUnknownAccess))) { | |
885 | client->errorValue = stuff->window; | |
886 | return rc; | |
887 | } | |
888 | ||
889 | FOR_NSCREENS_BACKWARD(i) { | |
890 | if ((rc = dixLookupResourceByType((void **) &pWin, win->info[i].id, | |
891 | XRT_WINDOW, client, | |
892 | DixUnknownAccess))) { | |
893 | client->errorValue = stuff->window; | |
894 | return rc; | |
895 | } | |
896 | pScreen = pWin->drawable.pScreen; | |
897 | ||
898 | /* | |
899 | * Has client queried a reference to the overlay window | |
900 | * on this screen? If not, generate an error. | |
901 | */ | |
902 | pOc = compFindOverlayClient(pWin->drawable.pScreen, client); | |
903 | if (pOc == NULL) | |
904 | return BadMatch; | |
905 | ||
906 | /* The delete function will free the client structure */ | |
907 | FreeResource(pOc->resource, RT_NONE); | |
908 | } | |
909 | ||
910 | return Success; | |
911 | } | |
912 | ||
913 | void | |
914 | PanoramiXCompositeInit(void) | |
915 | { | |
916 | int i; | |
917 | ||
918 | for (i = 0; i < CompositeNumberRequests; i++) | |
919 | PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i]; | |
920 | /* | |
921 | * Stuff in Xinerama aware request processing hooks | |
922 | */ | |
923 | ProcCompositeVector[X_CompositeRedirectWindow] = | |
924 | PanoramiXCompositeRedirectWindow; | |
925 | ProcCompositeVector[X_CompositeRedirectSubwindows] = | |
926 | PanoramiXCompositeRedirectSubwindows; | |
927 | ProcCompositeVector[X_CompositeUnredirectWindow] = | |
928 | PanoramiXCompositeUnredirectWindow; | |
929 | ProcCompositeVector[X_CompositeUnredirectSubwindows] = | |
930 | PanoramiXCompositeUnredirectSubwindows; | |
931 | ProcCompositeVector[X_CompositeNameWindowPixmap] = | |
932 | PanoramiXCompositeNameWindowPixmap; | |
933 | ProcCompositeVector[X_CompositeGetOverlayWindow] = | |
934 | PanoramiXCompositeGetOverlayWindow; | |
935 | ProcCompositeVector[X_CompositeReleaseOverlayWindow] = | |
936 | PanoramiXCompositeReleaseOverlayWindow; | |
937 | } | |
938 | ||
939 | void | |
940 | PanoramiXCompositeReset(void) | |
941 | { | |
942 | int i; | |
943 | ||
944 | for (i = 0; i < CompositeNumberRequests; i++) | |
945 | ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i]; | |
946 | } | |
947 | ||
948 | #endif |