2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
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:
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
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.
23 * Copyright © 2003 Keith Packard
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.
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.
44 #ifdef HAVE_DIX_CONFIG_H
45 #include <dix-config.h>
51 #include "panoramiXsrv.h"
54 #ifdef _F_STEREOSCOPIC_LEFT_BUFFER_COODINATE_
55 static int prefered_w = 0 ;
56 static int prefered_h = 0 ;
60 #endif // _F_STEREOSCOPIC_LEFT_BUFFER_COODINATE_
63 #define LOG_TAG "XORG_PIXMAP"
67 #ifdef COMPOSITE_DEBUG
69 compCheckWindow(WindowPtr pWin, void *data)
71 ScreenPtr pScreen = pWin->drawable.pScreen;
72 PixmapPtr pWinPixmap = (*pScreen->GetWindowPixmap) (pWin);
73 PixmapPtr pParentPixmap =
74 pWin->parent ? (*pScreen->GetWindowPixmap) (pWin->parent) : 0;
75 PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap) (pScreen);
78 assert(pWin->redirectDraw == RedirectDrawNone);
79 assert(pWinPixmap == pScreenPixmap);
81 else if (pWin->redirectDraw != RedirectDrawNone) {
82 assert(pWinPixmap != pParentPixmap);
83 assert(pWinPixmap != pScreenPixmap);
86 assert(pWinPixmap == pParentPixmap);
88 assert(0 < pWinPixmap->refcnt && pWinPixmap->refcnt < 3);
89 assert(0 < pScreenPixmap->refcnt && pScreenPixmap->refcnt < 3);
91 assert(0 <= pParentPixmap->refcnt && pParentPixmap->refcnt < 3);
92 return WT_WALKCHILDREN;
96 compCheckTree(ScreenPtr pScreen)
98 WalkTree(pScreen, compCheckWindow, 0);
102 typedef struct _compPixmapVisit {
105 } CompPixmapVisitRec, *CompPixmapVisitPtr;
108 compRepaintBorder(ClientPtr pClient, void *closure)
112 dixLookupWindow(&pWindow, (XID) (intptr_t) closure, pClient,
118 RegionNull(&exposed);
119 RegionSubtract(&exposed, &pWindow->borderClip, &pWindow->winSize);
120 miPaintWindow(pWindow, &exposed, PW_BORDER);
121 RegionUninit(&exposed);
127 compSetPixmapVisitWindow(WindowPtr pWindow, void *data)
129 CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data;
130 ScreenPtr pScreen = pWindow->drawable.pScreen;
132 if (pWindow != pVisit->pWindow && pWindow->redirectDraw != RedirectDrawNone)
133 return WT_DONTWALKCHILDREN;
134 (*pScreen->SetWindowPixmap) (pWindow, pVisit->pPixmap);
136 * Recompute winSize and borderSize. This is duplicate effort
137 * when resizing pixmaps, but necessary when changing redirection.
138 * Might be nice to fix this.
141 SetBorderSize(pWindow);
142 if (HasBorder(pWindow))
143 QueueWorkProc(compRepaintBorder, serverClient,
144 (void *) (intptr_t) pWindow->drawable.id);
145 return WT_WALKCHILDREN;
149 compSetPixmap(WindowPtr pWindow, PixmapPtr pPixmap)
151 CompPixmapVisitRec visitRec;
153 visitRec.pWindow = pWindow;
154 visitRec.pPixmap = pPixmap;
155 TraverseTree(pWindow, compSetPixmapVisitWindow, (void *) &visitRec);
156 compCheckTree(pWindow->drawable.pScreen);
160 compCheckRedirect(WindowPtr pWin)
162 CompWindowPtr cw = GetCompWindow(pWin);
163 CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
165 ScreenPtr pScreen = NULL;
166 PixmapPtr pPixmap = NULL;
169 should = pWin->realized && (pWin->drawable.class != InputOnly) &&
170 (cw != NULL) && (pWin->parent != NULL);
172 /* Never redirect the overlay window */
173 if (cs->pOverlayWin != NULL) {
174 if (pWin == cs->pOverlayWin) {
179 if (should != (pWin->redirectDraw != RedirectDrawNone)) {
181 ret = compAllocPixmap(pWin);
182 pScreen = pWin->drawable.pScreen;
183 pPixmap = (*pScreen->GetWindowPixmap) (pWin);
186 SLOG(LOG_INFO, "XORG_PIXMAP", "pix_id:%p, pixmap:%p (%dx%d) refcnt:%d win_id:%p win:%p (%dx%d) view:%d\n",
187 pPixmap->drawable.id,
189 pPixmap->drawable.width,
190 pPixmap->drawable.height,
194 pWin->drawable.width,
195 pWin->drawable.height,
202 pScreen = pWin->drawable.pScreen;
203 pPixmap = (*pScreen->GetWindowPixmap) (pWin);
205 compSetParentPixmap(pWin);
206 compRestoreWindow(pWin, pPixmap);
209 SLOG(LOG_INFO, "XORG_PIXMAP", "pix_id:%p, pixmap:%p (%dx%d) refcnt:%d-1 win_id:%p win:%p (%dx%d) view:%d\n",
210 pPixmap->drawable.id,
212 pPixmap->drawable.width,
213 pPixmap->drawable.height,
217 pWin->drawable.width,
218 pWin->drawable.height,
222 (*pScreen->DestroyPixmap) (pPixmap);
226 if (cw->update == CompositeRedirectAutomatic)
227 pWin->redirectDraw = RedirectDrawAutomatic;
229 pWin->redirectDraw = RedirectDrawManual;
234 pScreen = pWin->drawable.pScreen;
235 pPixmap = (*pScreen->GetWindowPixmap) (pWin);
238 SLOG(LOG_INFO, "XORG_PIXMAP", "pix_id:%p, pixmap:%p (%dx%d) refcnt:%d win_id:%p win:%p (%dx%d) view:%d\n",
239 pPixmap->drawable.id,
241 pPixmap->drawable.width,
242 pPixmap->drawable.height,
246 pWin->drawable.width,
247 pWin->drawable.height,
255 updateOverlayWindow(ScreenPtr pScreen)
258 WindowPtr pWin; /* overlay window */
260 int w = pScreen->width;
261 int h = pScreen->height;
264 if (!noPanoramiXExtension) {
265 w = PanoramiXPixWidth;
266 h = PanoramiXPixHeight;
270 cs = GetCompScreen(pScreen);
271 if ((pWin = cs->pOverlayWin) != NULL) {
272 if ((pWin->drawable.width == w) && (pWin->drawable.height == h))
275 /* Let's resize the overlay window. */
278 return ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin));
281 /* Let's be on the safe side and not assume an overlay window is
287 compPositionWindow(WindowPtr pWin, int x, int y)
289 ScreenPtr pScreen = pWin->drawable.pScreen;
290 CompScreenPtr cs = GetCompScreen(pScreen);
293 pScreen->PositionWindow = cs->PositionWindow;
295 * "Shouldn't need this as all possible places should be wrapped
297 compCheckRedirect (pWin);
299 #ifdef COMPOSITE_DEBUG
300 if ((pWin->redirectDraw != RedirectDrawNone) !=
301 (pWin->viewable && (GetCompWindow(pWin) != NULL)))
304 if (pWin->redirectDraw != RedirectDrawNone) {
305 PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
306 int bw = wBorderWidth(pWin);
307 int nx = pWin->drawable.x - bw;
308 int ny = pWin->drawable.y - bw;
310 if (pPixmap->screen_x != nx || pPixmap->screen_y != ny) {
311 pPixmap->screen_x = nx;
312 pPixmap->screen_y = ny;
313 pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
317 if (!(*pScreen->PositionWindow) (pWin, x, y))
319 cs->PositionWindow = pScreen->PositionWindow;
320 pScreen->PositionWindow = compPositionWindow;
321 compCheckTree(pWin->drawable.pScreen);
322 if (updateOverlayWindow(pScreen) != Success)
328 compRealizeWindow(WindowPtr pWin)
330 ScreenPtr pScreen = pWin->drawable.pScreen;
331 CompScreenPtr cs = GetCompScreen(pScreen);
334 pScreen->RealizeWindow = cs->RealizeWindow;
335 compCheckRedirect(pWin);
336 if (!(*pScreen->RealizeWindow) (pWin))
338 cs->RealizeWindow = pScreen->RealizeWindow;
339 pScreen->RealizeWindow = compRealizeWindow;
340 compCheckTree(pWin->drawable.pScreen);
345 compUnrealizeWindow(WindowPtr pWin)
347 ScreenPtr pScreen = pWin->drawable.pScreen;
348 CompScreenPtr cs = GetCompScreen(pScreen);
351 pScreen->UnrealizeWindow = cs->UnrealizeWindow;
352 compCheckRedirect(pWin);
353 if (!(*pScreen->UnrealizeWindow) (pWin))
355 cs->UnrealizeWindow = pScreen->UnrealizeWindow;
356 pScreen->UnrealizeWindow = compUnrealizeWindow;
357 compCheckTree(pWin->drawable.pScreen);
362 * Called after the borderClip for the window has settled down
363 * We use this to make sure our extra borderClip has the right origin
367 compClipNotify(WindowPtr pWin, int dx, int dy)
369 ScreenPtr pScreen = pWin->drawable.pScreen;
370 CompScreenPtr cs = GetCompScreen(pScreen);
371 CompWindowPtr cw = GetCompWindow(pWin);
374 if (cw->borderClipX != pWin->drawable.x ||
375 cw->borderClipY != pWin->drawable.y) {
376 RegionTranslate(&cw->borderClip,
377 pWin->drawable.x - cw->borderClipX,
378 pWin->drawable.y - cw->borderClipY);
379 cw->borderClipX = pWin->drawable.x;
380 cw->borderClipY = pWin->drawable.y;
383 if (cs->ClipNotify) {
384 pScreen->ClipNotify = cs->ClipNotify;
385 (*pScreen->ClipNotify) (pWin, dx, dy);
386 cs->ClipNotify = pScreen->ClipNotify;
387 pScreen->ClipNotify = compClipNotify;
392 * Returns TRUE if the window needs server-provided automatic redirect,
393 * which is true if the child and parent aren't both regular or ARGB visuals
397 compIsAlternateVisual(ScreenPtr pScreen, XID visual)
399 CompScreenPtr cs = GetCompScreen(pScreen);
402 for (i = 0; i < cs->numAlternateVisuals; i++)
403 if (cs->alternateVisuals[i] == visual)
409 compIsImplicitRedirectException(ScreenPtr pScreen,
410 XID parentVisual, XID winVisual)
412 CompScreenPtr cs = GetCompScreen(pScreen);
415 for (i = 0; i < cs->numImplicitRedirectExceptions; i++)
416 if (cs->implicitRedirectExceptions[i].parentVisual == parentVisual &&
417 cs->implicitRedirectExceptions[i].winVisual == winVisual)
424 compImplicitRedirect(WindowPtr pWin, WindowPtr pParent)
426 #ifdef _F_NO_IMPLICIT_REDIRECT_
428 Xserver redirect windows inside when the visuals(ex.depth) between parent of a window and the window is different.
429 Do not check the visuals between them in the composite extension when xserver redirect a window.
430 This make the 32 depth window get the root pixmap when compositor unredirect the 32 depth toplevel window.
435 ScreenPtr pScreen = pWin->drawable.pScreen;
436 XID winVisual = wVisual(pWin);
437 XID parentVisual = wVisual(pParent);
439 if (compIsImplicitRedirectException(pScreen, parentVisual, winVisual))
442 if (winVisual != parentVisual &&
443 (compIsAlternateVisual(pScreen, winVisual) ||
444 compIsAlternateVisual(pScreen, parentVisual)))
451 compFreeOldPixmap(WindowPtr pWin)
453 ScreenPtr pScreen = pWin->drawable.pScreen;
455 if (pWin->redirectDraw != RedirectDrawNone) {
456 CompWindowPtr cw = GetCompWindow(pWin);
458 if (cw->pOldPixmap) {
460 SLOG(LOG_INFO, "XORG_PIXMAP", "pix_id:%p, pixmap:%p (%dx%d) refcnt:%d-1 win_id:%p win:%p (%dx%d) view:%d\n",
461 cw->pOldPixmap->drawable.id,
463 cw->pOldPixmap->drawable.width,
464 cw->pOldPixmap->drawable.height,
465 cw->pOldPixmap->refcnt,
468 pWin->drawable.width,
469 pWin->drawable.height,
473 (*pScreen->DestroyPixmap) (cw->pOldPixmap);
474 cw->pOldPixmap = NullPixmap;
480 compMoveWindow(WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
482 ScreenPtr pScreen = pWin->drawable.pScreen;
483 CompScreenPtr cs = GetCompScreen(pScreen);
485 pScreen->MoveWindow = cs->MoveWindow;
486 (*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
487 cs->MoveWindow = pScreen->MoveWindow;
488 pScreen->MoveWindow = compMoveWindow;
490 compFreeOldPixmap(pWin);
491 compCheckTree(pScreen);
495 compResizeWindow(WindowPtr pWin, int x, int y,
496 unsigned int w, unsigned int h, WindowPtr pSib)
498 ScreenPtr pScreen = pWin->drawable.pScreen;
499 CompScreenPtr cs = GetCompScreen(pScreen);
501 pScreen->ResizeWindow = cs->ResizeWindow;
502 (*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
503 cs->ResizeWindow = pScreen->ResizeWindow;
504 pScreen->ResizeWindow = compResizeWindow;
506 compFreeOldPixmap(pWin);
507 compCheckTree(pWin->drawable.pScreen);
511 compChangeBorderWidth(WindowPtr pWin, unsigned int bw)
513 ScreenPtr pScreen = pWin->drawable.pScreen;
514 CompScreenPtr cs = GetCompScreen(pScreen);
516 pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
517 (*pScreen->ChangeBorderWidth) (pWin, bw);
518 cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
519 pScreen->ChangeBorderWidth = compChangeBorderWidth;
521 compFreeOldPixmap(pWin);
522 compCheckTree(pWin->drawable.pScreen);
526 compReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
528 ScreenPtr pScreen = pWin->drawable.pScreen;
529 CompScreenPtr cs = GetCompScreen(pScreen);
531 pScreen->ReparentWindow = cs->ReparentWindow;
533 * Remove any implicit redirect due to synthesized visual
535 if (compImplicitRedirect(pWin, pPriorParent))
536 compUnredirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
538 * Handle subwindows redirection
540 compUnredirectOneSubwindow(pPriorParent, pWin);
541 compRedirectOneSubwindow(pWin->parent, pWin);
543 * Add any implict redirect due to synthesized visual
545 if (compImplicitRedirect(pWin, pWin->parent))
546 compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
549 * Allocate any necessary redirect pixmap
550 * (this actually should never be true; pWin is always unmapped)
552 compCheckRedirect(pWin);
555 * Reset pixmap pointers as appropriate
557 if (pWin->parent && pWin->redirectDraw == RedirectDrawNone)
558 compSetPixmap(pWin, (*pScreen->GetWindowPixmap) (pWin->parent));
560 * Call down to next function
562 if (pScreen->ReparentWindow)
563 (*pScreen->ReparentWindow) (pWin, pPriorParent);
564 cs->ReparentWindow = pScreen->ReparentWindow;
565 pScreen->ReparentWindow = compReparentWindow;
566 compCheckTree(pWin->drawable.pScreen);
570 compCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
572 ScreenPtr pScreen = pWin->drawable.pScreen;
573 CompScreenPtr cs = GetCompScreen(pScreen);
576 if (pWin->redirectDraw != RedirectDrawNone) {
577 PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
578 CompWindowPtr cw = GetCompWindow(pWin);
580 assert(cw->oldx != COMP_ORIGIN_INVALID);
581 assert(cw->oldy != COMP_ORIGIN_INVALID);
582 if (cw->pOldPixmap) {
584 * Ok, the old bits are available in pOldPixmap and
585 * need to be copied to pNewPixmap.
590 dx = ptOldOrg.x - pWin->drawable.x;
591 dy = ptOldOrg.y - pWin->drawable.y;
592 RegionTranslate(prgnSrc, -dx, -dy);
596 RegionIntersect(&rgnDst, &pWin->borderClip, prgnSrc);
598 RegionTranslate(&rgnDst, -pPixmap->screen_x, -pPixmap->screen_y);
600 dx = dx + pPixmap->screen_x - cw->oldx;
601 dy = dy + pPixmap->screen_y - cw->oldy;
602 pGC = GetScratchGC(pPixmap->drawable.depth, pScreen);
604 BoxPtr pBox = RegionRects(&rgnDst);
605 int nBox = RegionNumRects(&rgnDst);
607 ValidateGC(&pPixmap->drawable, pGC);
609 (void) (*pGC->ops->CopyArea) (&cw->pOldPixmap->drawable,
612 pBox->x1 + dx, pBox->y1 + dy,
620 RegionUninit(&rgnDst);
623 dx = pPixmap->screen_x - cw->oldx;
624 dy = pPixmap->screen_y - cw->oldy;
629 pScreen->CopyWindow = cs->CopyWindow;
630 if (ptOldOrg.x != pWin->drawable.x || ptOldOrg.y != pWin->drawable.y) {
632 RegionTranslate(prgnSrc, dx, dy);
633 (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
635 RegionTranslate(prgnSrc, -dx, -dy);
640 RegionTranslate(prgnSrc,
641 pWin->drawable.x - ptOldOrg.x,
642 pWin->drawable.y - ptOldOrg.y);
643 DamageDamageRegion(&pWin->drawable, prgnSrc);
645 cs->CopyWindow = pScreen->CopyWindow;
646 pScreen->CopyWindow = compCopyWindow;
647 compCheckTree(pWin->drawable.pScreen);
651 compCreateWindow(WindowPtr pWin)
653 ScreenPtr pScreen = pWin->drawable.pScreen;
654 CompScreenPtr cs = GetCompScreen(pScreen);
657 pScreen->CreateWindow = cs->CreateWindow;
658 ret = (*pScreen->CreateWindow) (pWin);
659 if (pWin->parent && ret) {
660 CompSubwindowsPtr csw = GetCompSubwindows(pWin->parent);
661 CompClientWindowPtr ccw;
663 (*pScreen->SetWindowPixmap) (pWin,
664 (*pScreen->GetWindowPixmap) (pWin->
667 for (ccw = csw->clients; ccw; ccw = ccw->next)
668 compRedirectWindow(clients[CLIENT_ID(ccw->id)],
670 if (compImplicitRedirect(pWin, pWin->parent))
671 compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
673 cs->CreateWindow = pScreen->CreateWindow;
674 pScreen->CreateWindow = compCreateWindow;
675 compCheckTree(pWin->drawable.pScreen);
680 compDestroyWindow(WindowPtr pWin)
682 ScreenPtr pScreen = pWin->drawable.pScreen;
683 CompScreenPtr cs = GetCompScreen(pScreen);
685 CompSubwindowsPtr csw;
688 pScreen->DestroyWindow = cs->DestroyWindow;
689 while ((cw = GetCompWindow(pWin)))
690 FreeResource(cw->clients->id, RT_NONE);
691 while ((csw = GetCompSubwindows(pWin)))
692 FreeResource(csw->clients->id, RT_NONE);
694 if (pWin->redirectDraw != RedirectDrawNone) {
695 PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
697 compSetParentPixmap(pWin);
699 SLOG(LOG_INFO, "XORG_PIXMAP", "pix_id:%p, pixmap:%p (%dx%d) refcnt:%d-1 win_id:%p win:%p (%dx%d) view:%d\n",
700 pPixmap->drawable.id,
702 pPixmap->drawable.width,
703 pPixmap->drawable.height,
707 pWin->drawable.width,
708 pWin->drawable.height,
711 (*pScreen->DestroyPixmap) (pPixmap);
713 ret = (*pScreen->DestroyWindow) (pWin);
714 cs->DestroyWindow = pScreen->DestroyWindow;
715 pScreen->DestroyWindow = compDestroyWindow;
716 /* compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/
721 compSetRedirectBorderClip(WindowPtr pWin, RegionPtr pRegion)
723 CompWindowPtr cw = GetCompWindow(pWin);
728 * Align old border clip with new border clip
730 RegionTranslate(&cw->borderClip,
731 pWin->drawable.x - cw->borderClipX,
732 pWin->drawable.y - cw->borderClipY);
734 * Compute newly visible portion of window for repaint
736 RegionSubtract(&damage, pRegion, &cw->borderClip);
738 * Report that as damaged so it will be redrawn
740 DamageDamageRegion(&pWin->drawable, &damage);
741 RegionUninit(&damage);
743 * Save the new border clip region
745 RegionCopy(&cw->borderClip, pRegion);
746 cw->borderClipX = pWin->drawable.x;
747 cw->borderClipY = pWin->drawable.y;
751 compGetRedirectBorderClip(WindowPtr pWin)
753 CompWindowPtr cw = GetCompWindow(pWin);
755 return &cw->borderClip;
759 compWindowUpdateAutomatic(WindowPtr pWin)
761 CompWindowPtr cw = GetCompWindow(pWin);
762 ScreenPtr pScreen = pWin->drawable.pScreen;
763 WindowPtr pParent = pWin->parent;
764 PixmapPtr pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin);
765 PictFormatPtr pSrcFormat = PictureWindowFormat(pWin);
766 PictFormatPtr pDstFormat = PictureWindowFormat(pWin->parent);
767 PicturePtr pSrcPicture = NULL;
768 PicturePtr pDstPicture = NULL;
770 RegionPtr pRegion = DamageRegion(cw->damage);
771 XID subwindowMode = IncludeInferiors;
774 pSrcPicture = CreatePicture(0, &pSrcPixmap->drawable,
781 pDstPicture = CreatePicture(0, &pParent->drawable,
789 * First move the region from window to screen coordinates
791 RegionTranslate(pRegion, pWin->drawable.x, pWin->drawable.y);
794 * Clip against the "real" border clip
796 RegionIntersect(pRegion, pRegion, &cw->borderClip);
799 * Now translate from screen to dest coordinates
801 RegionTranslate(pRegion, -pParent->drawable.x, -pParent->drawable.y);
807 SetPictureClipRegion(pDstPicture, 0, 0, pRegion);
812 if (pSrcPicture && pDstPicture)
813 CompositePicture(PictOpSrc, pSrcPicture, 0, pDstPicture,
814 0, 0, /* src_x, src_y */
815 0, 0, /* msk_x, msk_y */
816 pSrcPixmap->screen_x - pParent->drawable.x,
817 pSrcPixmap->screen_y - pParent->drawable.y,
818 pSrcPixmap->drawable.width, pSrcPixmap->drawable.height);
820 FreePicture(pSrcPicture, 0);
822 FreePicture(pDstPicture, 0);
824 * Empty the damage region. This has the nice effect of
825 * rendering the translations above harmless
827 DamageEmpty(cw->damage);
831 compPaintWindowToParent(WindowPtr pWin)
833 compPaintChildrenToWindow(pWin);
835 if (pWin->redirectDraw != RedirectDrawNone) {
836 CompWindowPtr cw = GetCompWindow(pWin);
839 compWindowUpdateAutomatic(pWin);
846 compPaintChildrenToWindow(WindowPtr pWin)
850 if (!pWin->damagedDescendants)
853 for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
854 compPaintWindowToParent(pChild);
856 pWin->damagedDescendants = FALSE;
860 CompositeRealChildHead(WindowPtr pWin)
862 WindowPtr pChild, pChildBefore;
866 (screenIsSaved == SCREEN_SAVER_ON) &&
867 (HasSaverWindow(pWin->drawable.pScreen))) {
869 /* First child is the screen saver; see if next child is the overlay */
870 pChildBefore = pWin->firstChild;
871 pChild = pChildBefore->nextSib;
875 pChildBefore = NullWindow;
876 pChild = pWin->firstChild;
883 cs = GetCompScreen(pWin->drawable.pScreen);
884 if (pChild == cs->pOverlayWin) {
893 compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
894 int bw, WindowPtr pSib)
896 ScreenPtr pScreen = pWin->drawable.pScreen;
897 CompScreenPtr cs = GetCompScreen(pScreen);
899 WindowPtr pParent = pWin->parent;
903 if (cs->ConfigNotify) {
904 pScreen->ConfigNotify = cs->ConfigNotify;
905 ret = (*pScreen->ConfigNotify) (pWin, x, y, w, h, bw, pSib);
906 cs->ConfigNotify = pScreen->ConfigNotify;
907 pScreen->ConfigNotify = compConfigNotify;
913 if (pWin->redirectDraw == RedirectDrawNone)
916 compCheckTree(pScreen);
918 draw_x = pParent->drawable.x + x + bw;
919 draw_y = pParent->drawable.y + y + bw;
920 alloc_ret = compReallocPixmap(pWin, draw_x, draw_y, w, h, bw);
922 if (alloc_ret == FALSE)
927 #ifdef _F_INPUT_REDIRECTION_
929 print_matrix(char* name, pixman_transform_t* t)
931 #ifdef _PRINT_INPUT_REDIRECT_MATRIX_
933 ErrorF("[%s] %s = \n", __FUNCTION__, name);
936 ErrorF("\t%5.2f %5.2f %5.2f\n"
937 , pixman_fixed_to_double(t->matrix[i][0])
938 , pixman_fixed_to_double(t->matrix[i][1])
939 , pixman_fixed_to_double(t->matrix[i][2]));
941 #endif //_PRINT_INPUT_REDIRECT_MATRIX_
945 CompositeSetTransformPtr SetTransform;
946 } CompositeScreenRec, *CompositeScreenPtr;
948 static DevPrivateKeyRec compositePrivateKeyRec;
949 #define compositePrivatePrivateKey (&compositePrivateKeyRec)
951 static CompositeScreenPtr
952 CompositeGetScreen(ScreenPtr pScreen)
954 if (!dixPrivateKeyRegistered(compositePrivatePrivateKey))
956 return dixLookupPrivate(&pScreen->devPrivates, compositePrivatePrivateKey);
960 CompositeScreenInit (ScreenPtr pScreen, CompositeInfoPtr info)
962 CompositeScreenPtr cs = NULL;
964 if (!pScreen || !info)
967 if (!dixRegisterPrivateKey(&compositePrivateKeyRec, PRIVATE_SCREEN, 0))
970 cs = calloc(1, sizeof *cs);
974 cs->SetTransform = info->SetTransform;
976 dixSetPrivate(&pScreen->devPrivates, compositePrivatePrivateKey, cs);
978 ErrorF ("[%s] setup complete\n", __FUNCTION__);
984 CompositeCloseScreen (ScreenPtr pScreen)
986 CompositeScreenPtr cs = CompositeGetScreen(pScreen);
993 CompositeGetTransformPoint (WindowPtr pChild,
999 CompWindowPtr cw = GetCompWindow (pChild);
1001 if (cw && cw->pTransform)
1004 v.vector[0] = IntToxFixed(x);
1005 v.vector[1] = IntToxFixed(y);
1006 v.vector[2] = xFixed1;
1008 if(pixman_transform_point(cw->pTransform, &v))
1010 *tx = xFixedToInt(v.vector[0]);
1011 *ty = xFixedToInt(v.vector[1]);
1016 ErrorF("[%s] Failed on pixman_transform_point()\n", __FUNCTION__);
1023 /* There is no mesh, handle events like normal */
1024 if (!cw || !cw->pTransform)
1031 CompositeGetInvTransformPoint (WindowPtr pChild,
1039 CompWindowPtr cw = GetCompWindow (pChild);
1041 if (cw && cw->pInvTransform)
1044 v.vector[0] = IntToxFixed(x);
1045 v.vector[1] = IntToxFixed(y);
1046 v.vector[2] = xFixed1;
1048 if(pixman_transform_point(cw->pInvTransform, &v))
1050 *tx = xFixedToInt(v.vector[0]);
1051 *ty = xFixedToInt(v.vector[1]);
1056 ErrorF("[%s] Failed on pixman_transform_point(cw->pInvTransform, &v)\n",__FUNCTION__);
1063 /* There is no mesh, handle events like normal */
1064 if (!cw || !cw->pInvTransform)
1073 CompositeXYScreenToWindowRootCoordinate (WindowPtr pWin,
1086 CompositeXYScreenToWindowRootCoordinate (pWin->parent, x, y, &x, &y);
1087 CompositeGetInvTransformPoint(pWin, x, y, rootX, rootY);
1092 CompositeXYScreenFromWindowRootCoordinate (WindowPtr pWin,
1098 #ifdef _F_STEREOSCOPIC_LEFT_BUFFER_COODINATE_
1099 static Bool preferred_resolution_set = IS_NOT_SET;
1100 if(!preferred_resolution_set)
1102 ScreenPtr pScreen = pWin->drawable.pScreen;
1103 WindowPtr rootWin = pScreen->root;
1104 prefered_w = rootWin->drawable.width ;
1105 prefered_h = rootWin->drawable.height ;
1106 preferred_resolution_set = IS_SET;
1117 CompositeGetTransformPoint(pWin, x, y, &x, &y);
1118 CompositeXYScreenFromWindowRootCoordinate (pWin->parent,
1119 x, y, screenX, screenY);
1123 #ifdef _F_STEREOSCOPIC_LEFT_BUFFER_COODINATE_
1125 CompositeXYScreenFromWindowLeftBufferCoordinate (WindowPtr pWin,
1132 CompositeXYScreenFromWindowRootCoordinate (pWin,x, y, screenX, screenY);
1135 ScreenPtr pScreen = pWin->drawable.pScreen;
1136 WindowPtr rootWin = pScreen->root;
1137 fbW = rootWin->drawable.width ;
1138 fbH = rootWin->drawable.height ;
1140 *screenX = (*screenX * prefered_w)/fbW ;
1141 *screenY = (*screenY * prefered_h)/fbH ;
1148 CompositeSetCoordinateTransform (ClientPtr pClient,
1150 PictTransformPtr pTransform)
1152 CompSubwindowsPtr csw = NULL;
1153 CompWindowPtr cw = NULL;
1154 CompClientWindowPtr ccw;
1156 CompositeScreenPtr cs = CompositeGetScreen(pWin->drawable.pScreen);
1158 if (!dixPrivateKeyRegistered(CompSubwindowsPrivateKey))
1160 ErrorF("[%s:%d] Failed to CompSubwindowsPrivateKey\n", __FUNCTION__, __LINE__);
1164 csw = GetCompSubwindows (pWin->parent);
1166 if (!dixPrivateKeyRegistered(CompWindowPrivateKey))
1168 ErrorF("[%s:%d] Failed to CompWindowPrivateKey\n", __FUNCTION__, __LINE__);
1172 cw = GetCompWindow (pWin);
1175 * sub-window must be Manual update
1177 if (!csw || csw->update != CompositeRedirectManual)
1179 ErrorF("[%s] BadAccess : !csw || csw->update != CompositeRedirectManual\n", __FUNCTION__);
1184 * must be Manual update client
1186 for (ccw = csw->clients; ccw; ccw = ccw->next)
1187 if (ccw->update == CompositeRedirectManual &&
1188 CLIENT_ID (ccw->id) != pClient->index)
1190 ErrorF("[%s] BadAccess : CLIENT_ID (ccw->id) != pClient->index\n", __FUNCTION__);
1194 if (pTransform && pixman_transform_is_identity(pTransform))
1196 #ifdef _PRINT_INPUT_REDIRECT_MATRIX_
1197 ErrorF("[%s] pTransform=0 : pTransform && pixman_transform_is_identity(pTransform)\n", __FUNCTION__);
1198 #endif //_PRINT_INPUT_REDIRECT_MATRIX_
1203 print_matrix("pTransform", pTransform);
1204 #ifdef _PRINT_INPUT_REDIRECT_MATRIX_
1206 ErrorF("[%s] pTransform or pTransform->matrix is NULL !\n", __FUNCTION__);
1207 #endif //_PRINT_INPUT_REDIRECT_MATRIX_
1209 if (pTransform && !pixman_transform_invert(&inv, pTransform))
1211 ErrorF("[%s] BadRequest : !pixman_transform_invert(&inv, pTransform)\n", __FUNCTION__);
1217 if (!cw->pTransform)
1219 cw->pTransform = (PictTransform *) xalloc (sizeof (PictTransform));
1220 if (!cw->pTransform)
1222 ErrorF("[%s] BadAlloc : !cw->pTransform\n", __FUNCTION__);
1227 if (!cw->pInvTransform)
1229 cw->pInvTransform = (PictTransform *) xalloc (sizeof (PictTransform));
1230 if (!cw->pInvTransform)
1232 ErrorF("[%s] BadAlloc : !cw->pInvTransform\n", __FUNCTION__);
1237 *cw->pTransform = *pTransform;
1238 *cw->pInvTransform = inv;
1240 print_matrix("CW:transform", cw->pTransform);
1241 print_matrix("CW:inv transform", cw->pInvTransform);
1247 xfree (cw->pTransform);
1251 if (cw->pInvTransform)
1253 xfree(cw->pInvTransform);
1254 cw->pInvTransform = 0;
1258 if (cs && cs->SetTransform)
1260 int ret = cs->SetTransform(pWin, pTransform);
1264 ErrorF("[%s] SetTransform return %d \n", __FUNCTION__, ret);
1265 return BadImplementation;
1269 CheckCursorConfinement(pWin);
1273 #endif //_F_INPUT_REDIRECTION_