New upstream version 3.5.99.27

This commit is contained in:
geos_one
2025-08-08 20:00:36 +02:00
commit bc8d10cc33
4267 changed files with 1757978 additions and 0 deletions

View File

View File

@@ -0,0 +1,29 @@
#include <Server.tmpl>
NULL =
SRCS = compalloc.c compext.c compinit.c compoverlay.c compwindow.c
OBJS = compalloc.o compext.o compinit.o compoverlay.o compwindow.o
INCLUDES = -I../include -I../mi -I../Xext -I../render -I../xfixes \
-I../damageext -I../miext/damage -I$(EXTINCSRC) \
-I$(XINCLUDESRC) \
`pkg-config --cflags-only-I pixman-1`
LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
#if defined(NXAgentServer) && NXAgentServer
NX_DEFINES = -DNXAGENT_SERVER
#endif
DEFINES = \
$(NX_DEFINES) \
$(NULL)
NormalLibraryTarget(composite,$(OBJS))
NormalLibraryObjectRule()
LintLibraryTarget(composite,$(SRCS))
NormalLintTarget($(SRCS))
DependTarget()

View File

@@ -0,0 +1,710 @@
/*
* $Id: compalloc.c,v 1.7 2005/07/03 07:37:34 daniels Exp $
*
* Copyright © 2003 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "compint.h"
static void
compScreenUpdate(ScreenPtr pScreen)
{
compCheckTree(pScreen);
compPaintChildrenToWindow(pScreen, pScreen->root);
}
static void
compBlockHandler(int i, void *blockData, void *pTimeout, void *pReadmask)
{
ScreenPtr pScreen = screenInfo.screens[i];
CompScreenPtr cs = GetCompScreen(pScreen);
pScreen->BlockHandler = cs->BlockHandler;
compScreenUpdate(pScreen);
(*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
/* Next damage will restore the block handler */
cs->BlockHandler = NULL;
}
static void
compReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure)
{
WindowPtr pWin = (WindowPtr) closure;
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen(pScreen);
CompWindowPtr cw = GetCompWindow(pWin);
if (!cs->BlockHandler) {
cs->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = compBlockHandler;
}
cs->damaged = TRUE;
cw->damaged = TRUE;
/* Mark the ancestors */
/* We can't do this, Dave. No damagedDescendants support. */
/*
pWin = pWin->parent;
while (pWin) {
if (pWin->damagedDescendants)
break;
pWin->damagedDescendants = TRUE;
pWin = pWin->parent;
}
*/
}
static void
compDestroyDamage(DamagePtr pDamage, void *closure)
{
WindowPtr pWin = (WindowPtr) closure;
CompWindowPtr cw = GetCompWindow(pWin);
cw->damage = 0;
}
static Bool
compMarkWindows(WindowPtr pWin, WindowPtr *ppLayerWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
WindowPtr pLayerWin = pWin;
if (!pWin->viewable)
return FALSE;
(*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);
(*pScreen->MarkWindow) (pLayerWin->parent);
*ppLayerWin = pLayerWin;
return TRUE;
}
static void
compHandleMarkedWindows(WindowPtr pWin, WindowPtr pLayerWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
(*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTOther);
(*pScreen->HandleExposures) (pLayerWin->parent);
if (pScreen->PostValidateTree)
(*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, VTOther);
}
/*
* Redirect one window for one client
*/
int
compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update)
{
CompWindowPtr cw = GetCompWindow(pWin);
CompClientWindowPtr ccw;
CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
WindowPtr pLayerWin;
Bool anyMarked = FALSE;
if (pWin == cs->pOverlayWin) {
return Success;
}
if (!pWin->parent)
return BadMatch;
/*
* Only one Manual update is allowed
*/
if (cw && update == CompositeRedirectManual)
for (ccw = cw->clients; ccw; ccw = ccw->next)
if (ccw->update == CompositeRedirectManual)
return BadAccess;
/*
* Allocate per-client per-window structure
* The client *could* allocate multiple, but while supported,
* it is not expected to be common
*/
ccw = malloc (sizeof (CompClientWindowRec));
if (!ccw)
return BadAlloc;
ccw->id = FakeClientID (pClient->index);
ccw->update = update;
/*
* Now make sure there's a per-window structure to hang this from
*/
if (!cw)
{
cw = malloc (sizeof (CompWindowRec));
if (!cw)
{
free (ccw);
return BadAlloc;
}
cw->damage = DamageCreate (compReportDamage,
compDestroyDamage,
DamageReportNonEmpty,
FALSE,
pWin->drawable.pScreen,
pWin);
if (!cw->damage)
{
free (ccw);
free (cw);
return BadAlloc;
}
anyMarked = compMarkWindows(pWin, &pLayerWin);
RegionNull(&cw->borderClip);
cw->update = CompositeRedirectAutomatic;
cw->clients = 0;
cw->oldx = COMP_ORIGIN_INVALID;
cw->oldy = COMP_ORIGIN_INVALID;
cw->damageRegistered = FALSE;
cw->damaged = FALSE;
cw->pOldPixmap = NullPixmap;
FAKE_DIX_SET_WINDOW_PRIVATE(pWin, cw);
}
ccw->next = cw->clients;
cw->clients = ccw;
if (!AddResource (ccw->id, CompositeClientWindowType, pWin))
return BadAlloc;
if (ccw->update == CompositeRedirectManual)
{
if (!anyMarked)
anyMarked = compMarkWindows(pWin, &pLayerWin);
if (cw->damageRegistered) {
DamageUnregister (&pWin->drawable, cw->damage);
cw->damageRegistered = FALSE;
}
cw->update = CompositeRedirectManual;
}
else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered) {
if (!anyMarked)
anyMarked = compMarkWindows(pWin, &pLayerWin);
}
if (!compCheckRedirect (pWin))
{
FreeResource (ccw->id, RT_NONE);
return BadAlloc;
}
if (anyMarked)
compHandleMarkedWindows(pWin, pLayerWin);
return Success;
}
void
compRestoreWindow(WindowPtr pWin, PixmapPtr pPixmap)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
WindowPtr pParent = pWin->parent;
if (pParent->drawable.depth == pWin->drawable.depth) {
GCPtr pGC = GetScratchGC(pWin->drawable.depth, pScreen);
int bw = (int) pWin->borderWidth;
int x = bw;
int y = bw;
int w = pWin->drawable.width;
int h = pWin->drawable.height;
if (pGC) {
ChangeGCVal val;
val.val = IncludeInferiors;
dixChangeGC(NullClient, pGC, GCSubwindowMode, NULL, &val);
ValidateGC(&pWin->drawable, pGC);
(*pGC->ops->CopyArea) (&pPixmap->drawable,
&pWin->drawable, pGC, x, y, w, h, 0, 0);
FreeScratchGC(pGC);
}
}
}
/*
* Free one of the per-client per-window resources, clearing
* redirect and the per-window pointer as appropriate
*/
void
compFreeClientWindow (WindowPtr pWin, XID id)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompWindowPtr cw = GetCompWindow (pWin);
CompClientWindowPtr ccw, *prev;
Bool anyMarked = FALSE;
WindowPtr pLayerWin;
PixmapPtr pPixmap = NULL;
if (!cw)
return;
for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next)
{
if (ccw->id == id)
{
*prev = ccw->next;
if (ccw->update == CompositeRedirectManual)
cw->update = CompositeRedirectAutomatic;
free (ccw);
break;
}
}
if (!cw->clients)
{
anyMarked = compMarkWindows(pWin, &pLayerWin);
if (pWin->redirectDraw != RedirectDrawNone) {
pPixmap = (*pScreen->GetWindowPixmap) (pWin);
compSetParentPixmap(pWin);
}
if (cw->damage)
DamageDestroy (cw->damage);
RegionUninit(&cw->borderClip);
FAKE_DIX_SET_WINDOW_PRIVATE(pWin, NULL);
free (cw);
}
else if (cw->update == CompositeRedirectAutomatic &&
!cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
{
anyMarked = compMarkWindows(pWin, &pLayerWin);
DamageRegister (&pWin->drawable, cw->damage);
cw->damageRegistered = TRUE;
pWin->redirectDraw = RedirectDrawAutomatic;
DamageDamageRegion (&pWin->drawable, &pWin->borderSize);
}
if (anyMarked)
compHandleMarkedWindows(pWin, pLayerWin);
if (pPixmap) {
compRestoreWindow(pWin, pPixmap);
(*pScreen->DestroyPixmap) (pPixmap);
}
}
/*
* This is easy, just free the appropriate resource.
*/
int
compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
{
CompWindowPtr cw = GetCompWindow (pWin);
CompClientWindowPtr ccw;
if (!cw)
return BadValue;
for (ccw = cw->clients; ccw; ccw = ccw->next)
if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index)
{
FreeResource (ccw->id, RT_NONE);
return Success;
}
return BadValue;
}
/*
* Redirect all subwindows for one client
*/
int
compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
{
CompSubwindowsPtr csw = GetCompSubwindows (pWin);
CompClientWindowPtr ccw;
WindowPtr pChild;
/*
* Only one Manual update is allowed
*/
if (csw && update == CompositeRedirectManual)
for (ccw = csw->clients; ccw; ccw = ccw->next)
if (ccw->update == CompositeRedirectManual)
return BadAccess;
/*
* Allocate per-client per-window structure
* The client *could* allocate multiple, but while supported,
* it is not expected to be common
*/
ccw = malloc (sizeof (CompClientWindowRec));
if (!ccw)
return BadAlloc;
ccw->id = FakeClientID (pClient->index);
ccw->update = update;
/*
* Now make sure there's a per-window structure to hang this from
*/
if (!csw)
{
csw = malloc (sizeof (CompSubwindowsRec));
if (!csw)
{
free (ccw);
return BadAlloc;
}
csw->update = CompositeRedirectAutomatic;
csw->clients = 0;
FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, csw);
}
/*
* Redirect all existing windows
*/
for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
{
int ret = compRedirectWindow (pClient, pChild, update);
if (ret != Success)
{
for (pChild = pChild->nextSib; pChild; pChild = pChild->nextSib)
(void) compUnredirectWindow (pClient, pChild, update);
if (!csw->clients)
{
free (csw);
FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, NULL);
}
free (ccw);
return ret;
}
}
/*
* Hook into subwindows list
*/
ccw->next = csw->clients;
csw->clients = ccw;
if (!AddResource (ccw->id, CompositeClientSubwindowsType, pWin))
return BadAlloc;
if (ccw->update == CompositeRedirectManual)
{
csw->update = CompositeRedirectManual;
/*
* tell damage extension that damage events for this client are
* critical output
*/
DamageExtSetCritical (pClient, TRUE);
}
return Success;
}
/*
* Free one of the per-client per-subwindows resources,
* which frees one redirect per subwindow
*/
void
compFreeClientSubwindows (WindowPtr pWin, XID id)
{
CompSubwindowsPtr csw = GetCompSubwindows (pWin);
CompClientWindowPtr ccw, *prev;
WindowPtr pChild;
if (!csw)
return;
for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next)
{
if (ccw->id == id)
{
ClientPtr pClient = clients[CLIENT_ID(id)];
*prev = ccw->next;
if (ccw->update == CompositeRedirectManual)
{
/*
* tell damage extension that damage events for this client are
* critical output
*/
DamageExtSetCritical (pClient, FALSE);
csw->update = CompositeRedirectAutomatic;
if (pWin->mapped)
(*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, TRUE);
}
/*
* Unredirect all existing subwindows
*/
for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
(void) compUnredirectWindow (pClient, pChild, ccw->update);
free (ccw);
break;
}
}
/*
* Check if all of the per-client records are gone
*/
if (!csw->clients)
{
FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, NULL);
free (csw);
}
}
/*
* This is easy, just free the appropriate resource.
*/
int
compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
{
CompSubwindowsPtr csw = GetCompSubwindows (pWin);
CompClientWindowPtr ccw;
if (!csw)
return BadValue;
for (ccw = csw->clients; ccw; ccw = ccw->next)
if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index)
{
FreeResource (ccw->id, RT_NONE);
return Success;
}
return BadValue;
}
/*
* Add redirection information for one subwindow (during reparent)
*/
int
compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
{
CompSubwindowsPtr csw = GetCompSubwindows (pParent);
CompClientWindowPtr ccw;
if (!csw)
return Success;
for (ccw = csw->clients; ccw; ccw = ccw->next)
{
int ret = compRedirectWindow (clients[CLIENT_ID(ccw->id)],
pWin, ccw->update);
if (ret != Success)
return ret;
}
return Success;
}
/*
* Remove redirection information for one subwindow (during reparent)
*/
int
compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
{
CompSubwindowsPtr csw = GetCompSubwindows (pParent);
CompClientWindowPtr ccw;
if (!csw)
return Success;
for (ccw = csw->clients; ccw; ccw = ccw->next)
{
int ret = compUnredirectWindow (clients[CLIENT_ID(ccw->id)],
pWin, ccw->update);
if (ret != Success)
return ret;
}
return Success;
}
static PixmapPtr
compNewPixmap (WindowPtr pWin, int x, int y, int w, int h)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
WindowPtr pParent = pWin->parent;
PixmapPtr pPixmap;
/* usage_hint unsupported by our old server infrastructure. */
pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth,
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
if (!pPixmap)
return 0;
pPixmap->screen_x = x;
pPixmap->screen_y = y;
if (pParent->drawable.depth == pWin->drawable.depth) {
GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen);
/*
* Copy bits from the parent into the new pixmap so that it will
* have "reasonable" contents in case for background None areas.
*/
if (pGC)
{
ChangeGCVal val;
val.val = IncludeInferiors;
dixChangeGC(NullClient, pGC, GCSubwindowMode, NULL, &val);
ValidateGC(&pPixmap->drawable, pGC);
(*pGC->ops->CopyArea) (&pParent->drawable,
&pPixmap->drawable,
pGC,
x - pParent->drawable.x,
y - pParent->drawable.y,
w, h, 0, 0);
FreeScratchGC (pGC);
}
}
else {
PictFormatPtr pSrcFormat = compWindowFormat (pParent);
PictFormatPtr pDstFormat = compWindowFormat (pWin);
XID inferiors = IncludeInferiors;
int error;
PicturePtr pSrcPicture = CreatePicture(None,
&pParent->drawable,
pSrcFormat,
CPSubwindowMode,
&inferiors,
serverClient, &error);
PicturePtr pDstPicture = CreatePicture(None,
&pPixmap->drawable,
pDstFormat,
0, 0,
serverClient, &error);
if (pSrcPicture && pDstPicture) {
CompositePicture(PictOpSrc,
pSrcPicture,
NULL,
pDstPicture,
x - pParent->drawable.x,
y - pParent->drawable.y, 0, 0, 0, 0, w, h);
}
if (pSrcPicture)
FreePicture(pSrcPicture, 0);
if (pDstPicture)
FreePicture(pDstPicture, 0);
}
return pPixmap;
}
Bool
compAllocPixmap (WindowPtr pWin)
{
int bw = (int) pWin->borderWidth;
int x = pWin->drawable.x - bw;
int y = pWin->drawable.y - bw;
int w = pWin->drawable.width + (bw << 1);
int h = pWin->drawable.height + (bw << 1);
PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h);
CompWindowPtr cw = GetCompWindow (pWin);
if (!pPixmap)
return FALSE;
if (cw->update == CompositeRedirectAutomatic)
pWin->redirectDraw = RedirectDrawAutomatic;
else
pWin->redirectDraw = RedirectDrawManual;
compSetPixmap (pWin, pPixmap);
cw->oldx = COMP_ORIGIN_INVALID;
cw->oldy = COMP_ORIGIN_INVALID;
cw->damageRegistered = FALSE;
if (cw->update == CompositeRedirectAutomatic)
{
DamageRegister (&pWin->drawable, cw->damage);
cw->damageRegistered = TRUE;
}
/* Make sure our borderClip is up to date */
RegionUninit(&cw->borderClip);
RegionCopy(&cw->borderClip, &pWin->borderClip);
cw->borderClipX = pWin->drawable.x;
cw->borderClipY = pWin->drawable.y;
return TRUE;
}
void
compSetParentPixmap (WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
PixmapPtr pParentPixmap;
CompWindowPtr cw = GetCompWindow (pWin);
if (cw->damageRegistered)
{
DamageUnregister (&pWin->drawable, cw->damage);
cw->damageRegistered = FALSE;
DamageEmpty (cw->damage);
}
/*
* Move the parent-constrained border clip region back into
* the window so that ValidateTree will handle the unmap
* case correctly. Unmap adds the window borderClip to the
* parent exposed area; regions beyond the parent cause crashes
*/
RegionCopy(&pWin->borderClip, &cw->borderClip);
pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
pWin->redirectDraw = RedirectDrawNone;
compSetPixmap (pWin, pParentPixmap);
}
/*
* Make sure the pixmap is the right size and offset. Allocate a new
* pixmap to change size, adjust origin to change offset, leaving the
* old pixmap in cw->pOldPixmap so bits can be recovered
*/
Bool
compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y,
unsigned int w, unsigned int h, int bw)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
PixmapPtr pOld = (*pScreen->GetWindowPixmap) (pWin);
PixmapPtr pNew;
CompWindowPtr cw = GetCompWindow (pWin);
int pix_x, pix_y;
int pix_w, pix_h;
assert (cw && pWin->redirectDraw != RedirectDrawNone);
cw->oldx = pOld->screen_x;
cw->oldy = pOld->screen_y;
pix_x = draw_x - bw;
pix_y = draw_y - bw;
pix_w = w + (bw << 1);
pix_h = h + (bw << 1);
if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height)
{
pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h);
if (!pNew)
return FALSE;
cw->pOldPixmap = pOld;
compSetPixmap (pWin, pNew);
}
else
{
pNew = pOld;
cw->pOldPixmap = 0;
}
pNew->screen_x = pix_x;
pNew->screen_y = pix_y;
return TRUE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,492 @@
/*
* $Id: compinit.c,v 1.9 2005/07/03 07:37:34 daniels Exp $
*
* Copyright © 2003 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "compint.h"
#include "compositeext.h"
#ifndef NXAGENT_SERVER
DevPrivateKeyRec CompScreenPrivateKeyRec;
DevPrivateKeyRec CompWindowPrivateKeyRec;
DevPrivateKeyRec CompSubwindowsPrivateKeyRec;
#else /* !defined(NXAGENT_SERVER) */
int CompScreenPrivIndex = -1;
int CompWindowPrivIndex = -1;
int CompSubwindowsPrivIndex = -1;
#endif
static Bool
compCloseScreen (ScreenPtr pScreen)
{
CompScreenPtr cs = GetCompScreen (pScreen);
Bool ret;
free(cs->alternateVisuals);
pScreen->CloseScreen = cs->CloseScreen;
pScreen->InstallColormap = cs->InstallColormap;
pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
pScreen->ReparentWindow = cs->ReparentWindow;
/*
* Unsupported by our old Xserver infrastructure, replaced with direct calls to
* compReallocPixmap().
*/
/*
pScreen->ConfigNotify = cs->ConfigNotify;
*/
pScreen->MoveWindow = cs->MoveWindow;
pScreen->ResizeWindow = cs->ResizeWindow;
pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
pScreen->ClipNotify = cs->ClipNotify;
pScreen->UnrealizeWindow = cs->UnrealizeWindow;
pScreen->RealizeWindow = cs->RealizeWindow;
pScreen->DestroyWindow = cs->DestroyWindow;
pScreen->CreateWindow = cs->CreateWindow;
pScreen->CopyWindow = cs->CopyWindow;
pScreen->PositionWindow = cs->PositionWindow;
pScreen->GetImage = cs->GetImage;
pScreen->GetSpans = cs->GetSpans;
pScreen->SourceValidate = cs->SourceValidate;
free (cs);
FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, NULL);
ret = (*pScreen->CloseScreen) (pScreen);
return ret;
}
static void
compInstallColormap (ColormapPtr pColormap)
{
VisualPtr pVisual = pColormap->pVisual;
ScreenPtr pScreen = pColormap->pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
int a;
for (a = 0; a < cs->numAlternateVisuals; a++)
if (pVisual->vid == cs->alternateVisuals[a])
return;
pScreen->InstallColormap = cs->InstallColormap;
(*pScreen->InstallColormap) (pColormap);
cs->InstallColormap = pScreen->InstallColormap;
pScreen->InstallColormap = compInstallColormap;
}
/* Unsupported by current architecture, drop for now. */
#if 0
static void
compCheckBackingStore(WindowPtr pWin)
{
if (pWin->backingStore != NotUseful && !pWin->backStorage) {
compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
pWin->backStorage = TRUE;
}
else if (pWin->backingStore == NotUseful && pWin->backStorage) {
compUnredirectWindow(serverClient, pWin,
CompositeRedirectAutomatic);
pWin->backStorage = FALSE;
}
}
/* Fake backing store via automatic redirection */
static Bool
compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen(pScreen);
Bool ret;
pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
ret = pScreen->ChangeWindowAttributes(pWin, mask);
if (ret && (mask & CWBackingStore) &&
pScreen->backingStoreSupport != NotUseful)
compCheckBackingStore(pWin);
pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
return ret;
}
#endif /* 0 */
static void
compGetImage(DrawablePtr pDrawable,
int sx, int sy,
int w, int h,
unsigned int format, unsigned long planemask, char *pdstLine)
{
ScreenPtr pScreen = pDrawable->pScreen;
CompScreenPtr cs = GetCompScreen(pScreen);
pScreen->GetImage = cs->GetImage;
if (pDrawable->type == DRAWABLE_WINDOW)
compPaintChildrenToWindow(pScreen, (WindowPtr) pDrawable);
(*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine);
cs->GetImage = pScreen->GetImage;
pScreen->GetImage = compGetImage;
}
static void
compGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth,
int nspans, char *pdstStart)
{
ScreenPtr pScreen = pDrawable->pScreen;
CompScreenPtr cs = GetCompScreen(pScreen);
pScreen->GetSpans = cs->GetSpans;
if (pDrawable->type == DRAWABLE_WINDOW)
compPaintChildrenToWindow(pScreen, (WindowPtr) pDrawable);
(*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
cs->GetSpans = pScreen->GetSpans;
pScreen->GetSpans = compGetSpans;
}
static void
compSourceValidate(DrawablePtr pDrawable,
int x, int y,
int width, int height /* , unsigned int subWindowMode */ /* unsupported */)
{
ScreenPtr pScreen = pDrawable->pScreen;
CompScreenPtr cs = GetCompScreen(pScreen);
pScreen->SourceValidate = cs->SourceValidate;
if (pDrawable->type == DRAWABLE_WINDOW /* && subWindowMode == IncludeInferiors */ /* unsupported */)
compPaintChildrenToWindow(pScreen, (WindowPtr) pDrawable);
if (pScreen->SourceValidate)
(*pScreen->SourceValidate) (pDrawable, x, y, width, height /*,
subWindowMode */ /* unsupported */);
cs->SourceValidate = pScreen->SourceValidate;
pScreen->SourceValidate = compSourceValidate;
}
/*
* Add alternate visuals -- always expose an ARGB32 and RGB24 visual
*/
static DepthPtr
compFindVisuallessDepth (ScreenPtr pScreen, int d)
{
int i;
for (i = 0; i < pScreen->numDepths; i++)
{
DepthPtr depth = &pScreen->allowedDepths[i];
if (depth->depth == d)
{
/*
* Make sure it doesn't have visuals already
*/
if (depth->numVids)
return 0;
/*
* looks fine
*/
return depth;
}
}
/*
* If there isn't one, then it's gonna be hard to have
* an associated visual
*/
return 0;
}
/*
* Add a list of visual IDs to the list of visuals to implicitly redirect.
*/
static Bool
compRegisterAlternateVisuals(CompScreenPtr cs, VisualID * vids, int nVisuals)
{
VisualID *p;
p = reallocarray(cs->alternateVisuals,
cs->numAlternateVisuals + nVisuals, sizeof(VisualID));
if (p == NULL)
return FALSE;
memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals);
cs->alternateVisuals = p;
cs->numAlternateVisuals += nVisuals;
return TRUE;
}
Bool
CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids,
int nVisuals)
{
CompScreenPtr cs = GetCompScreen(pScreen);
return compRegisterAlternateVisuals(cs, vids, nVisuals);
}
Bool
CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
VisualID parentVisual,
VisualID winVisual)
{
CompScreenPtr cs = GetCompScreen(pScreen);
CompImplicitRedirectException *p;
p = reallocarray(cs->implicitRedirectExceptions,
cs->numImplicitRedirectExceptions + 1, sizeof(p[0]));
if (p == NULL)
return FALSE;
p[cs->numImplicitRedirectExceptions].parentVisual = parentVisual;
p[cs->numImplicitRedirectExceptions].winVisual = winVisual;
cs->implicitRedirectExceptions = p;
cs->numImplicitRedirectExceptions++;
return TRUE;
}
typedef struct _alternateVisual {
int depth;
CARD32 format;
} CompAlternateVisual;
static CompAlternateVisual altVisuals[] = {
#if COMP_INCLUDE_RGB24_VISUAL
{ 24, PICT_r8g8b8 },
#endif
{ 32, PICT_a8r8g8b8 },
};
static const int NUM_COMP_ALTERNATE_VISUALS = sizeof(altVisuals) /
sizeof(CompAlternateVisual);
static Bool
compAddAlternateVisual (ScreenPtr pScreen, CompScreenPtr cs,
CompAlternateVisual * alt)
{
VisualPtr visual;
DepthPtr depth;
PictFormatPtr pPictFormat;
unsigned long alphaMask;
/*
* The ARGB32 visual is always available. Other alternate depth visuals
* are only provided if their depth is less than the root window depth.
* There's no deep reason for this.
*/
if (alt->depth >= pScreen->rootDepth && alt->depth != 32)
return FALSE;
depth = compFindVisuallessDepth(pScreen, alt->depth);
if (!depth)
/* alt->depth doesn't exist or already has alternate visuals. */
return TRUE;
pPictFormat = PictureMatchFormat(pScreen, alt->depth, alt->format);
if (!pPictFormat)
return FALSE;
if (ResizeVisualArray(pScreen, 1, depth) == FALSE) {
return FALSE;
}
visual = pScreen->visuals + (pScreen->numVisuals - 1); /* the new one */
/* Initialize the visual */
visual->bitsPerRGBValue = 8;
if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) {
visual->class = PseudoColor;
visual->nplanes = PICT_FORMAT_BPP(alt->format);
visual->ColormapEntries = 1 << visual->nplanes;
}
else {
DirectFormatRec *direct = &pPictFormat->direct;
visual->class = TrueColor;
visual->redMask = ((unsigned long) direct->redMask) << direct->red;
visual->greenMask =
((unsigned long) direct->greenMask) << direct->green;
visual->blueMask = ((unsigned long) direct->blueMask) << direct->blue;
alphaMask = ((unsigned long) direct->alphaMask) << direct->alpha;
visual->offsetRed = direct->red;
visual->offsetGreen = direct->green;
visual->offsetBlue = direct->blue;
/*
* Include A bits in this (unlike GLX which includes only RGB)
* This lets DIX compute suitable masks for colormap allocations
*/
visual->nplanes = Ones(visual->redMask |
visual->greenMask |
visual->blueMask | alphaMask);
/* find widest component */
visual->ColormapEntries = (1 << max(Ones(visual->redMask),
max(Ones(visual->greenMask),
Ones(visual->blueMask))));
}
/* remember the visual ID to detect auto-update windows */
compRegisterAlternateVisuals(cs, &visual->vid, 1);
return TRUE;
}
static Bool
compAddAlternateVisuals(ScreenPtr pScreen, CompScreenPtr cs)
{
int alt, ret = 0;
for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++)
ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt);
return ! !ret;
}
Bool
compScreenInit (ScreenPtr pScreen)
{
CompScreenPtr cs;
#ifndef NXAGENT_SERVER
if (!dixRegisterPrivateKey(&CompScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
return FALSE;
if (!dixRegisterPrivateKey(&CompWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
return FALSE;
if (!dixRegisterPrivateKey(&CompSubwindowsPrivateKeyRec, PRIVATE_WINDOW, 0))
return FALSE;
#else /* !defined(NXAGENT_SERVER) */
if ((CompScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
return FALSE;
if ((CompWindowPrivIndex = AllocateWindowPrivateIndex()) < 0)
return FALSE;
if ((CompSubwindowsPrivIndex = AllocateWindowPrivateIndex()) < 0)
return FALSE;
if (!AllocateWindowPrivate (pScreen, CompWindowPrivIndex, 0))
return FALSE;
if (!AllocateWindowPrivate (pScreen, CompSubwindowsPrivIndex, 0))
return FALSE;
#endif
if (GetCompScreen (pScreen))
return TRUE;
cs = (CompScreenPtr) malloc (sizeof (CompScreenRec));
if (!cs)
return FALSE;
cs->damaged = FALSE;
cs->overlayWid = FakeClientID(0);
cs->pOverlayWin = NULL;
cs->pOverlayClients = NULL;
cs->numAlternateVisuals = 0;
cs->alternateVisuals = NULL;
cs->numImplicitRedirectExceptions = 0;
cs->implicitRedirectExceptions = NULL;
if (!compAddAlternateVisuals (pScreen, cs))
{
free (cs);
return FALSE;
}
if (!disableBackingStore)
pScreen->backingStoreSupport = WhenMapped;
cs->PositionWindow = pScreen->PositionWindow;
pScreen->PositionWindow = compPositionWindow;
cs->CopyWindow = pScreen->CopyWindow;
pScreen->CopyWindow = compCopyWindow;
cs->CreateWindow = pScreen->CreateWindow;
pScreen->CreateWindow = compCreateWindow;
cs->DestroyWindow = pScreen->DestroyWindow;
pScreen->DestroyWindow = compDestroyWindow;
cs->RealizeWindow = pScreen->RealizeWindow;
pScreen->RealizeWindow = compRealizeWindow;
cs->UnrealizeWindow = pScreen->UnrealizeWindow;
pScreen->UnrealizeWindow = compUnrealizeWindow;
cs->ClipNotify = pScreen->ClipNotify;
pScreen->ClipNotify = compClipNotify;
/*
* Unsupported by our old Xserver infrastructure, replaced with direct calls to
* compReallocPixmap().
*/
/*
cs->ConfigNotify = pScreen->ConfigNotify;
pScreen->ConfigNotify = compConfigNotify;
*/
cs->MoveWindow = pScreen->MoveWindow;
pScreen->MoveWindow = compMoveWindow;
cs->ResizeWindow = pScreen->ResizeWindow;
pScreen->ResizeWindow = compResizeWindow;
cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
pScreen->ChangeBorderWidth = compChangeBorderWidth;
cs->ReparentWindow = pScreen->ReparentWindow;
pScreen->ReparentWindow = compReparentWindow;
cs->InstallColormap = pScreen->InstallColormap;
pScreen->InstallColormap = compInstallColormap;
/* Unsupported by our current architecture, drop for now. */
/*
cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
*/
cs->BlockHandler = NULL;
cs->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = compCloseScreen;
cs->GetImage = pScreen->GetImage;
pScreen->GetImage = compGetImage;
cs->GetSpans = pScreen->GetSpans;
pScreen->GetSpans = compGetSpans;
cs->SourceValidate = pScreen->SourceValidate;
pScreen->SourceValidate = compSourceValidate;
FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, cs);
RegisterRealChildHeadProc(CompositeRealChildHead);
return TRUE;
}

View File

@@ -0,0 +1,360 @@
/*
* $Id: compint.h,v 1.8 2005/07/03 08:53:37 daniels Exp $
*
* Copyright © 2003 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#ifndef _COMPINT_H_
#define _COMPINT_H_
#include "misc.h"
#include "scrnintstr.h"
#include "os.h"
#include "regionstr.h"
#include "validate.h"
#include "windowstr.h"
#include "input.h"
#include "resource.h"
#include "colormapst.h"
#include "cursorstr.h"
#include "dixstruct.h"
#include "gcstruct.h"
#include "servermd.h"
#include "dixevents.h"
#include "globals.h"
#include "picturestr.h"
#include "extnsionst.h"
#include "mi.h"
#include "damage.h"
#include "damageextint.h"
#include "xfixes.h"
#include <nx-X11/extensions/compositeproto.h>
#include "compositeext.h"
#include <assert.h>
/*
* enable this for debugging
#define COMPOSITE_DEBUG
*/
typedef struct _CompClientWindow {
struct _CompClientWindow *next;
XID id;
int update;
} CompClientWindowRec, *CompClientWindowPtr;
typedef struct _CompWindow {
RegionRec borderClip;
DamagePtr damage; /* for automatic update mode */
Bool damageRegistered;
Bool damaged;
int update;
CompClientWindowPtr clients;
int oldx;
int oldy;
PixmapPtr pOldPixmap;
int borderClipX, borderClipY;
} CompWindowRec, *CompWindowPtr;
#define COMP_ORIGIN_INVALID 0x80000000
typedef struct _CompSubwindows {
int update;
CompClientWindowPtr clients;
} CompSubwindowsRec, *CompSubwindowsPtr;
#ifndef COMP_INCLUDE_RGB24_VISUAL
#define COMP_INCLUDE_RGB24_VISUAL 0
#endif
typedef struct _CompOverlayClientRec *CompOverlayClientPtr;
typedef struct _CompOverlayClientRec {
CompOverlayClientPtr pNext;
ClientPtr pClient;
ScreenPtr pScreen;
XID resource;
} CompOverlayClientRec;
typedef struct _CompImplicitRedirectException {
XID parentVisual;
XID winVisual;
} CompImplicitRedirectException;
typedef struct _CompScreen {
PositionWindowProcPtr PositionWindow;
CopyWindowProcPtr CopyWindow;
CreateWindowProcPtr CreateWindow;
DestroyWindowProcPtr DestroyWindow;
RealizeWindowProcPtr RealizeWindow;
UnrealizeWindowProcPtr UnrealizeWindow;
ClipNotifyProcPtr ClipNotify;
/*
* Called from ConfigureWindow, these
* three track changes to the offscreen storage
* geometry
*/
/*
* Unsupported by our old Xserver infrastructure, replaced with direct calls to
* compReallocPixmap().
*/
/*
ConfigNotifyProcPtr ConfigNotify;
*/
MoveWindowProcPtr MoveWindow;
ResizeWindowProcPtr ResizeWindow;
ChangeBorderWidthProcPtr ChangeBorderWidth;
/*
* Reparenting has an effect on Subwindows redirect
*/
ReparentWindowProcPtr ReparentWindow;
/*
* Colormaps for new visuals better not get installed
*/
InstallColormapProcPtr InstallColormap;
/*
* Fake backing store via automatic redirection
*/
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
ScreenBlockHandlerProcPtr BlockHandler;
CloseScreenProcPtr CloseScreen;
Bool damaged;
int numAlternateVisuals;
VisualID *alternateVisuals;
int numImplicitRedirectExceptions;
CompImplicitRedirectException *implicitRedirectExceptions;
WindowPtr pOverlayWin;
Window overlayWid;
CompOverlayClientPtr pOverlayClients;
GetImageProcPtr GetImage;
GetSpansProcPtr GetSpans;
SourceValidateProcPtr SourceValidate;
} CompScreenRec, *CompScreenPtr;
#ifndef NXAGENT_SERVER
extern DevPrivateKeyRec CompScreenPrivateKeyRec;
#define CompScreenPrivateKey (&CompScreenPrivateKeyRec)
extern DevPrivateKeyRec CompWindowPrivateKeyRec;
#define CompWindowPrivateKey (&CompWindowPrivateKeyRec)
extern DevPrivateKeyRec CompSubwindowsPrivateKeyRec;
#define CompSubwindowsPrivateKey (&CompSubwindowsPrivateKeyRec)
#define GetCompScreen(s) ((CompScreenPtr) \
dixLookupPrivate(&(s)->devPrivates, CompScreenPrivateKey))
#define GetCompWindow(w) ((CompWindowPtr) \
dixLookupPrivate(&(w)->devPrivates, CompWindowPrivateKey))
#define GetCompSubwindows(w) ((CompSubwindowsPtr) \
dixLookupPrivate(&(w)->devPrivates, CompSubwindowsPrivateKey))
#else /* !defined(NXAGENT_SERVER) */
extern int CompScreenPrivIndex;
extern int CompWindowPrivIndex;
extern int CompSubwindowsPrivIndex;
#define GetCompScreen(s) ((CompScreenPtr) (s)->devPrivates[CompScreenPrivIndex].ptr)
#define GetCompWindow(w) ((CompWindowPtr) (w)->devPrivates[CompWindowPrivIndex].ptr)
#define GetCompSubwindows(w) ((CompSubwindowsPtr) (w)->devPrivates[CompSubwindowsPrivIndex].ptr)
#endif /* !defined(NXAGENT_SERVER) */
extern RESTYPE CompositeClientSubwindowsType;
extern RESTYPE CompositeClientOverlayType;
/* Shim for less ifdefs within the actual code. */
#ifndef NXAGENT_SERVER
#define FAKE_DIX_SET_PRIVATE_IMPL(obj, privateKey, ptr_val) do { dixSetPrivate(&(obj)->devPrivates, privateKey, ptr_val); } while (0)
#define FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pScreen, CompScreenPrivateKey, ptr_val)
#define FAKE_DIX_SET_WINDOW_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompWindowPrivateKey, ptr_val)
#define FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompSubwindowsPrivateKey, ptr_val)
#else /* !defined(NXAGENT_SERVER) */
#define FAKE_DIX_SET_PRIVATE_IMPL(obj, privIndex, ptr_val) do { (obj)->devPrivates[privIndex].ptr = (void *) (ptr_val); } while (0)
#define FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pScreen, CompScreenPrivIndex, ptr_val)
#define FAKE_DIX_SET_WINDOW_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompWindowPrivIndex, ptr_val)
#define FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompSubwindowsPrivIndex, ptr_val)
#endif /* !defined(NXAGENT_SERVER) */
/*
* compalloc.c
*/
Bool
compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
void
compFreeClientWindow (WindowPtr pWin, XID id);
int
compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
int
compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
void
compFreeClientSubwindows (WindowPtr pWin, XID id);
int
compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
int
compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
int
compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
Bool
compAllocPixmap (WindowPtr pWin);
void
compSetParentPixmap(WindowPtr pWin);
void
compRestoreWindow(WindowPtr pWin, PixmapPtr pPixmap);
Bool
compReallocPixmap (WindowPtr pWin, int x, int y,
unsigned int w, unsigned int h, int bw);
/*
* compinit.c
*/
Bool
compScreenInit(ScreenPtr pScreen);
/*
* compoverlay.c
*/
void
compFreeOverlayClient(CompOverlayClientPtr pOcToDel);
CompOverlayClientPtr
compFindOverlayClient(ScreenPtr pScreen, ClientPtr pClient);
CompOverlayClientPtr
compCreateOverlayClient(ScreenPtr pScreen, ClientPtr pClient);
Bool
compCreateOverlayWindow(ScreenPtr pScreen);
void
compDestroyOverlayWindow(ScreenPtr pScreen);
/*
* compwindow.c
*/
#ifdef COMPOSITE_DEBUG
void
compCheckTree (ScreenPtr pScreen);
#else
#define compCheckTree(s)
#endif
PictFormatPtr
compWindowFormat (WindowPtr pWin);
void
compSetPixmap (WindowPtr pWin, PixmapPtr pPixmap);
Bool
compCheckRedirect (WindowPtr pWin);
Bool
compPositionWindow (WindowPtr pWin, int x, int y);
Bool
compRealizeWindow (WindowPtr pWin);
Bool
compUnrealizeWindow (WindowPtr pWin);
void
compClipNotify (WindowPtr pWin, int dx, int dy);
void
compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind);
void
compResizeWindow (WindowPtr pWin, int x, int y,
unsigned int w, unsigned int h, WindowPtr pSib);
void
compChangeBorderWidth (WindowPtr pWin, unsigned int border_width);
void
compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent);
Bool
compCreateWindow (WindowPtr pWin);
Bool
compDestroyWindow (WindowPtr pWin);
void
compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion);
RegionPtr
compGetRedirectBorderClip (WindowPtr pWin);
void
compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
void
compPaintChildrenToWindow(ScreenPtr pScreen, WindowPtr pWin);
WindowPtr
CompositeRealChildHead(WindowPtr pWin);
int
DeleteWindowNoInputDevices(void *value, XID wid);
/*
* Unsupported by our old Xserver infrastructure, replaced with direct calls to
* compReallocPixmap().
*/
/*
int
compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
int bw, WindowPtr pSib);
*/
void PanoramiXCompositeInit(void);
void PanoramiXCompositeReset(void);
#endif /* _COMPINT_H_ */

View File

@@ -0,0 +1,44 @@
/*
* Copyright © 2009 NVIDIA Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#ifndef _COMPOSITEEXT_H_
#define _COMPOSITEEXT_H_
#include "misc.h"
#include "scrnintstr.h"
extern _X_EXPORT Bool CompositeRegisterAlternateVisuals(ScreenPtr pScreen,
VisualID * vids,
int nVisuals);
extern _X_EXPORT Bool CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
VisualID parentVisual,
VisualID winVisual);
extern _X_EXPORT RESTYPE CompositeClientWindowType;
#endif /* _COMPOSITEEXT_H_ */

View File

@@ -0,0 +1,178 @@
/*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Copyright © 2003 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "compint.h"
#ifndef NXAGENT_SERVER
#include "xace.h"
#endif
#ifdef PANORAMIX
#include "panoramiXsrv.h"
#endif
/*
* Delete the given overlay client list element from its screen list.
*/
void
compFreeOverlayClient(CompOverlayClientPtr pOcToDel)
{
ScreenPtr pScreen = pOcToDel->pScreen;
CompScreenPtr cs = GetCompScreen(pScreen);
CompOverlayClientPtr *pPrev, pOc;
for (pPrev = &cs->pOverlayClients; (pOc = *pPrev); pPrev = &pOc->pNext) {
if (pOc == pOcToDel) {
*pPrev = pOc->pNext;
free(pOc);
break;
}
}
/* Destroy overlay window when there are no more clients using it */
if (cs->pOverlayClients == NULL)
compDestroyOverlayWindow(pScreen);
}
/*
* Return the client's first overlay client rec from the given screen
*/
CompOverlayClientPtr
compFindOverlayClient(ScreenPtr pScreen, ClientPtr pClient)
{
CompScreenPtr cs = GetCompScreen(pScreen);
CompOverlayClientPtr pOc;
for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext)
if (pOc->pClient == pClient)
return pOc;
return NULL;
}
/*
* Create an overlay client object for the given client
*/
CompOverlayClientPtr
compCreateOverlayClient(ScreenPtr pScreen, ClientPtr pClient)
{
CompScreenPtr cs = GetCompScreen(pScreen);
CompOverlayClientPtr pOc;
pOc = (CompOverlayClientPtr) malloc(sizeof(CompOverlayClientRec));
if (pOc == NULL)
return NULL;
pOc->pClient = pClient;
pOc->pScreen = pScreen;
pOc->resource = FakeClientID(pClient->index);
pOc->pNext = cs->pOverlayClients;
cs->pOverlayClients = pOc;
/*
* Create a resource for this element so it can be deleted
* when the client goes away.
*/
if (!AddResource(pOc->resource, CompositeClientOverlayType, (void *) pOc))
return NULL;
return pOc;
}
/*
* Create the overlay window and map it
*/
Bool
compCreateOverlayWindow(ScreenPtr pScreen)
{
CompScreenPtr cs = GetCompScreen(pScreen);
WindowPtr pRoot = pScreen->root;
WindowPtr pWin;
XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */
int result;
int w = pScreen->width;
int h = pScreen->height;
int x = 0, y = 0;
/* Unsupported by current architecture, disabled. */
#if 0
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
x = -pScreen->x;
y = -pScreen->y;
w = PanoramiXPixWidth;
h = PanoramiXPixHeight;
}
#endif
#endif
pWin = cs->pOverlayWin =
CreateWindow(cs->overlayWid, pRoot, x, y, w, h, 0,
InputOutput, CWBackPixmap | CWOverrideRedirect, &attrs[0],
pRoot->drawable.depth,
serverClient, pScreen->rootVisual, &result);
if (pWin == NULL)
return FALSE;
if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pWin))
return FALSE;
MapWindow(pWin, serverClient);
return TRUE;
}
/*
* Destroy the overlay window
*/
void
compDestroyOverlayWindow(ScreenPtr pScreen)
{
CompScreenPtr cs = GetCompScreen(pScreen);
cs->pOverlayWin = NullWindow;
FreeResource(cs->overlayWid, RT_NONE);
}

View File

@@ -0,0 +1,909 @@
/*
* $Id: compwindow.c,v 1.11 2005/07/03 07:37:34 daniels Exp $
*
* Copyright © 2003 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include "compint.h"
#ifdef PANORAMIX
#include "panoramiXsrv.h"
#endif
#ifdef COMPOSITE_DEBUG
static int
compCheckWindow (WindowPtr pWin, void * data)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
PixmapPtr pWinPixmap = (*pScreen->GetWindowPixmap) (pWin);
PixmapPtr pParentPixmap = pWin->parent ? (*pScreen->GetWindowPixmap) (pWin->parent) : 0;
PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap) (pScreen);
if (!pWin->parent)
{
assert (pWin->redirectDraw == RedriectDrawNone);
assert (pWinPixmap == pScreenPixmap);
}
else if (pWin->redirectDraw != RedirectDrawNone)
{
assert (pWinPixmap != pParentPixmap);
assert (pWinPixmap != pScreenPixmap);
}
else
{
assert (pWinPixmap == pParentPixmap);
}
assert (0 < pWinPixmap->refcnt && pWinPixmap->refcnt < 3);
assert (0 < pScreenPixmap->refcnt && pScreenPixmap->refcnt < 3);
if (pParentPixmap)
assert (0 <= pParentPixmap->refcnt && pParentPixmap->refcnt < 3);
return WT_WALKCHILDREN;
}
void
compCheckTree (ScreenPtr pScreen)
{
WalkTree (pScreen, compCheckWindow, 0);
}
#endif
typedef struct _compPixmapVisit {
WindowPtr pWindow;
PixmapPtr pPixmap;
} CompPixmapVisitRec, *CompPixmapVisitPtr;
static Bool
compRepaintBorder (ClientPtr pClient, void * closure)
{
WindowPtr pWindow;
#ifndef NXAGENT_SERVER
int rc =
dixLookupWindow(&pWindow, (XID) (intptr_t) closure, pClient,
DixWriteAccess);
#else
pWindow = SecurityLookupWindow((XID) (intptr_t) closure, pClient, DixWriteAccess);
int rc = pWindow ? Success : BadWindow;
#endif
if (rc == Success)
{
RegionRec exposed;
RegionNull(&exposed);
RegionSubtract(&exposed, &pWindow->borderClip, &pWindow->winSize);
#ifndef NXAGENT_SERVER
pWindow->drawable.pScreen->PaintWindowBorder(pWindow, &exposed, PW_BORDER);
#else
(*pWindow->drawable.pScreen->PaintWindowBorder)(pWindow, &exposed, PW_BORDER);
#endif
RegionUninit(&exposed);
}
return TRUE;
}
static int
compSetPixmapVisitWindow (WindowPtr pWindow, void * data)
{
CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data;
ScreenPtr pScreen = pWindow->drawable.pScreen;
if (pWindow != pVisit->pWindow && pWindow->redirectDraw != RedirectDrawNone)
return WT_DONTWALKCHILDREN;
(*pScreen->SetWindowPixmap) (pWindow, pVisit->pPixmap);
/*
* Recompute winSize and borderSize. This is duplicate effort
* when resizing pixmaps, but necessary when changing redirection.
* Might be nice to fix this.
*/
SetWinSize (pWindow);
SetBorderSize (pWindow);
if (HasBorder (pWindow))
QueueWorkProc (compRepaintBorder, serverClient,
(void *) (intptr_t) pWindow->drawable.id);
return WT_WALKCHILDREN;
}
void
compSetPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
{
CompPixmapVisitRec visitRec;
visitRec.pWindow = pWindow;
visitRec.pPixmap = pPixmap;
TraverseTree (pWindow, compSetPixmapVisitWindow, (void *) &visitRec);
compCheckTree (pWindow->drawable.pScreen);
}
Bool
compCheckRedirect (WindowPtr pWin)
{
CompWindowPtr cw = GetCompWindow (pWin);
CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
Bool should;
should = pWin->realized && (pWin->drawable.class != InputOnly) &&
(cw != NULL) && (pWin->parent != NULL);
/* Never redirect the overlay window */
if (cs->pOverlayWin != NULL) {
if (pWin == cs->pOverlayWin) {
should = FALSE;
}
}
if (should != (pWin->redirectDraw != RedirectDrawNone))
{
if (should)
return compAllocPixmap (pWin);
else {
ScreenPtr pScreen = pWin->drawable.pScreen;
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
compSetParentPixmap(pWin);
compRestoreWindow(pWin, pPixmap);
(*pScreen->DestroyPixmap) (pPixmap);
}
}
else if (should) {
if (cw->update == CompositeRedirectAutomatic)
pWin->redirectDraw = RedirectDrawAutomatic;
else
pWin->redirectDraw = RedirectDrawManual;
}
return TRUE;
}
static int
updateOverlayWindow(ScreenPtr pScreen)
{
CompScreenPtr cs;
WindowPtr pWin; /* overlay window */
XID vlist[2];
int w = pScreen->width;
int h = pScreen->height;
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
w = PanoramiXPixWidth;
h = PanoramiXPixHeight;
}
#endif
cs = GetCompScreen(pScreen);
if ((pWin = cs->pOverlayWin) != NULL) {
if ((pWin->drawable.width == w) && (pWin->drawable.height == h))
return Success;
/* Let's resize the overlay window. */
vlist[0] = w;
vlist[1] = h;
return ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin));
}
/* Let's be on the safe side and not assume an overlay window is
always allocated. */
return Success;
}
Bool
compPositionWindow (WindowPtr pWin, int x, int y)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
Bool ret = TRUE;
pScreen->PositionWindow = cs->PositionWindow;
/*
* "Shouldn't need this as all possible places should be wrapped
*
compCheckRedirect (pWin);
*/
#ifdef COMPOSITE_DEBUG
if ((pWin->redirectDraw != RedirectDrawNone) !=
(pWin->viewable && (GetCompWindow(pWin) != NULL)))
abort ();
#endif
if (pWin->redirectDraw != RedirectDrawNone)
{
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
int bw = wBorderWidth (pWin);
int nx = pWin->drawable.x - bw;
int ny = pWin->drawable.y - bw;
if (pPixmap->screen_x != nx || pPixmap->screen_y != ny)
{
pPixmap->screen_x = nx;
pPixmap->screen_y = ny;
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
}
if (!(*pScreen->PositionWindow) (pWin, x, y))
ret = FALSE;
cs->PositionWindow = pScreen->PositionWindow;
pScreen->PositionWindow = compPositionWindow;
compCheckTree (pWin->drawable.pScreen);
if (updateOverlayWindow(pScreen) != Success)
ret = FALSE;
return ret;
}
Bool
compRealizeWindow (WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
Bool ret = TRUE;
pScreen->RealizeWindow = cs->RealizeWindow;
compCheckRedirect (pWin);
if (!(*pScreen->RealizeWindow) (pWin))
ret = FALSE;
cs->RealizeWindow = pScreen->RealizeWindow;
pScreen->RealizeWindow = compRealizeWindow;
compCheckTree (pWin->drawable.pScreen);
return ret;
}
Bool
compUnrealizeWindow (WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
Bool ret = TRUE;
pScreen->UnrealizeWindow = cs->UnrealizeWindow;
compCheckRedirect (pWin);
if (!(*pScreen->UnrealizeWindow) (pWin))
ret = FALSE;
cs->UnrealizeWindow = pScreen->UnrealizeWindow;
pScreen->UnrealizeWindow = compUnrealizeWindow;
compCheckTree (pWin->drawable.pScreen);
return ret;
}
/*
* Called after the borderClip for the window has settled down
* We use this to make sure our extra borderClip has the right origin
*/
void
compClipNotify (WindowPtr pWin, int dx, int dy)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
CompWindowPtr cw = GetCompWindow (pWin);
if (cw)
{
if (cw->borderClipX != pWin->drawable.x ||
cw->borderClipY != pWin->drawable.y)
{
RegionTranslate(&cw->borderClip,
pWin->drawable.x - cw->borderClipX,
pWin->drawable.y - cw->borderClipY);
cw->borderClipX = pWin->drawable.x;
cw->borderClipY = pWin->drawable.y;
}
}
if (cs->ClipNotify)
{
pScreen->ClipNotify = cs->ClipNotify;
(*pScreen->ClipNotify) (pWin, dx, dy);
cs->ClipNotify = pScreen->ClipNotify;
pScreen->ClipNotify = compClipNotify;
}
}
/*
* Returns TRUE if the window needs server-provided automatic redirect,
* which is true if the child and parent aren't both regular or ARGB visuals
*/
static Bool
compIsAlternateVisual (ScreenPtr pScreen,
XID visual)
{
CompScreenPtr cs = GetCompScreen (pScreen);
int i;
for (i = 0; i < cs->numAlternateVisuals; i++)
if (cs->alternateVisuals[i] == visual)
return TRUE;
return FALSE;
}
static Bool
compIsImplicitRedirectException(ScreenPtr pScreen,
XID parentVisual, XID winVisual)
{
CompScreenPtr cs = GetCompScreen(pScreen);
int i;
for (i = 0; i < cs->numImplicitRedirectExceptions; i++)
if (cs->implicitRedirectExceptions[i].parentVisual == parentVisual &&
cs->implicitRedirectExceptions[i].winVisual == winVisual)
return TRUE;
return FALSE;
}
static Bool
compImplicitRedirect (WindowPtr pWin, WindowPtr pParent)
{
if (pParent)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
XID winVisual = wVisual (pWin);
XID parentVisual = wVisual (pParent);
if (compIsImplicitRedirectException(pScreen, parentVisual, winVisual))
return FALSE;
if (winVisual != parentVisual &&
(compIsAlternateVisual (pScreen, winVisual) ||
compIsAlternateVisual (pScreen, parentVisual)))
return TRUE;
}
return FALSE;
}
static void
compFreeOldPixmap(WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
if (pWin->redirectDraw != RedirectDrawNone) {
CompWindowPtr cw = GetCompWindow(pWin);
if (cw->pOldPixmap) {
(*pScreen->DestroyPixmap) (cw->pOldPixmap);
cw->pOldPixmap = NullPixmap;
}
}
}
void
compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
compCheckTree (pScreen);
if (pWin->redirectDraw != RedirectDrawNone) {
WindowPtr pParent;
int draw_x, draw_y;
unsigned int w, h, bw;
/* if this is a root window, can't be moved */
if (!(pParent = pWin->parent))
return;
bw = wBorderWidth (pWin);
draw_x = pParent->drawable.x + x + (int)bw;
draw_y = pParent->drawable.y + y + (int)bw;
w = pWin->drawable.width;
h = pWin->drawable.height;
compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
}
compCheckTree (pScreen);
pScreen->MoveWindow = cs->MoveWindow;
(*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
cs->MoveWindow = pScreen->MoveWindow;
pScreen->MoveWindow = compMoveWindow;
compFreeOldPixmap(pWin);
compCheckTree (pScreen);
}
void
compResizeWindow (WindowPtr pWin, int x, int y,
unsigned int w, unsigned int h, WindowPtr pSib)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
compCheckTree (pScreen);
if (pWin->redirectDraw != RedirectDrawNone)
{
WindowPtr pParent;
int draw_x, draw_y;
unsigned int bw;
/* if this is a root window, can't be moved */
if (!(pParent = pWin->parent))
return;
bw = wBorderWidth (pWin);
draw_x = pParent->drawable.x + x + (int)bw;
draw_y = pParent->drawable.y + y + (int)bw;
compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
}
compCheckTree (pScreen);
pScreen->ResizeWindow = cs->ResizeWindow;
(*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
cs->ResizeWindow = pScreen->ResizeWindow;
pScreen->ResizeWindow = compResizeWindow;
compFreeOldPixmap(pWin);
compCheckTree (pWin->drawable.pScreen);
}
void
compChangeBorderWidth (WindowPtr pWin, unsigned int bw)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
compCheckTree (pScreen);
if (pWin->redirectDraw != RedirectDrawNone)
{
WindowPtr pParent;
int draw_x, draw_y;
unsigned int w, h;
/* if this is a root window, can't be moved */
if (!(pParent = pWin->parent))
return;
draw_x = pWin->drawable.x;
draw_y = pWin->drawable.y;
w = pWin->drawable.width;
h = pWin->drawable.height;
compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
}
compCheckTree (pScreen);
pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
(*pScreen->ChangeBorderWidth) (pWin, bw);
cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
pScreen->ChangeBorderWidth = compChangeBorderWidth;
compFreeOldPixmap(pWin);
compCheckTree (pWin->drawable.pScreen);
}
void
compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
pScreen->ReparentWindow = cs->ReparentWindow;
/*
* Remove any implicit redirect due to synthesized visual
*/
if (compImplicitRedirect (pWin, pPriorParent))
compUnredirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
/*
* Handle subwindows redirection
*/
compUnredirectOneSubwindow (pPriorParent, pWin);
compRedirectOneSubwindow (pWin->parent, pWin);
/*
* Add any implict redirect due to synthesized visual
*/
if (compImplicitRedirect (pWin, pWin->parent))
compRedirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
/*
* Allocate any necessary redirect pixmap
* (this actually should never be true; pWin is always unmapped)
*/
compCheckRedirect (pWin);
/*
* Reset pixmap pointers as appropriate
*/
if (pWin->parent && pWin->redirectDraw == RedirectDrawNone)
compSetPixmap (pWin, (*pScreen->GetWindowPixmap) (pWin->parent));
/*
* Call down to next function
*/
if (pScreen->ReparentWindow)
(*pScreen->ReparentWindow) (pWin, pPriorParent);
cs->ReparentWindow = pScreen->ReparentWindow;
pScreen->ReparentWindow = compReparentWindow;
compCheckTree (pWin->drawable.pScreen);
}
void
compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
int dx = 0, dy = 0;
if (pWin->redirectDraw != RedirectDrawNone)
{
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
CompWindowPtr cw = GetCompWindow (pWin);
assert (cw->oldx != COMP_ORIGIN_INVALID);
assert (cw->oldy != COMP_ORIGIN_INVALID);
if (cw->pOldPixmap)
{
/*
* Ok, the old bits are available in pOldPixmap and
* need to be copied to pNewPixmap.
*/
RegionRec rgnDst;
GCPtr pGC;
dx = ptOldOrg.x - pWin->drawable.x;
dy = ptOldOrg.y - pWin->drawable.y;
RegionTranslate(prgnSrc, -dx, -dy);
RegionNull(&rgnDst);
RegionIntersect(&rgnDst,
&pWin->borderClip, prgnSrc);
RegionTranslate(&rgnDst,
-pPixmap->screen_x, -pPixmap->screen_y);
dx = dx + pPixmap->screen_x - cw->oldx;
dy = dy + pPixmap->screen_y - cw->oldy;
pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
if (pGC)
{
BoxPtr pBox = RegionRects (&rgnDst);
int nBox = RegionNumRects (&rgnDst);
ValidateGC(&pPixmap->drawable, pGC);
while (nBox--)
{
(void) (*pGC->ops->CopyArea) (&cw->pOldPixmap->drawable,
&pPixmap->drawable,
pGC,
pBox->x1 + dx, pBox->y1 + dy,
pBox->x2 - pBox->x1,
pBox->y2 - pBox->y1,
pBox->x1, pBox->y1);
pBox++;
}
FreeScratchGC (pGC);
}
RegionUninit (&rgnDst);
return;
}
dx = pPixmap->screen_x - cw->oldx;
dy = pPixmap->screen_y - cw->oldy;
ptOldOrg.x += dx;
ptOldOrg.y += dy;
}
pScreen->CopyWindow = cs->CopyWindow;
if (ptOldOrg.x != pWin->drawable.x || ptOldOrg.y != pWin->drawable.y)
{
if (dx || dy)
RegionTranslate(prgnSrc, dx, dy);
(*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
if (dx || dy)
RegionTranslate(prgnSrc, -dx, -dy);
}
else
{
ptOldOrg.x -= dx;
ptOldOrg.y -= dy;
RegionTranslate(prgnSrc,
pWin->drawable.x - ptOldOrg.x,
pWin->drawable.y - ptOldOrg.y);
DamageDamageRegion (&pWin->drawable, prgnSrc);
}
cs->CopyWindow = pScreen->CopyWindow;
pScreen->CopyWindow = compCopyWindow;
compCheckTree (pWin->drawable.pScreen);
}
Bool
compCreateWindow (WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
Bool ret;
pScreen->CreateWindow = cs->CreateWindow;
ret = (*pScreen->CreateWindow) (pWin);
if (pWin->parent && ret)
{
CompSubwindowsPtr csw = GetCompSubwindows (pWin->parent);
CompClientWindowPtr ccw;
PixmapPtr parent_pixmap = (*pScreen->GetWindowPixmap)(pWin->parent);
PixmapPtr window_pixmap = (*pScreen->GetWindowPixmap)(pWin);
if (window_pixmap != parent_pixmap)
(*pScreen->SetWindowPixmap) (pWin, parent_pixmap);
if (csw)
for (ccw = csw->clients; ccw; ccw = ccw->next)
compRedirectWindow (clients[CLIENT_ID(ccw->id)],
pWin, ccw->update);
if (compImplicitRedirect (pWin, pWin->parent))
compRedirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
}
cs->CreateWindow = pScreen->CreateWindow;
pScreen->CreateWindow = compCreateWindow;
compCheckTree (pWin->drawable.pScreen);
return ret;
}
Bool
compDestroyWindow (WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen (pScreen);
CompWindowPtr cw;
CompSubwindowsPtr csw;
Bool ret;
pScreen->DestroyWindow = cs->DestroyWindow;
while ((cw = GetCompWindow (pWin)))
FreeResource (cw->clients->id, RT_NONE);
while ((csw = GetCompSubwindows (pWin)))
FreeResource (csw->clients->id, RT_NONE);
if (pWin->redirectDraw != RedirectDrawNone) {
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
compSetParentPixmap (pWin);
(*pScreen->DestroyPixmap) (pPixmap);
}
ret = (*pScreen->DestroyWindow) (pWin);
cs->DestroyWindow = pScreen->DestroyWindow;
pScreen->DestroyWindow = compDestroyWindow;
/* compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/
return ret;
}
void
compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion)
{
CompWindowPtr cw = GetCompWindow (pWin);
RegionRec damage;
RegionNull(&damage);
/*
* Align old border clip with new border clip
*/
RegionTranslate(&cw->borderClip,
pWin->drawable.x - cw->borderClipX,
pWin->drawable.y - cw->borderClipY);
/*
* Compute newly visible portion of window for repaint
*/
RegionSubtract(&damage, pRegion, &cw->borderClip);
/*
* Report that as damaged so it will be redrawn
*/
DamageDamageRegion (&pWin->drawable, &damage);
RegionUninit(&damage);
/*
* Save the new border clip region
*/
RegionCopy(&cw->borderClip, pRegion);
cw->borderClipX = pWin->drawable.x;
cw->borderClipY = pWin->drawable.y;
}
RegionPtr
compGetRedirectBorderClip (WindowPtr pWin)
{
CompWindowPtr cw = GetCompWindow (pWin);
return &cw->borderClip;
}
static VisualPtr
compGetWindowVisual (WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
VisualID vid = wVisual (pWin);
int i;
for (i = 0; i < pScreen->numVisuals; i++)
if (pScreen->visuals[i].vid == vid)
return &pScreen->visuals[i];
return 0;
}
PictFormatPtr
compWindowFormat (WindowPtr pWin)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
return PictureMatchVisual (pScreen, pWin->drawable.depth,
compGetWindowVisual (pWin));
}
static void
compWindowUpdateAutomatic (WindowPtr pWin)
{
CompWindowPtr cw = GetCompWindow (pWin);
ScreenPtr pScreen = pWin->drawable.pScreen;
WindowPtr pParent = pWin->parent;
PixmapPtr pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin);
PictFormatPtr pSrcFormat = compWindowFormat (pWin);
PictFormatPtr pDstFormat = compWindowFormat (pWin->parent);
int error;
RegionPtr pRegion = DamageRegion (cw->damage);
PicturePtr pSrcPicture = CreatePicture (0, &pSrcPixmap->drawable,
pSrcFormat,
0, 0,
serverClient,
&error);
XID subwindowMode = IncludeInferiors;
PicturePtr pDstPicture = CreatePicture (0, &pParent->drawable,
pDstFormat,
CPSubwindowMode,
&subwindowMode,
serverClient,
&error);
/*
* First move the region from window to screen coordinates
*/
RegionTranslate(pRegion,
pWin->drawable.x, pWin->drawable.y);
/*
* Clip against the "real" border clip
*/
RegionIntersect(pRegion, pRegion, &cw->borderClip);
/*
* Now translate from screen to dest coordinates
*/
RegionTranslate(pRegion,
-pParent->drawable.x, -pParent->drawable.y);
/*
* Clip the picture
*/
SetPictureClipRegion (pDstPicture, 0, 0, pRegion);
/*
* And paint
*/
CompositePicture (PictOpSrc,
pSrcPicture,
0,
pDstPicture,
0, 0, /* src_x, src_y */
0, 0, /* msk_x, msk_y */
pSrcPixmap->screen_x - pParent->drawable.x,
pSrcPixmap->screen_y - pParent->drawable.y,
pSrcPixmap->drawable.width,
pSrcPixmap->drawable.height);
FreePicture (pSrcPicture, 0);
FreePicture (pDstPicture, 0);
/*
* Empty the damage region. This has the nice effect of
* rendering the translations above harmless
*/
DamageEmpty (cw->damage);
}
static void
compPaintWindowToParent(WindowPtr pWin)
{
compPaintChildrenToWindow(pWin->drawable.pScreen, pWin);
if (pWin->redirectDraw != RedirectDrawNone) {
CompWindowPtr cw = GetCompWindow(pWin);
if (cw->damaged) {
compWindowUpdateAutomatic(pWin);
cw->damaged = FALSE;
}
}
}
void
compPaintChildrenToWindow(ScreenPtr pScreen, WindowPtr pWin)
{
WindowPtr pChild;
CompScreenPtr cs = GetCompScreen(pScreen);
if (!cs->damaged)
return;
for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
compPaintWindowToParent(pChild);
cs->damaged = FALSE;
}
WindowPtr
CompositeRealChildHead(WindowPtr pWin)
{
WindowPtr pChild, pChildBefore;
CompScreenPtr cs;
if (!pWin->parent &&
(screenIsSaved == SCREEN_SAVER_ON) &&
(HasSaverWindow(pWin->drawable.pScreen->myNum))) {
/* First child is the screen saver; see if next child is the overlay */
pChildBefore = pWin->firstChild;
pChild = pChildBefore->nextSib;
}
else {
pChildBefore = NullWindow;
pChild = pWin->firstChild;
}
if (!pChild) {
return NullWindow;
}
cs = GetCompScreen(pWin->drawable.pScreen);
if (pChild == cs->pOverlayWin) {
return pChild;
}
else {
return pChildBefore;
}
}
/* ConfigNotify not implemented... replace with the old pixmap reallocation algorithm... */
/*
int
compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
int bw, WindowPtr pSib)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
CompScreenPtr cs = GetCompScreen(pScreen);
Bool ret = 0;
WindowPtr pParent = pWin->parent;
int draw_x, draw_y;
Bool alloc_ret;
if (cs->ConfigNotify) {
pScreen->ConfigNotify = cs->ConfigNotify;
ret = (*pScreen->ConfigNotify) (pWin, x, y, w, h, bw, pSib);
cs->ConfigNotify = pScreen->ConfigNotify;
pScreen->ConfigNotify = compConfigNotify;
if (ret)
return ret;
}
if (pWin->redirectDraw == RedirectDrawNone)
return Success;
compCheckTree(pScreen);
draw_x = pParent->drawable.x + x + bw;
draw_y = pParent->drawable.y + y + bw;
alloc_ret = compReallocPixmap(pWin, draw_x, draw_y, w, h, bw);
if (alloc_ret == FALSE)
return BadAlloc;
return Success;
}
*/