105b261ecSmrg/*
205b261ecSmrg *
305b261ecSmrg * Copyright © 2000 Keith Packard
405b261ecSmrg *
505b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that
705b261ecSmrg * the above copyright notice appear in all copies and that both that
805b261ecSmrg * copyright notice and this permission notice appear in supporting
905b261ecSmrg * documentation, and that the name of Keith Packard not be used in
1005b261ecSmrg * advertising or publicity pertaining to distribution of the software without
1105b261ecSmrg * specific, written prior permission.  Keith Packard makes no
1205b261ecSmrg * representations about the suitability of this software for any purpose.  It
1305b261ecSmrg * is provided "as is" without express or implied warranty.
1405b261ecSmrg *
1505b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1605b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1705b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1805b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1905b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
2005b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2105b261ecSmrg * PERFORMANCE OF THIS SOFTWARE.
2205b261ecSmrg */
2305b261ecSmrg
2405b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
2505b261ecSmrg#include <dix-config.h>
2605b261ecSmrg#endif
2705b261ecSmrg
2805b261ecSmrg#include <stdlib.h>
2905b261ecSmrg
3005b261ecSmrg#include    <X11/X.h>
3105b261ecSmrg#include    "scrnintstr.h"
3205b261ecSmrg#include    "windowstr.h"
3305b261ecSmrg#include    <X11/fonts/font.h>
3405b261ecSmrg#include    "dixfontstr.h"
3505b261ecSmrg#include    <X11/fonts/fontstruct.h>
3605b261ecSmrg#include    "mi.h"
3705b261ecSmrg#include    "regionstr.h"
3805b261ecSmrg#include    "globals.h"
3905b261ecSmrg#include    "gcstruct.h"
4005b261ecSmrg#include    "shadow.h"
4105b261ecSmrg#include    "fb.h"
4205b261ecSmrg
4305b261ecSmrg/*
4405b261ecSmrg * Expose 8bpp depth 4
4505b261ecSmrg */
4605b261ecSmrg
4705b261ecSmrg/*
4805b261ecSmrg *  32->8 conversion:
4905b261ecSmrg *
5005b261ecSmrg *      7 6 5 4 3 2 1 0
5105b261ecSmrg *      A B C D E F G H
5205b261ecSmrg *
5305b261ecSmrg *      3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
5405b261ecSmrg *      1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
5505b261ecSmrg * m1   D x x x x x x x C x x x x x x x B x x x x x x x A x x x x x x x     sha[0] << (7-(p))
5605b261ecSmrg * m2   x x x x H x x x x x x x G x x x x x x x F x x x x x x x E x x x     sha[1] << (3-(p))
5705b261ecSmrg * m3   D               C               B               A                   m1 & 0x80808080
5805b261ecSmrg * m4           H               G               F               E           m2 & 0x08080808
5905b261ecSmrg * m5   D       H       C       G       B       F       A       E	    m3 | m4
6005b261ecSmrg * m6                     D       H       C       G       B       F         m5 >> 9
6105b261ecSmrg * m7   D       H       C D     G H     B C     F G     A B     E F         m5 | m6
6205b261ecSmrg * m8                                       D       H       C D     G H     m7 >> 18
6305b261ecSmrg * m9   D       H       C D     G H     B C D   F G H   A B C D E F G H     m7 | m8
6405b261ecSmrg */
6505b261ecSmrg
6605b261ecSmrg#define PL_SHIFT    8
6705b261ecSmrg#define PL_UNIT	    (1 << PL_SHIFT)
6805b261ecSmrg#define PL_MASK	    (PL_UNIT - 1)
6905b261ecSmrg
7005b261ecSmrg#if 0
7105b261ecSmrg#define GetBits(p,o,d) { \
7205b261ecSmrg    CARD32	m1,m2,m3,m4,m5,m6,m7,m8; \
7305b261ecSmrg    m1 = sha[o] << (7 - (p)); \
7405b261ecSmrg    m2 = sha[(o)+1] << (3 - (p)); \
7505b261ecSmrg    m3 = m1 & 0x80808080; \
7605b261ecSmrg    m4 = m2 & 0x08080808; \
7705b261ecSmrg    m5 = m3 | m4; \
7805b261ecSmrg    m6 = m5 >> 9; \
7905b261ecSmrg    m7 = m5 | m6; \
8005b261ecSmrg    m8 = m7 >> 18; \
8105b261ecSmrg    d = m7 | m8; \
8205b261ecSmrg}
8305b261ecSmrg#else
8405b261ecSmrg#define GetBits(p,o,d) { \
8505b261ecSmrg    CARD32	m5,m7; \
8605b261ecSmrg    m5 = ((sha[o] << (7 - (p))) & 0x80808080) | ((sha[(o)+1] << (3 - (p))) & 0x08080808); \
8705b261ecSmrg    m7 = m5 | (m5 >> 9); \
8805b261ecSmrg    d = m7 | (m7 >> 18); \
8905b261ecSmrg}
9005b261ecSmrg#endif
9105b261ecSmrg
9205b261ecSmrgvoid
9335c4bbdfSmrgshadowUpdatePlanar4x8(ScreenPtr pScreen, shadowBufPtr pBuf)
9405b261ecSmrg{
951b5d61b8Smrg    RegionPtr damage = DamageRegion(pBuf->pDamage);
9635c4bbdfSmrg    PixmapPtr pShadow = pBuf->pPixmap;
9735c4bbdfSmrg    int nbox = RegionNumRects(damage);
9835c4bbdfSmrg    BoxPtr pbox = RegionRects(damage);
9935c4bbdfSmrg    CARD32 *shaBase, *shaLine, *sha;
10035c4bbdfSmrg    CARD8 s1, s2, s3, s4;
10135c4bbdfSmrg    FbStride shaStride;
10235c4bbdfSmrg    int scrBase, scrLine, scr;
10335c4bbdfSmrg    int shaBpp;
10435c4bbdfSmrg    _X_UNUSED int shaXoff, shaYoff;
10535c4bbdfSmrg    int x, y, w, h, width;
10635c4bbdfSmrg    int i;
10735c4bbdfSmrg    CARD32 *winBase = NULL, *win;
10835c4bbdfSmrg    CARD32 winSize;
10935c4bbdfSmrg    int plane;
11005b261ecSmrg
11135c4bbdfSmrg    fbGetStipDrawable(&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff,
11235c4bbdfSmrg                      shaYoff);
11335c4bbdfSmrg    while (nbox--) {
11435c4bbdfSmrg        x = pbox->x1 * shaBpp;
11535c4bbdfSmrg        y = pbox->y1;
11635c4bbdfSmrg        w = (pbox->x2 - pbox->x1) * shaBpp;
11735c4bbdfSmrg        h = pbox->y2 - pbox->y1;
11805b261ecSmrg
11935c4bbdfSmrg        w = (w + (x & PL_MASK) + PL_MASK) >> PL_SHIFT;
12035c4bbdfSmrg        x &= ~PL_MASK;
12135c4bbdfSmrg
12235c4bbdfSmrg        scrLine = (x >> PL_SHIFT);
12335c4bbdfSmrg        shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
12435c4bbdfSmrg
12535c4bbdfSmrg        while (h--) {
12635c4bbdfSmrg            for (plane = 0; plane < 4; plane++) {
12735c4bbdfSmrg                width = w;
12835c4bbdfSmrg                scr = scrLine;
12935c4bbdfSmrg                sha = shaLine;
13035c4bbdfSmrg                winSize = 0;
13135c4bbdfSmrg                scrBase = 0;
13235c4bbdfSmrg                while (width) {
13335c4bbdfSmrg                    /* how much remains in this window */
13435c4bbdfSmrg                    i = scrBase + winSize - scr;
13535c4bbdfSmrg                    if (i <= 0 || scr < scrBase) {
13635c4bbdfSmrg                        winBase = (CARD32 *) (*pBuf->window) (pScreen,
13735c4bbdfSmrg                                                              y,
13835c4bbdfSmrg                                                              (scr << 4) |
13935c4bbdfSmrg                                                              (plane),
14035c4bbdfSmrg                                                              SHADOW_WINDOW_WRITE,
14135c4bbdfSmrg                                                              &winSize,
14235c4bbdfSmrg                                                              pBuf->closure);
14335c4bbdfSmrg                        if (!winBase)
14435c4bbdfSmrg                            return;
14535c4bbdfSmrg                        winSize >>= 2;
14635c4bbdfSmrg                        scrBase = scr;
14735c4bbdfSmrg                        i = winSize;
14835c4bbdfSmrg                    }
14935c4bbdfSmrg                    win = winBase + (scr - scrBase);
15035c4bbdfSmrg                    if (i > width)
15135c4bbdfSmrg                        i = width;
15235c4bbdfSmrg                    width -= i;
15335c4bbdfSmrg                    scr += i;
15435c4bbdfSmrg
15535c4bbdfSmrg                    while (i--) {
15635c4bbdfSmrg                        GetBits(plane, 0, s1);
15735c4bbdfSmrg                        GetBits(plane, 2, s2);
15835c4bbdfSmrg                        GetBits(plane, 4, s3);
15935c4bbdfSmrg                        GetBits(plane, 6, s4);
16035c4bbdfSmrg                        *win++ = s1 | (s2 << 8) | (s3 << 16) | (s4 << 24);
16135c4bbdfSmrg                        sha += 8;
16235c4bbdfSmrg                    }
16335c4bbdfSmrg                }
16435c4bbdfSmrg            }
16535c4bbdfSmrg            shaLine += shaStride;
16635c4bbdfSmrg            y++;
16735c4bbdfSmrg        }
16835c4bbdfSmrg        pbox++;
16905b261ecSmrg    }
17005b261ecSmrg}
171