New upstream version 3.5.99.27
This commit is contained in:
0
nx-X11/programs/Xserver/composite/.gitignore
vendored
Normal file
0
nx-X11/programs/Xserver/composite/.gitignore
vendored
Normal file
29
nx-X11/programs/Xserver/composite/Imakefile
Normal file
29
nx-X11/programs/Xserver/composite/Imakefile
Normal file
@@ -0,0 +1,29 @@
|
||||
#include <Server.tmpl>
|
||||
|
||||
NULL =
|
||||
|
||||
SRCS = compalloc.c compext.c compinit.c compoverlay.c compwindow.c
|
||||
|
||||
OBJS = compalloc.o compext.o compinit.o compoverlay.o compwindow.o
|
||||
|
||||
INCLUDES = -I../include -I../mi -I../Xext -I../render -I../xfixes \
|
||||
-I../damageext -I../miext/damage -I$(EXTINCSRC) \
|
||||
-I$(XINCLUDESRC) \
|
||||
`pkg-config --cflags-only-I pixman-1`
|
||||
|
||||
LINTLIBS = ../dix/llib-ldix.ln ../os/llib-los.ln
|
||||
|
||||
#if defined(NXAgentServer) && NXAgentServer
|
||||
NX_DEFINES = -DNXAGENT_SERVER
|
||||
#endif
|
||||
|
||||
DEFINES = \
|
||||
$(NX_DEFINES) \
|
||||
$(NULL)
|
||||
|
||||
NormalLibraryTarget(composite,$(OBJS))
|
||||
NormalLibraryObjectRule()
|
||||
LintLibraryTarget(composite,$(SRCS))
|
||||
NormalLintTarget($(SRCS))
|
||||
|
||||
DependTarget()
|
||||
710
nx-X11/programs/Xserver/composite/compalloc.c
Normal file
710
nx-X11/programs/Xserver/composite/compalloc.c
Normal file
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
* $Id: compalloc.c,v 1.7 2005/07/03 07:37:34 daniels Exp $
|
||||
*
|
||||
* Copyright © 2003 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "compint.h"
|
||||
|
||||
static void
|
||||
compScreenUpdate(ScreenPtr pScreen)
|
||||
{
|
||||
compCheckTree(pScreen);
|
||||
compPaintChildrenToWindow(pScreen, pScreen->root);
|
||||
}
|
||||
|
||||
static void
|
||||
compBlockHandler(int i, void *blockData, void *pTimeout, void *pReadmask)
|
||||
{
|
||||
ScreenPtr pScreen = screenInfo.screens[i];
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
|
||||
pScreen->BlockHandler = cs->BlockHandler;
|
||||
compScreenUpdate(pScreen);
|
||||
(*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
|
||||
|
||||
/* Next damage will restore the block handler */
|
||||
cs->BlockHandler = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
compReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure)
|
||||
{
|
||||
WindowPtr pWin = (WindowPtr) closure;
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
CompWindowPtr cw = GetCompWindow(pWin);
|
||||
|
||||
if (!cs->BlockHandler) {
|
||||
cs->BlockHandler = pScreen->BlockHandler;
|
||||
pScreen->BlockHandler = compBlockHandler;
|
||||
}
|
||||
cs->damaged = TRUE;
|
||||
cw->damaged = TRUE;
|
||||
|
||||
/* Mark the ancestors */
|
||||
/* We can't do this, Dave. No damagedDescendants support. */
|
||||
/*
|
||||
pWin = pWin->parent;
|
||||
while (pWin) {
|
||||
if (pWin->damagedDescendants)
|
||||
break;
|
||||
pWin->damagedDescendants = TRUE;
|
||||
pWin = pWin->parent;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
compDestroyDamage(DamagePtr pDamage, void *closure)
|
||||
{
|
||||
WindowPtr pWin = (WindowPtr) closure;
|
||||
CompWindowPtr cw = GetCompWindow(pWin);
|
||||
|
||||
cw->damage = 0;
|
||||
}
|
||||
|
||||
static Bool
|
||||
compMarkWindows(WindowPtr pWin, WindowPtr *ppLayerWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
WindowPtr pLayerWin = pWin;
|
||||
|
||||
if (!pWin->viewable)
|
||||
return FALSE;
|
||||
|
||||
(*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);
|
||||
(*pScreen->MarkWindow) (pLayerWin->parent);
|
||||
|
||||
*ppLayerWin = pLayerWin;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
compHandleMarkedWindows(WindowPtr pWin, WindowPtr pLayerWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
|
||||
(*pScreen->ValidateTree) (pLayerWin->parent, pLayerWin, VTOther);
|
||||
(*pScreen->HandleExposures) (pLayerWin->parent);
|
||||
if (pScreen->PostValidateTree)
|
||||
(*pScreen->PostValidateTree) (pLayerWin->parent, pLayerWin, VTOther);
|
||||
}
|
||||
|
||||
/*
|
||||
* Redirect one window for one client
|
||||
*/
|
||||
int
|
||||
compRedirectWindow(ClientPtr pClient, WindowPtr pWin, int update)
|
||||
{
|
||||
CompWindowPtr cw = GetCompWindow(pWin);
|
||||
CompClientWindowPtr ccw;
|
||||
CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
|
||||
WindowPtr pLayerWin;
|
||||
Bool anyMarked = FALSE;
|
||||
|
||||
if (pWin == cs->pOverlayWin) {
|
||||
return Success;
|
||||
}
|
||||
|
||||
if (!pWin->parent)
|
||||
return BadMatch;
|
||||
|
||||
/*
|
||||
* Only one Manual update is allowed
|
||||
*/
|
||||
if (cw && update == CompositeRedirectManual)
|
||||
for (ccw = cw->clients; ccw; ccw = ccw->next)
|
||||
if (ccw->update == CompositeRedirectManual)
|
||||
return BadAccess;
|
||||
|
||||
/*
|
||||
* Allocate per-client per-window structure
|
||||
* The client *could* allocate multiple, but while supported,
|
||||
* it is not expected to be common
|
||||
*/
|
||||
ccw = malloc (sizeof (CompClientWindowRec));
|
||||
if (!ccw)
|
||||
return BadAlloc;
|
||||
ccw->id = FakeClientID (pClient->index);
|
||||
ccw->update = update;
|
||||
/*
|
||||
* Now make sure there's a per-window structure to hang this from
|
||||
*/
|
||||
if (!cw)
|
||||
{
|
||||
cw = malloc (sizeof (CompWindowRec));
|
||||
if (!cw)
|
||||
{
|
||||
free (ccw);
|
||||
return BadAlloc;
|
||||
}
|
||||
cw->damage = DamageCreate (compReportDamage,
|
||||
compDestroyDamage,
|
||||
DamageReportNonEmpty,
|
||||
FALSE,
|
||||
pWin->drawable.pScreen,
|
||||
pWin);
|
||||
if (!cw->damage)
|
||||
{
|
||||
free (ccw);
|
||||
free (cw);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
anyMarked = compMarkWindows(pWin, &pLayerWin);
|
||||
|
||||
RegionNull(&cw->borderClip);
|
||||
cw->update = CompositeRedirectAutomatic;
|
||||
cw->clients = 0;
|
||||
cw->oldx = COMP_ORIGIN_INVALID;
|
||||
cw->oldy = COMP_ORIGIN_INVALID;
|
||||
cw->damageRegistered = FALSE;
|
||||
cw->damaged = FALSE;
|
||||
cw->pOldPixmap = NullPixmap;
|
||||
FAKE_DIX_SET_WINDOW_PRIVATE(pWin, cw);
|
||||
}
|
||||
ccw->next = cw->clients;
|
||||
cw->clients = ccw;
|
||||
if (!AddResource (ccw->id, CompositeClientWindowType, pWin))
|
||||
return BadAlloc;
|
||||
if (ccw->update == CompositeRedirectManual)
|
||||
{
|
||||
if (!anyMarked)
|
||||
anyMarked = compMarkWindows(pWin, &pLayerWin);
|
||||
|
||||
if (cw->damageRegistered) {
|
||||
DamageUnregister (&pWin->drawable, cw->damage);
|
||||
cw->damageRegistered = FALSE;
|
||||
}
|
||||
cw->update = CompositeRedirectManual;
|
||||
}
|
||||
else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered) {
|
||||
if (!anyMarked)
|
||||
anyMarked = compMarkWindows(pWin, &pLayerWin);
|
||||
}
|
||||
|
||||
if (!compCheckRedirect (pWin))
|
||||
{
|
||||
FreeResource (ccw->id, RT_NONE);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
if (anyMarked)
|
||||
compHandleMarkedWindows(pWin, pLayerWin);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
void
|
||||
compRestoreWindow(WindowPtr pWin, PixmapPtr pPixmap)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
WindowPtr pParent = pWin->parent;
|
||||
|
||||
if (pParent->drawable.depth == pWin->drawable.depth) {
|
||||
GCPtr pGC = GetScratchGC(pWin->drawable.depth, pScreen);
|
||||
int bw = (int) pWin->borderWidth;
|
||||
int x = bw;
|
||||
int y = bw;
|
||||
int w = pWin->drawable.width;
|
||||
int h = pWin->drawable.height;
|
||||
|
||||
if (pGC) {
|
||||
ChangeGCVal val;
|
||||
|
||||
val.val = IncludeInferiors;
|
||||
dixChangeGC(NullClient, pGC, GCSubwindowMode, NULL, &val);
|
||||
ValidateGC(&pWin->drawable, pGC);
|
||||
(*pGC->ops->CopyArea) (&pPixmap->drawable,
|
||||
&pWin->drawable, pGC, x, y, w, h, 0, 0);
|
||||
FreeScratchGC(pGC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free one of the per-client per-window resources, clearing
|
||||
* redirect and the per-window pointer as appropriate
|
||||
*/
|
||||
void
|
||||
compFreeClientWindow (WindowPtr pWin, XID id)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
CompClientWindowPtr ccw, *prev;
|
||||
Bool anyMarked = FALSE;
|
||||
WindowPtr pLayerWin;
|
||||
PixmapPtr pPixmap = NULL;
|
||||
|
||||
if (!cw)
|
||||
return;
|
||||
for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next)
|
||||
{
|
||||
if (ccw->id == id)
|
||||
{
|
||||
*prev = ccw->next;
|
||||
if (ccw->update == CompositeRedirectManual)
|
||||
cw->update = CompositeRedirectAutomatic;
|
||||
free (ccw);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cw->clients)
|
||||
{
|
||||
anyMarked = compMarkWindows(pWin, &pLayerWin);
|
||||
|
||||
if (pWin->redirectDraw != RedirectDrawNone) {
|
||||
pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||
compSetParentPixmap(pWin);
|
||||
}
|
||||
|
||||
if (cw->damage)
|
||||
DamageDestroy (cw->damage);
|
||||
|
||||
RegionUninit(&cw->borderClip);
|
||||
|
||||
FAKE_DIX_SET_WINDOW_PRIVATE(pWin, NULL);
|
||||
free (cw);
|
||||
}
|
||||
else if (cw->update == CompositeRedirectAutomatic &&
|
||||
!cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
anyMarked = compMarkWindows(pWin, &pLayerWin);
|
||||
|
||||
DamageRegister (&pWin->drawable, cw->damage);
|
||||
cw->damageRegistered = TRUE;
|
||||
pWin->redirectDraw = RedirectDrawAutomatic;
|
||||
DamageDamageRegion (&pWin->drawable, &pWin->borderSize);
|
||||
}
|
||||
|
||||
if (anyMarked)
|
||||
compHandleMarkedWindows(pWin, pLayerWin);
|
||||
|
||||
if (pPixmap) {
|
||||
compRestoreWindow(pWin, pPixmap);
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is easy, just free the appropriate resource.
|
||||
*/
|
||||
|
||||
int
|
||||
compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
|
||||
{
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
CompClientWindowPtr ccw;
|
||||
|
||||
if (!cw)
|
||||
return BadValue;
|
||||
|
||||
for (ccw = cw->clients; ccw; ccw = ccw->next)
|
||||
if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index)
|
||||
{
|
||||
FreeResource (ccw->id, RT_NONE);
|
||||
return Success;
|
||||
}
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Redirect all subwindows for one client
|
||||
*/
|
||||
|
||||
int
|
||||
compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
|
||||
{
|
||||
CompSubwindowsPtr csw = GetCompSubwindows (pWin);
|
||||
CompClientWindowPtr ccw;
|
||||
WindowPtr pChild;
|
||||
|
||||
/*
|
||||
* Only one Manual update is allowed
|
||||
*/
|
||||
if (csw && update == CompositeRedirectManual)
|
||||
for (ccw = csw->clients; ccw; ccw = ccw->next)
|
||||
if (ccw->update == CompositeRedirectManual)
|
||||
return BadAccess;
|
||||
/*
|
||||
* Allocate per-client per-window structure
|
||||
* The client *could* allocate multiple, but while supported,
|
||||
* it is not expected to be common
|
||||
*/
|
||||
ccw = malloc (sizeof (CompClientWindowRec));
|
||||
if (!ccw)
|
||||
return BadAlloc;
|
||||
ccw->id = FakeClientID (pClient->index);
|
||||
ccw->update = update;
|
||||
/*
|
||||
* Now make sure there's a per-window structure to hang this from
|
||||
*/
|
||||
if (!csw)
|
||||
{
|
||||
csw = malloc (sizeof (CompSubwindowsRec));
|
||||
if (!csw)
|
||||
{
|
||||
free (ccw);
|
||||
return BadAlloc;
|
||||
}
|
||||
csw->update = CompositeRedirectAutomatic;
|
||||
csw->clients = 0;
|
||||
FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, csw);
|
||||
}
|
||||
/*
|
||||
* Redirect all existing windows
|
||||
*/
|
||||
for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
|
||||
{
|
||||
int ret = compRedirectWindow (pClient, pChild, update);
|
||||
if (ret != Success)
|
||||
{
|
||||
for (pChild = pChild->nextSib; pChild; pChild = pChild->nextSib)
|
||||
(void) compUnredirectWindow (pClient, pChild, update);
|
||||
if (!csw->clients)
|
||||
{
|
||||
free (csw);
|
||||
FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, NULL);
|
||||
}
|
||||
free (ccw);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Hook into subwindows list
|
||||
*/
|
||||
ccw->next = csw->clients;
|
||||
csw->clients = ccw;
|
||||
if (!AddResource (ccw->id, CompositeClientSubwindowsType, pWin))
|
||||
return BadAlloc;
|
||||
if (ccw->update == CompositeRedirectManual)
|
||||
{
|
||||
csw->update = CompositeRedirectManual;
|
||||
/*
|
||||
* tell damage extension that damage events for this client are
|
||||
* critical output
|
||||
*/
|
||||
DamageExtSetCritical (pClient, TRUE);
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free one of the per-client per-subwindows resources,
|
||||
* which frees one redirect per subwindow
|
||||
*/
|
||||
void
|
||||
compFreeClientSubwindows (WindowPtr pWin, XID id)
|
||||
{
|
||||
CompSubwindowsPtr csw = GetCompSubwindows (pWin);
|
||||
CompClientWindowPtr ccw, *prev;
|
||||
WindowPtr pChild;
|
||||
|
||||
if (!csw)
|
||||
return;
|
||||
for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next)
|
||||
{
|
||||
if (ccw->id == id)
|
||||
{
|
||||
ClientPtr pClient = clients[CLIENT_ID(id)];
|
||||
|
||||
*prev = ccw->next;
|
||||
if (ccw->update == CompositeRedirectManual)
|
||||
{
|
||||
/*
|
||||
* tell damage extension that damage events for this client are
|
||||
* critical output
|
||||
*/
|
||||
DamageExtSetCritical (pClient, FALSE);
|
||||
csw->update = CompositeRedirectAutomatic;
|
||||
if (pWin->mapped)
|
||||
(*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unredirect all existing subwindows
|
||||
*/
|
||||
for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
|
||||
(void) compUnredirectWindow (pClient, pChild, ccw->update);
|
||||
|
||||
free (ccw);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if all of the per-client records are gone
|
||||
*/
|
||||
if (!csw->clients)
|
||||
{
|
||||
FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, NULL);
|
||||
free (csw);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is easy, just free the appropriate resource.
|
||||
*/
|
||||
|
||||
int
|
||||
compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
|
||||
{
|
||||
CompSubwindowsPtr csw = GetCompSubwindows (pWin);
|
||||
CompClientWindowPtr ccw;
|
||||
|
||||
if (!csw)
|
||||
return BadValue;
|
||||
for (ccw = csw->clients; ccw; ccw = ccw->next)
|
||||
if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index)
|
||||
{
|
||||
FreeResource (ccw->id, RT_NONE);
|
||||
return Success;
|
||||
}
|
||||
return BadValue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add redirection information for one subwindow (during reparent)
|
||||
*/
|
||||
|
||||
int
|
||||
compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
|
||||
{
|
||||
CompSubwindowsPtr csw = GetCompSubwindows (pParent);
|
||||
CompClientWindowPtr ccw;
|
||||
|
||||
if (!csw)
|
||||
return Success;
|
||||
for (ccw = csw->clients; ccw; ccw = ccw->next)
|
||||
{
|
||||
int ret = compRedirectWindow (clients[CLIENT_ID(ccw->id)],
|
||||
pWin, ccw->update);
|
||||
if (ret != Success)
|
||||
return ret;
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove redirection information for one subwindow (during reparent)
|
||||
*/
|
||||
|
||||
int
|
||||
compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
|
||||
{
|
||||
CompSubwindowsPtr csw = GetCompSubwindows (pParent);
|
||||
CompClientWindowPtr ccw;
|
||||
|
||||
if (!csw)
|
||||
return Success;
|
||||
for (ccw = csw->clients; ccw; ccw = ccw->next)
|
||||
{
|
||||
int ret = compUnredirectWindow (clients[CLIENT_ID(ccw->id)],
|
||||
pWin, ccw->update);
|
||||
if (ret != Success)
|
||||
return ret;
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
||||
static PixmapPtr
|
||||
compNewPixmap (WindowPtr pWin, int x, int y, int w, int h)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
WindowPtr pParent = pWin->parent;
|
||||
PixmapPtr pPixmap;
|
||||
|
||||
/* usage_hint unsupported by our old server infrastructure. */
|
||||
pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth,
|
||||
CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
|
||||
|
||||
if (!pPixmap)
|
||||
return 0;
|
||||
|
||||
pPixmap->screen_x = x;
|
||||
pPixmap->screen_y = y;
|
||||
|
||||
if (pParent->drawable.depth == pWin->drawable.depth) {
|
||||
GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen);
|
||||
|
||||
/*
|
||||
* Copy bits from the parent into the new pixmap so that it will
|
||||
* have "reasonable" contents in case for background None areas.
|
||||
*/
|
||||
if (pGC)
|
||||
{
|
||||
ChangeGCVal val;
|
||||
|
||||
val.val = IncludeInferiors;
|
||||
dixChangeGC(NullClient, pGC, GCSubwindowMode, NULL, &val);
|
||||
ValidateGC(&pPixmap->drawable, pGC);
|
||||
(*pGC->ops->CopyArea) (&pParent->drawable,
|
||||
&pPixmap->drawable,
|
||||
pGC,
|
||||
x - pParent->drawable.x,
|
||||
y - pParent->drawable.y,
|
||||
w, h, 0, 0);
|
||||
FreeScratchGC (pGC);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PictFormatPtr pSrcFormat = compWindowFormat (pParent);
|
||||
PictFormatPtr pDstFormat = compWindowFormat (pWin);
|
||||
XID inferiors = IncludeInferiors;
|
||||
int error;
|
||||
|
||||
PicturePtr pSrcPicture = CreatePicture(None,
|
||||
&pParent->drawable,
|
||||
pSrcFormat,
|
||||
CPSubwindowMode,
|
||||
&inferiors,
|
||||
serverClient, &error);
|
||||
|
||||
PicturePtr pDstPicture = CreatePicture(None,
|
||||
&pPixmap->drawable,
|
||||
pDstFormat,
|
||||
0, 0,
|
||||
serverClient, &error);
|
||||
|
||||
if (pSrcPicture && pDstPicture) {
|
||||
CompositePicture(PictOpSrc,
|
||||
pSrcPicture,
|
||||
NULL,
|
||||
pDstPicture,
|
||||
x - pParent->drawable.x,
|
||||
y - pParent->drawable.y, 0, 0, 0, 0, w, h);
|
||||
}
|
||||
if (pSrcPicture)
|
||||
FreePicture(pSrcPicture, 0);
|
||||
if (pDstPicture)
|
||||
FreePicture(pDstPicture, 0);
|
||||
}
|
||||
return pPixmap;
|
||||
}
|
||||
|
||||
Bool
|
||||
compAllocPixmap (WindowPtr pWin)
|
||||
{
|
||||
int bw = (int) pWin->borderWidth;
|
||||
int x = pWin->drawable.x - bw;
|
||||
int y = pWin->drawable.y - bw;
|
||||
int w = pWin->drawable.width + (bw << 1);
|
||||
int h = pWin->drawable.height + (bw << 1);
|
||||
PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h);
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
|
||||
if (!pPixmap)
|
||||
return FALSE;
|
||||
if (cw->update == CompositeRedirectAutomatic)
|
||||
pWin->redirectDraw = RedirectDrawAutomatic;
|
||||
else
|
||||
pWin->redirectDraw = RedirectDrawManual;
|
||||
|
||||
compSetPixmap (pWin, pPixmap);
|
||||
cw->oldx = COMP_ORIGIN_INVALID;
|
||||
cw->oldy = COMP_ORIGIN_INVALID;
|
||||
cw->damageRegistered = FALSE;
|
||||
if (cw->update == CompositeRedirectAutomatic)
|
||||
{
|
||||
DamageRegister (&pWin->drawable, cw->damage);
|
||||
cw->damageRegistered = TRUE;
|
||||
}
|
||||
|
||||
/* Make sure our borderClip is up to date */
|
||||
RegionUninit(&cw->borderClip);
|
||||
RegionCopy(&cw->borderClip, &pWin->borderClip);
|
||||
cw->borderClipX = pWin->drawable.x;
|
||||
cw->borderClipY = pWin->drawable.y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
compSetParentPixmap (WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
PixmapPtr pParentPixmap;
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
|
||||
if (cw->damageRegistered)
|
||||
{
|
||||
DamageUnregister (&pWin->drawable, cw->damage);
|
||||
cw->damageRegistered = FALSE;
|
||||
DamageEmpty (cw->damage);
|
||||
}
|
||||
/*
|
||||
* Move the parent-constrained border clip region back into
|
||||
* the window so that ValidateTree will handle the unmap
|
||||
* case correctly. Unmap adds the window borderClip to the
|
||||
* parent exposed area; regions beyond the parent cause crashes
|
||||
*/
|
||||
RegionCopy(&pWin->borderClip, &cw->borderClip);
|
||||
pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
|
||||
pWin->redirectDraw = RedirectDrawNone;
|
||||
compSetPixmap (pWin, pParentPixmap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the pixmap is the right size and offset. Allocate a new
|
||||
* pixmap to change size, adjust origin to change offset, leaving the
|
||||
* old pixmap in cw->pOldPixmap so bits can be recovered
|
||||
*/
|
||||
Bool
|
||||
compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y,
|
||||
unsigned int w, unsigned int h, int bw)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
PixmapPtr pOld = (*pScreen->GetWindowPixmap) (pWin);
|
||||
PixmapPtr pNew;
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
int pix_x, pix_y;
|
||||
int pix_w, pix_h;
|
||||
|
||||
assert (cw && pWin->redirectDraw != RedirectDrawNone);
|
||||
cw->oldx = pOld->screen_x;
|
||||
cw->oldy = pOld->screen_y;
|
||||
pix_x = draw_x - bw;
|
||||
pix_y = draw_y - bw;
|
||||
pix_w = w + (bw << 1);
|
||||
pix_h = h + (bw << 1);
|
||||
if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height)
|
||||
{
|
||||
pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h);
|
||||
if (!pNew)
|
||||
return FALSE;
|
||||
cw->pOldPixmap = pOld;
|
||||
compSetPixmap (pWin, pNew);
|
||||
}
|
||||
else
|
||||
{
|
||||
pNew = pOld;
|
||||
cw->pOldPixmap = 0;
|
||||
}
|
||||
pNew->screen_x = pix_x;
|
||||
pNew->screen_y = pix_y;
|
||||
return TRUE;
|
||||
}
|
||||
1069
nx-X11/programs/Xserver/composite/compext.c
Normal file
1069
nx-X11/programs/Xserver/composite/compext.c
Normal file
File diff suppressed because it is too large
Load Diff
492
nx-X11/programs/Xserver/composite/compinit.c
Normal file
492
nx-X11/programs/Xserver/composite/compinit.c
Normal file
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
* $Id: compinit.c,v 1.9 2005/07/03 07:37:34 daniels Exp $
|
||||
*
|
||||
* Copyright © 2003 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "compint.h"
|
||||
#include "compositeext.h"
|
||||
|
||||
#ifndef NXAGENT_SERVER
|
||||
DevPrivateKeyRec CompScreenPrivateKeyRec;
|
||||
DevPrivateKeyRec CompWindowPrivateKeyRec;
|
||||
DevPrivateKeyRec CompSubwindowsPrivateKeyRec;
|
||||
#else /* !defined(NXAGENT_SERVER) */
|
||||
int CompScreenPrivIndex = -1;
|
||||
int CompWindowPrivIndex = -1;
|
||||
int CompSubwindowsPrivIndex = -1;
|
||||
#endif
|
||||
|
||||
static Bool
|
||||
compCloseScreen (ScreenPtr pScreen)
|
||||
{
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
Bool ret;
|
||||
|
||||
free(cs->alternateVisuals);
|
||||
|
||||
pScreen->CloseScreen = cs->CloseScreen;
|
||||
pScreen->InstallColormap = cs->InstallColormap;
|
||||
pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
|
||||
pScreen->ReparentWindow = cs->ReparentWindow;
|
||||
|
||||
/*
|
||||
* Unsupported by our old Xserver infrastructure, replaced with direct calls to
|
||||
* compReallocPixmap().
|
||||
*/
|
||||
/*
|
||||
pScreen->ConfigNotify = cs->ConfigNotify;
|
||||
*/
|
||||
|
||||
pScreen->MoveWindow = cs->MoveWindow;
|
||||
pScreen->ResizeWindow = cs->ResizeWindow;
|
||||
pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
|
||||
|
||||
pScreen->ClipNotify = cs->ClipNotify;
|
||||
pScreen->UnrealizeWindow = cs->UnrealizeWindow;
|
||||
pScreen->RealizeWindow = cs->RealizeWindow;
|
||||
pScreen->DestroyWindow = cs->DestroyWindow;
|
||||
pScreen->CreateWindow = cs->CreateWindow;
|
||||
pScreen->CopyWindow = cs->CopyWindow;
|
||||
pScreen->PositionWindow = cs->PositionWindow;
|
||||
|
||||
pScreen->GetImage = cs->GetImage;
|
||||
pScreen->GetSpans = cs->GetSpans;
|
||||
pScreen->SourceValidate = cs->SourceValidate;
|
||||
|
||||
free (cs);
|
||||
FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, NULL);
|
||||
ret = (*pScreen->CloseScreen) (pScreen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
compInstallColormap (ColormapPtr pColormap)
|
||||
{
|
||||
VisualPtr pVisual = pColormap->pVisual;
|
||||
ScreenPtr pScreen = pColormap->pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
int a;
|
||||
|
||||
for (a = 0; a < cs->numAlternateVisuals; a++)
|
||||
if (pVisual->vid == cs->alternateVisuals[a])
|
||||
return;
|
||||
pScreen->InstallColormap = cs->InstallColormap;
|
||||
(*pScreen->InstallColormap) (pColormap);
|
||||
cs->InstallColormap = pScreen->InstallColormap;
|
||||
pScreen->InstallColormap = compInstallColormap;
|
||||
}
|
||||
|
||||
/* Unsupported by current architecture, drop for now. */
|
||||
#if 0
|
||||
static void
|
||||
compCheckBackingStore(WindowPtr pWin)
|
||||
{
|
||||
if (pWin->backingStore != NotUseful && !pWin->backStorage) {
|
||||
compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
|
||||
pWin->backStorage = TRUE;
|
||||
}
|
||||
else if (pWin->backingStore == NotUseful && pWin->backStorage) {
|
||||
compUnredirectWindow(serverClient, pWin,
|
||||
CompositeRedirectAutomatic);
|
||||
pWin->backStorage = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fake backing store via automatic redirection */
|
||||
static Bool
|
||||
compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
Bool ret;
|
||||
|
||||
pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
|
||||
ret = pScreen->ChangeWindowAttributes(pWin, mask);
|
||||
|
||||
if (ret && (mask & CWBackingStore) &&
|
||||
pScreen->backingStoreSupport != NotUseful)
|
||||
compCheckBackingStore(pWin);
|
||||
|
||||
pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
static void
|
||||
compGetImage(DrawablePtr pDrawable,
|
||||
int sx, int sy,
|
||||
int w, int h,
|
||||
unsigned int format, unsigned long planemask, char *pdstLine)
|
||||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
|
||||
pScreen->GetImage = cs->GetImage;
|
||||
if (pDrawable->type == DRAWABLE_WINDOW)
|
||||
compPaintChildrenToWindow(pScreen, (WindowPtr) pDrawable);
|
||||
(*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine);
|
||||
cs->GetImage = pScreen->GetImage;
|
||||
pScreen->GetImage = compGetImage;
|
||||
}
|
||||
|
||||
static void
|
||||
compGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth,
|
||||
int nspans, char *pdstStart)
|
||||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
|
||||
pScreen->GetSpans = cs->GetSpans;
|
||||
if (pDrawable->type == DRAWABLE_WINDOW)
|
||||
compPaintChildrenToWindow(pScreen, (WindowPtr) pDrawable);
|
||||
(*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
|
||||
cs->GetSpans = pScreen->GetSpans;
|
||||
pScreen->GetSpans = compGetSpans;
|
||||
}
|
||||
|
||||
static void
|
||||
compSourceValidate(DrawablePtr pDrawable,
|
||||
int x, int y,
|
||||
int width, int height /* , unsigned int subWindowMode */ /* unsupported */)
|
||||
{
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
|
||||
pScreen->SourceValidate = cs->SourceValidate;
|
||||
if (pDrawable->type == DRAWABLE_WINDOW /* && subWindowMode == IncludeInferiors */ /* unsupported */)
|
||||
compPaintChildrenToWindow(pScreen, (WindowPtr) pDrawable);
|
||||
if (pScreen->SourceValidate)
|
||||
(*pScreen->SourceValidate) (pDrawable, x, y, width, height /*,
|
||||
subWindowMode */ /* unsupported */);
|
||||
cs->SourceValidate = pScreen->SourceValidate;
|
||||
pScreen->SourceValidate = compSourceValidate;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add alternate visuals -- always expose an ARGB32 and RGB24 visual
|
||||
*/
|
||||
|
||||
static DepthPtr
|
||||
compFindVisuallessDepth (ScreenPtr pScreen, int d)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pScreen->numDepths; i++)
|
||||
{
|
||||
DepthPtr depth = &pScreen->allowedDepths[i];
|
||||
if (depth->depth == d)
|
||||
{
|
||||
/*
|
||||
* Make sure it doesn't have visuals already
|
||||
*/
|
||||
if (depth->numVids)
|
||||
return 0;
|
||||
/*
|
||||
* looks fine
|
||||
*/
|
||||
return depth;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If there isn't one, then it's gonna be hard to have
|
||||
* an associated visual
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a list of visual IDs to the list of visuals to implicitly redirect.
|
||||
*/
|
||||
static Bool
|
||||
compRegisterAlternateVisuals(CompScreenPtr cs, VisualID * vids, int nVisuals)
|
||||
{
|
||||
VisualID *p;
|
||||
|
||||
p = reallocarray(cs->alternateVisuals,
|
||||
cs->numAlternateVisuals + nVisuals, sizeof(VisualID));
|
||||
if (p == NULL)
|
||||
return FALSE;
|
||||
|
||||
memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals);
|
||||
|
||||
cs->alternateVisuals = p;
|
||||
cs->numAlternateVisuals += nVisuals;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool
|
||||
CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids,
|
||||
int nVisuals)
|
||||
{
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
|
||||
return compRegisterAlternateVisuals(cs, vids, nVisuals);
|
||||
}
|
||||
|
||||
Bool
|
||||
CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
|
||||
VisualID parentVisual,
|
||||
VisualID winVisual)
|
||||
{
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
CompImplicitRedirectException *p;
|
||||
|
||||
p = reallocarray(cs->implicitRedirectExceptions,
|
||||
cs->numImplicitRedirectExceptions + 1, sizeof(p[0]));
|
||||
if (p == NULL)
|
||||
return FALSE;
|
||||
|
||||
p[cs->numImplicitRedirectExceptions].parentVisual = parentVisual;
|
||||
p[cs->numImplicitRedirectExceptions].winVisual = winVisual;
|
||||
|
||||
cs->implicitRedirectExceptions = p;
|
||||
cs->numImplicitRedirectExceptions++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct _alternateVisual {
|
||||
int depth;
|
||||
CARD32 format;
|
||||
} CompAlternateVisual;
|
||||
|
||||
static CompAlternateVisual altVisuals[] = {
|
||||
#if COMP_INCLUDE_RGB24_VISUAL
|
||||
{ 24, PICT_r8g8b8 },
|
||||
#endif
|
||||
{ 32, PICT_a8r8g8b8 },
|
||||
};
|
||||
|
||||
static const int NUM_COMP_ALTERNATE_VISUALS = sizeof(altVisuals) /
|
||||
sizeof(CompAlternateVisual);
|
||||
|
||||
static Bool
|
||||
compAddAlternateVisual (ScreenPtr pScreen, CompScreenPtr cs,
|
||||
CompAlternateVisual * alt)
|
||||
{
|
||||
VisualPtr visual;
|
||||
DepthPtr depth;
|
||||
PictFormatPtr pPictFormat;
|
||||
unsigned long alphaMask;
|
||||
|
||||
/*
|
||||
* The ARGB32 visual is always available. Other alternate depth visuals
|
||||
* are only provided if their depth is less than the root window depth.
|
||||
* There's no deep reason for this.
|
||||
*/
|
||||
if (alt->depth >= pScreen->rootDepth && alt->depth != 32)
|
||||
return FALSE;
|
||||
|
||||
depth = compFindVisuallessDepth(pScreen, alt->depth);
|
||||
if (!depth)
|
||||
/* alt->depth doesn't exist or already has alternate visuals. */
|
||||
return TRUE;
|
||||
|
||||
pPictFormat = PictureMatchFormat(pScreen, alt->depth, alt->format);
|
||||
if (!pPictFormat)
|
||||
return FALSE;
|
||||
|
||||
if (ResizeVisualArray(pScreen, 1, depth) == FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
visual = pScreen->visuals + (pScreen->numVisuals - 1); /* the new one */
|
||||
|
||||
/* Initialize the visual */
|
||||
visual->bitsPerRGBValue = 8;
|
||||
if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) {
|
||||
visual->class = PseudoColor;
|
||||
visual->nplanes = PICT_FORMAT_BPP(alt->format);
|
||||
visual->ColormapEntries = 1 << visual->nplanes;
|
||||
}
|
||||
else {
|
||||
DirectFormatRec *direct = &pPictFormat->direct;
|
||||
|
||||
visual->class = TrueColor;
|
||||
visual->redMask = ((unsigned long) direct->redMask) << direct->red;
|
||||
visual->greenMask =
|
||||
((unsigned long) direct->greenMask) << direct->green;
|
||||
visual->blueMask = ((unsigned long) direct->blueMask) << direct->blue;
|
||||
alphaMask = ((unsigned long) direct->alphaMask) << direct->alpha;
|
||||
visual->offsetRed = direct->red;
|
||||
visual->offsetGreen = direct->green;
|
||||
visual->offsetBlue = direct->blue;
|
||||
/*
|
||||
* Include A bits in this (unlike GLX which includes only RGB)
|
||||
* This lets DIX compute suitable masks for colormap allocations
|
||||
*/
|
||||
visual->nplanes = Ones(visual->redMask |
|
||||
visual->greenMask |
|
||||
visual->blueMask | alphaMask);
|
||||
/* find widest component */
|
||||
visual->ColormapEntries = (1 << max(Ones(visual->redMask),
|
||||
max(Ones(visual->greenMask),
|
||||
Ones(visual->blueMask))));
|
||||
}
|
||||
|
||||
/* remember the visual ID to detect auto-update windows */
|
||||
compRegisterAlternateVisuals(cs, &visual->vid, 1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
compAddAlternateVisuals(ScreenPtr pScreen, CompScreenPtr cs)
|
||||
{
|
||||
int alt, ret = 0;
|
||||
|
||||
for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++)
|
||||
ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt);
|
||||
|
||||
return ! !ret;
|
||||
}
|
||||
|
||||
Bool
|
||||
compScreenInit (ScreenPtr pScreen)
|
||||
{
|
||||
CompScreenPtr cs;
|
||||
|
||||
#ifndef NXAGENT_SERVER
|
||||
if (!dixRegisterPrivateKey(&CompScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
|
||||
return FALSE;
|
||||
if (!dixRegisterPrivateKey(&CompWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
|
||||
return FALSE;
|
||||
if (!dixRegisterPrivateKey(&CompSubwindowsPrivateKeyRec, PRIVATE_WINDOW, 0))
|
||||
return FALSE;
|
||||
#else /* !defined(NXAGENT_SERVER) */
|
||||
if ((CompScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
|
||||
return FALSE;
|
||||
if ((CompWindowPrivIndex = AllocateWindowPrivateIndex()) < 0)
|
||||
return FALSE;
|
||||
if ((CompSubwindowsPrivIndex = AllocateWindowPrivateIndex()) < 0)
|
||||
return FALSE;
|
||||
|
||||
if (!AllocateWindowPrivate (pScreen, CompWindowPrivIndex, 0))
|
||||
return FALSE;
|
||||
|
||||
if (!AllocateWindowPrivate (pScreen, CompSubwindowsPrivIndex, 0))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
if (GetCompScreen (pScreen))
|
||||
return TRUE;
|
||||
cs = (CompScreenPtr) malloc (sizeof (CompScreenRec));
|
||||
if (!cs)
|
||||
return FALSE;
|
||||
|
||||
cs->damaged = FALSE;
|
||||
|
||||
cs->overlayWid = FakeClientID(0);
|
||||
cs->pOverlayWin = NULL;
|
||||
cs->pOverlayClients = NULL;
|
||||
|
||||
cs->numAlternateVisuals = 0;
|
||||
cs->alternateVisuals = NULL;
|
||||
cs->numImplicitRedirectExceptions = 0;
|
||||
cs->implicitRedirectExceptions = NULL;
|
||||
|
||||
if (!compAddAlternateVisuals (pScreen, cs))
|
||||
{
|
||||
free (cs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!disableBackingStore)
|
||||
pScreen->backingStoreSupport = WhenMapped;
|
||||
|
||||
cs->PositionWindow = pScreen->PositionWindow;
|
||||
pScreen->PositionWindow = compPositionWindow;
|
||||
|
||||
cs->CopyWindow = pScreen->CopyWindow;
|
||||
pScreen->CopyWindow = compCopyWindow;
|
||||
|
||||
cs->CreateWindow = pScreen->CreateWindow;
|
||||
pScreen->CreateWindow = compCreateWindow;
|
||||
|
||||
cs->DestroyWindow = pScreen->DestroyWindow;
|
||||
pScreen->DestroyWindow = compDestroyWindow;
|
||||
|
||||
cs->RealizeWindow = pScreen->RealizeWindow;
|
||||
pScreen->RealizeWindow = compRealizeWindow;
|
||||
|
||||
cs->UnrealizeWindow = pScreen->UnrealizeWindow;
|
||||
pScreen->UnrealizeWindow = compUnrealizeWindow;
|
||||
|
||||
cs->ClipNotify = pScreen->ClipNotify;
|
||||
pScreen->ClipNotify = compClipNotify;
|
||||
|
||||
/*
|
||||
* Unsupported by our old Xserver infrastructure, replaced with direct calls to
|
||||
* compReallocPixmap().
|
||||
*/
|
||||
/*
|
||||
cs->ConfigNotify = pScreen->ConfigNotify;
|
||||
pScreen->ConfigNotify = compConfigNotify;
|
||||
*/
|
||||
|
||||
cs->MoveWindow = pScreen->MoveWindow;
|
||||
pScreen->MoveWindow = compMoveWindow;
|
||||
|
||||
cs->ResizeWindow = pScreen->ResizeWindow;
|
||||
pScreen->ResizeWindow = compResizeWindow;
|
||||
|
||||
cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
|
||||
pScreen->ChangeBorderWidth = compChangeBorderWidth;
|
||||
|
||||
cs->ReparentWindow = pScreen->ReparentWindow;
|
||||
pScreen->ReparentWindow = compReparentWindow;
|
||||
|
||||
cs->InstallColormap = pScreen->InstallColormap;
|
||||
pScreen->InstallColormap = compInstallColormap;
|
||||
|
||||
/* Unsupported by our current architecture, drop for now. */
|
||||
/*
|
||||
cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
|
||||
pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
|
||||
*/
|
||||
|
||||
cs->BlockHandler = NULL;
|
||||
|
||||
cs->CloseScreen = pScreen->CloseScreen;
|
||||
pScreen->CloseScreen = compCloseScreen;
|
||||
|
||||
cs->GetImage = pScreen->GetImage;
|
||||
pScreen->GetImage = compGetImage;
|
||||
|
||||
cs->GetSpans = pScreen->GetSpans;
|
||||
pScreen->GetSpans = compGetSpans;
|
||||
|
||||
cs->SourceValidate = pScreen->SourceValidate;
|
||||
pScreen->SourceValidate = compSourceValidate;
|
||||
|
||||
FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, cs);
|
||||
|
||||
RegisterRealChildHeadProc(CompositeRealChildHead);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
360
nx-X11/programs/Xserver/composite/compint.h
Normal file
360
nx-X11/programs/Xserver/composite/compint.h
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
* $Id: compint.h,v 1.8 2005/07/03 08:53:37 daniels Exp $
|
||||
*
|
||||
* Copyright © 2003 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _COMPINT_H_
|
||||
#define _COMPINT_H_
|
||||
|
||||
#include "misc.h"
|
||||
#include "scrnintstr.h"
|
||||
#include "os.h"
|
||||
#include "regionstr.h"
|
||||
#include "validate.h"
|
||||
#include "windowstr.h"
|
||||
#include "input.h"
|
||||
#include "resource.h"
|
||||
#include "colormapst.h"
|
||||
#include "cursorstr.h"
|
||||
#include "dixstruct.h"
|
||||
#include "gcstruct.h"
|
||||
#include "servermd.h"
|
||||
#include "dixevents.h"
|
||||
#include "globals.h"
|
||||
#include "picturestr.h"
|
||||
#include "extnsionst.h"
|
||||
#include "mi.h"
|
||||
#include "damage.h"
|
||||
#include "damageextint.h"
|
||||
#include "xfixes.h"
|
||||
#include <nx-X11/extensions/compositeproto.h>
|
||||
#include "compositeext.h"
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* enable this for debugging
|
||||
#define COMPOSITE_DEBUG
|
||||
*/
|
||||
|
||||
typedef struct _CompClientWindow {
|
||||
struct _CompClientWindow *next;
|
||||
XID id;
|
||||
int update;
|
||||
} CompClientWindowRec, *CompClientWindowPtr;
|
||||
|
||||
typedef struct _CompWindow {
|
||||
RegionRec borderClip;
|
||||
DamagePtr damage; /* for automatic update mode */
|
||||
Bool damageRegistered;
|
||||
Bool damaged;
|
||||
int update;
|
||||
CompClientWindowPtr clients;
|
||||
int oldx;
|
||||
int oldy;
|
||||
PixmapPtr pOldPixmap;
|
||||
int borderClipX, borderClipY;
|
||||
} CompWindowRec, *CompWindowPtr;
|
||||
|
||||
#define COMP_ORIGIN_INVALID 0x80000000
|
||||
|
||||
typedef struct _CompSubwindows {
|
||||
int update;
|
||||
CompClientWindowPtr clients;
|
||||
} CompSubwindowsRec, *CompSubwindowsPtr;
|
||||
|
||||
#ifndef COMP_INCLUDE_RGB24_VISUAL
|
||||
#define COMP_INCLUDE_RGB24_VISUAL 0
|
||||
#endif
|
||||
|
||||
typedef struct _CompOverlayClientRec *CompOverlayClientPtr;
|
||||
|
||||
typedef struct _CompOverlayClientRec {
|
||||
CompOverlayClientPtr pNext;
|
||||
ClientPtr pClient;
|
||||
ScreenPtr pScreen;
|
||||
XID resource;
|
||||
} CompOverlayClientRec;
|
||||
|
||||
typedef struct _CompImplicitRedirectException {
|
||||
XID parentVisual;
|
||||
XID winVisual;
|
||||
} CompImplicitRedirectException;
|
||||
|
||||
typedef struct _CompScreen {
|
||||
PositionWindowProcPtr PositionWindow;
|
||||
CopyWindowProcPtr CopyWindow;
|
||||
CreateWindowProcPtr CreateWindow;
|
||||
DestroyWindowProcPtr DestroyWindow;
|
||||
RealizeWindowProcPtr RealizeWindow;
|
||||
UnrealizeWindowProcPtr UnrealizeWindow;
|
||||
ClipNotifyProcPtr ClipNotify;
|
||||
/*
|
||||
* Called from ConfigureWindow, these
|
||||
* three track changes to the offscreen storage
|
||||
* geometry
|
||||
*/
|
||||
|
||||
/*
|
||||
* Unsupported by our old Xserver infrastructure, replaced with direct calls to
|
||||
* compReallocPixmap().
|
||||
*/
|
||||
/*
|
||||
ConfigNotifyProcPtr ConfigNotify;
|
||||
*/
|
||||
|
||||
MoveWindowProcPtr MoveWindow;
|
||||
ResizeWindowProcPtr ResizeWindow;
|
||||
ChangeBorderWidthProcPtr ChangeBorderWidth;
|
||||
/*
|
||||
* Reparenting has an effect on Subwindows redirect
|
||||
*/
|
||||
ReparentWindowProcPtr ReparentWindow;
|
||||
|
||||
/*
|
||||
* Colormaps for new visuals better not get installed
|
||||
*/
|
||||
InstallColormapProcPtr InstallColormap;
|
||||
|
||||
/*
|
||||
* Fake backing store via automatic redirection
|
||||
*/
|
||||
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
|
||||
|
||||
ScreenBlockHandlerProcPtr BlockHandler;
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
Bool damaged;
|
||||
int numAlternateVisuals;
|
||||
VisualID *alternateVisuals;
|
||||
int numImplicitRedirectExceptions;
|
||||
CompImplicitRedirectException *implicitRedirectExceptions;
|
||||
|
||||
WindowPtr pOverlayWin;
|
||||
Window overlayWid;
|
||||
CompOverlayClientPtr pOverlayClients;
|
||||
|
||||
GetImageProcPtr GetImage;
|
||||
GetSpansProcPtr GetSpans;
|
||||
SourceValidateProcPtr SourceValidate;
|
||||
} CompScreenRec, *CompScreenPtr;
|
||||
|
||||
#ifndef NXAGENT_SERVER
|
||||
extern DevPrivateKeyRec CompScreenPrivateKeyRec;
|
||||
|
||||
#define CompScreenPrivateKey (&CompScreenPrivateKeyRec)
|
||||
|
||||
extern DevPrivateKeyRec CompWindowPrivateKeyRec;
|
||||
|
||||
#define CompWindowPrivateKey (&CompWindowPrivateKeyRec)
|
||||
|
||||
extern DevPrivateKeyRec CompSubwindowsPrivateKeyRec;
|
||||
|
||||
#define CompSubwindowsPrivateKey (&CompSubwindowsPrivateKeyRec)
|
||||
|
||||
#define GetCompScreen(s) ((CompScreenPtr) \
|
||||
dixLookupPrivate(&(s)->devPrivates, CompScreenPrivateKey))
|
||||
#define GetCompWindow(w) ((CompWindowPtr) \
|
||||
dixLookupPrivate(&(w)->devPrivates, CompWindowPrivateKey))
|
||||
#define GetCompSubwindows(w) ((CompSubwindowsPtr) \
|
||||
dixLookupPrivate(&(w)->devPrivates, CompSubwindowsPrivateKey))
|
||||
#else /* !defined(NXAGENT_SERVER) */
|
||||
extern int CompScreenPrivIndex;
|
||||
extern int CompWindowPrivIndex;
|
||||
extern int CompSubwindowsPrivIndex;
|
||||
|
||||
#define GetCompScreen(s) ((CompScreenPtr) (s)->devPrivates[CompScreenPrivIndex].ptr)
|
||||
#define GetCompWindow(w) ((CompWindowPtr) (w)->devPrivates[CompWindowPrivIndex].ptr)
|
||||
#define GetCompSubwindows(w) ((CompSubwindowsPtr) (w)->devPrivates[CompSubwindowsPrivIndex].ptr)
|
||||
#endif /* !defined(NXAGENT_SERVER) */
|
||||
|
||||
extern RESTYPE CompositeClientSubwindowsType;
|
||||
extern RESTYPE CompositeClientOverlayType;
|
||||
|
||||
/* Shim for less ifdefs within the actual code. */
|
||||
#ifndef NXAGENT_SERVER
|
||||
#define FAKE_DIX_SET_PRIVATE_IMPL(obj, privateKey, ptr_val) do { dixSetPrivate(&(obj)->devPrivates, privateKey, ptr_val); } while (0)
|
||||
|
||||
#define FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pScreen, CompScreenPrivateKey, ptr_val)
|
||||
#define FAKE_DIX_SET_WINDOW_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompWindowPrivateKey, ptr_val)
|
||||
#define FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompSubwindowsPrivateKey, ptr_val)
|
||||
#else /* !defined(NXAGENT_SERVER) */
|
||||
#define FAKE_DIX_SET_PRIVATE_IMPL(obj, privIndex, ptr_val) do { (obj)->devPrivates[privIndex].ptr = (void *) (ptr_val); } while (0)
|
||||
|
||||
#define FAKE_DIX_SET_SCREEN_PRIVATE(pScreen, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pScreen, CompScreenPrivIndex, ptr_val)
|
||||
#define FAKE_DIX_SET_WINDOW_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompWindowPrivIndex, ptr_val)
|
||||
#define FAKE_DIX_SET_SUBWINDOWS_PRIVATE(pWin, ptr_val) FAKE_DIX_SET_PRIVATE_IMPL(pWin, CompSubwindowsPrivIndex, ptr_val)
|
||||
#endif /* !defined(NXAGENT_SERVER) */
|
||||
|
||||
/*
|
||||
* compalloc.c
|
||||
*/
|
||||
|
||||
Bool
|
||||
compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
|
||||
|
||||
void
|
||||
compFreeClientWindow (WindowPtr pWin, XID id);
|
||||
|
||||
int
|
||||
compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update);
|
||||
|
||||
int
|
||||
compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
|
||||
|
||||
void
|
||||
compFreeClientSubwindows (WindowPtr pWin, XID id);
|
||||
|
||||
int
|
||||
compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update);
|
||||
|
||||
int
|
||||
compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
|
||||
|
||||
int
|
||||
compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin);
|
||||
|
||||
Bool
|
||||
compAllocPixmap (WindowPtr pWin);
|
||||
|
||||
void
|
||||
compSetParentPixmap(WindowPtr pWin);
|
||||
|
||||
void
|
||||
compRestoreWindow(WindowPtr pWin, PixmapPtr pPixmap);
|
||||
|
||||
Bool
|
||||
compReallocPixmap (WindowPtr pWin, int x, int y,
|
||||
unsigned int w, unsigned int h, int bw);
|
||||
|
||||
/*
|
||||
* compinit.c
|
||||
*/
|
||||
|
||||
Bool
|
||||
compScreenInit(ScreenPtr pScreen);
|
||||
|
||||
/*
|
||||
* compoverlay.c
|
||||
*/
|
||||
|
||||
void
|
||||
compFreeOverlayClient(CompOverlayClientPtr pOcToDel);
|
||||
|
||||
CompOverlayClientPtr
|
||||
compFindOverlayClient(ScreenPtr pScreen, ClientPtr pClient);
|
||||
|
||||
CompOverlayClientPtr
|
||||
compCreateOverlayClient(ScreenPtr pScreen, ClientPtr pClient);
|
||||
|
||||
Bool
|
||||
compCreateOverlayWindow(ScreenPtr pScreen);
|
||||
|
||||
void
|
||||
compDestroyOverlayWindow(ScreenPtr pScreen);
|
||||
|
||||
/*
|
||||
* compwindow.c
|
||||
*/
|
||||
|
||||
#ifdef COMPOSITE_DEBUG
|
||||
void
|
||||
compCheckTree (ScreenPtr pScreen);
|
||||
#else
|
||||
#define compCheckTree(s)
|
||||
#endif
|
||||
|
||||
PictFormatPtr
|
||||
compWindowFormat (WindowPtr pWin);
|
||||
|
||||
void
|
||||
compSetPixmap (WindowPtr pWin, PixmapPtr pPixmap);
|
||||
|
||||
Bool
|
||||
compCheckRedirect (WindowPtr pWin);
|
||||
|
||||
Bool
|
||||
compPositionWindow (WindowPtr pWin, int x, int y);
|
||||
|
||||
Bool
|
||||
compRealizeWindow (WindowPtr pWin);
|
||||
|
||||
Bool
|
||||
compUnrealizeWindow (WindowPtr pWin);
|
||||
|
||||
|
||||
void
|
||||
compClipNotify (WindowPtr pWin, int dx, int dy);
|
||||
|
||||
void
|
||||
compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind);
|
||||
|
||||
void
|
||||
compResizeWindow (WindowPtr pWin, int x, int y,
|
||||
unsigned int w, unsigned int h, WindowPtr pSib);
|
||||
|
||||
void
|
||||
compChangeBorderWidth (WindowPtr pWin, unsigned int border_width);
|
||||
|
||||
void
|
||||
compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent);
|
||||
|
||||
Bool
|
||||
compCreateWindow (WindowPtr pWin);
|
||||
|
||||
Bool
|
||||
compDestroyWindow (WindowPtr pWin);
|
||||
|
||||
void
|
||||
compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion);
|
||||
|
||||
RegionPtr
|
||||
compGetRedirectBorderClip (WindowPtr pWin);
|
||||
|
||||
void
|
||||
compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
|
||||
|
||||
void
|
||||
compPaintChildrenToWindow(ScreenPtr pScreen, WindowPtr pWin);
|
||||
|
||||
WindowPtr
|
||||
CompositeRealChildHead(WindowPtr pWin);
|
||||
|
||||
int
|
||||
DeleteWindowNoInputDevices(void *value, XID wid);
|
||||
|
||||
/*
|
||||
* Unsupported by our old Xserver infrastructure, replaced with direct calls to
|
||||
* compReallocPixmap().
|
||||
*/
|
||||
/*
|
||||
int
|
||||
compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
|
||||
int bw, WindowPtr pSib);
|
||||
*/
|
||||
|
||||
void PanoramiXCompositeInit(void);
|
||||
void PanoramiXCompositeReset(void);
|
||||
|
||||
#endif /* _COMPINT_H_ */
|
||||
44
nx-X11/programs/Xserver/composite/compositeext.h
Normal file
44
nx-X11/programs/Xserver/composite/compositeext.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright © 2009 NVIDIA Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _COMPOSITEEXT_H_
|
||||
#define _COMPOSITEEXT_H_
|
||||
|
||||
#include "misc.h"
|
||||
#include "scrnintstr.h"
|
||||
|
||||
extern _X_EXPORT Bool CompositeRegisterAlternateVisuals(ScreenPtr pScreen,
|
||||
VisualID * vids,
|
||||
int nVisuals);
|
||||
|
||||
extern _X_EXPORT Bool CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
|
||||
VisualID parentVisual,
|
||||
VisualID winVisual);
|
||||
|
||||
extern _X_EXPORT RESTYPE CompositeClientWindowType;
|
||||
|
||||
#endif /* _COMPOSITEEXT_H_ */
|
||||
178
nx-X11/programs/Xserver/composite/compoverlay.c
Normal file
178
nx-X11/programs/Xserver/composite/compoverlay.c
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Copyright © 2003 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "compint.h"
|
||||
#ifndef NXAGENT_SERVER
|
||||
#include "xace.h"
|
||||
#endif
|
||||
|
||||
#ifdef PANORAMIX
|
||||
#include "panoramiXsrv.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Delete the given overlay client list element from its screen list.
|
||||
*/
|
||||
void
|
||||
compFreeOverlayClient(CompOverlayClientPtr pOcToDel)
|
||||
{
|
||||
ScreenPtr pScreen = pOcToDel->pScreen;
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
CompOverlayClientPtr *pPrev, pOc;
|
||||
|
||||
for (pPrev = &cs->pOverlayClients; (pOc = *pPrev); pPrev = &pOc->pNext) {
|
||||
if (pOc == pOcToDel) {
|
||||
*pPrev = pOc->pNext;
|
||||
free(pOc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Destroy overlay window when there are no more clients using it */
|
||||
if (cs->pOverlayClients == NULL)
|
||||
compDestroyOverlayWindow(pScreen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the client's first overlay client rec from the given screen
|
||||
*/
|
||||
CompOverlayClientPtr
|
||||
compFindOverlayClient(ScreenPtr pScreen, ClientPtr pClient)
|
||||
{
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
CompOverlayClientPtr pOc;
|
||||
|
||||
for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext)
|
||||
if (pOc->pClient == pClient)
|
||||
return pOc;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an overlay client object for the given client
|
||||
*/
|
||||
CompOverlayClientPtr
|
||||
compCreateOverlayClient(ScreenPtr pScreen, ClientPtr pClient)
|
||||
{
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
CompOverlayClientPtr pOc;
|
||||
|
||||
pOc = (CompOverlayClientPtr) malloc(sizeof(CompOverlayClientRec));
|
||||
if (pOc == NULL)
|
||||
return NULL;
|
||||
|
||||
pOc->pClient = pClient;
|
||||
pOc->pScreen = pScreen;
|
||||
pOc->resource = FakeClientID(pClient->index);
|
||||
pOc->pNext = cs->pOverlayClients;
|
||||
cs->pOverlayClients = pOc;
|
||||
|
||||
/*
|
||||
* Create a resource for this element so it can be deleted
|
||||
* when the client goes away.
|
||||
*/
|
||||
if (!AddResource(pOc->resource, CompositeClientOverlayType, (void *) pOc))
|
||||
return NULL;
|
||||
|
||||
return pOc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the overlay window and map it
|
||||
*/
|
||||
Bool
|
||||
compCreateOverlayWindow(ScreenPtr pScreen)
|
||||
{
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
WindowPtr pRoot = pScreen->root;
|
||||
WindowPtr pWin;
|
||||
XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */
|
||||
int result;
|
||||
int w = pScreen->width;
|
||||
int h = pScreen->height;
|
||||
int x = 0, y = 0;
|
||||
|
||||
/* Unsupported by current architecture, disabled. */
|
||||
#if 0
|
||||
#ifdef PANORAMIX
|
||||
if (!noPanoramiXExtension) {
|
||||
x = -pScreen->x;
|
||||
y = -pScreen->y;
|
||||
w = PanoramiXPixWidth;
|
||||
h = PanoramiXPixHeight;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pWin = cs->pOverlayWin =
|
||||
CreateWindow(cs->overlayWid, pRoot, x, y, w, h, 0,
|
||||
InputOutput, CWBackPixmap | CWOverrideRedirect, &attrs[0],
|
||||
pRoot->drawable.depth,
|
||||
serverClient, pScreen->rootVisual, &result);
|
||||
if (pWin == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!AddResource(pWin->drawable.id, RT_WINDOW, (void *) pWin))
|
||||
return FALSE;
|
||||
|
||||
MapWindow(pWin, serverClient);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy the overlay window
|
||||
*/
|
||||
void
|
||||
compDestroyOverlayWindow(ScreenPtr pScreen)
|
||||
{
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
|
||||
cs->pOverlayWin = NullWindow;
|
||||
FreeResource(cs->overlayWid, RT_NONE);
|
||||
}
|
||||
909
nx-X11/programs/Xserver/composite/compwindow.c
Normal file
909
nx-X11/programs/Xserver/composite/compwindow.c
Normal file
@@ -0,0 +1,909 @@
|
||||
/*
|
||||
* $Id: compwindow.c,v 1.11 2005/07/03 07:37:34 daniels Exp $
|
||||
*
|
||||
* Copyright © 2003 Keith Packard
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
||||
* documentation for any purpose is hereby granted without fee, provided that
|
||||
* the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of Keith Packard not be used in
|
||||
* advertising or publicity pertaining to distribution of the software without
|
||||
* specific, written prior permission. Keith Packard makes no
|
||||
* representations about the suitability of this software for any purpose. It
|
||||
* is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DIX_CONFIG_H
|
||||
#include <dix-config.h>
|
||||
#endif
|
||||
|
||||
#include "compint.h"
|
||||
|
||||
#ifdef PANORAMIX
|
||||
#include "panoramiXsrv.h"
|
||||
#endif
|
||||
|
||||
#ifdef COMPOSITE_DEBUG
|
||||
static int
|
||||
compCheckWindow (WindowPtr pWin, void * data)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
PixmapPtr pWinPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||
PixmapPtr pParentPixmap = pWin->parent ? (*pScreen->GetWindowPixmap) (pWin->parent) : 0;
|
||||
PixmapPtr pScreenPixmap = (*pScreen->GetScreenPixmap) (pScreen);
|
||||
|
||||
if (!pWin->parent)
|
||||
{
|
||||
assert (pWin->redirectDraw == RedriectDrawNone);
|
||||
assert (pWinPixmap == pScreenPixmap);
|
||||
}
|
||||
else if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
assert (pWinPixmap != pParentPixmap);
|
||||
assert (pWinPixmap != pScreenPixmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (pWinPixmap == pParentPixmap);
|
||||
}
|
||||
assert (0 < pWinPixmap->refcnt && pWinPixmap->refcnt < 3);
|
||||
assert (0 < pScreenPixmap->refcnt && pScreenPixmap->refcnt < 3);
|
||||
if (pParentPixmap)
|
||||
assert (0 <= pParentPixmap->refcnt && pParentPixmap->refcnt < 3);
|
||||
return WT_WALKCHILDREN;
|
||||
}
|
||||
|
||||
void
|
||||
compCheckTree (ScreenPtr pScreen)
|
||||
{
|
||||
WalkTree (pScreen, compCheckWindow, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct _compPixmapVisit {
|
||||
WindowPtr pWindow;
|
||||
PixmapPtr pPixmap;
|
||||
} CompPixmapVisitRec, *CompPixmapVisitPtr;
|
||||
|
||||
static Bool
|
||||
compRepaintBorder (ClientPtr pClient, void * closure)
|
||||
{
|
||||
WindowPtr pWindow;
|
||||
#ifndef NXAGENT_SERVER
|
||||
int rc =
|
||||
dixLookupWindow(&pWindow, (XID) (intptr_t) closure, pClient,
|
||||
DixWriteAccess);
|
||||
#else
|
||||
pWindow = SecurityLookupWindow((XID) (intptr_t) closure, pClient, DixWriteAccess);
|
||||
int rc = pWindow ? Success : BadWindow;
|
||||
#endif
|
||||
|
||||
if (rc == Success)
|
||||
{
|
||||
RegionRec exposed;
|
||||
|
||||
RegionNull(&exposed);
|
||||
RegionSubtract(&exposed, &pWindow->borderClip, &pWindow->winSize);
|
||||
#ifndef NXAGENT_SERVER
|
||||
pWindow->drawable.pScreen->PaintWindowBorder(pWindow, &exposed, PW_BORDER);
|
||||
#else
|
||||
(*pWindow->drawable.pScreen->PaintWindowBorder)(pWindow, &exposed, PW_BORDER);
|
||||
#endif
|
||||
RegionUninit(&exposed);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
compSetPixmapVisitWindow (WindowPtr pWindow, void * data)
|
||||
{
|
||||
CompPixmapVisitPtr pVisit = (CompPixmapVisitPtr) data;
|
||||
ScreenPtr pScreen = pWindow->drawable.pScreen;
|
||||
|
||||
if (pWindow != pVisit->pWindow && pWindow->redirectDraw != RedirectDrawNone)
|
||||
return WT_DONTWALKCHILDREN;
|
||||
(*pScreen->SetWindowPixmap) (pWindow, pVisit->pPixmap);
|
||||
/*
|
||||
* Recompute winSize and borderSize. This is duplicate effort
|
||||
* when resizing pixmaps, but necessary when changing redirection.
|
||||
* Might be nice to fix this.
|
||||
*/
|
||||
SetWinSize (pWindow);
|
||||
SetBorderSize (pWindow);
|
||||
if (HasBorder (pWindow))
|
||||
QueueWorkProc (compRepaintBorder, serverClient,
|
||||
(void *) (intptr_t) pWindow->drawable.id);
|
||||
return WT_WALKCHILDREN;
|
||||
}
|
||||
|
||||
void
|
||||
compSetPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
|
||||
{
|
||||
CompPixmapVisitRec visitRec;
|
||||
|
||||
visitRec.pWindow = pWindow;
|
||||
visitRec.pPixmap = pPixmap;
|
||||
TraverseTree (pWindow, compSetPixmapVisitWindow, (void *) &visitRec);
|
||||
compCheckTree (pWindow->drawable.pScreen);
|
||||
}
|
||||
|
||||
Bool
|
||||
compCheckRedirect (WindowPtr pWin)
|
||||
{
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
|
||||
Bool should;
|
||||
|
||||
should = pWin->realized && (pWin->drawable.class != InputOnly) &&
|
||||
(cw != NULL) && (pWin->parent != NULL);
|
||||
|
||||
/* Never redirect the overlay window */
|
||||
if (cs->pOverlayWin != NULL) {
|
||||
if (pWin == cs->pOverlayWin) {
|
||||
should = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (should != (pWin->redirectDraw != RedirectDrawNone))
|
||||
{
|
||||
if (should)
|
||||
return compAllocPixmap (pWin);
|
||||
else {
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||
|
||||
compSetParentPixmap(pWin);
|
||||
compRestoreWindow(pWin, pPixmap);
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
}
|
||||
}
|
||||
else if (should) {
|
||||
if (cw->update == CompositeRedirectAutomatic)
|
||||
pWin->redirectDraw = RedirectDrawAutomatic;
|
||||
else
|
||||
pWin->redirectDraw = RedirectDrawManual;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
updateOverlayWindow(ScreenPtr pScreen)
|
||||
{
|
||||
CompScreenPtr cs;
|
||||
WindowPtr pWin; /* overlay window */
|
||||
XID vlist[2];
|
||||
int w = pScreen->width;
|
||||
int h = pScreen->height;
|
||||
|
||||
#ifdef PANORAMIX
|
||||
if (!noPanoramiXExtension) {
|
||||
w = PanoramiXPixWidth;
|
||||
h = PanoramiXPixHeight;
|
||||
}
|
||||
#endif
|
||||
|
||||
cs = GetCompScreen(pScreen);
|
||||
if ((pWin = cs->pOverlayWin) != NULL) {
|
||||
if ((pWin->drawable.width == w) && (pWin->drawable.height == h))
|
||||
return Success;
|
||||
|
||||
/* Let's resize the overlay window. */
|
||||
vlist[0] = w;
|
||||
vlist[1] = h;
|
||||
return ConfigureWindow(pWin, CWWidth | CWHeight, vlist, wClient(pWin));
|
||||
}
|
||||
|
||||
/* Let's be on the safe side and not assume an overlay window is
|
||||
always allocated. */
|
||||
return Success;
|
||||
}
|
||||
|
||||
Bool
|
||||
compPositionWindow (WindowPtr pWin, int x, int y)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
Bool ret = TRUE;
|
||||
|
||||
pScreen->PositionWindow = cs->PositionWindow;
|
||||
/*
|
||||
* "Shouldn't need this as all possible places should be wrapped
|
||||
*
|
||||
compCheckRedirect (pWin);
|
||||
*/
|
||||
#ifdef COMPOSITE_DEBUG
|
||||
if ((pWin->redirectDraw != RedirectDrawNone) !=
|
||||
(pWin->viewable && (GetCompWindow(pWin) != NULL)))
|
||||
abort ();
|
||||
#endif
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||
int bw = wBorderWidth (pWin);
|
||||
int nx = pWin->drawable.x - bw;
|
||||
int ny = pWin->drawable.y - bw;
|
||||
|
||||
if (pPixmap->screen_x != nx || pPixmap->screen_y != ny)
|
||||
{
|
||||
pPixmap->screen_x = nx;
|
||||
pPixmap->screen_y = ny;
|
||||
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(*pScreen->PositionWindow) (pWin, x, y))
|
||||
ret = FALSE;
|
||||
cs->PositionWindow = pScreen->PositionWindow;
|
||||
pScreen->PositionWindow = compPositionWindow;
|
||||
compCheckTree (pWin->drawable.pScreen);
|
||||
if (updateOverlayWindow(pScreen) != Success)
|
||||
ret = FALSE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Bool
|
||||
compRealizeWindow (WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
Bool ret = TRUE;
|
||||
|
||||
pScreen->RealizeWindow = cs->RealizeWindow;
|
||||
compCheckRedirect (pWin);
|
||||
if (!(*pScreen->RealizeWindow) (pWin))
|
||||
ret = FALSE;
|
||||
cs->RealizeWindow = pScreen->RealizeWindow;
|
||||
pScreen->RealizeWindow = compRealizeWindow;
|
||||
compCheckTree (pWin->drawable.pScreen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Bool
|
||||
compUnrealizeWindow (WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
Bool ret = TRUE;
|
||||
|
||||
pScreen->UnrealizeWindow = cs->UnrealizeWindow;
|
||||
compCheckRedirect (pWin);
|
||||
if (!(*pScreen->UnrealizeWindow) (pWin))
|
||||
ret = FALSE;
|
||||
cs->UnrealizeWindow = pScreen->UnrealizeWindow;
|
||||
pScreen->UnrealizeWindow = compUnrealizeWindow;
|
||||
compCheckTree (pWin->drawable.pScreen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called after the borderClip for the window has settled down
|
||||
* We use this to make sure our extra borderClip has the right origin
|
||||
*/
|
||||
|
||||
void
|
||||
compClipNotify (WindowPtr pWin, int dx, int dy)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
|
||||
if (cw)
|
||||
{
|
||||
if (cw->borderClipX != pWin->drawable.x ||
|
||||
cw->borderClipY != pWin->drawable.y)
|
||||
{
|
||||
RegionTranslate(&cw->borderClip,
|
||||
pWin->drawable.x - cw->borderClipX,
|
||||
pWin->drawable.y - cw->borderClipY);
|
||||
cw->borderClipX = pWin->drawable.x;
|
||||
cw->borderClipY = pWin->drawable.y;
|
||||
}
|
||||
}
|
||||
if (cs->ClipNotify)
|
||||
{
|
||||
pScreen->ClipNotify = cs->ClipNotify;
|
||||
(*pScreen->ClipNotify) (pWin, dx, dy);
|
||||
cs->ClipNotify = pScreen->ClipNotify;
|
||||
pScreen->ClipNotify = compClipNotify;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns TRUE if the window needs server-provided automatic redirect,
|
||||
* which is true if the child and parent aren't both regular or ARGB visuals
|
||||
*/
|
||||
|
||||
static Bool
|
||||
compIsAlternateVisual (ScreenPtr pScreen,
|
||||
XID visual)
|
||||
{
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cs->numAlternateVisuals; i++)
|
||||
if (cs->alternateVisuals[i] == visual)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
compIsImplicitRedirectException(ScreenPtr pScreen,
|
||||
XID parentVisual, XID winVisual)
|
||||
{
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < cs->numImplicitRedirectExceptions; i++)
|
||||
if (cs->implicitRedirectExceptions[i].parentVisual == parentVisual &&
|
||||
cs->implicitRedirectExceptions[i].winVisual == winVisual)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
compImplicitRedirect (WindowPtr pWin, WindowPtr pParent)
|
||||
{
|
||||
if (pParent)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
XID winVisual = wVisual (pWin);
|
||||
XID parentVisual = wVisual (pParent);
|
||||
|
||||
if (compIsImplicitRedirectException(pScreen, parentVisual, winVisual))
|
||||
return FALSE;
|
||||
|
||||
if (winVisual != parentVisual &&
|
||||
(compIsAlternateVisual (pScreen, winVisual) ||
|
||||
compIsAlternateVisual (pScreen, parentVisual)))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
compFreeOldPixmap(WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
|
||||
if (pWin->redirectDraw != RedirectDrawNone) {
|
||||
CompWindowPtr cw = GetCompWindow(pWin);
|
||||
|
||||
if (cw->pOldPixmap) {
|
||||
(*pScreen->DestroyPixmap) (cw->pOldPixmap);
|
||||
cw->pOldPixmap = NullPixmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
compMoveWindow (WindowPtr pWin, int x, int y, WindowPtr pSib, VTKind kind)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
|
||||
compCheckTree (pScreen);
|
||||
if (pWin->redirectDraw != RedirectDrawNone) {
|
||||
WindowPtr pParent;
|
||||
int draw_x, draw_y;
|
||||
unsigned int w, h, bw;
|
||||
|
||||
/* if this is a root window, can't be moved */
|
||||
if (!(pParent = pWin->parent))
|
||||
return;
|
||||
|
||||
bw = wBorderWidth (pWin);
|
||||
draw_x = pParent->drawable.x + x + (int)bw;
|
||||
draw_y = pParent->drawable.y + y + (int)bw;
|
||||
w = pWin->drawable.width;
|
||||
h = pWin->drawable.height;
|
||||
compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
|
||||
}
|
||||
compCheckTree (pScreen);
|
||||
|
||||
pScreen->MoveWindow = cs->MoveWindow;
|
||||
(*pScreen->MoveWindow) (pWin, x, y, pSib, kind);
|
||||
cs->MoveWindow = pScreen->MoveWindow;
|
||||
pScreen->MoveWindow = compMoveWindow;
|
||||
|
||||
compFreeOldPixmap(pWin);
|
||||
compCheckTree (pScreen);
|
||||
}
|
||||
|
||||
void
|
||||
compResizeWindow (WindowPtr pWin, int x, int y,
|
||||
unsigned int w, unsigned int h, WindowPtr pSib)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
|
||||
compCheckTree (pScreen);
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
WindowPtr pParent;
|
||||
int draw_x, draw_y;
|
||||
unsigned int bw;
|
||||
|
||||
/* if this is a root window, can't be moved */
|
||||
if (!(pParent = pWin->parent))
|
||||
return;
|
||||
|
||||
bw = wBorderWidth (pWin);
|
||||
draw_x = pParent->drawable.x + x + (int)bw;
|
||||
draw_y = pParent->drawable.y + y + (int)bw;
|
||||
compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
|
||||
}
|
||||
compCheckTree (pScreen);
|
||||
|
||||
pScreen->ResizeWindow = cs->ResizeWindow;
|
||||
(*pScreen->ResizeWindow) (pWin, x, y, w, h, pSib);
|
||||
cs->ResizeWindow = pScreen->ResizeWindow;
|
||||
pScreen->ResizeWindow = compResizeWindow;
|
||||
|
||||
compFreeOldPixmap(pWin);
|
||||
compCheckTree (pWin->drawable.pScreen);
|
||||
}
|
||||
|
||||
void
|
||||
compChangeBorderWidth (WindowPtr pWin, unsigned int bw)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
|
||||
compCheckTree (pScreen);
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
WindowPtr pParent;
|
||||
int draw_x, draw_y;
|
||||
unsigned int w, h;
|
||||
|
||||
/* if this is a root window, can't be moved */
|
||||
if (!(pParent = pWin->parent))
|
||||
return;
|
||||
|
||||
draw_x = pWin->drawable.x;
|
||||
draw_y = pWin->drawable.y;
|
||||
w = pWin->drawable.width;
|
||||
h = pWin->drawable.height;
|
||||
compReallocPixmap (pWin, draw_x, draw_y, w, h, bw);
|
||||
}
|
||||
|
||||
compCheckTree (pScreen);
|
||||
pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
|
||||
(*pScreen->ChangeBorderWidth) (pWin, bw);
|
||||
cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
|
||||
pScreen->ChangeBorderWidth = compChangeBorderWidth;
|
||||
|
||||
compFreeOldPixmap(pWin);
|
||||
compCheckTree (pWin->drawable.pScreen);
|
||||
}
|
||||
|
||||
void
|
||||
compReparentWindow (WindowPtr pWin, WindowPtr pPriorParent)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
|
||||
pScreen->ReparentWindow = cs->ReparentWindow;
|
||||
/*
|
||||
* Remove any implicit redirect due to synthesized visual
|
||||
*/
|
||||
if (compImplicitRedirect (pWin, pPriorParent))
|
||||
compUnredirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
|
||||
/*
|
||||
* Handle subwindows redirection
|
||||
*/
|
||||
compUnredirectOneSubwindow (pPriorParent, pWin);
|
||||
compRedirectOneSubwindow (pWin->parent, pWin);
|
||||
/*
|
||||
* Add any implict redirect due to synthesized visual
|
||||
*/
|
||||
if (compImplicitRedirect (pWin, pWin->parent))
|
||||
compRedirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
|
||||
|
||||
/*
|
||||
* Allocate any necessary redirect pixmap
|
||||
* (this actually should never be true; pWin is always unmapped)
|
||||
*/
|
||||
compCheckRedirect (pWin);
|
||||
|
||||
/*
|
||||
* Reset pixmap pointers as appropriate
|
||||
*/
|
||||
if (pWin->parent && pWin->redirectDraw == RedirectDrawNone)
|
||||
compSetPixmap (pWin, (*pScreen->GetWindowPixmap) (pWin->parent));
|
||||
/*
|
||||
* Call down to next function
|
||||
*/
|
||||
if (pScreen->ReparentWindow)
|
||||
(*pScreen->ReparentWindow) (pWin, pPriorParent);
|
||||
cs->ReparentWindow = pScreen->ReparentWindow;
|
||||
pScreen->ReparentWindow = compReparentWindow;
|
||||
compCheckTree (pWin->drawable.pScreen);
|
||||
}
|
||||
|
||||
void
|
||||
compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
int dx = 0, dy = 0;
|
||||
|
||||
if (pWin->redirectDraw != RedirectDrawNone)
|
||||
{
|
||||
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
|
||||
assert (cw->oldx != COMP_ORIGIN_INVALID);
|
||||
assert (cw->oldy != COMP_ORIGIN_INVALID);
|
||||
if (cw->pOldPixmap)
|
||||
{
|
||||
/*
|
||||
* Ok, the old bits are available in pOldPixmap and
|
||||
* need to be copied to pNewPixmap.
|
||||
*/
|
||||
RegionRec rgnDst;
|
||||
GCPtr pGC;
|
||||
|
||||
dx = ptOldOrg.x - pWin->drawable.x;
|
||||
dy = ptOldOrg.y - pWin->drawable.y;
|
||||
RegionTranslate(prgnSrc, -dx, -dy);
|
||||
|
||||
RegionNull(&rgnDst);
|
||||
|
||||
RegionIntersect(&rgnDst,
|
||||
&pWin->borderClip, prgnSrc);
|
||||
|
||||
RegionTranslate(&rgnDst,
|
||||
-pPixmap->screen_x, -pPixmap->screen_y);
|
||||
|
||||
dx = dx + pPixmap->screen_x - cw->oldx;
|
||||
dy = dy + pPixmap->screen_y - cw->oldy;
|
||||
pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
|
||||
if (pGC)
|
||||
{
|
||||
BoxPtr pBox = RegionRects (&rgnDst);
|
||||
int nBox = RegionNumRects (&rgnDst);
|
||||
|
||||
ValidateGC(&pPixmap->drawable, pGC);
|
||||
while (nBox--)
|
||||
{
|
||||
(void) (*pGC->ops->CopyArea) (&cw->pOldPixmap->drawable,
|
||||
&pPixmap->drawable,
|
||||
pGC,
|
||||
pBox->x1 + dx, pBox->y1 + dy,
|
||||
pBox->x2 - pBox->x1,
|
||||
pBox->y2 - pBox->y1,
|
||||
pBox->x1, pBox->y1);
|
||||
pBox++;
|
||||
}
|
||||
FreeScratchGC (pGC);
|
||||
}
|
||||
RegionUninit (&rgnDst);
|
||||
return;
|
||||
}
|
||||
dx = pPixmap->screen_x - cw->oldx;
|
||||
dy = pPixmap->screen_y - cw->oldy;
|
||||
ptOldOrg.x += dx;
|
||||
ptOldOrg.y += dy;
|
||||
}
|
||||
|
||||
pScreen->CopyWindow = cs->CopyWindow;
|
||||
if (ptOldOrg.x != pWin->drawable.x || ptOldOrg.y != pWin->drawable.y)
|
||||
{
|
||||
if (dx || dy)
|
||||
RegionTranslate(prgnSrc, dx, dy);
|
||||
(*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
|
||||
if (dx || dy)
|
||||
RegionTranslate(prgnSrc, -dx, -dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptOldOrg.x -= dx;
|
||||
ptOldOrg.y -= dy;
|
||||
RegionTranslate(prgnSrc,
|
||||
pWin->drawable.x - ptOldOrg.x,
|
||||
pWin->drawable.y - ptOldOrg.y);
|
||||
DamageDamageRegion (&pWin->drawable, prgnSrc);
|
||||
}
|
||||
cs->CopyWindow = pScreen->CopyWindow;
|
||||
pScreen->CopyWindow = compCopyWindow;
|
||||
compCheckTree (pWin->drawable.pScreen);
|
||||
}
|
||||
|
||||
Bool
|
||||
compCreateWindow (WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
Bool ret;
|
||||
|
||||
pScreen->CreateWindow = cs->CreateWindow;
|
||||
ret = (*pScreen->CreateWindow) (pWin);
|
||||
if (pWin->parent && ret)
|
||||
{
|
||||
CompSubwindowsPtr csw = GetCompSubwindows (pWin->parent);
|
||||
CompClientWindowPtr ccw;
|
||||
PixmapPtr parent_pixmap = (*pScreen->GetWindowPixmap)(pWin->parent);
|
||||
PixmapPtr window_pixmap = (*pScreen->GetWindowPixmap)(pWin);
|
||||
|
||||
if (window_pixmap != parent_pixmap)
|
||||
(*pScreen->SetWindowPixmap) (pWin, parent_pixmap);
|
||||
if (csw)
|
||||
for (ccw = csw->clients; ccw; ccw = ccw->next)
|
||||
compRedirectWindow (clients[CLIENT_ID(ccw->id)],
|
||||
pWin, ccw->update);
|
||||
if (compImplicitRedirect (pWin, pWin->parent))
|
||||
compRedirectWindow (serverClient, pWin, CompositeRedirectAutomatic);
|
||||
}
|
||||
cs->CreateWindow = pScreen->CreateWindow;
|
||||
pScreen->CreateWindow = compCreateWindow;
|
||||
compCheckTree (pWin->drawable.pScreen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Bool
|
||||
compDestroyWindow (WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen (pScreen);
|
||||
CompWindowPtr cw;
|
||||
CompSubwindowsPtr csw;
|
||||
Bool ret;
|
||||
|
||||
pScreen->DestroyWindow = cs->DestroyWindow;
|
||||
while ((cw = GetCompWindow (pWin)))
|
||||
FreeResource (cw->clients->id, RT_NONE);
|
||||
while ((csw = GetCompSubwindows (pWin)))
|
||||
FreeResource (csw->clients->id, RT_NONE);
|
||||
|
||||
if (pWin->redirectDraw != RedirectDrawNone) {
|
||||
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||
|
||||
compSetParentPixmap (pWin);
|
||||
(*pScreen->DestroyPixmap) (pPixmap);
|
||||
}
|
||||
ret = (*pScreen->DestroyWindow) (pWin);
|
||||
cs->DestroyWindow = pScreen->DestroyWindow;
|
||||
pScreen->DestroyWindow = compDestroyWindow;
|
||||
/* compCheckTree (pWin->drawable.pScreen); can't check -- tree isn't good*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
compSetRedirectBorderClip (WindowPtr pWin, RegionPtr pRegion)
|
||||
{
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
RegionRec damage;
|
||||
|
||||
RegionNull(&damage);
|
||||
/*
|
||||
* Align old border clip with new border clip
|
||||
*/
|
||||
RegionTranslate(&cw->borderClip,
|
||||
pWin->drawable.x - cw->borderClipX,
|
||||
pWin->drawable.y - cw->borderClipY);
|
||||
/*
|
||||
* Compute newly visible portion of window for repaint
|
||||
*/
|
||||
RegionSubtract(&damage, pRegion, &cw->borderClip);
|
||||
/*
|
||||
* Report that as damaged so it will be redrawn
|
||||
*/
|
||||
DamageDamageRegion (&pWin->drawable, &damage);
|
||||
RegionUninit(&damage);
|
||||
/*
|
||||
* Save the new border clip region
|
||||
*/
|
||||
RegionCopy(&cw->borderClip, pRegion);
|
||||
cw->borderClipX = pWin->drawable.x;
|
||||
cw->borderClipY = pWin->drawable.y;
|
||||
}
|
||||
|
||||
RegionPtr
|
||||
compGetRedirectBorderClip (WindowPtr pWin)
|
||||
{
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
|
||||
return &cw->borderClip;
|
||||
}
|
||||
|
||||
static VisualPtr
|
||||
compGetWindowVisual (WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
VisualID vid = wVisual (pWin);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pScreen->numVisuals; i++)
|
||||
if (pScreen->visuals[i].vid == vid)
|
||||
return &pScreen->visuals[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
PictFormatPtr
|
||||
compWindowFormat (WindowPtr pWin)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
|
||||
return PictureMatchVisual (pScreen, pWin->drawable.depth,
|
||||
compGetWindowVisual (pWin));
|
||||
}
|
||||
|
||||
static void
|
||||
compWindowUpdateAutomatic (WindowPtr pWin)
|
||||
{
|
||||
CompWindowPtr cw = GetCompWindow (pWin);
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
WindowPtr pParent = pWin->parent;
|
||||
PixmapPtr pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
||||
PictFormatPtr pSrcFormat = compWindowFormat (pWin);
|
||||
PictFormatPtr pDstFormat = compWindowFormat (pWin->parent);
|
||||
int error;
|
||||
RegionPtr pRegion = DamageRegion (cw->damage);
|
||||
PicturePtr pSrcPicture = CreatePicture (0, &pSrcPixmap->drawable,
|
||||
pSrcFormat,
|
||||
0, 0,
|
||||
serverClient,
|
||||
&error);
|
||||
XID subwindowMode = IncludeInferiors;
|
||||
PicturePtr pDstPicture = CreatePicture (0, &pParent->drawable,
|
||||
pDstFormat,
|
||||
CPSubwindowMode,
|
||||
&subwindowMode,
|
||||
serverClient,
|
||||
&error);
|
||||
|
||||
/*
|
||||
* First move the region from window to screen coordinates
|
||||
*/
|
||||
RegionTranslate(pRegion,
|
||||
pWin->drawable.x, pWin->drawable.y);
|
||||
|
||||
/*
|
||||
* Clip against the "real" border clip
|
||||
*/
|
||||
RegionIntersect(pRegion, pRegion, &cw->borderClip);
|
||||
|
||||
/*
|
||||
* Now translate from screen to dest coordinates
|
||||
*/
|
||||
RegionTranslate(pRegion,
|
||||
-pParent->drawable.x, -pParent->drawable.y);
|
||||
|
||||
/*
|
||||
* Clip the picture
|
||||
*/
|
||||
SetPictureClipRegion (pDstPicture, 0, 0, pRegion);
|
||||
|
||||
/*
|
||||
* And paint
|
||||
*/
|
||||
CompositePicture (PictOpSrc,
|
||||
pSrcPicture,
|
||||
0,
|
||||
pDstPicture,
|
||||
0, 0, /* src_x, src_y */
|
||||
0, 0, /* msk_x, msk_y */
|
||||
pSrcPixmap->screen_x - pParent->drawable.x,
|
||||
pSrcPixmap->screen_y - pParent->drawable.y,
|
||||
pSrcPixmap->drawable.width,
|
||||
pSrcPixmap->drawable.height);
|
||||
FreePicture (pSrcPicture, 0);
|
||||
FreePicture (pDstPicture, 0);
|
||||
/*
|
||||
* Empty the damage region. This has the nice effect of
|
||||
* rendering the translations above harmless
|
||||
*/
|
||||
DamageEmpty (cw->damage);
|
||||
}
|
||||
|
||||
static void
|
||||
compPaintWindowToParent(WindowPtr pWin)
|
||||
{
|
||||
compPaintChildrenToWindow(pWin->drawable.pScreen, pWin);
|
||||
|
||||
if (pWin->redirectDraw != RedirectDrawNone) {
|
||||
CompWindowPtr cw = GetCompWindow(pWin);
|
||||
|
||||
if (cw->damaged) {
|
||||
compWindowUpdateAutomatic(pWin);
|
||||
cw->damaged = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
compPaintChildrenToWindow(ScreenPtr pScreen, WindowPtr pWin)
|
||||
{
|
||||
WindowPtr pChild;
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
|
||||
if (!cs->damaged)
|
||||
return;
|
||||
|
||||
for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
|
||||
compPaintWindowToParent(pChild);
|
||||
|
||||
cs->damaged = FALSE;
|
||||
}
|
||||
|
||||
WindowPtr
|
||||
CompositeRealChildHead(WindowPtr pWin)
|
||||
{
|
||||
WindowPtr pChild, pChildBefore;
|
||||
CompScreenPtr cs;
|
||||
|
||||
if (!pWin->parent &&
|
||||
(screenIsSaved == SCREEN_SAVER_ON) &&
|
||||
(HasSaverWindow(pWin->drawable.pScreen->myNum))) {
|
||||
|
||||
/* First child is the screen saver; see if next child is the overlay */
|
||||
pChildBefore = pWin->firstChild;
|
||||
pChild = pChildBefore->nextSib;
|
||||
|
||||
}
|
||||
else {
|
||||
pChildBefore = NullWindow;
|
||||
pChild = pWin->firstChild;
|
||||
}
|
||||
|
||||
if (!pChild) {
|
||||
return NullWindow;
|
||||
}
|
||||
|
||||
cs = GetCompScreen(pWin->drawable.pScreen);
|
||||
if (pChild == cs->pOverlayWin) {
|
||||
return pChild;
|
||||
}
|
||||
else {
|
||||
return pChildBefore;
|
||||
}
|
||||
}
|
||||
|
||||
/* ConfigNotify not implemented... replace with the old pixmap reallocation algorithm... */
|
||||
/*
|
||||
int
|
||||
compConfigNotify(WindowPtr pWin, int x, int y, int w, int h,
|
||||
int bw, WindowPtr pSib)
|
||||
{
|
||||
ScreenPtr pScreen = pWin->drawable.pScreen;
|
||||
CompScreenPtr cs = GetCompScreen(pScreen);
|
||||
Bool ret = 0;
|
||||
WindowPtr pParent = pWin->parent;
|
||||
int draw_x, draw_y;
|
||||
Bool alloc_ret;
|
||||
|
||||
if (cs->ConfigNotify) {
|
||||
pScreen->ConfigNotify = cs->ConfigNotify;
|
||||
ret = (*pScreen->ConfigNotify) (pWin, x, y, w, h, bw, pSib);
|
||||
cs->ConfigNotify = pScreen->ConfigNotify;
|
||||
pScreen->ConfigNotify = compConfigNotify;
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (pWin->redirectDraw == RedirectDrawNone)
|
||||
return Success;
|
||||
|
||||
compCheckTree(pScreen);
|
||||
|
||||
draw_x = pParent->drawable.x + x + bw;
|
||||
draw_y = pParent->drawable.y + y + bw;
|
||||
alloc_ret = compReallocPixmap(pWin, draw_x, draw_y, w, h, bw);
|
||||
|
||||
if (alloc_ret == FALSE)
|
||||
return BadAlloc;
|
||||
return Success;
|
||||
}
|
||||
*/
|
||||
Reference in New Issue
Block a user