From 4a6a2ab1cc40f3de66cfbddd9e6bd0779c586e73 Mon Sep 17 00:00:00 2001 From: CSRG Date: Fri, 3 Jan 1992 08:59:41 -0800 Subject: [PATCH] BSD 4_4_Lite2 development Work on file usr/src/contrib/X11R5-hp300/mit/server/ddx/hpbsd/cfb/hpByteBlt.c Synthesized-from: CSRG/cd3/4.4BSD-Lite2 --- .../mit/server/ddx/hpbsd/cfb/hpByteBlt.c | 525 ++++++++++++++++++ 1 file changed, 525 insertions(+) create mode 100644 usr/src/contrib/X11R5-hp300/mit/server/ddx/hpbsd/cfb/hpByteBlt.c diff --git a/usr/src/contrib/X11R5-hp300/mit/server/ddx/hpbsd/cfb/hpByteBlt.c b/usr/src/contrib/X11R5-hp300/mit/server/ddx/hpbsd/cfb/hpByteBlt.c new file mode 100644 index 0000000000..3e2ae085df --- /dev/null +++ b/usr/src/contrib/X11R5-hp300/mit/server/ddx/hpbsd/cfb/hpByteBlt.c @@ -0,0 +1,525 @@ +/* + +Copyright (c) 1986, 1987 by Hewlett-Packard Company +Copyright (c) 1986, 1987 by the Massachusetts Institute of Technology + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and without +fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright +notice and this permission notice appear in supporting +documentation, and that the name of M.I.T. not be used in +advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD +TO THIS SOFWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. Hewlett-Packard shall not be liable for errors +contained herein or direct, indirect, special, incidental or +consequential damages in connection with the furnishing, +performance, or use of this material. + +This software is not subject to any license of the American +Telephone and Telegraph Company or of the Regents of the +University of California. + +*/ +/*********************************************************************** + * file: hpByteBlt.c + * + * Byte-Per-Pixel 68000 (and hopefully Spectrum) bit/byte order + * image transfer routines. Specifically: + * hpGetByteImage + * + * Hewlett Packard -- Corvallis Workstation Operation + * Project -- port of X11 to HP9000 + * Harry Phinney -- MTS + * + * + */ + +#include "X.h" +#include "Xprotostr.h" + +#include "cfb.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "mi.h" +#include "regionstr.h" +#include "Xmd.h" +#include "servermd.h" + +static unsigned char masks[8] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 }; +#if 0 +static unsigned char trailMasks[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, + 0x2, 0x1 }; + +static unsigned long bmap[32] = { + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x00000100, 0x00000200, 0x00000400, 0x00000800, + 0x00001000, 0x00002000, 0x00004000, 0x00008000, + 0x00010000, 0x00020000, 0x00040000, 0x00080000, + 0x00100000, 0x00200000, 0x00400000, 0x00800000, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000 }; +#endif + +static unsigned long rbmap[32] = { + 0x80000000, 0x40000000, 0x20000000, 0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001 }; + + +/* hpGetPlane -- gets a bitmap representing one plane of pDraw + * A helper used for XY format GetImage + * No clever strategy here, we grab a scanline at a time, pull out the + * bits and then stuff them in a 1 bit deep map. + * This is a significantly modified version of miGetPlane. The arguments + * are different, as here we pass in the start address within the source + * pixmap, instead of the sx and sy within the pixmap, and we pass in the + * stride that will get us to the next line - either the pixmap width or + * the screen width depending on whether the pixmap is in framebuffer or + * main memory. + */ +unsigned long * +hpGetPlane(pDraw, planeNum, startAddr, w, h, stride, result) + DrawablePtr pDraw; + int planeNum; /* number of the bitPlane */ + unsigned char * startAddr; + int w, h; + int stride; /* stride to get to next line */ + unsigned long *result; +{ + register int i, j; + int k, widthInBytes; + register CARD32 bits; + CARD8 *pCharsOut; + register unsigned char *pixAddr; + register unsigned char pixel; + + if (pDraw->depth != 8) + FatalError("hpGetPlane: invalid depth\n"); + widthInBytes = PixmapBytePad(w, 1); + if (!result) + result = (unsigned long *)xalloc(h * widthInBytes); + + for (i = 0; i < h; i++) + { + pCharsOut = ((unsigned char *)result) + i * widthInBytes; + pixAddr = startAddr + i * (stride); + k = 0; + bits = 0; + for (j = 0; j < w; j++) + { + pixel = *pixAddr++; + if (BITMAP_BIT_ORDER == LSBFirst) + bits = (bits << 1) | ((pixel >> planeNum) & 1); + else + { +#ifdef notdef /* more portable, but slower code */ + bits |= ((pixel >> planeNum) & 1) << ((BITMAP_SCANLINE_UNIT - 1) + - k); +#else /* faster, but less portable code */ + if (pixel & masks[planeNum]) bits |= rbmap[k]; +#endif + } + k++; + if (BITMAP_SCANLINE_UNIT == k) + { + switch (BITMAP_SCANLINE_UNIT) + { + case 8: + *pCharsOut++ = (CARD8)bits; break; + case 16: + *(CARD16 *)pCharsOut = (CARD16) bits; + pCharsOut += sizeof(CARD16); + break; + case 32: + *(CARD32 *)pCharsOut = bits; + pCharsOut += sizeof(CARD32); + break; + } + k = bits = 0; + } + } + +#define ORBITs(type,ptr,bits) *(type *)ptr = (type)bits + + if (k) /* trailing bits */ + { + switch (BITMAP_SCANLINE_UNIT) + { + case 8: + ORBITs(CARD8, pCharsOut,bits); + break; + case 16: + ORBITs(CARD16,pCharsOut,bits); + break; + case 32: + ORBITs(CARD32,pCharsOut,bits); break; + } + } + } + return(result); +} + +/* hpGetByteImage -- public entry for the GetImage Request + * We're getting the image into a memory buffer. + * Since we know what an hp byte-deep framebuffer looks like, we can do + * this much faster than miGetImage. + * + * two different strategies are used, depending on whether we're getting the + * image in Z format or XY format + * Z format: + * For each row + * For each column + * Read the pixel into pdst + * If planeMask is not all ones (yech) + * For each row + * For each column + * Mask the unwanted bits + * + * XY format: + * Call hpGetBytePlane (see above in this file) + * + * + */ +void +hpGetByteImage(pDraw, sx, sy, w, h, format, planeMask, pdstLine) + DrawablePtr pDraw; + int sx, sy, w, h; + unsigned int format; + unsigned long planeMask; + pointer pdstLine; +{ + int depth, i, linelength; + + unsigned char *pSrc; + int widthSrc; + unsigned int screenPlanes = getPlanesMask(pDraw->pScreen); + + if ((w == 0) || (h == 0)) + return; + + depth = pDraw->depth; + switch (depth) + { + case 1: + mfbGetImage(pDraw, sx, sy, w, h, format, planeMask, pdstLine); + return; + case 8: + break; + default: + miGetImage(pDraw, sx, sy, w, h, format, planeMask, pdstLine); + return; + } + + if (!(planeMask &= screenPlanes)) + return; + + linelength = PixmapBytePad(w, depth); + if (pDraw->type == DRAWABLE_WINDOW) + { + sx += pDraw->x; + sy += pDraw->y; + widthSrc = (int) getPrivScreenPtr(pDraw->pScreen)->stride; + pSrc = (unsigned char *) + getPrivScreenPtr(pDraw->pScreen)->bits + sx + sy * widthSrc; + } + else + { /* we're getting from a pixmap */ + hpPrivPixmapPtr pPrivPix = + (hpPrivPixmapPtr)((PixmapPtr) pDraw)->devPrivate.ptr; + + if (((PixmapPtr)pDraw)->devKind == PIXMAP_FRAME_BUFFER) + { + sx += pPrivPix->pChunk->x; + sy += pPrivPix->pChunk->y; + widthSrc = (int) getPrivScreenPtr(pDraw->pScreen)->stride; + pSrc = (unsigned char *) + getPrivScreenPtr(pDraw->pScreen)->bits + sx + sy * widthSrc; + } + else + { /* main memory pixmap */ + widthSrc = (int) pPrivPix->stride; + pSrc = (unsigned char *) pPrivPix->bits + sx + sy * widthSrc; + } + } + if (format == ZPixmap) + { + WAIT_READY_TO_RENDER(pDraw->pScreen); + + for (i = 0; i < h; i++) + { /* for each row */ + register int j; + register unsigned char *pByteDst; + register unsigned char *pSrcByte; + + pSrcByte = pSrc + i * widthSrc; + pByteDst = ((unsigned char *)pdstLine) + i * linelength; + + for (j = 0; j < w; j++) + { /* for each pixel in row */ + *pByteDst++ = *pSrcByte++ & planeMask; + } + } + } + else + { + int planes = Ones(screenPlanes); + int planeSize = PixmapBytePad(w, 1) * h; + + for (i = planes - 1; i >= 0; i--) + if (planeMask & (1 << i)) + { + (void) hpGetPlane(pDraw, i, pSrc, w, h, widthSrc, pdstLine); + pdstLine += planeSize; + } + } +} + + +/* hpPutByteImage -- public entry for the PutImage Request + * This is here to try to make XY pixmap puts work reasonably on + * our byte-deep framebuffers. + */ +void +hpPutByteImage(pDraw, pGC, depth, dstx, dsty, w, h, srcOffset, format, pImage) + DrawablePtr pDraw; + GCPtr pGC; + int depth, dstx, dsty, w, h, srcOffset; + unsigned int format; + unsigned char *pImage; +{ + unsigned long planeMask = pGC->planemask; + int i; + unsigned int planeSize, srcStride, widthDst, garbageBits, bits; + CARD8 *psrc, *psrcLine, *psrcBase, *pdstBase, *pdstLine, *pdst; + RegionPtr pRegion; + unsigned int alu; + register BoxPtr pBox; + unsigned int numBoxes; + CARD8 srcByte; + unsigned int rows; + unsigned int pixels; + + if ((w == 0) || (h == 0)) + return; + + planeMask &= getPlanesMask(pDraw->pScreen); + + if ((format == ZPixmap) || + ((pDraw->type == DRAWABLE_PIXMAP) && + (((PixmapPtr)(pDraw))->devKind == PIXMAP_HOST_MEMORY))) + { + /* + * mi seems to work for ZPixmaps + * and my code doesn't work for main-memory pixmaps since + * I rely on the hardware plane-enable + */ + miPutImage(pDraw, pGC, depth, dstx, dsty, w, h, srcOffset, + format, pImage); + return; + } + + alu = pGC->alu; + pRegion = ((cfbPrivGC *) + (pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip; + pBox = REGION_RECTS(pRegion); + numBoxes = REGION_NUM_RECTS(pRegion); + + dstx += pDraw->x; + dsty += pDraw->y; + if (pDraw->type == DRAWABLE_WINDOW) + { + widthDst = (unsigned int) + getPrivScreenPtr(pDraw->pScreen)->stride; + pdstBase = (CARD8 *) + getPrivScreenPtr(pDraw->pScreen)->bits; + } + else + { + widthDst = (unsigned int) + (((hpPrivPixmapPtr)(((PixmapPtr)pDraw)->devPrivate.ptr))->stride); + pdstBase = (CARD8 *) + (((hpPrivPixmapPtr)(((PixmapPtr)pDraw)->devPrivate.ptr))->bits); + } + + srcStride = PixmapBytePad(w, 1); + planeSize = h * srcStride; + + while(numBoxes--) + { + int clippedWidth = w - srcOffset; + int clippedHeight = h; + int startx = dstx; + int starty = dsty; + int dx = 0, dy = 0; + CARD8 *pdstBox = pdstBase; + + psrcBase = (CARD8 *)pImage; + + /* + * clip the height + */ + if (dsty < pBox->y1) + { + dy = pBox->y1 - dsty; + clippedHeight -= dy; + if (clippedHeight <= 0) + { + pBox++; + continue; + } + starty = pBox->y1; + } + if (starty+clippedHeight > pBox->y2) + { + clippedHeight = pBox->y2 - starty; + if (clippedHeight <= 0) + { + pBox++; + continue; + } + } + /* + * clip the width + */ + if (dstx < pBox->x1) + { + dx = pBox->x1 - dstx; + clippedWidth -= dx; + if (clippedWidth <= 0) + { + pBox++; + continue; + } + startx = pBox->x1; + } + if (startx+clippedWidth > pBox->x2) + { + clippedWidth = pBox->x2 - startx; + if (clippedWidth <= 0) + { + pBox++; + continue; + } + } + + if (!clippedWidth || !clippedHeight) + { + pBox++; + continue; + } + + /* + * get address of the first destination pixel + */ + pdstBox += startx + starty * widthDst; + /* + * get address of the first source bytes with useful bits + */ + psrcBase += srcStride * dy + (srcOffset + dx) / 8; + garbageBits = (srcOffset + dx) % 8; + + if (depth == 1) + { + /* + * XYBitmap code + */ + unsigned int fore = pGC->fgPixel; + unsigned int back = pGC->bgPixel; + + rows = clippedHeight; + pixels = clippedWidth; + /* + * write enable the one plane we want to alter + */ + SET_REGISTERS_FOR_WRITING(pDraw->pScreen, planeMask, alu); + + psrcLine = psrcBase; + pdstLine = pdstBox; + while (rows--) + { + psrc = psrcLine; + pdst = pdstLine; + srcByte = *psrc++ << garbageBits; + bits = 8 - garbageBits; + + while (pixels--) + { + if (srcByte & 0x80) + *pdst++ = fore; + else + *pdst++ = back; + if (--bits) + srcByte <<= 1; + else + { + bits = 8; + srcByte = *psrc++; + } + } + pixels = clippedWidth; + psrcLine += srcStride; + pdstLine += widthDst; + } + } + else + { + for (i = 1 << (depth - 1); i > 0; i >>= 1, psrcBase += planeSize) + { + if (i & planeMask) + { + rows = clippedHeight; + pixels = clippedWidth; + + /* + * write enable the one plane we want to alter + */ + SET_REGISTERS_FOR_WRITING(pDraw->pScreen, i, alu); + + psrcLine = psrcBase; + pdstLine = pdstBox; + while (rows--) + { + psrc = psrcLine; + pdst = pdstLine; + srcByte = *psrc++ << garbageBits; + bits = 8 - garbageBits; + + while (pixels--) + { + if (srcByte & 0x80) + *pdst++ = 0xff; + else + *pdst++ = 0x00; + if (--bits) + srcByte <<= 1; + else + { + bits = 8; + srcByte = *psrc++; + } + } + pixels = clippedWidth; + psrcLine += srcStride; + pdstLine += widthDst; + } + } + } + } + pBox++; + } + SET_REGISTERS_FOR_WRITING(pDraw->pScreen, 0xff, alu); +} + -- 2.20.1