shm.c revision 4202a189
105b261ecSmrg/************************************************************ 205b261ecSmrg 305b261ecSmrgCopyright 1989, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg 2505b261ecSmrg********************************************************/ 2605b261ecSmrg 2705b261ecSmrg/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */ 2805b261ecSmrg 2905b261ecSmrg 3005b261ecSmrg#define SHM 3105b261ecSmrg 3205b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 3305b261ecSmrg#include <dix-config.h> 3405b261ecSmrg#endif 3505b261ecSmrg 3605b261ecSmrg#include <sys/types.h> 3705b261ecSmrg#include <sys/ipc.h> 3805b261ecSmrg#include <sys/shm.h> 3905b261ecSmrg#include <unistd.h> 4005b261ecSmrg#include <sys/stat.h> 4105b261ecSmrg#include <X11/X.h> 4205b261ecSmrg#include <X11/Xproto.h> 4305b261ecSmrg#include "misc.h" 4405b261ecSmrg#include "os.h" 4505b261ecSmrg#include "dixstruct.h" 4605b261ecSmrg#include "resource.h" 4705b261ecSmrg#include "scrnintstr.h" 4805b261ecSmrg#include "windowstr.h" 4905b261ecSmrg#include "pixmapstr.h" 5005b261ecSmrg#include "gcstruct.h" 5105b261ecSmrg#include "extnsionst.h" 5205b261ecSmrg#include "servermd.h" 534642e01fSmrg#include "shmint.h" 544642e01fSmrg#include "xace.h" 55684baedfSmrg#include <X11/extensions/shmproto.h> 5605b261ecSmrg#include <X11/Xfuncproto.h> 574202a189Smrg#include "protocol-versions.h" 5805b261ecSmrg 594642e01fSmrg/* Needed for Solaris cross-zone shared memory extension */ 604642e01fSmrg#ifdef HAVE_SHMCTL64 614642e01fSmrg#include <sys/ipc_impl.h> 624642e01fSmrg#define SHMSTAT(id, buf) shmctl64(id, IPC_STAT64, buf) 634642e01fSmrg#define SHMSTAT_TYPE struct shmid_ds64 644642e01fSmrg#define SHMPERM_TYPE struct ipc_perm64 654642e01fSmrg#define SHM_PERM(buf) buf.shmx_perm 664642e01fSmrg#define SHM_SEGSZ(buf) buf.shmx_segsz 674642e01fSmrg#define SHMPERM_UID(p) p->ipcx_uid 684642e01fSmrg#define SHMPERM_CUID(p) p->ipcx_cuid 694642e01fSmrg#define SHMPERM_GID(p) p->ipcx_gid 704642e01fSmrg#define SHMPERM_CGID(p) p->ipcx_cgid 714642e01fSmrg#define SHMPERM_MODE(p) p->ipcx_mode 724642e01fSmrg#define SHMPERM_ZONEID(p) p->ipcx_zoneid 734642e01fSmrg#else 744642e01fSmrg#define SHMSTAT(id, buf) shmctl(id, IPC_STAT, buf) 754642e01fSmrg#define SHMSTAT_TYPE struct shmid_ds 764642e01fSmrg#define SHMPERM_TYPE struct ipc_perm 774642e01fSmrg#define SHM_PERM(buf) buf.shm_perm 784642e01fSmrg#define SHM_SEGSZ(buf) buf.shm_segsz 794642e01fSmrg#define SHMPERM_UID(p) p->uid 804642e01fSmrg#define SHMPERM_CUID(p) p->cuid 814642e01fSmrg#define SHMPERM_GID(p) p->gid 824642e01fSmrg#define SHMPERM_CGID(p) p->cgid 834642e01fSmrg#define SHMPERM_MODE(p) p->mode 844642e01fSmrg#endif 854642e01fSmrg 8605b261ecSmrg#ifdef PANORAMIX 8705b261ecSmrg#include "panoramiX.h" 8805b261ecSmrg#include "panoramiXsrv.h" 8905b261ecSmrg#endif 9005b261ecSmrg 9105b261ecSmrg#include "modinit.h" 9205b261ecSmrg 9305b261ecSmrgtypedef struct _ShmDesc { 9405b261ecSmrg struct _ShmDesc *next; 9505b261ecSmrg int shmid; 9605b261ecSmrg int refcnt; 9705b261ecSmrg char *addr; 9805b261ecSmrg Bool writable; 9905b261ecSmrg unsigned long size; 10005b261ecSmrg} ShmDescRec, *ShmDescPtr; 10105b261ecSmrg 1024202a189Smrgtypedef struct _ShmScrPrivateRec { 1034202a189Smrg CloseScreenProcPtr CloseScreen; 1044202a189Smrg ShmFuncsPtr shmFuncs; 1054202a189Smrg DestroyPixmapProcPtr destroyPixmap; 1064202a189Smrg} ShmScrPrivateRec; 1074202a189Smrg 10805b261ecSmrgstatic PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS); 10905b261ecSmrgstatic int ShmDetachSegment( 11005b261ecSmrg pointer /* value */, 11105b261ecSmrg XID /* shmseg */ 11205b261ecSmrg ); 11305b261ecSmrgstatic void ShmResetProc( 11405b261ecSmrg ExtensionEntry * /* extEntry */ 11505b261ecSmrg ); 11605b261ecSmrgstatic void SShmCompletionEvent( 11705b261ecSmrg xShmCompletionEvent * /* from */, 11805b261ecSmrg xShmCompletionEvent * /* to */ 11905b261ecSmrg ); 12005b261ecSmrg 12105b261ecSmrgstatic Bool ShmDestroyPixmap (PixmapPtr pPixmap); 12205b261ecSmrg 12305b261ecSmrgstatic DISPATCH_PROC(ProcShmAttach); 12405b261ecSmrgstatic DISPATCH_PROC(ProcShmCreatePixmap); 12505b261ecSmrgstatic DISPATCH_PROC(ProcShmDetach); 12605b261ecSmrgstatic DISPATCH_PROC(ProcShmDispatch); 12705b261ecSmrgstatic DISPATCH_PROC(ProcShmGetImage); 12805b261ecSmrgstatic DISPATCH_PROC(ProcShmPutImage); 12905b261ecSmrgstatic DISPATCH_PROC(ProcShmQueryVersion); 13005b261ecSmrgstatic DISPATCH_PROC(SProcShmAttach); 13105b261ecSmrgstatic DISPATCH_PROC(SProcShmCreatePixmap); 13205b261ecSmrgstatic DISPATCH_PROC(SProcShmDetach); 13305b261ecSmrgstatic DISPATCH_PROC(SProcShmDispatch); 13405b261ecSmrgstatic DISPATCH_PROC(SProcShmGetImage); 13505b261ecSmrgstatic DISPATCH_PROC(SProcShmPutImage); 13605b261ecSmrgstatic DISPATCH_PROC(SProcShmQueryVersion); 13705b261ecSmrg 13805b261ecSmrgstatic unsigned char ShmReqCode; 1394202a189Smrgint ShmCompletionCode; 1404202a189Smrgint BadShmSegCode; 1414202a189SmrgRESTYPE ShmSegType; 14205b261ecSmrgstatic ShmDescPtr Shmsegs; 14305b261ecSmrgstatic Bool sharedPixmaps; 1444202a189Smrgstatic DevPrivateKeyRec shmScrPrivateKeyRec; 1454202a189Smrg#define shmScrPrivateKey (&shmScrPrivateKeyRec) 1464202a189Smrgstatic DevPrivateKeyRec shmPixmapPrivateKeyRec; 1474202a189Smrg#define shmPixmapPrivateKey (&shmPixmapPrivateKeyRec) 1484642e01fSmrgstatic ShmFuncs miFuncs = {NULL, NULL}; 1494642e01fSmrgstatic ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL}; 15005b261ecSmrg 1514202a189Smrg#define ShmGetScreenPriv(s) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey)) 1524202a189Smrg 15305b261ecSmrg#define VERIFY_SHMSEG(shmseg,shmdesc,client) \ 15405b261ecSmrg{ \ 1554202a189Smrg int rc; \ 1564202a189Smrg rc = dixLookupResourceByType((pointer *)&(shmdesc), shmseg, ShmSegType, \ 1574202a189Smrg client, DixReadAccess); \ 1584202a189Smrg if (rc != Success) \ 1594202a189Smrg return rc; \ 16005b261ecSmrg} 16105b261ecSmrg 16205b261ecSmrg#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \ 16305b261ecSmrg{ \ 16405b261ecSmrg VERIFY_SHMSEG(shmseg, shmdesc, client); \ 16505b261ecSmrg if ((offset & 3) || (offset > shmdesc->size)) \ 16605b261ecSmrg { \ 16705b261ecSmrg client->errorValue = offset; \ 16805b261ecSmrg return BadValue; \ 16905b261ecSmrg } \ 17005b261ecSmrg if (needwrite && !shmdesc->writable) \ 17105b261ecSmrg return BadAccess; \ 17205b261ecSmrg} 17305b261ecSmrg 17405b261ecSmrg#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \ 17505b261ecSmrg{ \ 17605b261ecSmrg if ((offset + len) > shmdesc->size) \ 17705b261ecSmrg { \ 17805b261ecSmrg return BadAccess; \ 17905b261ecSmrg } \ 18005b261ecSmrg} 18105b261ecSmrg 18205b261ecSmrg 18305b261ecSmrg#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__) 18405b261ecSmrg#include <sys/signal.h> 18505b261ecSmrg 18605b261ecSmrgstatic Bool badSysCall = FALSE; 18705b261ecSmrg 18805b261ecSmrgstatic void 1894642e01fSmrgSigSysHandler(int signo) 19005b261ecSmrg{ 19105b261ecSmrg badSysCall = TRUE; 19205b261ecSmrg} 19305b261ecSmrg 1944642e01fSmrgstatic Bool CheckForShmSyscall(void) 19505b261ecSmrg{ 19605b261ecSmrg void (*oldHandler)(); 19705b261ecSmrg int shmid = -1; 19805b261ecSmrg 19905b261ecSmrg /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ 20005b261ecSmrg oldHandler = signal(SIGSYS, SigSysHandler); 20105b261ecSmrg 20205b261ecSmrg badSysCall = FALSE; 20305b261ecSmrg shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); 20405b261ecSmrg 20505b261ecSmrg if (shmid != -1) 20605b261ecSmrg { 20705b261ecSmrg /* Successful allocation - clean up */ 2084202a189Smrg shmctl(shmid, IPC_RMID, NULL); 20905b261ecSmrg } 21005b261ecSmrg else 21105b261ecSmrg { 21205b261ecSmrg /* Allocation failed */ 21305b261ecSmrg badSysCall = TRUE; 21405b261ecSmrg } 21505b261ecSmrg signal(SIGSYS, oldHandler); 2164202a189Smrg return !badSysCall; 21705b261ecSmrg} 21805b261ecSmrg 21905b261ecSmrg#define MUST_CHECK_FOR_SHM_SYSCALL 22005b261ecSmrg 22105b261ecSmrg#endif 22205b261ecSmrg 2234202a189Smrgstatic Bool 2244202a189SmrgShmCloseScreen(int i, ScreenPtr pScreen) 2254202a189Smrg{ 2264202a189Smrg ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); 2274202a189Smrg pScreen->CloseScreen = screen_priv->CloseScreen; 2284202a189Smrg dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL); 2294202a189Smrg free(screen_priv); 2304202a189Smrg return (*pScreen->CloseScreen) (i, pScreen); 2314202a189Smrg} 2324202a189Smrg 2334202a189Smrgstatic ShmScrPrivateRec * 2344202a189SmrgShmInitScreenPriv(ScreenPtr pScreen) 2354202a189Smrg{ 2364202a189Smrg ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); 2374202a189Smrg if (!screen_priv) 2384202a189Smrg { 2394202a189Smrg screen_priv = calloc(1, sizeof (ShmScrPrivateRec)); 2404202a189Smrg screen_priv->CloseScreen = pScreen->CloseScreen; 2414202a189Smrg dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, screen_priv); 2424202a189Smrg pScreen->CloseScreen = ShmCloseScreen; 2434202a189Smrg } 2444202a189Smrg return screen_priv; 2454202a189Smrg} 2464202a189Smrg 2474202a189Smrgstatic Bool 2484202a189SmrgShmRegisterPrivates(void) 2494202a189Smrg{ 2504202a189Smrg if (!dixRegisterPrivateKey(&shmScrPrivateKeyRec, PRIVATE_SCREEN, 0)) 2514202a189Smrg return FALSE; 2524202a189Smrg if (!dixRegisterPrivateKey(&shmPixmapPrivateKeyRec, PRIVATE_PIXMAP, 0)) 2534202a189Smrg return FALSE; 2544202a189Smrg return TRUE; 2554202a189Smrg} 2564202a189Smrg 25705b261ecSmrgvoid 25805b261ecSmrgShmExtensionInit(INITARGS) 25905b261ecSmrg{ 26005b261ecSmrg ExtensionEntry *extEntry; 26105b261ecSmrg int i; 26205b261ecSmrg 26305b261ecSmrg#ifdef MUST_CHECK_FOR_SHM_SYSCALL 26405b261ecSmrg if (!CheckForShmSyscall()) 26505b261ecSmrg { 26605b261ecSmrg ErrorF("MIT-SHM extension disabled due to lack of kernel support\n"); 26705b261ecSmrg return; 26805b261ecSmrg } 26905b261ecSmrg#endif 27005b261ecSmrg 2714202a189Smrg if (!ShmRegisterPrivates()) 2724202a189Smrg return; 2734202a189Smrg 27405b261ecSmrg sharedPixmaps = xFalse; 27505b261ecSmrg { 27605b261ecSmrg sharedPixmaps = xTrue; 27705b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) 27805b261ecSmrg { 2794202a189Smrg ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]); 2804202a189Smrg if (!screen_priv->shmFuncs) 2814202a189Smrg screen_priv->shmFuncs = &miFuncs; 2824202a189Smrg if (!screen_priv->shmFuncs->CreatePixmap) 28305b261ecSmrg sharedPixmaps = xFalse; 28405b261ecSmrg } 28505b261ecSmrg if (sharedPixmaps) 28605b261ecSmrg for (i = 0; i < screenInfo.numScreens; i++) 28705b261ecSmrg { 2884202a189Smrg ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]); 2894202a189Smrg screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap; 29005b261ecSmrg screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap; 29105b261ecSmrg } 29205b261ecSmrg } 2934202a189Smrg ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg"); 29405b261ecSmrg if (ShmSegType && 29505b261ecSmrg (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors, 29605b261ecSmrg ProcShmDispatch, SProcShmDispatch, 29705b261ecSmrg ShmResetProc, StandardMinorOpcode))) 29805b261ecSmrg { 29905b261ecSmrg ShmReqCode = (unsigned char)extEntry->base; 30005b261ecSmrg ShmCompletionCode = extEntry->eventBase; 30105b261ecSmrg BadShmSegCode = extEntry->errorBase; 3024202a189Smrg SetResourceTypeErrorValue(ShmSegType, BadShmSegCode); 30305b261ecSmrg EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent; 30405b261ecSmrg } 30505b261ecSmrg} 30605b261ecSmrg 30705b261ecSmrg/*ARGSUSED*/ 30805b261ecSmrgstatic void 3094642e01fSmrgShmResetProc(ExtensionEntry *extEntry) 31005b261ecSmrg{ 31105b261ecSmrg int i; 3124202a189Smrg for (i = 0; i < screenInfo.numScreens; i++) 3134202a189Smrg ShmRegisterFuncs(screenInfo.screens[i], NULL); 31405b261ecSmrg} 31505b261ecSmrg 3164202a189Smrgvoid 3174642e01fSmrgShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs) 31805b261ecSmrg{ 3194202a189Smrg if (!ShmRegisterPrivates()) 3204202a189Smrg return; 3214202a189Smrg ShmInitScreenPriv(pScreen)->shmFuncs = funcs; 32205b261ecSmrg} 32305b261ecSmrg 32405b261ecSmrgstatic Bool 32505b261ecSmrgShmDestroyPixmap (PixmapPtr pPixmap) 32605b261ecSmrg{ 32705b261ecSmrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 3284202a189Smrg ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); 32905b261ecSmrg Bool ret; 33005b261ecSmrg if (pPixmap->refcnt == 1) 33105b261ecSmrg { 33205b261ecSmrg ShmDescPtr shmdesc; 3334642e01fSmrg shmdesc = (ShmDescPtr)dixLookupPrivate(&pPixmap->devPrivates, 3344202a189Smrg shmPixmapPrivateKey); 33505b261ecSmrg if (shmdesc) 33605b261ecSmrg ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id); 33705b261ecSmrg } 33805b261ecSmrg 3394202a189Smrg pScreen->DestroyPixmap = screen_priv->destroyPixmap; 34005b261ecSmrg ret = (*pScreen->DestroyPixmap) (pPixmap); 3414202a189Smrg screen_priv->destroyPixmap = pScreen->DestroyPixmap; 34205b261ecSmrg pScreen->DestroyPixmap = ShmDestroyPixmap; 34305b261ecSmrg return ret; 34405b261ecSmrg} 34505b261ecSmrg 3464202a189Smrgvoid 3474642e01fSmrgShmRegisterFbFuncs(ScreenPtr pScreen) 34805b261ecSmrg{ 3494202a189Smrg ShmRegisterFuncs(pScreen, &fbFuncs); 35005b261ecSmrg} 35105b261ecSmrg 35205b261ecSmrgstatic int 3534642e01fSmrgProcShmQueryVersion(ClientPtr client) 35405b261ecSmrg{ 35505b261ecSmrg xShmQueryVersionReply rep; 3564642e01fSmrg int n; 35705b261ecSmrg 35805b261ecSmrg REQUEST_SIZE_MATCH(xShmQueryVersionReq); 3594202a189Smrg memset(&rep, 0, sizeof(xShmQueryVersionReply)); 36005b261ecSmrg rep.type = X_Reply; 36105b261ecSmrg rep.length = 0; 36205b261ecSmrg rep.sequenceNumber = client->sequence; 36305b261ecSmrg rep.sharedPixmaps = sharedPixmaps; 3644642e01fSmrg rep.pixmapFormat = sharedPixmaps ? ZPixmap : 0; 3654202a189Smrg rep.majorVersion = SERVER_SHM_MAJOR_VERSION; 3664202a189Smrg rep.minorVersion = SERVER_SHM_MINOR_VERSION; 36705b261ecSmrg rep.uid = geteuid(); 36805b261ecSmrg rep.gid = getegid(); 36905b261ecSmrg if (client->swapped) { 37005b261ecSmrg swaps(&rep.sequenceNumber, n); 37105b261ecSmrg swapl(&rep.length, n); 37205b261ecSmrg swaps(&rep.majorVersion, n); 37305b261ecSmrg swaps(&rep.minorVersion, n); 37405b261ecSmrg swaps(&rep.uid, n); 37505b261ecSmrg swaps(&rep.gid, n); 37605b261ecSmrg } 37705b261ecSmrg WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep); 3784202a189Smrg return Success; 37905b261ecSmrg} 38005b261ecSmrg 38105b261ecSmrg/* 38205b261ecSmrg * Simulate the access() system call for a shared memory segement, 38305b261ecSmrg * using the credentials from the client if available 38405b261ecSmrg */ 38505b261ecSmrgstatic int 3864642e01fSmrgshm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly) 38705b261ecSmrg{ 38805b261ecSmrg int uid, gid; 38905b261ecSmrg mode_t mask; 3904642e01fSmrg int uidset = 0, gidset = 0; 3914642e01fSmrg LocalClientCredRec *lcc; 3924642e01fSmrg 3934642e01fSmrg if (GetLocalClientCreds(client, &lcc) != -1) { 39405b261ecSmrg 3954642e01fSmrg if (lcc->fieldsSet & LCC_UID_SET) { 3964642e01fSmrg uid = lcc->euid; 3974642e01fSmrg uidset = 1; 3984642e01fSmrg } 3994642e01fSmrg if (lcc->fieldsSet & LCC_GID_SET) { 4004642e01fSmrg gid = lcc->egid; 4014642e01fSmrg gidset = 1; 4024642e01fSmrg } 4034642e01fSmrg 4044642e01fSmrg#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID) 4054642e01fSmrg if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1) 4064642e01fSmrg || (lcc->zoneid != SHMPERM_ZONEID(perm))) { 4074642e01fSmrg uidset = 0; 4084642e01fSmrg gidset = 0; 40905b261ecSmrg } 4104642e01fSmrg#endif 4114642e01fSmrg FreeLocalClientCreds(lcc); 4124642e01fSmrg 4134642e01fSmrg if (uidset) { 4144642e01fSmrg /* User id 0 always gets access */ 4154642e01fSmrg if (uid == 0) { 4164642e01fSmrg return 0; 4174642e01fSmrg } 4184642e01fSmrg /* Check the owner */ 4194642e01fSmrg if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) { 4204642e01fSmrg mask = S_IRUSR; 4214642e01fSmrg if (!readonly) { 4224642e01fSmrg mask |= S_IWUSR; 4234642e01fSmrg } 4244642e01fSmrg return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; 42505b261ecSmrg } 42605b261ecSmrg } 4274642e01fSmrg 4284642e01fSmrg if (gidset) { 4294642e01fSmrg /* Check the group */ 4304642e01fSmrg if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) { 4314642e01fSmrg mask = S_IRGRP; 4324642e01fSmrg if (!readonly) { 4334642e01fSmrg mask |= S_IWGRP; 4344642e01fSmrg } 4354642e01fSmrg return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; 43605b261ecSmrg } 43705b261ecSmrg } 43805b261ecSmrg } 43905b261ecSmrg /* Otherwise, check everyone else */ 44005b261ecSmrg mask = S_IROTH; 44105b261ecSmrg if (!readonly) { 44205b261ecSmrg mask |= S_IWOTH; 44305b261ecSmrg } 4444642e01fSmrg return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; 44505b261ecSmrg} 44605b261ecSmrg 44705b261ecSmrgstatic int 4484642e01fSmrgProcShmAttach(ClientPtr client) 44905b261ecSmrg{ 4504642e01fSmrg SHMSTAT_TYPE buf; 45105b261ecSmrg ShmDescPtr shmdesc; 45205b261ecSmrg REQUEST(xShmAttachReq); 45305b261ecSmrg 45405b261ecSmrg REQUEST_SIZE_MATCH(xShmAttachReq); 45505b261ecSmrg LEGAL_NEW_RESOURCE(stuff->shmseg, client); 45605b261ecSmrg if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) 45705b261ecSmrg { 45805b261ecSmrg client->errorValue = stuff->readOnly; 4594202a189Smrg return BadValue; 46005b261ecSmrg } 46105b261ecSmrg for (shmdesc = Shmsegs; 46205b261ecSmrg shmdesc && (shmdesc->shmid != stuff->shmid); 46305b261ecSmrg shmdesc = shmdesc->next) 46405b261ecSmrg ; 46505b261ecSmrg if (shmdesc) 46605b261ecSmrg { 46705b261ecSmrg if (!stuff->readOnly && !shmdesc->writable) 46805b261ecSmrg return BadAccess; 46905b261ecSmrg shmdesc->refcnt++; 47005b261ecSmrg } 47105b261ecSmrg else 47205b261ecSmrg { 4734202a189Smrg shmdesc = malloc(sizeof(ShmDescRec)); 47405b261ecSmrg if (!shmdesc) 47505b261ecSmrg return BadAlloc; 47605b261ecSmrg shmdesc->addr = shmat(stuff->shmid, 0, 47705b261ecSmrg stuff->readOnly ? SHM_RDONLY : 0); 47805b261ecSmrg if ((shmdesc->addr == ((char *)-1)) || 4794642e01fSmrg SHMSTAT(stuff->shmid, &buf)) 48005b261ecSmrg { 4814202a189Smrg free(shmdesc); 48205b261ecSmrg return BadAccess; 48305b261ecSmrg } 48405b261ecSmrg 48505b261ecSmrg /* The attach was performed with root privs. We must 48605b261ecSmrg * do manual checking of access rights for the credentials 48705b261ecSmrg * of the client */ 48805b261ecSmrg 4894642e01fSmrg if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) { 49005b261ecSmrg shmdt(shmdesc->addr); 4914202a189Smrg free(shmdesc); 49205b261ecSmrg return BadAccess; 49305b261ecSmrg } 49405b261ecSmrg 49505b261ecSmrg shmdesc->shmid = stuff->shmid; 49605b261ecSmrg shmdesc->refcnt = 1; 49705b261ecSmrg shmdesc->writable = !stuff->readOnly; 4984642e01fSmrg shmdesc->size = SHM_SEGSZ(buf); 49905b261ecSmrg shmdesc->next = Shmsegs; 50005b261ecSmrg Shmsegs = shmdesc; 50105b261ecSmrg } 50205b261ecSmrg if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc)) 50305b261ecSmrg return BadAlloc; 5044202a189Smrg return Success; 50505b261ecSmrg} 50605b261ecSmrg 50705b261ecSmrg/*ARGSUSED*/ 50805b261ecSmrgstatic int 5094642e01fSmrgShmDetachSegment(pointer value, /* must conform to DeleteType */ 5104642e01fSmrg XID shmseg) 51105b261ecSmrg{ 51205b261ecSmrg ShmDescPtr shmdesc = (ShmDescPtr)value; 51305b261ecSmrg ShmDescPtr *prev; 51405b261ecSmrg 51505b261ecSmrg if (--shmdesc->refcnt) 51605b261ecSmrg return TRUE; 51705b261ecSmrg shmdt(shmdesc->addr); 51805b261ecSmrg for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next) 51905b261ecSmrg ; 52005b261ecSmrg *prev = shmdesc->next; 5214202a189Smrg free(shmdesc); 52205b261ecSmrg return Success; 52305b261ecSmrg} 52405b261ecSmrg 52505b261ecSmrgstatic int 5264642e01fSmrgProcShmDetach(ClientPtr client) 52705b261ecSmrg{ 52805b261ecSmrg ShmDescPtr shmdesc; 52905b261ecSmrg REQUEST(xShmDetachReq); 53005b261ecSmrg 53105b261ecSmrg REQUEST_SIZE_MATCH(xShmDetachReq); 53205b261ecSmrg VERIFY_SHMSEG(stuff->shmseg, shmdesc, client); 53305b261ecSmrg FreeResource(stuff->shmseg, RT_NONE); 5344202a189Smrg return Success; 53505b261ecSmrg} 53605b261ecSmrg 5374642e01fSmrg/* 5384642e01fSmrg * If the given request doesn't exactly match PutImage's constraints, 5394642e01fSmrg * wrap the image in a scratch pixmap header and let CopyArea sort it out. 5404642e01fSmrg */ 54105b261ecSmrgstatic void 5424642e01fSmrgdoShmPutImage(DrawablePtr dst, GCPtr pGC, 5434642e01fSmrg int depth, unsigned int format, 5444642e01fSmrg int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, 5454642e01fSmrg char *data) 54605b261ecSmrg{ 5474642e01fSmrg PixmapPtr pPixmap; 5484202a189Smrg 5494202a189Smrg if (format == ZPixmap || depth == 1) { 5504202a189Smrg pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth, 5514202a189Smrg BitsPerPixel(depth), 5524202a189Smrg PixmapBytePad(w, depth), 5534202a189Smrg data); 5544202a189Smrg if (!pPixmap) 5554202a189Smrg return; 5564202a189Smrg pGC->ops->CopyArea((DrawablePtr)pPixmap, dst, pGC, sx, sy, sw, sh, dx, dy); 5574202a189Smrg FreeScratchPixmapHeader(pPixmap); 5584202a189Smrg } else { 5594202a189Smrg GCPtr putGC = GetScratchGC(depth, dst->pScreen); 5604202a189Smrg 5614202a189Smrg if (!putGC) 5624202a189Smrg return; 5634202a189Smrg 5644202a189Smrg pPixmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth, 5654202a189Smrg CREATE_PIXMAP_USAGE_SCRATCH); 5664202a189Smrg if (!pPixmap) { 5674202a189Smrg FreeScratchGC(putGC); 5684202a189Smrg return; 5694202a189Smrg } 5704202a189Smrg ValidateGC(&pPixmap->drawable, putGC); 5714202a189Smrg (*putGC->ops->PutImage)(&pPixmap->drawable, putGC, depth, -sx, -sy, w, h, 0, 5724202a189Smrg (format == XYPixmap) ? XYPixmap : ZPixmap, data); 5734202a189Smrg FreeScratchGC(putGC); 5744202a189Smrg if (format == XYBitmap) 5754202a189Smrg (void)(*pGC->ops->CopyPlane)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, 5764202a189Smrg dx, dy, 1L); 5774202a189Smrg else 5784202a189Smrg (void)(*pGC->ops->CopyArea)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, 5794202a189Smrg dx, dy); 5804202a189Smrg (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 5814202a189Smrg } 58205b261ecSmrg} 58305b261ecSmrg 58405b261ecSmrg#ifdef PANORAMIX 58505b261ecSmrgstatic int 5864642e01fSmrgProcPanoramiXShmPutImage(ClientPtr client) 58705b261ecSmrg{ 5884202a189Smrg int j, result, orig_x, orig_y; 58905b261ecSmrg PanoramiXRes *draw, *gc; 59005b261ecSmrg Bool sendEvent, isRoot; 59105b261ecSmrg 59205b261ecSmrg REQUEST(xShmPutImageReq); 59305b261ecSmrg REQUEST_SIZE_MATCH(xShmPutImageReq); 59405b261ecSmrg 5954202a189Smrg result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 5964202a189Smrg XRC_DRAWABLE, client, DixWriteAccess); 5974202a189Smrg if (result != Success) 5984202a189Smrg return (result == BadValue) ? BadDrawable : result; 59905b261ecSmrg 6004202a189Smrg result = dixLookupResourceByType((pointer *)&gc, stuff->gc, 6014202a189Smrg XRT_GC, client, DixReadAccess); 6024202a189Smrg if (result != Success) 6034202a189Smrg return result; 60405b261ecSmrg 60505b261ecSmrg isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 60605b261ecSmrg 60705b261ecSmrg orig_x = stuff->dstX; 60805b261ecSmrg orig_y = stuff->dstY; 60905b261ecSmrg sendEvent = stuff->sendEvent; 61005b261ecSmrg stuff->sendEvent = 0; 61105b261ecSmrg FOR_NSCREENS(j) { 61205b261ecSmrg if(!j) stuff->sendEvent = sendEvent; 61305b261ecSmrg stuff->drawable = draw->info[j].id; 61405b261ecSmrg stuff->gc = gc->info[j].id; 61505b261ecSmrg if (isRoot) { 6164202a189Smrg stuff->dstX = orig_x - screenInfo.screens[j]->x; 6174202a189Smrg stuff->dstY = orig_y - screenInfo.screens[j]->y; 61805b261ecSmrg } 61905b261ecSmrg result = ProcShmPutImage(client); 6204202a189Smrg if(result != Success) break; 62105b261ecSmrg } 6224202a189Smrg return result; 62305b261ecSmrg} 62405b261ecSmrg 62505b261ecSmrgstatic int 62605b261ecSmrgProcPanoramiXShmGetImage(ClientPtr client) 62705b261ecSmrg{ 62805b261ecSmrg PanoramiXRes *draw; 6294202a189Smrg DrawablePtr *drawables; 63005b261ecSmrg DrawablePtr pDraw; 63105b261ecSmrg xShmGetImageReply xgi; 63205b261ecSmrg ShmDescPtr shmdesc; 63305b261ecSmrg int i, x, y, w, h, format, rc; 63405b261ecSmrg Mask plane = 0, planemask; 63505b261ecSmrg long lenPer = 0, length, widthBytesLine; 63605b261ecSmrg Bool isRoot; 63705b261ecSmrg 63805b261ecSmrg REQUEST(xShmGetImageReq); 63905b261ecSmrg 64005b261ecSmrg REQUEST_SIZE_MATCH(xShmGetImageReq); 64105b261ecSmrg 64205b261ecSmrg if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) { 64305b261ecSmrg client->errorValue = stuff->format; 6444202a189Smrg return BadValue; 64505b261ecSmrg } 64605b261ecSmrg 6474202a189Smrg rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 6484202a189Smrg XRC_DRAWABLE, client, DixWriteAccess); 6494202a189Smrg if (rc != Success) 6504202a189Smrg return (rc == BadValue) ? BadDrawable : rc; 65105b261ecSmrg 65205b261ecSmrg if (draw->type == XRT_PIXMAP) 65305b261ecSmrg return ProcShmGetImage(client); 65405b261ecSmrg 65505b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 6564642e01fSmrg DixReadAccess); 65705b261ecSmrg if (rc != Success) 65805b261ecSmrg return rc; 65905b261ecSmrg 66005b261ecSmrg VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); 66105b261ecSmrg 66205b261ecSmrg x = stuff->x; 66305b261ecSmrg y = stuff->y; 66405b261ecSmrg w = stuff->width; 66505b261ecSmrg h = stuff->height; 66605b261ecSmrg format = stuff->format; 66705b261ecSmrg planemask = stuff->planeMask; 66805b261ecSmrg 66905b261ecSmrg isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 67005b261ecSmrg 67105b261ecSmrg if(isRoot) { 67205b261ecSmrg if( /* check for being onscreen */ 67305b261ecSmrg x < 0 || x + w > PanoramiXPixWidth || 67405b261ecSmrg y < 0 || y + h > PanoramiXPixHeight ) 6754202a189Smrg return BadMatch; 67605b261ecSmrg } else { 67705b261ecSmrg if( /* check for being onscreen */ 6784202a189Smrg screenInfo.screens[0]->x + pDraw->x + x < 0 || 6794202a189Smrg screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth || 6804202a189Smrg screenInfo.screens[0]->y + pDraw->y + y < 0 || 6814202a189Smrg screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight || 68205b261ecSmrg /* check for being inside of border */ 68305b261ecSmrg x < - wBorderWidth((WindowPtr)pDraw) || 68405b261ecSmrg x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || 68505b261ecSmrg y < -wBorderWidth((WindowPtr)pDraw) || 68605b261ecSmrg y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height) 6874202a189Smrg return BadMatch; 68805b261ecSmrg } 68905b261ecSmrg 6904202a189Smrg drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr)); 6914202a189Smrg if(!drawables) 6924202a189Smrg return BadAlloc; 6934202a189Smrg 69405b261ecSmrg drawables[0] = pDraw; 69505b261ecSmrg for(i = 1; i < PanoramiXNumScreens; i++) { 69605b261ecSmrg rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, 6974642e01fSmrg DixReadAccess); 69805b261ecSmrg if (rc != Success) 6994202a189Smrg { 7004202a189Smrg free(drawables); 70105b261ecSmrg return rc; 7024202a189Smrg } 70305b261ecSmrg } 70405b261ecSmrg 70505b261ecSmrg xgi.visual = wVisual(((WindowPtr)pDraw)); 70605b261ecSmrg xgi.type = X_Reply; 70705b261ecSmrg xgi.length = 0; 70805b261ecSmrg xgi.sequenceNumber = client->sequence; 70905b261ecSmrg xgi.depth = pDraw->depth; 71005b261ecSmrg 71105b261ecSmrg if(format == ZPixmap) { 71205b261ecSmrg widthBytesLine = PixmapBytePad(w, pDraw->depth); 71305b261ecSmrg length = widthBytesLine * h; 71405b261ecSmrg } else { 71505b261ecSmrg widthBytesLine = PixmapBytePad(w, 1); 71605b261ecSmrg lenPer = widthBytesLine * h; 71705b261ecSmrg plane = ((Mask)1) << (pDraw->depth - 1); 71805b261ecSmrg length = lenPer * Ones(planemask & (plane | (plane - 1))); 71905b261ecSmrg } 72005b261ecSmrg 72105b261ecSmrg VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); 72205b261ecSmrg xgi.size = length; 72305b261ecSmrg 72405b261ecSmrg if (length == 0) {/* nothing to do */ } 72505b261ecSmrg else if (format == ZPixmap) { 72605b261ecSmrg XineramaGetImageData(drawables, x, y, w, h, format, planemask, 72705b261ecSmrg shmdesc->addr + stuff->offset, 72805b261ecSmrg widthBytesLine, isRoot); 72905b261ecSmrg } else { 73005b261ecSmrg 73105b261ecSmrg length = stuff->offset; 73205b261ecSmrg for (; plane; plane >>= 1) { 73305b261ecSmrg if (planemask & plane) { 73405b261ecSmrg XineramaGetImageData(drawables, x, y, w, h, 73505b261ecSmrg format, plane, shmdesc->addr + length, 73605b261ecSmrg widthBytesLine, isRoot); 73705b261ecSmrg length += lenPer; 73805b261ecSmrg } 73905b261ecSmrg } 74005b261ecSmrg } 7414202a189Smrg free(drawables); 74205b261ecSmrg 74305b261ecSmrg if (client->swapped) { 7444642e01fSmrg int n; 74505b261ecSmrg swaps(&xgi.sequenceNumber, n); 74605b261ecSmrg swapl(&xgi.length, n); 74705b261ecSmrg swapl(&xgi.visual, n); 74805b261ecSmrg swapl(&xgi.size, n); 74905b261ecSmrg } 75005b261ecSmrg WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); 75105b261ecSmrg 7524202a189Smrg return Success; 75305b261ecSmrg} 75405b261ecSmrg 75505b261ecSmrgstatic int 7564642e01fSmrgProcPanoramiXShmCreatePixmap(ClientPtr client) 75705b261ecSmrg{ 75805b261ecSmrg ScreenPtr pScreen = NULL; 75905b261ecSmrg PixmapPtr pMap = NULL; 76005b261ecSmrg DrawablePtr pDraw; 76105b261ecSmrg DepthPtr pDepth; 76205b261ecSmrg int i, j, result, rc; 76305b261ecSmrg ShmDescPtr shmdesc; 76405b261ecSmrg REQUEST(xShmCreatePixmapReq); 76505b261ecSmrg unsigned int width, height, depth; 76605b261ecSmrg unsigned long size; 76705b261ecSmrg PanoramiXRes *newPix; 76805b261ecSmrg 76905b261ecSmrg REQUEST_SIZE_MATCH(xShmCreatePixmapReq); 77005b261ecSmrg client->errorValue = stuff->pid; 77105b261ecSmrg if (!sharedPixmaps) 77205b261ecSmrg return BadImplementation; 77305b261ecSmrg LEGAL_NEW_RESOURCE(stuff->pid, client); 77405b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 7754642e01fSmrg DixGetAttrAccess); 77605b261ecSmrg if (rc != Success) 77705b261ecSmrg return rc; 77805b261ecSmrg 77905b261ecSmrg VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); 78005b261ecSmrg 78105b261ecSmrg width = stuff->width; 78205b261ecSmrg height = stuff->height; 78305b261ecSmrg depth = stuff->depth; 78405b261ecSmrg if (!width || !height || !depth) 78505b261ecSmrg { 78605b261ecSmrg client->errorValue = 0; 78705b261ecSmrg return BadValue; 78805b261ecSmrg } 78905b261ecSmrg if (width > 32767 || height > 32767) 79005b261ecSmrg return BadAlloc; 79105b261ecSmrg 79205b261ecSmrg if (stuff->depth != 1) 79305b261ecSmrg { 79405b261ecSmrg pDepth = pDraw->pScreen->allowedDepths; 79505b261ecSmrg for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) 79605b261ecSmrg if (pDepth->depth == stuff->depth) 79705b261ecSmrg goto CreatePmap; 79805b261ecSmrg client->errorValue = stuff->depth; 79905b261ecSmrg return BadValue; 80005b261ecSmrg } 80105b261ecSmrg 80205b261ecSmrgCreatePmap: 80305b261ecSmrg size = PixmapBytePad(width, depth) * height; 80405b261ecSmrg if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { 80505b261ecSmrg if (size < width * height) 80605b261ecSmrg return BadAlloc; 80705b261ecSmrg } 80805b261ecSmrg /* thankfully, offset is unsigned */ 80905b261ecSmrg if (stuff->offset + size < size) 81005b261ecSmrg return BadAlloc; 81105b261ecSmrg 81205b261ecSmrg VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); 81305b261ecSmrg 8144202a189Smrg if(!(newPix = malloc(sizeof(PanoramiXRes)))) 81505b261ecSmrg return BadAlloc; 81605b261ecSmrg 81705b261ecSmrg newPix->type = XRT_PIXMAP; 81805b261ecSmrg newPix->u.pix.shared = TRUE; 81905b261ecSmrg newPix->info[0].id = stuff->pid; 82005b261ecSmrg for(j = 1; j < PanoramiXNumScreens; j++) 82105b261ecSmrg newPix->info[j].id = FakeClientID(client->index); 82205b261ecSmrg 8234202a189Smrg result = Success; 82405b261ecSmrg 82505b261ecSmrg FOR_NSCREENS(j) { 8264202a189Smrg ShmScrPrivateRec *screen_priv; 82705b261ecSmrg pScreen = screenInfo.screens[j]; 82805b261ecSmrg 8294202a189Smrg screen_priv = ShmGetScreenPriv(pScreen); 8304202a189Smrg pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen, 83105b261ecSmrg stuff->width, stuff->height, stuff->depth, 83205b261ecSmrg shmdesc->addr + stuff->offset); 83305b261ecSmrg 83405b261ecSmrg if (pMap) { 8354202a189Smrg dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); 83605b261ecSmrg shmdesc->refcnt++; 83705b261ecSmrg pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 83805b261ecSmrg pMap->drawable.id = newPix->info[j].id; 83905b261ecSmrg if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) { 84005b261ecSmrg (*pScreen->DestroyPixmap)(pMap); 84105b261ecSmrg result = BadAlloc; 84205b261ecSmrg break; 84305b261ecSmrg } 84405b261ecSmrg } else { 84505b261ecSmrg result = BadAlloc; 84605b261ecSmrg break; 84705b261ecSmrg } 84805b261ecSmrg } 84905b261ecSmrg 85005b261ecSmrg if(result == BadAlloc) { 85105b261ecSmrg while(j--) { 85205b261ecSmrg (*pScreen->DestroyPixmap)(pMap); 85305b261ecSmrg FreeResource(newPix->info[j].id, RT_NONE); 85405b261ecSmrg } 8554202a189Smrg free(newPix); 85605b261ecSmrg } else 85705b261ecSmrg AddResource(stuff->pid, XRT_PIXMAP, newPix); 85805b261ecSmrg 85905b261ecSmrg return result; 86005b261ecSmrg} 86105b261ecSmrg 86205b261ecSmrg#endif 86305b261ecSmrg 86405b261ecSmrgstatic int 8654642e01fSmrgProcShmPutImage(ClientPtr client) 86605b261ecSmrg{ 86705b261ecSmrg GCPtr pGC; 86805b261ecSmrg DrawablePtr pDraw; 86905b261ecSmrg long length; 87005b261ecSmrg ShmDescPtr shmdesc; 87105b261ecSmrg REQUEST(xShmPutImageReq); 87205b261ecSmrg 87305b261ecSmrg REQUEST_SIZE_MATCH(xShmPutImageReq); 8744642e01fSmrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 87505b261ecSmrg VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client); 87605b261ecSmrg if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse)) 87705b261ecSmrg return BadValue; 87805b261ecSmrg if (stuff->format == XYBitmap) 87905b261ecSmrg { 88005b261ecSmrg if (stuff->depth != 1) 88105b261ecSmrg return BadMatch; 88205b261ecSmrg length = PixmapBytePad(stuff->totalWidth, 1); 88305b261ecSmrg } 88405b261ecSmrg else if (stuff->format == XYPixmap) 88505b261ecSmrg { 88605b261ecSmrg if (pDraw->depth != stuff->depth) 88705b261ecSmrg return BadMatch; 88805b261ecSmrg length = PixmapBytePad(stuff->totalWidth, 1); 88905b261ecSmrg length *= stuff->depth; 89005b261ecSmrg } 89105b261ecSmrg else if (stuff->format == ZPixmap) 89205b261ecSmrg { 89305b261ecSmrg if (pDraw->depth != stuff->depth) 89405b261ecSmrg return BadMatch; 89505b261ecSmrg length = PixmapBytePad(stuff->totalWidth, stuff->depth); 89605b261ecSmrg } 89705b261ecSmrg else 89805b261ecSmrg { 89905b261ecSmrg client->errorValue = stuff->format; 90005b261ecSmrg return BadValue; 90105b261ecSmrg } 90205b261ecSmrg 90305b261ecSmrg /* 90405b261ecSmrg * There's a potential integer overflow in this check: 90505b261ecSmrg * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, 90605b261ecSmrg * client); 90705b261ecSmrg * the version below ought to avoid it 90805b261ecSmrg */ 90905b261ecSmrg if (stuff->totalHeight != 0 && 91005b261ecSmrg length > (shmdesc->size - stuff->offset)/stuff->totalHeight) { 91105b261ecSmrg client->errorValue = stuff->totalWidth; 91205b261ecSmrg return BadValue; 91305b261ecSmrg } 91405b261ecSmrg if (stuff->srcX > stuff->totalWidth) 91505b261ecSmrg { 91605b261ecSmrg client->errorValue = stuff->srcX; 91705b261ecSmrg return BadValue; 91805b261ecSmrg } 91905b261ecSmrg if (stuff->srcY > stuff->totalHeight) 92005b261ecSmrg { 92105b261ecSmrg client->errorValue = stuff->srcY; 92205b261ecSmrg return BadValue; 92305b261ecSmrg } 92405b261ecSmrg if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth) 92505b261ecSmrg { 92605b261ecSmrg client->errorValue = stuff->srcWidth; 92705b261ecSmrg return BadValue; 92805b261ecSmrg } 92905b261ecSmrg if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight) 93005b261ecSmrg { 93105b261ecSmrg client->errorValue = stuff->srcHeight; 93205b261ecSmrg return BadValue; 93305b261ecSmrg } 93405b261ecSmrg 93505b261ecSmrg if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) || 93605b261ecSmrg ((stuff->format != ZPixmap) && 93705b261ecSmrg (stuff->srcX < screenInfo.bitmapScanlinePad) && 93805b261ecSmrg ((stuff->format == XYBitmap) || 93905b261ecSmrg ((stuff->srcY == 0) && 94005b261ecSmrg (stuff->srcHeight == stuff->totalHeight))))) && 94105b261ecSmrg ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth)) 94205b261ecSmrg (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, 94305b261ecSmrg stuff->dstX, stuff->dstY, 94405b261ecSmrg stuff->totalWidth, stuff->srcHeight, 94505b261ecSmrg stuff->srcX, stuff->format, 94605b261ecSmrg shmdesc->addr + stuff->offset + 94705b261ecSmrg (stuff->srcY * length)); 94805b261ecSmrg else 9494642e01fSmrg doShmPutImage(pDraw, pGC, stuff->depth, stuff->format, 9504642e01fSmrg stuff->totalWidth, stuff->totalHeight, 9514642e01fSmrg stuff->srcX, stuff->srcY, 9524642e01fSmrg stuff->srcWidth, stuff->srcHeight, 9534642e01fSmrg stuff->dstX, stuff->dstY, 9544642e01fSmrg shmdesc->addr + stuff->offset); 95505b261ecSmrg 95605b261ecSmrg if (stuff->sendEvent) 95705b261ecSmrg { 95805b261ecSmrg xShmCompletionEvent ev; 95905b261ecSmrg 96005b261ecSmrg ev.type = ShmCompletionCode; 96105b261ecSmrg ev.drawable = stuff->drawable; 96205b261ecSmrg ev.minorEvent = X_ShmPutImage; 96305b261ecSmrg ev.majorEvent = ShmReqCode; 96405b261ecSmrg ev.shmseg = stuff->shmseg; 96505b261ecSmrg ev.offset = stuff->offset; 96605b261ecSmrg WriteEventsToClient(client, 1, (xEvent *) &ev); 96705b261ecSmrg } 96805b261ecSmrg 9694202a189Smrg return Success; 97005b261ecSmrg} 97105b261ecSmrg 97205b261ecSmrg 97305b261ecSmrg 97405b261ecSmrgstatic int 9754642e01fSmrgProcShmGetImage(ClientPtr client) 97605b261ecSmrg{ 97705b261ecSmrg DrawablePtr pDraw; 97805b261ecSmrg long lenPer = 0, length; 97905b261ecSmrg Mask plane = 0; 98005b261ecSmrg xShmGetImageReply xgi; 98105b261ecSmrg ShmDescPtr shmdesc; 98205b261ecSmrg int n, rc; 98305b261ecSmrg 98405b261ecSmrg REQUEST(xShmGetImageReq); 98505b261ecSmrg 98605b261ecSmrg REQUEST_SIZE_MATCH(xShmGetImageReq); 98705b261ecSmrg if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) 98805b261ecSmrg { 98905b261ecSmrg client->errorValue = stuff->format; 9904202a189Smrg return BadValue; 99105b261ecSmrg } 99205b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 9934642e01fSmrg DixReadAccess); 99405b261ecSmrg if (rc != Success) 99505b261ecSmrg return rc; 99605b261ecSmrg VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); 99705b261ecSmrg if (pDraw->type == DRAWABLE_WINDOW) 99805b261ecSmrg { 99905b261ecSmrg if( /* check for being viewable */ 100005b261ecSmrg !((WindowPtr) pDraw)->realized || 100105b261ecSmrg /* check for being on screen */ 100205b261ecSmrg pDraw->x + stuff->x < 0 || 100305b261ecSmrg pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width || 100405b261ecSmrg pDraw->y + stuff->y < 0 || 100505b261ecSmrg pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height || 100605b261ecSmrg /* check for being inside of border */ 100705b261ecSmrg stuff->x < - wBorderWidth((WindowPtr)pDraw) || 100805b261ecSmrg stuff->x + (int)stuff->width > 100905b261ecSmrg wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || 101005b261ecSmrg stuff->y < -wBorderWidth((WindowPtr)pDraw) || 101105b261ecSmrg stuff->y + (int)stuff->height > 101205b261ecSmrg wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height 101305b261ecSmrg ) 10144202a189Smrg return BadMatch; 101505b261ecSmrg xgi.visual = wVisual(((WindowPtr)pDraw)); 101605b261ecSmrg } 101705b261ecSmrg else 101805b261ecSmrg { 101905b261ecSmrg if (stuff->x < 0 || 102005b261ecSmrg stuff->x+(int)stuff->width > pDraw->width || 102105b261ecSmrg stuff->y < 0 || 102205b261ecSmrg stuff->y+(int)stuff->height > pDraw->height 102305b261ecSmrg ) 10244202a189Smrg return BadMatch; 102505b261ecSmrg xgi.visual = None; 102605b261ecSmrg } 102705b261ecSmrg xgi.type = X_Reply; 102805b261ecSmrg xgi.length = 0; 102905b261ecSmrg xgi.sequenceNumber = client->sequence; 103005b261ecSmrg xgi.depth = pDraw->depth; 103105b261ecSmrg if(stuff->format == ZPixmap) 103205b261ecSmrg { 103305b261ecSmrg length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height; 103405b261ecSmrg } 103505b261ecSmrg else 103605b261ecSmrg { 103705b261ecSmrg lenPer = PixmapBytePad(stuff->width, 1) * stuff->height; 103805b261ecSmrg plane = ((Mask)1) << (pDraw->depth - 1); 103905b261ecSmrg /* only planes asked for */ 104005b261ecSmrg length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1))); 104105b261ecSmrg } 104205b261ecSmrg 104305b261ecSmrg VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); 104405b261ecSmrg xgi.size = length; 104505b261ecSmrg 104605b261ecSmrg if (length == 0) 104705b261ecSmrg { 104805b261ecSmrg /* nothing to do */ 104905b261ecSmrg } 105005b261ecSmrg else if (stuff->format == ZPixmap) 105105b261ecSmrg { 105205b261ecSmrg (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y, 105305b261ecSmrg stuff->width, stuff->height, 105405b261ecSmrg stuff->format, stuff->planeMask, 105505b261ecSmrg shmdesc->addr + stuff->offset); 105605b261ecSmrg } 105705b261ecSmrg else 105805b261ecSmrg { 105905b261ecSmrg 106005b261ecSmrg length = stuff->offset; 106105b261ecSmrg for (; plane; plane >>= 1) 106205b261ecSmrg { 106305b261ecSmrg if (stuff->planeMask & plane) 106405b261ecSmrg { 106505b261ecSmrg (*pDraw->pScreen->GetImage)(pDraw, 106605b261ecSmrg stuff->x, stuff->y, 106705b261ecSmrg stuff->width, stuff->height, 106805b261ecSmrg stuff->format, plane, 106905b261ecSmrg shmdesc->addr + length); 107005b261ecSmrg length += lenPer; 107105b261ecSmrg } 107205b261ecSmrg } 107305b261ecSmrg } 107405b261ecSmrg 107505b261ecSmrg if (client->swapped) { 107605b261ecSmrg swaps(&xgi.sequenceNumber, n); 107705b261ecSmrg swapl(&xgi.length, n); 107805b261ecSmrg swapl(&xgi.visual, n); 107905b261ecSmrg swapl(&xgi.size, n); 108005b261ecSmrg } 108105b261ecSmrg WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); 108205b261ecSmrg 10834202a189Smrg return Success; 108405b261ecSmrg} 108505b261ecSmrg 108605b261ecSmrgstatic PixmapPtr 10874642e01fSmrgfbShmCreatePixmap (ScreenPtr pScreen, 10884642e01fSmrg int width, int height, int depth, char *addr) 108905b261ecSmrg{ 10904642e01fSmrg PixmapPtr pPixmap; 109105b261ecSmrg 10924642e01fSmrg pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); 109305b261ecSmrg if (!pPixmap) 109405b261ecSmrg return NullPixmap; 109505b261ecSmrg 109605b261ecSmrg if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth, 109705b261ecSmrg BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) { 109805b261ecSmrg (*pScreen->DestroyPixmap)(pPixmap); 109905b261ecSmrg return NullPixmap; 110005b261ecSmrg } 110105b261ecSmrg return pPixmap; 110205b261ecSmrg} 110305b261ecSmrg 110405b261ecSmrgstatic int 11054642e01fSmrgProcShmCreatePixmap(ClientPtr client) 110605b261ecSmrg{ 110705b261ecSmrg PixmapPtr pMap; 110805b261ecSmrg DrawablePtr pDraw; 110905b261ecSmrg DepthPtr pDepth; 11104642e01fSmrg int i, rc; 111105b261ecSmrg ShmDescPtr shmdesc; 11124202a189Smrg ShmScrPrivateRec *screen_priv; 111305b261ecSmrg REQUEST(xShmCreatePixmapReq); 111405b261ecSmrg unsigned int width, height, depth; 111505b261ecSmrg unsigned long size; 111605b261ecSmrg 111705b261ecSmrg REQUEST_SIZE_MATCH(xShmCreatePixmapReq); 111805b261ecSmrg client->errorValue = stuff->pid; 111905b261ecSmrg if (!sharedPixmaps) 112005b261ecSmrg return BadImplementation; 112105b261ecSmrg LEGAL_NEW_RESOURCE(stuff->pid, client); 112205b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 11234642e01fSmrg DixGetAttrAccess); 112405b261ecSmrg if (rc != Success) 112505b261ecSmrg return rc; 112605b261ecSmrg 112705b261ecSmrg VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); 112805b261ecSmrg 112905b261ecSmrg width = stuff->width; 113005b261ecSmrg height = stuff->height; 113105b261ecSmrg depth = stuff->depth; 113205b261ecSmrg if (!width || !height || !depth) 113305b261ecSmrg { 113405b261ecSmrg client->errorValue = 0; 113505b261ecSmrg return BadValue; 113605b261ecSmrg } 113705b261ecSmrg if (width > 32767 || height > 32767) 113805b261ecSmrg return BadAlloc; 113905b261ecSmrg 114005b261ecSmrg if (stuff->depth != 1) 114105b261ecSmrg { 114205b261ecSmrg pDepth = pDraw->pScreen->allowedDepths; 114305b261ecSmrg for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) 114405b261ecSmrg if (pDepth->depth == stuff->depth) 114505b261ecSmrg goto CreatePmap; 114605b261ecSmrg client->errorValue = stuff->depth; 114705b261ecSmrg return BadValue; 114805b261ecSmrg } 114905b261ecSmrg 115005b261ecSmrgCreatePmap: 115105b261ecSmrg size = PixmapBytePad(width, depth) * height; 115205b261ecSmrg if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { 115305b261ecSmrg if (size < width * height) 115405b261ecSmrg return BadAlloc; 115505b261ecSmrg } 115605b261ecSmrg /* thankfully, offset is unsigned */ 115705b261ecSmrg if (stuff->offset + size < size) 115805b261ecSmrg return BadAlloc; 115905b261ecSmrg 116005b261ecSmrg VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); 11614202a189Smrg screen_priv = ShmGetScreenPriv(pDraw->pScreen); 11624202a189Smrg pMap = (*screen_priv->shmFuncs->CreatePixmap)( 116305b261ecSmrg pDraw->pScreen, stuff->width, 116405b261ecSmrg stuff->height, stuff->depth, 116505b261ecSmrg shmdesc->addr + stuff->offset); 116605b261ecSmrg if (pMap) 116705b261ecSmrg { 11684642e01fSmrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, 11694642e01fSmrg pMap, RT_NONE, NULL, DixCreateAccess); 11704642e01fSmrg if (rc != Success) { 11714642e01fSmrg pDraw->pScreen->DestroyPixmap(pMap); 11724642e01fSmrg return rc; 11734642e01fSmrg } 11744202a189Smrg dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); 117505b261ecSmrg shmdesc->refcnt++; 117605b261ecSmrg pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 117705b261ecSmrg pMap->drawable.id = stuff->pid; 117805b261ecSmrg if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) 117905b261ecSmrg { 11804202a189Smrg return Success; 118105b261ecSmrg } 11824642e01fSmrg pDraw->pScreen->DestroyPixmap(pMap); 118305b261ecSmrg } 11844202a189Smrg return BadAlloc; 118505b261ecSmrg} 118605b261ecSmrg 118705b261ecSmrgstatic int 11884642e01fSmrgProcShmDispatch (ClientPtr client) 118905b261ecSmrg{ 119005b261ecSmrg REQUEST(xReq); 119105b261ecSmrg switch (stuff->data) 119205b261ecSmrg { 119305b261ecSmrg case X_ShmQueryVersion: 119405b261ecSmrg return ProcShmQueryVersion(client); 119505b261ecSmrg case X_ShmAttach: 119605b261ecSmrg return ProcShmAttach(client); 119705b261ecSmrg case X_ShmDetach: 119805b261ecSmrg return ProcShmDetach(client); 119905b261ecSmrg case X_ShmPutImage: 120005b261ecSmrg#ifdef PANORAMIX 120105b261ecSmrg if ( !noPanoramiXExtension ) 120205b261ecSmrg return ProcPanoramiXShmPutImage(client); 120305b261ecSmrg#endif 120405b261ecSmrg return ProcShmPutImage(client); 120505b261ecSmrg case X_ShmGetImage: 120605b261ecSmrg#ifdef PANORAMIX 120705b261ecSmrg if ( !noPanoramiXExtension ) 120805b261ecSmrg return ProcPanoramiXShmGetImage(client); 120905b261ecSmrg#endif 121005b261ecSmrg return ProcShmGetImage(client); 121105b261ecSmrg case X_ShmCreatePixmap: 121205b261ecSmrg#ifdef PANORAMIX 121305b261ecSmrg if ( !noPanoramiXExtension ) 121405b261ecSmrg return ProcPanoramiXShmCreatePixmap(client); 121505b261ecSmrg#endif 121605b261ecSmrg return ProcShmCreatePixmap(client); 121705b261ecSmrg default: 121805b261ecSmrg return BadRequest; 121905b261ecSmrg } 122005b261ecSmrg} 122105b261ecSmrg 122205b261ecSmrgstatic void 12234642e01fSmrgSShmCompletionEvent(xShmCompletionEvent *from, xShmCompletionEvent *to) 122405b261ecSmrg{ 122505b261ecSmrg to->type = from->type; 122605b261ecSmrg cpswaps(from->sequenceNumber, to->sequenceNumber); 122705b261ecSmrg cpswapl(from->drawable, to->drawable); 122805b261ecSmrg cpswaps(from->minorEvent, to->minorEvent); 122905b261ecSmrg to->majorEvent = from->majorEvent; 123005b261ecSmrg cpswapl(from->shmseg, to->shmseg); 123105b261ecSmrg cpswapl(from->offset, to->offset); 123205b261ecSmrg} 123305b261ecSmrg 123405b261ecSmrgstatic int 12354642e01fSmrgSProcShmQueryVersion(ClientPtr client) 123605b261ecSmrg{ 12374642e01fSmrg int n; 123805b261ecSmrg REQUEST(xShmQueryVersionReq); 123905b261ecSmrg 124005b261ecSmrg swaps(&stuff->length, n); 124105b261ecSmrg return ProcShmQueryVersion(client); 124205b261ecSmrg} 124305b261ecSmrg 124405b261ecSmrgstatic int 12454642e01fSmrgSProcShmAttach(ClientPtr client) 124605b261ecSmrg{ 12474642e01fSmrg int n; 124805b261ecSmrg REQUEST(xShmAttachReq); 124905b261ecSmrg swaps(&stuff->length, n); 125005b261ecSmrg REQUEST_SIZE_MATCH(xShmAttachReq); 125105b261ecSmrg swapl(&stuff->shmseg, n); 125205b261ecSmrg swapl(&stuff->shmid, n); 125305b261ecSmrg return ProcShmAttach(client); 125405b261ecSmrg} 125505b261ecSmrg 125605b261ecSmrgstatic int 12574642e01fSmrgSProcShmDetach(ClientPtr client) 125805b261ecSmrg{ 12594642e01fSmrg int n; 126005b261ecSmrg REQUEST(xShmDetachReq); 126105b261ecSmrg swaps(&stuff->length, n); 126205b261ecSmrg REQUEST_SIZE_MATCH(xShmDetachReq); 126305b261ecSmrg swapl(&stuff->shmseg, n); 126405b261ecSmrg return ProcShmDetach(client); 126505b261ecSmrg} 126605b261ecSmrg 126705b261ecSmrgstatic int 12684642e01fSmrgSProcShmPutImage(ClientPtr client) 126905b261ecSmrg{ 12704642e01fSmrg int n; 127105b261ecSmrg REQUEST(xShmPutImageReq); 127205b261ecSmrg swaps(&stuff->length, n); 127305b261ecSmrg REQUEST_SIZE_MATCH(xShmPutImageReq); 127405b261ecSmrg swapl(&stuff->drawable, n); 127505b261ecSmrg swapl(&stuff->gc, n); 127605b261ecSmrg swaps(&stuff->totalWidth, n); 127705b261ecSmrg swaps(&stuff->totalHeight, n); 127805b261ecSmrg swaps(&stuff->srcX, n); 127905b261ecSmrg swaps(&stuff->srcY, n); 128005b261ecSmrg swaps(&stuff->srcWidth, n); 128105b261ecSmrg swaps(&stuff->srcHeight, n); 128205b261ecSmrg swaps(&stuff->dstX, n); 128305b261ecSmrg swaps(&stuff->dstY, n); 128405b261ecSmrg swapl(&stuff->shmseg, n); 128505b261ecSmrg swapl(&stuff->offset, n); 128605b261ecSmrg return ProcShmPutImage(client); 128705b261ecSmrg} 128805b261ecSmrg 128905b261ecSmrgstatic int 12904642e01fSmrgSProcShmGetImage(ClientPtr client) 129105b261ecSmrg{ 12924642e01fSmrg int n; 129305b261ecSmrg REQUEST(xShmGetImageReq); 129405b261ecSmrg swaps(&stuff->length, n); 129505b261ecSmrg REQUEST_SIZE_MATCH(xShmGetImageReq); 129605b261ecSmrg swapl(&stuff->drawable, n); 129705b261ecSmrg swaps(&stuff->x, n); 129805b261ecSmrg swaps(&stuff->y, n); 129905b261ecSmrg swaps(&stuff->width, n); 130005b261ecSmrg swaps(&stuff->height, n); 130105b261ecSmrg swapl(&stuff->planeMask, n); 130205b261ecSmrg swapl(&stuff->shmseg, n); 130305b261ecSmrg swapl(&stuff->offset, n); 130405b261ecSmrg return ProcShmGetImage(client); 130505b261ecSmrg} 130605b261ecSmrg 130705b261ecSmrgstatic int 13084642e01fSmrgSProcShmCreatePixmap(ClientPtr client) 130905b261ecSmrg{ 13104642e01fSmrg int n; 131105b261ecSmrg REQUEST(xShmCreatePixmapReq); 131205b261ecSmrg swaps(&stuff->length, n); 131305b261ecSmrg REQUEST_SIZE_MATCH(xShmCreatePixmapReq); 131405b261ecSmrg swapl(&stuff->pid, n); 131505b261ecSmrg swapl(&stuff->drawable, n); 131605b261ecSmrg swaps(&stuff->width, n); 131705b261ecSmrg swaps(&stuff->height, n); 131805b261ecSmrg swapl(&stuff->shmseg, n); 131905b261ecSmrg swapl(&stuff->offset, n); 132005b261ecSmrg return ProcShmCreatePixmap(client); 132105b261ecSmrg} 132205b261ecSmrg 132305b261ecSmrgstatic int 13244642e01fSmrgSProcShmDispatch (ClientPtr client) 132505b261ecSmrg{ 132605b261ecSmrg REQUEST(xReq); 132705b261ecSmrg switch (stuff->data) 132805b261ecSmrg { 132905b261ecSmrg case X_ShmQueryVersion: 133005b261ecSmrg return SProcShmQueryVersion(client); 133105b261ecSmrg case X_ShmAttach: 133205b261ecSmrg return SProcShmAttach(client); 133305b261ecSmrg case X_ShmDetach: 133405b261ecSmrg return SProcShmDetach(client); 133505b261ecSmrg case X_ShmPutImage: 133605b261ecSmrg return SProcShmPutImage(client); 133705b261ecSmrg case X_ShmGetImage: 133805b261ecSmrg return SProcShmGetImage(client); 133905b261ecSmrg case X_ShmCreatePixmap: 134005b261ecSmrg return SProcShmCreatePixmap(client); 134105b261ecSmrg default: 134205b261ecSmrg return BadRequest; 134305b261ecSmrg } 134405b261ecSmrg} 1345