244 lines
6.2 KiB
C
244 lines
6.2 KiB
C
|
|
#include <dix-config.h>
|
|
|
|
#include <X11/X.h>
|
|
|
|
#include "dix/cursor_priv.h"
|
|
#include "mi/mi_priv.h"
|
|
|
|
#include "scrnintstr.h"
|
|
#include <X11/extensions/shapeproto.h>
|
|
#include "validate.h"
|
|
#include "windowstr.h"
|
|
#include "gcstruct.h"
|
|
#include "regionstr.h"
|
|
#include "privates.h"
|
|
#include "mivalidate.h"
|
|
#include "mioverlay.h"
|
|
#include "migc.h"
|
|
|
|
#include "globals.h"
|
|
|
|
typedef struct {
|
|
RegionRec exposed;
|
|
RegionRec borderExposed;
|
|
RegionPtr borderVisible;
|
|
DDXPointRec oldAbsCorner;
|
|
} miOverlayValDataRec, *miOverlayValDataPtr;
|
|
|
|
typedef struct _TreeRec {
|
|
WindowPtr pWin;
|
|
struct _TreeRec *parent;
|
|
struct _TreeRec *firstChild;
|
|
struct _TreeRec *lastChild;
|
|
struct _TreeRec *prevSib;
|
|
struct _TreeRec *nextSib;
|
|
RegionRec borderClip;
|
|
RegionRec clipList;
|
|
unsigned visibility;
|
|
miOverlayValDataPtr valdata;
|
|
} miOverlayTreeRec, *miOverlayTreePtr;
|
|
|
|
typedef struct {
|
|
miOverlayTreePtr tree;
|
|
} miOverlayWindowRec, *miOverlayWindowPtr;
|
|
|
|
typedef struct {
|
|
CloseScreenProcPtr CloseScreen;
|
|
CreateWindowProcPtr CreateWindow;
|
|
DestroyWindowProcPtr DestroyWindow;
|
|
UnrealizeWindowProcPtr UnrealizeWindow;
|
|
RealizeWindowProcPtr RealizeWindow;
|
|
miOverlayTransFunc MakeTransparent;
|
|
miOverlayInOverlayFunc InOverlay;
|
|
Bool underlayMarked;
|
|
Bool copyUnderlay;
|
|
} miOverlayScreenRec, *miOverlayScreenPtr;
|
|
|
|
static DevPrivateKeyRec miOverlayWindowKeyRec;
|
|
|
|
#define miOverlayWindowKey (&miOverlayWindowKeyRec)
|
|
static DevPrivateKeyRec miOverlayScreenKeyRec;
|
|
|
|
#define miOverlayScreenKey (&miOverlayScreenKeyRec)
|
|
|
|
static void MarkUnderlayWindow(WindowPtr);
|
|
static Bool CollectUnderlayChildrenRegions(WindowPtr, RegionPtr);
|
|
|
|
#define MIOVERLAY_GET_SCREEN_PRIVATE(pScreen) ((miOverlayScreenPtr) \
|
|
dixLookupPrivate(&(pScreen)->devPrivates, miOverlayScreenKey))
|
|
#define MIOVERLAY_GET_WINDOW_PRIVATE(pWin) ((miOverlayWindowPtr) \
|
|
dixLookupPrivate(&(pWin)->devPrivates, miOverlayWindowKey))
|
|
#define MIOVERLAY_GET_WINDOW_TREE(pWin) \
|
|
(MIOVERLAY_GET_WINDOW_PRIVATE(pWin)->tree)
|
|
|
|
#define MARK_UNDERLAY(w) MarkUnderlayWindow(w)
|
|
|
|
/* We need this as an addition since the xf86 common code doesn't
|
|
know about the second tree which is static to this file. */
|
|
|
|
void
|
|
miOverlaySetRootClip(ScreenPtr pScreen, Bool enable)
|
|
{
|
|
WindowPtr pRoot = pScreen->root;
|
|
miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pRoot);
|
|
|
|
MARK_UNDERLAY(pRoot);
|
|
|
|
if (enable) {
|
|
BoxRec box;
|
|
|
|
box.x1 = 0;
|
|
box.y1 = 0;
|
|
box.x2 = pScreen->width;
|
|
box.y2 = pScreen->height;
|
|
|
|
RegionReset(&pTree->borderClip, &box);
|
|
}
|
|
else
|
|
RegionEmpty(&pTree->borderClip);
|
|
|
|
RegionBreak(&pTree->clipList);
|
|
}
|
|
|
|
/****************************************************************/
|
|
|
|
void
|
|
miOverlaySetTransFunction(ScreenPtr pScreen, miOverlayTransFunc transFunc)
|
|
{
|
|
MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->MakeTransparent = transFunc;
|
|
}
|
|
|
|
Bool
|
|
miOverlayCopyUnderlay(ScreenPtr pScreen)
|
|
{
|
|
return MIOVERLAY_GET_SCREEN_PRIVATE(pScreen)->copyUnderlay;
|
|
}
|
|
|
|
void
|
|
miOverlayComputeCompositeClip(GCPtr pGC, WindowPtr pWin)
|
|
{
|
|
miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
|
|
RegionPtr pregWin;
|
|
Bool freeTmpClip, freeCompClip;
|
|
|
|
if (!pTree) {
|
|
miComputeCompositeClip(pGC, &pWin->drawable);
|
|
return;
|
|
}
|
|
|
|
if (pGC->subWindowMode == IncludeInferiors) {
|
|
pregWin = RegionCreate(NullBox, 1);
|
|
freeTmpClip = TRUE;
|
|
if (pWin->parent || (screenIsSaved != SCREEN_SAVER_ON) ||
|
|
!HasSaverWindow(pGC->pScreen)) {
|
|
RegionIntersect(pregWin, &pTree->borderClip, &pWin->winSize);
|
|
}
|
|
}
|
|
else {
|
|
pregWin = &pTree->clipList;
|
|
freeTmpClip = FALSE;
|
|
}
|
|
freeCompClip = pGC->freeCompClip;
|
|
if (!pGC->clientClip) {
|
|
if (freeCompClip)
|
|
RegionDestroy(pGC->pCompositeClip);
|
|
pGC->pCompositeClip = pregWin;
|
|
pGC->freeCompClip = freeTmpClip;
|
|
}
|
|
else {
|
|
RegionTranslate(pGC->clientClip,
|
|
pWin->drawable.x + pGC->clipOrg.x,
|
|
pWin->drawable.y + pGC->clipOrg.y);
|
|
|
|
if (freeCompClip) {
|
|
RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
|
|
if (freeTmpClip)
|
|
RegionDestroy(pregWin);
|
|
}
|
|
else if (freeTmpClip) {
|
|
RegionIntersect(pregWin, pregWin, pGC->clientClip);
|
|
pGC->pCompositeClip = pregWin;
|
|
}
|
|
else {
|
|
pGC->pCompositeClip = RegionCreate(NullBox, 0);
|
|
RegionIntersect(pGC->pCompositeClip, pregWin, pGC->clientClip);
|
|
}
|
|
pGC->freeCompClip = TRUE;
|
|
RegionTranslate(pGC->clientClip,
|
|
-(pWin->drawable.x + pGC->clipOrg.x),
|
|
-(pWin->drawable.y + pGC->clipOrg.y));
|
|
}
|
|
}
|
|
|
|
Bool
|
|
miOverlayCollectUnderlayRegions(WindowPtr pWin, RegionPtr *region)
|
|
{
|
|
miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
|
|
|
|
if (pTree) {
|
|
*region = &pTree->borderClip;
|
|
return FALSE;
|
|
}
|
|
|
|
*region = RegionCreate(NullBox, 0);
|
|
|
|
CollectUnderlayChildrenRegions(pWin, *region);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
CollectUnderlayChildrenRegions(WindowPtr pWin, RegionPtr pReg)
|
|
{
|
|
WindowPtr pChild;
|
|
miOverlayTreePtr pTree;
|
|
Bool hasUnderlay;
|
|
|
|
if (!(pChild = pWin->firstChild))
|
|
return FALSE;
|
|
|
|
hasUnderlay = FALSE;
|
|
|
|
while (1) {
|
|
if ((pTree = MIOVERLAY_GET_WINDOW_TREE(pChild))) {
|
|
RegionAppend(pReg, &pTree->borderClip);
|
|
hasUnderlay = TRUE;
|
|
}
|
|
else if (pChild->firstChild) {
|
|
pChild = pChild->firstChild;
|
|
continue;
|
|
}
|
|
|
|
while (!pChild->nextSib && (pWin != pChild))
|
|
pChild = pChild->parent;
|
|
|
|
if (pChild == pWin)
|
|
break;
|
|
|
|
pChild = pChild->nextSib;
|
|
}
|
|
|
|
if (hasUnderlay) {
|
|
Bool overlap;
|
|
|
|
RegionValidate(pReg, &overlap);
|
|
}
|
|
|
|
return hasUnderlay;
|
|
}
|
|
|
|
static void
|
|
MarkUnderlayWindow(WindowPtr pWin)
|
|
{
|
|
miOverlayTreePtr pTree = MIOVERLAY_GET_WINDOW_TREE(pWin);
|
|
|
|
if (pTree->valdata)
|
|
return;
|
|
pTree->valdata =
|
|
(miOverlayValDataPtr) XNFalloc(sizeof(miOverlayValDataRec));
|
|
pTree->valdata->oldAbsCorner.x = pWin->drawable.x;
|
|
pTree->valdata->oldAbsCorner.y = pWin->drawable.y;
|
|
pTree->valdata->borderVisible = NullRegion;
|
|
}
|