1 /************************************************************
3 Copyright 1989, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
25 ********************************************************/
27 /* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
31 #include <dix-config.h>
33 #include <sys/types.h>
41 #include <X11/Xproto.h>
42 #include <X11/extensions/shmproto.h>
43 #include <X11/Xfuncproto.h>
45 #include "dix/dix_priv.h"
47 #include "os/busfault.h"
52 #include "dixstruct_priv.h"
54 #include "scrnintstr.h"
55 #include "windowstr.h"
56 #include "pixmapstr.h"
58 #include "extnsionst.h"
62 #include "extinit_priv.h"
63 #include "protocol-versions.h"
65 /* Needed for Solaris cross-zone shared memory extension */
67 #include <sys/ipc_impl.h>
68 #define SHMSTAT(id, buf) shmctl64(id, IPC_STAT64, buf)
69 #define SHMSTAT_TYPE struct shmid_ds64
70 #define SHMPERM_TYPE struct ipc_perm64
71 #define SHM_PERM(buf) buf.shmx_perm
72 #define SHM_SEGSZ(buf) buf.shmx_segsz
73 #define SHMPERM_UID(p) p->ipcx_uid
74 #define SHMPERM_CUID(p) p->ipcx_cuid
75 #define SHMPERM_GID(p) p->ipcx_gid
76 #define SHMPERM_CGID(p) p->ipcx_cgid
77 #define SHMPERM_MODE(p) p->ipcx_mode
78 #define SHMPERM_ZONEID(p) p->ipcx_zoneid
80 #define SHMSTAT(id, buf) shmctl(id, IPC_STAT, buf)
81 #define SHMSTAT_TYPE struct shmid_ds
82 #define SHMPERM_TYPE struct ipc_perm
83 #define SHM_PERM(buf) buf.shm_perm
84 #define SHM_SEGSZ(buf) buf.shm_segsz
85 #define SHMPERM_UID(p) p->uid
86 #define SHMPERM_CUID(p) p->cuid
87 #define SHMPERM_GID(p) p->gid
88 #define SHMPERM_CGID(p) p->cgid
89 #define SHMPERM_MODE(p) p->mode
93 #include "panoramiX.h"
94 #include "panoramiXsrv.h"
97 typedef struct _ShmScrPrivateRec
{
98 CloseScreenProcPtr CloseScreen
;
100 DestroyPixmapProcPtr destroyPixmap
;
103 static PixmapPtr
fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS
);
104 static int ShmDetachSegment(void *value
, XID shmseg
);
105 static void ShmResetProc(ExtensionEntry
*extEntry
);
106 static void SShmCompletionEvent(xShmCompletionEvent
*from
,
107 xShmCompletionEvent
*to
);
109 static Bool
ShmDestroyPixmap(PixmapPtr pPixmap
);
111 static unsigned char ShmReqCode
;
112 int ShmCompletionCode
;
115 static ShmDescPtr Shmsegs
;
116 static Bool sharedPixmaps
;
117 static DevPrivateKeyRec shmScrPrivateKeyRec
;
119 #define shmScrPrivateKey (&shmScrPrivateKeyRec)
120 static DevPrivateKeyRec shmPixmapPrivateKeyRec
;
122 #define shmPixmapPrivateKey (&shmPixmapPrivateKeyRec)
123 static ShmFuncs miFuncs
= { NULL
, NULL
};
124 static ShmFuncs fbFuncs
= { fbShmCreatePixmap
, NULL
};
126 #define ShmGetScreenPriv(s) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey))
128 #define VERIFY_SHMSEG(shmseg,shmdesc,client) \
131 tmprc = dixLookupResourceByType((void **)&(shmdesc), shmseg, ShmSegType, \
132 client, DixReadAccess); \
133 if (tmprc != Success) \
137 #define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
139 VERIFY_SHMSEG(shmseg, shmdesc, client); \
140 if ((offset & 3) || (offset > shmdesc->size)) \
142 client->errorValue = offset; \
145 if (needwrite && !shmdesc->writable) \
149 #define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
151 if ((offset + len) > shmdesc->size) \
157 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__)
159 static Bool badSysCall
= FALSE
;
162 SigSysHandler(int signo
)
168 CheckForShmSyscall(void)
170 void (*oldHandler
) (int);
173 /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
174 oldHandler
= OsSignal(SIGSYS
, SigSysHandler
);
177 shmid
= shmget(IPC_PRIVATE
, 4096, IPC_CREAT
);
180 /* Successful allocation - clean up */
181 shmctl(shmid
, IPC_RMID
, NULL
);
184 /* Allocation failed */
187 OsSignal(SIGSYS
, oldHandler
);
191 #define MUST_CHECK_FOR_SHM_SYSCALL
196 ShmCloseScreen(ScreenPtr pScreen
)
198 ShmScrPrivateRec
*screen_priv
= ShmGetScreenPriv(pScreen
);
200 pScreen
->CloseScreen
= screen_priv
->CloseScreen
;
201 dixSetPrivate(&pScreen
->devPrivates
, shmScrPrivateKey
, NULL
);
203 return (*pScreen
->CloseScreen
) (pScreen
);
206 static ShmScrPrivateRec
*
207 ShmInitScreenPriv(ScreenPtr pScreen
)
209 ShmScrPrivateRec
*screen_priv
= ShmGetScreenPriv(pScreen
);
212 screen_priv
= calloc(1, sizeof(ShmScrPrivateRec
));
213 screen_priv
->CloseScreen
= pScreen
->CloseScreen
;
214 dixSetPrivate(&pScreen
->devPrivates
, shmScrPrivateKey
, screen_priv
);
215 pScreen
->CloseScreen
= ShmCloseScreen
;
221 ShmRegisterPrivates(void)
223 if (!dixRegisterPrivateKey(&shmScrPrivateKeyRec
, PRIVATE_SCREEN
, 0))
225 if (!dixRegisterPrivateKey(&shmPixmapPrivateKeyRec
, PRIVATE_PIXMAP
, 0))
230 /*ARGSUSED*/ static void
231 ShmResetProc(ExtensionEntry
* extEntry
)
235 for (i
= 0; i
< screenInfo
.numScreens
; i
++)
236 ShmRegisterFuncs(screenInfo
.screens
[i
], NULL
);
240 ShmRegisterFuncs(ScreenPtr pScreen
, ShmFuncsPtr funcs
)
242 if (!ShmRegisterPrivates())
244 ShmInitScreenPriv(pScreen
)->shmFuncs
= funcs
;
248 ShmDestroyPixmap(PixmapPtr pPixmap
)
250 ScreenPtr pScreen
= pPixmap
->drawable
.pScreen
;
251 ShmScrPrivateRec
*screen_priv
= ShmGetScreenPriv(pScreen
);
252 void *shmdesc
= NULL
;
255 if (pPixmap
->refcnt
== 1)
256 shmdesc
= dixLookupPrivate(&pPixmap
->devPrivates
, shmPixmapPrivateKey
);
258 pScreen
->DestroyPixmap
= screen_priv
->destroyPixmap
;
259 ret
= (*pScreen
->DestroyPixmap
) (pPixmap
);
260 screen_priv
->destroyPixmap
= pScreen
->DestroyPixmap
;
261 pScreen
->DestroyPixmap
= ShmDestroyPixmap
;
264 ShmDetachSegment(shmdesc
, 0);
270 ShmRegisterFbFuncs(ScreenPtr pScreen
)
272 ShmRegisterFuncs(pScreen
, &fbFuncs
);
276 ProcShmQueryVersion(ClientPtr client
)
278 xShmQueryVersionReply rep
= {
280 .sharedPixmaps
= sharedPixmaps
,
281 .sequenceNumber
= client
->sequence
,
283 .majorVersion
= SERVER_SHM_MAJOR_VERSION
,
284 .minorVersion
= SERVER_SHM_MINOR_VERSION
,
287 .pixmapFormat
= sharedPixmaps
? ZPixmap
: 0
290 REQUEST_SIZE_MATCH(xShmQueryVersionReq
);
292 if (client
->swapped
) {
293 swaps(&rep
.sequenceNumber
);
295 swaps(&rep
.majorVersion
);
296 swaps(&rep
.minorVersion
);
300 WriteToClient(client
, sizeof(xShmQueryVersionReply
), &rep
);
305 * Simulate the access() system call for a shared memory segment,
306 * using the credentials from the client if available.
309 shm_access(ClientPtr client
, SHMPERM_TYPE
* perm
, int readonly
)
313 int uidset
= 0, gidset
= 0;
314 LocalClientCredRec
*lcc
;
316 if (GetLocalClientCreds(client
, &lcc
) != -1) {
318 if (lcc
->fieldsSet
& LCC_UID_SET
) {
322 if (lcc
->fieldsSet
& LCC_GID_SET
) {
327 #if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID)
328 if (((lcc
->fieldsSet
& LCC_ZID_SET
) == 0) || (lcc
->zoneid
== -1)
329 || (lcc
->zoneid
!= SHMPERM_ZONEID(perm
))) {
334 FreeLocalClientCreds(lcc
);
337 /* User id 0 always gets access */
341 /* Check the owner */
342 if (SHMPERM_UID(perm
) == uid
|| SHMPERM_CUID(perm
) == uid
) {
347 return (SHMPERM_MODE(perm
) & mask
) == mask
? 0 : -1;
352 /* Check the group */
353 if (SHMPERM_GID(perm
) == gid
|| SHMPERM_CGID(perm
) == gid
) {
358 return (SHMPERM_MODE(perm
) & mask
) == mask
? 0 : -1;
362 /* Otherwise, check everyone else */
367 return (SHMPERM_MODE(perm
) & mask
) == mask
? 0 : -1;
371 ProcShmAttach(ClientPtr client
)
376 REQUEST(xShmAttachReq
);
378 REQUEST_SIZE_MATCH(xShmAttachReq
);
379 LEGAL_NEW_RESOURCE(stuff
->shmseg
, client
);
380 if ((stuff
->readOnly
!= xTrue
) && (stuff
->readOnly
!= xFalse
)) {
381 client
->errorValue
= stuff
->readOnly
;
384 for (shmdesc
= Shmsegs
; shmdesc
; shmdesc
= shmdesc
->next
) {
385 if (!SHMDESC_IS_FD(shmdesc
) && shmdesc
->shmid
== stuff
->shmid
)
389 if (!stuff
->readOnly
&& !shmdesc
->writable
)
394 shmdesc
= malloc(sizeof(ShmDescRec
));
397 #ifdef SHM_FD_PASSING
398 shmdesc
->is_fd
= FALSE
;
400 shmdesc
->addr
= shmat(stuff
->shmid
, 0,
401 stuff
->readOnly
? SHM_RDONLY
: 0);
402 if ((shmdesc
->addr
== ((char *) -1)) || SHMSTAT(stuff
->shmid
, &buf
)) {
407 /* The attach was performed with root privs. We must
408 * do manual checking of access rights for the credentials
411 if (shm_access(client
, &(SHM_PERM(buf
)), stuff
->readOnly
) == -1) {
412 shmdt(shmdesc
->addr
);
417 shmdesc
->shmid
= stuff
->shmid
;
419 shmdesc
->writable
= !stuff
->readOnly
;
420 shmdesc
->size
= SHM_SEGSZ(buf
);
421 shmdesc
->next
= Shmsegs
;
424 if (!AddResource(stuff
->shmseg
, ShmSegType
, (void *) shmdesc
))
429 /*ARGSUSED*/ static int
430 ShmDetachSegment(void *value
, /* must conform to DeleteType */
433 ShmDescPtr shmdesc
= (ShmDescPtr
) value
;
436 if (--shmdesc
->refcnt
)
439 if (shmdesc
->is_fd
) {
440 if (shmdesc
->busfault
)
441 busfault_unregister(shmdesc
->busfault
);
442 munmap(shmdesc
->addr
, shmdesc
->size
);
445 shmdt(shmdesc
->addr
);
446 for (prev
= &Shmsegs
; *prev
!= shmdesc
; prev
= &(*prev
)->next
);
447 *prev
= shmdesc
->next
;
453 ProcShmDetach(ClientPtr client
)
457 REQUEST(xShmDetachReq
);
459 REQUEST_SIZE_MATCH(xShmDetachReq
);
460 VERIFY_SHMSEG(stuff
->shmseg
, shmdesc
, client
);
461 FreeResource(stuff
->shmseg
, X11_RESTYPE_NONE
);
466 * If the given request doesn't exactly match PutImage's constraints,
467 * wrap the image in a scratch pixmap header and let CopyArea sort it out.
470 doShmPutImage(DrawablePtr dst
, GCPtr pGC
,
471 int depth
, unsigned int format
,
472 int w
, int h
, int sx
, int sy
, int sw
, int sh
, int dx
, int dy
,
477 if (format
== ZPixmap
|| (format
== XYPixmap
&& depth
== 1)) {
478 pPixmap
= GetScratchPixmapHeader(dst
->pScreen
, w
, h
, depth
,
480 PixmapBytePad(w
, depth
), data
);
483 (void) pGC
->ops
->CopyArea((DrawablePtr
) pPixmap
, dst
, pGC
,
484 sx
, sy
, sw
, sh
, dx
, dy
);
485 FreeScratchPixmapHeader(pPixmap
);
488 GCPtr putGC
= GetScratchGC(depth
, dst
->pScreen
);
493 pPixmap
= (*dst
->pScreen
->CreatePixmap
) (dst
->pScreen
, sw
, sh
, depth
,
494 CREATE_PIXMAP_USAGE_SCRATCH
);
496 FreeScratchGC(putGC
);
499 ValidateGC(&pPixmap
->drawable
, putGC
);
500 (*putGC
->ops
->PutImage
) (&pPixmap
->drawable
, putGC
, depth
, -sx
, -sy
, w
,
502 (format
== XYPixmap
) ? XYPixmap
: ZPixmap
,
504 FreeScratchGC(putGC
);
505 if (format
== XYBitmap
)
506 (void) (*pGC
->ops
->CopyPlane
) (&pPixmap
->drawable
, dst
, pGC
, 0, 0,
509 (void) (*pGC
->ops
->CopyArea
) (&pPixmap
->drawable
, dst
, pGC
, 0, 0,
511 (*pPixmap
->drawable
.pScreen
->DestroyPixmap
) (pPixmap
);
516 ProcShmPutImage(ClientPtr client
)
523 REQUEST(xShmPutImageReq
);
525 REQUEST_SIZE_MATCH(xShmPutImageReq
);
526 VALIDATE_DRAWABLE_AND_GC(stuff
->drawable
, pDraw
, DixWriteAccess
);
527 VERIFY_SHMPTR(stuff
->shmseg
, stuff
->offset
, FALSE
, shmdesc
, client
);
528 if ((stuff
->sendEvent
!= xTrue
) && (stuff
->sendEvent
!= xFalse
))
530 if (stuff
->format
== XYBitmap
) {
531 if (stuff
->depth
!= 1)
533 length
= PixmapBytePad(stuff
->totalWidth
, 1);
535 else if (stuff
->format
== XYPixmap
) {
536 if (pDraw
->depth
!= stuff
->depth
)
538 length
= PixmapBytePad(stuff
->totalWidth
, 1);
539 length
*= stuff
->depth
;
541 else if (stuff
->format
== ZPixmap
) {
542 if (pDraw
->depth
!= stuff
->depth
)
544 length
= PixmapBytePad(stuff
->totalWidth
, stuff
->depth
);
547 client
->errorValue
= stuff
->format
;
552 * There's a potential integer overflow in this check:
553 * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
555 * the version below ought to avoid it
557 if (stuff
->totalHeight
!= 0 &&
558 length
> (shmdesc
->size
- stuff
->offset
) / stuff
->totalHeight
) {
559 client
->errorValue
= stuff
->totalWidth
;
562 if (stuff
->srcX
> stuff
->totalWidth
) {
563 client
->errorValue
= stuff
->srcX
;
566 if (stuff
->srcY
> stuff
->totalHeight
) {
567 client
->errorValue
= stuff
->srcY
;
570 if ((stuff
->srcX
+ stuff
->srcWidth
) > stuff
->totalWidth
) {
571 client
->errorValue
= stuff
->srcWidth
;
574 if ((stuff
->srcY
+ stuff
->srcHeight
) > stuff
->totalHeight
) {
575 client
->errorValue
= stuff
->srcHeight
;
579 if ((((stuff
->format
== ZPixmap
) && (stuff
->srcX
== 0)) ||
580 ((stuff
->format
!= ZPixmap
) &&
581 (stuff
->srcX
< screenInfo
.bitmapScanlinePad
) &&
582 ((stuff
->format
== XYBitmap
) ||
583 ((stuff
->srcY
== 0) &&
584 (stuff
->srcHeight
== stuff
->totalHeight
))))) &&
585 ((stuff
->srcX
+ stuff
->srcWidth
) == stuff
->totalWidth
))
586 (*pGC
->ops
->PutImage
) (pDraw
, pGC
, stuff
->depth
,
587 stuff
->dstX
, stuff
->dstY
,
588 stuff
->totalWidth
, stuff
->srcHeight
,
589 stuff
->srcX
, stuff
->format
,
590 shmdesc
->addr
+ stuff
->offset
+
591 (stuff
->srcY
* length
));
593 doShmPutImage(pDraw
, pGC
, stuff
->depth
, stuff
->format
,
594 stuff
->totalWidth
, stuff
->totalHeight
,
595 stuff
->srcX
, stuff
->srcY
,
596 stuff
->srcWidth
, stuff
->srcHeight
,
597 stuff
->dstX
, stuff
->dstY
, shmdesc
->addr
+ stuff
->offset
);
599 if (stuff
->sendEvent
) {
600 xShmCompletionEvent ev
= {
601 .type
= ShmCompletionCode
,
602 .drawable
= stuff
->drawable
,
603 .minorEvent
= X_ShmPutImage
,
604 .majorEvent
= ShmReqCode
,
605 .shmseg
= stuff
->shmseg
,
606 .offset
= stuff
->offset
608 WriteEventsToClient(client
, 1, (xEvent
*) &ev
);
615 ProcShmGetImage(ClientPtr client
)
618 long lenPer
= 0, length
;
620 xShmGetImageReply xgi
;
622 VisualID visual
= None
;
623 RegionPtr pVisibleRegion
= NULL
;
626 REQUEST(xShmGetImageReq
);
628 REQUEST_SIZE_MATCH(xShmGetImageReq
);
629 if ((stuff
->format
!= XYPixmap
) && (stuff
->format
!= ZPixmap
)) {
630 client
->errorValue
= stuff
->format
;
633 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, 0, DixReadAccess
);
636 VERIFY_SHMPTR(stuff
->shmseg
, stuff
->offset
, TRUE
, shmdesc
, client
);
637 if (pDraw
->type
== DRAWABLE_WINDOW
) {
638 if ( /* check for being viewable */
639 !((WindowPtr
) pDraw
)->realized
||
640 /* check for being on screen */
641 pDraw
->x
+ stuff
->x
< 0 ||
642 pDraw
->x
+ stuff
->x
+ (int) stuff
->width
> pDraw
->pScreen
->width
643 || pDraw
->y
+ stuff
->y
< 0 ||
644 pDraw
->y
+ stuff
->y
+ (int) stuff
->height
>
645 pDraw
->pScreen
->height
||
646 /* check for being inside of border */
647 stuff
->x
< -wBorderWidth((WindowPtr
) pDraw
) ||
648 stuff
->x
+ (int) stuff
->width
>
649 wBorderWidth((WindowPtr
) pDraw
) + (int) pDraw
->width
||
650 stuff
->y
< -wBorderWidth((WindowPtr
) pDraw
) ||
651 stuff
->y
+ (int) stuff
->height
>
652 wBorderWidth((WindowPtr
) pDraw
) + (int) pDraw
->height
)
654 visual
= wVisual(((WindowPtr
) pDraw
));
655 if (pDraw
->type
== DRAWABLE_WINDOW
)
656 pVisibleRegion
= &((WindowPtr
) pDraw
)->borderClip
;
657 pDraw
->pScreen
->SourceValidate(pDraw
, stuff
->x
, stuff
->y
,
658 stuff
->width
, stuff
->height
,
663 stuff
->x
+ (int) stuff
->width
> pDraw
->width
||
664 stuff
->y
< 0 || stuff
->y
+ (int) stuff
->height
> pDraw
->height
)
668 xgi
= (xShmGetImageReply
) {
670 .sequenceNumber
= client
->sequence
,
673 .depth
= pDraw
->depth
675 if (stuff
->format
== ZPixmap
) {
676 length
= PixmapBytePad(stuff
->width
, pDraw
->depth
) * stuff
->height
;
679 lenPer
= PixmapBytePad(stuff
->width
, 1) * stuff
->height
;
680 plane
= ((Mask
) 1) << (pDraw
->depth
- 1);
681 /* only planes asked for */
682 length
= lenPer
* Ones(stuff
->planeMask
& (plane
| (plane
- 1)));
685 VERIFY_SHMSIZE(shmdesc
, stuff
->offset
, length
, client
);
691 else if (stuff
->format
== ZPixmap
) {
692 (*pDraw
->pScreen
->GetImage
) (pDraw
, stuff
->x
, stuff
->y
,
693 stuff
->width
, stuff
->height
,
694 stuff
->format
, stuff
->planeMask
,
695 shmdesc
->addr
+ stuff
->offset
);
697 XaceCensorImage(client
, pVisibleRegion
,
698 PixmapBytePad(stuff
->width
, pDraw
->depth
), pDraw
,
699 stuff
->x
, stuff
->y
, stuff
->width
, stuff
->height
,
700 stuff
->format
, shmdesc
->addr
+ stuff
->offset
);
704 length
= stuff
->offset
;
705 for (; plane
; plane
>>= 1) {
706 if (stuff
->planeMask
& plane
) {
707 (*pDraw
->pScreen
->GetImage
) (pDraw
,
709 stuff
->width
, stuff
->height
,
710 stuff
->format
, plane
,
711 shmdesc
->addr
+ length
);
713 XaceCensorImage(client
, pVisibleRegion
,
714 BitmapBytePad(stuff
->width
), pDraw
,
715 stuff
->x
, stuff
->y
, stuff
->width
, stuff
->height
,
716 stuff
->format
, shmdesc
->addr
+ length
);
722 if (client
->swapped
) {
723 swaps(&xgi
.sequenceNumber
);
728 WriteToClient(client
, sizeof(xShmGetImageReply
), &xgi
);
735 ProcPanoramiXShmPutImage(ClientPtr client
)
737 int j
, result
, orig_x
, orig_y
;
738 PanoramiXRes
*draw
, *gc
;
739 Bool sendEvent
, isRoot
;
741 REQUEST(xShmPutImageReq
);
742 REQUEST_SIZE_MATCH(xShmPutImageReq
);
744 result
= dixLookupResourceByClass((void **) &draw
, stuff
->drawable
,
745 XRC_DRAWABLE
, client
, DixWriteAccess
);
746 if (result
!= Success
)
747 return (result
== BadValue
) ? BadDrawable
: result
;
749 result
= dixLookupResourceByType((void **) &gc
, stuff
->gc
,
750 XRT_GC
, client
, DixReadAccess
);
751 if (result
!= Success
)
754 isRoot
= (draw
->type
== XRT_WINDOW
) && draw
->u
.win
.root
;
756 orig_x
= stuff
->dstX
;
757 orig_y
= stuff
->dstY
;
758 sendEvent
= stuff
->sendEvent
;
759 stuff
->sendEvent
= 0;
762 stuff
->sendEvent
= sendEvent
;
763 stuff
->drawable
= draw
->info
[j
].id
;
764 stuff
->gc
= gc
->info
[j
].id
;
766 stuff
->dstX
= orig_x
- screenInfo
.screens
[j
]->x
;
767 stuff
->dstY
= orig_y
- screenInfo
.screens
[j
]->y
;
769 result
= ProcShmPutImage(client
);
770 if (result
!= Success
)
777 ProcPanoramiXShmGetImage(ClientPtr client
)
780 DrawablePtr
*drawables
;
782 xShmGetImageReply xgi
;
784 int i
, x
, y
, w
, h
, format
, rc
;
785 Mask plane
= 0, planemask
;
786 long lenPer
= 0, length
, widthBytesLine
;
789 REQUEST(xShmGetImageReq
);
791 REQUEST_SIZE_MATCH(xShmGetImageReq
);
793 if ((stuff
->format
!= XYPixmap
) && (stuff
->format
!= ZPixmap
)) {
794 client
->errorValue
= stuff
->format
;
798 rc
= dixLookupResourceByClass((void **) &draw
, stuff
->drawable
,
799 XRC_DRAWABLE
, client
, DixWriteAccess
);
801 return (rc
== BadValue
) ? BadDrawable
: rc
;
803 if (draw
->type
== XRT_PIXMAP
)
804 return ProcShmGetImage(client
);
806 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, 0, DixReadAccess
);
810 VERIFY_SHMPTR(stuff
->shmseg
, stuff
->offset
, TRUE
, shmdesc
, client
);
816 format
= stuff
->format
;
817 planemask
= stuff
->planeMask
;
819 isRoot
= (draw
->type
== XRT_WINDOW
) && draw
->u
.win
.root
;
822 if ( /* check for being onscreen */
823 x
< 0 || x
+ w
> PanoramiXPixWidth
||
824 y
< 0 || y
+ h
> PanoramiXPixHeight
)
828 if ( /* check for being onscreen */
829 screenInfo
.screens
[0]->x
+ pDraw
->x
+ x
< 0 ||
830 screenInfo
.screens
[0]->x
+ pDraw
->x
+ x
+ w
> PanoramiXPixWidth
831 || screenInfo
.screens
[0]->y
+ pDraw
->y
+ y
< 0 ||
832 screenInfo
.screens
[0]->y
+ pDraw
->y
+ y
+ h
> PanoramiXPixHeight
834 /* check for being inside of border */
835 x
< -wBorderWidth((WindowPtr
) pDraw
) ||
836 x
+ w
> wBorderWidth((WindowPtr
) pDraw
) + (int) pDraw
->width
||
837 y
< -wBorderWidth((WindowPtr
) pDraw
) ||
838 y
+ h
> wBorderWidth((WindowPtr
) pDraw
) + (int) pDraw
->height
)
842 if (format
== ZPixmap
) {
843 widthBytesLine
= PixmapBytePad(w
, pDraw
->depth
);
844 length
= widthBytesLine
* h
;
847 widthBytesLine
= PixmapBytePad(w
, 1);
848 lenPer
= widthBytesLine
* h
;
849 plane
= ((Mask
) 1) << (pDraw
->depth
- 1);
850 length
= lenPer
* Ones(planemask
& (plane
| (plane
- 1)));
853 VERIFY_SHMSIZE(shmdesc
, stuff
->offset
, length
, client
);
855 drawables
= calloc(PanoramiXNumScreens
, sizeof(DrawablePtr
));
859 drawables
[0] = pDraw
;
860 FOR_NSCREENS_FORWARD_SKIP(i
) {
861 rc
= dixLookupDrawable(drawables
+ i
, draw
->info
[i
].id
, client
, 0,
868 FOR_NSCREENS_FORWARD(i
) {
869 drawables
[i
]->pScreen
->SourceValidate(drawables
[i
], 0, 0,
871 drawables
[i
]->height
,
875 xgi
= (xShmGetImageReply
) {
877 .sequenceNumber
= client
->sequence
,
879 .visual
= wVisual(((WindowPtr
) pDraw
)),
880 .depth
= pDraw
->depth
885 if (length
== 0) { /* nothing to do */
887 else if (format
== ZPixmap
) {
888 XineramaGetImageData(drawables
, x
, y
, w
, h
, format
, planemask
,
889 shmdesc
->addr
+ stuff
->offset
,
890 widthBytesLine
, isRoot
);
894 length
= stuff
->offset
;
895 for (; plane
; plane
>>= 1) {
896 if (planemask
& plane
) {
897 XineramaGetImageData(drawables
, x
, y
, w
, h
,
898 format
, plane
, shmdesc
->addr
+ length
,
899 widthBytesLine
, isRoot
);
906 if (client
->swapped
) {
907 swaps(&xgi
.sequenceNumber
);
912 WriteToClient(client
, sizeof(xShmGetImageReply
), &xgi
);
918 ProcPanoramiXShmCreatePixmap(ClientPtr client
)
920 ScreenPtr pScreen
= NULL
;
921 PixmapPtr pMap
= NULL
;
924 int i
, j
, result
, rc
;
927 REQUEST(xShmCreatePixmapReq
);
928 unsigned int width
, height
, depth
;
930 PanoramiXRes
*newPix
;
932 REQUEST_SIZE_MATCH(xShmCreatePixmapReq
);
933 client
->errorValue
= stuff
->pid
;
935 return BadImplementation
;
936 LEGAL_NEW_RESOURCE(stuff
->pid
, client
);
937 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, M_ANY
,
942 VERIFY_SHMPTR(stuff
->shmseg
, stuff
->offset
, TRUE
, shmdesc
, client
);
944 width
= stuff
->width
;
945 height
= stuff
->height
;
946 depth
= stuff
->depth
;
947 if (!width
|| !height
|| !depth
) {
948 client
->errorValue
= 0;
951 if (width
> 32767 || height
> 32767)
954 if (stuff
->depth
!= 1) {
955 pDepth
= pDraw
->pScreen
->allowedDepths
;
956 for (i
= 0; i
< pDraw
->pScreen
->numDepths
; i
++, pDepth
++)
957 if (pDepth
->depth
== stuff
->depth
)
959 client
->errorValue
= stuff
->depth
;
964 size
= PixmapBytePad(width
, depth
) * height
;
965 if (sizeof(size
) == 4 && BitsPerPixel(depth
) > 8) {
966 if (size
< width
* height
)
969 /* thankfully, offset is unsigned */
970 if (stuff
->offset
+ size
< size
)
973 VERIFY_SHMSIZE(shmdesc
, stuff
->offset
, size
, client
);
975 if (!(newPix
= malloc(sizeof(PanoramiXRes
))))
978 newPix
->type
= XRT_PIXMAP
;
979 newPix
->u
.pix
.shared
= TRUE
;
980 panoramix_setup_ids(newPix
, client
, stuff
->pid
);
985 ShmScrPrivateRec
*screen_priv
;
987 pScreen
= screenInfo
.screens
[j
];
989 screen_priv
= ShmGetScreenPriv(pScreen
);
990 pMap
= (*screen_priv
->shmFuncs
->CreatePixmap
) (pScreen
,
998 result
= XaceHookResourceAccess(client
, stuff
->pid
,
999 X11_RESTYPE_PIXMAP
, pMap
, X11_RESTYPE_NONE
, NULL
, DixCreateAccess
);
1000 if (result
!= Success
) {
1001 pDraw
->pScreen
->DestroyPixmap(pMap
);
1004 dixSetPrivate(&pMap
->devPrivates
, shmPixmapPrivateKey
, shmdesc
);
1006 pMap
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
1007 pMap
->drawable
.id
= newPix
->info
[j
].id
;
1008 if (!AddResource(newPix
->info
[j
].id
, X11_RESTYPE_PIXMAP
, (void *) pMap
)) {
1019 if (result
!= Success
) {
1021 FreeResource(newPix
->info
[j
].id
, X11_RESTYPE_NONE
);
1025 AddResource(stuff
->pid
, XRT_PIXMAP
, newPix
);
1032 fbShmCreatePixmap(ScreenPtr pScreen
,
1033 int width
, int height
, int depth
, char *addr
)
1037 pPixmap
= (*pScreen
->CreatePixmap
) (pScreen
, 0, 0, pScreen
->rootDepth
, 0);
1041 if (!(*pScreen
->ModifyPixmapHeader
) (pPixmap
, width
, height
, depth
,
1042 BitsPerPixel(depth
),
1043 PixmapBytePad(width
, depth
),
1045 (*pScreen
->DestroyPixmap
) (pPixmap
);
1052 ProcShmCreatePixmap(ClientPtr client
)
1059 ShmScrPrivateRec
*screen_priv
;
1061 REQUEST(xShmCreatePixmapReq
);
1062 unsigned int width
, height
, depth
;
1065 REQUEST_SIZE_MATCH(xShmCreatePixmapReq
);
1066 client
->errorValue
= stuff
->pid
;
1068 return BadImplementation
;
1069 LEGAL_NEW_RESOURCE(stuff
->pid
, client
);
1070 rc
= dixLookupDrawable(&pDraw
, stuff
->drawable
, client
, M_ANY
,
1075 VERIFY_SHMPTR(stuff
->shmseg
, stuff
->offset
, TRUE
, shmdesc
, client
);
1077 width
= stuff
->width
;
1078 height
= stuff
->height
;
1079 depth
= stuff
->depth
;
1080 if (!width
|| !height
|| !depth
) {
1081 client
->errorValue
= 0;
1084 if (width
> 32767 || height
> 32767)
1087 if (stuff
->depth
!= 1) {
1088 pDepth
= pDraw
->pScreen
->allowedDepths
;
1089 for (i
= 0; i
< pDraw
->pScreen
->numDepths
; i
++, pDepth
++)
1090 if (pDepth
->depth
== stuff
->depth
)
1092 client
->errorValue
= stuff
->depth
;
1097 size
= PixmapBytePad(width
, depth
) * height
;
1098 if (sizeof(size
) == 4 && BitsPerPixel(depth
) > 8) {
1099 if (size
< width
* height
)
1102 /* thankfully, offset is unsigned */
1103 if (stuff
->offset
+ size
< size
)
1106 VERIFY_SHMSIZE(shmdesc
, stuff
->offset
, size
, client
);
1107 screen_priv
= ShmGetScreenPriv(pDraw
->pScreen
);
1108 pMap
= (*screen_priv
->shmFuncs
->CreatePixmap
) (pDraw
->pScreen
, stuff
->width
,
1109 stuff
->height
, stuff
->depth
,
1113 rc
= XaceHookResourceAccess(client
, stuff
->pid
, X11_RESTYPE_PIXMAP
,
1114 pMap
, X11_RESTYPE_NONE
, NULL
, DixCreateAccess
);
1115 if (rc
!= Success
) {
1116 pDraw
->pScreen
->DestroyPixmap(pMap
);
1119 dixSetPrivate(&pMap
->devPrivates
, shmPixmapPrivateKey
, shmdesc
);
1121 pMap
->drawable
.serialNumber
= NEXT_SERIAL_NUMBER
;
1122 pMap
->drawable
.id
= stuff
->pid
;
1123 if (AddResource(stuff
->pid
, X11_RESTYPE_PIXMAP
, (void *) pMap
)) {
1130 #ifdef SHM_FD_PASSING
1133 ShmBusfaultNotify(void *context
)
1135 ShmDescPtr shmdesc
= context
;
1137 ErrorF("shared memory 0x%x truncated by client\n",
1138 (unsigned int) shmdesc
->resource
);
1139 busfault_unregister(shmdesc
->busfault
);
1140 shmdesc
->busfault
= NULL
;
1141 FreeResource (shmdesc
->resource
, X11_RESTYPE_NONE
);
1145 ProcShmAttachFd(ClientPtr client
)
1149 REQUEST(xShmAttachFdReq
);
1152 SetReqFds(client
, 1);
1153 REQUEST_SIZE_MATCH(xShmAttachFdReq
);
1154 LEGAL_NEW_RESOURCE(stuff
->shmseg
, client
);
1155 if ((stuff
->readOnly
!= xTrue
) && (stuff
->readOnly
!= xFalse
)) {
1156 client
->errorValue
= stuff
->readOnly
;
1159 fd
= ReadFdFromClient(client
);
1163 if (fstat(fd
, &statb
) < 0 || statb
.st_size
== 0) {
1168 shmdesc
= malloc(sizeof(ShmDescRec
));
1173 shmdesc
->is_fd
= TRUE
;
1174 shmdesc
->addr
= mmap(NULL
, statb
.st_size
,
1175 stuff
->readOnly
? PROT_READ
: PROT_READ
|PROT_WRITE
,
1180 if (shmdesc
->addr
== ((char *) -1)) {
1185 shmdesc
->refcnt
= 1;
1186 shmdesc
->writable
= !stuff
->readOnly
;
1187 shmdesc
->size
= statb
.st_size
;
1188 shmdesc
->resource
= stuff
->shmseg
;
1190 shmdesc
->busfault
= busfault_register_mmap(shmdesc
->addr
, shmdesc
->size
, ShmBusfaultNotify
, shmdesc
);
1191 if (!shmdesc
->busfault
) {
1192 munmap(shmdesc
->addr
, shmdesc
->size
);
1197 shmdesc
->next
= Shmsegs
;
1200 if (!AddResource(stuff
->shmseg
, ShmSegType
, (void *) shmdesc
))
1208 const char *shmdirs
[] = {
1215 #ifdef HAVE_MEMFD_CREATE
1216 fd
= memfd_create("xorg", MFD_CLOEXEC
|MFD_ALLOW_SEALING
);
1218 fcntl(fd
, F_ADD_SEALS
, F_SEAL_SHRINK
);
1219 DebugF ("Using memfd_create\n");
1225 for (int i
= 0; i
< ARRAY_SIZE(shmdirs
); i
++) {
1226 fd
= open(shmdirs
[i
], O_TMPFILE
|O_RDWR
|O_CLOEXEC
|O_EXCL
, 0666);
1228 DebugF ("Using O_TMPFILE\n");
1232 ErrorF ("Not using O_TMPFILE\n");
1235 for (int i
= 0; i
< ARRAY_SIZE(shmdirs
); i
++) {
1236 char template[PATH_MAX
];
1237 snprintf(template, ARRAY_SIZE(template), "%s/shmfd-XXXXXX", shmdirs
[i
]);
1238 #ifdef HAVE_MKOSTEMP
1239 fd
= mkostemp(template, O_CLOEXEC
);
1241 fd
= mkstemp(template);
1246 #ifndef HAVE_MKOSTEMP
1247 int flags
= fcntl(fd
, F_GETFD
);
1249 flags
|= FD_CLOEXEC
;
1250 (void) fcntl(fd
, F_SETFD
, flags
);
1260 ProcShmCreateSegment(ClientPtr client
)
1264 REQUEST(xShmCreateSegmentReq
);
1265 xShmCreateSegmentReply rep
= {
1268 .sequenceNumber
= client
->sequence
,
1272 REQUEST_SIZE_MATCH(xShmCreateSegmentReq
);
1273 LEGAL_NEW_RESOURCE(stuff
->shmseg
, client
);
1274 if ((stuff
->readOnly
!= xTrue
) && (stuff
->readOnly
!= xFalse
)) {
1275 client
->errorValue
= stuff
->readOnly
;
1281 if (ftruncate(fd
, stuff
->size
) < 0) {
1285 shmdesc
= malloc(sizeof(ShmDescRec
));
1290 shmdesc
->is_fd
= TRUE
;
1291 shmdesc
->addr
= mmap(NULL
, stuff
->size
,
1292 stuff
->readOnly
? PROT_READ
: PROT_READ
|PROT_WRITE
,
1296 if (shmdesc
->addr
== ((char *) -1)) {
1302 shmdesc
->refcnt
= 1;
1303 shmdesc
->writable
= !stuff
->readOnly
;
1304 shmdesc
->size
= stuff
->size
;
1306 shmdesc
->busfault
= busfault_register_mmap(shmdesc
->addr
, shmdesc
->size
, ShmBusfaultNotify
, shmdesc
);
1307 if (!shmdesc
->busfault
) {
1309 munmap(shmdesc
->addr
, shmdesc
->size
);
1314 shmdesc
->next
= Shmsegs
;
1317 if (!AddResource(stuff
->shmseg
, ShmSegType
, (void *) shmdesc
)) {
1322 if (WriteFdToClient(client
, fd
, TRUE
) < 0) {
1323 FreeResource(stuff
->shmseg
, X11_RESTYPE_NONE
);
1327 WriteToClient(client
, sizeof (xShmCreateSegmentReply
), &rep
);
1330 #endif /* SHM_FD_PASSING */
1333 ProcShmDispatch(ClientPtr client
)
1337 if (stuff
->data
== X_ShmQueryVersion
)
1338 return ProcShmQueryVersion(client
);
1343 switch (stuff
->data
) {
1345 return ProcShmAttach(client
);
1347 return ProcShmDetach(client
);
1350 if (!noPanoramiXExtension
)
1351 return ProcPanoramiXShmPutImage(client
);
1353 return ProcShmPutImage(client
);
1356 if (!noPanoramiXExtension
)
1357 return ProcPanoramiXShmGetImage(client
);
1359 return ProcShmGetImage(client
);
1360 case X_ShmCreatePixmap
:
1362 if (!noPanoramiXExtension
)
1363 return ProcPanoramiXShmCreatePixmap(client
);
1365 return ProcShmCreatePixmap(client
);
1366 #ifdef SHM_FD_PASSING
1368 return ProcShmAttachFd(client
);
1369 case X_ShmCreateSegment
:
1370 return ProcShmCreateSegment(client
);
1378 SShmCompletionEvent(xShmCompletionEvent
* from
, xShmCompletionEvent
* to
)
1380 to
->type
= from
->type
;
1381 cpswaps(from
->sequenceNumber
, to
->sequenceNumber
);
1382 cpswapl(from
->drawable
, to
->drawable
);
1383 cpswaps(from
->minorEvent
, to
->minorEvent
);
1384 to
->majorEvent
= from
->majorEvent
;
1385 cpswapl(from
->shmseg
, to
->shmseg
);
1386 cpswapl(from
->offset
, to
->offset
);
1390 SProcShmQueryVersion(ClientPtr client
)
1392 REQUEST(xShmQueryVersionReq
);
1394 swaps(&stuff
->length
);
1395 return ProcShmQueryVersion(client
);
1399 SProcShmAttach(ClientPtr client
)
1401 REQUEST(xShmAttachReq
);
1402 swaps(&stuff
->length
);
1403 REQUEST_SIZE_MATCH(xShmAttachReq
);
1404 swapl(&stuff
->shmseg
);
1405 swapl(&stuff
->shmid
);
1406 return ProcShmAttach(client
);
1410 SProcShmDetach(ClientPtr client
)
1412 REQUEST(xShmDetachReq
);
1413 swaps(&stuff
->length
);
1414 REQUEST_SIZE_MATCH(xShmDetachReq
);
1415 swapl(&stuff
->shmseg
);
1416 return ProcShmDetach(client
);
1420 SProcShmPutImage(ClientPtr client
)
1422 REQUEST(xShmPutImageReq
);
1423 swaps(&stuff
->length
);
1424 REQUEST_SIZE_MATCH(xShmPutImageReq
);
1425 swapl(&stuff
->drawable
);
1427 swaps(&stuff
->totalWidth
);
1428 swaps(&stuff
->totalHeight
);
1429 swaps(&stuff
->srcX
);
1430 swaps(&stuff
->srcY
);
1431 swaps(&stuff
->srcWidth
);
1432 swaps(&stuff
->srcHeight
);
1433 swaps(&stuff
->dstX
);
1434 swaps(&stuff
->dstY
);
1435 swapl(&stuff
->shmseg
);
1436 swapl(&stuff
->offset
);
1437 return ProcShmPutImage(client
);
1441 SProcShmGetImage(ClientPtr client
)
1443 REQUEST(xShmGetImageReq
);
1444 swaps(&stuff
->length
);
1445 REQUEST_SIZE_MATCH(xShmGetImageReq
);
1446 swapl(&stuff
->drawable
);
1449 swaps(&stuff
->width
);
1450 swaps(&stuff
->height
);
1451 swapl(&stuff
->planeMask
);
1452 swapl(&stuff
->shmseg
);
1453 swapl(&stuff
->offset
);
1454 return ProcShmGetImage(client
);
1458 SProcShmCreatePixmap(ClientPtr client
)
1460 REQUEST(xShmCreatePixmapReq
);
1461 swaps(&stuff
->length
);
1462 REQUEST_SIZE_MATCH(xShmCreatePixmapReq
);
1464 swapl(&stuff
->drawable
);
1465 swaps(&stuff
->width
);
1466 swaps(&stuff
->height
);
1467 swapl(&stuff
->shmseg
);
1468 swapl(&stuff
->offset
);
1469 return ProcShmCreatePixmap(client
);
1472 #ifdef SHM_FD_PASSING
1474 SProcShmAttachFd(ClientPtr client
)
1476 REQUEST(xShmAttachFdReq
);
1477 SetReqFds(client
, 1);
1478 swaps(&stuff
->length
);
1479 REQUEST_SIZE_MATCH(xShmAttachFdReq
);
1480 swapl(&stuff
->shmseg
);
1481 return ProcShmAttachFd(client
);
1485 SProcShmCreateSegment(ClientPtr client
)
1487 REQUEST(xShmCreateSegmentReq
);
1488 swaps(&stuff
->length
);
1489 REQUEST_SIZE_MATCH(xShmCreateSegmentReq
);
1490 swapl(&stuff
->shmseg
);
1491 swapl(&stuff
->size
);
1492 return ProcShmCreateSegment(client
);
1494 #endif /* SHM_FD_PASSING */
1497 SProcShmDispatch(ClientPtr client
)
1501 if (stuff
->data
== X_ShmQueryVersion
)
1502 return SProcShmQueryVersion(client
);
1507 switch (stuff
->data
) {
1509 return SProcShmAttach(client
);
1511 return SProcShmDetach(client
);
1513 return SProcShmPutImage(client
);
1515 return SProcShmGetImage(client
);
1516 case X_ShmCreatePixmap
:
1517 return SProcShmCreatePixmap(client
);
1518 #ifdef SHM_FD_PASSING
1520 return SProcShmAttachFd(client
);
1521 case X_ShmCreateSegment
:
1522 return SProcShmCreateSegment(client
);
1530 ShmExtensionInit(void)
1532 ExtensionEntry
*extEntry
;
1535 #ifdef MUST_CHECK_FOR_SHM_SYSCALL
1536 if (!CheckForShmSyscall()) {
1537 ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
1542 if (!ShmRegisterPrivates())
1545 sharedPixmaps
= xFalse
;
1547 sharedPixmaps
= xTrue
;
1548 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
1549 ShmScrPrivateRec
*screen_priv
=
1550 ShmInitScreenPriv(screenInfo
.screens
[i
]);
1551 if (!screen_priv
->shmFuncs
)
1552 screen_priv
->shmFuncs
= &miFuncs
;
1553 if (!screen_priv
->shmFuncs
->CreatePixmap
)
1554 sharedPixmaps
= xFalse
;
1557 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
1558 ShmScrPrivateRec
*screen_priv
=
1559 ShmGetScreenPriv(screenInfo
.screens
[i
]);
1560 screen_priv
->destroyPixmap
=
1561 screenInfo
.screens
[i
]->DestroyPixmap
;
1562 screenInfo
.screens
[i
]->DestroyPixmap
= ShmDestroyPixmap
;
1565 ShmSegType
= CreateNewResourceType(ShmDetachSegment
, "ShmSeg");
1567 (extEntry
= AddExtension(SHMNAME
, ShmNumberEvents
, ShmNumberErrors
,
1568 ProcShmDispatch
, SProcShmDispatch
,
1569 ShmResetProc
, StandardMinorOpcode
))) {
1570 ShmReqCode
= (unsigned char) extEntry
->base
;
1571 ShmCompletionCode
= extEntry
->eventBase
;
1572 BadShmSegCode
= extEntry
->errorBase
;
1573 SetResourceTypeErrorValue(ShmSegType
, BadShmSegCode
);
1574 EventSwapVector
[ShmCompletionCode
] = (EventSwapPtr
) SShmCompletionEvent
;