shm.c revision 65b04b38
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 12305b261ecSmrg 12405b261ecSmrgstatic unsigned char ShmReqCode; 1254202a189Smrgint ShmCompletionCode; 1264202a189Smrgint BadShmSegCode; 1274202a189SmrgRESTYPE ShmSegType; 12805b261ecSmrgstatic ShmDescPtr Shmsegs; 12905b261ecSmrgstatic Bool sharedPixmaps; 1304202a189Smrgstatic DevPrivateKeyRec shmScrPrivateKeyRec; 1314202a189Smrg#define shmScrPrivateKey (&shmScrPrivateKeyRec) 1324202a189Smrgstatic DevPrivateKeyRec shmPixmapPrivateKeyRec; 1334202a189Smrg#define shmPixmapPrivateKey (&shmPixmapPrivateKeyRec) 1344642e01fSmrgstatic ShmFuncs miFuncs = {NULL, NULL}; 1354642e01fSmrgstatic ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL}; 13605b261ecSmrg 1374202a189Smrg#define ShmGetScreenPriv(s) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey)) 1384202a189Smrg 13905b261ecSmrg#define VERIFY_SHMSEG(shmseg,shmdesc,client) \ 14005b261ecSmrg{ \ 1414202a189Smrg int rc; \ 1424202a189Smrg rc = dixLookupResourceByType((pointer *)&(shmdesc), shmseg, ShmSegType, \ 1434202a189Smrg client, DixReadAccess); \ 1444202a189Smrg if (rc != Success) \ 1454202a189Smrg return rc; \ 14605b261ecSmrg} 14705b261ecSmrg 14805b261ecSmrg#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \ 14905b261ecSmrg{ \ 15005b261ecSmrg VERIFY_SHMSEG(shmseg, shmdesc, client); \ 15105b261ecSmrg if ((offset & 3) || (offset > shmdesc->size)) \ 15205b261ecSmrg { \ 15305b261ecSmrg client->errorValue = offset; \ 15405b261ecSmrg return BadValue; \ 15505b261ecSmrg } \ 15605b261ecSmrg if (needwrite && !shmdesc->writable) \ 15705b261ecSmrg return BadAccess; \ 15805b261ecSmrg} 15905b261ecSmrg 16005b261ecSmrg#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \ 16105b261ecSmrg{ \ 16205b261ecSmrg if ((offset + len) > shmdesc->size) \ 16305b261ecSmrg { \ 16405b261ecSmrg return BadAccess; \ 16505b261ecSmrg } \ 16605b261ecSmrg} 16705b261ecSmrg 16805b261ecSmrg 16905b261ecSmrg#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__) 17005b261ecSmrg#include <sys/signal.h> 17105b261ecSmrg 17205b261ecSmrgstatic Bool badSysCall = FALSE; 17305b261ecSmrg 17405b261ecSmrgstatic void 1754642e01fSmrgSigSysHandler(int signo) 17605b261ecSmrg{ 17705b261ecSmrg badSysCall = TRUE; 17805b261ecSmrg} 17905b261ecSmrg 1804642e01fSmrgstatic Bool CheckForShmSyscall(void) 18105b261ecSmrg{ 18205b261ecSmrg void (*oldHandler)(); 18305b261ecSmrg int shmid = -1; 18405b261ecSmrg 18505b261ecSmrg /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ 18605b261ecSmrg oldHandler = signal(SIGSYS, SigSysHandler); 18705b261ecSmrg 18805b261ecSmrg badSysCall = FALSE; 18905b261ecSmrg shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); 19005b261ecSmrg 19105b261ecSmrg if (shmid != -1) 19205b261ecSmrg { 19305b261ecSmrg /* Successful allocation - clean up */ 1944202a189Smrg shmctl(shmid, IPC_RMID, NULL); 19505b261ecSmrg } 19605b261ecSmrg else 19705b261ecSmrg { 19805b261ecSmrg /* Allocation failed */ 19905b261ecSmrg badSysCall = TRUE; 20005b261ecSmrg } 20105b261ecSmrg signal(SIGSYS, oldHandler); 2024202a189Smrg return !badSysCall; 20305b261ecSmrg} 20405b261ecSmrg 20505b261ecSmrg#define MUST_CHECK_FOR_SHM_SYSCALL 20605b261ecSmrg 20705b261ecSmrg#endif 20805b261ecSmrg 2094202a189Smrgstatic Bool 2104202a189SmrgShmCloseScreen(int i, ScreenPtr pScreen) 2114202a189Smrg{ 2124202a189Smrg ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); 2134202a189Smrg pScreen->CloseScreen = screen_priv->CloseScreen; 2144202a189Smrg dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL); 2154202a189Smrg free(screen_priv); 2164202a189Smrg return (*pScreen->CloseScreen) (i, pScreen); 2174202a189Smrg} 2184202a189Smrg 2194202a189Smrgstatic ShmScrPrivateRec * 2204202a189SmrgShmInitScreenPriv(ScreenPtr pScreen) 2214202a189Smrg{ 2224202a189Smrg ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); 2234202a189Smrg if (!screen_priv) 2244202a189Smrg { 2254202a189Smrg screen_priv = calloc(1, sizeof (ShmScrPrivateRec)); 2264202a189Smrg screen_priv->CloseScreen = pScreen->CloseScreen; 2274202a189Smrg dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, screen_priv); 2284202a189Smrg pScreen->CloseScreen = ShmCloseScreen; 2294202a189Smrg } 2304202a189Smrg return screen_priv; 2314202a189Smrg} 2324202a189Smrg 2334202a189Smrgstatic Bool 2344202a189SmrgShmRegisterPrivates(void) 2354202a189Smrg{ 2364202a189Smrg if (!dixRegisterPrivateKey(&shmScrPrivateKeyRec, PRIVATE_SCREEN, 0)) 2374202a189Smrg return FALSE; 2384202a189Smrg if (!dixRegisterPrivateKey(&shmPixmapPrivateKeyRec, PRIVATE_PIXMAP, 0)) 2394202a189Smrg return FALSE; 2404202a189Smrg return TRUE; 2414202a189Smrg} 2424202a189Smrg 24305b261ecSmrg/*ARGSUSED*/ 24405b261ecSmrgstatic void 2454642e01fSmrgShmResetProc(ExtensionEntry *extEntry) 24605b261ecSmrg{ 24705b261ecSmrg int i; 2484202a189Smrg for (i = 0; i < screenInfo.numScreens; i++) 2494202a189Smrg ShmRegisterFuncs(screenInfo.screens[i], NULL); 25005b261ecSmrg} 25105b261ecSmrg 2524202a189Smrgvoid 2534642e01fSmrgShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs) 25405b261ecSmrg{ 2554202a189Smrg if (!ShmRegisterPrivates()) 2564202a189Smrg return; 2574202a189Smrg ShmInitScreenPriv(pScreen)->shmFuncs = funcs; 25805b261ecSmrg} 25905b261ecSmrg 26005b261ecSmrgstatic Bool 26105b261ecSmrgShmDestroyPixmap (PixmapPtr pPixmap) 26205b261ecSmrg{ 26305b261ecSmrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 2644202a189Smrg ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); 26505b261ecSmrg Bool ret; 26605b261ecSmrg if (pPixmap->refcnt == 1) 26705b261ecSmrg { 26805b261ecSmrg ShmDescPtr shmdesc; 2694642e01fSmrg shmdesc = (ShmDescPtr)dixLookupPrivate(&pPixmap->devPrivates, 2704202a189Smrg shmPixmapPrivateKey); 27105b261ecSmrg if (shmdesc) 27205b261ecSmrg ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id); 27305b261ecSmrg } 27405b261ecSmrg 2754202a189Smrg pScreen->DestroyPixmap = screen_priv->destroyPixmap; 27605b261ecSmrg ret = (*pScreen->DestroyPixmap) (pPixmap); 2774202a189Smrg screen_priv->destroyPixmap = pScreen->DestroyPixmap; 27805b261ecSmrg pScreen->DestroyPixmap = ShmDestroyPixmap; 27905b261ecSmrg return ret; 28005b261ecSmrg} 28105b261ecSmrg 2824202a189Smrgvoid 2834642e01fSmrgShmRegisterFbFuncs(ScreenPtr pScreen) 28405b261ecSmrg{ 2854202a189Smrg ShmRegisterFuncs(pScreen, &fbFuncs); 28605b261ecSmrg} 28705b261ecSmrg 28805b261ecSmrgstatic int 2894642e01fSmrgProcShmQueryVersion(ClientPtr client) 29005b261ecSmrg{ 29105b261ecSmrg xShmQueryVersionReply rep; 2924642e01fSmrg int n; 29305b261ecSmrg 29405b261ecSmrg REQUEST_SIZE_MATCH(xShmQueryVersionReq); 2954202a189Smrg memset(&rep, 0, sizeof(xShmQueryVersionReply)); 29605b261ecSmrg rep.type = X_Reply; 29705b261ecSmrg rep.length = 0; 29805b261ecSmrg rep.sequenceNumber = client->sequence; 29905b261ecSmrg rep.sharedPixmaps = sharedPixmaps; 3004642e01fSmrg rep.pixmapFormat = sharedPixmaps ? ZPixmap : 0; 3014202a189Smrg rep.majorVersion = SERVER_SHM_MAJOR_VERSION; 3024202a189Smrg rep.minorVersion = SERVER_SHM_MINOR_VERSION; 30305b261ecSmrg rep.uid = geteuid(); 30405b261ecSmrg rep.gid = getegid(); 30505b261ecSmrg if (client->swapped) { 30605b261ecSmrg swaps(&rep.sequenceNumber, n); 30705b261ecSmrg swapl(&rep.length, n); 30805b261ecSmrg swaps(&rep.majorVersion, n); 30905b261ecSmrg swaps(&rep.minorVersion, n); 31005b261ecSmrg swaps(&rep.uid, n); 31105b261ecSmrg swaps(&rep.gid, n); 31205b261ecSmrg } 31305b261ecSmrg WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep); 3144202a189Smrg return Success; 31505b261ecSmrg} 31605b261ecSmrg 31705b261ecSmrg/* 31805b261ecSmrg * Simulate the access() system call for a shared memory segement, 31905b261ecSmrg * using the credentials from the client if available 32005b261ecSmrg */ 32105b261ecSmrgstatic int 3224642e01fSmrgshm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly) 32305b261ecSmrg{ 32405b261ecSmrg int uid, gid; 32505b261ecSmrg mode_t mask; 3264642e01fSmrg int uidset = 0, gidset = 0; 3274642e01fSmrg LocalClientCredRec *lcc; 3284642e01fSmrg 3294642e01fSmrg if (GetLocalClientCreds(client, &lcc) != -1) { 33005b261ecSmrg 3314642e01fSmrg if (lcc->fieldsSet & LCC_UID_SET) { 3324642e01fSmrg uid = lcc->euid; 3334642e01fSmrg uidset = 1; 3344642e01fSmrg } 3354642e01fSmrg if (lcc->fieldsSet & LCC_GID_SET) { 3364642e01fSmrg gid = lcc->egid; 3374642e01fSmrg gidset = 1; 3384642e01fSmrg } 3394642e01fSmrg 3404642e01fSmrg#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID) 3414642e01fSmrg if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1) 3424642e01fSmrg || (lcc->zoneid != SHMPERM_ZONEID(perm))) { 3434642e01fSmrg uidset = 0; 3444642e01fSmrg gidset = 0; 34505b261ecSmrg } 3464642e01fSmrg#endif 3474642e01fSmrg FreeLocalClientCreds(lcc); 3484642e01fSmrg 3494642e01fSmrg if (uidset) { 3504642e01fSmrg /* User id 0 always gets access */ 3514642e01fSmrg if (uid == 0) { 3524642e01fSmrg return 0; 3534642e01fSmrg } 3544642e01fSmrg /* Check the owner */ 3554642e01fSmrg if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) { 3564642e01fSmrg mask = S_IRUSR; 3574642e01fSmrg if (!readonly) { 3584642e01fSmrg mask |= S_IWUSR; 3594642e01fSmrg } 3604642e01fSmrg return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; 36105b261ecSmrg } 36205b261ecSmrg } 3634642e01fSmrg 3644642e01fSmrg if (gidset) { 3654642e01fSmrg /* Check the group */ 3664642e01fSmrg if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) { 3674642e01fSmrg mask = S_IRGRP; 3684642e01fSmrg if (!readonly) { 3694642e01fSmrg mask |= S_IWGRP; 3704642e01fSmrg } 3714642e01fSmrg return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; 37205b261ecSmrg } 37305b261ecSmrg } 37405b261ecSmrg } 37505b261ecSmrg /* Otherwise, check everyone else */ 37605b261ecSmrg mask = S_IROTH; 37705b261ecSmrg if (!readonly) { 37805b261ecSmrg mask |= S_IWOTH; 37905b261ecSmrg } 3804642e01fSmrg return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; 38105b261ecSmrg} 38205b261ecSmrg 38305b261ecSmrgstatic int 3844642e01fSmrgProcShmAttach(ClientPtr client) 38505b261ecSmrg{ 3864642e01fSmrg SHMSTAT_TYPE buf; 38705b261ecSmrg ShmDescPtr shmdesc; 38805b261ecSmrg REQUEST(xShmAttachReq); 38905b261ecSmrg 39005b261ecSmrg REQUEST_SIZE_MATCH(xShmAttachReq); 39105b261ecSmrg LEGAL_NEW_RESOURCE(stuff->shmseg, client); 39205b261ecSmrg if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) 39305b261ecSmrg { 39405b261ecSmrg client->errorValue = stuff->readOnly; 3954202a189Smrg return BadValue; 39605b261ecSmrg } 39705b261ecSmrg for (shmdesc = Shmsegs; 39805b261ecSmrg shmdesc && (shmdesc->shmid != stuff->shmid); 39905b261ecSmrg shmdesc = shmdesc->next) 40005b261ecSmrg ; 40105b261ecSmrg if (shmdesc) 40205b261ecSmrg { 40305b261ecSmrg if (!stuff->readOnly && !shmdesc->writable) 40405b261ecSmrg return BadAccess; 40505b261ecSmrg shmdesc->refcnt++; 40605b261ecSmrg } 40705b261ecSmrg else 40805b261ecSmrg { 4094202a189Smrg shmdesc = malloc(sizeof(ShmDescRec)); 41005b261ecSmrg if (!shmdesc) 41105b261ecSmrg return BadAlloc; 41205b261ecSmrg shmdesc->addr = shmat(stuff->shmid, 0, 41305b261ecSmrg stuff->readOnly ? SHM_RDONLY : 0); 41405b261ecSmrg if ((shmdesc->addr == ((char *)-1)) || 4154642e01fSmrg SHMSTAT(stuff->shmid, &buf)) 41605b261ecSmrg { 4174202a189Smrg free(shmdesc); 41805b261ecSmrg return BadAccess; 41905b261ecSmrg } 42005b261ecSmrg 42105b261ecSmrg /* The attach was performed with root privs. We must 42205b261ecSmrg * do manual checking of access rights for the credentials 42305b261ecSmrg * of the client */ 42405b261ecSmrg 4254642e01fSmrg if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) { 42605b261ecSmrg shmdt(shmdesc->addr); 4274202a189Smrg free(shmdesc); 42805b261ecSmrg return BadAccess; 42905b261ecSmrg } 43005b261ecSmrg 43105b261ecSmrg shmdesc->shmid = stuff->shmid; 43205b261ecSmrg shmdesc->refcnt = 1; 43305b261ecSmrg shmdesc->writable = !stuff->readOnly; 4344642e01fSmrg shmdesc->size = SHM_SEGSZ(buf); 43505b261ecSmrg shmdesc->next = Shmsegs; 43605b261ecSmrg Shmsegs = shmdesc; 43705b261ecSmrg } 43805b261ecSmrg if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc)) 43905b261ecSmrg return BadAlloc; 4404202a189Smrg return Success; 44105b261ecSmrg} 44205b261ecSmrg 44305b261ecSmrg/*ARGSUSED*/ 44405b261ecSmrgstatic int 4454642e01fSmrgShmDetachSegment(pointer value, /* must conform to DeleteType */ 4464642e01fSmrg XID shmseg) 44705b261ecSmrg{ 44805b261ecSmrg ShmDescPtr shmdesc = (ShmDescPtr)value; 44905b261ecSmrg ShmDescPtr *prev; 45005b261ecSmrg 45105b261ecSmrg if (--shmdesc->refcnt) 45205b261ecSmrg return TRUE; 45305b261ecSmrg shmdt(shmdesc->addr); 45405b261ecSmrg for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next) 45505b261ecSmrg ; 45605b261ecSmrg *prev = shmdesc->next; 4574202a189Smrg free(shmdesc); 45805b261ecSmrg return Success; 45905b261ecSmrg} 46005b261ecSmrg 46105b261ecSmrgstatic int 4624642e01fSmrgProcShmDetach(ClientPtr client) 46305b261ecSmrg{ 46405b261ecSmrg ShmDescPtr shmdesc; 46505b261ecSmrg REQUEST(xShmDetachReq); 46605b261ecSmrg 46705b261ecSmrg REQUEST_SIZE_MATCH(xShmDetachReq); 46805b261ecSmrg VERIFY_SHMSEG(stuff->shmseg, shmdesc, client); 46905b261ecSmrg FreeResource(stuff->shmseg, RT_NONE); 4704202a189Smrg return Success; 47105b261ecSmrg} 47205b261ecSmrg 4734642e01fSmrg/* 4744642e01fSmrg * If the given request doesn't exactly match PutImage's constraints, 4754642e01fSmrg * wrap the image in a scratch pixmap header and let CopyArea sort it out. 4764642e01fSmrg */ 47705b261ecSmrgstatic void 4784642e01fSmrgdoShmPutImage(DrawablePtr dst, GCPtr pGC, 4794642e01fSmrg int depth, unsigned int format, 4804642e01fSmrg int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, 4814642e01fSmrg char *data) 48205b261ecSmrg{ 4834642e01fSmrg PixmapPtr pPixmap; 4844202a189Smrg 4854202a189Smrg if (format == ZPixmap || depth == 1) { 4864202a189Smrg pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth, 4874202a189Smrg BitsPerPixel(depth), 4884202a189Smrg PixmapBytePad(w, depth), 4894202a189Smrg data); 4904202a189Smrg if (!pPixmap) 4914202a189Smrg return; 4924202a189Smrg pGC->ops->CopyArea((DrawablePtr)pPixmap, dst, pGC, sx, sy, sw, sh, dx, dy); 4934202a189Smrg FreeScratchPixmapHeader(pPixmap); 4944202a189Smrg } else { 4954202a189Smrg GCPtr putGC = GetScratchGC(depth, dst->pScreen); 4964202a189Smrg 4974202a189Smrg if (!putGC) 4984202a189Smrg return; 4994202a189Smrg 5004202a189Smrg pPixmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth, 5014202a189Smrg CREATE_PIXMAP_USAGE_SCRATCH); 5024202a189Smrg if (!pPixmap) { 5034202a189Smrg FreeScratchGC(putGC); 5044202a189Smrg return; 5054202a189Smrg } 5064202a189Smrg ValidateGC(&pPixmap->drawable, putGC); 5074202a189Smrg (*putGC->ops->PutImage)(&pPixmap->drawable, putGC, depth, -sx, -sy, w, h, 0, 5084202a189Smrg (format == XYPixmap) ? XYPixmap : ZPixmap, data); 5094202a189Smrg FreeScratchGC(putGC); 5104202a189Smrg if (format == XYBitmap) 5114202a189Smrg (void)(*pGC->ops->CopyPlane)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, 5124202a189Smrg dx, dy, 1L); 5134202a189Smrg else 5144202a189Smrg (void)(*pGC->ops->CopyArea)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, 5154202a189Smrg dx, dy); 5164202a189Smrg (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 5174202a189Smrg } 51805b261ecSmrg} 51905b261ecSmrg 52065b04b38Smrgstatic int 52165b04b38SmrgProcShmPutImage(ClientPtr client) 52205b261ecSmrg{ 52365b04b38Smrg GCPtr pGC; 52465b04b38Smrg DrawablePtr pDraw; 52565b04b38Smrg long length; 52665b04b38Smrg ShmDescPtr shmdesc; 52705b261ecSmrg REQUEST(xShmPutImageReq); 52865b04b38Smrg 52905b261ecSmrg REQUEST_SIZE_MATCH(xShmPutImageReq); 53065b04b38Smrg VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 53165b04b38Smrg VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client); 53265b04b38Smrg if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse)) 53365b04b38Smrg return BadValue; 53465b04b38Smrg if (stuff->format == XYBitmap) 53565b04b38Smrg { 53665b04b38Smrg if (stuff->depth != 1) 53765b04b38Smrg return BadMatch; 53865b04b38Smrg length = PixmapBytePad(stuff->totalWidth, 1); 53965b04b38Smrg } 54065b04b38Smrg else if (stuff->format == XYPixmap) 54165b04b38Smrg { 54265b04b38Smrg if (pDraw->depth != stuff->depth) 54365b04b38Smrg return BadMatch; 54465b04b38Smrg length = PixmapBytePad(stuff->totalWidth, 1); 54565b04b38Smrg length *= stuff->depth; 54665b04b38Smrg } 54765b04b38Smrg else if (stuff->format == ZPixmap) 54865b04b38Smrg { 54965b04b38Smrg if (pDraw->depth != stuff->depth) 55065b04b38Smrg return BadMatch; 55165b04b38Smrg length = PixmapBytePad(stuff->totalWidth, stuff->depth); 55265b04b38Smrg } 55365b04b38Smrg else 55465b04b38Smrg { 55565b04b38Smrg client->errorValue = stuff->format; 55665b04b38Smrg return BadValue; 55765b04b38Smrg } 55805b261ecSmrg 55965b04b38Smrg /* 56065b04b38Smrg * There's a potential integer overflow in this check: 56165b04b38Smrg * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, 56265b04b38Smrg * client); 56365b04b38Smrg * the version below ought to avoid it 56465b04b38Smrg */ 56565b04b38Smrg if (stuff->totalHeight != 0 && 56665b04b38Smrg length > (shmdesc->size - stuff->offset)/stuff->totalHeight) { 56765b04b38Smrg client->errorValue = stuff->totalWidth; 56865b04b38Smrg return BadValue; 56965b04b38Smrg } 57065b04b38Smrg if (stuff->srcX > stuff->totalWidth) 57165b04b38Smrg { 57265b04b38Smrg client->errorValue = stuff->srcX; 57365b04b38Smrg return BadValue; 57465b04b38Smrg } 57565b04b38Smrg if (stuff->srcY > stuff->totalHeight) 57665b04b38Smrg { 57765b04b38Smrg client->errorValue = stuff->srcY; 57865b04b38Smrg return BadValue; 57965b04b38Smrg } 58065b04b38Smrg if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth) 58165b04b38Smrg { 58265b04b38Smrg client->errorValue = stuff->srcWidth; 58365b04b38Smrg return BadValue; 58465b04b38Smrg } 58565b04b38Smrg if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight) 58665b04b38Smrg { 58765b04b38Smrg client->errorValue = stuff->srcHeight; 58865b04b38Smrg return BadValue; 58965b04b38Smrg } 59005b261ecSmrg 59165b04b38Smrg if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) || 59265b04b38Smrg ((stuff->format != ZPixmap) && 59365b04b38Smrg (stuff->srcX < screenInfo.bitmapScanlinePad) && 59465b04b38Smrg ((stuff->format == XYBitmap) || 59565b04b38Smrg ((stuff->srcY == 0) && 59665b04b38Smrg (stuff->srcHeight == stuff->totalHeight))))) && 59765b04b38Smrg ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth)) 59865b04b38Smrg (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, 59965b04b38Smrg stuff->dstX, stuff->dstY, 60065b04b38Smrg stuff->totalWidth, stuff->srcHeight, 60165b04b38Smrg stuff->srcX, stuff->format, 60265b04b38Smrg shmdesc->addr + stuff->offset + 60365b04b38Smrg (stuff->srcY * length)); 60465b04b38Smrg else 60565b04b38Smrg doShmPutImage(pDraw, pGC, stuff->depth, stuff->format, 60665b04b38Smrg stuff->totalWidth, stuff->totalHeight, 60765b04b38Smrg stuff->srcX, stuff->srcY, 60865b04b38Smrg stuff->srcWidth, stuff->srcHeight, 60965b04b38Smrg stuff->dstX, stuff->dstY, 61065b04b38Smrg shmdesc->addr + stuff->offset); 61105b261ecSmrg 61265b04b38Smrg if (stuff->sendEvent) 61365b04b38Smrg { 61465b04b38Smrg xShmCompletionEvent ev; 61505b261ecSmrg 61665b04b38Smrg ev.type = ShmCompletionCode; 61765b04b38Smrg ev.drawable = stuff->drawable; 61865b04b38Smrg ev.minorEvent = X_ShmPutImage; 61965b04b38Smrg ev.majorEvent = ShmReqCode; 62065b04b38Smrg ev.shmseg = stuff->shmseg; 62165b04b38Smrg ev.offset = stuff->offset; 62265b04b38Smrg WriteEventsToClient(client, 1, (xEvent *) &ev); 62305b261ecSmrg } 62465b04b38Smrg 62565b04b38Smrg return Success; 62605b261ecSmrg} 62705b261ecSmrg 62865b04b38Smrgstatic int 62965b04b38SmrgProcShmGetImage(ClientPtr client) 63005b261ecSmrg{ 63165b04b38Smrg DrawablePtr pDraw; 63265b04b38Smrg long lenPer = 0, length; 63365b04b38Smrg Mask plane = 0; 63405b261ecSmrg xShmGetImageReply xgi; 63505b261ecSmrg ShmDescPtr shmdesc; 63665b04b38Smrg int n, rc; 63705b261ecSmrg 63805b261ecSmrg REQUEST(xShmGetImageReq); 63905b261ecSmrg 64005b261ecSmrg REQUEST_SIZE_MATCH(xShmGetImageReq); 64165b04b38Smrg if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) 64265b04b38Smrg { 64305b261ecSmrg client->errorValue = stuff->format; 6444202a189Smrg return BadValue; 64505b261ecSmrg } 64605b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 6474642e01fSmrg DixReadAccess); 64805b261ecSmrg if (rc != Success) 64905b261ecSmrg return rc; 65005b261ecSmrg VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); 65165b04b38Smrg if (pDraw->type == DRAWABLE_WINDOW) 65265b04b38Smrg { 65365b04b38Smrg if( /* check for being viewable */ 65465b04b38Smrg !((WindowPtr) pDraw)->realized || 65565b04b38Smrg /* check for being on screen */ 65665b04b38Smrg pDraw->x + stuff->x < 0 || 65765b04b38Smrg pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width || 65865b04b38Smrg pDraw->y + stuff->y < 0 || 65965b04b38Smrg pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height || 66065b04b38Smrg /* check for being inside of border */ 66165b04b38Smrg stuff->x < - wBorderWidth((WindowPtr)pDraw) || 66265b04b38Smrg stuff->x + (int)stuff->width > 66365b04b38Smrg wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || 66465b04b38Smrg stuff->y < -wBorderWidth((WindowPtr)pDraw) || 66565b04b38Smrg stuff->y + (int)stuff->height > 66665b04b38Smrg wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height 66765b04b38Smrg ) 6684202a189Smrg return BadMatch; 66965b04b38Smrg xgi.visual = wVisual(((WindowPtr)pDraw)); 67065b04b38Smrg } 67165b04b38Smrg else 67265b04b38Smrg { 67365b04b38Smrg if (stuff->x < 0 || 67465b04b38Smrg stuff->x+(int)stuff->width > pDraw->width || 67565b04b38Smrg stuff->y < 0 || 67665b04b38Smrg stuff->y+(int)stuff->height > pDraw->height 67765b04b38Smrg ) 6784202a189Smrg return BadMatch; 67965b04b38Smrg xgi.visual = None; 68005b261ecSmrg } 68165b04b38Smrg xgi.type = X_Reply; 68265b04b38Smrg xgi.length = 0; 68365b04b38Smrg xgi.sequenceNumber = client->sequence; 68465b04b38Smrg xgi.depth = pDraw->depth; 68565b04b38Smrg if(stuff->format == ZPixmap) 68665b04b38Smrg { 68765b04b38Smrg length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height; 68865b04b38Smrg } 68965b04b38Smrg else 69065b04b38Smrg { 69165b04b38Smrg lenPer = PixmapBytePad(stuff->width, 1) * stuff->height; 69265b04b38Smrg plane = ((Mask)1) << (pDraw->depth - 1); 69365b04b38Smrg /* only planes asked for */ 69465b04b38Smrg length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1))); 69565b04b38Smrg } 69665b04b38Smrg 69765b04b38Smrg VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); 69865b04b38Smrg xgi.size = length; 69965b04b38Smrg 70065b04b38Smrg if (length == 0) 70165b04b38Smrg { 70265b04b38Smrg /* nothing to do */ 70365b04b38Smrg } 70465b04b38Smrg else if (stuff->format == ZPixmap) 70565b04b38Smrg { 70665b04b38Smrg (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y, 70765b04b38Smrg stuff->width, stuff->height, 70865b04b38Smrg stuff->format, stuff->planeMask, 70965b04b38Smrg shmdesc->addr + stuff->offset); 71065b04b38Smrg } 71165b04b38Smrg else 71265b04b38Smrg { 71365b04b38Smrg 71465b04b38Smrg length = stuff->offset; 71565b04b38Smrg for (; plane; plane >>= 1) 71665b04b38Smrg { 71765b04b38Smrg if (stuff->planeMask & plane) 71865b04b38Smrg { 71965b04b38Smrg (*pDraw->pScreen->GetImage)(pDraw, 72065b04b38Smrg stuff->x, stuff->y, 72165b04b38Smrg stuff->width, stuff->height, 72265b04b38Smrg stuff->format, plane, 72365b04b38Smrg shmdesc->addr + length); 72465b04b38Smrg length += lenPer; 72565b04b38Smrg } 72665b04b38Smrg } 72765b04b38Smrg } 72865b04b38Smrg 72965b04b38Smrg if (client->swapped) { 73065b04b38Smrg swaps(&xgi.sequenceNumber, n); 73165b04b38Smrg swapl(&xgi.length, n); 73265b04b38Smrg swapl(&xgi.visual, n); 73365b04b38Smrg swapl(&xgi.size, n); 73465b04b38Smrg } 73565b04b38Smrg WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); 73665b04b38Smrg 73765b04b38Smrg return Success; 73865b04b38Smrg} 73965b04b38Smrg 74065b04b38Smrg#ifdef PANORAMIX 74165b04b38Smrgstatic int 74265b04b38SmrgProcPanoramiXShmPutImage(ClientPtr client) 74365b04b38Smrg{ 74465b04b38Smrg int j, result, orig_x, orig_y; 74565b04b38Smrg PanoramiXRes *draw, *gc; 74665b04b38Smrg Bool sendEvent, isRoot; 74765b04b38Smrg 74865b04b38Smrg REQUEST(xShmPutImageReq); 74965b04b38Smrg REQUEST_SIZE_MATCH(xShmPutImageReq); 75065b04b38Smrg 75165b04b38Smrg result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 75265b04b38Smrg XRC_DRAWABLE, client, DixWriteAccess); 75365b04b38Smrg if (result != Success) 75465b04b38Smrg return (result == BadValue) ? BadDrawable : result; 75565b04b38Smrg 75665b04b38Smrg result = dixLookupResourceByType((pointer *)&gc, stuff->gc, 75765b04b38Smrg XRT_GC, client, DixReadAccess); 75865b04b38Smrg if (result != Success) 75965b04b38Smrg return result; 76065b04b38Smrg 76165b04b38Smrg isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 76265b04b38Smrg 76365b04b38Smrg orig_x = stuff->dstX; 76465b04b38Smrg orig_y = stuff->dstY; 76565b04b38Smrg sendEvent = stuff->sendEvent; 76665b04b38Smrg stuff->sendEvent = 0; 76765b04b38Smrg FOR_NSCREENS(j) { 76865b04b38Smrg if(!j) stuff->sendEvent = sendEvent; 76965b04b38Smrg stuff->drawable = draw->info[j].id; 77065b04b38Smrg stuff->gc = gc->info[j].id; 77165b04b38Smrg if (isRoot) { 77265b04b38Smrg stuff->dstX = orig_x - screenInfo.screens[j]->x; 77365b04b38Smrg stuff->dstY = orig_y - screenInfo.screens[j]->y; 77465b04b38Smrg } 77565b04b38Smrg result = ProcShmPutImage(client); 77665b04b38Smrg if(result != Success) break; 77765b04b38Smrg } 77865b04b38Smrg return result; 77965b04b38Smrg} 78065b04b38Smrg 78165b04b38Smrgstatic int 78265b04b38SmrgProcPanoramiXShmGetImage(ClientPtr client) 78365b04b38Smrg{ 78465b04b38Smrg PanoramiXRes *draw; 78565b04b38Smrg DrawablePtr *drawables; 78665b04b38Smrg DrawablePtr pDraw; 78765b04b38Smrg xShmGetImageReply xgi; 78865b04b38Smrg ShmDescPtr shmdesc; 78965b04b38Smrg int i, x, y, w, h, format, rc; 79065b04b38Smrg Mask plane = 0, planemask; 79165b04b38Smrg long lenPer = 0, length, widthBytesLine; 79265b04b38Smrg Bool isRoot; 79365b04b38Smrg 79465b04b38Smrg REQUEST(xShmGetImageReq); 79565b04b38Smrg 79665b04b38Smrg REQUEST_SIZE_MATCH(xShmGetImageReq); 79765b04b38Smrg 79865b04b38Smrg if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) { 79965b04b38Smrg client->errorValue = stuff->format; 80065b04b38Smrg return BadValue; 80165b04b38Smrg } 80265b04b38Smrg 80365b04b38Smrg rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 80465b04b38Smrg XRC_DRAWABLE, client, DixWriteAccess); 80565b04b38Smrg if (rc != Success) 80665b04b38Smrg return (rc == BadValue) ? BadDrawable : rc; 80765b04b38Smrg 80865b04b38Smrg if (draw->type == XRT_PIXMAP) 80965b04b38Smrg return ProcShmGetImage(client); 81065b04b38Smrg 81165b04b38Smrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 81265b04b38Smrg DixReadAccess); 81365b04b38Smrg if (rc != Success) 81465b04b38Smrg return rc; 81565b04b38Smrg 81665b04b38Smrg VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); 81765b04b38Smrg 81865b04b38Smrg x = stuff->x; 81965b04b38Smrg y = stuff->y; 82065b04b38Smrg w = stuff->width; 82165b04b38Smrg h = stuff->height; 82265b04b38Smrg format = stuff->format; 82365b04b38Smrg planemask = stuff->planeMask; 82465b04b38Smrg 82565b04b38Smrg isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; 82665b04b38Smrg 82765b04b38Smrg if(isRoot) { 82865b04b38Smrg if( /* check for being onscreen */ 82965b04b38Smrg x < 0 || x + w > PanoramiXPixWidth || 83065b04b38Smrg y < 0 || y + h > PanoramiXPixHeight ) 83165b04b38Smrg return BadMatch; 83265b04b38Smrg } else { 83365b04b38Smrg if( /* check for being onscreen */ 83465b04b38Smrg screenInfo.screens[0]->x + pDraw->x + x < 0 || 83565b04b38Smrg screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth || 83665b04b38Smrg screenInfo.screens[0]->y + pDraw->y + y < 0 || 83765b04b38Smrg screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight || 83865b04b38Smrg /* check for being inside of border */ 83965b04b38Smrg x < - wBorderWidth((WindowPtr)pDraw) || 84065b04b38Smrg x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || 84165b04b38Smrg y < -wBorderWidth((WindowPtr)pDraw) || 84265b04b38Smrg y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height) 84365b04b38Smrg return BadMatch; 84465b04b38Smrg } 84565b04b38Smrg 8464202a189Smrg drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr)); 8474202a189Smrg if(!drawables) 8484202a189Smrg return BadAlloc; 8494202a189Smrg 85005b261ecSmrg drawables[0] = pDraw; 85105b261ecSmrg for(i = 1; i < PanoramiXNumScreens; i++) { 85205b261ecSmrg rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, 8534642e01fSmrg DixReadAccess); 85405b261ecSmrg if (rc != Success) 8554202a189Smrg { 8564202a189Smrg free(drawables); 85705b261ecSmrg return rc; 8584202a189Smrg } 85905b261ecSmrg } 86005b261ecSmrg 86105b261ecSmrg xgi.visual = wVisual(((WindowPtr)pDraw)); 86205b261ecSmrg xgi.type = X_Reply; 86305b261ecSmrg xgi.length = 0; 86405b261ecSmrg xgi.sequenceNumber = client->sequence; 86505b261ecSmrg xgi.depth = pDraw->depth; 86605b261ecSmrg 86705b261ecSmrg if(format == ZPixmap) { 86805b261ecSmrg widthBytesLine = PixmapBytePad(w, pDraw->depth); 86905b261ecSmrg length = widthBytesLine * h; 87005b261ecSmrg } else { 87105b261ecSmrg widthBytesLine = PixmapBytePad(w, 1); 87205b261ecSmrg lenPer = widthBytesLine * h; 87305b261ecSmrg plane = ((Mask)1) << (pDraw->depth - 1); 87405b261ecSmrg length = lenPer * Ones(planemask & (plane | (plane - 1))); 87505b261ecSmrg } 87605b261ecSmrg 87705b261ecSmrg VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); 87805b261ecSmrg xgi.size = length; 87905b261ecSmrg 88005b261ecSmrg if (length == 0) {/* nothing to do */ } 88105b261ecSmrg else if (format == ZPixmap) { 88205b261ecSmrg XineramaGetImageData(drawables, x, y, w, h, format, planemask, 88305b261ecSmrg shmdesc->addr + stuff->offset, 88405b261ecSmrg widthBytesLine, isRoot); 88505b261ecSmrg } else { 88605b261ecSmrg 88705b261ecSmrg length = stuff->offset; 88805b261ecSmrg for (; plane; plane >>= 1) { 88905b261ecSmrg if (planemask & plane) { 89005b261ecSmrg XineramaGetImageData(drawables, x, y, w, h, 89105b261ecSmrg format, plane, shmdesc->addr + length, 89205b261ecSmrg widthBytesLine, isRoot); 89305b261ecSmrg length += lenPer; 89405b261ecSmrg } 89505b261ecSmrg } 89605b261ecSmrg } 8974202a189Smrg free(drawables); 89805b261ecSmrg 89905b261ecSmrg if (client->swapped) { 9004642e01fSmrg int n; 90105b261ecSmrg swaps(&xgi.sequenceNumber, n); 90205b261ecSmrg swapl(&xgi.length, n); 90305b261ecSmrg swapl(&xgi.visual, n); 90405b261ecSmrg swapl(&xgi.size, n); 90505b261ecSmrg } 90605b261ecSmrg WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); 90705b261ecSmrg 9084202a189Smrg return Success; 90905b261ecSmrg} 91005b261ecSmrg 91105b261ecSmrgstatic int 9124642e01fSmrgProcPanoramiXShmCreatePixmap(ClientPtr client) 91305b261ecSmrg{ 91405b261ecSmrg ScreenPtr pScreen = NULL; 91505b261ecSmrg PixmapPtr pMap = NULL; 91605b261ecSmrg DrawablePtr pDraw; 91705b261ecSmrg DepthPtr pDepth; 91805b261ecSmrg int i, j, result, rc; 91905b261ecSmrg ShmDescPtr shmdesc; 92005b261ecSmrg REQUEST(xShmCreatePixmapReq); 92105b261ecSmrg unsigned int width, height, depth; 92205b261ecSmrg unsigned long size; 92305b261ecSmrg PanoramiXRes *newPix; 92405b261ecSmrg 92505b261ecSmrg REQUEST_SIZE_MATCH(xShmCreatePixmapReq); 92605b261ecSmrg client->errorValue = stuff->pid; 92705b261ecSmrg if (!sharedPixmaps) 92805b261ecSmrg return BadImplementation; 92905b261ecSmrg LEGAL_NEW_RESOURCE(stuff->pid, client); 93005b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 9314642e01fSmrg DixGetAttrAccess); 93205b261ecSmrg if (rc != Success) 93305b261ecSmrg return rc; 93405b261ecSmrg 93505b261ecSmrg VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); 93605b261ecSmrg 93705b261ecSmrg width = stuff->width; 93805b261ecSmrg height = stuff->height; 93905b261ecSmrg depth = stuff->depth; 94005b261ecSmrg if (!width || !height || !depth) 94105b261ecSmrg { 94205b261ecSmrg client->errorValue = 0; 94305b261ecSmrg return BadValue; 94405b261ecSmrg } 94505b261ecSmrg if (width > 32767 || height > 32767) 94605b261ecSmrg return BadAlloc; 94705b261ecSmrg 94805b261ecSmrg if (stuff->depth != 1) 94905b261ecSmrg { 95005b261ecSmrg pDepth = pDraw->pScreen->allowedDepths; 95105b261ecSmrg for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) 95205b261ecSmrg if (pDepth->depth == stuff->depth) 95305b261ecSmrg goto CreatePmap; 95405b261ecSmrg client->errorValue = stuff->depth; 95505b261ecSmrg return BadValue; 95605b261ecSmrg } 95705b261ecSmrg 95805b261ecSmrgCreatePmap: 95905b261ecSmrg size = PixmapBytePad(width, depth) * height; 96005b261ecSmrg if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { 96105b261ecSmrg if (size < width * height) 96205b261ecSmrg return BadAlloc; 96305b261ecSmrg } 96405b261ecSmrg /* thankfully, offset is unsigned */ 96505b261ecSmrg if (stuff->offset + size < size) 96605b261ecSmrg return BadAlloc; 96705b261ecSmrg 96805b261ecSmrg VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); 96905b261ecSmrg 9704202a189Smrg if(!(newPix = malloc(sizeof(PanoramiXRes)))) 97105b261ecSmrg return BadAlloc; 97205b261ecSmrg 97305b261ecSmrg newPix->type = XRT_PIXMAP; 97405b261ecSmrg newPix->u.pix.shared = TRUE; 97505b261ecSmrg newPix->info[0].id = stuff->pid; 97605b261ecSmrg for(j = 1; j < PanoramiXNumScreens; j++) 97705b261ecSmrg newPix->info[j].id = FakeClientID(client->index); 97805b261ecSmrg 9794202a189Smrg result = Success; 98005b261ecSmrg 98105b261ecSmrg FOR_NSCREENS(j) { 9824202a189Smrg ShmScrPrivateRec *screen_priv; 98305b261ecSmrg pScreen = screenInfo.screens[j]; 98405b261ecSmrg 9854202a189Smrg screen_priv = ShmGetScreenPriv(pScreen); 9864202a189Smrg pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen, 98705b261ecSmrg stuff->width, stuff->height, stuff->depth, 98805b261ecSmrg shmdesc->addr + stuff->offset); 98905b261ecSmrg 99005b261ecSmrg if (pMap) { 9914202a189Smrg dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); 99205b261ecSmrg shmdesc->refcnt++; 99305b261ecSmrg pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 99405b261ecSmrg pMap->drawable.id = newPix->info[j].id; 99505b261ecSmrg if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) { 99605b261ecSmrg (*pScreen->DestroyPixmap)(pMap); 99705b261ecSmrg result = BadAlloc; 99805b261ecSmrg break; 99905b261ecSmrg } 100005b261ecSmrg } else { 100105b261ecSmrg result = BadAlloc; 100205b261ecSmrg break; 100305b261ecSmrg } 100405b261ecSmrg } 100505b261ecSmrg 100605b261ecSmrg if(result == BadAlloc) { 100705b261ecSmrg while(j--) { 100805b261ecSmrg (*pScreen->DestroyPixmap)(pMap); 100905b261ecSmrg FreeResource(newPix->info[j].id, RT_NONE); 101005b261ecSmrg } 10114202a189Smrg free(newPix); 101205b261ecSmrg } else 101305b261ecSmrg AddResource(stuff->pid, XRT_PIXMAP, newPix); 101405b261ecSmrg 101505b261ecSmrg return result; 101605b261ecSmrg} 101705b261ecSmrg#endif 101805b261ecSmrg 101905b261ecSmrgstatic PixmapPtr 10204642e01fSmrgfbShmCreatePixmap (ScreenPtr pScreen, 10214642e01fSmrg int width, int height, int depth, char *addr) 102205b261ecSmrg{ 10234642e01fSmrg PixmapPtr pPixmap; 102405b261ecSmrg 10254642e01fSmrg pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); 102605b261ecSmrg if (!pPixmap) 102705b261ecSmrg return NullPixmap; 102805b261ecSmrg 102905b261ecSmrg if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth, 103005b261ecSmrg BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) { 103105b261ecSmrg (*pScreen->DestroyPixmap)(pPixmap); 103205b261ecSmrg return NullPixmap; 103305b261ecSmrg } 103405b261ecSmrg return pPixmap; 103505b261ecSmrg} 103605b261ecSmrg 103705b261ecSmrgstatic int 10384642e01fSmrgProcShmCreatePixmap(ClientPtr client) 103905b261ecSmrg{ 104005b261ecSmrg PixmapPtr pMap; 104105b261ecSmrg DrawablePtr pDraw; 104205b261ecSmrg DepthPtr pDepth; 10434642e01fSmrg int i, rc; 104405b261ecSmrg ShmDescPtr shmdesc; 10454202a189Smrg ShmScrPrivateRec *screen_priv; 104605b261ecSmrg REQUEST(xShmCreatePixmapReq); 104705b261ecSmrg unsigned int width, height, depth; 104805b261ecSmrg unsigned long size; 104905b261ecSmrg 105005b261ecSmrg REQUEST_SIZE_MATCH(xShmCreatePixmapReq); 105105b261ecSmrg client->errorValue = stuff->pid; 105205b261ecSmrg if (!sharedPixmaps) 105305b261ecSmrg return BadImplementation; 105405b261ecSmrg LEGAL_NEW_RESOURCE(stuff->pid, client); 105505b261ecSmrg rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 10564642e01fSmrg DixGetAttrAccess); 105705b261ecSmrg if (rc != Success) 105805b261ecSmrg return rc; 105905b261ecSmrg 106005b261ecSmrg VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); 106105b261ecSmrg 106205b261ecSmrg width = stuff->width; 106305b261ecSmrg height = stuff->height; 106405b261ecSmrg depth = stuff->depth; 106505b261ecSmrg if (!width || !height || !depth) 106605b261ecSmrg { 106705b261ecSmrg client->errorValue = 0; 106805b261ecSmrg return BadValue; 106905b261ecSmrg } 107005b261ecSmrg if (width > 32767 || height > 32767) 107105b261ecSmrg return BadAlloc; 107205b261ecSmrg 107305b261ecSmrg if (stuff->depth != 1) 107405b261ecSmrg { 107505b261ecSmrg pDepth = pDraw->pScreen->allowedDepths; 107605b261ecSmrg for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) 107705b261ecSmrg if (pDepth->depth == stuff->depth) 107805b261ecSmrg goto CreatePmap; 107905b261ecSmrg client->errorValue = stuff->depth; 108005b261ecSmrg return BadValue; 108105b261ecSmrg } 108205b261ecSmrg 108305b261ecSmrgCreatePmap: 108405b261ecSmrg size = PixmapBytePad(width, depth) * height; 108505b261ecSmrg if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { 108605b261ecSmrg if (size < width * height) 108705b261ecSmrg return BadAlloc; 108805b261ecSmrg } 108905b261ecSmrg /* thankfully, offset is unsigned */ 109005b261ecSmrg if (stuff->offset + size < size) 109105b261ecSmrg return BadAlloc; 109205b261ecSmrg 109305b261ecSmrg VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); 10944202a189Smrg screen_priv = ShmGetScreenPriv(pDraw->pScreen); 10954202a189Smrg pMap = (*screen_priv->shmFuncs->CreatePixmap)( 109605b261ecSmrg pDraw->pScreen, stuff->width, 109705b261ecSmrg stuff->height, stuff->depth, 109805b261ecSmrg shmdesc->addr + stuff->offset); 109905b261ecSmrg if (pMap) 110005b261ecSmrg { 11014642e01fSmrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, 11024642e01fSmrg pMap, RT_NONE, NULL, DixCreateAccess); 11034642e01fSmrg if (rc != Success) { 11044642e01fSmrg pDraw->pScreen->DestroyPixmap(pMap); 11054642e01fSmrg return rc; 11064642e01fSmrg } 11074202a189Smrg dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); 110805b261ecSmrg shmdesc->refcnt++; 110905b261ecSmrg pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 111005b261ecSmrg pMap->drawable.id = stuff->pid; 111105b261ecSmrg if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) 111205b261ecSmrg { 11134202a189Smrg return Success; 111405b261ecSmrg } 11154642e01fSmrg pDraw->pScreen->DestroyPixmap(pMap); 111605b261ecSmrg } 11174202a189Smrg return BadAlloc; 111805b261ecSmrg} 111905b261ecSmrg 112005b261ecSmrgstatic int 11214642e01fSmrgProcShmDispatch (ClientPtr client) 112205b261ecSmrg{ 112305b261ecSmrg REQUEST(xReq); 112405b261ecSmrg switch (stuff->data) 112505b261ecSmrg { 112605b261ecSmrg case X_ShmQueryVersion: 112705b261ecSmrg return ProcShmQueryVersion(client); 112805b261ecSmrg case X_ShmAttach: 112905b261ecSmrg return ProcShmAttach(client); 113005b261ecSmrg case X_ShmDetach: 113105b261ecSmrg return ProcShmDetach(client); 113205b261ecSmrg case X_ShmPutImage: 113305b261ecSmrg#ifdef PANORAMIX 113405b261ecSmrg if ( !noPanoramiXExtension ) 113505b261ecSmrg return ProcPanoramiXShmPutImage(client); 113605b261ecSmrg#endif 113705b261ecSmrg return ProcShmPutImage(client); 113805b261ecSmrg case X_ShmGetImage: 113905b261ecSmrg#ifdef PANORAMIX 114005b261ecSmrg if ( !noPanoramiXExtension ) 114105b261ecSmrg return ProcPanoramiXShmGetImage(client); 114205b261ecSmrg#endif 114305b261ecSmrg return ProcShmGetImage(client); 114405b261ecSmrg case X_ShmCreatePixmap: 114505b261ecSmrg#ifdef PANORAMIX 114605b261ecSmrg if ( !noPanoramiXExtension ) 114705b261ecSmrg return ProcPanoramiXShmCreatePixmap(client); 114805b261ecSmrg#endif 114905b261ecSmrg return ProcShmCreatePixmap(client); 115005b261ecSmrg default: 115105b261ecSmrg return BadRequest; 115205b261ecSmrg } 115305b261ecSmrg} 115405b261ecSmrg 115505b261ecSmrgstatic void 11564642e01fSmrgSShmCompletionEvent(xShmCompletionEvent *from, xShmCompletionEvent *to) 115705b261ecSmrg{ 115805b261ecSmrg to->type = from->type; 115905b261ecSmrg cpswaps(from->sequenceNumber, to->sequenceNumber); 116005b261ecSmrg cpswapl(from->drawable, to->drawable); 116105b261ecSmrg cpswaps(from->minorEvent, to->minorEvent); 116205b261ecSmrg to->majorEvent = from->majorEvent; 116305b261ecSmrg cpswapl(from->shmseg, to->shmseg); 116405b261ecSmrg cpswapl(from->offset, to->offset); 116505b261ecSmrg} 116605b261ecSmrg 116705b261ecSmrgstatic int 11684642e01fSmrgSProcShmQueryVersion(ClientPtr client) 116905b261ecSmrg{ 11704642e01fSmrg int n; 117105b261ecSmrg REQUEST(xShmQueryVersionReq); 117205b261ecSmrg 117305b261ecSmrg swaps(&stuff->length, n); 117405b261ecSmrg return ProcShmQueryVersion(client); 117505b261ecSmrg} 117605b261ecSmrg 117705b261ecSmrgstatic int 11784642e01fSmrgSProcShmAttach(ClientPtr client) 117905b261ecSmrg{ 11804642e01fSmrg int n; 118105b261ecSmrg REQUEST(xShmAttachReq); 118205b261ecSmrg swaps(&stuff->length, n); 118305b261ecSmrg REQUEST_SIZE_MATCH(xShmAttachReq); 118405b261ecSmrg swapl(&stuff->shmseg, n); 118505b261ecSmrg swapl(&stuff->shmid, n); 118605b261ecSmrg return ProcShmAttach(client); 118705b261ecSmrg} 118805b261ecSmrg 118905b261ecSmrgstatic int 11904642e01fSmrgSProcShmDetach(ClientPtr client) 119105b261ecSmrg{ 11924642e01fSmrg int n; 119305b261ecSmrg REQUEST(xShmDetachReq); 119405b261ecSmrg swaps(&stuff->length, n); 119505b261ecSmrg REQUEST_SIZE_MATCH(xShmDetachReq); 119605b261ecSmrg swapl(&stuff->shmseg, n); 119705b261ecSmrg return ProcShmDetach(client); 119805b261ecSmrg} 119905b261ecSmrg 120005b261ecSmrgstatic int 12014642e01fSmrgSProcShmPutImage(ClientPtr client) 120205b261ecSmrg{ 12034642e01fSmrg int n; 120405b261ecSmrg REQUEST(xShmPutImageReq); 120505b261ecSmrg swaps(&stuff->length, n); 120605b261ecSmrg REQUEST_SIZE_MATCH(xShmPutImageReq); 120705b261ecSmrg swapl(&stuff->drawable, n); 120805b261ecSmrg swapl(&stuff->gc, n); 120905b261ecSmrg swaps(&stuff->totalWidth, n); 121005b261ecSmrg swaps(&stuff->totalHeight, n); 121105b261ecSmrg swaps(&stuff->srcX, n); 121205b261ecSmrg swaps(&stuff->srcY, n); 121305b261ecSmrg swaps(&stuff->srcWidth, n); 121405b261ecSmrg swaps(&stuff->srcHeight, n); 121505b261ecSmrg swaps(&stuff->dstX, n); 121605b261ecSmrg swaps(&stuff->dstY, n); 121705b261ecSmrg swapl(&stuff->shmseg, n); 121805b261ecSmrg swapl(&stuff->offset, n); 121905b261ecSmrg return ProcShmPutImage(client); 122005b261ecSmrg} 122105b261ecSmrg 122205b261ecSmrgstatic int 12234642e01fSmrgSProcShmGetImage(ClientPtr client) 122405b261ecSmrg{ 12254642e01fSmrg int n; 122605b261ecSmrg REQUEST(xShmGetImageReq); 122705b261ecSmrg swaps(&stuff->length, n); 122805b261ecSmrg REQUEST_SIZE_MATCH(xShmGetImageReq); 122905b261ecSmrg swapl(&stuff->drawable, n); 123005b261ecSmrg swaps(&stuff->x, n); 123105b261ecSmrg swaps(&stuff->y, n); 123205b261ecSmrg swaps(&stuff->width, n); 123305b261ecSmrg swaps(&stuff->height, n); 123405b261ecSmrg swapl(&stuff->planeMask, n); 123505b261ecSmrg swapl(&stuff->shmseg, n); 123605b261ecSmrg swapl(&stuff->offset, n); 123705b261ecSmrg return ProcShmGetImage(client); 123805b261ecSmrg} 123905b261ecSmrg 124005b261ecSmrgstatic int 12414642e01fSmrgSProcShmCreatePixmap(ClientPtr client) 124205b261ecSmrg{ 12434642e01fSmrg int n; 124405b261ecSmrg REQUEST(xShmCreatePixmapReq); 124505b261ecSmrg swaps(&stuff->length, n); 124605b261ecSmrg REQUEST_SIZE_MATCH(xShmCreatePixmapReq); 124705b261ecSmrg swapl(&stuff->pid, n); 124805b261ecSmrg swapl(&stuff->drawable, n); 124905b261ecSmrg swaps(&stuff->width, n); 125005b261ecSmrg swaps(&stuff->height, n); 125105b261ecSmrg swapl(&stuff->shmseg, n); 125205b261ecSmrg swapl(&stuff->offset, n); 125305b261ecSmrg return ProcShmCreatePixmap(client); 125405b261ecSmrg} 125505b261ecSmrg 125605b261ecSmrgstatic int 12574642e01fSmrgSProcShmDispatch (ClientPtr client) 125805b261ecSmrg{ 125905b261ecSmrg REQUEST(xReq); 126005b261ecSmrg switch (stuff->data) 126105b261ecSmrg { 126205b261ecSmrg case X_ShmQueryVersion: 126305b261ecSmrg return SProcShmQueryVersion(client); 126405b261ecSmrg case X_ShmAttach: 126505b261ecSmrg return SProcShmAttach(client); 126605b261ecSmrg case X_ShmDetach: 126705b261ecSmrg return SProcShmDetach(client); 126805b261ecSmrg case X_ShmPutImage: 126905b261ecSmrg return SProcShmPutImage(client); 127005b261ecSmrg case X_ShmGetImage: 127105b261ecSmrg return SProcShmGetImage(client); 127205b261ecSmrg case X_ShmCreatePixmap: 127305b261ecSmrg return SProcShmCreatePixmap(client); 127405b261ecSmrg default: 127505b261ecSmrg return BadRequest; 127605b261ecSmrg } 127705b261ecSmrg} 127865b04b38Smrg 127965b04b38Smrgvoid 128065b04b38SmrgShmExtensionInit(INITARGS) 128165b04b38Smrg{ 128265b04b38Smrg ExtensionEntry *extEntry; 128365b04b38Smrg int i; 128465b04b38Smrg 128565b04b38Smrg#ifdef MUST_CHECK_FOR_SHM_SYSCALL 128665b04b38Smrg if (!CheckForShmSyscall()) 128765b04b38Smrg { 128865b04b38Smrg ErrorF("MIT-SHM extension disabled due to lack of kernel support\n"); 128965b04b38Smrg return; 129065b04b38Smrg } 129165b04b38Smrg#endif 129265b04b38Smrg 129365b04b38Smrg if (!ShmRegisterPrivates()) 129465b04b38Smrg return; 129565b04b38Smrg 129665b04b38Smrg sharedPixmaps = xFalse; 129765b04b38Smrg { 129865b04b38Smrg sharedPixmaps = xTrue; 129965b04b38Smrg for (i = 0; i < screenInfo.numScreens; i++) 130065b04b38Smrg { 130165b04b38Smrg ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]); 130265b04b38Smrg if (!screen_priv->shmFuncs) 130365b04b38Smrg screen_priv->shmFuncs = &miFuncs; 130465b04b38Smrg if (!screen_priv->shmFuncs->CreatePixmap) 130565b04b38Smrg sharedPixmaps = xFalse; 130665b04b38Smrg } 130765b04b38Smrg if (sharedPixmaps) 130865b04b38Smrg for (i = 0; i < screenInfo.numScreens; i++) 130965b04b38Smrg { 131065b04b38Smrg ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]); 131165b04b38Smrg screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap; 131265b04b38Smrg screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap; 131365b04b38Smrg } 131465b04b38Smrg } 131565b04b38Smrg ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg"); 131665b04b38Smrg if (ShmSegType && 131765b04b38Smrg (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors, 131865b04b38Smrg ProcShmDispatch, SProcShmDispatch, 131965b04b38Smrg ShmResetProc, StandardMinorOpcode))) 132065b04b38Smrg { 132165b04b38Smrg ShmReqCode = (unsigned char)extEntry->base; 132265b04b38Smrg ShmCompletionCode = extEntry->eventBase; 132365b04b38Smrg BadShmSegCode = extEntry->errorBase; 132465b04b38Smrg SetResourceTypeErrorValue(ShmSegType, BadShmSegCode); 132565b04b38Smrg EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent; 132665b04b38Smrg } 132765b04b38Smrg} 1328