105b261ecSmrg/*********************************************************** 205b261ecSmrg 305b261ecSmrgCopyright 1987, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg 2505b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 2605b261ecSmrg 2705b261ecSmrg All Rights Reserved 2805b261ecSmrg 2935c4bbdfSmrgPermission to use, copy, modify, and distribute this software and its 3035c4bbdfSmrgdocumentation for any purpose and without fee is hereby granted, 3105b261ecSmrgprovided that the above copyright notice appear in all copies and that 3235c4bbdfSmrgboth that copyright notice and this permission notice appear in 3305b261ecSmrgsupporting documentation, and that the name of Digital not be 3405b261ecSmrgused in advertising or publicity pertaining to distribution of the 3535c4bbdfSmrgsoftware without specific, written prior permission. 3605b261ecSmrg 3705b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3805b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 3905b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4005b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4105b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4205b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4305b261ecSmrgSOFTWARE. 4405b261ecSmrg 4505b261ecSmrg******************************************************************/ 4605b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 4705b261ecSmrg#include <dix-config.h> 4805b261ecSmrg#endif 4905b261ecSmrg 5005b261ecSmrg#include <X11/X.h> 5105b261ecSmrg#include "gcstruct.h" 5205b261ecSmrg#include "scrnintstr.h" 5305b261ecSmrg#include "pixmapstr.h" 5405b261ecSmrg#include "regionstr.h" 5505b261ecSmrg#include "mi.h" 564642e01fSmrg#include "servermd.h" 5705b261ecSmrg 5805b261ecSmrg#define NPT 128 5905b261ecSmrg 604642e01fSmrg/* These were stolen from mfb. They don't really belong here. */ 614642e01fSmrg#define LONG2CHARSSAMEORDER(x) ((MiBits)(x)) 624642e01fSmrg#define LONG2CHARSDIFFORDER( x ) ( ( ( ( x ) & (MiBits)0x000000FF ) << 0x18 ) \ 634642e01fSmrg | ( ( ( x ) & (MiBits)0x0000FF00 ) << 0x08 ) \ 644642e01fSmrg | ( ( ( x ) & (MiBits)0x00FF0000 ) >> 0x08 ) \ 654642e01fSmrg | ( ( ( x ) & (MiBits)0xFF000000 ) >> 0x18 ) ) 664642e01fSmrg 674642e01fSmrg#define PGSZB 4 6835c4bbdfSmrg#define PPW (PGSZB<<3) /* assuming 8 bits per byte */ 694642e01fSmrg#define PGSZ PPW 704642e01fSmrg#define PLST (PPW-1) 714642e01fSmrg#define PIM PLST 724642e01fSmrg#define PWSH 5 734642e01fSmrg 7405b261ecSmrg/* miPushPixels -- squeegees the fill style of pGC through pBitMap 7505b261ecSmrg * into pDrawable. pBitMap is a stencil (dx by dy of it is used, it may 7605b261ecSmrg * be bigger) which is placed on the drawable at xOrg, yOrg. Where a 1 bit 7705b261ecSmrg * is set in the bitmap, the fill style is put onto the drawable using 7805b261ecSmrg * the GC's logical function. The drawable is not changed where the bitmap 7905b261ecSmrg * has a zero bit or outside the area covered by the stencil. 8005b261ecSmrg 8105b261ecSmrgWARNING: 8205b261ecSmrg this code works if the 1-bit deep pixmap format returned by GetSpans 8305b261ecSmrgis the same as the format defined by the mfb code (i.e. 32-bit padding 8405b261ecSmrgper scanline, scanline unit = 32 bits; later, this might mean 8505b261ecSmrgbitsizeof(int) padding and sacnline unit == bitsizeof(int).) 8605b261ecSmrg 8705b261ecSmrg */ 8805b261ecSmrg 8905b261ecSmrg/* 9005b261ecSmrg * in order to have both (MSB_FIRST and LSB_FIRST) versions of this 9105b261ecSmrg * in the server, we need to rename one of them 9205b261ecSmrg */ 934642e01fSmrgvoid 944642e01fSmrgmiPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, 954642e01fSmrg int dx, int dy, int xOrg, int yOrg) 9605b261ecSmrg{ 9735c4bbdfSmrg int h, dxDivPPW, ibEnd; 9835c4bbdfSmrg MiBits *pwLineStart; 9935c4bbdfSmrg MiBits *pw, *pwEnd; 10035c4bbdfSmrg MiBits msk; 10135c4bbdfSmrg int ib, w; 10235c4bbdfSmrg int ipt; /* index into above arrays */ 10335c4bbdfSmrg Bool fInBox; 10435c4bbdfSmrg DDXPointRec pt[NPT], ptThisLine; 10535c4bbdfSmrg int width[NPT]; 10635c4bbdfSmrg 10705b261ecSmrg#if 1 10835c4bbdfSmrg MiBits startmask; 10935c4bbdfSmrg 11005b261ecSmrg if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER) 11135c4bbdfSmrg if (screenInfo.bitmapBitOrder == LSBFirst) 11235c4bbdfSmrg startmask = (MiBits) (-1) ^ LONG2CHARSSAMEORDER((MiBits) (-1) << 1); 11335c4bbdfSmrg else 11435c4bbdfSmrg startmask = (MiBits) (-1) ^ LONG2CHARSSAMEORDER((MiBits) (-1) >> 1); 11535c4bbdfSmrg else if (screenInfo.bitmapBitOrder == LSBFirst) 11635c4bbdfSmrg startmask = (MiBits) (-1) ^ LONG2CHARSDIFFORDER((MiBits) (-1) << 1); 11705b261ecSmrg else 11835c4bbdfSmrg startmask = (MiBits) (-1) ^ LONG2CHARSDIFFORDER((MiBits) (-1) >> 1); 11905b261ecSmrg#endif 12005b261ecSmrg 1216747b715Smrg pwLineStart = malloc(BitmapBytePad(dx)); 12205b261ecSmrg if (!pwLineStart) 12335c4bbdfSmrg return; 12405b261ecSmrg ipt = 0; 12535c4bbdfSmrg dxDivPPW = dx / PPW; 12635c4bbdfSmrg 12735c4bbdfSmrg for (h = 0, ptThisLine.x = 0, ptThisLine.y = 0; h < dy; h++, ptThisLine.y++) { 12805b261ecSmrg 12935c4bbdfSmrg (*pBitMap->drawable.pScreen->GetSpans) ((DrawablePtr) pBitMap, dx, 13035c4bbdfSmrg &ptThisLine, &dx, 1, 13135c4bbdfSmrg (char *) pwLineStart); 13205b261ecSmrg 13335c4bbdfSmrg pw = pwLineStart; 13435c4bbdfSmrg /* Process all words which are fully in the pixmap */ 13505b261ecSmrg 13635c4bbdfSmrg fInBox = FALSE; 13735c4bbdfSmrg pwEnd = pwLineStart + dxDivPPW; 13835c4bbdfSmrg while (pw < pwEnd) { 13935c4bbdfSmrg w = *pw; 14005b261ecSmrg#if 1 14135c4bbdfSmrg msk = startmask; 14205b261ecSmrg#else 14335c4bbdfSmrg msk = (MiBits) (-1) ^ SCRRIGHT((MiBits) (-1), 1); 14405b261ecSmrg#endif 14535c4bbdfSmrg for (ib = 0; ib < PPW; ib++) { 14635c4bbdfSmrg if (w & msk) { 14735c4bbdfSmrg if (!fInBox) { 14835c4bbdfSmrg pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; 14935c4bbdfSmrg pt[ipt].y = h + yOrg; 15035c4bbdfSmrg /* start new box */ 15135c4bbdfSmrg fInBox = TRUE; 15235c4bbdfSmrg } 15335c4bbdfSmrg } 15435c4bbdfSmrg else { 15535c4bbdfSmrg if (fInBox) { 15635c4bbdfSmrg width[ipt] = ((pw - pwLineStart) << PWSH) + 15735c4bbdfSmrg ib + xOrg - pt[ipt].x; 15835c4bbdfSmrg if (++ipt >= NPT) { 15935c4bbdfSmrg (*pGC->ops->FillSpans) (pDrawable, pGC, 16035c4bbdfSmrg NPT, pt, width, TRUE); 16135c4bbdfSmrg ipt = 0; 16235c4bbdfSmrg } 16335c4bbdfSmrg /* end box */ 16435c4bbdfSmrg fInBox = FALSE; 16535c4bbdfSmrg } 16635c4bbdfSmrg } 16705b261ecSmrg#if 1 16835c4bbdfSmrg /* This is not quite right, but it'll do for now */ 16935c4bbdfSmrg if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER) 17035c4bbdfSmrg if (screenInfo.bitmapBitOrder == LSBFirst) 17135c4bbdfSmrg msk = 17235c4bbdfSmrg LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1); 17335c4bbdfSmrg else 17435c4bbdfSmrg msk = 17535c4bbdfSmrg LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1); 17635c4bbdfSmrg else if (screenInfo.bitmapBitOrder == LSBFirst) 17735c4bbdfSmrg msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1); 17835c4bbdfSmrg else 17935c4bbdfSmrg msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1); 18005b261ecSmrg#else 18135c4bbdfSmrg msk = SCRRIGHT(msk, 1); 18205b261ecSmrg#endif 18335c4bbdfSmrg } 18435c4bbdfSmrg pw++; 18535c4bbdfSmrg } 18635c4bbdfSmrg ibEnd = dx & PIM; 18735c4bbdfSmrg if (ibEnd) { 18835c4bbdfSmrg /* Process final partial word on line */ 18935c4bbdfSmrg w = *pw; 19005b261ecSmrg#if 1 19135c4bbdfSmrg msk = startmask; 19205b261ecSmrg#else 19335c4bbdfSmrg msk = (MiBits) (-1) ^ SCRRIGHT((MiBits) (-1), 1); 19405b261ecSmrg#endif 19535c4bbdfSmrg for (ib = 0; ib < ibEnd; ib++) { 19635c4bbdfSmrg if (w & msk) { 19735c4bbdfSmrg if (!fInBox) { 19835c4bbdfSmrg /* start new box */ 19935c4bbdfSmrg pt[ipt].x = ((pw - pwLineStart) << PWSH) + ib + xOrg; 20035c4bbdfSmrg pt[ipt].y = h + yOrg; 20135c4bbdfSmrg fInBox = TRUE; 20235c4bbdfSmrg } 20335c4bbdfSmrg } 20435c4bbdfSmrg else { 20535c4bbdfSmrg if (fInBox) { 20635c4bbdfSmrg /* end box */ 20735c4bbdfSmrg width[ipt] = ((pw - pwLineStart) << PWSH) + 20835c4bbdfSmrg ib + xOrg - pt[ipt].x; 20935c4bbdfSmrg if (++ipt >= NPT) { 21035c4bbdfSmrg (*pGC->ops->FillSpans) (pDrawable, 21135c4bbdfSmrg pGC, NPT, pt, width, TRUE); 21235c4bbdfSmrg ipt = 0; 21335c4bbdfSmrg } 21435c4bbdfSmrg fInBox = FALSE; 21535c4bbdfSmrg } 21635c4bbdfSmrg } 21705b261ecSmrg#if 1 21835c4bbdfSmrg /* This is not quite right, but it'll do for now */ 21935c4bbdfSmrg if (screenInfo.bitmapBitOrder == IMAGE_BYTE_ORDER) 22035c4bbdfSmrg if (screenInfo.bitmapBitOrder == LSBFirst) 22135c4bbdfSmrg msk = 22235c4bbdfSmrg LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) << 1); 22335c4bbdfSmrg else 22435c4bbdfSmrg msk = 22535c4bbdfSmrg LONG2CHARSSAMEORDER(LONG2CHARSSAMEORDER(msk) >> 1); 22635c4bbdfSmrg else if (screenInfo.bitmapBitOrder == LSBFirst) 22735c4bbdfSmrg msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) << 1); 22835c4bbdfSmrg else 22935c4bbdfSmrg msk = LONG2CHARSDIFFORDER(LONG2CHARSDIFFORDER(msk) >> 1); 23005b261ecSmrg#else 23135c4bbdfSmrg msk = SCRRIGHT(msk, 1); 23205b261ecSmrg#endif 23335c4bbdfSmrg } 23435c4bbdfSmrg } 23535c4bbdfSmrg /* If scanline ended with last bit set, end the box */ 23635c4bbdfSmrg if (fInBox) { 23735c4bbdfSmrg width[ipt] = dx + xOrg - pt[ipt].x; 23835c4bbdfSmrg if (++ipt >= NPT) { 23935c4bbdfSmrg (*pGC->ops->FillSpans) (pDrawable, pGC, NPT, pt, width, TRUE); 24035c4bbdfSmrg ipt = 0; 24135c4bbdfSmrg } 24235c4bbdfSmrg } 24305b261ecSmrg } 2446747b715Smrg free(pwLineStart); 24505b261ecSmrg /* Flush any remaining spans */ 24635c4bbdfSmrg if (ipt) { 24735c4bbdfSmrg (*pGC->ops->FillSpans) (pDrawable, pGC, ipt, pt, width, TRUE); 24805b261ecSmrg } 24905b261ecSmrg} 250