953 lines
27 KiB
C
953 lines
27 KiB
C
/*
|
|
* 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"
|
|
#include "xace.h"
|
|
#include "protocol-versions.h"
|
|
#include "extinit.h"
|
|
|
|
static CARD8 CompositeReqCode;
|
|
static DevPrivateKeyRec CompositeClientPrivateKeyRec;
|
|
|
|
#define CompositeClientPrivateKey (&CompositeClientPrivateKeyRec)
|
|
RESTYPE CompositeClientWindowType;
|
|
RESTYPE CompositeClientSubwindowsType;
|
|
RESTYPE CompositeClientOverlayType;
|
|
|
|
typedef struct _CompositeClient {
|
|
int major_version;
|
|
int minor_version;
|
|
} CompositeClientRec, *CompositeClientPtr;
|
|
|
|
#define GetCompositeClient(pClient) ((CompositeClientPtr) \
|
|
dixLookupPrivate(&(pClient)->devPrivates, CompositeClientPrivateKey))
|
|
|
|
static void
|
|
CompositeClientCallback(CallbackListPtr *list, void *closure, void *data)
|
|
{
|
|
NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
|
|
ClientPtr pClient = clientinfo->client;
|
|
CompositeClientPtr pCompositeClient = GetCompositeClient(pClient);
|
|
|
|
pCompositeClient->major_version = 0;
|
|
pCompositeClient->minor_version = 0;
|
|
}
|
|
|
|
static int
|
|
FreeCompositeClientWindow(void *value, XID ccwid)
|
|
{
|
|
WindowPtr pWin = value;
|
|
|
|
compFreeClientWindow(pWin, ccwid);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
FreeCompositeClientSubwindows(void *value, XID ccwid)
|
|
{
|
|
WindowPtr pWin = value;
|
|
|
|
compFreeClientSubwindows(pWin, ccwid);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
FreeCompositeClientOverlay(void *value, XID ccwid)
|
|
{
|
|
CompOverlayClientPtr pOc = (CompOverlayClientPtr) value;
|
|
|
|
compFreeOverlayClient(pOc);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcCompositeQueryVersion(ClientPtr client)
|
|
{
|
|
CompositeClientPtr pCompositeClient = GetCompositeClient(client);
|
|
xCompositeQueryVersionReply rep = {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = 0
|
|
};
|
|
|
|
REQUEST(xCompositeQueryVersionReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
|
|
if (stuff->majorVersion < SERVER_COMPOSITE_MAJOR_VERSION) {
|
|
rep.majorVersion = stuff->majorVersion;
|
|
rep.minorVersion = stuff->minorVersion;
|
|
}
|
|
else {
|
|
rep.majorVersion = SERVER_COMPOSITE_MAJOR_VERSION;
|
|
rep.minorVersion = SERVER_COMPOSITE_MINOR_VERSION;
|
|
}
|
|
pCompositeClient->major_version = rep.majorVersion;
|
|
pCompositeClient->minor_version = rep.minorVersion;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.majorVersion);
|
|
swapl(&rep.minorVersion);
|
|
}
|
|
WriteToClient(client, sizeof(xCompositeQueryVersionReply), &rep);
|
|
return Success;
|
|
}
|
|
|
|
#define VERIFY_WINDOW(pWindow, wid, client, mode) \
|
|
do { \
|
|
int err; \
|
|
err = dixLookupResourceByType((void **) &pWindow, wid, \
|
|
RT_WINDOW, client, mode); \
|
|
if (err != Success) { \
|
|
client->errorValue = wid; \
|
|
return err; \
|
|
} \
|
|
} while (0)
|
|
|
|
static int
|
|
ProcCompositeRedirectWindow(ClientPtr client)
|
|
{
|
|
WindowPtr pWin;
|
|
|
|
REQUEST(xCompositeRedirectWindowReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
|
|
VERIFY_WINDOW(pWin, stuff->window, client,
|
|
DixSetAttrAccess | DixManageAccess | DixBlendAccess);
|
|
|
|
return compRedirectWindow(client, pWin, stuff->update);
|
|
}
|
|
|
|
static int
|
|
ProcCompositeRedirectSubwindows(ClientPtr client)
|
|
{
|
|
WindowPtr pWin;
|
|
|
|
REQUEST(xCompositeRedirectSubwindowsReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
|
|
VERIFY_WINDOW(pWin, stuff->window, client,
|
|
DixSetAttrAccess | DixManageAccess | DixBlendAccess);
|
|
|
|
return compRedirectSubwindows(client, pWin, stuff->update);
|
|
}
|
|
|
|
static int
|
|
ProcCompositeUnredirectWindow(ClientPtr client)
|
|
{
|
|
WindowPtr pWin;
|
|
|
|
REQUEST(xCompositeUnredirectWindowReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
|
|
VERIFY_WINDOW(pWin, stuff->window, client,
|
|
DixSetAttrAccess | DixManageAccess | DixBlendAccess);
|
|
|
|
return compUnredirectWindow(client, pWin, stuff->update);
|
|
}
|
|
|
|
static int
|
|
ProcCompositeUnredirectSubwindows(ClientPtr client)
|
|
{
|
|
WindowPtr pWin;
|
|
|
|
REQUEST(xCompositeUnredirectSubwindowsReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
|
|
VERIFY_WINDOW(pWin, stuff->window, client,
|
|
DixSetAttrAccess | DixManageAccess | DixBlendAccess);
|
|
|
|
return compUnredirectSubwindows(client, pWin, stuff->update);
|
|
}
|
|
|
|
static int
|
|
ProcCompositeCreateRegionFromBorderClip(ClientPtr client)
|
|
{
|
|
WindowPtr pWin;
|
|
CompWindowPtr cw;
|
|
RegionPtr pBorderClip, pRegion;
|
|
|
|
REQUEST(xCompositeCreateRegionFromBorderClipReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
|
|
VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
|
|
LEGAL_NEW_RESOURCE(stuff->region, client);
|
|
|
|
cw = GetCompWindow(pWin);
|
|
if (cw)
|
|
pBorderClip = &cw->borderClip;
|
|
else
|
|
pBorderClip = &pWin->borderClip;
|
|
pRegion = XFixesRegionCopy(pBorderClip);
|
|
if (!pRegion)
|
|
return BadAlloc;
|
|
RegionTranslate(pRegion, -pWin->drawable.x, -pWin->drawable.y);
|
|
|
|
if (!AddResource(stuff->region, RegionResType, (void *) pRegion))
|
|
return BadAlloc;
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcCompositeNameWindowPixmap(ClientPtr client)
|
|
{
|
|
WindowPtr pWin;
|
|
CompWindowPtr cw;
|
|
PixmapPtr pPixmap;
|
|
ScreenPtr pScreen;
|
|
int rc;
|
|
|
|
REQUEST(xCompositeNameWindowPixmapReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
|
|
VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
|
|
|
|
pScreen = pWin->drawable.pScreen;
|
|
|
|
if (!pWin->viewable)
|
|
return BadMatch;
|
|
|
|
LEGAL_NEW_RESOURCE(stuff->pixmap, client);
|
|
|
|
cw = GetCompWindow(pWin);
|
|
if (!cw)
|
|
return BadMatch;
|
|
|
|
pPixmap = (*pScreen->GetWindowPixmap) (pWin);
|
|
if (!pPixmap)
|
|
return BadMatch;
|
|
|
|
/* security creation/labeling check */
|
|
rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
|
|
pPixmap, RT_WINDOW, pWin, DixCreateAccess);
|
|
if (rc != Success)
|
|
return rc;
|
|
|
|
++pPixmap->refcnt;
|
|
|
|
if (!AddResource(stuff->pixmap, RT_PIXMAP, (void *) pPixmap))
|
|
return BadAlloc;
|
|
|
|
if (pScreen->NameWindowPixmap) {
|
|
rc = pScreen->NameWindowPixmap(pWin, pPixmap, stuff->pixmap);
|
|
if (rc != Success) {
|
|
FreeResource(stuff->pixmap, RT_NONE);
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcCompositeGetOverlayWindow(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeGetOverlayWindowReq);
|
|
xCompositeGetOverlayWindowReply rep;
|
|
WindowPtr pWin;
|
|
ScreenPtr pScreen;
|
|
CompScreenPtr cs;
|
|
CompOverlayClientPtr pOc;
|
|
int rc;
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
|
|
VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
|
|
pScreen = pWin->drawable.pScreen;
|
|
|
|
/*
|
|
* Create an OverlayClient structure to mark this client's
|
|
* interest in the overlay window
|
|
*/
|
|
pOc = compCreateOverlayClient(pScreen, client);
|
|
if (pOc == NULL)
|
|
return BadAlloc;
|
|
|
|
/*
|
|
* Make sure the overlay window exists
|
|
*/
|
|
cs = GetCompScreen(pScreen);
|
|
if (cs->pOverlayWin == NULL)
|
|
if (!compCreateOverlayWindow(pScreen)) {
|
|
FreeResource(pOc->resource, RT_NONE);
|
|
return BadAlloc;
|
|
}
|
|
|
|
rc = XaceHook(XACE_RESOURCE_ACCESS, client, cs->pOverlayWin->drawable.id,
|
|
RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL, DixGetAttrAccess);
|
|
if (rc != Success) {
|
|
FreeResource(pOc->resource, RT_NONE);
|
|
return rc;
|
|
}
|
|
|
|
rep = (xCompositeGetOverlayWindowReply) {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = 0,
|
|
.overlayWin = cs->pOverlayWin->drawable.id
|
|
};
|
|
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.overlayWin);
|
|
}
|
|
WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcCompositeReleaseOverlayWindow(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeReleaseOverlayWindowReq);
|
|
WindowPtr pWin;
|
|
CompOverlayClientPtr pOc;
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
|
|
VERIFY_WINDOW(pWin, stuff->window, client, DixGetAttrAccess);
|
|
|
|
/*
|
|
* Has client queried a reference to the overlay window
|
|
* on this screen? If not, generate an error.
|
|
*/
|
|
pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
|
|
if (pOc == NULL)
|
|
return BadMatch;
|
|
|
|
/* The delete function will free the client structure */
|
|
FreeResource(pOc->resource, RT_NONE);
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int (*ProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = {
|
|
ProcCompositeQueryVersion,
|
|
ProcCompositeRedirectWindow,
|
|
ProcCompositeRedirectSubwindows,
|
|
ProcCompositeUnredirectWindow,
|
|
ProcCompositeUnredirectSubwindows,
|
|
ProcCompositeCreateRegionFromBorderClip,
|
|
ProcCompositeNameWindowPixmap,
|
|
ProcCompositeGetOverlayWindow, ProcCompositeReleaseOverlayWindow,};
|
|
|
|
static int
|
|
ProcCompositeDispatch(ClientPtr client)
|
|
{
|
|
REQUEST(xReq);
|
|
|
|
if (stuff->data < CompositeNumberRequests)
|
|
return (*ProcCompositeVector[stuff->data]) (client);
|
|
else
|
|
return BadRequest;
|
|
}
|
|
|
|
static int
|
|
SProcCompositeQueryVersion(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeQueryVersionReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xCompositeQueryVersionReq);
|
|
swapl(&stuff->majorVersion);
|
|
swapl(&stuff->minorVersion);
|
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
|
}
|
|
|
|
static int
|
|
SProcCompositeRedirectWindow(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeRedirectWindowReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
|
|
swapl(&stuff->window);
|
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
|
}
|
|
|
|
static int
|
|
SProcCompositeRedirectSubwindows(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeRedirectSubwindowsReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
|
|
swapl(&stuff->window);
|
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
|
}
|
|
|
|
static int
|
|
SProcCompositeUnredirectWindow(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeUnredirectWindowReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
|
|
swapl(&stuff->window);
|
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
|
}
|
|
|
|
static int
|
|
SProcCompositeUnredirectSubwindows(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeUnredirectSubwindowsReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
|
|
swapl(&stuff->window);
|
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
|
}
|
|
|
|
static int
|
|
SProcCompositeCreateRegionFromBorderClip(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeCreateRegionFromBorderClipReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xCompositeCreateRegionFromBorderClipReq);
|
|
swapl(&stuff->region);
|
|
swapl(&stuff->window);
|
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
|
}
|
|
|
|
static int
|
|
SProcCompositeNameWindowPixmap(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeNameWindowPixmapReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
|
|
swapl(&stuff->window);
|
|
swapl(&stuff->pixmap);
|
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
|
}
|
|
|
|
static int
|
|
SProcCompositeGetOverlayWindow(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeGetOverlayWindowReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
|
|
swapl(&stuff->window);
|
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
|
}
|
|
|
|
static int
|
|
SProcCompositeReleaseOverlayWindow(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeReleaseOverlayWindowReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
|
|
swapl(&stuff->window);
|
|
return (*ProcCompositeVector[stuff->compositeReqType]) (client);
|
|
}
|
|
|
|
static int (*SProcCompositeVector[CompositeNumberRequests]) (ClientPtr) = {
|
|
SProcCompositeQueryVersion,
|
|
SProcCompositeRedirectWindow,
|
|
SProcCompositeRedirectSubwindows,
|
|
SProcCompositeUnredirectWindow,
|
|
SProcCompositeUnredirectSubwindows,
|
|
SProcCompositeCreateRegionFromBorderClip,
|
|
SProcCompositeNameWindowPixmap,
|
|
SProcCompositeGetOverlayWindow, SProcCompositeReleaseOverlayWindow,};
|
|
|
|
static int
|
|
SProcCompositeDispatch(ClientPtr client)
|
|
{
|
|
REQUEST(xReq);
|
|
|
|
if (stuff->data < CompositeNumberRequests)
|
|
return (*SProcCompositeVector[stuff->data]) (client);
|
|
else
|
|
return BadRequest;
|
|
}
|
|
|
|
/** @see GetDefaultBytes */
|
|
static void
|
|
GetCompositeClientWindowBytes(void *value, XID id, ResourceSizePtr size)
|
|
{
|
|
WindowPtr window = value;
|
|
|
|
/* Currently only pixmap bytes are reported to clients. */
|
|
size->resourceSize = 0;
|
|
|
|
/* Calculate pixmap reference sizes. */
|
|
size->pixmapRefSize = 0;
|
|
if (window->redirectDraw != RedirectDrawNone)
|
|
{
|
|
SizeType pixmapSizeFunc = GetResourceTypeSizeFunc(RT_PIXMAP);
|
|
ResourceSizeRec pixmapSize = { 0, 0 };
|
|
ScreenPtr screen = window->drawable.pScreen;
|
|
PixmapPtr pixmap = screen->GetWindowPixmap(window);
|
|
pixmapSizeFunc(pixmap, pixmap->drawable.id, &pixmapSize);
|
|
size->pixmapRefSize += pixmapSize.pixmapRefSize;
|
|
}
|
|
}
|
|
|
|
void
|
|
CompositeExtensionInit(void)
|
|
{
|
|
ExtensionEntry *extEntry;
|
|
int s;
|
|
|
|
/* Assume initialization is going to fail */
|
|
noCompositeExtension = TRUE;
|
|
|
|
for (s = 0; s < screenInfo.numScreens; s++) {
|
|
ScreenPtr pScreen = screenInfo.screens[s];
|
|
VisualPtr vis;
|
|
|
|
/* Composite on 8bpp pseudocolor root windows appears to fail, so
|
|
* just disable it on anything pseudocolor for safety.
|
|
*/
|
|
for (vis = pScreen->visuals; vis->vid != pScreen->rootVisual; vis++);
|
|
if ((vis->class | DynamicClass) == PseudoColor)
|
|
return;
|
|
|
|
/* Ensure that Render is initialized, which is required for automatic
|
|
* compositing.
|
|
*/
|
|
if (GetPictureScreenIfSet(pScreen) == NULL)
|
|
return;
|
|
}
|
|
|
|
CompositeClientWindowType = CreateNewResourceType
|
|
(FreeCompositeClientWindow, "CompositeClientWindow");
|
|
if (!CompositeClientWindowType)
|
|
return;
|
|
|
|
SetResourceTypeSizeFunc(CompositeClientWindowType,
|
|
GetCompositeClientWindowBytes);
|
|
|
|
CompositeClientSubwindowsType = CreateNewResourceType
|
|
(FreeCompositeClientSubwindows, "CompositeClientSubwindows");
|
|
if (!CompositeClientSubwindowsType)
|
|
return;
|
|
|
|
CompositeClientOverlayType = CreateNewResourceType
|
|
(FreeCompositeClientOverlay, "CompositeClientOverlay");
|
|
if (!CompositeClientOverlayType)
|
|
return;
|
|
|
|
if (!dixRegisterPrivateKey(&CompositeClientPrivateKeyRec, PRIVATE_CLIENT,
|
|
sizeof(CompositeClientRec)))
|
|
return;
|
|
|
|
if (!AddCallback(&ClientStateCallback, CompositeClientCallback, 0))
|
|
return;
|
|
|
|
for (s = 0; s < screenInfo.numScreens; s++)
|
|
if (!compScreenInit(screenInfo.screens[s]))
|
|
return;
|
|
|
|
extEntry = AddExtension(COMPOSITE_NAME, 0, 0,
|
|
ProcCompositeDispatch, SProcCompositeDispatch,
|
|
NULL, StandardMinorOpcode);
|
|
if (!extEntry)
|
|
return;
|
|
CompositeReqCode = (CARD8) extEntry->base;
|
|
|
|
/* Initialization succeeded */
|
|
noCompositeExtension = FALSE;
|
|
}
|
|
|
|
#ifdef PANORAMIX
|
|
#include "panoramiXsrv.h"
|
|
|
|
int (*PanoramiXSaveCompositeVector[CompositeNumberRequests]) (ClientPtr);
|
|
|
|
static int
|
|
PanoramiXCompositeRedirectWindow(ClientPtr client)
|
|
{
|
|
PanoramiXRes *win;
|
|
int rc = 0, j;
|
|
|
|
REQUEST(xCompositeRedirectWindowReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeRedirectWindowReq);
|
|
|
|
if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
|
|
client, DixUnknownAccess))) {
|
|
client->errorValue = stuff->window;
|
|
return rc;
|
|
}
|
|
|
|
FOR_NSCREENS_FORWARD(j) {
|
|
stuff->window = win->info[j].id;
|
|
rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
|
|
if (rc != Success)
|
|
break;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static int
|
|
PanoramiXCompositeRedirectSubwindows(ClientPtr client)
|
|
{
|
|
PanoramiXRes *win;
|
|
int rc = 0, j;
|
|
|
|
REQUEST(xCompositeRedirectSubwindowsReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeRedirectSubwindowsReq);
|
|
|
|
if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
|
|
client, DixUnknownAccess))) {
|
|
client->errorValue = stuff->window;
|
|
return rc;
|
|
}
|
|
|
|
FOR_NSCREENS_FORWARD(j) {
|
|
stuff->window = win->info[j].id;
|
|
rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
|
|
if (rc != Success)
|
|
break;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static int
|
|
PanoramiXCompositeUnredirectWindow(ClientPtr client)
|
|
{
|
|
PanoramiXRes *win;
|
|
int rc = 0, j;
|
|
|
|
REQUEST(xCompositeUnredirectWindowReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeUnredirectWindowReq);
|
|
|
|
if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
|
|
client, DixUnknownAccess))) {
|
|
client->errorValue = stuff->window;
|
|
return rc;
|
|
}
|
|
|
|
FOR_NSCREENS_FORWARD(j) {
|
|
stuff->window = win->info[j].id;
|
|
rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
|
|
if (rc != Success)
|
|
break;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static int
|
|
PanoramiXCompositeUnredirectSubwindows(ClientPtr client)
|
|
{
|
|
PanoramiXRes *win;
|
|
int rc = 0, j;
|
|
|
|
REQUEST(xCompositeUnredirectSubwindowsReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeUnredirectSubwindowsReq);
|
|
|
|
if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
|
|
client, DixUnknownAccess))) {
|
|
client->errorValue = stuff->window;
|
|
return rc;
|
|
}
|
|
|
|
FOR_NSCREENS_FORWARD(j) {
|
|
stuff->window = win->info[j].id;
|
|
rc = (*PanoramiXSaveCompositeVector[stuff->compositeReqType]) (client);
|
|
if (rc != Success)
|
|
break;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static int
|
|
PanoramiXCompositeNameWindowPixmap(ClientPtr client)
|
|
{
|
|
WindowPtr pWin;
|
|
CompWindowPtr cw;
|
|
PixmapPtr pPixmap;
|
|
int rc;
|
|
PanoramiXRes *win, *newPix;
|
|
int i;
|
|
|
|
REQUEST(xCompositeNameWindowPixmapReq);
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeNameWindowPixmapReq);
|
|
|
|
if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
|
|
client, DixUnknownAccess))) {
|
|
client->errorValue = stuff->window;
|
|
return rc;
|
|
}
|
|
|
|
LEGAL_NEW_RESOURCE(stuff->pixmap, client);
|
|
|
|
if (!(newPix = malloc(sizeof(PanoramiXRes))))
|
|
return BadAlloc;
|
|
|
|
newPix->type = XRT_PIXMAP;
|
|
newPix->u.pix.shared = FALSE;
|
|
panoramix_setup_ids(newPix, client, stuff->pixmap);
|
|
|
|
FOR_NSCREENS(i) {
|
|
rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
|
|
RT_WINDOW, client, DixGetAttrAccess);
|
|
if (rc != Success) {
|
|
client->errorValue = stuff->window;
|
|
free(newPix);
|
|
return rc;
|
|
}
|
|
|
|
if (!pWin->viewable) {
|
|
free(newPix);
|
|
return BadMatch;
|
|
}
|
|
|
|
cw = GetCompWindow(pWin);
|
|
if (!cw) {
|
|
free(newPix);
|
|
return BadMatch;
|
|
}
|
|
|
|
pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
|
|
if (!pPixmap) {
|
|
free(newPix);
|
|
return BadMatch;
|
|
}
|
|
|
|
if (!AddResource(newPix->info[i].id, RT_PIXMAP, (void *) pPixmap))
|
|
return BadAlloc;
|
|
|
|
++pPixmap->refcnt;
|
|
}
|
|
|
|
if (!AddResource(stuff->pixmap, XRT_PIXMAP, (void *) newPix))
|
|
return BadAlloc;
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
PanoramiXCompositeGetOverlayWindow(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeGetOverlayWindowReq);
|
|
xCompositeGetOverlayWindowReply rep;
|
|
WindowPtr pWin;
|
|
ScreenPtr pScreen;
|
|
CompScreenPtr cs;
|
|
CompOverlayClientPtr pOc;
|
|
int rc;
|
|
PanoramiXRes *win, *overlayWin = NULL;
|
|
int i;
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeGetOverlayWindowReq);
|
|
|
|
if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
|
|
client, DixUnknownAccess))) {
|
|
client->errorValue = stuff->window;
|
|
return rc;
|
|
}
|
|
|
|
cs = GetCompScreen(screenInfo.screens[0]);
|
|
if (!cs->pOverlayWin) {
|
|
if (!(overlayWin = malloc(sizeof(PanoramiXRes))))
|
|
return BadAlloc;
|
|
|
|
overlayWin->type = XRT_WINDOW;
|
|
overlayWin->u.win.root = FALSE;
|
|
}
|
|
|
|
FOR_NSCREENS_BACKWARD(i) {
|
|
rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
|
|
RT_WINDOW, client, DixGetAttrAccess);
|
|
if (rc != Success) {
|
|
client->errorValue = stuff->window;
|
|
free(overlayWin);
|
|
return rc;
|
|
}
|
|
pScreen = pWin->drawable.pScreen;
|
|
|
|
/*
|
|
* Create an OverlayClient structure to mark this client's
|
|
* interest in the overlay window
|
|
*/
|
|
pOc = compCreateOverlayClient(pScreen, client);
|
|
if (pOc == NULL) {
|
|
free(overlayWin);
|
|
return BadAlloc;
|
|
}
|
|
|
|
/*
|
|
* Make sure the overlay window exists
|
|
*/
|
|
cs = GetCompScreen(pScreen);
|
|
if (cs->pOverlayWin == NULL)
|
|
if (!compCreateOverlayWindow(pScreen)) {
|
|
FreeResource(pOc->resource, RT_NONE);
|
|
free(overlayWin);
|
|
return BadAlloc;
|
|
}
|
|
|
|
rc = XaceHook(XACE_RESOURCE_ACCESS, client,
|
|
cs->pOverlayWin->drawable.id,
|
|
RT_WINDOW, cs->pOverlayWin, RT_NONE, NULL,
|
|
DixGetAttrAccess);
|
|
if (rc != Success) {
|
|
FreeResource(pOc->resource, RT_NONE);
|
|
free(overlayWin);
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
if (overlayWin) {
|
|
FOR_NSCREENS(i) {
|
|
cs = GetCompScreen(screenInfo.screens[i]);
|
|
overlayWin->info[i].id = cs->pOverlayWin->drawable.id;
|
|
}
|
|
|
|
AddResource(overlayWin->info[0].id, XRT_WINDOW, overlayWin);
|
|
}
|
|
|
|
cs = GetCompScreen(screenInfo.screens[0]);
|
|
|
|
rep = (xCompositeGetOverlayWindowReply) {
|
|
.type = X_Reply,
|
|
.sequenceNumber = client->sequence,
|
|
.length = 0,
|
|
.overlayWin = cs->pOverlayWin->drawable.id
|
|
};
|
|
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.overlayWin);
|
|
}
|
|
WriteToClient(client, sz_xCompositeGetOverlayWindowReply, &rep);
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
PanoramiXCompositeReleaseOverlayWindow(ClientPtr client)
|
|
{
|
|
REQUEST(xCompositeReleaseOverlayWindowReq);
|
|
WindowPtr pWin;
|
|
CompOverlayClientPtr pOc;
|
|
PanoramiXRes *win;
|
|
int i, rc;
|
|
|
|
REQUEST_SIZE_MATCH(xCompositeReleaseOverlayWindowReq);
|
|
|
|
if ((rc = dixLookupResourceByType((void **) &win, stuff->window, XRT_WINDOW,
|
|
client, DixUnknownAccess))) {
|
|
client->errorValue = stuff->window;
|
|
return rc;
|
|
}
|
|
|
|
FOR_NSCREENS_BACKWARD(i) {
|
|
if ((rc = dixLookupResourceByType((void **) &pWin, win->info[i].id,
|
|
XRT_WINDOW, client,
|
|
DixUnknownAccess))) {
|
|
client->errorValue = stuff->window;
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* Has client queried a reference to the overlay window
|
|
* on this screen? If not, generate an error.
|
|
*/
|
|
pOc = compFindOverlayClient(pWin->drawable.pScreen, client);
|
|
if (pOc == NULL)
|
|
return BadMatch;
|
|
|
|
/* The delete function will free the client structure */
|
|
FreeResource(pOc->resource, RT_NONE);
|
|
}
|
|
|
|
return Success;
|
|
}
|
|
|
|
void
|
|
PanoramiXCompositeInit(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < CompositeNumberRequests; i++)
|
|
PanoramiXSaveCompositeVector[i] = ProcCompositeVector[i];
|
|
/*
|
|
* Stuff in Xinerama aware request processing hooks
|
|
*/
|
|
ProcCompositeVector[X_CompositeRedirectWindow] =
|
|
PanoramiXCompositeRedirectWindow;
|
|
ProcCompositeVector[X_CompositeRedirectSubwindows] =
|
|
PanoramiXCompositeRedirectSubwindows;
|
|
ProcCompositeVector[X_CompositeUnredirectWindow] =
|
|
PanoramiXCompositeUnredirectWindow;
|
|
ProcCompositeVector[X_CompositeUnredirectSubwindows] =
|
|
PanoramiXCompositeUnredirectSubwindows;
|
|
ProcCompositeVector[X_CompositeNameWindowPixmap] =
|
|
PanoramiXCompositeNameWindowPixmap;
|
|
ProcCompositeVector[X_CompositeGetOverlayWindow] =
|
|
PanoramiXCompositeGetOverlayWindow;
|
|
ProcCompositeVector[X_CompositeReleaseOverlayWindow] =
|
|
PanoramiXCompositeReleaseOverlayWindow;
|
|
}
|
|
|
|
void
|
|
PanoramiXCompositeReset(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < CompositeNumberRequests; i++)
|
|
ProcCompositeVector[i] = PanoramiXSaveCompositeVector[i];
|
|
}
|
|
|
|
#endif
|