xf1bpp.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ xf1bpp.h | 14 +++-- 2 files changed, 160 insertions(+), 5 deletions(-) Index: xf1bpp.c =================================================================== RCS file: xf1bpp.c diff -N xf1bpp.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ xf1bpp.c 18 Oct 2005 20:06:40 -0000 @@ -0,0 +1,151 @@ +/* + * Copyright 2005 Adam Jackson. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * xf1bpp is for when hardware bit order doesn't match hardware byte order. + * We used to do this by subclassing mfb, but shadowfb is simpler, and + * faster if you have the RAM. + */ + +#include "fb.h" +#include "shadowfb.h" + +/* this whole thing assumes that sizeof(int) == 4 */ + +typedef struct { + unsigned int *fb; + unsigned int *shadow; + int x; + int y; + int width; + CloseScreenProcPtr CloseScreen; +} xf1bppScreenPrivateRec; + +static int xf1Generation = 0; +static int xf1ScreenPrivateIndex = 0; + +static unsigned int +flip_word(unsigned int i) +{ + /* sneaky */ + i = ((i >> 1) & 0x55555555) | ((i << 1) & 0xaaaaaaaa); + i = ((i >> 2) & 0x33333333) | ((i << 2) & 0xcccccccc); + i = ((i >> 4) & 0x0f0f0f0f) | ((i << 4) & 0xf0f0f0f0); + return i; +} + +static void +refreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox) +{ + xf1ScreenPrivateRec *priv; + BoxRec b; + int i, j, start; + pointer src, dst; + priv = pScrn->screen->devPrivates[xf1ScreenPrivateIndex].ptr; + + /* + * this will copy slightly more than each box, because we can't really + * do bit writes. + */ + while (num--) { + b = *pbox; + b.x1 &= ~3; + b.x2 = (b.x2 + 3) & ~3; + for (i = b.y1; i < b.y2; i++) { + start = priv->width * b.y1 / 8; + src = priv->shadow[start]; + dst = priv->fb[start]; + for (j = b.x1; j < b.x2; j++) + dst[j] = flip_word(src[j]); + } + pbox++; + } +} + +static Bool +xf1bppCloseScreen(int index, ScreenPtr pScreen) +{ + xf1ScreenPrivateRec *priv; + CloseScreenProcPtr CloseScreen; + + if (!xf1ScreenPrivateIndex) + return TRUE; + + priv = devPrivates[xf1ScreenPrivateIndex].ptr; + if (priv) { + CloseScreen = priv->CloseScreen; + if (priv->shadow) + xfree(priv->shadow); + xfree(priv); + if (CloseScreen) + return CloseScreen(index, pScreen); + } + + return TRUE; +} + +_X_EXPORT Bool +xf1bppScreenInit(ScreenPtr pScreen, pointer pbits, int x, int y, + int dpix, int dpiy, int width) +{ + xf1ScreenPrivateRec *priv; + + if (xf1Generation != serverGeneration) { + xf1ScreenPrivateIndex = AllocateScreenPrivateIndex(); + if (xf1ScreenPrivateIndex == -1) + return FALSE; + if (!AllocateScreenPrivate(pScreen, xf1ScreenPrivateIndex, + sizeof(xf1ScreenPrivateRec))) + return FALSE; + xf1Generation = serverGeneration; + } + + priv = pScreen->devPrivates[xf1ScreenPrivateIndex].ptr; + + /* the size here is a WAG */ + if (!(priv->shadow = xnfcalloc((width * y + 7) / 8))) { + xfree(priv); + return FALSE; + } + + if (!xf86LoadSubModule(pScrn, "shadowfb")) { + xfree(priv->shadow); + xfree(priv); + return FALSE; + } + + ShadowFBInit(pScreen, refreshArea); + + priv->fb = pbits; + priv->x = x; + priv->y = y; + priv->width = width; + + priv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = xf1bppCloseScreen; + + if (!fbScreenInit(pScreen, priv->shadow, x, y, xdpi, ydpi, width, 1)) { + xfree(priv->shadow); + xfree(priv); + return FALSE; + } +} Index: xf1bpp.h =================================================================== RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/xf1bpp/xf1bpp.h,v retrieving revision 1.3 diff -u -d -p -r1.3 xf1bpp.h --- xf1bpp.h 24 Aug 2005 11:18:33 -0000 1.3 +++ xf1bpp.h 18 Oct 2005 20:06:40 -0000 @@ -28,10 +28,14 @@ #ifndef __XF1BPP_H__ #define __XF1BPP_H__ -#define MFB_PROTOTYPES_ONLY -#include "mfbmap.h" -#include "mfb.h" -#include "mfbunmap.h" -#undef MFB_PROTOTYPES_ONLY +extern Bool xf1bppScreenInit( + ScreenPtr pScreen, + pointer pbits, + int x, + int y, + int dpix, + int dpiy, + int width +); #endif