258
ShmExtensionInit(INITARGS)
260
ExtensionEntry *extEntry;
263
#ifdef MUST_CHECK_FOR_SHM_SYSCALL
264
if (!CheckForShmSyscall())
266
ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
271
if (!ShmRegisterPrivates())
274
sharedPixmaps = xFalse;
276
sharedPixmaps = xTrue;
277
for (i = 0; i < screenInfo.numScreens; i++)
279
ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]);
280
if (!screen_priv->shmFuncs)
281
screen_priv->shmFuncs = &miFuncs;
282
if (!screen_priv->shmFuncs->CreatePixmap)
283
sharedPixmaps = xFalse;
286
for (i = 0; i < screenInfo.numScreens; i++)
288
ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]);
289
screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap;
290
screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
293
ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg");
295
(extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
296
ProcShmDispatch, SProcShmDispatch,
297
ShmResetProc, StandardMinorOpcode)))
299
ShmReqCode = (unsigned char)extEntry->base;
300
ShmCompletionCode = extEntry->eventBase;
301
BadShmSegCode = extEntry->errorBase;
302
SetResourceTypeErrorValue(ShmSegType, BadShmSegCode);
303
EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
309
245
ShmResetProc(ExtensionEntry *extEntry)
521
ProcShmPutImage(ClientPtr client)
527
REQUEST(xShmPutImageReq);
529
REQUEST_SIZE_MATCH(xShmPutImageReq);
530
VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
531
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
532
if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
534
if (stuff->format == XYBitmap)
536
if (stuff->depth != 1)
538
length = PixmapBytePad(stuff->totalWidth, 1);
540
else if (stuff->format == XYPixmap)
542
if (pDraw->depth != stuff->depth)
544
length = PixmapBytePad(stuff->totalWidth, 1);
545
length *= stuff->depth;
547
else if (stuff->format == ZPixmap)
549
if (pDraw->depth != stuff->depth)
551
length = PixmapBytePad(stuff->totalWidth, stuff->depth);
555
client->errorValue = stuff->format;
560
* There's a potential integer overflow in this check:
561
* VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
563
* the version below ought to avoid it
565
if (stuff->totalHeight != 0 &&
566
length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
567
client->errorValue = stuff->totalWidth;
570
if (stuff->srcX > stuff->totalWidth)
572
client->errorValue = stuff->srcX;
575
if (stuff->srcY > stuff->totalHeight)
577
client->errorValue = stuff->srcY;
580
if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
582
client->errorValue = stuff->srcWidth;
585
if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
587
client->errorValue = stuff->srcHeight;
591
if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
592
((stuff->format != ZPixmap) &&
593
(stuff->srcX < screenInfo.bitmapScanlinePad) &&
594
((stuff->format == XYBitmap) ||
595
((stuff->srcY == 0) &&
596
(stuff->srcHeight == stuff->totalHeight))))) &&
597
((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
598
(*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
599
stuff->dstX, stuff->dstY,
600
stuff->totalWidth, stuff->srcHeight,
601
stuff->srcX, stuff->format,
602
shmdesc->addr + stuff->offset +
603
(stuff->srcY * length));
605
doShmPutImage(pDraw, pGC, stuff->depth, stuff->format,
606
stuff->totalWidth, stuff->totalHeight,
607
stuff->srcX, stuff->srcY,
608
stuff->srcWidth, stuff->srcHeight,
609
stuff->dstX, stuff->dstY,
610
shmdesc->addr + stuff->offset);
612
if (stuff->sendEvent)
614
xShmCompletionEvent ev;
616
ev.type = ShmCompletionCode;
617
ev.drawable = stuff->drawable;
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);
629
ProcShmGetImage(ClientPtr client)
632
long lenPer = 0, length;
634
xShmGetImageReply xgi;
638
REQUEST(xShmGetImageReq);
640
REQUEST_SIZE_MATCH(xShmGetImageReq);
641
if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
643
client->errorValue = stuff->format;
646
rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
650
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
651
if (pDraw->type == DRAWABLE_WINDOW)
653
if( /* check for being viewable */
654
!((WindowPtr) pDraw)->realized ||
655
/* check for being on screen */
656
pDraw->x + stuff->x < 0 ||
657
pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
658
pDraw->y + stuff->y < 0 ||
659
pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
660
/* check for being inside of border */
661
stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
662
stuff->x + (int)stuff->width >
663
wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
664
stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
665
stuff->y + (int)stuff->height >
666
wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
669
xgi.visual = wVisual(((WindowPtr)pDraw));
674
stuff->x+(int)stuff->width > pDraw->width ||
676
stuff->y+(int)stuff->height > pDraw->height
683
xgi.sequenceNumber = client->sequence;
684
xgi.depth = pDraw->depth;
685
if(stuff->format == ZPixmap)
687
length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
691
lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
692
plane = ((Mask)1) << (pDraw->depth - 1);
693
/* only planes asked for */
694
length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
697
VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
704
else if (stuff->format == ZPixmap)
706
(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
707
stuff->width, stuff->height,
708
stuff->format, stuff->planeMask,
709
shmdesc->addr + stuff->offset);
714
length = stuff->offset;
715
for (; plane; plane >>= 1)
717
if (stuff->planeMask & plane)
719
(*pDraw->pScreen->GetImage)(pDraw,
721
stuff->width, stuff->height,
722
stuff->format, plane,
723
shmdesc->addr + length);
729
if (client->swapped) {
730
swaps(&xgi.sequenceNumber, n);
731
swapl(&xgi.length, n);
732
swapl(&xgi.visual, n);
735
WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
586
742
ProcPanoramiXShmPutImage(ClientPtr client)
865
ProcShmPutImage(ClientPtr client)
871
REQUEST(xShmPutImageReq);
873
REQUEST_SIZE_MATCH(xShmPutImageReq);
874
VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
875
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
876
if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
878
if (stuff->format == XYBitmap)
880
if (stuff->depth != 1)
882
length = PixmapBytePad(stuff->totalWidth, 1);
884
else if (stuff->format == XYPixmap)
886
if (pDraw->depth != stuff->depth)
888
length = PixmapBytePad(stuff->totalWidth, 1);
889
length *= stuff->depth;
891
else if (stuff->format == ZPixmap)
893
if (pDraw->depth != stuff->depth)
895
length = PixmapBytePad(stuff->totalWidth, stuff->depth);
899
client->errorValue = stuff->format;
904
* There's a potential integer overflow in this check:
905
* VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
907
* the version below ought to avoid it
909
if (stuff->totalHeight != 0 &&
910
length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
911
client->errorValue = stuff->totalWidth;
914
if (stuff->srcX > stuff->totalWidth)
916
client->errorValue = stuff->srcX;
919
if (stuff->srcY > stuff->totalHeight)
921
client->errorValue = stuff->srcY;
924
if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
926
client->errorValue = stuff->srcWidth;
929
if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
931
client->errorValue = stuff->srcHeight;
935
if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
936
((stuff->format != ZPixmap) &&
937
(stuff->srcX < screenInfo.bitmapScanlinePad) &&
938
((stuff->format == XYBitmap) ||
939
((stuff->srcY == 0) &&
940
(stuff->srcHeight == stuff->totalHeight))))) &&
941
((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
942
(*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
943
stuff->dstX, stuff->dstY,
944
stuff->totalWidth, stuff->srcHeight,
945
stuff->srcX, stuff->format,
946
shmdesc->addr + stuff->offset +
947
(stuff->srcY * length));
949
doShmPutImage(pDraw, pGC, stuff->depth, stuff->format,
950
stuff->totalWidth, stuff->totalHeight,
951
stuff->srcX, stuff->srcY,
952
stuff->srcWidth, stuff->srcHeight,
953
stuff->dstX, stuff->dstY,
954
shmdesc->addr + stuff->offset);
956
if (stuff->sendEvent)
958
xShmCompletionEvent ev;
960
ev.type = ShmCompletionCode;
961
ev.drawable = stuff->drawable;
962
ev.minorEvent = X_ShmPutImage;
963
ev.majorEvent = ShmReqCode;
964
ev.shmseg = stuff->shmseg;
965
ev.offset = stuff->offset;
966
WriteEventsToClient(client, 1, (xEvent *) &ev);
975
ProcShmGetImage(ClientPtr client)
978
long lenPer = 0, length;
980
xShmGetImageReply xgi;
984
REQUEST(xShmGetImageReq);
986
REQUEST_SIZE_MATCH(xShmGetImageReq);
987
if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
989
client->errorValue = stuff->format;
992
rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
996
VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
997
if (pDraw->type == DRAWABLE_WINDOW)
999
if( /* check for being viewable */
1000
!((WindowPtr) pDraw)->realized ||
1001
/* check for being on screen */
1002
pDraw->x + stuff->x < 0 ||
1003
pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
1004
pDraw->y + stuff->y < 0 ||
1005
pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
1006
/* check for being inside of border */
1007
stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
1008
stuff->x + (int)stuff->width >
1009
wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
1010
stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
1011
stuff->y + (int)stuff->height >
1012
wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
1015
xgi.visual = wVisual(((WindowPtr)pDraw));
1020
stuff->x+(int)stuff->width > pDraw->width ||
1022
stuff->y+(int)stuff->height > pDraw->height
1029
xgi.sequenceNumber = client->sequence;
1030
xgi.depth = pDraw->depth;
1031
if(stuff->format == ZPixmap)
1033
length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
1037
lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
1038
plane = ((Mask)1) << (pDraw->depth - 1);
1039
/* only planes asked for */
1040
length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
1043
VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
1050
else if (stuff->format == ZPixmap)
1052
(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
1053
stuff->width, stuff->height,
1054
stuff->format, stuff->planeMask,
1055
shmdesc->addr + stuff->offset);
1060
length = stuff->offset;
1061
for (; plane; plane >>= 1)
1063
if (stuff->planeMask & plane)
1065
(*pDraw->pScreen->GetImage)(pDraw,
1067
stuff->width, stuff->height,
1068
stuff->format, plane,
1069
shmdesc->addr + length);
1075
if (client->swapped) {
1076
swaps(&xgi.sequenceNumber, n);
1077
swapl(&xgi.length, n);
1078
swapl(&xgi.visual, n);
1079
swapl(&xgi.size, n);
1081
WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
1086
1019
static PixmapPtr
1087
1020
fbShmCreatePixmap (ScreenPtr pScreen,
1088
1021
int width, int height, int depth, char *addr)
1342
1275
return BadRequest;
1280
ShmExtensionInit(INITARGS)
1282
ExtensionEntry *extEntry;
1285
#ifdef MUST_CHECK_FOR_SHM_SYSCALL
1286
if (!CheckForShmSyscall())
1288
ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
1293
if (!ShmRegisterPrivates())
1296
sharedPixmaps = xFalse;
1298
sharedPixmaps = xTrue;
1299
for (i = 0; i < screenInfo.numScreens; i++)
1301
ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]);
1302
if (!screen_priv->shmFuncs)
1303
screen_priv->shmFuncs = &miFuncs;
1304
if (!screen_priv->shmFuncs->CreatePixmap)
1305
sharedPixmaps = xFalse;
1308
for (i = 0; i < screenInfo.numScreens; i++)
1310
ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]);
1311
screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap;
1312
screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
1315
ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg");
1317
(extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
1318
ProcShmDispatch, SProcShmDispatch,
1319
ShmResetProc, StandardMinorOpcode)))
1321
ShmReqCode = (unsigned char)extEntry->base;
1322
ShmCompletionCode = extEntry->eventBase;
1323
BadShmSegCode = extEntry->errorBase;
1324
SetResourceTypeErrorValue(ShmSegType, BadShmSegCode);
1325
EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;