#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <stdarg.h>
#include "scrnintstr.h"
#include "extnsionst.h"
#include "pixmapstr.h"
#include "regionstr.h"
#include "gcstruct.h"
#include "xacestr.h"
#define XSERV_t
#define TRANS_SERVER
#include <X11/Xtrans/Xtrans.h>
#include "../os/osdep.h"
_X_EXPORT CallbackListPtr XaceHooks[XACE_NUM_HOOKS] = {0};
int XaceHookDispatch(ClientPtr client, int major)
{
XaceAuditRec rec = { client, 0 };
CallCallbacks(&XaceHooks[XACE_AUDIT_BEGIN], &rec);
if (major < 128) {
XaceCoreDispatchRec rec = { client, Success };
CallCallbacks(&XaceHooks[XACE_CORE_DISPATCH], &rec);
return rec.status;
} else {
ExtensionEntry *ext = GetExtensionEntry(major);
XaceExtAccessRec rec = { client, ext, DixUseAccess, Success };
if (ext)
CallCallbacks(&XaceHooks[XACE_EXT_DISPATCH], &rec);
return (rec.status == Success) ? Success : BadRequest;
}
}
int XaceHookPropertyAccess(ClientPtr client, WindowPtr pWin,
PropertyPtr *ppProp, Mask access_mode)
{
XacePropertyAccessRec rec = { client, pWin, ppProp, access_mode, Success };
CallCallbacks(&XaceHooks[XACE_PROPERTY_ACCESS], &rec);
return rec.status;
}
int XaceHookSelectionAccess(ClientPtr client,
Selection **ppSel, Mask access_mode)
{
XaceSelectionAccessRec rec = { client, ppSel, access_mode, Success };
CallCallbacks(&XaceHooks[XACE_SELECTION_ACCESS], &rec);
return rec.status;
}
void XaceHookAuditEnd(ClientPtr ptr, int result)
{
XaceAuditRec rec = { ptr, result };
CallCallbacks(&XaceHooks[XACE_AUDIT_END], &rec);
}
int XaceHook(int hook, ...)
{
union {
XaceResourceAccessRec res;
XaceDeviceAccessRec dev;
XaceSendAccessRec send;
XaceReceiveAccessRec recv;
XaceClientAccessRec client;
XaceExtAccessRec ext;
XaceServerAccessRec server;
XaceScreenAccessRec screen;
XaceAuthAvailRec auth;
XaceKeyAvailRec key;
} u;
int *prv = NULL;
va_list ap;
va_start(ap, hook);
switch (hook)
{
case XACE_RESOURCE_ACCESS:
u.res.client = va_arg(ap, ClientPtr);
u.res.id = va_arg(ap, XID);
u.res.rtype = va_arg(ap, RESTYPE);
u.res.res = va_arg(ap, pointer);
u.res.ptype = va_arg(ap, RESTYPE);
u.res.parent = va_arg(ap, pointer);
u.res.access_mode = va_arg(ap, Mask);
u.res.status = Success;
prv = &u.res.status;
break;
case XACE_DEVICE_ACCESS:
u.dev.client = va_arg(ap, ClientPtr);
u.dev.dev = va_arg(ap, DeviceIntPtr);
u.dev.access_mode = va_arg(ap, Mask);
u.dev.status = Success;
prv = &u.dev.status;
break;
case XACE_SEND_ACCESS:
u.send.client = va_arg(ap, ClientPtr);
u.send.dev = va_arg(ap, DeviceIntPtr);
u.send.pWin = va_arg(ap, WindowPtr);
u.send.events = va_arg(ap, xEventPtr);
u.send.count = va_arg(ap, int);
u.send.status = Success;
prv = &u.send.status;
break;
case XACE_RECEIVE_ACCESS:
u.recv.client = va_arg(ap, ClientPtr);
u.recv.pWin = va_arg(ap, WindowPtr);
u.recv.events = va_arg(ap, xEventPtr);
u.recv.count = va_arg(ap, int);
u.recv.status = Success;
prv = &u.recv.status;
break;
case XACE_CLIENT_ACCESS:
u.client.client = va_arg(ap, ClientPtr);
u.client.target = va_arg(ap, ClientPtr);
u.client.access_mode = va_arg(ap, Mask);
u.client.status = Success;
prv = &u.client.status;
break;
case XACE_EXT_ACCESS:
u.ext.client = va_arg(ap, ClientPtr);
u.ext.ext = va_arg(ap, ExtensionEntry*);
u.ext.access_mode = DixGetAttrAccess;
u.ext.status = Success;
prv = &u.ext.status;
break;
case XACE_SERVER_ACCESS:
u.server.client = va_arg(ap, ClientPtr);
u.server.access_mode = va_arg(ap, Mask);
u.server.status = Success;
prv = &u.server.status;
break;
case XACE_SCREEN_ACCESS:
case XACE_SCREENSAVER_ACCESS:
u.screen.client = va_arg(ap, ClientPtr);
u.screen.screen = va_arg(ap, ScreenPtr);
u.screen.access_mode = va_arg(ap, Mask);
u.screen.status = Success;
prv = &u.screen.status;
break;
case XACE_AUTH_AVAIL:
u.auth.client = va_arg(ap, ClientPtr);
u.auth.authId = va_arg(ap, XID);
break;
case XACE_KEY_AVAIL:
u.key.event = va_arg(ap, xEventPtr);
u.key.keybd = va_arg(ap, DeviceIntPtr);
u.key.count = va_arg(ap, int);
break;
default:
va_end(ap);
return 0;
}
va_end(ap);
CallCallbacks(&XaceHooks[hook], &u);
return prv ? *prv : Success;
}
void
XaceCensorImage(
ClientPtr client,
RegionPtr pVisibleRegion,
long widthBytesLine,
DrawablePtr pDraw,
int x, int y, int w, int h,
unsigned int format,
char *pBuf)
{
RegionRec imageRegion;
RegionRec censorRegion;
BoxRec imageBox;
int nRects;
imageBox.x1 = x;
imageBox.y1 = y;
imageBox.x2 = x + w;
imageBox.y2 = y + h;
RegionInit(&imageRegion, &imageBox, 1);
RegionNull(&censorRegion);
RegionSubtract(&censorRegion, &imageRegion, pVisibleRegion);
nRects = RegionNumRects(&censorRegion);
if (nRects > 0)
{
GCPtr pScratchGC = NULL;
PixmapPtr pPix = NULL;
xRectangle *pRects = NULL;
Bool failed = FALSE;
int depth = 1;
int bitsPerPixel = 1;
int i;
BoxPtr pBox;
pRects = malloc(nRects * sizeof(xRectangle));
if (!pRects)
{
failed = TRUE;
goto failSafe;
}
for (pBox = RegionRects(&censorRegion), i = 0;
i < nRects;
i++, pBox++)
{
pRects[i].x = pBox->x1;
pRects[i].y = pBox->y1 - imageBox.y1;
pRects[i].width = pBox->x2 - pBox->x1;
pRects[i].height = pBox->y2 - pBox->y1;
}
if (format == ZPixmap)
{
depth = pDraw->depth;
bitsPerPixel = pDraw->bitsPerPixel;
}
pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
depth, bitsPerPixel,
widthBytesLine, (pointer)pBuf);
if (!pPix)
{
failed = TRUE;
goto failSafe;
}
pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
if (!pScratchGC)
{
failed = TRUE;
goto failSafe;
}
ValidateGC(&pPix->drawable, pScratchGC);
(* pScratchGC->ops->PolyFillRect)(&pPix->drawable,
pScratchGC, nRects, pRects);
failSafe:
if (failed)
{
memset(pBuf, 0, (int)(widthBytesLine * h));
}
free(pRects);
if (pScratchGC) FreeScratchGC(pScratchGC);
if (pPix) FreeScratchPixmapHeader(pPix);
}
RegionUninit(&imageRegion);
RegionUninit(&censorRegion);
}
int XaceGetConnectionNumber(ClientPtr client)
{
XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn;
return _XSERVTransGetConnectionNumber(ci);
}
int XaceIsLocal(ClientPtr client)
{
XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn;
return _XSERVTransIsLocal(ci);
}