1706f2543Smrg
2706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
3706f2543Smrg#include <xorg-config.h>
4706f2543Smrg#endif
5706f2543Smrg
6706f2543Smrg#include <string.h>
7706f2543Smrg
8706f2543Smrg#include "misc.h"
9706f2543Smrg#include "xf86.h"
10706f2543Smrg#include "xf86_OSproc.h"
11706f2543Smrg
12706f2543Smrg#include <X11/X.h>
13706f2543Smrg#include "scrnintstr.h"
14706f2543Smrg#include "pixmapstr.h"
15706f2543Smrg#include "windowstr.h"
16706f2543Smrg#include "xf86str.h"
17706f2543Smrg#include "cursorstr.h"
18706f2543Smrg#include "mi.h"
19706f2543Smrg#include "mipointer.h"
20706f2543Smrg#include "xf86CursorPriv.h"
21706f2543Smrg
22706f2543Smrg#include "servermd.h"
23706f2543Smrg
24706f2543Smrg#if BITMAP_SCANLINE_PAD == 64
25706f2543Smrg
26706f2543Smrg#if 1
27706f2543Smrg/* Cursors might be only 32 wide. Give'em a chance */
28706f2543Smrg#define SCANLINE CARD32
29706f2543Smrg#define CUR_BITMAP_SCANLINE_PAD 32
30706f2543Smrg#define CUR_LOG2_BITMAP_PAD 5
31706f2543Smrg#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
32706f2543Smrg#else
33706f2543Smrg#define SCANLINE CARD64
34706f2543Smrg#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
35706f2543Smrg#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
36706f2543Smrg#define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
37706f2543Smrgstatic CARD64 xf86CARD64ReverseBits(CARD64 w);
38706f2543Smrg
39706f2543Smrgstatic CARD64
40706f2543Smrgxf86CARD64ReverseBits(CARD64 w)
41706f2543Smrg{
42706f2543Smrg  unsigned char *p = (unsigned char *)&w;
43706f2543Smrg
44706f2543Smrg  p[0] = byte_reversed[p[0]];
45706f2543Smrg  p[1] = byte_reversed[p[1]];
46706f2543Smrg  p[2] = byte_reversed[p[2]];
47706f2543Smrg  p[3] = byte_reversed[p[3]];
48706f2543Smrg  p[4] = byte_reversed[p[4]];
49706f2543Smrg  p[5] = byte_reversed[p[5]];
50706f2543Smrg  p[6] = byte_reversed[p[6]];
51706f2543Smrg  p[7] = byte_reversed[p[7]];
52706f2543Smrg
53706f2543Smrg  return w;
54706f2543Smrg}
55706f2543Smrg#endif
56706f2543Smrg
57706f2543Smrg#else
58706f2543Smrg
59706f2543Smrg#define SCANLINE CARD32
60706f2543Smrg#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
61706f2543Smrg#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
62706f2543Smrg#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
63706f2543Smrg
64706f2543Smrg#endif /* BITMAP_SCANLINE_PAD == 64 */
65706f2543Smrg
66706f2543Smrgstatic unsigned char* RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
67706f2543Smrgstatic unsigned char* RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
68706f2543Smrgstatic unsigned char* RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
69706f2543Smrgstatic unsigned char* RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
70706f2543Smrgstatic unsigned char* RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
71706f2543Smrgstatic unsigned char* RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
72706f2543Smrg
73706f2543SmrgBool
74706f2543Smrgxf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
75706f2543Smrg{
76706f2543Smrg    if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
77706f2543Smrg	return FALSE;
78706f2543Smrg
79706f2543Smrg    /* These are required for now */
80706f2543Smrg    if (!infoPtr->SetCursorPosition ||
81706f2543Smrg	!infoPtr->LoadCursorImage ||
82706f2543Smrg	!infoPtr->HideCursor ||
83706f2543Smrg	!infoPtr->ShowCursor ||
84706f2543Smrg	!infoPtr->SetCursorColors)
85706f2543Smrg	return FALSE;
86706f2543Smrg
87706f2543Smrg    if (infoPtr->RealizeCursor) {
88706f2543Smrg	/* Don't overwrite a driver provided Realize Cursor function */
89706f2543Smrg    } else
90706f2543Smrg    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
91706f2543Smrg	infoPtr->RealizeCursor = RealizeCursorInterleave1;
92706f2543Smrg    } else
93706f2543Smrg    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
94706f2543Smrg	infoPtr->RealizeCursor = RealizeCursorInterleave8;
95706f2543Smrg    } else
96706f2543Smrg    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
97706f2543Smrg	infoPtr->RealizeCursor = RealizeCursorInterleave16;
98706f2543Smrg    } else
99706f2543Smrg    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
100706f2543Smrg	infoPtr->RealizeCursor = RealizeCursorInterleave32;
101706f2543Smrg    } else
102706f2543Smrg    if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
103706f2543Smrg	infoPtr->RealizeCursor = RealizeCursorInterleave64;
104706f2543Smrg    } else {    /* not interleaved */
105706f2543Smrg	infoPtr->RealizeCursor = RealizeCursorInterleave0;
106706f2543Smrg    }
107706f2543Smrg
108706f2543Smrg    infoPtr->pScrn = xf86Screens[pScreen->myNum];
109706f2543Smrg
110706f2543Smrg    return TRUE;
111706f2543Smrg}
112706f2543Smrg
113706f2543Smrgvoid
114706f2543Smrgxf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
115706f2543Smrg{
116706f2543Smrg    xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
117706f2543Smrg	&pScreen->devPrivates, xf86CursorScreenKey);
118706f2543Smrg    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
119706f2543Smrg    unsigned char *bits;
120706f2543Smrg
121706f2543Smrg    if (pCurs == NullCursor) {
122706f2543Smrg	(*infoPtr->HideCursor)(infoPtr->pScrn);
123706f2543Smrg	return;
124706f2543Smrg    }
125706f2543Smrg
126706f2543Smrg    bits = dixLookupPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen));
127706f2543Smrg
128706f2543Smrg    x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
129706f2543Smrg    y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
130706f2543Smrg
131706f2543Smrg#ifdef ARGB_CURSOR
132706f2543Smrg    if (!pCurs->bits->argb || !infoPtr->LoadCursorARGB)
133706f2543Smrg#endif
134706f2543Smrg    if (!bits) {
135706f2543Smrg	bits = (*infoPtr->RealizeCursor)(infoPtr, pCurs);
136706f2543Smrg	dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), bits);
137706f2543Smrg    }
138706f2543Smrg
139706f2543Smrg    if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
140706f2543Smrg	(*infoPtr->HideCursor)(infoPtr->pScrn);
141706f2543Smrg
142706f2543Smrg#ifdef ARGB_CURSOR
143706f2543Smrg    if (pCurs->bits->argb && infoPtr->LoadCursorARGB)
144706f2543Smrg	(*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs);
145706f2543Smrg    else
146706f2543Smrg#endif
147706f2543Smrg    if (bits)
148706f2543Smrg	(*infoPtr->LoadCursorImage)(infoPtr->pScrn, bits);
149706f2543Smrg
150706f2543Smrg    xf86RecolorCursor(pScreen, pCurs, 1);
151706f2543Smrg
152706f2543Smrg    (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
153706f2543Smrg
154706f2543Smrg    (*infoPtr->ShowCursor)(infoPtr->pScrn);
155706f2543Smrg}
156706f2543Smrg
157706f2543Smrgvoid
158706f2543Smrgxf86SetTransparentCursor(ScreenPtr pScreen)
159706f2543Smrg{
160706f2543Smrg    xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
161706f2543Smrg	&pScreen->devPrivates, xf86CursorScreenKey);
162706f2543Smrg    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
163706f2543Smrg
164706f2543Smrg    if (!ScreenPriv->transparentData)
165706f2543Smrg	ScreenPriv->transparentData =
166706f2543Smrg	    (*infoPtr->RealizeCursor)(infoPtr, NullCursor);
167706f2543Smrg
168706f2543Smrg    if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
169706f2543Smrg	(*infoPtr->HideCursor)(infoPtr->pScrn);
170706f2543Smrg
171706f2543Smrg    if (ScreenPriv->transparentData)
172706f2543Smrg	(*infoPtr->LoadCursorImage)(infoPtr->pScrn,
173706f2543Smrg				    ScreenPriv->transparentData);
174706f2543Smrg
175706f2543Smrg    (*infoPtr->ShowCursor)(infoPtr->pScrn);
176706f2543Smrg}
177706f2543Smrg
178706f2543Smrgvoid
179706f2543Smrgxf86MoveCursor(ScreenPtr pScreen, int x, int y)
180706f2543Smrg{
181706f2543Smrg    xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
182706f2543Smrg	&pScreen->devPrivates, xf86CursorScreenKey);
183706f2543Smrg    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
184706f2543Smrg
185706f2543Smrg    x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
186706f2543Smrg    y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
187706f2543Smrg
188706f2543Smrg    (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
189706f2543Smrg}
190706f2543Smrg
191706f2543Smrgvoid
192706f2543Smrgxf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
193706f2543Smrg{
194706f2543Smrg    xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
195706f2543Smrg	&pScreen->devPrivates, xf86CursorScreenKey);
196706f2543Smrg    xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
197706f2543Smrg
198706f2543Smrg#ifdef ARGB_CURSOR
199706f2543Smrg    /* recoloring isn't applicable to ARGB cursors and drivers
200706f2543Smrg       shouldn't have to ignore SetCursorColors requests */
201706f2543Smrg    if (pCurs->bits->argb)
202706f2543Smrg        return;
203706f2543Smrg#endif
204706f2543Smrg
205706f2543Smrg    if (ScreenPriv->PalettedCursor) {
206706f2543Smrg	xColorItem sourceColor, maskColor;
207706f2543Smrg	ColormapPtr pmap = ScreenPriv->pInstalledMap;
208706f2543Smrg
209706f2543Smrg	if (!pmap)
210706f2543Smrg	    return;
211706f2543Smrg
212706f2543Smrg	sourceColor.red = pCurs->foreRed;
213706f2543Smrg	sourceColor.green = pCurs->foreGreen;
214706f2543Smrg	sourceColor.blue = pCurs->foreBlue;
215706f2543Smrg	FakeAllocColor(pmap, &sourceColor);
216706f2543Smrg	maskColor.red = pCurs->backRed;
217706f2543Smrg	maskColor.green = pCurs->backGreen;
218706f2543Smrg	maskColor.blue = pCurs->backBlue;
219706f2543Smrg	FakeAllocColor(pmap, &maskColor);
220706f2543Smrg	FakeFreeColor(pmap, sourceColor.pixel);
221706f2543Smrg	FakeFreeColor(pmap, maskColor.pixel);
222706f2543Smrg	(*infoPtr->SetCursorColors)(infoPtr->pScrn,
223706f2543Smrg		maskColor.pixel, sourceColor.pixel);
224706f2543Smrg    } else {    /* Pass colors in 8-8-8 RGB format */
225706f2543Smrg	(*infoPtr->SetCursorColors)(infoPtr->pScrn,
226706f2543Smrg	    (pCurs->backBlue >> 8) |
227706f2543Smrg	    ((pCurs->backGreen >> 8) << 8) |
228706f2543Smrg	    ((pCurs->backRed >> 8) << 16),
229706f2543Smrg	    (pCurs->foreBlue >> 8) |
230706f2543Smrg	    ((pCurs->foreGreen >> 8) << 8) |
231706f2543Smrg	    ((pCurs->foreRed >> 8) << 16)
232706f2543Smrg	);
233706f2543Smrg    }
234706f2543Smrg}
235706f2543Smrg
236706f2543Smrg/* These functions assume that MaxWidth is a multiple of 32 */
237706f2543Smrgstatic unsigned char*
238706f2543SmrgRealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
239706f2543Smrg{
240706f2543Smrg
241706f2543Smrg    SCANLINE *SrcS, *SrcM, *DstS, *DstM;
242706f2543Smrg    SCANLINE *pSrc, *pMsk;
243706f2543Smrg    unsigned char *mem;
244706f2543Smrg    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
245706f2543Smrg    int SrcPitch, DstPitch, Pitch, y, x;
246706f2543Smrg    /* how many words are in the source or mask */
247706f2543Smrg    int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);
248706f2543Smrg
249706f2543Smrg
250706f2543Smrg    if (!(mem = calloc(1, size)))
251706f2543Smrg	return NULL;
252706f2543Smrg
253706f2543Smrg    if (pCurs == NullCursor) {
254706f2543Smrg	if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
255706f2543Smrg	    DstM = (SCANLINE*)mem;
256706f2543Smrg	    if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
257706f2543Smrg		DstM += words;
258706f2543Smrg	    memset(DstM, -1, words * sizeof(SCANLINE));
259706f2543Smrg	}
260706f2543Smrg	return mem;
261706f2543Smrg    }
262706f2543Smrg
263706f2543Smrg    /* SrcPitch == the number of scanlines wide the cursor image is */
264706f2543Smrg    SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
265706f2543Smrg      CUR_LOG2_BITMAP_PAD;
266706f2543Smrg
267706f2543Smrg    /* DstPitch is the width of the hw cursor in scanlines */
268706f2543Smrg    DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
269706f2543Smrg    Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;
270706f2543Smrg
271706f2543Smrg    SrcS = (SCANLINE*)pCurs->bits->source;
272706f2543Smrg    SrcM = (SCANLINE*)pCurs->bits->mask;
273706f2543Smrg    DstS = (SCANLINE*)mem;
274706f2543Smrg    DstM = DstS + words;
275706f2543Smrg
276706f2543Smrg    if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
277706f2543Smrg	SCANLINE *tmp;
278706f2543Smrg	tmp = DstS; DstS = DstM; DstM = tmp;
279706f2543Smrg    }
280706f2543Smrg
281706f2543Smrg    if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
282706f2543Smrg	for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
283706f2543Smrg	    y--;
284706f2543Smrg	    pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
285706f2543Smrg	    for(x = 0; x < Pitch; x++) {
286706f2543Smrg		pSrc[x] = SrcS[x] & SrcM[x];
287706f2543Smrg		pMsk[x] = SrcM[x];
288706f2543Smrg	    }
289706f2543Smrg	}
290706f2543Smrg    } else {
291706f2543Smrg	for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
292706f2543Smrg	    y--;
293706f2543Smrg	    pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
294706f2543Smrg	    for(x = 0; x < Pitch; x++) {
295706f2543Smrg		pSrc[x] = SrcS[x];
296706f2543Smrg		pMsk[x] = SrcM[x];
297706f2543Smrg	    }
298706f2543Smrg	}
299706f2543Smrg    }
300706f2543Smrg
301706f2543Smrg    if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
302706f2543Smrg	int count = size;
303706f2543Smrg	unsigned char* pntr1 = (unsigned char *)DstS;
304706f2543Smrg	unsigned char* pntr2 = (unsigned char *)DstM;
305706f2543Smrg	unsigned char a, b;
306706f2543Smrg	while (count) {
307706f2543Smrg
308706f2543Smrg	   a = *pntr1;
309706f2543Smrg	   b = *pntr2;
310706f2543Smrg	   *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
311706f2543Smrg	   *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
312706f2543Smrg	   pntr1++; pntr2++;
313706f2543Smrg	   count-=2;
314706f2543Smrg	}
315706f2543Smrg    }
316706f2543Smrg
317706f2543Smrg    /*
318706f2543Smrg     * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
319706f2543Smrg     * out entire source mask.
320706f2543Smrg     */
321706f2543Smrg    if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
322706f2543Smrg	int count = words;
323706f2543Smrg	SCANLINE* pntr = DstM;
324706f2543Smrg	while (count--) {
325706f2543Smrg	   *pntr = ~(*pntr);
326706f2543Smrg	    pntr++;
327706f2543Smrg	}
328706f2543Smrg    }
329706f2543Smrg
330706f2543Smrg    if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
331706f2543Smrg	for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
332706f2543Smrg	    y--;
333706f2543Smrg	    pSrc+=DstPitch, pMsk+=DstPitch) {
334706f2543Smrg	    for(x = 0; x < Pitch; x++) {
335706f2543Smrg		pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
336706f2543Smrg		pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
337706f2543Smrg	    }
338706f2543Smrg	}
339706f2543Smrg    }
340706f2543Smrg
341706f2543Smrg    return mem;
342706f2543Smrg}
343706f2543Smrg
344706f2543Smrgstatic unsigned char*
345706f2543SmrgRealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
346706f2543Smrg{
347706f2543Smrg    unsigned char *DstS, *DstM;
348706f2543Smrg    unsigned char *pntr;
349706f2543Smrg    unsigned char *mem, *mem2;
350706f2543Smrg    int count;
351706f2543Smrg    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
352706f2543Smrg
353706f2543Smrg    /* Realize the cursor without interleaving */
354706f2543Smrg    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
355706f2543Smrg	return NULL;
356706f2543Smrg
357706f2543Smrg    if (!(mem = calloc(1, size))) {
358706f2543Smrg	free(mem2);
359706f2543Smrg	return NULL;
360706f2543Smrg    }
361706f2543Smrg
362706f2543Smrg     /* 1 bit interleave */
363706f2543Smrg    DstS = mem2;
364706f2543Smrg    DstM = DstS + (size >> 1);
365706f2543Smrg    pntr = mem;
366706f2543Smrg    count = size;
367706f2543Smrg    while (count) {
368706f2543Smrg	*pntr++ = ((*DstS&0x01)     ) | ((*DstM&0x01) << 1) |
369706f2543Smrg		  ((*DstS&0x02) << 1) | ((*DstM&0x02) << 2) |
370706f2543Smrg		  ((*DstS&0x04) << 2) | ((*DstM&0x04) << 3) |
371706f2543Smrg		  ((*DstS&0x08) << 3) | ((*DstM&0x08) << 4);
372706f2543Smrg	*pntr++ = ((*DstS&0x10) >> 4) | ((*DstM&0x10) >> 3) |
373706f2543Smrg		  ((*DstS&0x20) >> 3) | ((*DstM&0x20) >> 2) |
374706f2543Smrg		  ((*DstS&0x40) >> 2) | ((*DstM&0x40) >> 1) |
375706f2543Smrg		  ((*DstS&0x80) >> 1) | ((*DstM&0x80)     );
376706f2543Smrg	DstS++;
377706f2543Smrg	DstM++;
378706f2543Smrg	count-=2;
379706f2543Smrg    }
380706f2543Smrg
381706f2543Smrg    /* Free the uninterleaved cursor */
382706f2543Smrg    free(mem2);
383706f2543Smrg
384706f2543Smrg    return mem;
385706f2543Smrg}
386706f2543Smrg
387706f2543Smrgstatic unsigned char*
388706f2543SmrgRealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
389706f2543Smrg{
390706f2543Smrg    unsigned char *DstS, *DstM;
391706f2543Smrg    unsigned char *pntr;
392706f2543Smrg    unsigned char *mem, *mem2;
393706f2543Smrg    int count;
394706f2543Smrg    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
395706f2543Smrg
396706f2543Smrg    /* Realize the cursor without interleaving */
397706f2543Smrg    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
398706f2543Smrg	return NULL;
399706f2543Smrg
400706f2543Smrg    if (!(mem = calloc(1, size))) {
401706f2543Smrg	free(mem2);
402706f2543Smrg	return NULL;
403706f2543Smrg    }
404706f2543Smrg
405706f2543Smrg    /* 8 bit interleave */
406706f2543Smrg    DstS = mem2;
407706f2543Smrg    DstM = DstS + (size >> 1);
408706f2543Smrg    pntr = mem;
409706f2543Smrg    count = size;
410706f2543Smrg    while (count) {
411706f2543Smrg	*pntr++ = *DstS++;
412706f2543Smrg	*pntr++ = *DstM++;
413706f2543Smrg	count-=2;
414706f2543Smrg    }
415706f2543Smrg
416706f2543Smrg    /* Free the uninterleaved cursor */
417706f2543Smrg    free(mem2);
418706f2543Smrg
419706f2543Smrg    return mem;
420706f2543Smrg}
421706f2543Smrg
422706f2543Smrgstatic unsigned char*
423706f2543SmrgRealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
424706f2543Smrg{
425706f2543Smrg    unsigned short *DstS, *DstM;
426706f2543Smrg    unsigned short *pntr;
427706f2543Smrg    unsigned char *mem, *mem2;
428706f2543Smrg    int count;
429706f2543Smrg    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
430706f2543Smrg
431706f2543Smrg    /* Realize the cursor without interleaving */
432706f2543Smrg    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
433706f2543Smrg	return NULL;
434706f2543Smrg
435706f2543Smrg    if (!(mem = calloc(1, size))) {
436706f2543Smrg	free(mem2);
437706f2543Smrg	return NULL;
438706f2543Smrg    }
439706f2543Smrg
440706f2543Smrg    /* 16 bit interleave */
441706f2543Smrg    DstS = (pointer)mem2;
442706f2543Smrg    DstM = DstS + (size >> 2);
443706f2543Smrg    pntr = (pointer)mem;
444706f2543Smrg    count = (size >> 1);
445706f2543Smrg    while (count) {
446706f2543Smrg	*pntr++ = *DstS++;
447706f2543Smrg	*pntr++ = *DstM++;
448706f2543Smrg	count-=2;
449706f2543Smrg    }
450706f2543Smrg
451706f2543Smrg    /* Free the uninterleaved cursor */
452706f2543Smrg    free(mem2);
453706f2543Smrg
454706f2543Smrg    return mem;
455706f2543Smrg}
456706f2543Smrg
457706f2543Smrgstatic unsigned char*
458706f2543SmrgRealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
459706f2543Smrg{
460706f2543Smrg    CARD32 *DstS, *DstM;
461706f2543Smrg    CARD32 *pntr;
462706f2543Smrg    unsigned char *mem, *mem2;
463706f2543Smrg    int count;
464706f2543Smrg    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
465706f2543Smrg
466706f2543Smrg    /* Realize the cursor without interleaving */
467706f2543Smrg    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
468706f2543Smrg	return NULL;
469706f2543Smrg
470706f2543Smrg    if (!(mem = calloc(1, size))) {
471706f2543Smrg	free(mem2);
472706f2543Smrg	return NULL;
473706f2543Smrg    }
474706f2543Smrg
475706f2543Smrg    /* 32 bit interleave */
476706f2543Smrg    DstS = (pointer)mem2;
477706f2543Smrg    DstM = DstS + (size >> 3);
478706f2543Smrg    pntr = (pointer)mem;
479706f2543Smrg    count = (size >> 2);
480706f2543Smrg    while (count) {
481706f2543Smrg	*pntr++ = *DstS++;
482706f2543Smrg	*pntr++ = *DstM++;
483706f2543Smrg	count-=2;
484706f2543Smrg    }
485706f2543Smrg
486706f2543Smrg    /* Free the uninterleaved cursor */
487706f2543Smrg    free(mem2);
488706f2543Smrg
489706f2543Smrg    return mem;
490706f2543Smrg}
491706f2543Smrg
492706f2543Smrgstatic unsigned char*
493706f2543SmrgRealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
494706f2543Smrg{
495706f2543Smrg    CARD32 *DstS, *DstM;
496706f2543Smrg    CARD32 *pntr;
497706f2543Smrg    unsigned char *mem, *mem2;
498706f2543Smrg    int count;
499706f2543Smrg    int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
500706f2543Smrg
501706f2543Smrg    /* Realize the cursor without interleaving */
502706f2543Smrg    if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
503706f2543Smrg	return NULL;
504706f2543Smrg
505706f2543Smrg    if (!(mem = calloc(1, size))) {
506706f2543Smrg	free(mem2);
507706f2543Smrg	return NULL;
508706f2543Smrg    }
509706f2543Smrg
510706f2543Smrg    /* 64 bit interleave */
511706f2543Smrg    DstS = (pointer)mem2;
512706f2543Smrg    DstM = DstS + (size >> 3);
513706f2543Smrg    pntr = (pointer)mem;
514706f2543Smrg    count = (size >> 2);
515706f2543Smrg    while (count) {
516706f2543Smrg	*pntr++ = *DstS++;
517706f2543Smrg	*pntr++ = *DstS++;
518706f2543Smrg	*pntr++ = *DstM++;
519706f2543Smrg	*pntr++ = *DstM++;
520706f2543Smrg	count-=4;
521706f2543Smrg    }
522706f2543Smrg
523706f2543Smrg    /* Free the uninterleaved cursor */
524706f2543Smrg    free(mem2);
525706f2543Smrg
526706f2543Smrg    return mem;
527706f2543Smrg}
528