1 /************************************************************
3 Copyright (c) 1989 X Consortium
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of the X Consortium shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from the X Consortium.
26 ********************************************************/
28 /* THIS IS NOT AN X CONSORTIUM STANDARD */
30 /* $XConsortium: shm.c,v 1.25 95/04/06 16:00:55 dpw Exp $ */
31 /* $XFree86: xc/programs/Xserver/Xext/shm.c,v 3.8 1997/01/18 06:52:59 dawes Exp $ */
33 #include <sys/types.h>
47 #include "dixstruct.h"
49 #include "scrnintstr.h"
50 #include "windowstr.h"
51 #include "pixmapstr.h"
53 #include "extnsionst.h"
57 #include "Xfuncproto.h"
59 typedef struct _ShmDesc {
60 struct _ShmDesc *next;
66 } ShmDescRec, *ShmDescPtr;
68 static void miShmPutImage(XSHM_PUT_IMAGE_ARGS);
69 static void fbShmPutImage(XSHM_PUT_IMAGE_ARGS);
70 static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
71 static int ShmDetachSegment(
72 #if NeedFunctionPrototypes
77 static void ShmResetProc(
78 #if NeedFunctionPrototypes
79 ExtensionEntry * /* extEntry */
82 static void SShmCompletionEvent(
83 #if NeedFunctionPrototypes
84 xShmCompletionEvent * /* from */,
85 xShmCompletionEvent * /* to */
89 static DISPATCH_PROC(ProcShmAttach);
90 static DISPATCH_PROC(ProcShmCreatePixmap);
91 static DISPATCH_PROC(ProcShmDetach);
92 static DISPATCH_PROC(ProcShmDispatch);
93 static DISPATCH_PROC(ProcShmGetImage);
94 static DISPATCH_PROC(ProcShmGetImage);
95 static DISPATCH_PROC(ProcShmGetImage);
96 static DISPATCH_PROC(ProcShmPutImage);
97 static DISPATCH_PROC(ProcShmQueryVersion);
98 static DISPATCH_PROC(SProcShmAttach);
99 static DISPATCH_PROC(SProcShmCreatePixmap);
100 static DISPATCH_PROC(SProcShmDetach);
101 static DISPATCH_PROC(SProcShmDispatch);
102 static DISPATCH_PROC(SProcShmGetImage);
103 static DISPATCH_PROC(SProcShmPutImage);
104 static DISPATCH_PROC(SProcShmQueryVersion);
106 static unsigned char ShmReqCode;
107 static int ShmCompletionCode;
108 static int BadShmSegCode;
109 static RESTYPE ShmSegType, ShmPixType;
110 static ShmDescPtr Shmsegs;
111 static Bool sharedPixmaps;
112 static int pixmapFormat;
113 static int shmPixFormat[MAXSCREENS];
114 static ShmFuncsPtr shmFuncs[MAXSCREENS];
115 static ShmFuncs miFuncs = {NULL, miShmPutImage};
116 static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
118 #define VERIFY_SHMSEG(shmseg,shmdesc,client) \
120 shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
123 client->errorValue = shmseg; \
124 return BadShmSegCode; \
128 #define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
130 VERIFY_SHMSEG(shmseg, shmdesc, client); \
131 if ((offset & 3) || (offset > shmdesc->size)) \
133 client->errorValue = offset; \
136 if (needwrite && !shmdesc->writable) \
140 #define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
142 if ((offset + len) > shmdesc->size) \
149 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
150 #include <sys/signal.h>
152 static Bool badSysCall = FALSE;
161 static Bool CheckForShmSyscall()
163 void (*oldHandler)();
166 /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
167 oldHandler = signal(SIGSYS, SigSysHandler);
170 shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
174 shmctl(shmid, IPC_RMID, (struct shmid_ds *)NULL);
176 signal(SIGSYS, oldHandler);
184 ExtensionEntry *extEntry;
187 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
188 if (!CheckForShmSyscall())
190 ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
195 #ifdef INTERNAL_VS_EXTERNAL_PADDING
196 sharedPixmaps = xFalse;
199 sharedPixmaps = xTrue;
200 pixmapFormat = shmPixFormat[0];
201 for (i = 0; i < screenInfo.numScreens; i++)
204 shmFuncs[i] = &miFuncs;
205 if (!shmFuncs[i]->CreatePixmap)
206 sharedPixmaps = xFalse;
207 if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
209 sharedPixmaps = xFalse;
214 pixmapFormat = ZPixmap;
216 ShmSegType = CreateNewResourceType(ShmDetachSegment);
217 ShmPixType = CreateNewResourceType(ShmDetachSegment);
218 if (ShmSegType && ShmPixType &&
219 (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
220 ProcShmDispatch, SProcShmDispatch,
221 ShmResetProc, StandardMinorOpcode)))
223 ShmReqCode = (unsigned char)extEntry->base;
224 ShmCompletionCode = extEntry->eventBase;
225 BadShmSegCode = extEntry->errorBase;
226 EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
232 ShmResetProc (extEntry)
233 ExtensionEntry *extEntry;
237 for (i = 0; i < MAXSCREENS; i++)
239 shmFuncs[i] = (ShmFuncsPtr)NULL;
245 ShmRegisterFuncs(pScreen, funcs)
249 shmFuncs[pScreen->myNum] = funcs;
253 ShmSetPixmapFormat(pScreen, format)
257 shmPixFormat[pScreen->myNum] = format;
261 ShmRegisterFbFuncs(pScreen)
264 shmFuncs[pScreen->myNum] = &fbFuncs;
268 ProcShmQueryVersion(client)
269 register ClientPtr client;
271 xShmQueryVersionReply rep;
274 REQUEST_SIZE_MATCH(xShmQueryVersionReq);
277 rep.sequenceNumber = client->sequence;
278 rep.sharedPixmaps = sharedPixmaps;
279 rep.pixmapFormat = pixmapFormat;
280 rep.majorVersion = SHM_MAJOR_VERSION;
281 rep.minorVersion = SHM_MINOR_VERSION;
284 if (client->swapped) {
285 swaps(&rep.sequenceNumber, n);
286 swapl(&rep.length, n);
287 swaps(&rep.majorVersion, n);
288 swaps(&rep.minorVersion, n);
292 WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
293 return (client->noClientException);
297 ProcShmAttach(client)
298 register ClientPtr client;
302 REQUEST(xShmAttachReq);
304 REQUEST_SIZE_MATCH(xShmAttachReq);
305 LEGAL_NEW_RESOURCE(stuff->shmseg, client);
306 if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
308 client->errorValue = stuff->readOnly;
311 for (shmdesc = Shmsegs;
312 shmdesc && (shmdesc->shmid != stuff->shmid);
313 shmdesc = shmdesc->next)
317 if (!stuff->readOnly && !shmdesc->writable)
323 shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
326 shmdesc->addr = shmat(stuff->shmid, 0,
327 stuff->readOnly ? SHM_RDONLY : 0);
328 if ((shmdesc->addr == ((char *)-1)) ||
329 shmctl(stuff->shmid, IPC_STAT, &buf))
334 shmdesc->shmid = stuff->shmid;
336 shmdesc->writable = !stuff->readOnly;
337 shmdesc->size = buf.shm_segsz;
338 shmdesc->next = Shmsegs;
341 if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
343 return(client->noClientException);
348 ShmDetachSegment(value, shmseg)
349 pointer value; /* must conform to DeleteType */
352 ShmDescPtr shmdesc = (ShmDescPtr)value;
355 if (--shmdesc->refcnt)
357 shmdt(shmdesc->addr);
358 for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
360 *prev = shmdesc->next;
366 ProcShmDetach(client)
367 register ClientPtr client;
370 REQUEST(xShmDetachReq);
372 REQUEST_SIZE_MATCH(xShmDetachReq);
373 VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
374 FreeResource(stuff->shmseg, RT_NONE);
375 return(client->noClientException);
379 miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
382 int depth, w, h, sx, sy, sw, sh, dx, dy;
389 putGC = GetScratchGC(depth, dst->pScreen);
392 pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
395 FreeScratchGC(putGC);
398 ValidateGC((DrawablePtr)pmap, putGC);
399 (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
400 (format == XYPixmap) ? XYPixmap : ZPixmap, data);
401 FreeScratchGC(putGC);
402 if (format == XYBitmap)
403 (void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
406 (void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
408 (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
412 fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
415 int depth, w, h, sx, sy, sw, sh, dx, dy;
419 if ((format == ZPixmap) || (depth == 1))
423 pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
424 /*XXX*/depth, PixmapBytePad(w, depth), (pointer)data);
427 if (format == XYBitmap)
428 (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
429 sx, sy, sw, sh, dx, dy, 1L);
431 (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
432 sx, sy, sw, sh, dx, dy);
433 FreeScratchPixmapHeader(pPixmap);
436 miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
441 ProcShmPutImage(client)
442 register ClientPtr client;
445 register DrawablePtr pDraw;
447 #ifdef INTERNAL_VS_EXTERNAL_PADDING
453 REQUEST(xShmPutImageReq);
455 REQUEST_SIZE_MATCH(xShmPutImageReq);
456 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
457 VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
458 if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
460 if (stuff->format == XYBitmap)
462 if (stuff->depth != 1)
464 length = PixmapBytePad(stuff->totalWidth, 1);
465 #ifdef INTERNAL_VS_EXTERNAL_PADDING
466 lengthProto = PixmapBytePadProto(stuff->totalWidth, 1);
469 else if (stuff->format == XYPixmap)
471 if (pDraw->depth != stuff->depth)
473 length = PixmapBytePad(stuff->totalWidth, 1);
474 length *= stuff->depth;
475 #ifdef INTERNAL_VS_EXTERNAL_PADDING
476 lengthProto = PixmapBytePadProto(stuff->totalWidth, 1);
477 lengthProto *= stuff->depth;
480 else if (stuff->format == ZPixmap)
482 if (pDraw->depth != stuff->depth)
484 length = PixmapBytePad(stuff->totalWidth, stuff->depth);
485 #ifdef INTERNAL_VS_EXTERNAL_PADDING
486 lengthProto = PixmapBytePadProto(stuff->totalWidth, stuff->depth);
491 client->errorValue = stuff->format;
495 #ifdef INTERNAL_VS_EXTERNAL_PADDING
496 VERIFY_SHMSIZE(shmdesc, stuff->offset, lengthProto * stuff->totalHeight,
499 VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
502 if (stuff->srcX > stuff->totalWidth)
504 client->errorValue = stuff->srcX;
507 if (stuff->srcY > stuff->totalHeight)
509 client->errorValue = stuff->srcY;
512 if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
514 client->errorValue = stuff->srcWidth;
517 if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
519 client->errorValue = stuff->srcHeight;
523 #ifdef INTERNAL_VS_EXTERNAL_PADDING
524 /* handle 64 bit case where protocol may pad to 32 and we want 64
525 * In this case, length is what the server wants and lengthProto is
526 * what the protocol thinks it is. If the the two are different,
527 * copy the protocol version (i.e. the memory shared between the
528 * server and the client) to a version with a scanline pad of 64.
530 if (length != lengthProto)
533 char * stuffptr, /* pointer into protocol data */
534 * tmpptr; /* new location to copy to */
536 if(!(tmpImage = (char *) ALLOCATE_LOCAL(length*stuff->totalHeight)))
540 bzero(tmpImage,length*stuff->totalHeight);
542 if (stuff->format == XYPixmap)
544 int lineBytes = PixmapBytePad(stuff->totalWidth, 1);
545 int lineBytesProto = PixmapBytePadProto(stuff->totalWidth, 1);
546 int depth = stuff->depth;
548 stuffptr = shmdesc->addr + stuff->offset ;
550 for (i = 0; i < stuff->totalHeight*stuff->depth;
551 stuffptr += lineBytesProto,tmpptr += lineBytes, i++)
552 bcopy(stuffptr,tmpptr,lineBytesProto);
557 stuffptr = shmdesc->addr + stuff->offset,
559 i < stuff->totalHeight;
560 stuffptr += lengthProto,tmpptr += length, i++)
561 bcopy(stuffptr,tmpptr,lengthProto);
564 /* handle 64-bit case where stuff is not 64-bit aligned
566 else if ((unsigned long)(shmdesc->addr+stuff->offset) &
569 if(!(tmpImage = (char *) ALLOCATE_LOCAL(length*stuff->totalHeight)))
572 bcopy((char *)(shmdesc->addr+stuff->offset),
574 length*stuff->totalHeight);
577 tmpImage = (char *)(shmdesc->addr+stuff->offset);
580 if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
581 ((stuff->format != ZPixmap) &&
582 (stuff->srcX < screenInfo.bitmapScanlinePad) &&
583 ((stuff->format == XYBitmap) ||
584 ((stuff->srcY == 0) &&
585 (stuff->srcHeight == stuff->totalHeight))))) &&
586 ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
587 (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
588 stuff->dstX, stuff->dstY,
589 stuff->totalWidth, stuff->srcHeight,
590 stuff->srcX, stuff->format,
591 #ifdef INTERNAL_VS_EXTERNAL_PADDING
594 shmdesc->addr + stuff->offset +
596 (stuff->srcY * length));
598 (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
599 pDraw, pGC, stuff->depth, stuff->format,
600 stuff->totalWidth, stuff->totalHeight,
601 stuff->srcX, stuff->srcY,
602 stuff->srcWidth, stuff->srcHeight,
603 stuff->dstX, stuff->dstY,
604 #ifdef INTERNAL_VS_EXTERNAL_PADDING
608 shmdesc->addr + stuff->offset);
611 if (stuff->sendEvent)
613 xShmCompletionEvent ev;
615 ev.type = ShmCompletionCode;
616 ev.drawable = stuff->drawable;
617 ev.sequenceNumber = client->sequence;
618 ev.minorEvent = X_ShmPutImage;
619 ev.majorEvent = ShmReqCode;
620 ev.shmseg = stuff->shmseg;
621 ev.offset = stuff->offset;
622 WriteEventsToClient(client, 1, (xEvent *) &ev);
625 #ifdef INTERNAL_VS_EXTERNAL_PADDING
627 DEALLOCATE_LOCAL(tmpImage);
630 return (client->noClientException);
636 ProcShmGetImage(client)
637 register ClientPtr client;
639 register DrawablePtr pDraw;
642 xShmGetImageReply xgi;
645 #ifdef INTERNAL_VS_EXTERNAL_PADDING
646 long widthBytesLine,widthBytesLineProto;
647 long lenPerProto,lengthProto;
652 REQUEST(xShmGetImageReq);
654 REQUEST_SIZE_MATCH(xShmGetImageReq);
655 if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
657 client->errorValue = stuff->format;
660 VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
661 VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
662 if (pDraw->type == DRAWABLE_WINDOW)
664 if( /* check for being viewable */
665 !((WindowPtr) pDraw)->realized ||
666 /* check for being on screen */
667 pDraw->x + stuff->x < 0 ||
668 pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
669 pDraw->y + stuff->y < 0 ||
670 pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
671 /* check for being inside of border */
672 stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
673 stuff->x + (int)stuff->width >
674 wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
675 stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
676 stuff->y + (int)stuff->height >
677 wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
680 xgi.visual = wVisual(((WindowPtr)pDraw));
685 stuff->x+(int)stuff->width > pDraw->width ||
687 stuff->y+(int)stuff->height > pDraw->height
694 xgi.sequenceNumber = client->sequence;
695 xgi.depth = pDraw->depth;
696 if(stuff->format == ZPixmap)
698 #ifdef INTERNAL_VS_EXTERNAL_PADDING
699 widthBytesLine = PixmapBytePad(stuff->width, pDraw->depth);
700 length = widthBytesLine * stuff->height;
701 widthBytesLineProto = PixmapBytePadProto(stuff->width, pDraw->depth);
702 lengthProto = widthBytesLineProto * stuff->height;
704 length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
709 #ifdef INTERNAL_VS_EXTERNAL_PADDING
710 widthBytesLine = PixmapBytePad(stuff->width, 1);
711 lenPer = widthBytesLine * stuff->height;
712 plane = ((Mask)1) << (pDraw->depth - 1);
713 /* only planes asked for */
714 length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
716 widthBytesLineProto = PixmapBytePadProto(stuff->width, 1);
717 lenPerProto = widthBytesLineProto * stuff->height;
718 lengthProto = lenPerProto * Ones(stuff->planeMask &
719 (plane | (plane - 1)));
721 lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
722 plane = ((Mask)1) << (pDraw->depth - 1);
723 /* only planes asked for */
724 length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
728 #ifdef INTERNAL_VS_EXTERNAL_PADDING
729 VERIFY_SHMSIZE(shmdesc, stuff->offset, lengthProto, client);
730 xgi.size = lengthProto;
732 VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
740 else if (stuff->format == ZPixmap)
742 #ifdef INTERNAL_VS_EXTERNAL_PADDING
743 /* check for protocol/server padding differences.
745 if ((widthBytesLine != widthBytesLineProto) ||
746 ((unsigned long)shmdesc->addr + stuff->offset & (sizeof(long)-1)))
748 /* temp stuff for 64 bit alignment stuff */
749 register char * bufPtr, * protoPtr;
752 if(!(tmpImage = (char *) ALLOCATE_LOCAL(length)))
756 (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
757 stuff->width, stuff->height,
758 stuff->format, stuff->planeMask,
761 /* for 64-bit server, convert image to pad to 32 bits
763 bzero(shmdesc->addr + stuff->offset,lengthProto);
765 for (i=0,bufPtr=tmpImage,protoPtr=shmdesc->addr + stuff->offset;
767 bufPtr += widthBytesLine,protoPtr += widthBytesLineProto,
769 bcopy(bufPtr,protoPtr,widthBytesLineProto);
773 (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
774 stuff->width, stuff->height,
775 stuff->format, stuff->planeMask,
776 shmdesc->addr + stuff->offset);
779 (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
780 stuff->width, stuff->height,
781 stuff->format, stuff->planeMask,
782 shmdesc->addr + stuff->offset);
787 #ifdef INTERNAL_VS_EXTERNAL_PADDING
788 /* check for protocol/server padding differences.
790 if ((widthBytesLine != widthBytesLineProto) ||
791 ((unsigned long)shmdesc->addr + stuff->offset &
794 if(!(tmpImage = (char *) ALLOCATE_LOCAL(length)))
800 length = stuff->offset;
801 for (; plane; plane >>= 1)
803 if (stuff->planeMask & plane)
805 #ifdef INTERNAL_VS_EXTERNAL_PADDING
806 if ((widthBytesLine != widthBytesLineProto) ||
807 ((unsigned long)shmdesc->addr + stuff->offset &
810 /* get image for each plane.
812 (*pDraw->pScreen->GetImage)(pDraw,
814 stuff->width, stuff->height,
815 stuff->format, plane,
818 /* for 64-bit server, convert image to pad to 32 bits */
819 bzero(shmdesc->addr+length, widthBytesLine);
820 bcopy(tmpImage, shmdesc->addr+length, widthBytesLineProto);
821 /* increment length */
822 length += lenPerProto;
824 else /* no diff between protocol and server */
826 (*pDraw->pScreen->GetImage)(pDraw,
828 stuff->width, stuff->height,
829 stuff->format, plane,
830 shmdesc->addr + length);
834 (*pDraw->pScreen->GetImage)(pDraw,
836 stuff->width, stuff->height,
837 stuff->format, plane,
838 shmdesc->addr + length);
845 if (client->swapped) {
846 swaps(&xgi.sequenceNumber, n);
847 swapl(&xgi.length, n);
848 swapl(&xgi.visual, n);
851 WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
853 #ifdef INTERNAL_VS_EXTERNAL_PADDING
855 DEALLOCATE_LOCAL(tmpImage);
858 return(client->noClientException);
862 fbShmCreatePixmap (pScreen, width, height, depth, addr)
869 register PixmapPtr pPixmap;
871 pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
875 if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
876 /*XXX*/depth, PixmapBytePad(width, depth), (pointer)addr))
882 ProcShmCreatePixmap(client)
883 register ClientPtr client;
886 register DrawablePtr pDraw;
890 REQUEST(xShmCreatePixmapReq);
892 REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
893 client->errorValue = stuff->pid;
895 return BadImplementation;
896 LEGAL_NEW_RESOURCE(stuff->pid, client);
897 VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
898 VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
899 if (!stuff->width || !stuff->height)
901 client->errorValue = 0;
904 if (stuff->depth != 1)
906 pDepth = pDraw->pScreen->allowedDepths;
907 for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
908 if (pDepth->depth == stuff->depth)
910 client->errorValue = stuff->depth;
914 VERIFY_SHMSIZE(shmdesc, stuff->offset,
915 PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
917 pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
918 pDraw->pScreen, stuff->width,
919 stuff->height, stuff->depth,
920 shmdesc->addr + stuff->offset);
923 pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
924 pMap->drawable.id = stuff->pid;
925 if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
928 if (AddResource(stuff->pid, ShmPixType, (pointer)shmdesc))
929 return(client->noClientException);
930 FreeResource(stuff->pid, RT_NONE);
937 ProcShmDispatch (client)
938 register ClientPtr client;
943 case X_ShmQueryVersion:
944 return ProcShmQueryVersion(client);
946 return ProcShmAttach(client);
948 return ProcShmDetach(client);
950 return ProcShmPutImage(client);
952 return ProcShmGetImage(client);
953 case X_ShmCreatePixmap:
954 return ProcShmCreatePixmap(client);
961 SShmCompletionEvent(from, to)
962 xShmCompletionEvent *from, *to;
964 to->type = from->type;
965 cpswaps(from->sequenceNumber, to->sequenceNumber);
966 cpswapl(from->drawable, to->drawable);
967 cpswaps(from->minorEvent, to->minorEvent);
968 to->majorEvent = from->majorEvent;
969 cpswapl(from->shmseg, to->shmseg);
970 cpswapl(from->offset, to->offset);
974 SProcShmQueryVersion(client)
975 register ClientPtr client;
978 REQUEST(xShmQueryVersionReq);
980 swaps(&stuff->length, n);
981 return ProcShmQueryVersion(client);
985 SProcShmAttach(client)
989 REQUEST(xShmAttachReq);
990 swaps(&stuff->length, n);
991 REQUEST_SIZE_MATCH(xShmAttachReq);
992 swapl(&stuff->shmseg, n);
993 swapl(&stuff->shmid, n);
994 return ProcShmAttach(client);
998 SProcShmDetach(client)
1002 REQUEST(xShmDetachReq);
1003 swaps(&stuff->length, n);
1004 REQUEST_SIZE_MATCH(xShmDetachReq);
1005 swapl(&stuff->shmseg, n);
1006 return ProcShmDetach(client);
1010 SProcShmPutImage(client)
1014 REQUEST(xShmPutImageReq);
1015 swaps(&stuff->length, n);
1016 REQUEST_SIZE_MATCH(xShmPutImageReq);
1017 swapl(&stuff->drawable, n);
1018 swapl(&stuff->gc, n);
1019 swaps(&stuff->totalWidth, n);
1020 swaps(&stuff->totalHeight, n);
1021 swaps(&stuff->srcX, n);
1022 swaps(&stuff->srcY, n);
1023 swaps(&stuff->srcWidth, n);
1024 swaps(&stuff->srcHeight, n);
1025 swaps(&stuff->dstX, n);
1026 swaps(&stuff->dstY, n);
1027 swapl(&stuff->shmseg, n);
1028 swapl(&stuff->offset, n);
1029 return ProcShmPutImage(client);
1033 SProcShmGetImage(client)
1037 REQUEST(xShmGetImageReq);
1038 swaps(&stuff->length, n);
1039 REQUEST_SIZE_MATCH(xShmGetImageReq);
1040 swapl(&stuff->drawable, n);
1041 swaps(&stuff->x, n);
1042 swaps(&stuff->y, n);
1043 swaps(&stuff->width, n);
1044 swaps(&stuff->height, n);
1045 swapl(&stuff->planeMask, n);
1046 swapl(&stuff->shmseg, n);
1047 swapl(&stuff->offset, n);
1048 return ProcShmGetImage(client);
1052 SProcShmCreatePixmap(client)
1056 REQUEST(xShmCreatePixmapReq);
1057 swaps(&stuff->length, n);
1058 REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
1059 swapl(&stuff->drawable, n);
1060 swaps(&stuff->width, n);
1061 swaps(&stuff->height, n);
1062 swapl(&stuff->shmseg, n);
1063 swapl(&stuff->offset, n);
1064 return ProcShmCreatePixmap(client);
1068 SProcShmDispatch (client)
1069 register ClientPtr client;
1072 switch (stuff->data)
1074 case X_ShmQueryVersion:
1075 return SProcShmQueryVersion(client);
1077 return SProcShmAttach(client);
1079 return SProcShmDetach(client);
1081 return SProcShmPutImage(client);
1083 return SProcShmGetImage(client);
1084 case X_ShmCreatePixmap:
1085 return SProcShmCreatePixmap(client);