home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / extensions / server / shm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-11  |  20.7 KB  |  805 lines

  1. /************************************************************
  2. Copyright 1989 by The Massachusetts Institute of Technology
  3.  
  4. Permission to use, copy, modify, and distribute this
  5. software and its documentation for any purpose and without
  6. fee is hereby granted, provided that the above copyright
  7. no- tice appear in all copies and that both that copyright
  8. no- tice and this permission notice appear in supporting
  9. docu- mentation, and that the name of MIT not be used in
  10. advertising or publicity pertaining to distribution of the
  11. software without specific prior written permission.
  12. M.I.T. makes no representation about the suitability of
  13. this software for any purpose. It is provided "as is"
  14. without any express or implied warranty.
  15.  
  16. ********************************************************/
  17.  
  18. /* THIS IS NOT AN X CONSORTIUM STANDARD */
  19.  
  20. /* $XConsortium: shm.c,v 1.11 91/07/12 09:54:58 rws Exp $ */
  21.  
  22. #include <sys/types.h>
  23. #include <sys/ipc.h>
  24. #include <sys/shm.h>
  25. #define NEED_REPLIES
  26. #define NEED_EVENTS
  27. #include "X.h"
  28. #include "Xproto.h"
  29. #include "misc.h"
  30. #include "os.h"
  31. #include "dixstruct.h"
  32. #include "resource.h"
  33. #include "scrnintstr.h"
  34. #include "windowstr.h"
  35. #include "pixmapstr.h"
  36. #include "gcstruct.h"
  37. #include "extnsionst.h"
  38. #include "servermd.h"
  39. #define _XSHM_SERVER_
  40. #include "shmstr.h"
  41. #include "Xfuncproto.h"
  42.  
  43. typedef struct _ShmDesc {
  44.     struct _ShmDesc *next;
  45.     int shmid;
  46.     int refcnt;
  47.     char *addr;
  48.     Bool writable;
  49.     unsigned long size;
  50. } ShmDescRec, *ShmDescPtr;
  51.  
  52. #if NeedFunctionPrototypes && !defined(ultrix)
  53. void *shmat(int, void*, int);
  54. #else
  55. char *shmat();
  56. #endif
  57. static void miShmPutImage(), fbShmPutImage();
  58. static PixmapPtr fbShmCreatePixmap();
  59. ExtensionEntry *AddExtension();
  60. static int ProcShmDispatch(), SProcShmDispatch();
  61. static int ShmDetachSegment();
  62. static void ShmResetProc(), SShmCompletionEvent();
  63.  
  64. static unsigned char ShmReqCode;
  65. static int ShmCompletionCode;
  66. static int BadShmSegCode;
  67. static RESTYPE ShmSegType, ShmPixType;
  68. static ShmDescPtr Shmsegs;
  69. static Bool sharedPixmaps;
  70. static int pixmapFormat;
  71. static int shmPixFormat[MAXSCREENS];
  72. static ShmFuncsPtr shmFuncs[MAXSCREENS];
  73. static ShmFuncs miFuncs = {NULL, miShmPutImage};
  74. static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
  75.  
  76. #define VERIFY_SHMSEG(shmseg,shmdesc,client) \
  77. { \
  78.     shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
  79.     if (!shmdesc) \
  80.     { \
  81.     client->errorValue = shmseg; \
  82.     return BadShmSegCode; \
  83.     } \
  84. }
  85.  
  86. #define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
  87. { \
  88.     VERIFY_SHMSEG(shmseg, shmdesc, client); \
  89.     if ((offset & 3) || (offset > shmdesc->size)) \
  90.     { \
  91.     client->errorValue = offset; \
  92.     return BadValue; \
  93.     } \
  94.     if (needwrite && !shmdesc->writable) \
  95.     return BadAccess; \
  96. }
  97.  
  98. #define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
  99. { \
  100.     if ((offset + len) > shmdesc->size) \
  101.     { \
  102.     return BadAccess; \
  103.     } \
  104. }
  105.  
  106. void
  107. ShmExtensionInit()
  108. {
  109.     ExtensionEntry *extEntry;
  110.     int i;
  111.  
  112.     sharedPixmaps = xTrue;
  113.     pixmapFormat = shmPixFormat[0];
  114.     for (i = 0; i < screenInfo.numScreens; i++)
  115.     {
  116.     if (!shmFuncs[i])
  117.         shmFuncs[i] = &miFuncs;
  118.     if (!shmFuncs[i]->CreatePixmap)
  119.         sharedPixmaps = xFalse;
  120.     if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
  121.     {
  122.         sharedPixmaps = xFalse;
  123.         pixmapFormat = 0;
  124.     }
  125.     }
  126.     if (!pixmapFormat)
  127.     pixmapFormat = ZPixmap;
  128.     ShmSegType = CreateNewResourceType(ShmDetachSegment);
  129.     ShmPixType = CreateNewResourceType(ShmDetachSegment);
  130.     if (ShmSegType && ShmPixType &&
  131.     (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
  132.                  ProcShmDispatch, SProcShmDispatch,
  133.                  ShmResetProc, StandardMinorOpcode)))
  134.     {
  135.     ShmReqCode = (unsigned char)extEntry->base;
  136.     ShmCompletionCode = extEntry->eventBase;
  137.     BadShmSegCode = extEntry->errorBase;
  138.     EventSwapVector[ShmCompletionCode] = SShmCompletionEvent;
  139.     }
  140. }
  141.  
  142. /*ARGSUSED*/
  143. static void
  144. ShmResetProc (extEntry)
  145. ExtensionEntry    *extEntry;
  146. {
  147.     int i;
  148.  
  149.     for (i = 0; i < MAXSCREENS; i++)
  150.     {
  151.     shmFuncs[i] = (ShmFuncsPtr)NULL;
  152.     shmPixFormat[i] = 0;
  153.     }
  154. }
  155.  
  156. void
  157. ShmRegisterFuncs(pScreen, funcs)
  158.     ScreenPtr pScreen;
  159.     ShmFuncsPtr funcs;
  160. {
  161.     shmFuncs[pScreen->myNum] = funcs;
  162. }
  163.  
  164. void
  165. ShmSetPixmapFormat(pScreen, format)
  166.     ScreenPtr pScreen;
  167.     int format;
  168. {
  169.     shmPixFormat[pScreen->myNum] = format;
  170. }
  171.  
  172. void
  173. ShmRegisterFbFuncs(pScreen)
  174.     ScreenPtr pScreen;
  175. {
  176.     shmFuncs[pScreen->myNum] = &fbFuncs;
  177. }
  178.  
  179. static int
  180. ProcShmQueryVersion(client)
  181.     register ClientPtr client;
  182. {
  183.     REQUEST(xShmQueryVersionReq);
  184.     xShmQueryVersionReply rep;
  185.     register int n;
  186.  
  187.     REQUEST_SIZE_MATCH(xShmQueryVersionReq);
  188.     rep.type = X_Reply;
  189.     rep.length = 0;
  190.     rep.sequenceNumber = client->sequence;
  191.     rep.sharedPixmaps = sharedPixmaps;
  192.     rep.majorVersion = SHM_MAJOR_VERSION;
  193.     rep.minorVersion = SHM_MINOR_VERSION;
  194.     rep.uid = geteuid();
  195.     rep.gid = getegid();
  196.     if (client->swapped) {
  197.         swaps(&rep.sequenceNumber, n);
  198.         swapl(&rep.length, n);
  199.     swaps(&rep.majorVersion, n);
  200.     swaps(&rep.minorVersion, n);
  201.     swaps(&rep.uid, n);
  202.     swaps(&rep.gid, n);
  203.     }
  204.     WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
  205.     return (client->noClientException);
  206. }
  207.  
  208. static int
  209. ProcShmAttach(client)
  210.     register ClientPtr client;
  211. {
  212.     struct shmid_ds buf;
  213.     ShmDescPtr shmdesc;
  214.     REQUEST(xShmAttachReq);
  215.  
  216.     REQUEST_SIZE_MATCH(xShmAttachReq);
  217.     LEGAL_NEW_RESOURCE(stuff->shmseg, client);
  218.     if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
  219.     {
  220.     client->errorValue = stuff->readOnly;
  221.         return(BadValue);
  222.     }
  223.     for (shmdesc = Shmsegs;
  224.      shmdesc && (shmdesc->shmid != stuff->shmid);
  225.      shmdesc = shmdesc->next)
  226.     ;
  227.     if (shmdesc)
  228.     {
  229.     if (!stuff->readOnly && !shmdesc->writable)
  230.         return BadAccess;
  231.     shmdesc->refcnt++;
  232.     }
  233.     else
  234.     {
  235.     shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
  236.     if (!shmdesc)
  237.         return BadAlloc;
  238.     shmdesc->addr = shmat(stuff->shmid, 0,
  239.                   stuff->readOnly ? SHM_RDONLY : 0);
  240.     if ((shmdesc->addr == ((char *)-1)) ||
  241.         shmctl(stuff->shmid, IPC_STAT, &buf))
  242.     {
  243.         xfree(shmdesc);
  244.         return BadAccess;
  245.     }
  246.     shmdesc->shmid = stuff->shmid;
  247.     shmdesc->refcnt = 1;
  248.     shmdesc->writable = !stuff->readOnly;
  249.     shmdesc->size = buf.shm_segsz;
  250.     shmdesc->next = Shmsegs;
  251.     Shmsegs = shmdesc;
  252.     }
  253.     if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
  254.     return BadAlloc;
  255.     return(client->noClientException);
  256. }
  257.  
  258. /*ARGSUSED*/
  259. static int
  260. ShmDetachSegment(shmdesc, shmseg)
  261.     ShmDescPtr shmdesc;
  262.     ShmSeg shmseg;
  263. {
  264.     ShmDescPtr *prev;
  265.  
  266.     if (--shmdesc->refcnt)
  267.     return TRUE;
  268.     shmdt(shmdesc->addr);
  269.     for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
  270.     ;
  271.     *prev = shmdesc->next;
  272.     xfree(shmdesc);
  273. }
  274.  
  275. static int
  276. ProcShmDetach(client)
  277.     register ClientPtr client;
  278. {
  279.     ShmDescPtr shmdesc;
  280.     REQUEST(xShmDetachReq);
  281.  
  282.     REQUEST_SIZE_MATCH(xShmDetachReq);
  283.     VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
  284.     FreeResource(stuff->shmseg, RT_NONE);
  285.     return(client->noClientException);
  286. }
  287.  
  288. static void
  289. miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
  290.     DrawablePtr dst;
  291.     GCPtr    pGC;
  292.     int        depth, w, h, sx, sy, sw, sh, dx, dy;
  293.     unsigned int format;
  294.     char     *data;
  295. {
  296.     PixmapPtr pmap;
  297.     GCPtr putGC;
  298.  
  299.     putGC = GetScratchGC(depth, dst->pScreen);
  300.     if (!putGC)
  301.     return;
  302.     pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
  303.     if (!pmap)
  304.     {
  305.     FreeScratchGC(putGC);
  306.     return;
  307.     }
  308.     ValidateGC((DrawablePtr)pmap, putGC);
  309.     (*putGC->ops->PutImage)(pmap, putGC, depth, -sx, -sy, w, h, 0,
  310.                 (format == XYPixmap) ? XYPixmap : ZPixmap, data);
  311.     FreeScratchGC(putGC);
  312.     if (format == XYBitmap)
  313.     (void)(*pGC->ops->CopyPlane)(pmap, dst, pGC, 0, 0, sw, sh, dx, dy, 1L);
  314.     else
  315.     (void)(*pGC->ops->CopyArea)(pmap, dst, pGC, 0, 0, sw, sh, dx, dy);
  316.     (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
  317. }
  318.  
  319. static void
  320. fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
  321.     DrawablePtr dst;
  322.     GCPtr    pGC;
  323.     int        depth, w, h, sx, sy, sw, sh, dx, dy;
  324.     unsigned int format;
  325.     char     *data;
  326. {
  327.     if ((format == ZPixmap) || (depth == 1))
  328.     {
  329.     PixmapRec FakePixmap;
  330.         FakePixmap.drawable.type = DRAWABLE_PIXMAP;
  331.         FakePixmap.drawable.class = 0;
  332.         FakePixmap.drawable.pScreen = dst->pScreen;
  333.         FakePixmap.drawable.depth = depth;
  334.         FakePixmap.drawable.bitsPerPixel = depth;
  335.         FakePixmap.drawable.id = 0;
  336.         FakePixmap.drawable.serialNumber = NEXT_SERIAL_NUMBER;
  337.         FakePixmap.drawable.x = 0;
  338.         FakePixmap.drawable.y = 0;
  339.         FakePixmap.drawable.width = w;
  340.         FakePixmap.drawable.height = h;
  341.         FakePixmap.devKind = PixmapBytePad(w, depth);
  342.         FakePixmap.refcnt = 1;
  343.         FakePixmap.devPrivate.ptr = (pointer)data;
  344.     if (format == XYBitmap)
  345.         (void)(*pGC->ops->CopyPlane)(&FakePixmap, dst, pGC,
  346.                      sx, sy, sw, sh, dx, dy, 1L);
  347.     else
  348.         (void)(*pGC->ops->CopyArea)(&FakePixmap, dst, pGC,
  349.                     sx, sy, sw, sh, dx, dy);
  350.     }
  351.     else
  352.     miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
  353.               data);
  354. }
  355.  
  356. static int
  357. ProcShmPutImage(client)
  358.     register ClientPtr client;
  359. {
  360.     register GCPtr pGC;
  361.     register DrawablePtr pDraw;
  362.     long length;
  363.     ShmDescPtr shmdesc;
  364.     REQUEST(xShmPutImageReq);
  365.  
  366.     REQUEST_SIZE_MATCH(xShmPutImageReq);
  367.     VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
  368.     VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
  369.     if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
  370.     return BadValue;
  371.     if (stuff->format == XYBitmap)
  372.     {
  373.         if (stuff->depth != 1)
  374.             return BadMatch;
  375.         length = PixmapBytePad(stuff->totalWidth, 1);
  376.     }
  377.     else if (stuff->format == XYPixmap)
  378.     {
  379.         if (pDraw->depth != stuff->depth)
  380.             return BadMatch;
  381.         length = PixmapBytePad(stuff->totalWidth, 1);
  382.     length *= stuff->depth;
  383.     }
  384.     else if (stuff->format == ZPixmap)
  385.     {
  386.         if (pDraw->depth != stuff->depth)
  387.             return BadMatch;
  388.         length = PixmapBytePad(stuff->totalWidth, stuff->depth);
  389.     }
  390.     else
  391.     {
  392.     client->errorValue = stuff->format;
  393.         return BadValue;
  394.     }
  395.     VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
  396.            client);
  397.     if (stuff->srcX > stuff->totalWidth)
  398.     {
  399.     client->errorValue = stuff->srcX;
  400.     return BadValue;
  401.     }
  402.     if (stuff->srcY > stuff->totalHeight)
  403.     {
  404.     client->errorValue = stuff->srcY;
  405.     return BadValue;
  406.     }
  407.     if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
  408.     {
  409.     client->errorValue = stuff->srcWidth;
  410.     return BadValue;
  411.     }
  412.     if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
  413.     {
  414.     client->errorValue = stuff->srcHeight;
  415.     return BadValue;
  416.     }
  417.     if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
  418.      ((stuff->format != ZPixmap) &&
  419.       (stuff->srcX < screenInfo.bitmapScanlinePad) &&
  420.       ((stuff->format == XYBitmap) ||
  421.        ((stuff->srcY == 0) &&
  422.         (stuff->srcHeight == stuff->totalHeight))))) &&
  423.     ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
  424.     (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
  425.                    stuff->dstX, stuff->dstY,
  426.                    stuff->totalWidth, stuff->srcHeight, 
  427.                    stuff->srcX, stuff->format, 
  428.                    shmdesc->addr + stuff->offset +
  429.                    (stuff->srcY * length));
  430.     else
  431.     (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
  432.                    pDraw, pGC, stuff->depth, stuff->format,
  433.                    stuff->totalWidth, stuff->totalHeight,
  434.                    stuff->srcX, stuff->srcY,
  435.                    stuff->srcWidth, stuff->srcHeight,
  436.                    stuff->dstX, stuff->dstY,
  437.                    shmdesc->addr + stuff->offset);
  438.     if (stuff->sendEvent)
  439.     {
  440.     xShmCompletionEvent ev;
  441.  
  442.     ev.type = ShmCompletionCode;
  443.     ev.drawable = stuff->drawable;
  444.     ev.sequenceNumber = client->sequence;
  445.     ev.minorEvent = X_ShmPutImage;
  446.     ev.majorEvent = ShmReqCode;
  447.     ev.shmseg = stuff->shmseg;
  448.     ev.offset = stuff->offset;
  449.     WriteEventsToClient(client, 1, (xEvent *) &ev);
  450.     }
  451.      return (client->noClientException);
  452. }
  453.  
  454. static int
  455. ProcShmGetImage(client)
  456.     register ClientPtr client;
  457. {
  458.     register DrawablePtr pDraw;
  459.     long        lenPer, length;
  460.     Mask        plane;
  461.     xShmGetImageReply    xgi;
  462.     ShmDescPtr        shmdesc;
  463.     int            n;
  464.     REQUEST(xShmGetImageReq);
  465.  
  466.     REQUEST_SIZE_MATCH(xShmGetImageReq);
  467.     if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
  468.     {
  469.     client->errorValue = stuff->format;
  470.         return(BadValue);
  471.     }
  472.     if (!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client)))
  473.     {
  474.     client->errorValue = stuff->drawable;
  475.     return (BadDrawable);
  476.     }
  477.     VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
  478.     if (pDraw->type == DRAWABLE_WINDOW)
  479.     {
  480.       if( /* check for being viewable */
  481.      !((WindowPtr) pDraw)->realized ||
  482.       /* check for being on screen */
  483.          pDraw->x + stuff->x < 0 ||
  484.       pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
  485.          pDraw->y + stuff->y < 0 ||
  486.          pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
  487.           /* check for being inside of border */
  488.          stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
  489.          stuff->x + (int)stuff->width >
  490.         wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
  491.          stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
  492.          stuff->y + (int)stuff->height >
  493.         wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
  494.         )
  495.         return(BadMatch);
  496.     xgi.visual = wVisual(((WindowPtr)pDraw));
  497.     }
  498.     else
  499.     {
  500.     if (stuff->x < 0 ||
  501.         stuff->x+(int)stuff->width > pDraw->width ||
  502.         stuff->y < 0 ||
  503.         stuff->y+(int)stuff->height > pDraw->height
  504.         )
  505.         return(BadMatch);
  506.     xgi.visual = None;
  507.     }
  508.     xgi.type = X_Reply;
  509.     xgi.length = 0;
  510.     xgi.sequenceNumber = client->sequence;
  511.     xgi.depth = pDraw->depth;
  512.     if(stuff->format == ZPixmap)
  513.     {
  514.     length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
  515.     }
  516.     else 
  517.     {
  518.     lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
  519.     plane = ((Mask)1) << (pDraw->depth - 1);
  520.     /* only planes asked for */
  521.     length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
  522.     }
  523.     VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
  524.     xgi.size = length;
  525.     if (length == 0)
  526.     {
  527.     /* nothing to do */
  528.     }
  529.     else if (stuff->format == ZPixmap)
  530.     {
  531.     (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
  532.                     stuff->width, stuff->height,
  533.                     stuff->format, stuff->planeMask,
  534.                     shmdesc->addr + stuff->offset);
  535.     }
  536.     else
  537.     {
  538.     length = stuff->offset;
  539.         for (; plane; plane >>= 1)
  540.     {
  541.         if (stuff->planeMask & plane)
  542.         {
  543.         (*pDraw->pScreen->GetImage)(pDraw,
  544.                         stuff->x, stuff->y,
  545.                         stuff->width, stuff->height,
  546.                         stuff->format, plane,
  547.                         shmdesc->addr + length);
  548.         length += lenPer;
  549.         }
  550.     }
  551.     }
  552.     if (client->swapped) {
  553.         swaps(&xgi.sequenceNumber, n);
  554.         swapl(&xgi.length, n);
  555.     swapl(&xgi.visual, n);
  556.     swapl(&xgi.size, n);
  557.     }
  558.     WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
  559.     return(client->noClientException);
  560. }
  561.  
  562. static PixmapPtr
  563. fbShmCreatePixmap (pScreen, width, height, depth, addr)
  564.     ScreenPtr    pScreen;
  565.     int        width;
  566.     int        height;
  567.     int        depth;
  568.     char    *addr;
  569. {
  570.     register PixmapPtr pPixmap;
  571.  
  572.     pPixmap = (PixmapPtr)xalloc(sizeof(PixmapRec));
  573.     if (!pPixmap)
  574.     return NullPixmap;
  575.     pPixmap->drawable.type = DRAWABLE_PIXMAP;
  576.     pPixmap->drawable.class = 0;
  577.     pPixmap->drawable.pScreen = pScreen;
  578.     pPixmap->drawable.depth = depth;
  579.     pPixmap->drawable.bitsPerPixel = depth;
  580.     pPixmap->drawable.id = 0;
  581.     pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  582.     pPixmap->drawable.x = 0;
  583.     pPixmap->drawable.y = 0;
  584.     pPixmap->drawable.width = width;
  585.     pPixmap->drawable.height = height;
  586.     pPixmap->devKind = PixmapBytePad(width, depth);
  587.     pPixmap->refcnt = 1;
  588.     pPixmap->devPrivate.ptr = (pointer)addr;
  589.     return pPixmap;
  590. }
  591.  
  592. static int
  593. ProcShmCreatePixmap(client)
  594.     register ClientPtr client;
  595. {
  596.     PixmapPtr pMap;
  597.     register DrawablePtr pDraw;
  598.     DepthPtr pDepth;
  599.     register int i;
  600.     ShmDescPtr shmdesc;
  601.     REQUEST(xShmCreatePixmapReq);
  602.  
  603.     REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
  604.     client->errorValue = stuff->pid;
  605.     if (!sharedPixmaps)
  606.     return BadImplementation;
  607.     LEGAL_NEW_RESOURCE(stuff->pid, client);
  608.     if (!(pDraw = LOOKUP_DRAWABLE(stuff->drawable, client)))
  609.     {        /* can be inputonly */
  610.         if (!(pDraw = (DrawablePtr)LookupWindow(stuff->drawable, client))) 
  611.             return (BadDrawable);
  612.     }
  613.     VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
  614.     if (!stuff->width || !stuff->height)
  615.     {
  616.     client->errorValue = 0;
  617.         return BadValue;
  618.     }
  619.     if (stuff->depth != 1)
  620.     {
  621.         pDepth = pDraw->pScreen->allowedDepths;
  622.         for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
  623.        if (pDepth->depth == stuff->depth)
  624.                goto CreatePmap;
  625.     client->errorValue = stuff->depth;
  626.         return BadValue;
  627.     }
  628. CreatePmap:
  629.     VERIFY_SHMSIZE(shmdesc, stuff->offset,
  630.            PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
  631.            client);
  632.     pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
  633.                 pDraw->pScreen, stuff->width,
  634.                 stuff->height, stuff->depth,
  635.                 shmdesc->addr + stuff->offset);
  636.     if (pMap)
  637.     {
  638.     pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  639.     pMap->drawable.id = stuff->pid;
  640.     if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
  641.     {
  642.         shmdesc->refcnt++;
  643.         if (AddResource(stuff->pid, ShmPixType, (pointer)shmdesc))
  644.         return(client->noClientException);
  645.         FreeResource(stuff->pid, RT_NONE);
  646.     }
  647.     }
  648.     return (BadAlloc);
  649. }
  650.  
  651. static int
  652. ProcShmDispatch (client)
  653.     register ClientPtr    client;
  654. {
  655.     REQUEST(xReq);
  656.     switch (stuff->data)
  657.     {
  658.     case X_ShmQueryVersion:
  659.     return ProcShmQueryVersion(client);
  660.     case X_ShmAttach:
  661.     return ProcShmAttach(client);
  662.     case X_ShmDetach:
  663.     return ProcShmDetach(client);
  664.     case X_ShmPutImage:
  665.     return ProcShmPutImage(client);
  666.     case X_ShmGetImage:
  667.     return ProcShmGetImage(client);
  668.     case X_ShmCreatePixmap:
  669.     return ProcShmCreatePixmap(client);
  670.     default:
  671.     return BadRequest;
  672.     }
  673. }
  674.  
  675. static void
  676. SShmCompletionEvent(from, to)
  677.     xShmCompletionEvent *from, *to;
  678. {
  679.     to->type = from->type;
  680.     cpswaps(from->sequenceNumber, to->sequenceNumber);
  681.     cpswapl(from->drawable, to->drawable);
  682.     cpswaps(from->minorEvent, to->minorEvent);
  683.     to->majorEvent = from->majorEvent;
  684.     cpswapl(from->shmseg, to->shmseg);
  685.     cpswapl(from->offset, to->offset);
  686. }
  687.  
  688. static int
  689. SProcShmQueryVersion(client)
  690.     register ClientPtr    client;
  691. {
  692.     register int n;
  693.     REQUEST(xShmQueryVersionReq);
  694.  
  695.     swaps(&stuff->length, n);
  696.     return ProcShmQueryVersion(client);
  697. }
  698.  
  699. static int
  700. SProcShmAttach(client)
  701.     ClientPtr client;
  702. {
  703.     register int n;
  704.     REQUEST(xShmAttachReq);
  705.     swaps(&stuff->length, n);
  706.     REQUEST_SIZE_MATCH(xShmAttachReq);
  707.     swapl(&stuff->shmseg, n);
  708.     swapl(&stuff->shmid, n);
  709.     return ProcShmAttach(client);
  710. }
  711.  
  712. static int
  713. SProcShmDetach(client)
  714.     ClientPtr client;
  715. {
  716.     register int n;
  717.     REQUEST(xShmDetachReq);
  718.     swaps(&stuff->length, n);
  719.     REQUEST_SIZE_MATCH(xShmDetachReq);
  720.     swapl(&stuff->shmseg, n);
  721.     return ProcShmDetach(client);
  722. }
  723.  
  724. static int
  725. SProcShmPutImage(client)
  726.     ClientPtr client;
  727. {
  728.     register int n;
  729.     REQUEST(xShmPutImageReq);
  730.     swaps(&stuff->length, n);
  731.     REQUEST_SIZE_MATCH(xShmPutImageReq);
  732.     swapl(&stuff->drawable, n);
  733.     swapl(&stuff->gc, n);
  734.     swaps(&stuff->totalWidth, n);
  735.     swaps(&stuff->totalHeight, n);
  736.     swaps(&stuff->srcX, n);
  737.     swaps(&stuff->srcY, n);
  738.     swaps(&stuff->srcWidth, n);
  739.     swaps(&stuff->srcHeight, n);
  740.     swaps(&stuff->dstX, n);
  741.     swaps(&stuff->dstY, n);
  742.     swapl(&stuff->shmseg, n);
  743.     swapl(&stuff->offset, n);
  744.     return ProcShmPutImage(client);
  745. }
  746.  
  747. static int
  748. SProcShmGetImage(client)
  749.     ClientPtr client;
  750. {
  751.     register int n;
  752.     REQUEST(xShmGetImageReq);
  753.     swaps(&stuff->length, n);
  754.     REQUEST_SIZE_MATCH(xShmGetImageReq);
  755.     swapl(&stuff->drawable, n);
  756.     swaps(&stuff->x, n);
  757.     swaps(&stuff->y, n);
  758.     swaps(&stuff->width, n);
  759.     swaps(&stuff->height, n);
  760.     swapl(&stuff->planeMask, n);
  761.     swapl(&stuff->shmseg, n);
  762.     swapl(&stuff->offset, n);
  763.     return ProcShmGetImage(client);
  764. }
  765.  
  766. static int
  767. SProcShmCreatePixmap(client)
  768.     ClientPtr client;
  769. {
  770.     register int n;
  771.     REQUEST(xShmCreatePixmapReq);
  772.     swaps(&stuff->length, n);
  773.     REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
  774.     swapl(&stuff->drawable, n);
  775.     swaps(&stuff->width, n);
  776.     swaps(&stuff->height, n);
  777.     swapl(&stuff->shmseg, n);
  778.     swapl(&stuff->offset, n);
  779.     return ProcShmCreatePixmap(client);
  780. }
  781.  
  782. static int
  783. SProcShmDispatch (client)
  784.     register ClientPtr    client;
  785. {
  786.     REQUEST(xReq);
  787.     switch (stuff->data)
  788.     {
  789.     case X_ShmQueryVersion:
  790.     return SProcShmQueryVersion(client);
  791.     case X_ShmAttach:
  792.     return SProcShmAttach(client);
  793.     case X_ShmDetach:
  794.     return SProcShmDetach(client);
  795.     case X_ShmPutImage:
  796.     return SProcShmPutImage(client);
  797.     case X_ShmGetImage:
  798.     return SProcShmGetImage(client);
  799.     case X_ShmCreatePixmap:
  800.     return SProcShmCreatePixmap(client);
  801.     default:
  802.     return BadRequest;
  803.     }
  804. }
  805.