Commit c6f86b3b authored by Mike Gabriel's avatar Mike Gabriel

hw/nxagent/NXshm.c: Shrink file, drop duplicate code that can identically be found in Xext/shm.c.

parent 51e4ed0f
......@@ -30,7 +30,7 @@ XCOMM $XFree86: xc/programs/Xserver/Xext/Imakefile,v 3.43 2003/04/21 18:56:48 sv
SUBDIRS = extmod
#endif
#if HasShm
#if HasShm && (!(defined(NXAgentServer) && NXAgentServer))
SHMSRCS = shm.c
SHMOBJS = shm.o
#endif
......
......@@ -202,6 +202,7 @@ static Bool CheckForShmSyscall()
#endif
#ifndef NXAGENT_SERVER
void
ShmExtensionInit(INITARGS)
{
......@@ -265,6 +266,7 @@ ShmExtensionInit(INITARGS)
EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
}
}
#endif /* NXAGENT_SERVER */
/*ARGSUSED*/
static void
......@@ -502,6 +504,7 @@ ProcShmDetach(client)
return(client->noClientException);
}
#ifndef NXAGENT_SERVER
static void
miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
DrawablePtr dst;
......@@ -563,6 +566,7 @@ fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
data);
}
#endif /* NXAGENT_SERVER */
#ifdef PANORAMIX
......@@ -824,6 +828,7 @@ CreatePmap:
#endif
#ifndef NXAGENT_SERVER
static int
ProcShmPutImage(client)
register ClientPtr client;
......@@ -934,7 +939,7 @@ ProcShmPutImage(client)
return (client->noClientException);
}
#endif /* NXAGENT_SERVER */
static int
......@@ -1047,6 +1052,7 @@ ProcShmGetImage(client)
return(client->noClientException);
}
#ifndef NXAGENT_SERVER
static PixmapPtr
fbShmCreatePixmap (pScreen, width, height, depth, addr)
ScreenPtr pScreen;
......@@ -1068,6 +1074,7 @@ fbShmCreatePixmap (pScreen, width, height, depth, addr)
}
return pPixmap;
}
#endif /* NXAGENT_SERVER */
static int
ProcShmCreatePixmap(client)
......@@ -1142,6 +1149,7 @@ CreatePmap:
return (BadAlloc);
}
#ifndef NXAGENT_SERVER
static int
ProcShmDispatch (client)
register ClientPtr client;
......@@ -1177,6 +1185,7 @@ ProcShmDispatch (client)
return BadRequest;
}
}
#endif /* NXAGENT_SERVER */
static void
SShmCompletionEvent(from, to)
......@@ -1286,6 +1295,7 @@ SProcShmCreatePixmap(client)
return ProcShmCreatePixmap(client);
}
#ifndef NXAGENT_SERVER
static int
SProcShmDispatch (client)
register ClientPtr client;
......@@ -1309,3 +1319,4 @@ SProcShmDispatch (client)
return BadRequest;
}
}
#endif /* NXAGENT_SERVER */
\ No newline at end of file
......@@ -46,55 +46,16 @@ in this Software without prior written authorization from The Open Group.
/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
#define SHM
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <sys/types.h>
#ifndef Lynx
#include <sys/ipc.h>
#include <sys/shm.h>
#else
#include <ipc.h>
#include <shm.h>
#endif
#include <unistd.h>
#include <sys/stat.h>
#define NEED_REPLIES
#define NEED_EVENTS
#include <nx-X11/X.h>
#include <nx-X11/Xproto.h>
#include "misc.h"
#include "os.h"
#include "dixstruct.h"
#include "resource.h"
#include "scrnintstr.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "gcstruct.h"
#include "extnsionst.h"
#include "servermd.h"
#define _XSHM_SERVER_
#include <nx-X11/extensions/shmstr.h>
#include <nx-X11/Xfuncproto.h>
#ifdef EXTMODULE
#include "xf86_ansic.h"
#endif
#ifdef PANORAMIX
#include "panoramiX.h"
#include "panoramiXsrv.h"
#endif
#include "modinit.h"
#include "Trap.h"
#include "Agent.h"
#include "Drawable.h"
#include "Pixmaps.h"
#include "../../Xext/shm.c"
/*
* Set here the required log level.
*/
......@@ -115,135 +76,6 @@ extern void fbPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
int x, int y, int w, int h, int leftPad, int format,
char *pImage);
typedef struct _ShmDesc {
struct _ShmDesc *next;
int shmid;
int refcnt;
char *addr;
Bool writable;
unsigned long size;
} ShmDescRec, *ShmDescPtr;
static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
static int ShmDetachSegment(
void * /* value */,
XID /* shmseg */
);
static void ShmResetProc(
ExtensionEntry * /* extEntry */
);
static void SShmCompletionEvent(
xShmCompletionEvent * /* from */,
xShmCompletionEvent * /* to */
);
static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
static DISPATCH_PROC(ProcShmAttach);
static DISPATCH_PROC(ProcShmCreatePixmap);
static DISPATCH_PROC(ProcShmDetach);
static DISPATCH_PROC(ProcShmDispatch);
static DISPATCH_PROC(ProcShmGetImage);
static DISPATCH_PROC(ProcShmPutImage);
static DISPATCH_PROC(ProcShmQueryVersion);
static DISPATCH_PROC(SProcShmAttach);
static DISPATCH_PROC(SProcShmCreatePixmap);
static DISPATCH_PROC(SProcShmDetach);
static DISPATCH_PROC(SProcShmDispatch);
static DISPATCH_PROC(SProcShmGetImage);
static DISPATCH_PROC(SProcShmPutImage);
static DISPATCH_PROC(SProcShmQueryVersion);
static unsigned char ShmReqCode;
int ShmCompletionCode;
int BadShmSegCode;
RESTYPE ShmSegType;
static ShmDescPtr Shmsegs;
static Bool sharedPixmaps;
static int pixmapFormat;
static int shmPixFormat[MAXSCREENS];
static ShmFuncsPtr shmFuncs[MAXSCREENS];
static DestroyPixmapProcPtr destroyPixmap[MAXSCREENS];
#ifdef PIXPRIV
static int shmPixmapPrivate;
#endif
static ShmFuncs miFuncs = {NULL, miShmPutImage};
static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
{ \
shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
if (!shmdesc) \
{ \
client->errorValue = shmseg; \
return BadShmSegCode; \
} \
}
#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
{ \
VERIFY_SHMSEG(shmseg, shmdesc, client); \
if ((offset & 3) || (offset > shmdesc->size)) \
{ \
client->errorValue = offset; \
return BadValue; \
} \
if (needwrite && !shmdesc->writable) \
return BadAccess; \
}
#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
{ \
if ((offset + len) > shmdesc->size) \
{ \
return BadAccess; \
} \
}
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
#include <sys/signal.h>
static Bool badSysCall = FALSE;
static void
SigSysHandler(signo)
int signo;
{
badSysCall = TRUE;
}
static Bool CheckForShmSyscall()
{
void (*oldHandler)();
int shmid = -1;
/* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
oldHandler = signal(SIGSYS, SigSysHandler);
badSysCall = FALSE;
shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
if (shmid != -1)
{
/* Successful allocation - clean up */
shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
}
else
{
/* Allocation failed */
badSysCall = TRUE;
}
signal(SIGSYS, oldHandler);
return(!badSysCall);
}
#define MUST_CHECK_FOR_SHM_SYSCALL
#endif
void
ShmExtensionInit(INITARGS)
{
......@@ -318,245 +150,6 @@ ShmExtensionInit(INITARGS)
}
}
/*ARGSUSED*/
static void
ShmResetProc (extEntry)
ExtensionEntry *extEntry;
{
int i;
for (i = 0; i < MAXSCREENS; i++)
{
shmFuncs[i] = (ShmFuncsPtr)NULL;
shmPixFormat[i] = 0;
}
}
void
ShmRegisterFuncs(
ScreenPtr pScreen,
ShmFuncsPtr funcs)
{
shmFuncs[pScreen->myNum] = funcs;
}
void
ShmSetPixmapFormat(
ScreenPtr pScreen,
int format)
{
shmPixFormat[pScreen->myNum] = format;
}
static Bool
ShmDestroyPixmap (PixmapPtr pPixmap)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
Bool ret;
if (pPixmap->refcnt == 1)
{
ShmDescPtr shmdesc;
#ifdef PIXPRIV
shmdesc = (ShmDescPtr) pPixmap->devPrivates[shmPixmapPrivate].ptr;
#else
char *base = (char *) pPixmap->devPrivate.ptr;
if (base != (void *) (pPixmap + 1))
{
for (shmdesc = Shmsegs; shmdesc; shmdesc = shmdesc->next)
{
if (shmdesc->addr <= base && base <= shmdesc->addr + shmdesc->size)
break;
}
}
else
shmdesc = 0;
#endif
if (shmdesc)
ShmDetachSegment ((void *) shmdesc, pPixmap->drawable.id);
}
pScreen->DestroyPixmap = destroyPixmap[pScreen->myNum];
ret = (*pScreen->DestroyPixmap) (pPixmap);
destroyPixmap[pScreen->myNum] = pScreen->DestroyPixmap;
pScreen->DestroyPixmap = ShmDestroyPixmap;
return ret;
}
void
ShmRegisterFbFuncs(pScreen)
ScreenPtr pScreen;
{
#ifdef TEST
fprintf(stderr, "ShmRegisterFbFuncs: Registering shmFuncs as fbFuncs.\n");
#endif
shmFuncs[pScreen->myNum] = &fbFuncs;
}
static int
ProcShmQueryVersion(client)
register ClientPtr client;
{
xShmQueryVersionReply rep;
register int n;
REQUEST_SIZE_MATCH(xShmQueryVersionReq);
memset(&rep, 0, sizeof(xShmQueryVersionReply));
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.sharedPixmaps = sharedPixmaps;
rep.pixmapFormat = pixmapFormat;
rep.majorVersion = SHM_MAJOR_VERSION;
rep.minorVersion = SHM_MINOR_VERSION;
rep.uid = geteuid();
rep.gid = getegid();
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swaps(&rep.majorVersion, n);
swaps(&rep.minorVersion, n);
swaps(&rep.uid, n);
swaps(&rep.gid, n);
}
WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
return (client->noClientException);
}
/*
* Simulate the access() system call for a shared memory segement,
* using the credentials from the client if available
*/
static int
shm_access(ClientPtr client, struct ipc_perm *perm, int readonly)
{
int uid, gid;
mode_t mask;
if (LocalClientCred(client, &uid, &gid) != -1) {
/* User id 0 always gets access */
if (uid == 0) {
return 0;
}
/* Check the owner */
if (perm->uid == uid || perm->cuid == uid) {
mask = S_IRUSR;
if (!readonly) {
mask |= S_IWUSR;
}
return (perm->mode & mask) == mask ? 0 : -1;
}
/* Check the group */
if (perm->gid == gid || perm->cgid == gid) {
mask = S_IRGRP;
if (!readonly) {
mask |= S_IWGRP;
}
return (perm->mode & mask) == mask ? 0 : -1;
}
}
/* Otherwise, check everyone else */
mask = S_IROTH;
if (!readonly) {
mask |= S_IWOTH;
}
return (perm->mode & mask) == mask ? 0 : -1;
}
static int
ProcShmAttach(client)
register ClientPtr client;
{
struct shmid_ds buf;
ShmDescPtr shmdesc;
REQUEST(xShmAttachReq);
REQUEST_SIZE_MATCH(xShmAttachReq);
LEGAL_NEW_RESOURCE(stuff->shmseg, client);
if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
{
client->errorValue = stuff->readOnly;
return(BadValue);
}
for (shmdesc = Shmsegs;
shmdesc && (shmdesc->shmid != stuff->shmid);
shmdesc = shmdesc->next)
;
if (shmdesc)
{
if (!stuff->readOnly && !shmdesc->writable)
return BadAccess;
shmdesc->refcnt++;
}
else
{
shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
if (!shmdesc)
return BadAlloc;
shmdesc->addr = shmat(stuff->shmid, 0,
stuff->readOnly ? SHM_RDONLY : 0);
if ((shmdesc->addr == ((char *)-1)) ||
shmctl(stuff->shmid, IPC_STAT, &buf))
{
xfree(shmdesc);
return BadAccess;
}
/* The attach was performed with root privs. We must
* do manual checking of access rights for the credentials
* of the client */
if (shm_access(client, &(buf.shm_perm), stuff->readOnly) == -1) {
shmdt(shmdesc->addr);
xfree(shmdesc);
return BadAccess;
}
shmdesc->shmid = stuff->shmid;
shmdesc->refcnt = 1;
shmdesc->writable = !stuff->readOnly;
shmdesc->size = buf.shm_segsz;
shmdesc->next = Shmsegs;
Shmsegs = shmdesc;
}
if (!AddResource(stuff->shmseg, ShmSegType, (void *)shmdesc))
return BadAlloc;
return(client->noClientException);
}
/*ARGSUSED*/
static int
ShmDetachSegment(value, shmseg)
void * value; /* must conform to DeleteType */
XID shmseg;
{
ShmDescPtr shmdesc = (ShmDescPtr)value;
ShmDescPtr *prev;
if (--shmdesc->refcnt)
return TRUE;
shmdt(shmdesc->addr);
for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
;
*prev = shmdesc->next;
xfree(shmdesc);
return Success;
}
static int
ProcShmDetach(client)
register ClientPtr client;
{
ShmDescPtr shmdesc;
REQUEST(xShmDetachReq);
REQUEST_SIZE_MATCH(xShmDetachReq);
VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
FreeResource(stuff->shmseg, RT_NONE);
return(client->noClientException);
}
static void
miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
DrawablePtr dst;
......@@ -668,266 +261,6 @@ fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
}
}
#ifdef PANORAMIX
static int
ProcPanoramiXShmPutImage(register ClientPtr client)
{
int j, result = 0, orig_x, orig_y;
PanoramiXRes *draw, *gc;
Bool sendEvent, isRoot;
REQUEST(xShmPutImageReq);
REQUEST_SIZE_MATCH(xShmPutImageReq);
if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
return BadDrawable;
if(!(gc = (PanoramiXRes *)SecurityLookupIDByType(
client, stuff->gc, XRT_GC, SecurityReadAccess)))
return BadGC;
isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
orig_x = stuff->dstX;
orig_y = stuff->dstY;
sendEvent = stuff->sendEvent;
stuff->sendEvent = 0;
FOR_NSCREENS(j) {
if(!j) stuff->sendEvent = sendEvent;
stuff->drawable = draw->info[j].id;
stuff->gc = gc->info[j].id;
if (isRoot) {
stuff->dstX = orig_x - panoramiXdataPtr[j].x;
stuff->dstY = orig_y - panoramiXdataPtr[j].y;
}
result = ProcShmPutImage(client);
if(result != client->noClientException) break;
}
return(result);
}
static int
ProcPanoramiXShmGetImage(ClientPtr client)
{
PanoramiXRes *draw;
DrawablePtr drawables[MAXSCREENS];
DrawablePtr pDraw;
xShmGetImageReply xgi;
ShmDescPtr shmdesc;
int i, x, y, w, h, format;
Mask plane = 0, planemask;
long lenPer = 0, length, widthBytesLine;
Bool isRoot;
REQUEST(xShmGetImageReq);
REQUEST_SIZE_MATCH(xShmGetImageReq);
if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
client->errorValue = stuff->format;
return(BadValue);
}
if(!(draw = (PanoramiXRes *)SecurityLookupIDByClass(
client, stuff->drawable, XRC_DRAWABLE, SecurityWriteAccess)))
return BadDrawable;
if (draw->type == XRT_PIXMAP)
return ProcShmGetImage(client);
VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
x = stuff->x;
y = stuff->y;
w = stuff->width;
h = stuff->height;
format = stuff->format;
planemask = stuff->planeMask;
isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
if(isRoot) {
if( /* check for being onscreen */
x < 0 || x + w > PanoramiXPixWidth ||
y < 0 || y + h > PanoramiXPixHeight )
return(BadMatch);
} else {
if( /* check for being onscreen */
panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight ||
/* check for being inside of border */
x < - wBorderWidth((WindowPtr)pDraw) ||
x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
y < -wBorderWidth((WindowPtr)pDraw) ||
y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
return(BadMatch);
}
drawables[0] = pDraw;
for(i = 1; i < PanoramiXNumScreens; i++)
VERIFY_DRAWABLE(drawables[i], draw->info[i].id, client);
xgi.visual = wVisual(((WindowPtr)pDraw));
xgi.type = X_Reply;
xgi.length = 0;
xgi.sequenceNumber = client->sequence;
xgi.depth = pDraw->depth;
if(format == ZPixmap) {
widthBytesLine = PixmapBytePad(w, pDraw->depth);
length = widthBytesLine * h;
} else {
widthBytesLine = PixmapBytePad(w, 1);
lenPer = widthBytesLine * h;
plane = ((Mask)1) << (pDraw->depth - 1);
length = lenPer * Ones(planemask & (plane | (plane - 1)));
}
VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
xgi.size = length;
if (length == 0) {/* nothing to do */ }
else if (format == ZPixmap) {
XineramaGetImageData(drawables, x, y, w, h, format, planemask,
shmdesc->addr + stuff->offset,
widthBytesLine, isRoot);
} else {
length = stuff->offset;
for (; plane; plane >>= 1) {
if (planemask & plane) {
XineramaGetImageData(drawables, x, y, w, h,
format, plane, shmdesc->addr + length,
widthBytesLine, isRoot);
length += lenPer;
}
}
}
if (client->swapped) {
register int n;
swaps(&xgi.sequenceNumber, n);
swapl(&xgi.length, n);
swapl(&xgi.visual, n);
swapl(&xgi.size, n);
}
WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
return(client->noClientException);
}
static int
ProcPanoramiXShmCreatePixmap(
register ClientPtr client)
{
ScreenPtr pScreen = NULL;
PixmapPtr pMap = NULL;
DrawablePtr pDraw;
DepthPtr pDepth;
int i, j, result;
ShmDescPtr shmdesc;
REQUEST(xShmCreatePixmapReq);
unsigned int width, height, depth;
unsigned long size;
PanoramiXRes *newPix;
REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
client->errorValue = stuff->pid;
if (!sharedPixmaps)
return BadImplementation;
LEGAL_NEW_RESOURCE(stuff->pid, client);
VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
width = stuff->width;
height = stuff->height;
depth = stuff->depth;
if (!width || !height || !depth)
{
client->errorValue = 0;
return BadValue;
}
if (width > 32767 || height > 32767)
return BadAlloc;
if (stuff->depth != 1)
{
pDepth = pDraw->pScreen->allowedDepths;
for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
if (pDepth->depth == stuff->depth)
goto CreatePmap;
client->errorValue = stuff->depth;
return BadValue;
}
CreatePmap:
size = PixmapBytePad(width, depth) * height;
if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
if (size < width * height)
return BadAlloc;
/* thankfully, offset is unsigned */
if (stuff->offset + size < size)
return BadAlloc;
}
VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
if(!(newPix = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes))))
return BadAlloc;
newPix->type = XRT_PIXMAP;
newPix->u.pix.shared = TRUE;
newPix->info[0].id = stuff->pid;
for(j = 1; j < PanoramiXNumScreens; j++)
newPix->info[j].id = FakeClientID(client->index);
result = (client->noClientException);
FOR_NSCREENS(j) {
pScreen = screenInfo.screens[j];
pMap = (*shmFuncs[j]->CreatePixmap)(pScreen,
stuff->width, stuff->height, stuff->depth,
shmdesc->addr + stuff->offset);
if (pMap) {
#ifdef PIXPRIV
pMap->devPrivates[shmPixmapPrivate].ptr = (void *) shmdesc;
#endif
shmdesc->refcnt++;
pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
pMap->drawable.id = newPix->info[j].id;
if (!AddResource(newPix->info[j].id, RT_PIXMAP, (void *)pMap)) {
(*pScreen->DestroyPixmap)(pMap);
result = BadAlloc;
break;
}
} else {
result = BadAlloc;
break;
}
}
if(result == BadAlloc) {
while(j--) {
(*pScreen->DestroyPixmap)(pMap);
FreeResource(newPix->info[j].id, RT_NONE);
}
xfree(newPix);
} else
AddResource(stuff->pid, XRT_PIXMAP, newPix);
return result;
}
#endif
static int
ProcShmPutImage(client)
register ClientPtr client;
......@@ -1036,117 +369,6 @@ ProcShmPutImage(client)
}
static int
ProcShmGetImage(client)
register ClientPtr client;
{
register DrawablePtr pDraw;
long lenPer = 0, length;
Mask plane = 0;
xShmGetImageReply xgi;
ShmDescPtr shmdesc;
int n;
REQUEST(xShmGetImageReq);
REQUEST_SIZE_MATCH(xShmGetImageReq);
if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
{
client->errorValue = stuff->format;
return(BadValue);
}
VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
if (pDraw->type == DRAWABLE_WINDOW)
{
if( /* check for being viewable */
!((WindowPtr) pDraw)->realized ||
/* check for being on screen */
pDraw->x + stuff->x < 0 ||
pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
pDraw->y + stuff->y < 0 ||
pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
/* check for being inside of border */
stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
stuff->x + (int)stuff->width >
wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
stuff->y + (int)stuff->height >
wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
)
return(BadMatch);
xgi.visual = wVisual(((WindowPtr)pDraw));
}
else
{
if (stuff->x < 0 ||
stuff->x+(int)stuff->width > pDraw->width ||
stuff->y < 0 ||
stuff->y+(int)stuff->height > pDraw->height
)
return(BadMatch);
xgi.visual = None;
}
xgi.type = X_Reply;
xgi.length = 0;
xgi.sequenceNumber = client->sequence;
xgi.depth = pDraw->depth;
if(stuff->format == ZPixmap)
{
length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
}
else
{
lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
plane = ((Mask)1) << (pDraw->depth - 1);
/* only planes asked for */
length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
}
VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
xgi.size = length;
if (length == 0)
{
/* nothing to do */
}
else if (stuff->format == ZPixmap)
{
(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
stuff->width, stuff->height,
stuff->format, stuff->planeMask,
shmdesc->addr + stuff->offset);
}
else
{
length = stuff->offset;
for (; plane; plane >>= 1)
{
if (stuff->planeMask & plane)
{
(*pDraw->pScreen->GetImage)(pDraw,
stuff->x, stuff->y,
stuff->width, stuff->height,
stuff->format, plane,
shmdesc->addr + length);
length += lenPer;
}
}
}
if (client->swapped) {
swaps(&xgi.sequenceNumber, n);
swapl(&xgi.length, n);
swapl(&xgi.visual, n);
swapl(&xgi.size, n);
}
WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
return(client->noClientException);
}
static PixmapPtr
fbShmCreatePixmap (pScreen, width, height, depth, addr)
ScreenPtr pScreen;
......@@ -1191,78 +413,6 @@ fbShmCreatePixmap (pScreen, width, height, depth, addr)
return pPixmap;
}
static int
ProcShmCreatePixmap(client)
register ClientPtr client;
{
PixmapPtr pMap;
register DrawablePtr pDraw;
DepthPtr pDepth;
register int i;
ShmDescPtr shmdesc;
REQUEST(xShmCreatePixmapReq);
unsigned int width, height, depth;
unsigned long size;
REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
client->errorValue = stuff->pid;
if (!sharedPixmaps)
return BadImplementation;
LEGAL_NEW_RESOURCE(stuff->pid, client);
VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
width = stuff->width;
height = stuff->height;
depth = stuff->depth;
if (!width || !height || !depth)
{
client->errorValue = 0;
return BadValue;
}
if (width > 32767 || height > 32767)
return BadAlloc;
if (stuff->depth != 1)
{
pDepth = pDraw->pScreen->allowedDepths;
for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
if (pDepth->depth == stuff->depth)
goto CreatePmap;
client->errorValue = stuff->depth;
return BadValue;
}
CreatePmap:
size = PixmapBytePad(width, depth) * height;
if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
if (size < width * height)
return BadAlloc;
/* thankfully, offset is unsigned */
if (stuff->offset + size < size)
return BadAlloc;
}
VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
pDraw->pScreen, stuff->width,
stuff->height, stuff->depth,
shmdesc->addr + stuff->offset);
if (pMap)
{
#ifdef PIXPRIV
pMap->devPrivates[shmPixmapPrivate].ptr = (void *) shmdesc;
#endif
shmdesc->refcnt++;
pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
pMap->drawable.id = stuff->pid;
if (AddResource(stuff->pid, RT_PIXMAP, (void *)pMap))
{
return(client->noClientException);
}
}
return (BadAlloc);
}
static int
ProcShmDispatch (client)
......@@ -1339,114 +489,6 @@ ProcShmDispatch (client)
}
}
static void
SShmCompletionEvent(from, to)
xShmCompletionEvent *from, *to;
{
to->type = from->type;
cpswaps(from->sequenceNumber, to->sequenceNumber);
cpswapl(from->drawable, to->drawable);
cpswaps(from->minorEvent, to->minorEvent);
to->majorEvent = from->majorEvent;
cpswapl(from->shmseg, to->shmseg);
cpswapl(from->offset, to->offset);
}
static int
SProcShmQueryVersion(client)
register ClientPtr client;
{
register int n;
REQUEST(xShmQueryVersionReq);
swaps(&stuff->length, n);
return ProcShmQueryVersion(client);
}
static int
SProcShmAttach(client)
ClientPtr client;
{
register int n;
REQUEST(xShmAttachReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xShmAttachReq);
swapl(&stuff->shmseg, n);
swapl(&stuff->shmid, n);
return ProcShmAttach(client);
}
static int
SProcShmDetach(client)
ClientPtr client;
{
register int n;
REQUEST(xShmDetachReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xShmDetachReq);
swapl(&stuff->shmseg, n);
return ProcShmDetach(client);
}
static int
SProcShmPutImage(client)
ClientPtr client;
{
register int n;
REQUEST(xShmPutImageReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xShmPutImageReq);
swapl(&stuff->drawable, n);
swapl(&stuff->gc, n);
swaps(&stuff->totalWidth, n);
swaps(&stuff->totalHeight, n);
swaps(&stuff->srcX, n);
swaps(&stuff->srcY, n);
swaps(&stuff->srcWidth, n);
swaps(&stuff->srcHeight, n);
swaps(&stuff->dstX, n);
swaps(&stuff->dstY, n);
swapl(&stuff->shmseg, n);
swapl(&stuff->offset, n);
return ProcShmPutImage(client);
}
static int
SProcShmGetImage(client)
ClientPtr client;
{
register int n;
REQUEST(xShmGetImageReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xShmGetImageReq);
swapl(&stuff->drawable, n);
swaps(&stuff->x, n);
swaps(&stuff->y, n);
swaps(&stuff->width, n);
swaps(&stuff->height, n);
swapl(&stuff->planeMask, n);
swapl(&stuff->shmseg, n);
swapl(&stuff->offset, n);
return ProcShmGetImage(client);
}
static int
SProcShmCreatePixmap(client)
ClientPtr client;
{
register int n;
REQUEST(xShmCreatePixmapReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
swapl(&stuff->pid, n);
swapl(&stuff->drawable, n);
swaps(&stuff->width, n);
swaps(&stuff->height, n);
swapl(&stuff->shmseg, n);
swapl(&stuff->offset, n);
return ProcShmCreatePixmap(client);
}
static int
SProcShmDispatch (client)
register ClientPtr client;
......@@ -1496,4 +538,3 @@ SProcShmDispatch (client)
return BadRequest;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment