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 $ */
|
||||
/***********************************************************
|
||||
|
||||
|
@ -190,7 +190,15 @@ static void FindColorInRootCmap (
|
|||
#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
|
||||
#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 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) --
|
||||
* (Suggestion: First read the macro, then read this explanation.
|
||||
|
@ -866,6 +874,9 @@ AllocColor (pmap, pred, pgreen, pblue, pPix, client)
|
|||
*pPix = (pixR << pVisual->offsetRed) |
|
||||
(pixG << pVisual->offsetGreen) |
|
||||
(pixB << pVisual->offsetBlue);
|
||||
#ifdef COMPOSITE
|
||||
*pPix |= pVisual->alphaMask;
|
||||
#endif
|
||||
*pred = pmap->red[pixR].co.local.red;
|
||||
*pgreen = pmap->green[pixG].co.local.green;
|
||||
*pblue = pmap->blue[pixB].co.local.blue;
|
||||
|
@ -956,6 +967,9 @@ AllocColor (pmap, pred, pgreen, pblue, pPix, client)
|
|||
return (BadAlloc);
|
||||
}
|
||||
*pPix = pixR | pixG | pixB;
|
||||
#ifdef COMPOSITE
|
||||
*pPix |= pVisual->alphaMask;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1928,6 +1942,10 @@ AllocDirect (client, pmap, c, r, g, b, contig, pixels, prmask, pgmask, pbmask)
|
|||
}
|
||||
pmap->numPixelsBlue[client] += npixB;
|
||||
pmap->freeBlue -= npixB;
|
||||
#ifdef COMPOSITE
|
||||
for (pDst = pixels; pDst < pixels + c; pDst++)
|
||||
*pDst |= pmap->pVisual->alphaMask;
|
||||
#endif
|
||||
|
||||
DEALLOCATE_LOCAL(ppixBlue);
|
||||
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 $ */
|
||||
/*
|
||||
|
||||
|
@ -291,6 +291,9 @@ SetWindowToDefaults(register WindowPtr pWin)
|
|||
pWin->srcBuffer = DBE_FRONT_BUFFER;
|
||||
pWin->dstBuffer = DBE_FRONT_BUFFER;
|
||||
#endif
|
||||
#ifdef COMPOSITE
|
||||
pWin->redirectDraw = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1661,6 +1664,19 @@ void
|
|||
SetWinSize (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,
|
||||
pWin->drawable.x, pWin->drawable.y,
|
||||
(int)pWin->drawable.width,
|
||||
|
@ -1691,6 +1707,19 @@ SetBorderSize (pWin)
|
|||
|
||||
if (HasBorder (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,
|
||||
pWin->drawable.x - bw, pWin->drawable.y - bw,
|
||||
(int)(pWin->drawable.width + (bw<<1)),
|
||||
|
|
|
@ -79,6 +79,10 @@ typedef struct _Pixmap {
|
|||
#ifdef PIXPRIV
|
||||
DevUnion *devPrivates; /* real devPrivates like gcs & windows */
|
||||
#endif
|
||||
#ifdef COMPOSITE
|
||||
short screen_x;
|
||||
short screen_y;
|
||||
#endif
|
||||
} PixmapRec;
|
||||
|
||||
#endif /* PIXMAPSTRUCT_H */
|
||||
|
|
|
@ -75,6 +75,10 @@ typedef struct _Visual {
|
|||
* it may have more or fewer */
|
||||
unsigned long redMask, greenMask, blueMask;
|
||||
int offsetRed, offsetGreen, offsetBlue;
|
||||
#ifdef COMPOSITE
|
||||
unsigned long alphaMask;
|
||||
int offsetAlpha;
|
||||
#endif
|
||||
} VisualRec;
|
||||
|
||||
typedef struct _Depth {
|
||||
|
|
|
@ -135,6 +135,9 @@ typedef struct _Window {
|
|||
#define DBE_BACK_BUFFER 0
|
||||
unsigned dstBuffer:1; /* destination buffer for rendering */
|
||||
unsigned srcBuffer:1; /* source buffer for rendering */
|
||||
#endif
|
||||
#ifdef COMPOSITE
|
||||
unsigned redirectDraw:1; /* rendering is redirected from here */
|
||||
#endif
|
||||
DevUnion *devPrivates;
|
||||
} WindowRec;
|
||||
|
|
10
mi/mi.h
10
mi/mi.h
|
@ -495,6 +495,16 @@ extern int miShapedWindowIn(
|
|||
int /*y*/
|
||||
);
|
||||
|
||||
typedef void
|
||||
(*SetRedirectBorderClipProcPtr) (WindowPtr pWindow, RegionPtr pRegion);
|
||||
|
||||
typedef RegionPtr
|
||||
(*GetRedirectBorderClipProcPtr) (WindowPtr pWindow);
|
||||
|
||||
void
|
||||
miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
|
||||
GetRedirectBorderClipProcPtr getBorderClip);
|
||||
|
||||
extern int miValidateTree(
|
||||
WindowPtr /*pParent*/,
|
||||
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 $ */
|
||||
/***********************************************************
|
||||
|
||||
|
@ -282,6 +282,9 @@ extern void XFixesExtensionInit(INITARGS);
|
|||
#ifdef DAMAGE
|
||||
extern void DamageExtensionInit(INITARGS);
|
||||
#endif
|
||||
#ifdef COMPOSITE
|
||||
extern void CompositeExtensionInit(INITARGS);
|
||||
#endif
|
||||
|
||||
/* The following is only a small first step towards run-time
|
||||
* configurable extensions.
|
||||
|
@ -456,6 +459,10 @@ InitExtensions(argc, argv)
|
|||
DPSExtensionInit();
|
||||
#endif
|
||||
#endif
|
||||
#ifdef XFIXES
|
||||
/* must be before Render to layer DisplayCursor correctly */
|
||||
XFixesExtensionInit();
|
||||
#endif
|
||||
#ifdef RENDER
|
||||
if (!noRenderExtension) RenderExtensionInit();
|
||||
#endif
|
||||
|
@ -471,12 +478,12 @@ InitExtensions(argc, argv)
|
|||
#ifdef XEVIE
|
||||
if (!noXevieExtension) XevieExtensionInit();
|
||||
#endif
|
||||
#ifdef XFIXES
|
||||
XFixesExtensionInit();
|
||||
#endif
|
||||
#ifdef DAMAGE
|
||||
DamageExtensionInit();
|
||||
#endif
|
||||
#ifdef COMPOSITE
|
||||
CompositeExtensionInit ();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -590,6 +597,10 @@ static ExtensionModule staticExtensions[] = {
|
|||
#ifdef PANORAMIX
|
||||
{ PanoramiXExtensionInit, PANORAMIX_PROTOCOL_NAME, &noPanoramiXExtension, NULL, NULL },
|
||||
#endif
|
||||
#ifdef XFIXES
|
||||
/* must be before Render to layer DisplayCursor correctly */
|
||||
{ XFixesExtensionInit, "XFIXES", NULL, NULL, NULL },
|
||||
#endif
|
||||
#ifdef XF86BIGFONT
|
||||
{ XFree86BigfontExtensionInit, XF86BIGFONTNAME, NULL, NULL, NULL },
|
||||
#endif
|
||||
|
@ -602,8 +613,8 @@ static ExtensionModule staticExtensions[] = {
|
|||
#ifdef DAMAGE
|
||||
{ DamageExtensionInit, "DAMAGE", NULL, NULL },
|
||||
#endif
|
||||
#ifdef XFIXES
|
||||
{ XFixesExtensionInit, "XFIXES", NULL, NULL },
|
||||
#ifdef COMPOSITE
|
||||
{ CompositeExtensionInit, "COMPOSITE", NULL, NULL },
|
||||
#endif
|
||||
#ifdef XEVIE
|
||||
{ XevieExtensionInit, "XEVIE", &noXevieExtension, NULL },
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $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 --
|
||||
* Functions for recalculating window clip lists. Main function
|
||||
|
@ -167,6 +167,17 @@ miShapedWindowIn (pScreen, universe, bounding, rect, x, y)
|
|||
}
|
||||
#endif
|
||||
|
||||
static GetRedirectBorderClipProcPtr miGetRedirectBorderClipProc;
|
||||
static SetRedirectBorderClipProcPtr miSetRedirectBorderClipProc;
|
||||
|
||||
void
|
||||
miRegisterRedirectBorderClipProc (SetRedirectBorderClipProcPtr setBorderClip,
|
||||
GetRedirectBorderClipProcPtr getBorderClip)
|
||||
{
|
||||
miSetRedirectBorderClipProc = setBorderClip;
|
||||
miGetRedirectBorderClipProc = getBorderClip;
|
||||
}
|
||||
|
||||
#define HasParentRelativeBorder(w) (!(w)->borderIsPixel && \
|
||||
HasBorder(w) && \
|
||||
(w)->backgroundState == ParentRelative)
|
||||
|
@ -264,6 +275,18 @@ miComputeClips (
|
|||
((pParent->eventMask | wOtherEventMasks(pParent)) & VisibilityChangeMask))
|
||||
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;
|
||||
dy = pParent->drawable.y - pParent->valdata->before.oldAbsCorner.y;
|
||||
|
||||
|
@ -640,7 +663,12 @@ miValidateTree (pParent, pChild, kind)
|
|||
{
|
||||
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)
|
||||
viewvals++;
|
||||
}
|
||||
|
@ -654,7 +682,12 @@ miValidateTree (pParent, pChild, kind)
|
|||
{
|
||||
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)
|
||||
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