Integrate COMPOSITEWRAP branch including composite wrapper. This code still
has several issues, including: - CopyWindow and PaintWindow wrappers missing (will be done soon) - Some segfaults seen in the Render wrappers. - Xprt server build breaks with Composite. - DDXs must be recompiled for Composite due to VisualRec size change. - Composite bugs pointed out by Deron Johnson in email. Also, reorder XFixes initialization according to comments by Keith which are also in xserver CVS.
This commit is contained in:
parent
8763cca7f9
commit
d690556d49
|
@ -0,0 +1,537 @@
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* 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_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
#include "compint.h"
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
cs->damaged = TRUE;
|
||||||
|
cw->damaged = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
compDestroyDamage (DamagePtr pDamage, void *closure)
|
||||||
|
{
|
||||||
|
WindowPtr pWin = (WindowPtr) closure;
|
||||||
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
|
|
||||||
|
cw->damage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Redirect one window for one client
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
|
||||||
|
{
|
||||||
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
|
CompClientWindowPtr ccw;
|
||||||
|
Bool wasMapped = pWin->mapped;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 = xalloc (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 = xalloc (sizeof (CompWindowRec));
|
||||||
|
if (!cw)
|
||||||
|
{
|
||||||
|
xfree (ccw);
|
||||||
|
return BadAlloc;
|
||||||
|
}
|
||||||
|
cw->damage = DamageCreate (compReportDamage,
|
||||||
|
compDestroyDamage,
|
||||||
|
DamageReportNonEmpty,
|
||||||
|
FALSE,
|
||||||
|
pWin->drawable.pScreen,
|
||||||
|
pWin);
|
||||||
|
if (!cw->damage)
|
||||||
|
{
|
||||||
|
xfree (ccw);
|
||||||
|
xfree (cw);
|
||||||
|
return BadAlloc;
|
||||||
|
}
|
||||||
|
if (wasMapped)
|
||||||
|
UnmapWindow (pWin, FALSE);
|
||||||
|
|
||||||
|
REGION_NULL (pScreen, &cw->borderClip);
|
||||||
|
cw->update = CompositeRedirectAutomatic;
|
||||||
|
cw->clients = 0;
|
||||||
|
cw->oldx = COMP_ORIGIN_INVALID;
|
||||||
|
cw->oldy = COMP_ORIGIN_INVALID;
|
||||||
|
cw->damageRegistered = FALSE;
|
||||||
|
cw->damaged = FALSE;
|
||||||
|
pWin->devPrivates[CompWindowPrivateIndex].ptr = cw;
|
||||||
|
}
|
||||||
|
ccw->next = cw->clients;
|
||||||
|
cw->clients = ccw;
|
||||||
|
if (!AddResource (ccw->id, CompositeClientWindowType, pWin))
|
||||||
|
return BadAlloc;
|
||||||
|
if (ccw->update == CompositeRedirectManual)
|
||||||
|
{
|
||||||
|
if (cw->damageRegistered)
|
||||||
|
{
|
||||||
|
DamageUnregister (&pWin->drawable, cw->damage);
|
||||||
|
cw->damageRegistered = FALSE;
|
||||||
|
}
|
||||||
|
cw->update = CompositeRedirectManual;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!compCheckRedirect (pWin))
|
||||||
|
{
|
||||||
|
FreeResource (ccw->id, RT_NONE);
|
||||||
|
return BadAlloc;
|
||||||
|
}
|
||||||
|
if (wasMapped && !pWin->mapped)
|
||||||
|
{
|
||||||
|
Bool overrideRedirect = pWin->overrideRedirect;
|
||||||
|
pWin->overrideRedirect = TRUE;
|
||||||
|
MapWindow (pWin, pClient);
|
||||||
|
pWin->overrideRedirect = overrideRedirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free one of the per-client per-window resources, clearing
|
||||||
|
* redirect and the per-window pointer as appropriate
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
compFreeClientWindow (WindowPtr pWin, XID id)
|
||||||
|
{
|
||||||
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
|
CompClientWindowPtr ccw, *prev;
|
||||||
|
Bool wasMapped = pWin->mapped;
|
||||||
|
|
||||||
|
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;
|
||||||
|
xfree (ccw);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!cw->clients)
|
||||||
|
{
|
||||||
|
if (wasMapped)
|
||||||
|
UnmapWindow (pWin, FALSE);
|
||||||
|
|
||||||
|
if (pWin->redirectDraw)
|
||||||
|
compFreePixmap (pWin);
|
||||||
|
|
||||||
|
if (cw->damage)
|
||||||
|
DamageDestroy (cw->damage);
|
||||||
|
|
||||||
|
REGION_UNINIT (pScreen, &cw->borderClip);
|
||||||
|
|
||||||
|
pWin->devPrivates[CompWindowPrivateIndex].ptr = 0;
|
||||||
|
xfree (cw);
|
||||||
|
}
|
||||||
|
else if (cw->update == CompositeRedirectAutomatic &&
|
||||||
|
!cw->damageRegistered && pWin->redirectDraw)
|
||||||
|
{
|
||||||
|
DamageRegister (&pWin->drawable, cw->damage);
|
||||||
|
cw->damageRegistered = TRUE;
|
||||||
|
DamageDamageRegion (&pWin->drawable, &pWin->borderSize);
|
||||||
|
}
|
||||||
|
if (wasMapped && !pWin->mapped)
|
||||||
|
{
|
||||||
|
Bool overrideRedirect = pWin->overrideRedirect;
|
||||||
|
pWin->overrideRedirect = TRUE;
|
||||||
|
MapWindow (pWin, clients[CLIENT_ID(id)]);
|
||||||
|
pWin->overrideRedirect = overrideRedirect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 = xalloc (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 = xalloc (sizeof (CompSubwindowsRec));
|
||||||
|
if (!csw)
|
||||||
|
{
|
||||||
|
xfree (ccw);
|
||||||
|
return BadAlloc;
|
||||||
|
}
|
||||||
|
csw->update = CompositeRedirectAutomatic;
|
||||||
|
csw->clients = 0;
|
||||||
|
pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 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)
|
||||||
|
{
|
||||||
|
xfree (csw);
|
||||||
|
pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 0;
|
||||||
|
}
|
||||||
|
xfree (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);
|
||||||
|
|
||||||
|
xfree (ccw);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if all of the per-client records are gone
|
||||||
|
*/
|
||||||
|
if (!csw->clients)
|
||||||
|
{
|
||||||
|
pWin->devPrivates[CompSubwindowsPrivateIndex].ptr = 0;
|
||||||
|
xfree (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
compAllocPixmap (WindowPtr pWin)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||||
|
PixmapPtr pPixmap;
|
||||||
|
int bw = (int) pWin->borderWidth;
|
||||||
|
int x, y, w, h;
|
||||||
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
|
|
||||||
|
x = pWin->drawable.x - bw;
|
||||||
|
y = pWin->drawable.y - bw;
|
||||||
|
w = pWin->drawable.width + (bw << 1);
|
||||||
|
h = pWin->drawable.height + (bw << 1);
|
||||||
|
pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth);
|
||||||
|
if (!pPixmap)
|
||||||
|
return FALSE;
|
||||||
|
pPixmap->screen_x = x;
|
||||||
|
pPixmap->screen_y = y;
|
||||||
|
pWin->redirectDraw = TRUE;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
compFreePixmap (WindowPtr pWin)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||||
|
PixmapPtr pRedirectPixmap, pParentPixmap;
|
||||||
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
|
|
||||||
|
if (cw->damageRegistered)
|
||||||
|
{
|
||||||
|
DamageUnregister (&pWin->drawable, cw->damage);
|
||||||
|
cw->damageRegistered = FALSE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
REGION_COPY (pScreen, &pWin->borderClip, &cw->borderClip);
|
||||||
|
pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||||
|
pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
|
||||||
|
pWin->redirectDraw = FALSE;
|
||||||
|
compSetPixmap (pWin, pParentPixmap);
|
||||||
|
(*pScreen->DestroyPixmap) (pRedirectPixmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
unsigned int pix_w, pix_h;
|
||||||
|
|
||||||
|
assert (cw && pWin->redirectDraw);
|
||||||
|
pix_x = draw_x - bw;
|
||||||
|
pix_y = draw_y - bw;
|
||||||
|
pix_w = w + (bw << 1);
|
||||||
|
pix_h = h + (bw << 1);
|
||||||
|
cw->oldx = pOld->screen_x;
|
||||||
|
cw->oldy = pOld->screen_y;
|
||||||
|
if (pix_w != pOld->drawable.width ||
|
||||||
|
pix_h != pOld->drawable.height)
|
||||||
|
{
|
||||||
|
GCPtr pGC;
|
||||||
|
|
||||||
|
pNew = (*pScreen->CreatePixmap) (pScreen, pix_w, pix_h, pWin->drawable.depth);
|
||||||
|
if (!pNew)
|
||||||
|
return FALSE;
|
||||||
|
cw->pOldPixmap = pOld;
|
||||||
|
compSetPixmap (pWin, pNew);
|
||||||
|
/*
|
||||||
|
* Copy new bits to align at same place on the screen. CopyWindow
|
||||||
|
* calls will patch up any differences
|
||||||
|
*/
|
||||||
|
pGC = GetScratchGC (pNew->drawable.depth, pScreen);
|
||||||
|
if (pGC)
|
||||||
|
{
|
||||||
|
ValidateGC(&pNew->drawable, pGC);
|
||||||
|
(*pGC->ops->CopyArea) (&pOld->drawable,
|
||||||
|
&pNew->drawable,
|
||||||
|
pGC,
|
||||||
|
pWin->drawable.x - draw_x,
|
||||||
|
pWin->drawable.y - draw_y,
|
||||||
|
pix_w, pix_h,
|
||||||
|
0, 0);
|
||||||
|
FreeScratchGC (pGC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pNew = pOld;
|
||||||
|
cw->pOldPixmap = 0;
|
||||||
|
}
|
||||||
|
pNew->screen_x = pix_x;
|
||||||
|
pNew->screen_y = pix_y;
|
||||||
|
return TRUE;
|
||||||
|
}
|
|
@ -0,0 +1,408 @@
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* 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_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
#include "compint.h"
|
||||||
|
|
||||||
|
static CARD8 CompositeReqCode;
|
||||||
|
int CompositeClientPrivateIndex;
|
||||||
|
RESTYPE CompositeClientWindowType;
|
||||||
|
RESTYPE CompositeClientSubwindowsType;
|
||||||
|
|
||||||
|
typedef struct _CompositeClient {
|
||||||
|
int major_version;
|
||||||
|
int minor_version;
|
||||||
|
} CompositeClientRec, *CompositeClientPtr;
|
||||||
|
|
||||||
|
#define GetCompositeClient(pClient) ((CompositeClientPtr) (pClient)->devPrivates[CompositeClientPrivateIndex].ptr)
|
||||||
|
|
||||||
|
static void
|
||||||
|
CompositeClientCallback (CallbackListPtr *list,
|
||||||
|
pointer closure,
|
||||||
|
pointer data)
|
||||||
|
{
|
||||||
|
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
|
||||||
|
ClientPtr pClient = clientinfo->client;
|
||||||
|
CompositeClientPtr pCompositeClient = GetCompositeClient (pClient);
|
||||||
|
|
||||||
|
pCompositeClient->major_version = 0;
|
||||||
|
pCompositeClient->minor_version = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
CompositeResetProc (ExtensionEntry *extEntry)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
FreeCompositeClientWindow (pointer value, XID ccwid)
|
||||||
|
{
|
||||||
|
WindowPtr pWin = value;
|
||||||
|
|
||||||
|
compFreeClientWindow (pWin, ccwid);
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
FreeCompositeClientSubwindows (pointer value, XID ccwid)
|
||||||
|
{
|
||||||
|
WindowPtr pWin = value;
|
||||||
|
|
||||||
|
compFreeClientSubwindows (pWin, ccwid);
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ProcCompositeQueryVersion (ClientPtr client)
|
||||||
|
{
|
||||||
|
CompositeClientPtr pCompositeClient = GetCompositeClient (client);
|
||||||
|
xCompositeQueryVersionReply rep;
|
||||||
|
register int n;
|
||||||
|
REQUEST(xCompositeQueryVersionReq);
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
|
||||||
|
rep.type = X_Reply;
|
||||||
|
rep.length = 0;
|
||||||
|
rep.sequenceNumber = client->sequence;
|
||||||
|
if (stuff->majorVersion < COMPOSITE_MAJOR) {
|
||||||
|
rep.majorVersion = stuff->majorVersion;
|
||||||
|
rep.minorVersion = stuff->minorVersion;
|
||||||
|
} else {
|
||||||
|
rep.majorVersion = COMPOSITE_MAJOR;
|
||||||
|
if (stuff->majorVersion == COMPOSITE_MAJOR &&
|
||||||
|
stuff->minorVersion < COMPOSITE_MINOR)
|
||||||
|
rep.minorVersion = stuff->minorVersion;
|
||||||
|
else
|
||||||
|
rep.minorVersion = COMPOSITE_MINOR;
|
||||||
|
}
|
||||||
|
pCompositeClient->major_version = rep.majorVersion;
|
||||||
|
pCompositeClient->minor_version = rep.minorVersion;
|
||||||
|
if (client->swapped) {
|
||||||
|
swaps(&rep.sequenceNumber, n);
|
||||||
|
swapl(&rep.length, n);
|
||||||
|
swapl(&rep.majorVersion, n);
|
||||||
|
swapl(&rep.minorVersion, n);
|
||||||
|
}
|
||||||
|
WriteToClient(client, sizeof(xCompositeQueryVersionReply), (char *)&rep);
|
||||||
|
return(client->noClientException);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ProcCompositeRedirectWindow (ClientPtr client)
|
||||||
|
{
|
||||||
|
WindowPtr pWin;
|
||||||
|
REQUEST(xCompositeRedirectWindowReq);
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
|
||||||
|
pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
|
||||||
|
if (!pWin)
|
||||||
|
{
|
||||||
|
client->errorValue = stuff->window;
|
||||||
|
return BadWindow;
|
||||||
|
}
|
||||||
|
return compRedirectWindow (client, pWin, stuff->update);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ProcCompositeRedirectSubwindows (ClientPtr client)
|
||||||
|
{
|
||||||
|
WindowPtr pWin;
|
||||||
|
REQUEST(xCompositeRedirectSubwindowsReq);
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
|
||||||
|
pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
|
||||||
|
if (!pWin)
|
||||||
|
{
|
||||||
|
client->errorValue = stuff->window;
|
||||||
|
return BadWindow;
|
||||||
|
}
|
||||||
|
return compRedirectSubwindows (client, pWin, stuff->update);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ProcCompositeUnredirectWindow (ClientPtr client)
|
||||||
|
{
|
||||||
|
WindowPtr pWin;
|
||||||
|
REQUEST(xCompositeUnredirectWindowReq);
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
|
||||||
|
pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
|
||||||
|
if (!pWin)
|
||||||
|
{
|
||||||
|
client->errorValue = stuff->window;
|
||||||
|
return BadWindow;
|
||||||
|
}
|
||||||
|
return compUnredirectWindow (client, pWin, stuff->update);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ProcCompositeUnredirectSubwindows (ClientPtr client)
|
||||||
|
{
|
||||||
|
WindowPtr pWin;
|
||||||
|
REQUEST(xCompositeUnredirectSubwindowsReq);
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
|
||||||
|
pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
|
||||||
|
if (!pWin)
|
||||||
|
{
|
||||||
|
client->errorValue = stuff->window;
|
||||||
|
return BadWindow;
|
||||||
|
}
|
||||||
|
return compUnredirectSubwindows (client, pWin, stuff->update);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ProcCompositeCreateRegionFromBorderClip (ClientPtr client)
|
||||||
|
{
|
||||||
|
WindowPtr pWin;
|
||||||
|
CompWindowPtr cw;
|
||||||
|
RegionPtr pBorderClip, pRegion;
|
||||||
|
REQUEST(xCompositeCreateRegionFromBorderClipReq);
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
|
||||||
|
pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
|
||||||
|
if (!pWin)
|
||||||
|
{
|
||||||
|
client->errorValue = stuff->window;
|
||||||
|
return BadWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
LEGAL_NEW_RESOURCE (stuff->region, client);
|
||||||
|
|
||||||
|
cw = GetCompWindow (pWin);
|
||||||
|
if (cw)
|
||||||
|
pBorderClip = &cw->borderClip;
|
||||||
|
else
|
||||||
|
pBorderClip = &pWin->borderClip;
|
||||||
|
pRegion = XFixesRegionCopy (pBorderClip);
|
||||||
|
if (!pRegion)
|
||||||
|
return BadAlloc;
|
||||||
|
REGION_TRANSLATE (pScreen, pRegion, -pWin->drawable.x, -pWin->drawable.y);
|
||||||
|
|
||||||
|
if (!AddResource (stuff->region, RegionResType, (pointer) pRegion))
|
||||||
|
return BadAlloc;
|
||||||
|
|
||||||
|
return(client->noClientException);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ProcCompositeNameWindowPixmap (ClientPtr client)
|
||||||
|
{
|
||||||
|
WindowPtr pWin;
|
||||||
|
CompWindowPtr cw;
|
||||||
|
PixmapPtr pPixmap;
|
||||||
|
REQUEST(xCompositeNameWindowPixmapReq);
|
||||||
|
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
|
||||||
|
pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW);
|
||||||
|
if (!pWin)
|
||||||
|
{
|
||||||
|
client->errorValue = stuff->window;
|
||||||
|
return BadWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
LEGAL_NEW_RESOURCE (stuff->pixmap, client);
|
||||||
|
|
||||||
|
cw = GetCompWindow (pWin);
|
||||||
|
if (!cw)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
|
||||||
|
if (!pPixmap)
|
||||||
|
return BadMatch;
|
||||||
|
|
||||||
|
++pPixmap->refcnt;
|
||||||
|
|
||||||
|
if (!AddResource (stuff->pixmap, RT_PIXMAP, (pointer) pPixmap))
|
||||||
|
return BadAlloc;
|
||||||
|
|
||||||
|
return(client->noClientException);
|
||||||
|
}
|
||||||
|
|
||||||
|
int (*ProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
|
||||||
|
ProcCompositeQueryVersion,
|
||||||
|
ProcCompositeRedirectWindow,
|
||||||
|
ProcCompositeRedirectSubwindows,
|
||||||
|
ProcCompositeUnredirectWindow,
|
||||||
|
ProcCompositeUnredirectSubwindows,
|
||||||
|
ProcCompositeCreateRegionFromBorderClip,
|
||||||
|
ProcCompositeNameWindowPixmap,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
ProcCompositeDispatch (ClientPtr client)
|
||||||
|
{
|
||||||
|
REQUEST(xReq);
|
||||||
|
|
||||||
|
if (stuff->data < CompositeNumberRequests)
|
||||||
|
return (*ProcCompositeVector[stuff->data]) (client);
|
||||||
|
else
|
||||||
|
return BadRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SProcCompositeQueryVersion (ClientPtr client)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
REQUEST(xCompositeQueryVersionReq);
|
||||||
|
|
||||||
|
swaps(&stuff->length, n);
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
|
||||||
|
swapl(&stuff->majorVersion, n);
|
||||||
|
swapl(&stuff->minorVersion, n);
|
||||||
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SProcCompositeRedirectWindow (ClientPtr client)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
REQUEST(xCompositeRedirectWindowReq);
|
||||||
|
|
||||||
|
swaps(&stuff->length, n);
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
|
||||||
|
swapl (&stuff->window, n);
|
||||||
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SProcCompositeRedirectSubwindows (ClientPtr client)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
REQUEST(xCompositeRedirectSubwindowsReq);
|
||||||
|
|
||||||
|
swaps(&stuff->length, n);
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
|
||||||
|
swapl (&stuff->window, n);
|
||||||
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SProcCompositeUnredirectWindow (ClientPtr client)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
REQUEST(xCompositeUnredirectWindowReq);
|
||||||
|
|
||||||
|
swaps(&stuff->length, n);
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
|
||||||
|
swapl (&stuff->window, n);
|
||||||
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SProcCompositeUnredirectSubwindows (ClientPtr client)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
REQUEST(xCompositeUnredirectSubwindowsReq);
|
||||||
|
|
||||||
|
swaps(&stuff->length, n);
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
|
||||||
|
swapl (&stuff->window, n);
|
||||||
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SProcCompositeCreateRegionFromBorderClip (ClientPtr client)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
REQUEST(xCompositeCreateRegionFromBorderClipReq);
|
||||||
|
|
||||||
|
swaps(&stuff->length, n);
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
|
||||||
|
swapl (&stuff->region, n);
|
||||||
|
swapl (&stuff->window, n);
|
||||||
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
SProcCompositeNameWindowPixmap (ClientPtr client)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
REQUEST(xCompositeNameWindowPixmapReq);
|
||||||
|
|
||||||
|
swaps(&stuff->length, n);
|
||||||
|
REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
|
||||||
|
swapl (&stuff->window, n);
|
||||||
|
swapl (&stuff->pixmap, n);
|
||||||
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
||||||
|
}
|
||||||
|
|
||||||
|
int (*SProcCompositeVector[CompositeNumberRequests])(ClientPtr) = {
|
||||||
|
SProcCompositeQueryVersion,
|
||||||
|
SProcCompositeRedirectWindow,
|
||||||
|
SProcCompositeRedirectSubwindows,
|
||||||
|
SProcCompositeUnredirectWindow,
|
||||||
|
SProcCompositeUnredirectSubwindows,
|
||||||
|
SProcCompositeCreateRegionFromBorderClip,
|
||||||
|
SProcCompositeNameWindowPixmap,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
SProcCompositeDispatch (ClientPtr client)
|
||||||
|
{
|
||||||
|
REQUEST(xReq);
|
||||||
|
|
||||||
|
if (stuff->data < CompositeNumberRequests)
|
||||||
|
return (*SProcCompositeVector[stuff->data]) (client);
|
||||||
|
else
|
||||||
|
return BadRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CompositeExtensionInit (void)
|
||||||
|
{
|
||||||
|
ExtensionEntry *extEntry;
|
||||||
|
int s;
|
||||||
|
|
||||||
|
CompositeClientWindowType = CreateNewResourceType (FreeCompositeClientWindow);
|
||||||
|
if (!CompositeClientWindowType)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CompositeClientSubwindowsType = CreateNewResourceType (FreeCompositeClientSubwindows);
|
||||||
|
if (!CompositeClientSubwindowsType)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CompositeClientPrivateIndex = AllocateClientPrivateIndex ();
|
||||||
|
if (!AllocateClientPrivate (CompositeClientPrivateIndex,
|
||||||
|
sizeof (CompositeClientRec)))
|
||||||
|
return;
|
||||||
|
if (!AddCallback (&ClientStateCallback, CompositeClientCallback, 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
extEntry = AddExtension (COMPOSITE_NAME, 0, 0,
|
||||||
|
ProcCompositeDispatch, SProcCompositeDispatch,
|
||||||
|
CompositeResetProc, StandardMinorOpcode);
|
||||||
|
if (!extEntry)
|
||||||
|
return;
|
||||||
|
CompositeReqCode = (CARD8) extEntry->base;
|
||||||
|
|
||||||
|
|
||||||
|
for (s = 0; s < screenInfo.numScreens; s++)
|
||||||
|
if (!compScreenInit (screenInfo.screens[s]))
|
||||||
|
return;
|
||||||
|
miRegisterRedirectBorderClipProc (compSetRedirectBorderClip,
|
||||||
|
compGetRedirectBorderClip);
|
||||||
|
}
|
|
@ -0,0 +1,371 @@
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* 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_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
#include "compint.h"
|
||||||
|
|
||||||
|
int CompScreenPrivateIndex;
|
||||||
|
int CompWindowPrivateIndex;
|
||||||
|
int CompSubwindowsPrivateIndex;
|
||||||
|
int CompGeneration;
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
compCloseScreen (int index, ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||||
|
Bool ret;
|
||||||
|
|
||||||
|
pScreen->CloseScreen = cs->CloseScreen;
|
||||||
|
pScreen->BlockHandler = cs->BlockHandler;
|
||||||
|
pScreen->ReparentWindow = cs->ReparentWindow;
|
||||||
|
pScreen->MoveWindow = cs->MoveWindow;
|
||||||
|
pScreen->ResizeWindow = cs->ResizeWindow;
|
||||||
|
pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
|
||||||
|
|
||||||
|
pScreen->ClipNotify = cs->ClipNotify;
|
||||||
|
pScreen->PaintWindowBackground = cs->PaintWindowBackground;
|
||||||
|
pScreen->UnrealizeWindow = cs->UnrealizeWindow;
|
||||||
|
pScreen->RealizeWindow = cs->RealizeWindow;
|
||||||
|
pScreen->DestroyWindow = cs->DestroyWindow;
|
||||||
|
pScreen->CreateWindow = cs->CreateWindow;
|
||||||
|
pScreen->CopyWindow = cs->CopyWindow;
|
||||||
|
pScreen->PositionWindow = cs->PositionWindow;
|
||||||
|
xfree (cs);
|
||||||
|
pScreen->devPrivates[CompScreenPrivateIndex].ptr = 0;
|
||||||
|
ret = (*pScreen->CloseScreen) (index, pScreen);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
compScreenUpdate (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||||
|
|
||||||
|
compCheckTree (pScreen);
|
||||||
|
if (cs->damaged)
|
||||||
|
{
|
||||||
|
compWindowUpdate (WindowTable[pScreen->myNum]);
|
||||||
|
cs->damaged = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
compBlockHandler (int i,
|
||||||
|
pointer blockData,
|
||||||
|
pointer pTimeout,
|
||||||
|
pointer pReadmask)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = screenInfo.screens[i];
|
||||||
|
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||||
|
|
||||||
|
pScreen->BlockHandler = cs->BlockHandler;
|
||||||
|
compScreenUpdate (pScreen);
|
||||||
|
(*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
|
||||||
|
cs->BlockHandler = pScreen->BlockHandler;
|
||||||
|
pScreen->BlockHandler = compBlockHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _alternateVisual {
|
||||||
|
int depth;
|
||||||
|
CARD32 format;
|
||||||
|
} CompAlternateVisual;
|
||||||
|
|
||||||
|
static CompAlternateVisual altVisuals[NUM_COMP_ALTERNATE_VISUALS] = {
|
||||||
|
{ 24, PICT_r8g8b8 },
|
||||||
|
{ 32, PICT_a8r8g8b8 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
compAddAlternateVisuals (ScreenPtr pScreen, CompScreenPtr cs)
|
||||||
|
{
|
||||||
|
VisualPtr visuals;
|
||||||
|
DepthPtr depths[NUM_COMP_ALTERNATE_VISUALS];
|
||||||
|
PictFormatPtr pPictFormats[NUM_COMP_ALTERNATE_VISUALS];
|
||||||
|
int i;
|
||||||
|
int numVisuals;
|
||||||
|
VisualID *vids[NUM_COMP_ALTERNATE_VISUALS];
|
||||||
|
XID *installedCmaps;
|
||||||
|
ColormapPtr installedCmap;
|
||||||
|
int numInstalledCmaps;
|
||||||
|
int numAlternate = 0;
|
||||||
|
int alt;
|
||||||
|
|
||||||
|
memset (cs->alternateVisuals, '\0', sizeof (cs->alternateVisuals));
|
||||||
|
|
||||||
|
for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++)
|
||||||
|
{
|
||||||
|
DepthPtr depth;
|
||||||
|
PictFormatPtr pPictFormat;
|
||||||
|
|
||||||
|
depth = compFindVisuallessDepth (pScreen, altVisuals[alt].depth);
|
||||||
|
if (!depth)
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* Find the right picture format
|
||||||
|
*/
|
||||||
|
pPictFormat = PictureMatchFormat (pScreen, altVisuals[alt].depth,
|
||||||
|
altVisuals[alt].format);
|
||||||
|
if (!pPictFormat)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ok, create a visual id for this format
|
||||||
|
*/
|
||||||
|
cs->alternateVisuals[numAlternate] = FakeClientID (0);
|
||||||
|
/*
|
||||||
|
* Allocate vid list for this depth
|
||||||
|
*/
|
||||||
|
vids[numAlternate] = xalloc (sizeof (VisualID));
|
||||||
|
if (!vids[numAlternate])
|
||||||
|
continue;
|
||||||
|
depths[numAlternate] = depth;
|
||||||
|
pPictFormats[numAlternate] = pPictFormat;
|
||||||
|
numAlternate++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!numAlternate)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the installed colormaps
|
||||||
|
*/
|
||||||
|
installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID));
|
||||||
|
if (!installedCmaps)
|
||||||
|
{
|
||||||
|
for (alt = 0; alt < numAlternate; alt++)
|
||||||
|
xfree (vids[alt]);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
numInstalledCmaps = (*pScreen->ListInstalledColormaps) (pScreen,
|
||||||
|
installedCmaps);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* realloc the visual array to fit the new one in place
|
||||||
|
*/
|
||||||
|
numVisuals = pScreen->numVisuals;
|
||||||
|
visuals = xrealloc (pScreen->visuals,
|
||||||
|
(numVisuals + numAlternate) * sizeof (VisualRec));
|
||||||
|
if (!visuals)
|
||||||
|
{
|
||||||
|
for (alt = 0; alt < numAlternate; alt++)
|
||||||
|
xfree (vids[alt]);
|
||||||
|
xfree (installedCmaps);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix up any existing installed colormaps -- we'll assume that
|
||||||
|
* the only ones created so far have been installed. If this
|
||||||
|
* isn't true, we'll have to walk the resource database looking
|
||||||
|
* for all colormaps.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < numInstalledCmaps; i++)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP);
|
||||||
|
if (!installedCmap)
|
||||||
|
continue;
|
||||||
|
j = installedCmap->pVisual - pScreen->visuals;
|
||||||
|
installedCmap->pVisual = &visuals[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
xfree (installedCmaps);
|
||||||
|
|
||||||
|
pScreen->visuals = visuals;
|
||||||
|
pScreen->numVisuals = numVisuals + numAlternate;
|
||||||
|
|
||||||
|
for (alt = 0; alt < numAlternate; alt++)
|
||||||
|
{
|
||||||
|
DepthPtr depth = depths[alt];
|
||||||
|
PictFormatPtr pPictFormat = pPictFormats[alt];
|
||||||
|
VisualPtr visual = &visuals[numVisuals + alt];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the visual
|
||||||
|
*/
|
||||||
|
visual->class = TrueColor;
|
||||||
|
visual->bitsPerRGBValue = 8;
|
||||||
|
|
||||||
|
visual->vid = FakeClientID (0);
|
||||||
|
visual->redMask = (((unsigned long) pPictFormat->direct.redMask) <<
|
||||||
|
pPictFormat->direct.red);
|
||||||
|
visual->greenMask = (((unsigned long) pPictFormat->direct.greenMask) <<
|
||||||
|
pPictFormat->direct.green);
|
||||||
|
visual->blueMask = (((unsigned long) pPictFormat->direct.blueMask) <<
|
||||||
|
pPictFormat->direct.blue);
|
||||||
|
visual->offsetRed = pPictFormat->direct.red;
|
||||||
|
visual->offsetGreen = pPictFormat->direct.green;
|
||||||
|
visual->offsetBlue = pPictFormat->direct.blue;
|
||||||
|
visual->alphaMask = (((unsigned long) pPictFormat->direct.alphaMask) <<
|
||||||
|
pPictFormat->direct.alpha);
|
||||||
|
visual->offsetAlpha = pPictFormat->direct.alpha;
|
||||||
|
/*
|
||||||
|
* follow GLX and set nplanes to just the bits
|
||||||
|
* used for the RGB value, not A
|
||||||
|
*/
|
||||||
|
visual->nplanes = Ones (visual->redMask |
|
||||||
|
visual->greenMask |
|
||||||
|
visual->blueMask);
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
cs->alternateVisuals[alt] = visual->vid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix up the depth
|
||||||
|
*/
|
||||||
|
vids[alt][0] = visual->vid;
|
||||||
|
depth->numVids = 1;
|
||||||
|
depth->vids = vids[alt];
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
compScreenInit (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
CompScreenPtr cs;
|
||||||
|
|
||||||
|
if (CompGeneration != serverGeneration)
|
||||||
|
{
|
||||||
|
CompScreenPrivateIndex = AllocateScreenPrivateIndex ();
|
||||||
|
if (CompScreenPrivateIndex == -1)
|
||||||
|
return FALSE;
|
||||||
|
CompWindowPrivateIndex = AllocateWindowPrivateIndex ();
|
||||||
|
if (CompWindowPrivateIndex == -1)
|
||||||
|
return FALSE;
|
||||||
|
CompSubwindowsPrivateIndex = AllocateWindowPrivateIndex ();
|
||||||
|
if (CompSubwindowsPrivateIndex == -1)
|
||||||
|
return FALSE;
|
||||||
|
CompGeneration = serverGeneration;
|
||||||
|
}
|
||||||
|
if (!AllocateWindowPrivate (pScreen, CompWindowPrivateIndex, 0))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!AllocateWindowPrivate (pScreen, CompSubwindowsPrivateIndex, 0))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (GetCompScreen (pScreen))
|
||||||
|
return TRUE;
|
||||||
|
cs = (CompScreenPtr) xalloc (sizeof (CompScreenRec));
|
||||||
|
if (!cs)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
cs->damaged = FALSE;
|
||||||
|
|
||||||
|
if (!compAddAlternateVisuals (pScreen, cs))
|
||||||
|
{
|
||||||
|
xfree (cs);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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->PaintWindowBackground = pScreen->PaintWindowBackground;
|
||||||
|
pScreen->PaintWindowBackground = compPaintWindowBackground;
|
||||||
|
|
||||||
|
cs->ClipNotify = pScreen->ClipNotify;
|
||||||
|
pScreen->ClipNotify = compClipNotify;
|
||||||
|
|
||||||
|
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->BlockHandler = pScreen->BlockHandler;
|
||||||
|
pScreen->BlockHandler = compBlockHandler;
|
||||||
|
|
||||||
|
cs->CloseScreen = pScreen->CloseScreen;
|
||||||
|
pScreen->CloseScreen = compCloseScreen;
|
||||||
|
|
||||||
|
miInitializeCompositeWrapper(pScreen);
|
||||||
|
|
||||||
|
pScreen->devPrivates[CompScreenPrivateIndex].ptr = (pointer) cs;
|
||||||
|
return TRUE;
|
||||||
|
}
|
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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 <X11/extensions/compositeproto.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
extern int CompPixmapPrivateIndex;
|
||||||
|
|
||||||
|
#define NUM_COMP_ALTERNATE_VISUALS 2
|
||||||
|
|
||||||
|
typedef struct _CompScreen {
|
||||||
|
PositionWindowProcPtr PositionWindow;
|
||||||
|
CopyWindowProcPtr CopyWindow;
|
||||||
|
CreateWindowProcPtr CreateWindow;
|
||||||
|
DestroyWindowProcPtr DestroyWindow;
|
||||||
|
RealizeWindowProcPtr RealizeWindow;
|
||||||
|
UnrealizeWindowProcPtr UnrealizeWindow;
|
||||||
|
PaintWindowProcPtr PaintWindowBackground;
|
||||||
|
ClipNotifyProcPtr ClipNotify;
|
||||||
|
/*
|
||||||
|
* Called from ConfigureWindow, these
|
||||||
|
* three track changes to the offscreen storage
|
||||||
|
* geometry
|
||||||
|
*/
|
||||||
|
MoveWindowProcPtr MoveWindow;
|
||||||
|
ResizeWindowProcPtr ResizeWindow;
|
||||||
|
ChangeBorderWidthProcPtr ChangeBorderWidth;
|
||||||
|
/*
|
||||||
|
* Reparenting has an effect on Subwindows redirect
|
||||||
|
*/
|
||||||
|
ReparentWindowProcPtr ReparentWindow;
|
||||||
|
|
||||||
|
ScreenBlockHandlerProcPtr BlockHandler;
|
||||||
|
CloseScreenProcPtr CloseScreen;
|
||||||
|
Bool damaged;
|
||||||
|
XID alternateVisuals[NUM_COMP_ALTERNATE_VISUALS];
|
||||||
|
} CompScreenRec, *CompScreenPtr;
|
||||||
|
|
||||||
|
#define HasCompRedirect(w) (wPixmap(w) != wPixmap(w->parent))
|
||||||
|
#define wScreen(w) ((w)->drawable.pScreen)
|
||||||
|
#define wPixmap(w) (*(wScreen(w)->GetWindowPixmap) (w))
|
||||||
|
|
||||||
|
extern int CompScreenPrivateIndex;
|
||||||
|
extern int CompWindowPrivateIndex;
|
||||||
|
extern int CompSubwindowsPrivateIndex;
|
||||||
|
|
||||||
|
#define GetCompScreen(s) ((CompScreenPtr) ((s)->devPrivates[CompScreenPrivateIndex].ptr))
|
||||||
|
#define GetCompWindow(w) ((CompWindowPtr) ((w)->devPrivates[CompWindowPrivateIndex].ptr))
|
||||||
|
#define GetCompSubwindows(w) ((CompSubwindowsPtr) ((w)->devPrivates[CompSubwindowsPrivateIndex].ptr))
|
||||||
|
|
||||||
|
extern RESTYPE CompositeClientWindowType;
|
||||||
|
extern RESTYPE CompositeClientSubwindowsType;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compalloc.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure);
|
||||||
|
|
||||||
|
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
|
||||||
|
compFreePixmap (WindowPtr pWin);
|
||||||
|
|
||||||
|
Bool
|
||||||
|
compReallocPixmap (WindowPtr pWin, int x, int y,
|
||||||
|
unsigned int w, unsigned int h, int bw);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compext.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
CompositeExtensionInit (void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compinit.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
Bool
|
||||||
|
compScreenInit (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compwindow.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#define compCheckTree(s)
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
compCheckTree (ScreenPtr pScreen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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
|
||||||
|
compPaintWindowBackground (WindowPtr pWin, RegionPtr pRegion, int what);
|
||||||
|
|
||||||
|
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
|
||||||
|
compWindowUpdate (WindowPtr pWin);
|
||||||
|
|
||||||
|
#endif /* _COMPINT_H_ */
|
|
@ -0,0 +1,708 @@
|
||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* 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_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
#include "compint.h"
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
static int
|
||||||
|
compCheckWindow (WindowPtr pWin, pointer 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);
|
||||||
|
assert (pWinPixmap == pScreenPixmap);
|
||||||
|
}
|
||||||
|
else if (pWin->redirectDraw)
|
||||||
|
{
|
||||||
|
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 int
|
||||||
|
compSetPixmapVisitWindow (WindowPtr pWindow, pointer data)
|
||||||
|
{
|
||||||
|
CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data;
|
||||||
|
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||||
|
|
||||||
|
if (pWindow != pVisit->pWindow && pWindow->redirectDraw)
|
||||||
|
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);
|
||||||
|
return WT_WALKCHILDREN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
compSetPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
|
||||||
|
{
|
||||||
|
CompPixmapVisitRec visitRec;
|
||||||
|
|
||||||
|
visitRec.pWindow = pWindow;
|
||||||
|
visitRec.pPixmap = pPixmap;
|
||||||
|
TraverseTree (pWindow, compSetPixmapVisitWindow, (pointer) &visitRec);
|
||||||
|
compCheckTree (pWindow->drawable.pScreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
compCheckRedirect (WindowPtr pWin)
|
||||||
|
{
|
||||||
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
|
Bool should = pWin->viewable && (cw != NULL);
|
||||||
|
|
||||||
|
if (should != pWin->redirectDraw)
|
||||||
|
{
|
||||||
|
if (should)
|
||||||
|
return compAllocPixmap (pWin);
|
||||||
|
else
|
||||||
|
compFreePixmap (pWin);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
*/
|
||||||
|
if (pWin->redirectDraw != (pWin->viewable && (GetCompWindow(pWin) != NULL)))
|
||||||
|
abort ();
|
||||||
|
if (pWin->redirectDraw)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
compPaintWindowBackground (WindowPtr pWin, RegionPtr pRegion, int what)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||||
|
CompSubwindowsPtr csw = GetCompSubwindows (pWin);
|
||||||
|
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||||
|
|
||||||
|
if (csw && csw->update == CompositeRedirectManual)
|
||||||
|
return;
|
||||||
|
pScreen->PaintWindowBackground = cs->PaintWindowBackground;
|
||||||
|
(*pScreen->PaintWindowBackground) (pWin, pRegion, what);
|
||||||
|
cs->PaintWindowBackground = pScreen->PaintWindowBackground;
|
||||||
|
pScreen->PaintWindowBackground = compPaintWindowBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
REGION_TRANSLATE (pScreen, &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 < NUM_COMP_ALTERNATE_VISUALS; i++)
|
||||||
|
if (cs->alternateVisuals[i] == visual)
|
||||||
|
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 (winVisual != parentVisual &&
|
||||||
|
(compIsAlternateVisual (pScreen, winVisual) ||
|
||||||
|
compIsAlternateVisual (pScreen, parentVisual)))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (pWin->redirectDraw)
|
||||||
|
{
|
||||||
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
|
if (cw->pOldPixmap)
|
||||||
|
{
|
||||||
|
(*pScreen->DestroyPixmap) (cw->pOldPixmap);
|
||||||
|
cw->pOldPixmap = NullPixmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
if (pWin->redirectDraw)
|
||||||
|
{
|
||||||
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
|
if (cw->pOldPixmap)
|
||||||
|
{
|
||||||
|
(*pScreen->DestroyPixmap) (cw->pOldPixmap);
|
||||||
|
cw->pOldPixmap = NullPixmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
if (pWin->redirectDraw)
|
||||||
|
{
|
||||||
|
CompWindowPtr cw = GetCompWindow (pWin);
|
||||||
|
if (cw->pOldPixmap)
|
||||||
|
{
|
||||||
|
(*pScreen->DestroyPixmap) (cw->pOldPixmap);
|
||||||
|
cw->pOldPixmap = NullPixmap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||||
|
GCPtr pGC;
|
||||||
|
|
||||||
|
dx = ptOldOrg.x - pWin->drawable.x;
|
||||||
|
dy = ptOldOrg.y - pWin->drawable.y;
|
||||||
|
REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
|
||||||
|
|
||||||
|
REGION_NULL (pWin->drawable.pScreen, &rgnDst);
|
||||||
|
|
||||||
|
REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst,
|
||||||
|
&pWin->borderClip, prgnSrc);
|
||||||
|
|
||||||
|
REGION_TRANSLATE (pWin->drawable.pScreen, &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 = REGION_RECTS (&rgnDst);
|
||||||
|
int nBox = REGION_NUM_RECTS (&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);
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
|
||||||
|
(*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
|
||||||
|
if (dx || dy)
|
||||||
|
REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptOldOrg.x -= dx;
|
||||||
|
ptOldOrg.y -= dy;
|
||||||
|
REGION_TRANSLATE (prgnSrc, 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;
|
||||||
|
|
||||||
|
(*pScreen->SetWindowPixmap) (pWin, (*pScreen->GetWindowPixmap) (pWin->parent));
|
||||||
|
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)
|
||||||
|
compFreePixmap (pWin);
|
||||||
|
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;
|
||||||
|
|
||||||
|
REGION_NULL (pScreen, &damage);
|
||||||
|
/*
|
||||||
|
* Align old border clip with new border clip
|
||||||
|
*/
|
||||||
|
REGION_TRANSLATE (pScreen, &cw->borderClip,
|
||||||
|
pWin->drawable.x - cw->borderClipX,
|
||||||
|
pWin->drawable.y - cw->borderClipY);
|
||||||
|
/*
|
||||||
|
* Compute newly visible portion of window for repaint
|
||||||
|
*/
|
||||||
|
REGION_SUBTRACT (pScreen, &damage, pRegion, &cw->borderClip);
|
||||||
|
/*
|
||||||
|
* Report that as damaged so it will be redrawn
|
||||||
|
*/
|
||||||
|
DamageDamageRegion (&pWin->drawable, &damage);
|
||||||
|
REGION_UNINIT (pScreen, &damage);
|
||||||
|
/*
|
||||||
|
* Save the new border clip region
|
||||||
|
*/
|
||||||
|
REGION_COPY (pScreen, &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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static 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);
|
||||||
|
PixmapPtr pDstPixmap = (*pScreen->GetWindowPixmap) (pParent);
|
||||||
|
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);
|
||||||
|
PicturePtr pDstPicture = CreatePicture (0, &pDstPixmap->drawable,
|
||||||
|
pDstFormat,
|
||||||
|
0, 0,
|
||||||
|
serverClient,
|
||||||
|
&error);
|
||||||
|
|
||||||
|
REGION_TRANSLATE (pScreen, pRegion,
|
||||||
|
pSrcPixmap->screen_x, pSrcPixmap->screen_y);
|
||||||
|
REGION_INTERSECT (pScreen, pRegion, pRegion, &cw->borderClip);
|
||||||
|
REGION_TRANSLATE (pScreen, pRegion,
|
||||||
|
-pSrcPixmap->screen_x, -pSrcPixmap->screen_y);
|
||||||
|
|
||||||
|
SetPictureClipRegion (pSrcPicture, 0, 0, pRegion);
|
||||||
|
|
||||||
|
CompositePicture (PictOpSrc,
|
||||||
|
pSrcPicture,
|
||||||
|
0,
|
||||||
|
pDstPicture,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0, 0,
|
||||||
|
pSrcPixmap->screen_x - pDstPixmap->screen_x,
|
||||||
|
pSrcPixmap->screen_y - pDstPixmap->screen_y,
|
||||||
|
pSrcPixmap->drawable.width,
|
||||||
|
pSrcPixmap->drawable.height);
|
||||||
|
FreePicture (pSrcPicture, 0);
|
||||||
|
FreePicture (pDstPicture, 0);
|
||||||
|
DamageEmpty (cw->damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
compWindowUpdate (WindowPtr pWin)
|
||||||
|
{
|
||||||
|
WindowPtr pChild;
|
||||||
|
|
||||||
|
for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
|
||||||
|
compWindowUpdate (pChild);
|
||||||
|
if (pWin->redirectDraw)
|
||||||
|
{
|
||||||
|
CompWindowPtr cw = GetCompWindow(pWin);
|
||||||
|
|
||||||
|
if (cw->damaged)
|
||||||
|
{
|
||||||
|
compWindowUpdateAutomatic (pWin);
|
||||||
|
cw->damaged = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/* $XdotOrg$ */
|
/* $XdotOrg: xc/programs/Xserver/dix/colormap.c,v 1.2.2.1 2004/07/30 06:54:41 anholt Exp $ */
|
||||||
/* $XFree86: xc/programs/Xserver/dix/colormap.c,v 3.11 2003/11/03 05:10:59 tsi Exp $ */
|
/* $XFree86: xc/programs/Xserver/dix/colormap.c,v 3.11 2003/11/03 05:10:59 tsi Exp $ */
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
|
|
||||||
|
@ -190,7 +190,15 @@ static void FindColorInRootCmap (
|
||||||
#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
|
#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
|
||||||
#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
|
#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
|
||||||
#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
|
#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
|
||||||
#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask)
|
#ifdef COMPOSITE
|
||||||
|
#define NUMALPHA(vis) ((vis->alphaMask >> vis->offsetAlpha) + 1)
|
||||||
|
#define ALPHAMASK(vis) (vis->alphaMask)
|
||||||
|
#else
|
||||||
|
#define NUMALPHA(vis) 0
|
||||||
|
#define ALPHAMASK(vis) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis))
|
||||||
|
|
||||||
/* GetNextBitsOrBreak(bits, mask, base) --
|
/* GetNextBitsOrBreak(bits, mask, base) --
|
||||||
* (Suggestion: First read the macro, then read this explanation.
|
* (Suggestion: First read the macro, then read this explanation.
|
||||||
|
@ -866,6 +874,9 @@ AllocColor (pmap, pred, pgreen, pblue, pPix, client)
|
||||||
*pPix = (pixR << pVisual->offsetRed) |
|
*pPix = (pixR << pVisual->offsetRed) |
|
||||||
(pixG << pVisual->offsetGreen) |
|
(pixG << pVisual->offsetGreen) |
|
||||||
(pixB << pVisual->offsetBlue);
|
(pixB << pVisual->offsetBlue);
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
*pPix |= pVisual->alphaMask;
|
||||||
|
#endif
|
||||||
*pred = pmap->red[pixR].co.local.red;
|
*pred = pmap->red[pixR].co.local.red;
|
||||||
*pgreen = pmap->green[pixG].co.local.green;
|
*pgreen = pmap->green[pixG].co.local.green;
|
||||||
*pblue = pmap->blue[pixB].co.local.blue;
|
*pblue = pmap->blue[pixB].co.local.blue;
|
||||||
|
@ -956,6 +967,9 @@ AllocColor (pmap, pred, pgreen, pblue, pPix, client)
|
||||||
return (BadAlloc);
|
return (BadAlloc);
|
||||||
}
|
}
|
||||||
*pPix = pixR | pixG | pixB;
|
*pPix = pixR | pixG | pixB;
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
*pPix |= pVisual->alphaMask;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1928,6 +1942,10 @@ AllocDirect (client, pmap, c, r, g, b, contig, pixels, prmask, pgmask, pbmask)
|
||||||
}
|
}
|
||||||
pmap->numPixelsBlue[client] += npixB;
|
pmap->numPixelsBlue[client] += npixB;
|
||||||
pmap->freeBlue -= npixB;
|
pmap->freeBlue -= npixB;
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
for (pDst = pixels; pDst < pixels + c; pDst++)
|
||||||
|
*pDst |= pmap->pVisual->alphaMask;
|
||||||
|
#endif
|
||||||
|
|
||||||
DEALLOCATE_LOCAL(ppixBlue);
|
DEALLOCATE_LOCAL(ppixBlue);
|
||||||
DEALLOCATE_LOCAL(ppixGreen);
|
DEALLOCATE_LOCAL(ppixGreen);
|
||||||
|
|
31
dix/window.c
31
dix/window.c
|
@ -1,4 +1,4 @@
|
||||||
/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.4 2004/07/29 23:43:39 kem Exp $ */
|
/* $XdotOrg: xc/programs/Xserver/dix/window.c,v 1.4.2.1 2004/07/30 06:54:41 anholt Exp $ */
|
||||||
/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
|
/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -291,6 +291,9 @@ SetWindowToDefaults(register WindowPtr pWin)
|
||||||
pWin->srcBuffer = DBE_FRONT_BUFFER;
|
pWin->srcBuffer = DBE_FRONT_BUFFER;
|
||||||
pWin->dstBuffer = DBE_FRONT_BUFFER;
|
pWin->dstBuffer = DBE_FRONT_BUFFER;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
pWin->redirectDraw = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1661,6 +1664,19 @@ void
|
||||||
SetWinSize (pWin)
|
SetWinSize (pWin)
|
||||||
register WindowPtr pWin;
|
register WindowPtr pWin;
|
||||||
{
|
{
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
if (pWin->redirectDraw)
|
||||||
|
{
|
||||||
|
BoxRec box;
|
||||||
|
|
||||||
|
box.x1 = pWin->drawable.x;
|
||||||
|
box.y1 = pWin->drawable.y;
|
||||||
|
box.x2 = pWin->drawable.x + pWin->drawable.width;
|
||||||
|
box.y2 = pWin->drawable.y + pWin->drawable.height;
|
||||||
|
REGION_RESET (pScreen, &pWin->winSize, &box);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
ClippedRegionFromBox(pWin->parent, &pWin->winSize,
|
ClippedRegionFromBox(pWin->parent, &pWin->winSize,
|
||||||
pWin->drawable.x, pWin->drawable.y,
|
pWin->drawable.x, pWin->drawable.y,
|
||||||
(int)pWin->drawable.width,
|
(int)pWin->drawable.width,
|
||||||
|
@ -1691,6 +1707,19 @@ SetBorderSize (pWin)
|
||||||
|
|
||||||
if (HasBorder (pWin)) {
|
if (HasBorder (pWin)) {
|
||||||
bw = wBorderWidth (pWin);
|
bw = wBorderWidth (pWin);
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
if (pWin->redirectDraw)
|
||||||
|
{
|
||||||
|
BoxRec box;
|
||||||
|
|
||||||
|
box.x1 = pWin->drawable.x - bw;
|
||||||
|
box.y1 = pWin->drawable.y - bw;
|
||||||
|
box.x2 = pWin->drawable.x + pWin->drawable.width + bw;
|
||||||
|
box.y2 = pWin->drawable.y + pWin->drawable.height + bw;
|
||||||
|
REGION_RESET (pScreen, &pWin->borderSize, &box);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
|
ClippedRegionFromBox(pWin->parent, &pWin->borderSize,
|
||||||
pWin->drawable.x - bw, pWin->drawable.y - bw,
|
pWin->drawable.x - bw, pWin->drawable.y - bw,
|
||||||
(int)(pWin->drawable.width + (bw<<1)),
|
(int)(pWin->drawable.width + (bw<<1)),
|
||||||
|
|
|
@ -79,6 +79,10 @@ typedef struct _Pixmap {
|
||||||
#ifdef PIXPRIV
|
#ifdef PIXPRIV
|
||||||
DevUnion *devPrivates; /* real devPrivates like gcs & windows */
|
DevUnion *devPrivates; /* real devPrivates like gcs & windows */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
short screen_x;
|
||||||
|
short screen_y;
|
||||||
|
#endif
|
||||||
} PixmapRec;
|
} PixmapRec;
|
||||||
|
|
||||||
#endif /* PIXMAPSTRUCT_H */
|
#endif /* PIXMAPSTRUCT_H */
|
||||||
|
|
|
@ -75,6 +75,10 @@ typedef struct _Visual {
|
||||||
* it may have more or fewer */
|
* it may have more or fewer */
|
||||||
unsigned long redMask, greenMask, blueMask;
|
unsigned long redMask, greenMask, blueMask;
|
||||||
int offsetRed, offsetGreen, offsetBlue;
|
int offsetRed, offsetGreen, offsetBlue;
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
unsigned long alphaMask;
|
||||||
|
int offsetAlpha;
|
||||||
|
#endif
|
||||||
} VisualRec;
|
} VisualRec;
|
||||||
|
|
||||||
typedef struct _Depth {
|
typedef struct _Depth {
|
||||||
|
|
|
@ -135,6 +135,9 @@ typedef struct _Window {
|
||||||
#define DBE_BACK_BUFFER 0
|
#define DBE_BACK_BUFFER 0
|
||||||
unsigned dstBuffer:1; /* destination buffer for rendering */
|
unsigned dstBuffer:1; /* destination buffer for rendering */
|
||||||
unsigned srcBuffer:1; /* source buffer for rendering */
|
unsigned srcBuffer:1; /* source buffer for rendering */
|
||||||
|
#endif
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
unsigned redirectDraw:1; /* rendering is redirected from here */
|
||||||
#endif
|
#endif
|
||||||
DevUnion *devPrivates;
|
DevUnion *devPrivates;
|
||||||
} WindowRec;
|
} WindowRec;
|
||||||
|
|
10
mi/mi.h
10
mi/mi.h
|
@ -495,6 +495,16 @@ extern int miShapedWindowIn(
|
||||||
int /*y*/
|
int /*y*/
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef void
|
||||||
|
(*SetRedirectBorderClipProcPtr) (WindowPtr pWindow, RegionPtr pRegion);
|
||||||
|
|
||||||
|
typedef RegionPtr
|
||||||
|
(*GetRedirectBorderClipProcPtr) (WindowPtr pWindow);
|
||||||
|
|
||||||
|
void
|
||||||
|
miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
|
||||||
|
GetRedirectBorderClipProcPtr getBorderClip);
|
||||||
|
|
||||||
extern int miValidateTree(
|
extern int miValidateTree(
|
||||||
WindowPtr /*pParent*/,
|
WindowPtr /*pParent*/,
|
||||||
WindowPtr /*pChild*/,
|
WindowPtr /*pChild*/,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $XdotOrg: xc/programs/Xserver/mi/miinitext.c,v 1.6 2004/07/31 01:37:47 stukreit Exp $ */
|
/* $XdotOrg: xc/programs/Xserver/mi/miinitext.c,v 1.7 2004/07/31 04:23:21 kem Exp $ */
|
||||||
/* $XFree86: xc/programs/Xserver/mi/miinitext.c,v 3.67 2003/01/12 02:44:27 dawes Exp $ */
|
/* $XFree86: xc/programs/Xserver/mi/miinitext.c,v 3.67 2003/01/12 02:44:27 dawes Exp $ */
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
|
|
||||||
|
@ -282,6 +282,9 @@ extern void XFixesExtensionInit(INITARGS);
|
||||||
#ifdef DAMAGE
|
#ifdef DAMAGE
|
||||||
extern void DamageExtensionInit(INITARGS);
|
extern void DamageExtensionInit(INITARGS);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
extern void CompositeExtensionInit(INITARGS);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The following is only a small first step towards run-time
|
/* The following is only a small first step towards run-time
|
||||||
* configurable extensions.
|
* configurable extensions.
|
||||||
|
@ -456,6 +459,10 @@ InitExtensions(argc, argv)
|
||||||
DPSExtensionInit();
|
DPSExtensionInit();
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef XFIXES
|
||||||
|
/* must be before Render to layer DisplayCursor correctly */
|
||||||
|
XFixesExtensionInit();
|
||||||
|
#endif
|
||||||
#ifdef RENDER
|
#ifdef RENDER
|
||||||
if (!noRenderExtension) RenderExtensionInit();
|
if (!noRenderExtension) RenderExtensionInit();
|
||||||
#endif
|
#endif
|
||||||
|
@ -471,12 +478,12 @@ InitExtensions(argc, argv)
|
||||||
#ifdef XEVIE
|
#ifdef XEVIE
|
||||||
if (!noXevieExtension) XevieExtensionInit();
|
if (!noXevieExtension) XevieExtensionInit();
|
||||||
#endif
|
#endif
|
||||||
#ifdef XFIXES
|
|
||||||
XFixesExtensionInit();
|
|
||||||
#endif
|
|
||||||
#ifdef DAMAGE
|
#ifdef DAMAGE
|
||||||
DamageExtensionInit();
|
DamageExtensionInit();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
CompositeExtensionInit ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -590,6 +597,10 @@ static ExtensionModule staticExtensions[] = {
|
||||||
#ifdef PANORAMIX
|
#ifdef PANORAMIX
|
||||||
{ PanoramiXExtensionInit, PANORAMIX_PROTOCOL_NAME, &noPanoramiXExtension, NULL, NULL },
|
{ PanoramiXExtensionInit, PANORAMIX_PROTOCOL_NAME, &noPanoramiXExtension, NULL, NULL },
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef XFIXES
|
||||||
|
/* must be before Render to layer DisplayCursor correctly */
|
||||||
|
{ XFixesExtensionInit, "XFIXES", NULL, NULL, NULL },
|
||||||
|
#endif
|
||||||
#ifdef XF86BIGFONT
|
#ifdef XF86BIGFONT
|
||||||
{ XFree86BigfontExtensionInit, XF86BIGFONTNAME, NULL, NULL, NULL },
|
{ XFree86BigfontExtensionInit, XF86BIGFONTNAME, NULL, NULL, NULL },
|
||||||
#endif
|
#endif
|
||||||
|
@ -602,8 +613,8 @@ static ExtensionModule staticExtensions[] = {
|
||||||
#ifdef DAMAGE
|
#ifdef DAMAGE
|
||||||
{ DamageExtensionInit, "DAMAGE", NULL, NULL },
|
{ DamageExtensionInit, "DAMAGE", NULL, NULL },
|
||||||
#endif
|
#endif
|
||||||
#ifdef XFIXES
|
#ifdef COMPOSITE
|
||||||
{ XFixesExtensionInit, "XFIXES", NULL, NULL },
|
{ CompositeExtensionInit, "COMPOSITE", NULL, NULL },
|
||||||
#endif
|
#endif
|
||||||
#ifdef XEVIE
|
#ifdef XEVIE
|
||||||
{ XevieExtensionInit, "XEVIE", &noXevieExtension, NULL },
|
{ XevieExtensionInit, "XEVIE", &noXevieExtension, NULL },
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* $Xorg: mivaltree.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
|
/* $Xorg: mivaltree.c,v 1.4 2001/02/09 02:05:22 xorgcvs Exp $ */
|
||||||
/* $XdotOrg$ */
|
/* $XdotOrg: xc/programs/Xserver/mi/mivaltree.c,v 1.2.2.1 2004/07/30 06:54:42 anholt Exp $ */
|
||||||
/*
|
/*
|
||||||
* mivaltree.c --
|
* mivaltree.c --
|
||||||
* Functions for recalculating window clip lists. Main function
|
* Functions for recalculating window clip lists. Main function
|
||||||
|
@ -167,6 +167,17 @@ miShapedWindowIn (pScreen, universe, bounding, rect, x, y)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static GetRedirectBorderClipProcPtr miGetRedirectBorderClipProc;
|
||||||
|
static SetRedirectBorderClipProcPtr miSetRedirectBorderClipProc;
|
||||||
|
|
||||||
|
void
|
||||||
|
miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
|
||||||
|
GetRedirectBorderClipProcPtr getBorderClip)
|
||||||
|
{
|
||||||
|
miSetRedirectBorderClipProc = setBorderClip;
|
||||||
|
miGetRedirectBorderClipProc = getBorderClip;
|
||||||
|
}
|
||||||
|
|
||||||
#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
|
#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
|
||||||
HasBorder(w) && \
|
HasBorder(w) && \
|
||||||
(w)->backgroundState == ParentRelative)
|
(w)->backgroundState == ParentRelative)
|
||||||
|
@ -264,6 +275,18 @@ miComputeClips (
|
||||||
((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
|
((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
|
||||||
SendVisibilityNotify(pParent);
|
SendVisibilityNotify(pParent);
|
||||||
|
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
/*
|
||||||
|
* In redirected drawing case, reset universe to borderSize
|
||||||
|
*/
|
||||||
|
if (pParent->redirectDraw)
|
||||||
|
{
|
||||||
|
if (miSetRedirectBorderClipProc)
|
||||||
|
(*miSetRedirectBorderClipProc) (pParent, universe);
|
||||||
|
REGION_COPY(pScreen, universe, &pParent->borderSize);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
|
dx = pParent->drawable.x - pParent->valdata->before.oldAbsCorner.x;
|
||||||
dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
|
dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
|
||||||
|
|
||||||
|
@ -640,7 +663,12 @@ miValidateTree (pParent, pChild, kind)
|
||||||
{
|
{
|
||||||
if (pWin->valdata)
|
if (pWin->valdata)
|
||||||
{
|
{
|
||||||
REGION_APPEND( pScreen, &totalClip, &pWin->borderClip);
|
RegionPtr pBorderClip = &pWin->borderClip;
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
if (pWin->redirectDraw && miGetRedirectBorderClipProc)
|
||||||
|
pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
|
||||||
|
#endif
|
||||||
|
REGION_APPEND( pScreen, &totalClip, pBorderClip );
|
||||||
if (pWin->viewable)
|
if (pWin->viewable)
|
||||||
viewvals++;
|
viewvals++;
|
||||||
}
|
}
|
||||||
|
@ -654,7 +682,12 @@ miValidateTree (pParent, pChild, kind)
|
||||||
{
|
{
|
||||||
if (pWin->valdata)
|
if (pWin->valdata)
|
||||||
{
|
{
|
||||||
REGION_APPEND( pScreen, &totalClip, &pWin->borderClip);
|
RegionPtr pBorderClip = &pWin->borderClip;
|
||||||
|
#ifdef COMPOSITE
|
||||||
|
if (pWin->redirectDraw && miGetRedirectBorderClipProc)
|
||||||
|
pBorderClip = (*miGetRedirectBorderClipProc)(pWin);
|
||||||
|
#endif
|
||||||
|
REGION_APPEND( pScreen, &totalClip, pBorderClip );
|
||||||
if (pWin->viewable)
|
if (pWin->viewable)
|
||||||
viewvals++;
|
viewvals++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,570 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2004 Eric Anholt
|
||||||
|
*
|
||||||
|
* 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 Eric Anholt not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the software without
|
||||||
|
* specific, written prior permission. Eric Anholt makes no
|
||||||
|
* representations about the suitability of this software for any purpose. It
|
||||||
|
* is provided "as is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL ERIC ANHOLT 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.
|
||||||
|
*/
|
||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
#include "gcstruct.h"
|
||||||
|
#include "windowstr.h"
|
||||||
|
#include "cw.h"
|
||||||
|
|
||||||
|
#define CW_DEBUG 1
|
||||||
|
|
||||||
|
#if CW_DEBUG
|
||||||
|
#define CW_ASSERT(x) do { \
|
||||||
|
if (!(x)) { \
|
||||||
|
ErrorF("composite wrapper: assertion failed at %s:%d\n", __FUNC__, \
|
||||||
|
__LINE__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define CW_ASSERT(x) do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int cwGCIndex;
|
||||||
|
int cwScreenIndex;
|
||||||
|
#ifdef RENDER
|
||||||
|
int cwPictureIndex;
|
||||||
|
#endif
|
||||||
|
static unsigned long cwGeneration = 0;
|
||||||
|
extern GCOps cwGCOps;
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
cwCloseScreen (int i, ScreenPtr pScreen);
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable);
|
||||||
|
static void
|
||||||
|
cwChangeGC(GCPtr pGC, unsigned long mask);
|
||||||
|
static void
|
||||||
|
cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
|
||||||
|
static void
|
||||||
|
cwDestroyGC(GCPtr pGC);
|
||||||
|
static void
|
||||||
|
cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
|
||||||
|
static void
|
||||||
|
cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
|
||||||
|
static void
|
||||||
|
cwDestroyClip(GCPtr pGC);
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCheapValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable);
|
||||||
|
static void
|
||||||
|
cwCheapChangeGC(GCPtr pGC, unsigned long mask);
|
||||||
|
static void
|
||||||
|
cwCheapCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
|
||||||
|
static void
|
||||||
|
cwCheapDestroyGC(GCPtr pGC);
|
||||||
|
static void
|
||||||
|
cwCheapChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
|
||||||
|
static void
|
||||||
|
cwCheapCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
|
||||||
|
static void
|
||||||
|
cwCheapDestroyClip(GCPtr pGC);
|
||||||
|
|
||||||
|
static GCFuncs cwGCFuncs = {
|
||||||
|
cwValidateGC,
|
||||||
|
cwChangeGC,
|
||||||
|
cwCopyGC,
|
||||||
|
cwDestroyGC,
|
||||||
|
cwChangeClip,
|
||||||
|
cwDestroyClip,
|
||||||
|
cwCopyClip,
|
||||||
|
};
|
||||||
|
|
||||||
|
static GCFuncs cwCheapGCFuncs = {
|
||||||
|
cwCheapValidateGC,
|
||||||
|
cwCheapChangeGC,
|
||||||
|
cwCheapCopyGC,
|
||||||
|
cwCheapDestroyGC,
|
||||||
|
cwCheapChangeClip,
|
||||||
|
cwCheapDestroyClip,
|
||||||
|
cwCheapCopyClip,
|
||||||
|
};
|
||||||
|
|
||||||
|
DrawablePtr
|
||||||
|
cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off)
|
||||||
|
{
|
||||||
|
if (cwDrawableIsRedirWindow(pDrawable)) {
|
||||||
|
WindowPtr pWin = (WindowPtr)pDrawable;
|
||||||
|
PixmapPtr pPixmap = (*pDrawable->pScreen->GetWindowPixmap)(pWin);
|
||||||
|
*x_off = -pPixmap->screen_x;
|
||||||
|
*y_off = -pPixmap->screen_y;
|
||||||
|
|
||||||
|
return &pPixmap->drawable;
|
||||||
|
} else {
|
||||||
|
*x_off = *y_off = 0;
|
||||||
|
|
||||||
|
return pDrawable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create the full func/op wrappers for a GC
|
||||||
|
*/
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
cwCreateGCPrivate(GCPtr pGC, DrawablePtr pDrawable)
|
||||||
|
{
|
||||||
|
cwGCRec *pPriv;
|
||||||
|
int status, x_off, y_off;
|
||||||
|
XID noexpose = xFalse;
|
||||||
|
DrawablePtr pBackingDrawable;
|
||||||
|
|
||||||
|
pPriv = (cwGCRec *)xalloc(sizeof (cwGCRec));
|
||||||
|
if (!pPriv)
|
||||||
|
return FALSE;
|
||||||
|
pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
|
||||||
|
pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures,
|
||||||
|
&noexpose, &status);
|
||||||
|
if (status != Success) {
|
||||||
|
xfree(pPriv);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
pPriv->guarantee = GuaranteeNothing;
|
||||||
|
pPriv->serialNumber = 0;
|
||||||
|
pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
|
||||||
|
pPriv->wrapOps = pGC->ops;
|
||||||
|
pPriv->wrapFuncs = pGC->funcs;
|
||||||
|
pGC->funcs = &cwGCFuncs;
|
||||||
|
pGC->ops = &cwGCOps;
|
||||||
|
setCwGC (pGC, pPriv);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwDestroyGCPrivate(GCPtr pGC)
|
||||||
|
{
|
||||||
|
cwGCPtr pPriv;
|
||||||
|
|
||||||
|
pPriv = (cwGCPtr) getCwGC (pGC);
|
||||||
|
pGC->funcs = &cwCheapGCFuncs;
|
||||||
|
pGC->ops = pPriv->wrapOps;
|
||||||
|
if (pPriv->pBackingGC)
|
||||||
|
FreeGC(pPriv->pBackingGC, (XID)0);
|
||||||
|
setCwGC (pGC, pPriv->wrapFuncs);
|
||||||
|
xfree((pointer)pPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GCFuncs wrappers. These only get used when the drawable is a window with a
|
||||||
|
* backing pixmap, to avoid the overhead in the non-window-backing-pixmap case.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FUNC_PROLOGUE(pGC, pPriv) \
|
||||||
|
((pGC)->funcs = pPriv->wrapFuncs), \
|
||||||
|
((pGC)->ops = pPriv->wrapOps)
|
||||||
|
|
||||||
|
#define FUNC_EPILOGUE(pGC, pPriv) \
|
||||||
|
((pGC)->funcs = &cwGCFuncs), \
|
||||||
|
((pGC)->ops = &cwGCOps)
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
|
||||||
|
{
|
||||||
|
GCPtr pBackingGC;
|
||||||
|
cwGCPtr pPriv;
|
||||||
|
DrawablePtr pBackingDrawable;
|
||||||
|
int x_off, y_off;
|
||||||
|
|
||||||
|
pPriv = (cwGCPtr) getCwGC (pGC);
|
||||||
|
|
||||||
|
FUNC_PROLOGUE(pGC, pPriv);
|
||||||
|
|
||||||
|
if (pDrawable->serialNumber != pPriv->serialNumber &&
|
||||||
|
!cwDrawableIsRedirWindow(pDrawable))
|
||||||
|
{
|
||||||
|
/* The drawable is no longer a window with backing store, so kill the
|
||||||
|
* private and go back to cheap functions.
|
||||||
|
*/
|
||||||
|
cwDestroyGCPrivate(pGC);
|
||||||
|
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rewrap funcs and ops as Validate may have changed them
|
||||||
|
*/
|
||||||
|
pPriv->wrapFuncs = pGC->funcs;
|
||||||
|
pPriv->wrapOps = pGC->ops;
|
||||||
|
|
||||||
|
pBackingGC = pPriv->pBackingGC;
|
||||||
|
pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
|
||||||
|
|
||||||
|
pPriv->stateChanges |= stateChanges;
|
||||||
|
|
||||||
|
if (pPriv->stateChanges) {
|
||||||
|
CopyGC(pGC, pBackingGC, pPriv->stateChanges);
|
||||||
|
pPriv->stateChanges = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x ||
|
||||||
|
(pGC->patOrg.y + y_off) != pBackingGC->patOrg.y)
|
||||||
|
{
|
||||||
|
XID vals[2];
|
||||||
|
vals[0] = pGC->patOrg.x + x_off;
|
||||||
|
vals[1] = pGC->patOrg.y + y_off;
|
||||||
|
DoChangeGC(pBackingGC, GCTileStipXOrigin|GCTileStipYOrigin, vals, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDrawable->serialNumber != pPriv->serialNumber) {
|
||||||
|
XID vals[2];
|
||||||
|
|
||||||
|
/* Either the drawable has changed, or the clip list in the drawable has
|
||||||
|
* changed. Copy the new clip list over and set the new translated
|
||||||
|
* offset for it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(*pBackingGC->funcs->DestroyClip)(pBackingGC);
|
||||||
|
(*pBackingGC->funcs->CopyClip)(pBackingGC, pGC);
|
||||||
|
vals[0] = pGC->clipOrg.x + x_off;
|
||||||
|
vals[1] = pGC->clipOrg.y + y_off;
|
||||||
|
DoChangeGC(pBackingGC, GCClipXOrigin|GCClipYOrigin, vals, 0);
|
||||||
|
|
||||||
|
ValidateGC(pBackingDrawable, pBackingGC);
|
||||||
|
pPriv->serialNumber = pDrawable->serialNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
FUNC_EPILOGUE(pGC, pPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwChangeGC(GCPtr pGC, unsigned long mask)
|
||||||
|
{
|
||||||
|
cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
|
||||||
|
|
||||||
|
FUNC_PROLOGUE(pGC, pPriv);
|
||||||
|
|
||||||
|
(*pGC->funcs->ChangeGC) (pGC, mask);
|
||||||
|
|
||||||
|
FUNC_EPILOGUE(pGC, pPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
|
||||||
|
{
|
||||||
|
cwGCPtr pPriv = (cwGCPtr)(pGCDst)->devPrivates[cwGCIndex].ptr;
|
||||||
|
|
||||||
|
FUNC_PROLOGUE(pGCDst, pPriv);
|
||||||
|
|
||||||
|
(*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
|
||||||
|
|
||||||
|
FUNC_EPILOGUE(pGCDst, pPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwDestroyGC(GCPtr pGC)
|
||||||
|
{
|
||||||
|
cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
|
||||||
|
|
||||||
|
FUNC_PROLOGUE(pGC, pPriv);
|
||||||
|
|
||||||
|
cwDestroyGCPrivate(pGC);
|
||||||
|
|
||||||
|
(*pGC->funcs->DestroyGC) (pGC);
|
||||||
|
|
||||||
|
/* leave it unwrapped */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
|
||||||
|
{
|
||||||
|
cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
|
||||||
|
|
||||||
|
FUNC_PROLOGUE(pGC, pPriv);
|
||||||
|
|
||||||
|
(*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
|
||||||
|
|
||||||
|
FUNC_EPILOGUE(pGC, pPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
|
||||||
|
{
|
||||||
|
cwGCPtr pPriv = (cwGCPtr)(pgcDst)->devPrivates[cwGCIndex].ptr;
|
||||||
|
|
||||||
|
FUNC_PROLOGUE(pgcDst, pPriv);
|
||||||
|
|
||||||
|
(*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
|
||||||
|
|
||||||
|
FUNC_EPILOGUE(pgcDst, pPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwDestroyClip(GCPtr pGC)
|
||||||
|
{
|
||||||
|
cwGCPtr pPriv = (cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr;
|
||||||
|
|
||||||
|
FUNC_PROLOGUE(pGC, pPriv);
|
||||||
|
|
||||||
|
(*pGC->funcs->DestroyClip)(pGC);
|
||||||
|
|
||||||
|
FUNC_EPILOGUE(pGC, pPriv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cheap GC func wrappers. Pass everything through unless we find a window with
|
||||||
|
* a backing pixmap, then turn on the real wrappers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CHEAP_FUNC_PROLOGUE(pGC) \
|
||||||
|
((pGC)->funcs = (GCFuncs *)(pGC)->devPrivates[cwGCIndex].ptr)
|
||||||
|
|
||||||
|
#define CHEAP_FUNC_EPILOGUE(pGC) \
|
||||||
|
((pGC)->funcs = &cwCheapGCFuncs)
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCheapValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
|
||||||
|
{
|
||||||
|
CHEAP_FUNC_PROLOGUE(pGC);
|
||||||
|
|
||||||
|
/* Check if the drawable is a window with backing pixmap. If so,
|
||||||
|
* cwCreateGCPrivate will wrap with the backing-pixmap GC funcs and we won't
|
||||||
|
* re-wrap on return.
|
||||||
|
*/
|
||||||
|
if (pDrawable->type == DRAWABLE_WINDOW &&
|
||||||
|
cwDrawableIsRedirWindow(pDrawable) &&
|
||||||
|
cwCreateGCPrivate(pGC, pDrawable))
|
||||||
|
{
|
||||||
|
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
|
||||||
|
|
||||||
|
/* rewrap funcs as Validate may have changed them */
|
||||||
|
pGC->devPrivates[cwGCIndex].ptr = (pointer) pGC->funcs;
|
||||||
|
|
||||||
|
CHEAP_FUNC_EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCheapChangeGC(GCPtr pGC, unsigned long mask)
|
||||||
|
{
|
||||||
|
CHEAP_FUNC_PROLOGUE(pGC);
|
||||||
|
|
||||||
|
(*pGC->funcs->ChangeGC)(pGC, mask);
|
||||||
|
|
||||||
|
CHEAP_FUNC_EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCheapCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
|
||||||
|
{
|
||||||
|
CHEAP_FUNC_PROLOGUE(pGCDst);
|
||||||
|
|
||||||
|
(*pGCDst->funcs->CopyGC)(pGCSrc, mask, pGCDst);
|
||||||
|
|
||||||
|
CHEAP_FUNC_EPILOGUE(pGCDst);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCheapDestroyGC(GCPtr pGC)
|
||||||
|
{
|
||||||
|
CHEAP_FUNC_PROLOGUE(pGC);
|
||||||
|
|
||||||
|
(*pGC->funcs->DestroyGC)(pGC);
|
||||||
|
|
||||||
|
/* leave it unwrapped */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCheapChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
|
||||||
|
{
|
||||||
|
CHEAP_FUNC_PROLOGUE(pGC);
|
||||||
|
|
||||||
|
(*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
|
||||||
|
|
||||||
|
CHEAP_FUNC_EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCheapCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
|
||||||
|
{
|
||||||
|
CHEAP_FUNC_PROLOGUE(pgcDst);
|
||||||
|
|
||||||
|
(*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
|
||||||
|
|
||||||
|
CHEAP_FUNC_EPILOGUE(pgcDst);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCheapDestroyClip(GCPtr pGC)
|
||||||
|
{
|
||||||
|
CHEAP_FUNC_PROLOGUE(pGC);
|
||||||
|
|
||||||
|
(*pGC->funcs->DestroyClip)(pGC);
|
||||||
|
|
||||||
|
CHEAP_FUNC_EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GC Create wrapper. Set up the cheap GC func wrappers to track
|
||||||
|
* GC validation on BackingStore windows.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SCREEN_PROLOGUE(pScreen, field)\
|
||||||
|
((pScreen)->field = ((cwScreenPtr) \
|
||||||
|
(pScreen)->devPrivates[cwScreenIndex].ptr)->field)
|
||||||
|
|
||||||
|
#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
|
||||||
|
((pScreen)->field = wrapper)
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
cwCreateGC(GCPtr pGC)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pGC->pScreen;
|
||||||
|
Bool ret;
|
||||||
|
|
||||||
|
SCREEN_PROLOGUE(pScreen, CreateGC);
|
||||||
|
|
||||||
|
if ( (ret = (*pScreen->CreateGC)(pGC)) )
|
||||||
|
{
|
||||||
|
pGC->devPrivates[cwGCIndex].ptr = (pointer)pGC->funcs;
|
||||||
|
pGC->funcs = &cwCheapGCFuncs;
|
||||||
|
}
|
||||||
|
|
||||||
|
SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwGetImage(DrawablePtr pSrc, int sx, int sy, int w, int h, unsigned int format,
|
||||||
|
unsigned long planemask, char *pdstLine)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pSrc->pScreen;
|
||||||
|
DrawablePtr pBackingDrawable;
|
||||||
|
int x_off, y_off;
|
||||||
|
|
||||||
|
SCREEN_PROLOGUE(pScreen, GetImage);
|
||||||
|
|
||||||
|
pBackingDrawable = cwGetBackingDrawable(pSrc, &x_off, &y_off);
|
||||||
|
|
||||||
|
sx += x_off;
|
||||||
|
sy += y_off;
|
||||||
|
|
||||||
|
(*pScreen->GetImage)(pBackingDrawable, sx, sy, w, h, format, planemask, pdstLine);
|
||||||
|
|
||||||
|
SCREEN_EPILOGUE(pScreen, GetImage, cwGetImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwGetSpans(DrawablePtr pSrc, int wMax, DDXPointPtr ppt, int *pwidth,
|
||||||
|
int nspans, char *pdstStart)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pSrc->pScreen;
|
||||||
|
DrawablePtr pBackingDrawable;
|
||||||
|
int i;
|
||||||
|
int x_off, y_off;
|
||||||
|
DDXPointPtr ppt_trans;
|
||||||
|
|
||||||
|
SCREEN_PROLOGUE(pScreen, GetSpans);
|
||||||
|
|
||||||
|
pBackingDrawable = cwGetBackingDrawable(pSrc, &x_off, &y_off);
|
||||||
|
|
||||||
|
ppt_trans = (DDXPointPtr)ALLOCATE_LOCAL(nspans * sizeof(DDXPointRec));
|
||||||
|
if (ppt_trans) {
|
||||||
|
for (i = 0; i < nspans; i++) {
|
||||||
|
ppt_trans[i].x = ppt[i].x + x_off;
|
||||||
|
ppt_trans[i].y = ppt[i].y + y_off;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*pScreen->GetSpans)(pBackingDrawable, wMax, ppt, pwidth, nspans,
|
||||||
|
pdstStart);
|
||||||
|
DEALLOCATE_LOCAL(ppt_trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
SCREEN_EPILOGUE(pScreen, GetSpans, cwGetSpans);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Screen initialization/teardown */
|
||||||
|
void
|
||||||
|
miInitializeCompositeWrapper(ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
cwScreenPtr pScreenPriv;
|
||||||
|
|
||||||
|
if (cwGeneration != serverGeneration)
|
||||||
|
{
|
||||||
|
cwScreenIndex = AllocateScreenPrivateIndex();
|
||||||
|
if (cwScreenIndex < 0)
|
||||||
|
return;
|
||||||
|
cwGCIndex = AllocateGCPrivateIndex();
|
||||||
|
#ifdef RENDER
|
||||||
|
cwPictureIndex = AllocatePicturePrivateIndex();
|
||||||
|
#endif
|
||||||
|
cwGeneration = serverGeneration;
|
||||||
|
}
|
||||||
|
if (!AllocateGCPrivate(pScreen, cwGCIndex, 0))
|
||||||
|
return;
|
||||||
|
pScreenPriv = (cwScreenPtr)xalloc(sizeof(cwScreenRec));
|
||||||
|
if (!pScreenPriv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pScreenPriv->CloseScreen = pScreen->CloseScreen;
|
||||||
|
pScreenPriv->GetImage = pScreen->GetImage;
|
||||||
|
pScreenPriv->GetSpans = pScreen->GetSpans;
|
||||||
|
pScreenPriv->CreateGC = pScreen->CreateGC;
|
||||||
|
|
||||||
|
pScreen->CloseScreen = cwCloseScreen;
|
||||||
|
pScreen->GetImage = cwGetImage;
|
||||||
|
pScreen->GetSpans = cwGetSpans;
|
||||||
|
pScreen->CreateGC = cwCreateGC;
|
||||||
|
|
||||||
|
pScreen->devPrivates[cwScreenIndex].ptr = (pointer)pScreenPriv;
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
if (GetPictureScreen (pScreen))
|
||||||
|
{
|
||||||
|
if (!cwInitializeRender (pScreen))
|
||||||
|
/* FIXME */;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ErrorF("Initialized composite wrapper\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bool
|
||||||
|
cwCloseScreen (int i, ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
cwScreenPtr pScreenPriv;
|
||||||
|
#ifdef RENDER
|
||||||
|
PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pScreenPriv = (cwScreenPtr)pScreen->devPrivates[cwScreenIndex].ptr;
|
||||||
|
|
||||||
|
pScreen->CloseScreen = pScreenPriv->CloseScreen;
|
||||||
|
pScreen->GetImage = pScreenPriv->GetImage;
|
||||||
|
pScreen->GetSpans = pScreenPriv->GetSpans;
|
||||||
|
pScreen->CreateGC = pScreenPriv->CreateGC;
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
if (ps) {
|
||||||
|
ps->Composite = pScreenPriv->Composite;
|
||||||
|
ps->Glyphs = pScreenPriv->Glyphs;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
xfree((pointer)pScreenPriv);
|
||||||
|
|
||||||
|
return (*pScreen->CloseScreen)(i, pScreen);
|
||||||
|
}
|
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2004 Eric Anholt
|
||||||
|
*
|
||||||
|
* 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 Eric Anholt not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the software without
|
||||||
|
* specific, written prior permission. Eric Anholt makes no
|
||||||
|
* representations about the suitability of this software for any purpose. It
|
||||||
|
* is provided "as is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL ERIC ANHOLT 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.
|
||||||
|
*/
|
||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
#include "picturestr.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One of these structures is allocated per GC that gets used with a window with
|
||||||
|
* backing pixmap.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GCPtr pBackingGC; /* Copy of the GC but with graphicsExposures
|
||||||
|
* set FALSE and the clientClip set to
|
||||||
|
* clip output to the valid regions of the
|
||||||
|
* backing pixmap. */
|
||||||
|
int guarantee; /* GuaranteeNothing, etc. */
|
||||||
|
unsigned long serialNumber; /* clientClip computed time */
|
||||||
|
unsigned long stateChanges; /* changes in parent gc since last copy */
|
||||||
|
GCOps *wrapOps; /* wrapped ops */
|
||||||
|
GCFuncs *wrapFuncs; /* wrapped funcs */
|
||||||
|
} cwGCRec, *cwGCPtr;
|
||||||
|
|
||||||
|
extern int cwGCIndex;
|
||||||
|
|
||||||
|
#define getCwGC(pGC) ((cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr)
|
||||||
|
#define setCwGC(pGC,p) ((pGC)->devPrivates[cwGCIndex].ptr = (pointer) (p))
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PicturePtr pBackingPicture;
|
||||||
|
unsigned long serialNumber; /* clientClip computed time */
|
||||||
|
unsigned long stateChanges; /* changes in parent gc since last copy */
|
||||||
|
} cwPictureRec, *cwPicturePtr;
|
||||||
|
|
||||||
|
extern int cwPictureIndex;
|
||||||
|
|
||||||
|
#define getCwPicture(pPicture) ((cwPicturePtr)(pPicture)->devPrivates[cwPictureIndex].ptr)
|
||||||
|
#define setCwPicture(pPicture,p) ((pPicture)->devPrivates[cwPictureIndex].ptr = (pointer) (p))
|
||||||
|
|
||||||
|
#define cwDrawableIsRedirWindow(pDraw) ((pDraw)->type == DRAWABLE_WINDOW && \
|
||||||
|
((WindowPtr)(pDraw))->redirectDraw)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
/*
|
||||||
|
* screen func wrappers
|
||||||
|
*/
|
||||||
|
CloseScreenProcPtr CloseScreen;
|
||||||
|
GetImageProcPtr GetImage;
|
||||||
|
GetSpansProcPtr GetSpans;
|
||||||
|
CreateGCProcPtr CreateGC;
|
||||||
|
|
||||||
|
DestroyWindowProcPtr DestroyWindow;
|
||||||
|
|
||||||
|
StoreColorsProcPtr StoreColors;
|
||||||
|
|
||||||
|
InitIndexedProcPtr InitIndexed;
|
||||||
|
CloseIndexedProcPtr CloseIndexed;
|
||||||
|
UpdateIndexedProcPtr UpdateIndexed;
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
CreatePictureProcPtr CreatePicture;
|
||||||
|
DestroyPictureProcPtr DestroyPicture;
|
||||||
|
ChangePictureClipProcPtr ChangePictureClip;
|
||||||
|
DestroyPictureClipProcPtr DestroyPictureClip;
|
||||||
|
|
||||||
|
ChangePictureProcPtr ChangePicture;
|
||||||
|
ValidatePictureProcPtr ValidatePicture;
|
||||||
|
|
||||||
|
CompositeProcPtr Composite;
|
||||||
|
GlyphsProcPtr Glyphs;
|
||||||
|
CompositeRectsProcPtr CompositeRects;
|
||||||
|
|
||||||
|
TrapezoidsProcPtr Trapezoids;
|
||||||
|
TrianglesProcPtr Triangles;
|
||||||
|
TriStripProcPtr TriStrip;
|
||||||
|
TriFanProcPtr TriFan;
|
||||||
|
|
||||||
|
RasterizeTrapezoidProcPtr RasterizeTrapezoid;
|
||||||
|
#if 0
|
||||||
|
AddTrapsProcPtr AddTraps;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
} cwScreenRec, *cwScreenPtr;
|
||||||
|
|
||||||
|
extern int cwScreenIndex;
|
||||||
|
|
||||||
|
#define getCwScreen(pScreen) ((cwScreenPtr)(pScreen)->devPrivates[cwScreenIndex].ptr)
|
||||||
|
#define setCwScreen(pScreen,p) ((cwScreenPtr)(pScreen)->devPrivates[cwScreenIndex].ptr = (p))
|
||||||
|
|
||||||
|
#define CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, npt) do { \
|
||||||
|
short *_origpt = (short *)(ppt); \
|
||||||
|
short *_transpt = (short *)(ppt_trans); \
|
||||||
|
int _i; \
|
||||||
|
for (_i = 0; _i < npt; _i++) { \
|
||||||
|
*_transpt++ = *_origpt++ + dst_off_x; \
|
||||||
|
*_transpt++ = *_origpt++ + dst_off_y; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CW_COPY_OFFSET_RECTS(prect_trans, prect, nrect) do { \
|
||||||
|
short *_origpt = (short *)(prect); \
|
||||||
|
short *_transpt = (short *)(prect_trans); \
|
||||||
|
int _i; \
|
||||||
|
for (_i = 0; _i < nrect; _i++) { \
|
||||||
|
*_transpt++ = *_origpt++ + dst_off_x; \
|
||||||
|
*_transpt++ = *_origpt++ + dst_off_y; \
|
||||||
|
_transpt += 2; \
|
||||||
|
_origpt += 2; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CW_COPY_OFFSET_ARCS(parc_trans, parc, narc) do { \
|
||||||
|
short *_origpt = (short *)(parc); \
|
||||||
|
short *_transpt = (short *)(parc_trans); \
|
||||||
|
int _i; \
|
||||||
|
for (_i = 0; _i < narc; _i++) { \
|
||||||
|
*_transpt++ = *_origpt++ + dst_off_x; \
|
||||||
|
*_transpt++ = *_origpt++ + dst_off_y; \
|
||||||
|
_transpt += 4; \
|
||||||
|
_origpt += 4; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CW_COPY_OFFSET_XY_DST(bx, by, x, y) do { \
|
||||||
|
bx = x + dst_off_x; \
|
||||||
|
by = y + dst_off_y; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CW_COPY_OFFSET_XY_SRC(bx, by, x, y) do { \
|
||||||
|
bx = x + src_off_x; \
|
||||||
|
by = y + src_off_y; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/* cw.c */
|
||||||
|
DrawablePtr
|
||||||
|
cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off);
|
||||||
|
|
||||||
|
/* cw_render.c */
|
||||||
|
|
||||||
|
Bool
|
||||||
|
cwInitializeRender (ScreenPtr pScreen);
|
||||||
|
|
||||||
|
/* cw.c */
|
||||||
|
void
|
||||||
|
miInitializeCompositeWrapper(ScreenPtr pScreen);
|
|
@ -0,0 +1,537 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2004 Eric Anholt
|
||||||
|
*
|
||||||
|
* 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 Eric Anholt not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the software without
|
||||||
|
* specific, written prior permission. Eric Anholt makes no
|
||||||
|
* representations about the suitability of this software for any purpose. It
|
||||||
|
* is provided "as is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL ERIC ANHOLT 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.
|
||||||
|
*/
|
||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
#include "gcstruct.h"
|
||||||
|
#include "cw.h"
|
||||||
|
|
||||||
|
#define SETUP_BACKING_DST(_pDst, _pGC) \
|
||||||
|
cwGCPtr pGCPrivate = getCwGC (_pGC); \
|
||||||
|
GCFuncs *oldFuncs = (_pGC)->funcs; \
|
||||||
|
GCPtr pBackingGC = pGCPrivate->pBackingGC; \
|
||||||
|
int dst_off_x, dst_off_y; \
|
||||||
|
DrawablePtr pBackingDst = cwGetBackingDrawable(pDst, &dst_off_x, \
|
||||||
|
&dst_off_y)
|
||||||
|
|
||||||
|
#define SETUP_BACKING_SRC(pSrc, pGC) \
|
||||||
|
int src_off_x, src_off_y; \
|
||||||
|
DrawablePtr pBackingSrc = cwGetBackingDrawable(pSrc, &src_off_x, \
|
||||||
|
&src_off_y)
|
||||||
|
|
||||||
|
#define PROLOGUE(pGC) do { \
|
||||||
|
pGC->ops = pGCPrivate->wrapOps;\
|
||||||
|
pGC->funcs = pGCPrivate->wrapFuncs; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define EPILOGUE(pGC) do { \
|
||||||
|
pGCPrivate->wrapOps = (pGC)->ops; \
|
||||||
|
(pGC)->ops = &cwGCOps; \
|
||||||
|
(pGC)->funcs = oldFuncs; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GC ops -- wrap each GC operation with our own function
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nInit,
|
||||||
|
DDXPointPtr pptInit, int *pwidthInit, int fSorted);
|
||||||
|
static void cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc,
|
||||||
|
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
|
||||||
|
static void cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth,
|
||||||
|
int x, int y, int w, int h, int leftPad, int format,
|
||||||
|
char *pBits);
|
||||||
|
static RegionPtr cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int srcx, int srcy, int w, int h,
|
||||||
|
int dstx, int dsty);
|
||||||
|
static RegionPtr cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int srcx, int srcy, int w, int h,
|
||||||
|
int dstx, int dsty, unsigned long plane);
|
||||||
|
static void cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt,
|
||||||
|
xPoint *pptInit);
|
||||||
|
static void cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt,
|
||||||
|
DDXPointPtr pptInit);
|
||||||
|
static void cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg,
|
||||||
|
xSegment *pSegs);
|
||||||
|
static void cwPolyRectangle(DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int nrects, xRectangle *pRects);
|
||||||
|
static void cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs);
|
||||||
|
static void cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode,
|
||||||
|
int count, DDXPointPtr pPts);
|
||||||
|
static void cwPolyFillRect(DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int nrectFill, xRectangle *prectInit);
|
||||||
|
static void cwPolyFillArc(DrawablePtr pDst, GCPtr pGC,
|
||||||
|
int narcs, xArc *parcs);
|
||||||
|
static int cwPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y,
|
||||||
|
int count, char *chars);
|
||||||
|
static int cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y,
|
||||||
|
int count, unsigned short *chars);
|
||||||
|
static void cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y,
|
||||||
|
int count, char *chars);
|
||||||
|
static void cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y,
|
||||||
|
int count, unsigned short *chars);
|
||||||
|
static void cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y,
|
||||||
|
unsigned int nglyph, CharInfoPtr *ppci,
|
||||||
|
pointer pglyphBase);
|
||||||
|
static void cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y,
|
||||||
|
unsigned int nglyph, CharInfoPtr *ppci,
|
||||||
|
pointer pglyphBase);
|
||||||
|
static void cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst,
|
||||||
|
int w, int h, int x, int y);
|
||||||
|
|
||||||
|
GCOps cwGCOps = {
|
||||||
|
cwFillSpans,
|
||||||
|
cwSetSpans,
|
||||||
|
cwPutImage,
|
||||||
|
cwCopyArea,
|
||||||
|
cwCopyPlane,
|
||||||
|
cwPolyPoint,
|
||||||
|
cwPolylines,
|
||||||
|
cwPolySegment,
|
||||||
|
cwPolyRectangle,
|
||||||
|
cwPolyArc,
|
||||||
|
cwFillPolygon,
|
||||||
|
cwPolyFillRect,
|
||||||
|
cwPolyFillArc,
|
||||||
|
cwPolyText8,
|
||||||
|
cwPolyText16,
|
||||||
|
cwImageText8,
|
||||||
|
cwImageText16,
|
||||||
|
cwImageGlyphBlt,
|
||||||
|
cwPolyGlyphBlt,
|
||||||
|
cwPushPixels
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwFillSpans(DrawablePtr pDst, GCPtr pGC, int nspans, DDXPointPtr ppt,
|
||||||
|
int *pwidth, int fSorted)
|
||||||
|
{
|
||||||
|
DDXPointPtr ppt_trans;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
ppt_trans = (DDXPointPtr)ALLOCATE_LOCAL(nspans * sizeof(DDXPointRec));
|
||||||
|
if (ppt_trans)
|
||||||
|
{
|
||||||
|
CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, nspans);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->FillSpans)(pBackingDst, pBackingGC,
|
||||||
|
nspans, ppt_trans, pwidth, fSorted);
|
||||||
|
|
||||||
|
DEALLOCATE_LOCAL(ppt_trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwSetSpans(DrawablePtr pDst, GCPtr pGC, char *psrc, DDXPointPtr ppt,
|
||||||
|
int *pwidth, int nspans, int fSorted)
|
||||||
|
{
|
||||||
|
DDXPointPtr ppt_trans;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
ppt_trans = (DDXPointPtr)ALLOCATE_LOCAL(nspans*sizeof(DDXPointRec));
|
||||||
|
if (ppt_trans)
|
||||||
|
{
|
||||||
|
CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, nspans);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->SetSpans)(pBackingDst, pBackingGC, psrc,
|
||||||
|
ppt_trans, pwidth, nspans, fSorted);
|
||||||
|
|
||||||
|
DEALLOCATE_LOCAL(ppt_trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwPutImage(DrawablePtr pDst, GCPtr pGC, int depth, int x, int y, int w, int h,
|
||||||
|
int leftPad, int format, char *pBits)
|
||||||
|
{
|
||||||
|
int bx, by;
|
||||||
|
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
CW_COPY_OFFSET_XY_DST(bx, by, x, y);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->PutImage)(pBackingDst, pBackingGC, depth, bx, by,
|
||||||
|
w, h, leftPad, format, pBits);
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegionPtr
|
||||||
|
cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
|
||||||
|
int w, int h, int dstx, int dsty)
|
||||||
|
{
|
||||||
|
int bsrcx, bsrcy, bdstx, bdsty;
|
||||||
|
RegionPtr exposed = NULL;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
SETUP_BACKING_SRC(pSrc, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
CW_COPY_OFFSET_XY_DST(bdstx, bdsty, dstx, dsty);
|
||||||
|
CW_COPY_OFFSET_XY_SRC(bsrcx, bsrcy, srcx, srcy);
|
||||||
|
|
||||||
|
exposed = (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst,
|
||||||
|
pBackingGC, bsrcx, bsrcy, w, h,
|
||||||
|
bdstx, bdsty);
|
||||||
|
|
||||||
|
/* XXX: Simplify? */
|
||||||
|
if (exposed != NULL)
|
||||||
|
REGION_TRANSLATE(pDst->pScreen, exposed, dstx - bdstx, dsty - bdsty);
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
|
||||||
|
return exposed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegionPtr
|
||||||
|
cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
|
||||||
|
int w, int h, int dstx, int dsty, unsigned long plane)
|
||||||
|
{
|
||||||
|
int bsrcx, bsrcy, bdstx, bdsty;
|
||||||
|
RegionPtr exposed = NULL;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
SETUP_BACKING_SRC(pSrc, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
CW_COPY_OFFSET_XY_DST(bdstx, bdsty, dstx, dsty);
|
||||||
|
CW_COPY_OFFSET_XY_SRC(bsrcx, bsrcy, srcx, srcy);
|
||||||
|
|
||||||
|
exposed = (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst,
|
||||||
|
pBackingGC, bsrcx, bsrcy, w, h,
|
||||||
|
bdstx, bdsty, plane);
|
||||||
|
|
||||||
|
/* XXX: Simplify? */
|
||||||
|
REGION_TRANSLATE(pDst->pScreen, exposed, dstx - bdstx, dsty - bdsty);
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
|
||||||
|
return exposed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwPolyPoint(DrawablePtr pDst, GCPtr pGC, int mode, int npt, xPoint *ppt)
|
||||||
|
{
|
||||||
|
xPoint *ppt_trans;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
ppt_trans = (xPoint *)ALLOCATE_LOCAL(npt * sizeof(xPoint));
|
||||||
|
if (ppt_trans)
|
||||||
|
{
|
||||||
|
CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, npt);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->PolyPoint)(pBackingDst, pBackingGC, mode, npt,
|
||||||
|
ppt_trans);
|
||||||
|
|
||||||
|
DEALLOCATE_LOCAL(ppt_trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwPolylines(DrawablePtr pDst, GCPtr pGC, int mode, int npt, DDXPointPtr ppt)
|
||||||
|
{
|
||||||
|
DDXPointPtr ppt_trans;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
ppt_trans = (DDXPointPtr)ALLOCATE_LOCAL(npt * sizeof(DDXPointRec));
|
||||||
|
if (ppt_trans)
|
||||||
|
{
|
||||||
|
CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, npt);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->Polylines)(pBackingDst, pBackingGC, mode, npt,
|
||||||
|
ppt_trans);
|
||||||
|
|
||||||
|
DEALLOCATE_LOCAL(ppt_trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwPolySegment(DrawablePtr pDst, GCPtr pGC, int nseg, xSegment *pSegs)
|
||||||
|
{
|
||||||
|
xSegment *psegs_trans;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
psegs_trans = (xSegment *)ALLOCATE_LOCAL(nseg * sizeof(xSegment));
|
||||||
|
if (psegs_trans)
|
||||||
|
{
|
||||||
|
CW_COPY_OFFSET_XYPOINTS(psegs_trans, pSegs, nseg * 2);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->PolySegment)(pBackingDst, pBackingGC, nseg,
|
||||||
|
psegs_trans);
|
||||||
|
|
||||||
|
DEALLOCATE_LOCAL(psegs_trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwPolyRectangle(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects)
|
||||||
|
{
|
||||||
|
xRectangle *prects_trans;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
prects_trans = (xRectangle *)ALLOCATE_LOCAL(nrects * sizeof(xRectangle));
|
||||||
|
if (prects_trans)
|
||||||
|
{
|
||||||
|
CW_COPY_OFFSET_RECTS(prects_trans, pRects, nrects);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->PolyRectangle)(pBackingDst, pBackingGC, nrects,
|
||||||
|
prects_trans);
|
||||||
|
|
||||||
|
DEALLOCATE_LOCAL(pRectsCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwPolyArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *pArcs)
|
||||||
|
{
|
||||||
|
xArc *parcs_trans;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
parcs_trans = (xArc *)ALLOCATE_LOCAL(narcs * sizeof(xArc));
|
||||||
|
if (parcs_trans)
|
||||||
|
{
|
||||||
|
CW_COPY_OFFSET_RECTS(parcs_trans, pArcs, narcs);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->PolyArc)(pBackingDst, pBackingGC, narcs,
|
||||||
|
parcs_trans);
|
||||||
|
|
||||||
|
DEALLOCATE_LOCAL(parcs_trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwFillPolygon(DrawablePtr pDst, GCPtr pGC, int shape, int mode, int npt,
|
||||||
|
DDXPointPtr ppt)
|
||||||
|
{
|
||||||
|
DDXPointPtr ppt_trans;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
ppt_trans = (DDXPointPtr)ALLOCATE_LOCAL(npt * sizeof(DDXPointRec));
|
||||||
|
if (ppt_trans)
|
||||||
|
{
|
||||||
|
CW_COPY_OFFSET_XYPOINTS(ppt_trans, ppt, npt);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->FillPolygon)(pBackingDst, pBackingGC, shape, mode,
|
||||||
|
npt, ppt_trans);
|
||||||
|
|
||||||
|
DEALLOCATE_LOCAL(ppt_trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwPolyFillRect(DrawablePtr pDst, GCPtr pGC, int nrects, xRectangle *pRects)
|
||||||
|
{
|
||||||
|
xRectangle *prects_trans;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
prects_trans = (xRectangle *)ALLOCATE_LOCAL(nrects * sizeof(xRectangle));
|
||||||
|
if (prects_trans)
|
||||||
|
{
|
||||||
|
CW_COPY_OFFSET_RECTS(prects_trans, pRects, nrects);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->PolyFillRect)(pBackingDst, pBackingGC, nrects,
|
||||||
|
prects_trans);
|
||||||
|
|
||||||
|
DEALLOCATE_LOCAL(pRectsCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwPolyFillArc(DrawablePtr pDst, GCPtr pGC, int narcs, xArc *parcs)
|
||||||
|
{
|
||||||
|
xArc *parcs_trans;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
parcs_trans = (xArc *)ALLOCATE_LOCAL(narcs * sizeof(xArc));
|
||||||
|
if (parcs_trans)
|
||||||
|
{
|
||||||
|
CW_COPY_OFFSET_RECTS(parcs_trans, parcs, narcs);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->PolyFillArc)(pBackingDst, pBackingGC, narcs,
|
||||||
|
parcs_trans);
|
||||||
|
|
||||||
|
DEALLOCATE_LOCAL(parcs_trans);
|
||||||
|
}
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cwPolyText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int bx, by;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
CW_COPY_OFFSET_XY_DST(bx, by, x, y);
|
||||||
|
|
||||||
|
result = (*pBackingGC->ops->PolyText8)(pBackingDst, pBackingGC, bx, by,
|
||||||
|
count, chars);
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cwPolyText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count,
|
||||||
|
unsigned short *chars)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int bx, by;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
CW_COPY_OFFSET_XY_DST(bx, by, x, y);
|
||||||
|
|
||||||
|
result = (*pBackingGC->ops->PolyText16)(pBackingDst, pBackingGC, bx, by,
|
||||||
|
count, chars);
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwImageText8(DrawablePtr pDst, GCPtr pGC, int x, int y, int count, char *chars)
|
||||||
|
{
|
||||||
|
int bx, by;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
CW_COPY_OFFSET_XY_DST(bx, by, x, y);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->ImageText8)(pBackingDst, pBackingGC, bx, by, count,
|
||||||
|
chars);
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwImageText16(DrawablePtr pDst, GCPtr pGC, int x, int y, int count,
|
||||||
|
unsigned short *chars)
|
||||||
|
{
|
||||||
|
int bx, by;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
CW_COPY_OFFSET_XY_DST(bx, by, x, y);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->ImageText16)(pBackingDst, pBackingGC, bx, by, count,
|
||||||
|
chars);
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwImageGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph,
|
||||||
|
CharInfoPtr *ppci, pointer pglyphBase)
|
||||||
|
{
|
||||||
|
int bx, by;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
CW_COPY_OFFSET_XY_DST(bx, by, x, y);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->ImageGlyphBlt)(pBackingDst, pBackingGC, bx, by, nglyph,
|
||||||
|
ppci, pglyphBase);
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwPolyGlyphBlt(DrawablePtr pDst, GCPtr pGC, int x, int y, unsigned int nglyph,
|
||||||
|
CharInfoPtr *ppci, pointer pglyphBase)
|
||||||
|
{
|
||||||
|
int bx, by;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
CW_COPY_OFFSET_XY_DST(bx, by, x, y);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->PolyGlyphBlt)(pBackingDst, pBackingGC, bx, by, nglyph,
|
||||||
|
ppci, pglyphBase);
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, int w, int h,
|
||||||
|
int x, int y)
|
||||||
|
{
|
||||||
|
int bx, by;
|
||||||
|
SETUP_BACKING_DST(pDst, pGC);
|
||||||
|
|
||||||
|
PROLOGUE(pGC);
|
||||||
|
|
||||||
|
CW_COPY_OFFSET_XY_DST(bx, by, x, y);
|
||||||
|
|
||||||
|
(*pBackingGC->ops->PushPixels)(pBackingGC, pBitMap, pBackingDst, w, h,
|
||||||
|
bx, by);
|
||||||
|
|
||||||
|
EPILOGUE(pGC);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,447 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2004 Eric Anholt
|
||||||
|
*
|
||||||
|
* 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 Eric Anholt not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the software without
|
||||||
|
* specific, written prior permission. Eric Anholt makes no
|
||||||
|
* representations about the suitability of this software for any purpose. It
|
||||||
|
* is provided "as is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||||
|
* EVENT SHALL ERIC ANHOLT 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.
|
||||||
|
*/
|
||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
#include "gcstruct.h"
|
||||||
|
#include "windowstr.h"
|
||||||
|
#include "cw.h"
|
||||||
|
|
||||||
|
#ifdef RENDER
|
||||||
|
|
||||||
|
#define cwPsDecl(pScreen) \
|
||||||
|
PictureScreenPtr ps = GetPictureScreen (pScreen); \
|
||||||
|
cwScreenPtr pCwScreen = getCwScreen (pScreen)
|
||||||
|
|
||||||
|
#define cwBackingPicture(pCwPicture, pPicture) \
|
||||||
|
((pCwPicture && pCwPicture->pBackingPicture) ? \
|
||||||
|
pCwPicture->pBackingPicture : pPicture)
|
||||||
|
|
||||||
|
#define cwPictureDecl \
|
||||||
|
cwPicturePtr pCwPicture = getCwPicture(pPicture); \
|
||||||
|
PicturePtr pBackingPicture = pCwPicture ? pCwPicture->pBackingPicture : 0
|
||||||
|
|
||||||
|
#define cwSrcPictureDecl \
|
||||||
|
int src_picture_x_off, src_picture_y_off; \
|
||||||
|
PicturePtr pBackingSrcPicture = cwGetBackingPicture(pSrcPicture, \
|
||||||
|
&src_picture_x_off,\
|
||||||
|
&src_picture_y_off)
|
||||||
|
|
||||||
|
#define cwDstPictureDecl \
|
||||||
|
int dst_picture_x_off, dst_picture_y_off; \
|
||||||
|
PicturePtr pBackingDstPicture = cwGetBackingPicture(pDstPicture, \
|
||||||
|
&dst_picture_x_off,\
|
||||||
|
&dst_picture_y_off)
|
||||||
|
|
||||||
|
#define cwMskPictureDecl \
|
||||||
|
int msk_picture_x_off = 0, msk_picture_y_off = 0; \
|
||||||
|
PicturePtr pBackingMskPicture = (!pMskPicture ? 0 : \
|
||||||
|
cwGetBackingPicture(pMskPicture, \
|
||||||
|
&msk_picture_x_off,\
|
||||||
|
&msk_picture_y_off))
|
||||||
|
|
||||||
|
#define cwPsUnwrap(elt) { \
|
||||||
|
ps->elt = pCwScreen->elt; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define cwPsWrap(elt,func) { \
|
||||||
|
pCwScreen->elt = ps->elt; \
|
||||||
|
ps->elt = func; \
|
||||||
|
}
|
||||||
|
|
||||||
|
static VisualPtr
|
||||||
|
cwFindVisualById (ScreenPtr pScreen, VisualID visual)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
VisualPtr pVisual;
|
||||||
|
for (i = 0, pVisual = pScreen->visuals;
|
||||||
|
i < pScreen->numVisuals;
|
||||||
|
i++, pVisual++)
|
||||||
|
{
|
||||||
|
if (pVisual->vid == visual)
|
||||||
|
return pVisual;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PicturePtr
|
||||||
|
cwCreateBackingPicture (PicturePtr pPicture)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
||||||
|
WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
|
||||||
|
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWindow);
|
||||||
|
VisualPtr pVisual = cwFindVisualById (pScreen, wVisual (pWindow));
|
||||||
|
PictFormatPtr pFormat = PictureMatchVisual (pScreen, pWindow->drawable.depth,
|
||||||
|
pVisual);
|
||||||
|
int error;
|
||||||
|
PicturePtr pBackingPicture = CreatePicture (0, &pPixmap->drawable, pFormat,
|
||||||
|
0, 0, serverClient, &error);
|
||||||
|
cwPicturePtr pCwPicture = getCwPicture (pPicture);
|
||||||
|
|
||||||
|
return pCwPicture->pBackingPicture = pBackingPicture;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwDestroyBackingPicture (PicturePtr pPicture)
|
||||||
|
{
|
||||||
|
cwPictureDecl;
|
||||||
|
|
||||||
|
if (pBackingPicture)
|
||||||
|
{
|
||||||
|
FreePicture (pBackingPicture, 0);
|
||||||
|
pCwPicture->pBackingPicture = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static PicturePtr
|
||||||
|
cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
|
||||||
|
{
|
||||||
|
cwPictureDecl;
|
||||||
|
|
||||||
|
if (pBackingPicture)
|
||||||
|
{
|
||||||
|
DrawablePtr pDrawable = pPicture->pDrawable;
|
||||||
|
ScreenPtr pScreen = pDrawable->pScreen;
|
||||||
|
WindowPtr pWin = (WindowPtr) pDrawable;
|
||||||
|
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||||
|
|
||||||
|
*x_off = -pPixmap->screen_x;
|
||||||
|
*y_off = -pPixmap->screen_y;
|
||||||
|
|
||||||
|
return pBackingPicture;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*x_off = *y_off = 0;
|
||||||
|
return pPicture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cwCreatePicture (PicturePtr pPicture)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
||||||
|
cwPsDecl(pScreen);
|
||||||
|
|
||||||
|
cwPsUnwrap (CreatePicture);
|
||||||
|
setCwPicture(pPicture, 0);
|
||||||
|
ret = (*ps->CreatePicture) (pPicture);
|
||||||
|
cwPsWrap (CreatePicture, cwCreatePicture);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwDestroyPicture (PicturePtr pPicture)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
||||||
|
cwPsDecl(pScreen);
|
||||||
|
|
||||||
|
cwPsUnwrap(DestroyPicture);
|
||||||
|
cwDestroyBackingPicture (pPicture);
|
||||||
|
(*ps->DestroyPicture) (pPicture);
|
||||||
|
cwPsWrap(DestroyPicture, cwDestroyPicture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwChangePicture (PicturePtr pPicture,
|
||||||
|
Mask mask)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
||||||
|
cwPsDecl(pScreen);
|
||||||
|
cwPictureDecl;
|
||||||
|
|
||||||
|
cwPsUnwrap(ChangePicture);
|
||||||
|
if (pBackingPicture)
|
||||||
|
{
|
||||||
|
(*ps->ChangePicture) (pBackingPicture, mask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*ps->ChangePicture) (pPicture, mask);
|
||||||
|
}
|
||||||
|
cwPsWrap(ChangePicture, cwChangePicture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwValidatePicture (PicturePtr pPicture,
|
||||||
|
Mask mask)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
||||||
|
cwPsDecl(pScreen);
|
||||||
|
cwPictureDecl;
|
||||||
|
|
||||||
|
cwPsUnwrap(ValidatePicture);
|
||||||
|
(*ps->ValidatePicture) (pPicture, mask);
|
||||||
|
if (!cwDrawableIsRedirWindow (pPicture->pDrawable))
|
||||||
|
{
|
||||||
|
if (pBackingPicture)
|
||||||
|
cwDestroyBackingPicture (pPicture);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawablePtr pDrawable = pPicture->pDrawable;
|
||||||
|
WindowPtr pWin = (WindowPtr) (pDrawable);
|
||||||
|
DrawablePtr pBackingDrawable;
|
||||||
|
int x_off, y_off;
|
||||||
|
|
||||||
|
if (pBackingPicture && pBackingPicture->pDrawable !=
|
||||||
|
&(*pScreen->GetWindowPixmap) ((WindowPtr) pPicture->pDrawable)->drawable)
|
||||||
|
{
|
||||||
|
cwDestroyBackingPicture (pPicture);
|
||||||
|
pBackingPicture = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pBackingPicture)
|
||||||
|
{
|
||||||
|
pBackingPicture = cwCreateBackingPicture (pPicture);
|
||||||
|
if (!pBackingPicture)
|
||||||
|
{
|
||||||
|
cwPsWrap(ValidatePicture, cwValidatePicture);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pBackingDrawable = cwGetBackingDrawable (&pWin->drawable, &x_off, &y_off);
|
||||||
|
|
||||||
|
/* Check to see if a new composite clip must be generated */
|
||||||
|
|
||||||
|
if (pDrawable->serialNumber != pCwPicture->serialNumber ||
|
||||||
|
(mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)))
|
||||||
|
{
|
||||||
|
RegionPtr pCompositeClip;
|
||||||
|
|
||||||
|
pCompositeClip = REGION_CREATE(pScreen, NULL, 1);
|
||||||
|
/* note - CT_PIXMAP "cannot" happen because no DDX supports it*/
|
||||||
|
REGION_COPY (pScreen, pCompositeClip, pPicture->pCompositeClip);
|
||||||
|
SetPictureClipRegion (pBackingPicture, -x_off, -y_off,
|
||||||
|
pCompositeClip);
|
||||||
|
pCwPicture->serialNumber = pDrawable->serialNumber;
|
||||||
|
}
|
||||||
|
mask |= pCwPicture->stateChanges;
|
||||||
|
(*ps->ValidatePicture) (pBackingPicture, mask);
|
||||||
|
pCwPicture->stateChanges = 0;
|
||||||
|
pBackingPicture->serialNumber = pBackingDrawable->serialNumber;
|
||||||
|
}
|
||||||
|
cwPsWrap(ValidatePicture, cwValidatePicture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwComposite (CARD8 op,
|
||||||
|
PicturePtr pSrcPicture,
|
||||||
|
PicturePtr pMskPicture,
|
||||||
|
PicturePtr pDstPicture,
|
||||||
|
INT16 xSrc,
|
||||||
|
INT16 ySrc,
|
||||||
|
INT16 xMsk,
|
||||||
|
INT16 yMsk,
|
||||||
|
INT16 xDst,
|
||||||
|
INT16 yDst,
|
||||||
|
CARD16 width,
|
||||||
|
CARD16 height)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
|
||||||
|
cwPsDecl(pScreen);
|
||||||
|
cwSrcPictureDecl;
|
||||||
|
cwMskPictureDecl;
|
||||||
|
cwDstPictureDecl;
|
||||||
|
|
||||||
|
cwPsUnwrap(Composite);
|
||||||
|
(*ps->Composite) (op, pBackingSrcPicture, pBackingMskPicture, pBackingDstPicture,
|
||||||
|
xSrc + src_picture_x_off, ySrc + src_picture_y_off,
|
||||||
|
xMsk + msk_picture_x_off, yMsk + msk_picture_y_off,
|
||||||
|
xDst + dst_picture_x_off, yDst + dst_picture_y_off,
|
||||||
|
width, height);
|
||||||
|
cwPsWrap(Composite, cwComposite);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwGlyphs (CARD8 op,
|
||||||
|
PicturePtr pSrcPicture,
|
||||||
|
PicturePtr pDstPicture,
|
||||||
|
PictFormatPtr maskFormat,
|
||||||
|
INT16 xSrc,
|
||||||
|
INT16 ySrc,
|
||||||
|
int nlists,
|
||||||
|
GlyphListPtr lists,
|
||||||
|
GlyphPtr *glyphs)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
|
||||||
|
cwPsDecl(pScreen);
|
||||||
|
cwSrcPictureDecl;
|
||||||
|
cwDstPictureDecl;
|
||||||
|
|
||||||
|
cwPsUnwrap(Glyphs);
|
||||||
|
if (nlists)
|
||||||
|
{
|
||||||
|
lists->xOff += dst_picture_x_off;
|
||||||
|
lists->yOff += dst_picture_y_off;
|
||||||
|
}
|
||||||
|
(*ps->Glyphs) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
|
||||||
|
xSrc + src_picture_x_off, ySrc + src_picture_y_off,
|
||||||
|
nlists, lists, glyphs);
|
||||||
|
if (nlists)
|
||||||
|
{
|
||||||
|
lists->xOff -= dst_picture_x_off;
|
||||||
|
lists->yOff -= dst_picture_y_off;
|
||||||
|
}
|
||||||
|
cwPsWrap(Glyphs, cwGlyphs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwCompositeRects (CARD8 op,
|
||||||
|
PicturePtr pDstPicture,
|
||||||
|
xRenderColor *color,
|
||||||
|
int nRect,
|
||||||
|
xRectangle *rects)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
|
||||||
|
cwPsDecl(pScreen);
|
||||||
|
cwDstPictureDecl;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cwPsUnwrap(CompositeRects);
|
||||||
|
for (i = 0; i < nRect; i++)
|
||||||
|
{
|
||||||
|
rects[i].x += dst_picture_x_off;
|
||||||
|
rects[i].y += dst_picture_y_off;
|
||||||
|
}
|
||||||
|
(*ps->CompositeRects) (op, pBackingDstPicture, color, nRect, rects);
|
||||||
|
for (i = 0; i < nRect; i++)
|
||||||
|
{
|
||||||
|
rects[i].x -= dst_picture_x_off;
|
||||||
|
rects[i].y -= dst_picture_y_off;
|
||||||
|
}
|
||||||
|
cwPsWrap(CompositeRects, cwCompositeRects);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwTrapezoids (CARD8 op,
|
||||||
|
PicturePtr pSrcPicture,
|
||||||
|
PicturePtr pDstPicture,
|
||||||
|
PictFormatPtr maskFormat,
|
||||||
|
INT16 xSrc,
|
||||||
|
INT16 ySrc,
|
||||||
|
int ntrap,
|
||||||
|
xTrapezoid *traps)
|
||||||
|
{
|
||||||
|
ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
|
||||||
|
cwPsDecl(pScreen);
|
||||||
|
cwSrcPictureDecl;
|
||||||
|
cwDstPictureDecl;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cwPsUnwrap(Trapezoids);
|
||||||
|
if (dst_picture_x_off | dst_picture_y_off)
|
||||||
|
for (i = 0; i < ntrap; i++)
|
||||||
|
{
|
||||||
|
traps[i].top += dst_picture_y_off << 16;
|
||||||
|
traps[i].bottom += dst_picture_y_off << 16;
|
||||||
|
traps[i].left.p1.x += dst_picture_x_off << 16;
|
||||||
|
traps[i].left.p1.y += dst_picture_y_off << 16;
|
||||||
|
traps[i].left.p2.x += dst_picture_x_off << 16;
|
||||||
|
traps[i].left.p2.y += dst_picture_y_off << 16;
|
||||||
|
traps[i].right.p1.x += dst_picture_x_off << 16;
|
||||||
|
traps[i].right.p1.y += dst_picture_y_off << 16;
|
||||||
|
traps[i].right.p2.x += dst_picture_x_off << 16;
|
||||||
|
traps[i].right.p2.y += dst_picture_y_off << 16;
|
||||||
|
}
|
||||||
|
(*ps->Trapezoids) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
|
||||||
|
xSrc + src_picture_x_off, ySrc + src_picture_y_off,
|
||||||
|
ntrap, traps);
|
||||||
|
if (dst_picture_x_off | dst_picture_y_off)
|
||||||
|
for (i = 0; i < ntrap; i++)
|
||||||
|
{
|
||||||
|
traps[i].top -= dst_picture_y_off << 16;
|
||||||
|
traps[i].bottom -= dst_picture_y_off << 16;
|
||||||
|
traps[i].left.p1.x -= dst_picture_x_off << 16;
|
||||||
|
traps[i].left.p1.y -= dst_picture_y_off << 16;
|
||||||
|
traps[i].left.p2.x -= dst_picture_x_off << 16;
|
||||||
|
traps[i].left.p2.y -= dst_picture_y_off << 16;
|
||||||
|
traps[i].right.p1.x -= dst_picture_x_off << 16;
|
||||||
|
traps[i].right.p1.y -= dst_picture_y_off << 16;
|
||||||
|
traps[i].right.p2.x -= dst_picture_x_off << 16;
|
||||||
|
traps[i].right.p2.y -= dst_picture_y_off << 16;
|
||||||
|
}
|
||||||
|
cwPsWrap(Trapezoids, cwTrapezoids);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwTriangles (CARD8 op,
|
||||||
|
PicturePtr pSrc,
|
||||||
|
PicturePtr pDst,
|
||||||
|
PictFormatPtr maskFormat,
|
||||||
|
INT16 xSrc,
|
||||||
|
INT16 ySrc,
|
||||||
|
int ntri,
|
||||||
|
xTriangle *tris)
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwTriStrip (CARD8 op,
|
||||||
|
PicturePtr pSrc,
|
||||||
|
PicturePtr pDst,
|
||||||
|
PictFormatPtr maskFormat,
|
||||||
|
INT16 xSrc,
|
||||||
|
INT16 ySrc,
|
||||||
|
int npoint,
|
||||||
|
xPointFixed *points)
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cwTriFan (CARD8 op,
|
||||||
|
PicturePtr pSrc,
|
||||||
|
PicturePtr pDst,
|
||||||
|
PictFormatPtr maskFormat,
|
||||||
|
INT16 xSrc,
|
||||||
|
INT16 ySrc,
|
||||||
|
int npoint,
|
||||||
|
xPointFixed *points)
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
cwInitializeRender (ScreenPtr pScreen)
|
||||||
|
{
|
||||||
|
cwPsDecl (pScreen);
|
||||||
|
|
||||||
|
if (!AllocatePicturePrivate (pScreen, cwPictureIndex, 0))
|
||||||
|
return FALSE;
|
||||||
|
cwPsWrap(CreatePicture, cwCreatePicture);
|
||||||
|
cwPsWrap(DestroyPicture, cwDestroyPicture);
|
||||||
|
cwPsWrap(ChangePicture, cwChangePicture);
|
||||||
|
cwPsWrap(ValidatePicture, cwValidatePicture);
|
||||||
|
cwPsWrap(Composite, cwComposite);
|
||||||
|
cwPsWrap(Glyphs, cwGlyphs);
|
||||||
|
cwPsWrap(CompositeRects, cwCompositeRects);
|
||||||
|
cwPsWrap(Trapezoids, cwTrapezoids);
|
||||||
|
cwPsWrap(Triangles, cwTriangles);
|
||||||
|
cwPsWrap(TriStrip, cwTriStrip);
|
||||||
|
cwPsWrap(TriFan, cwTriFan);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* RENDER */
|
Loading…
Reference in New Issue