From 8bb0616cc2799c2c34448da6337ea8cb9438cda7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 22 Feb 2013 21:10:07 +0100 Subject: [PATCH 01/16] miext/shadow/shpacked.c: Remove unused PickBit() define Signed-off-by: Geert Uytterhoeven Reviewed-by: Keith Packard --- miext/shadow/shpacked.c | 1 - 1 file changed, 1 deletion(-) diff --git a/miext/shadow/shpacked.c b/miext/shadow/shpacked.c index d2b2e5e24..5ef18f86d 100644 --- a/miext/shadow/shpacked.c +++ b/miext/shadow/shpacked.c @@ -98,7 +98,6 @@ shadowUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf) i = width; width -= i; scr += i; -#define PickBit(a,i) (((a) >> (i)) & 1) memcpy(win, sha, i * sizeof(FbBits)); sha += i; } From e7045c9dd208a1afe36526ab21ef15f8b01c8bd2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 23 Feb 2013 20:09:22 +0100 Subject: [PATCH 02/16] test/input: Fix double-aligned test in dix_valuator_alloc() on m68k On m68k, doubles are not 64-bit aligned, just like on i386 and sh. Signed-off-by: Geert Uytterhoeven --- test/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/input.c b/test/input.c index be988a4a3..df20f8235 100644 --- a/test/input.c +++ b/test/input.c @@ -1384,7 +1384,7 @@ dix_valuator_alloc(void) assert(v); assert(v->numAxes == num_axes); -#if !defined(__i386__) && !defined(__sh__) +#if !defined(__i386__) && !defined(__m68k__) && !defined(__sh__) /* must be double-aligned on 64 bit */ assert(((void *) v->axisVal - (void *) v) % sizeof(double) == 0); assert(((void *) v->axes - (void *) v) % sizeof(double) == 0); From b08afbc53c1d583c3913b92e67db44823077b112 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 12 Mar 2013 15:20:00 +0100 Subject: [PATCH 03/16] KDrive: Bail out if screen initialization failed Else we may get a segmentation fault later. Signed-off-by: Geert Uytterhoeven Reviewed-by: Keith Packard --- hw/kdrive/src/kdrive.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c index 7d9bf9ddd..1899a27a9 100644 --- a/hw/kdrive/src/kdrive.c +++ b/hw/kdrive/src/kdrive.c @@ -943,7 +943,8 @@ KdInitScreen(ScreenInfo * pScreenInfo, { KdCardInfo *card = screen->card; - (*card->cfuncs->scrinit) (screen); + if (!(*card->cfuncs->scrinit) (screen)) + FatalError("Screen initialization failed!\n"); if (!card->cfuncs->initAccel) screen->dumb = TRUE; From 5c509c360d97bea78ef461596ab4b7bde69020ac Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 22 Feb 2013 13:21:28 +0100 Subject: [PATCH 04/16] Xfbdev: Make char *fbdevDevicePath const This fixes: hw/kdrive/fbdev/fbdev.c: In function 'fbdevInitialize': hw/kdrive/fbdev/fbdev.c:41:25: warning: assignment discards 'const' qualifier from pointer target type [enabled by default] Signed-off-by: Geert Uytterhoeven Reviewed-by: Keith Packard --- hw/kdrive/fbdev/fbdev.c | 2 +- hw/kdrive/fbdev/fbdev.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index d6fcf1a5f..a8d36c6ac 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -30,7 +30,7 @@ extern int KdTsPhyScreen; -char *fbdevDevicePath = NULL; +const char *fbdevDevicePath = NULL; static Bool fbdevInitialize(KdCardInfo * card, FbdevPriv * priv) diff --git a/hw/kdrive/fbdev/fbdev.h b/hw/kdrive/fbdev/fbdev.h index 0706f4e11..f3f7aeceb 100644 --- a/hw/kdrive/fbdev/fbdev.h +++ b/hw/kdrive/fbdev/fbdev.h @@ -49,7 +49,7 @@ typedef struct _fbdevScrPriv { } FbdevScrPriv; extern KdCardFuncs fbdevFuncs; -extern char *fbdevDevicePath; +extern const char *fbdevDevicePath; Bool fbdevCardInit(KdCardInfo * card); From 1049b32166760bdc00106625e213d31a8fc60bad Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 12 Mar 2013 14:19:25 +0100 Subject: [PATCH 05/16] Xfbdev: Handle unset fix.line_length Older frame buffer devices may not fill in fix.line_length, in which case it must be calculated by the application. Signed-off-by: Geert Uytterhoeven --- hw/kdrive/fbdev/fbdev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index a8d36c6ac..7b29f42cd 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -206,6 +206,10 @@ fbdevScreenInitialize(KdScreenInfo * screen, FbdevScrPriv * scrpriv) depth = priv->var.bits_per_pixel; gray = priv->var.grayscale; + /* Calculate fix.line_length if it's zero */ + if (!priv->fix.line_length) + priv->fix.line_length = (priv->var.xres_virtual * depth + 7) / 8; + switch (priv->fix.visual) { case FB_VISUAL_PSEUDOCOLOR: if (gray) { From 6dfb94a891ed445f47832ba1364fcbf1de018f4a Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 12 Mar 2013 14:16:10 +0100 Subject: [PATCH 06/16] Xfbdev: Add support for monochrome visuals Monochrome supports StaticGray, with hardcoded black and white pixels. Signed-off-by: Geert Uytterhoeven Reviewed-by: Keith Packard --- hw/kdrive/fbdev/fbdev.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index 7b29f42cd..0082575bf 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -211,6 +211,10 @@ fbdevScreenInitialize(KdScreenInfo * screen, FbdevScrPriv * scrpriv) priv->fix.line_length = (priv->var.xres_virtual * depth + 7) / 8; switch (priv->fix.visual) { + case FB_VISUAL_MONO01: + case FB_VISUAL_MONO10: + screen->fb.visuals = (1 << StaticGray); + break; case FB_VISUAL_PSEUDOCOLOR: if (gray) { screen->fb.visuals = (1 << StaticGray); @@ -577,6 +581,26 @@ fbdevCreateColormap(ColormapPtr pmap) xColorItem *pdefs; switch (priv->fix.visual) { + case FB_VISUAL_MONO01: + pScreen->whitePixel = 0; + pScreen->blackPixel = 1; + pmap->red[0].co.local.red = 65535; + pmap->red[0].co.local.green = 65535; + pmap->red[0].co.local.blue = 65535; + pmap->red[1].co.local.red = 0; + pmap->red[1].co.local.green = 0; + pmap->red[1].co.local.blue = 0; + return TRUE; + case FB_VISUAL_MONO10: + pScreen->blackPixel = 0; + pScreen->whitePixel = 1; + pmap->red[0].co.local.red = 0; + pmap->red[0].co.local.green = 0; + pmap->red[0].co.local.blue = 0; + pmap->red[1].co.local.red = 65535; + pmap->red[1].co.local.green = 65535; + pmap->red[1].co.local.blue = 65535; + return TRUE; case FB_VISUAL_STATIC_PSEUDOCOLOR: pVisual = pmap->pVisual; nent = pVisual->ColormapEntries; From 4ee2566c3e420a717be36f79126a14e15edac30f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 12 Mar 2013 18:10:40 +0100 Subject: [PATCH 07/16] Xfbdev: Treat 1 bpp pseudocolor as monochrome miCreateDefColormap() only preallocates black and white pixels if depth > 1. Hence override the visual, so fbdevCreateColormap() takes care of it. Signed-off-by: Geert Uytterhoeven Reviewed-by: Keith Packard --- hw/kdrive/fbdev/fbdev.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index 0082575bf..ebbfeb9ca 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -216,11 +216,13 @@ fbdevScreenInitialize(KdScreenInfo * screen, FbdevScrPriv * scrpriv) screen->fb.visuals = (1 << StaticGray); break; case FB_VISUAL_PSEUDOCOLOR: - if (gray) { - screen->fb.visuals = (1 << StaticGray); + screen->fb.visuals = (1 << StaticGray); + if (priv->var.bits_per_pixel == 1) { + /* Override to monochrome, to have preallocated black/white */ + priv->fix.visual = FB_VISUAL_MONO01; + } else if (gray) { /* could also support GrayScale, but what's the point? */ - } - else { + } else { screen->fb.visuals = ((1 << StaticGray) | (1 << GrayScale) | (1 << StaticColor) | From 87af9ab7d52578b0ea315fc4f8dfd906d19755fb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 10 Mar 2013 17:15:05 +0100 Subject: [PATCH 08/16] Shadow: Add c2p core Add Chunky-to-Planar core functionality, to be used by the Atari and Amiga (interleaved) bitplanes code. Signed-off-by: Geert Uytterhoeven Acked-by: Keith Packard --- miext/shadow/c2p_core.h | 184 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 miext/shadow/c2p_core.h diff --git a/miext/shadow/c2p_core.h b/miext/shadow/c2p_core.h new file mode 100644 index 000000000..252f93ea7 --- /dev/null +++ b/miext/shadow/c2p_core.h @@ -0,0 +1,184 @@ +/* + * Fast C2P (Chunky-to-Planar) Conversion + * + * Copyright (C) 2003-2008 Geert Uytterhoeven + * + * NOTES: + * - This code was inspired by Scout's C2P tutorial + * - It assumes to run on a big endian system + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 Geert Uytterhoeven not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Geert Uytterhoeven makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * GEERT UYTTERHOEVEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL GEERT UYTTERHOEVEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + + + /* + * Basic transpose step + */ + +static inline void _transp(CARD32 d[], unsigned int i1, unsigned int i2, + unsigned int shift, CARD32 mask) +{ + CARD32 t = (d[i1] ^ (d[i2] >> shift)) & mask; + + d[i1] ^= t; + d[i2] ^= t << shift; +} + + +extern void c2p_unsupported(void); + +static inline CARD32 get_mask(unsigned int n) +{ + switch (n) { + case 1: + return 0x55555555; + + case 2: + return 0x33333333; + + case 4: + return 0x0f0f0f0f; + + case 8: + return 0x00ff00ff; + + case 16: + return 0x0000ffff; + } + + c2p_unsupported(); + return 0; +} + + + /* + * Transpose operations on 8 32-bit words + */ + +static inline void transp8(CARD32 d[], unsigned int n, unsigned int m) +{ + CARD32 mask = get_mask(n); + + switch (m) { + case 1: + /* First n x 1 block */ + _transp(d, 0, 1, n, mask); + /* Second n x 1 block */ + _transp(d, 2, 3, n, mask); + /* Third n x 1 block */ + _transp(d, 4, 5, n, mask); + /* Fourth n x 1 block */ + _transp(d, 6, 7, n, mask); + return; + + case 2: + /* First n x 2 block */ + _transp(d, 0, 2, n, mask); + _transp(d, 1, 3, n, mask); + /* Second n x 2 block */ + _transp(d, 4, 6, n, mask); + _transp(d, 5, 7, n, mask); + return; + + case 4: + /* Single n x 4 block */ + _transp(d, 0, 4, n, mask); + _transp(d, 1, 5, n, mask); + _transp(d, 2, 6, n, mask); + _transp(d, 3, 7, n, mask); + return; + } + + c2p_unsupported(); +} + + + /* + * Transpose operations on 4 32-bit words + */ + +static inline void transp4(CARD32 d[], unsigned int n, unsigned int m) +{ + CARD32 mask = get_mask(n); + + switch (m) { + case 1: + /* First n x 1 block */ + _transp(d, 0, 1, n, mask); + /* Second n x 1 block */ + _transp(d, 2, 3, n, mask); + return; + + case 2: + /* Single n x 2 block */ + _transp(d, 0, 2, n, mask); + _transp(d, 1, 3, n, mask); + return; + } + + c2p_unsupported(); +} + + + /* + * Transpose operations on 4 32-bit words (reverse order) + */ + +static inline void transp4x(CARD32 d[], unsigned int n, unsigned int m) +{ + CARD32 mask = get_mask(n); + + switch (m) { + case 2: + /* Single n x 2 block */ + _transp(d, 2, 0, n, mask); + _transp(d, 3, 1, n, mask); + return; + } + + c2p_unsupported(); +} + + + /* + * Transpose operations on 2 32-bit words + */ + +static inline void transp2(CARD32 d[], unsigned int n) +{ + CARD32 mask = get_mask(n); + + /* Single n x 1 block */ + _transp(d, 0, 1, n, mask); + return; +} + + + /* + * Transpose operations on 2 32-bit words (reverse order) + */ + +static inline void transp2x(CARD32 d[], unsigned int n) +{ + CARD32 mask = get_mask(n); + + /* Single n x 1 block */ + _transp(d, 1, 0, n, mask); + return; +} From 3f7506b0fca72b2462b85bc4f613de809ae95859 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 10 Mar 2013 21:01:02 +0100 Subject: [PATCH 09/16] Shadow: Add support for Atari iplan2p4 Add support for Atari-style interleaved bitplanes, with 2 bytes interleave and 4 bits per pixel. Signed-off-by: Geert Uytterhoeven Acked-by: Keith Packard --- miext/shadow/Makefile.am | 1 + miext/shadow/shadow.h | 3 + miext/shadow/shiplan2p4.c | 136 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 140 insertions(+) create mode 100644 miext/shadow/shiplan2p4.c diff --git a/miext/shadow/Makefile.am b/miext/shadow/Makefile.am index 30f7bda96..adb10bfd4 100644 --- a/miext/shadow/Makefile.am +++ b/miext/shadow/Makefile.am @@ -10,6 +10,7 @@ libshadow_la_SOURCES = \ shadow.c \ shadow.h \ shalloc.c \ + shiplan2p4.c \ shpacked.c \ shplanar8.c \ shplanar.c \ diff --git a/miext/shadow/shadow.h b/miext/shadow/shadow.h index 83de22ccc..d62903cb7 100644 --- a/miext/shadow/shadow.h +++ b/miext/shadow/shadow.h @@ -95,6 +95,9 @@ shadowInit(ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window); extern _X_EXPORT void *shadowAlloc(int width, int height, int bpp); +extern _X_EXPORT void + shadowUpdateIplan2p4(ScreenPtr pScreen, shadowBufPtr pBuf); + extern _X_EXPORT void shadowUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf); diff --git a/miext/shadow/shiplan2p4.c b/miext/shadow/shiplan2p4.c new file mode 100644 index 000000000..79ada99a4 --- /dev/null +++ b/miext/shadow/shiplan2p4.c @@ -0,0 +1,136 @@ +/* + * + * Copyright © 2013 Geert Uytterhoeven + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 Geert Uytterhoeven not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Geert Uytterhoeven makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * GEERT UYTTERHOEVEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL GEERT UYTTERHOEVEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Based on shpacked.c, which is Copyright © 2000 Keith Packard + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include +#include "scrnintstr.h" +#include "windowstr.h" +#include +#include "dixfontstr.h" +#include +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" +#include "c2p_core.h" + + + /* + * Perform a full C2P step on 16 4-bit pixels, stored in 2 32-bit words + * containing + * - 16 4-bit chunky pixels on input + * - permutated planar data (2 planes per 32-bit word) on output + */ + +static void c2p_16x4(CARD32 d[2]) +{ + transp2(d, 8); + transp2(d, 2); + transp2x(d, 1); + transp2(d, 16); + transp2(d, 4); + transp2(d, 1); +} + + + /* + * Store a full block of iplan2p4 data after c2p conversion + */ + +static inline void store_iplan2p4(void *dst, const CARD32 d[2]) +{ + CARD32 *p = dst; + + *p++ = d[0]; + *p++ = d[1]; +} + + +void +shadowUpdateIplan2p4(ScreenPtr pScreen, shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + FbBits *shaBase; + CARD16 *shaLine, *sha; + FbStride shaStride; + int scrLine; + _X_UNUSED int shaBpp, shaXoff, shaYoff; + int x, y, w, h; + int i, n; + CARD16 *win; + _X_UNUSED CARD32 winSize; + union { + CARD8 bytes[8]; + CARD32 words[2]; + } d; + + fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, + shaYoff); + shaStride *= sizeof(FbBits) / sizeof(CARD16); + + while (nbox--) { + x = pbox->x1; + y = pbox->y1; + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + + scrLine = (x & -16) / 2; + shaLine = (CARD16 *)shaBase + y * shaStride + scrLine / sizeof(CARD16); + + n = ((x & 15) + w + 15) / 16; /* number of c2p units in scanline */ + + while (h--) { + sha = shaLine; + win = (CARD16 *) (*pBuf->window) (pScreen, + y, + scrLine, + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if (!win) + return; + for (i = 0; i < n; i++) { + memcpy(d.bytes, sha, sizeof(d.bytes)); + c2p_16x4(d.words); + store_iplan2p4(win, d.words); + sha += sizeof(d.bytes) / sizeof(*sha); + win += sizeof(d.bytes) / sizeof(*win); + } + shaLine += shaStride; + y++; + } + pbox++; + } +} From d7181e567d1629c387b834da7eecdf618d14718e Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 10 Mar 2013 17:16:17 +0100 Subject: [PATCH 10/16] Shadow: Add support for Atari iplan2p8 Add support for Atari-style interleaved bitplanes, with 2 bytes interleave and 8 bits per pixel. Signed-off-by: Geert Uytterhoeven Acked-by: Keith Packard --- miext/shadow/Makefile.am | 1 + miext/shadow/shadow.h | 3 + miext/shadow/shiplan2p8.c | 137 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 miext/shadow/shiplan2p8.c diff --git a/miext/shadow/Makefile.am b/miext/shadow/Makefile.am index adb10bfd4..882463e58 100644 --- a/miext/shadow/Makefile.am +++ b/miext/shadow/Makefile.am @@ -11,6 +11,7 @@ libshadow_la_SOURCES = \ shadow.h \ shalloc.c \ shiplan2p4.c \ + shiplan2p8.c \ shpacked.c \ shplanar8.c \ shplanar.c \ diff --git a/miext/shadow/shadow.h b/miext/shadow/shadow.h index d62903cb7..e190cd48f 100644 --- a/miext/shadow/shadow.h +++ b/miext/shadow/shadow.h @@ -98,6 +98,9 @@ extern _X_EXPORT void *shadowAlloc(int width, int height, int bpp); extern _X_EXPORT void shadowUpdateIplan2p4(ScreenPtr pScreen, shadowBufPtr pBuf); +extern _X_EXPORT void + shadowUpdateIplan2p8(ScreenPtr pScreen, shadowBufPtr pBuf); + extern _X_EXPORT void shadowUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf); diff --git a/miext/shadow/shiplan2p8.c b/miext/shadow/shiplan2p8.c new file mode 100644 index 000000000..55762f6d1 --- /dev/null +++ b/miext/shadow/shiplan2p8.c @@ -0,0 +1,137 @@ +/* + * + * Copyright © 2013 Geert Uytterhoeven + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 Geert Uytterhoeven not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Geert Uytterhoeven makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * GEERT UYTTERHOEVEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL GEERT UYTTERHOEVEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Based on shpacked.c, which is Copyright © 2000 Keith Packard + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include +#include "scrnintstr.h" +#include "windowstr.h" +#include +#include "dixfontstr.h" +#include +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" +#include "c2p_core.h" + + + /* + * Perform a full C2P step on 16 8-bit pixels, stored in 4 32-bit words + * containing + * - 16 8-bit chunky pixels on input + * - permutated planar data (2 planes per 32-bit word) on output + */ + +static void c2p_16x8(CARD32 d[4]) +{ + transp4(d, 8, 2); + transp4(d, 1, 2); + transp4x(d, 16, 2); + transp4x(d, 2, 2); + transp4(d, 4, 1); +} + + + /* + * Store a full block of permutated iplan2p8 data after c2p conversion + */ + +static inline void store_iplan2p8(void *dst, const CARD32 d[4]) +{ + CARD32 *p = dst; + + *p++ = d[1]; + *p++ = d[3]; + *p++ = d[0]; + *p++ = d[2]; +} + + +void +shadowUpdateIplan2p8(ScreenPtr pScreen, shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + FbBits *shaBase; + CARD16 *shaLine, *sha; + FbStride shaStride; + int scrLine; + _X_UNUSED int shaBpp, shaXoff, shaYoff; + int x, y, w, h; + int i, n; + CARD16 *win; + _X_UNUSED CARD32 winSize; + union { + CARD8 bytes[16]; + CARD32 words[4]; + } d; + + fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, + shaYoff); + shaStride *= sizeof(FbBits) / sizeof(CARD16); + + while (nbox--) { + x = pbox->x1; + y = pbox->y1; + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + + scrLine = x & -16; + shaLine = (CARD16 *)shaBase + y * shaStride + scrLine / sizeof(CARD16); + + n = ((x & 15) + w + 15) / 16; /* number of c2p units in scanline */ + + while (h--) { + sha = shaLine; + win = (CARD16 *) (*pBuf->window) (pScreen, + y, + scrLine, + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if (!win) + return; + for (i = 0; i < n; i++) { + memcpy(d.bytes, sha, sizeof(d.bytes)); + c2p_16x8(d.words); + store_iplan2p8(win, d.words); + sha += sizeof(d.bytes) / sizeof(*sha); + win += sizeof(d.bytes) / sizeof(*win); + } + shaLine += shaStride; + y++; + } + pbox++; + } +} From a1b8e7f1e6118b611ba9d332b8763ee2b44f550c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 27 Mar 2013 09:37:02 +0100 Subject: [PATCH 11/16] Shadow: Add support for Amiga afb4 Add support for Amiga-style bitplanes, with 4 bits per pixel. Signed-off-by: Geert Uytterhoeven Acked-by: Keith Packard --- miext/shadow/Makefile.am | 1 + miext/shadow/shadow.h | 3 + miext/shadow/shafb4.c | 139 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 miext/shadow/shafb4.c diff --git a/miext/shadow/Makefile.am b/miext/shadow/Makefile.am index 882463e58..d2142ad6d 100644 --- a/miext/shadow/Makefile.am +++ b/miext/shadow/Makefile.am @@ -9,6 +9,7 @@ endif libshadow_la_SOURCES = \ shadow.c \ shadow.h \ + shafb4.c \ shalloc.c \ shiplan2p4.c \ shiplan2p8.c \ diff --git a/miext/shadow/shadow.h b/miext/shadow/shadow.h index e190cd48f..f9ea6c45e 100644 --- a/miext/shadow/shadow.h +++ b/miext/shadow/shadow.h @@ -95,6 +95,9 @@ shadowInit(ScreenPtr pScreen, ShadowUpdateProc update, ShadowWindowProc window); extern _X_EXPORT void *shadowAlloc(int width, int height, int bpp); +extern _X_EXPORT void + shadowUpdateAfb4(ScreenPtr pScreen, shadowBufPtr pBuf); + extern _X_EXPORT void shadowUpdateIplan2p4(ScreenPtr pScreen, shadowBufPtr pBuf); diff --git a/miext/shadow/shafb4.c b/miext/shadow/shafb4.c new file mode 100644 index 000000000..07249323a --- /dev/null +++ b/miext/shadow/shafb4.c @@ -0,0 +1,139 @@ +/* + * + * Copyright © 2013 Geert Uytterhoeven + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 Geert Uytterhoeven not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Geert Uytterhoeven makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * GEERT UYTTERHOEVEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL GEERT UYTTERHOEVEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Based on shpacked.c, which is Copyright © 2000 Keith Packard + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include +#include "scrnintstr.h" +#include "windowstr.h" +#include +#include "dixfontstr.h" +#include +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" +#include "c2p_core.h" + + + /* + * Perform a full C2P step on 32 4-bit pixels, stored in 4 32-bit words + * containing + * - 32 4-bit chunky pixels on input + * - permutated planar data (1 plane per 32-bit word) on output + */ + +static void c2p_32x4(CARD32 d[4]) +{ + transp4(d, 16, 2); + transp4(d, 8, 1); + transp4(d, 4, 2); + transp4(d, 2, 1); + transp4(d, 1, 2); +} + + + /* + * Store a full block of permutated planar data after c2p conversion + */ + +static inline void store_afb4(void *dst, unsigned int stride, + const CARD32 d[4]) +{ + CARD8 *p = dst; + + *(CARD32 *)p = d[3]; p += stride; + *(CARD32 *)p = d[1]; p += stride; + *(CARD32 *)p = d[2]; p += stride; + *(CARD32 *)p = d[0]; p += stride; +} + + +void +shadowUpdateAfb4(ScreenPtr pScreen, shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + FbBits *shaBase; + CARD32 *shaLine, *sha; + FbStride shaStride; + int scrLine; + _X_UNUSED int shaBpp, shaXoff, shaYoff; + int x, y, w, h; + int i, n; + CARD32 *win; + CARD32 off, winStride; + union { + CARD8 bytes[16]; + CARD32 words[4]; + } d; + + fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, + shaYoff); + if (sizeof(FbBits) != sizeof(CARD32)) + shaStride = shaStride * sizeof(FbBits) / sizeof(CARD32); + + while (nbox--) { + x = pbox->x1; + y = pbox->y1; + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + + scrLine = (x & -32) / 2; + shaLine = (CARD32 *)shaBase + y * shaStride + scrLine / sizeof(CARD32); + + off = scrLine / 4; /* byte offset in bitplane scanline */ + n = ((x & 31) + w + 31) / 32; /* number of c2p units in scanline */ + + while (h--) { + sha = shaLine; + win = (CARD32 *) (*pBuf->window) (pScreen, + y, + off, + SHADOW_WINDOW_WRITE, + &winStride, + pBuf->closure); + if (!win) + return; + for (i = 0; i < n; i++) { + memcpy(d.bytes, sha, sizeof(d.bytes)); + c2p_32x4(d.words); + store_afb4(win++, winStride, d.words); + sha += sizeof(d.bytes) / sizeof(*sha); + } + shaLine += shaStride; + y++; + } + pbox++; + } +} From cfd10576812c36f5844805eb95ed1f2d093d1691 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 10 Mar 2013 21:03:44 +0100 Subject: [PATCH 12/16] Shadow: Add support for Amiga afb8 Add support for Amiga-style bitplanes, with 8 bits per pixel. Signed-off-by: Geert Uytterhoeven Acked-by: Keith Packard --- miext/shadow/Makefile.am | 1 + miext/shadow/shadow.h | 3 + miext/shadow/shafb8.c | 143 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 miext/shadow/shafb8.c diff --git a/miext/shadow/Makefile.am b/miext/shadow/Makefile.am index d2142ad6d..1db8a26b4 100644 --- a/miext/shadow/Makefile.am +++ b/miext/shadow/Makefile.am @@ -10,6 +10,7 @@ libshadow_la_SOURCES = \ shadow.c \ shadow.h \ shafb4.c \ + shafb8.c \ shalloc.c \ shiplan2p4.c \ shiplan2p8.c \ diff --git a/miext/shadow/shadow.h b/miext/shadow/shadow.h index f9ea6c45e..421ae96a6 100644 --- a/miext/shadow/shadow.h +++ b/miext/shadow/shadow.h @@ -98,6 +98,9 @@ extern _X_EXPORT void *shadowAlloc(int width, int height, int bpp); extern _X_EXPORT void shadowUpdateAfb4(ScreenPtr pScreen, shadowBufPtr pBuf); +extern _X_EXPORT void + shadowUpdateAfb8(ScreenPtr pScreen, shadowBufPtr pBuf); + extern _X_EXPORT void shadowUpdateIplan2p4(ScreenPtr pScreen, shadowBufPtr pBuf); diff --git a/miext/shadow/shafb8.c b/miext/shadow/shafb8.c new file mode 100644 index 000000000..0835e1650 --- /dev/null +++ b/miext/shadow/shafb8.c @@ -0,0 +1,143 @@ +/* + * + * Copyright © 2013 Geert Uytterhoeven + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, 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 Geert Uytterhoeven not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Geert Uytterhoeven makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * GEERT UYTTERHOEVEN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL GEERT UYTTERHOEVEN BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + * + * Based on shpacked.c, which is Copyright © 2000 Keith Packard + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include +#include "scrnintstr.h" +#include "windowstr.h" +#include +#include "dixfontstr.h" +#include +#include "mi.h" +#include "regionstr.h" +#include "globals.h" +#include "gcstruct.h" +#include "shadow.h" +#include "fb.h" +#include "c2p_core.h" + + + /* + * Perform a full C2P step on 32 8-bit pixels, stored in 8 32-bit words + * containing + * - 32 8-bit chunky pixels on input + * - permutated planar data (1 plane per 32-bit word) on output + */ + +static void c2p_32x8(CARD32 d[8]) +{ + transp8(d, 16, 4); + transp8(d, 8, 2); + transp8(d, 4, 1); + transp8(d, 2, 4); + transp8(d, 1, 2); +} + + + /* + * Store a full block of permutated planar data after c2p conversion + */ + +static inline void store_afb8(void *dst, unsigned int stride, + const CARD32 d[8]) +{ + CARD8 *p = dst; + + *(CARD32 *)p = d[7]; p += stride; + *(CARD32 *)p = d[5]; p += stride; + *(CARD32 *)p = d[3]; p += stride; + *(CARD32 *)p = d[1]; p += stride; + *(CARD32 *)p = d[6]; p += stride; + *(CARD32 *)p = d[4]; p += stride; + *(CARD32 *)p = d[2]; p += stride; + *(CARD32 *)p = d[0]; p += stride; +} + + +void +shadowUpdateAfb8(ScreenPtr pScreen, shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = RegionNumRects(damage); + BoxPtr pbox = RegionRects(damage); + FbBits *shaBase; + CARD32 *shaLine, *sha; + FbStride shaStride; + int scrLine; + _X_UNUSED int shaBpp, shaXoff, shaYoff; + int x, y, w, h; + int i, n; + CARD32 *win; + CARD32 off, winStride; + union { + CARD8 bytes[32]; + CARD32 words[8]; + } d; + + fbGetDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, + shaYoff); + if (sizeof(FbBits) != sizeof(CARD32)) + shaStride = shaStride * sizeof(FbBits) / sizeof(CARD32); + + while (nbox--) { + x = pbox->x1; + y = pbox->y1; + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + + scrLine = x & -32; + shaLine = (CARD32 *)shaBase + y * shaStride + scrLine / sizeof(CARD32); + + off = scrLine / 8; /* byte offset in bitplane scanline */ + n = ((x & 31) + w + 31) / 32; /* number of c2p units in scanline */ + + while (h--) { + sha = shaLine; + win = (CARD32 *) (*pBuf->window) (pScreen, + y, + off, + SHADOW_WINDOW_WRITE, + &winStride, + pBuf->closure); + if (!win) + return; + for (i = 0; i < n; i++) { + memcpy(d.bytes, sha, sizeof(d.bytes)); + c2p_32x8(d.words); + store_afb8(win++, winStride, d.words); + sha += sizeof(d.bytes) / sizeof(*sha); + } + shaLine += shaStride; + y++; + } + pbox++; + } +} From 0e808110df216649e05503baecd06cd5a3e50421 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 10 Mar 2013 17:17:26 +0100 Subject: [PATCH 13/16] Xfbdev: Reject unsupported frame buffer types Signed-off-by: Geert Uytterhoeven Reviewed-by: Keith Packard --- hw/kdrive/fbdev/fbdev.c | 75 +++++++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index ebbfeb9ca..f31635d29 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -402,33 +402,58 @@ fbdevSetShadow(ScreenPtr pScreen) window = fbdevWindowLinear; update = 0; - if (scrpriv->randr) - if (priv->var.bits_per_pixel == 16) { - switch (scrpriv->randr) { - case RR_Rotate_90: - if (useYX) - update = shadowUpdateRotate16_90YX; - else - update = shadowUpdateRotate16_90; - break; - case RR_Rotate_180: - update = shadowUpdateRotate16_180; - break; - case RR_Rotate_270: - if (useYX) - update = shadowUpdateRotate16_270YX; - else - update = shadowUpdateRotate16_270; - break; - default: - update = shadowUpdateRotate16; - break; + switch (priv->fix.type) { + case FB_TYPE_PACKED_PIXELS: + if (scrpriv->randr) + if (priv->var.bits_per_pixel == 16) { + switch (scrpriv->randr) { + case RR_Rotate_90: + if (useYX) + update = shadowUpdateRotate16_90YX; + else + update = shadowUpdateRotate16_90; + break; + case RR_Rotate_180: + update = shadowUpdateRotate16_180; + break; + case RR_Rotate_270: + if (useYX) + update = shadowUpdateRotate16_270YX; + else + update = shadowUpdateRotate16_270; + break; + default: + update = shadowUpdateRotate16; + break; + } } - } + else + update = shadowUpdateRotatePacked; else - update = shadowUpdateRotatePacked; - else - update = shadowUpdatePacked; + update = shadowUpdatePacked; + break; + + case FB_TYPE_PLANES: + FatalError("Bitplanes are not yet supported\n"); + break; + + case FB_TYPE_INTERLEAVED_PLANES: + FatalError("Interleaved bitplanes are not yet supported\n"); + break; + + case FB_TYPE_TEXT: + FatalError("Text frame buffers are not yet supported\n"); + break; + + case FB_TYPE_VGA_PLANES: + FatalError("VGA planes are not yet supported\n"); + break; + + default: + FatalError("Unsupported frame buffer type %u\n", priv->fix.type); + break; + } + return KdShadowSet(pScreen, scrpriv->randr, update, window); } From 95a3c7536c1a4afe97aaf955980034cc69af9c2f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 10 Mar 2013 17:17:26 +0100 Subject: [PATCH 14/16] Xfbdev: Force shadowfb for frame buffers with non-packed pixels Signed-off-by: Geert Uytterhoeven Reviewed-by: Keith Packard --- hw/kdrive/fbdev/fbdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index f31635d29..52dfbf5ba 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -326,7 +326,8 @@ fbdevMapFramebuffer(KdScreenInfo * screen) KdPointerMatrix m; FbdevPriv *priv = screen->card->driver; - if (scrpriv->randr != RR_Rotate_0) + if (scrpriv->randr != RR_Rotate_0 || + priv->fix.type != FB_TYPE_PACKED_PIXELS) scrpriv->shadow = TRUE; else scrpriv->shadow = FALSE; From 672bc5bb38918304cf68114a1112cd48651a5e83 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 10 Mar 2013 17:17:26 +0100 Subject: [PATCH 15/16] Xfbdev: Wire up Atari iplan2p4 and iplan2p8 support Add support for Atari-style interleaved bitplanes, with 2 bytes interleave and 4 or 8 bits per pixel. Signed-off-by: Geert Uytterhoeven Reviewed-by: Keith Packard --- hw/kdrive/fbdev/fbdev.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index 52dfbf5ba..40747fe8b 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -439,7 +439,24 @@ fbdevSetShadow(ScreenPtr pScreen) break; case FB_TYPE_INTERLEAVED_PLANES: - FatalError("Interleaved bitplanes are not yet supported\n"); + if (priv->fix.type_aux == 2) { + switch (priv->var.bits_per_pixel) { + case 4: + update = shadowUpdateIplan2p4; + break; + + case 8: + update = shadowUpdateIplan2p8; + break; + + default: + FatalError("Atari interleaved bitplanes with bpp %u are not yet supported\n", + priv->var.bits_per_pixel); + } + } else { + FatalError("Interleaved bitplanes with interleave %u are not yet supported\n", + priv->fix.type_aux); + } break; case FB_TYPE_TEXT: From 5ab260317ad3b2aafff31a97df21620db52eacd1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 10 Mar 2013 21:04:19 +0100 Subject: [PATCH 16/16] Xfbdev: Wire up Amiga afb4 and afb8 support Add support for Amiga-style bitplanes, with 4 or 8 bits per pixel. Signed-off-by: Geert Uytterhoeven Acked-by: Keith Packard --- hw/kdrive/fbdev/fbdev.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/hw/kdrive/fbdev/fbdev.c b/hw/kdrive/fbdev/fbdev.c index 40747fe8b..95f64cbef 100644 --- a/hw/kdrive/fbdev/fbdev.c +++ b/hw/kdrive/fbdev/fbdev.c @@ -319,6 +319,21 @@ fbdevWindowLinear(ScreenPtr pScreen, return (CARD8 *) priv->fb + row * priv->fix.line_length + offset; } +static void * +fbdevWindowAfb(ScreenPtr pScreen, + CARD32 row, + CARD32 offset, int mode, CARD32 *size, void *closure) +{ + KdScreenPriv(pScreen); + FbdevPriv *priv = pScreenPriv->card->driver; + + if (!pScreenPriv->enabled) + return 0; + /* offset to next plane */ + *size = priv->var.yres_virtual * priv->fix.line_length; + return (CARD8 *) priv->fb + row * priv->fix.line_length + offset; +} + Bool fbdevMapFramebuffer(KdScreenInfo * screen) { @@ -435,7 +450,20 @@ fbdevSetShadow(ScreenPtr pScreen) break; case FB_TYPE_PLANES: - FatalError("Bitplanes are not yet supported\n"); + window = fbdevWindowAfb; + switch (priv->var.bits_per_pixel) { + case 4: + update = shadowUpdateAfb4; + break; + + case 8: + update = shadowUpdateAfb8; + break; + + default: + FatalError("Bitplanes with bpp %u are not yet supported\n", + priv->var.bits_per_pixel); + } break; case FB_TYPE_INTERLEAVED_PLANES: