mirror of
https://github.com/X11Libre/xserver.git
synced 2026-03-24 05:54:08 +00:00
Xext: shape: replace ShapeEventType resource by devPrivate
Instead of abusing resource types, use the standard devPrivate mechanism for assigning auxillary data to windows. Signed-off-by: squishypinkelephant <squishypinkelephant@gmail.com>
This commit is contained in:
committed by
Enrico Weigelt
parent
cb445cef6b
commit
02f1efe2bc
204
Xext/shape.c
204
Xext/shape.c
@@ -31,10 +31,13 @@ in this Software without prior written authorization from The Open Group.
|
|||||||
#include <X11/Xproto.h>
|
#include <X11/Xproto.h>
|
||||||
#include <X11/extensions/shapeproto.h>
|
#include <X11/extensions/shapeproto.h>
|
||||||
|
|
||||||
|
#include "dix/client_priv.h"
|
||||||
#include "dix/dix_priv.h"
|
#include "dix/dix_priv.h"
|
||||||
#include "dix/gc_priv.h"
|
#include "dix/gc_priv.h"
|
||||||
#include "dix/request_priv.h"
|
#include "dix/request_priv.h"
|
||||||
#include "dix/rpcbuf_priv.h"
|
#include "dix/rpcbuf_priv.h"
|
||||||
|
#include "dix/screenint_priv.h"
|
||||||
|
#include "dix/screen_hooks_priv.h"
|
||||||
#include "dix/window_priv.h"
|
#include "dix/window_priv.h"
|
||||||
#include "miext/extinit_priv.h"
|
#include "miext/extinit_priv.h"
|
||||||
#include "Xext/panoramiX.h"
|
#include "Xext/panoramiX.h"
|
||||||
@@ -47,7 +50,6 @@ in this Software without prior written authorization from The Open Group.
|
|||||||
#include "pixmapstr.h"
|
#include "pixmapstr.h"
|
||||||
#include "extnsionst.h"
|
#include "extnsionst.h"
|
||||||
#include "dixstruct.h"
|
#include "dixstruct.h"
|
||||||
#include "resource.h"
|
|
||||||
#include "opaque.h"
|
#include "opaque.h"
|
||||||
#include "regionstr.h"
|
#include "regionstr.h"
|
||||||
#include "gcstruct.h"
|
#include "gcstruct.h"
|
||||||
@@ -58,12 +60,8 @@ Bool noShapeExtension = FALSE;
|
|||||||
typedef RegionPtr (*CreateDftPtr) (WindowPtr /* pWin */
|
typedef RegionPtr (*CreateDftPtr) (WindowPtr /* pWin */
|
||||||
);
|
);
|
||||||
|
|
||||||
static int ShapeFreeClient(void * /* data */ ,
|
static DevPrivateKeyRec ShapeWindowPrivateKeyRec;
|
||||||
XID /* id */
|
|
||||||
);
|
|
||||||
static int ShapeFreeEvents(void * /* data */ ,
|
|
||||||
XID /* id */
|
|
||||||
);
|
|
||||||
static void SShapeNotifyEvent(xShapeNotifyEvent * /* from */ ,
|
static void SShapeNotifyEvent(xShapeNotifyEvent * /* from */ ,
|
||||||
xShapeNotifyEvent * /* to */
|
xShapeNotifyEvent * /* to */
|
||||||
);
|
);
|
||||||
@@ -73,7 +71,6 @@ static void SShapeNotifyEvent(xShapeNotifyEvent * /* from */ ,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static int ShapeEventBase = 0;
|
static int ShapeEventBase = 0;
|
||||||
static RESTYPE ClientType, ShapeEventType; /* resource types for event masks */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* each window has a list of clients requesting
|
* each window has a list of clients requesting
|
||||||
@@ -89,9 +86,30 @@ typedef struct _ShapeEvent {
|
|||||||
ShapeEventPtr next;
|
ShapeEventPtr next;
|
||||||
ClientPtr client;
|
ClientPtr client;
|
||||||
WindowPtr window;
|
WindowPtr window;
|
||||||
XID clientResource;
|
|
||||||
} ShapeEventRec;
|
} ShapeEventRec;
|
||||||
|
|
||||||
|
#define SHAPE_WINDOW_PRIVADDR(pWin) ((ShapeEventPtr *) \
|
||||||
|
dixLookupPrivateAddr(&(pWin)->devPrivates, &ShapeWindowPrivateKeyRec))
|
||||||
|
|
||||||
|
static int
|
||||||
|
ShapeDelClientFromWin(WindowPtr pWin, void *value) {
|
||||||
|
ClientPtr client = value;
|
||||||
|
ShapeEventPtr *pHead = SHAPE_WINDOW_PRIVADDR(pWin);
|
||||||
|
ShapeEventPtr *prev = pHead;
|
||||||
|
ShapeEventPtr curr = *pHead;
|
||||||
|
|
||||||
|
while (curr) {
|
||||||
|
if (curr->client == client) {
|
||||||
|
*prev = curr->next;
|
||||||
|
free(curr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev = &curr->next;
|
||||||
|
curr = curr->next;
|
||||||
|
}
|
||||||
|
return WT_WALKCHILDREN;
|
||||||
|
}
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* ShapeExtensionInit
|
* ShapeExtensionInit
|
||||||
*
|
*
|
||||||
@@ -711,135 +729,45 @@ ProcShapeQueryExtents(ClientPtr client)
|
|||||||
return X_SEND_REPLY_SIMPLE(client, reply);
|
return X_SEND_REPLY_SIMPLE(client, reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ARGSUSED*/ static int
|
|
||||||
ShapeFreeClient(void *data, XID id)
|
|
||||||
{
|
|
||||||
ShapeEventPtr pShapeEvent;
|
|
||||||
WindowPtr pWin;
|
|
||||||
ShapeEventPtr *pHead, pCur, pPrev;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
pShapeEvent = (ShapeEventPtr) data;
|
|
||||||
pWin = pShapeEvent->window;
|
|
||||||
rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
|
|
||||||
ShapeEventType, serverClient, DixReadAccess);
|
|
||||||
if (rc == Success) {
|
|
||||||
pPrev = 0;
|
|
||||||
for (pCur = *pHead; pCur && pCur != pShapeEvent; pCur = pCur->next)
|
|
||||||
pPrev = pCur;
|
|
||||||
if (pCur) {
|
|
||||||
if (pPrev)
|
|
||||||
pPrev->next = pShapeEvent->next;
|
|
||||||
else
|
|
||||||
*pHead = pShapeEvent->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free((void *) pShapeEvent);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*ARGSUSED*/ static int
|
|
||||||
ShapeFreeEvents(void *data, XID id)
|
|
||||||
{
|
|
||||||
ShapeEventPtr *pHead, pCur, pNext;
|
|
||||||
|
|
||||||
pHead = (ShapeEventPtr *) data;
|
|
||||||
for (pCur = *pHead; pCur; pCur = pNext) {
|
|
||||||
pNext = pCur->next;
|
|
||||||
FreeResource(pCur->clientResource, ClientType);
|
|
||||||
free((void *) pCur);
|
|
||||||
}
|
|
||||||
free((void *) pHead);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ProcShapeSelectInput(ClientPtr client)
|
ProcShapeSelectInput(ClientPtr client)
|
||||||
{
|
{
|
||||||
REQUEST(xShapeSelectInputReq);
|
REQUEST(xShapeSelectInputReq);
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
ShapeEventPtr pShapeEvent, pNewShapeEvent, *pHead;
|
ShapeEventPtr pNewShapeEvent;
|
||||||
XID clientResource;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
REQUEST_SIZE_MATCH(xShapeSelectInputReq);
|
REQUEST_SIZE_MATCH(xShapeSelectInputReq);
|
||||||
|
|
||||||
if (client->swapped)
|
if (client->swapped)
|
||||||
swapl(&stuff->window);
|
swapl(&stuff->window);
|
||||||
|
|
||||||
rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
|
rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
return rc;
|
return rc;
|
||||||
rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
|
ShapeEventPtr pShapeEvent, *pHead = SHAPE_WINDOW_PRIVADDR(pWin);
|
||||||
ShapeEventType, client, DixWriteAccess);
|
|
||||||
if (rc != Success && rc != BadValue)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
switch (stuff->enable) {
|
switch (stuff->enable) {
|
||||||
case xTrue:
|
case xTrue:
|
||||||
if (pHead) {
|
|
||||||
|
|
||||||
/* check for existing entry. */
|
/* check for existing entry. */
|
||||||
for (pShapeEvent = *pHead;
|
for (pShapeEvent = *pHead;
|
||||||
pShapeEvent; pShapeEvent = pShapeEvent->next) {
|
pShapeEvent; pShapeEvent = pShapeEvent->next) {
|
||||||
if (pShapeEvent->client == client)
|
if (pShapeEvent->client == client) {
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build the entry */
|
/* Form the event */
|
||||||
pNewShapeEvent = calloc(1, sizeof(ShapeEventRec));
|
pNewShapeEvent = calloc(1, sizeof(ShapeEventRec));
|
||||||
if (!pNewShapeEvent)
|
if (!pNewShapeEvent)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
pNewShapeEvent->next = 0;
|
pNewShapeEvent->next = *pHead;
|
||||||
pNewShapeEvent->client = client;
|
pNewShapeEvent->client = client;
|
||||||
pNewShapeEvent->window = pWin;
|
pNewShapeEvent->window = pWin;
|
||||||
/*
|
dixSetPrivate(&pWin->devPrivates, &ShapeWindowPrivateKeyRec, pNewShapeEvent);
|
||||||
* add a resource that will be deleted when
|
|
||||||
* the client goes away
|
|
||||||
*/
|
|
||||||
clientResource = FakeClientID(client->index);
|
|
||||||
pNewShapeEvent->clientResource = clientResource;
|
|
||||||
if (!AddResource(clientResource, ClientType, (void *) pNewShapeEvent))
|
|
||||||
return BadAlloc;
|
|
||||||
/*
|
|
||||||
* create a resource to contain a void *to the list
|
|
||||||
* of clients selecting input. This must be indirect as
|
|
||||||
* the list may be arbitrarily rearranged which cannot be
|
|
||||||
* done through the resource database.
|
|
||||||
*/
|
|
||||||
if (!pHead) {
|
|
||||||
pHead = calloc(1, sizeof(ShapeEventPtr));
|
|
||||||
if (!pHead ||
|
|
||||||
!AddResource(pWin->drawable.id, ShapeEventType,
|
|
||||||
(void *) pHead)) {
|
|
||||||
FreeResource(clientResource, X11_RESTYPE_NONE);
|
|
||||||
return BadAlloc;
|
|
||||||
}
|
|
||||||
*pHead = 0;
|
|
||||||
}
|
|
||||||
pNewShapeEvent->next = *pHead;
|
|
||||||
*pHead = pNewShapeEvent;
|
|
||||||
break;
|
break;
|
||||||
case xFalse:
|
case xFalse:
|
||||||
/* delete the interest */
|
/* remove the events with (client) */
|
||||||
if (pHead) {
|
ShapeDelClientFromWin(pWin,client);
|
||||||
pNewShapeEvent = 0;
|
|
||||||
for (pShapeEvent = *pHead; pShapeEvent;
|
|
||||||
pShapeEvent = pShapeEvent->next) {
|
|
||||||
if (pShapeEvent->client == client)
|
|
||||||
break;
|
|
||||||
pNewShapeEvent = pShapeEvent;
|
|
||||||
}
|
|
||||||
if (pShapeEvent) {
|
|
||||||
FreeResource(pShapeEvent->clientResource, ClientType);
|
|
||||||
if (pNewShapeEvent)
|
|
||||||
pNewShapeEvent->next = pShapeEvent->next;
|
|
||||||
else
|
|
||||||
*pHead = pShapeEvent->next;
|
|
||||||
free(pShapeEvent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
client->errorValue = stuff->enable;
|
client->errorValue = stuff->enable;
|
||||||
@@ -855,16 +783,12 @@ ProcShapeSelectInput(ClientPtr client)
|
|||||||
void
|
void
|
||||||
SendShapeNotify(WindowPtr pWin, int which)
|
SendShapeNotify(WindowPtr pWin, int which)
|
||||||
{
|
{
|
||||||
ShapeEventPtr *pHead, pShapeEvent;
|
|
||||||
BoxRec extents;
|
BoxRec extents;
|
||||||
RegionPtr region;
|
RegionPtr region;
|
||||||
BYTE shaped;
|
BYTE shaped;
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
|
ShapeEventPtr pShapeEvent, *pHead = SHAPE_WINDOW_PRIVADDR(pWin);
|
||||||
ShapeEventType, serverClient, DixReadAccess);
|
|
||||||
if (rc != Success)
|
|
||||||
return;
|
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case ShapeBounding:
|
case ShapeBounding:
|
||||||
region = wBoundingShape(pWin);
|
region = wBoundingShape(pWin);
|
||||||
@@ -933,7 +857,6 @@ ProcShapeInputSelected(ClientPtr client)
|
|||||||
{
|
{
|
||||||
REQUEST(xShapeInputSelectedReq);
|
REQUEST(xShapeInputSelectedReq);
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
ShapeEventPtr pShapeEvent, *pHead;
|
|
||||||
int enabled, rc;
|
int enabled, rc;
|
||||||
|
|
||||||
REQUEST_SIZE_MATCH(xShapeInputSelectedReq);
|
REQUEST_SIZE_MATCH(xShapeInputSelectedReq);
|
||||||
@@ -944,10 +867,8 @@ ProcShapeInputSelected(ClientPtr client)
|
|||||||
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
|
rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
return rc;
|
return rc;
|
||||||
rc = dixLookupResourceByType((void **) &pHead, pWin->drawable.id,
|
|
||||||
ShapeEventType, client, DixReadAccess);
|
ShapeEventPtr pShapeEvent, *pHead = SHAPE_WINDOW_PRIVADDR(pWin);
|
||||||
if (rc != Success && rc != BadValue)
|
|
||||||
return rc;
|
|
||||||
enabled = xFalse;
|
enabled = xFalse;
|
||||||
if (pHead) {
|
if (pHead) {
|
||||||
for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
|
for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
|
||||||
@@ -1092,15 +1013,46 @@ SShapeNotifyEvent(xShapeNotifyEvent * from, xShapeNotifyEvent * to)
|
|||||||
to->shaped = from->shaped;
|
to->shaped = from->shaped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ShapeWindowDestroy(CallbackListPtr *pcbl, ScreenPtr pScreen, WindowPtr pWin)
|
||||||
|
{
|
||||||
|
/* free the events before the window's devPrivates are free'd by destruction */
|
||||||
|
ShapeEventPtr pShapeEvent, next;
|
||||||
|
ShapeEventPtr *pHead = SHAPE_WINDOW_PRIVADDR(pWin);
|
||||||
|
|
||||||
|
pShapeEvent = *pHead;
|
||||||
|
while (pShapeEvent) {
|
||||||
|
next = pShapeEvent->next;
|
||||||
|
free(pShapeEvent);
|
||||||
|
pShapeEvent = next;
|
||||||
|
}
|
||||||
|
dixSetPrivate(&pWin->devPrivates, &ShapeWindowPrivateKeyRec, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ShapeClientDestroyCallback(CallbackListPtr *pcbl, void *unused, void *calldata)
|
||||||
|
{
|
||||||
|
ClientPtr client = calldata;
|
||||||
|
DIX_FOR_EACH_SCREEN({
|
||||||
|
WalkTree(walkScreen, ShapeDelClientFromWin, client);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShapeExtensionInit(void)
|
ShapeExtensionInit(void)
|
||||||
{
|
{
|
||||||
ExtensionEntry *extEntry;
|
ExtensionEntry *extEntry;
|
||||||
|
|
||||||
ClientType = CreateNewResourceType(ShapeFreeClient, "ShapeClient");
|
if (!dixRegisterPrivateKey(&ShapeWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
|
||||||
ShapeEventType = CreateNewResourceType(ShapeFreeEvents, "ShapeEvent");
|
return;
|
||||||
if (ClientType && ShapeEventType &&
|
|
||||||
(extEntry = AddExtension(SHAPENAME, ShapeNumberEvents, 0,
|
DIX_FOR_EACH_SCREEN({
|
||||||
|
dixScreenHookWindowDestroy(walkScreen,ShapeWindowDestroy);
|
||||||
|
})
|
||||||
|
|
||||||
|
AddCallback(&ClientDestroyCallback, ShapeClientDestroyCallback, NULL);
|
||||||
|
|
||||||
|
if ((extEntry = AddExtension(SHAPENAME, ShapeNumberEvents, 0,
|
||||||
ProcShapeDispatch, ProcShapeDispatch,
|
ProcShapeDispatch, ProcShapeDispatch,
|
||||||
NULL, StandardMinorOpcode))) {
|
NULL, StandardMinorOpcode))) {
|
||||||
ShapeEventBase = extEntry->eventBase;
|
ShapeEventBase = extEntry->eventBase;
|
||||||
|
|||||||
Reference in New Issue
Block a user