xref: /OK3568_Linux_fs/external/xserver/hw/xfree86/ramdac/xf86HWCurs.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 
2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
4 #endif
5 
6 #include <string.h>
7 
8 #include "misc.h"
9 #include "xf86.h"
10 #include "xf86_OSproc.h"
11 
12 #include <X11/X.h>
13 #include "scrnintstr.h"
14 #include "pixmapstr.h"
15 #include "windowstr.h"
16 #include "xf86str.h"
17 #include "cursorstr.h"
18 #include "mi.h"
19 #include "mipointer.h"
20 #include "randrstr.h"
21 #include "xf86CursorPriv.h"
22 
23 #include "servermd.h"
24 
25 static void
26 xf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs);
27 
28 static CARD32
xf86ReverseBitOrder(CARD32 v)29 xf86ReverseBitOrder(CARD32 v)
30 {
31     return (((0x01010101 & v) << 7) | ((0x02020202 & v) << 5) |
32             ((0x04040404 & v) << 3) | ((0x08080808 & v) << 1) |
33             ((0x10101010 & v) >> 1) | ((0x20202020 & v) >> 3) |
34             ((0x40404040 & v) >> 5) | ((0x80808080 & v) >> 7));
35 }
36 
37 #if BITMAP_SCANLINE_PAD == 64
38 
39 #if 1
40 /* Cursors might be only 32 wide. Give'em a chance */
41 #define SCANLINE CARD32
42 #define CUR_BITMAP_SCANLINE_PAD 32
43 #define CUR_LOG2_BITMAP_PAD 5
44 #define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
45 #else
46 #define SCANLINE CARD64
47 #define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
48 #define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
49 #define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
50 static CARD64 xf86CARD64ReverseBits(CARD64 w);
51 
52 static CARD64
xf86CARD64ReverseBits(CARD64 w)53 xf86CARD64ReverseBits(CARD64 w)
54 {
55     unsigned char *p = (unsigned char *) &w;
56 
57     p[0] = byte_reversed[p[0]];
58     p[1] = byte_reversed[p[1]];
59     p[2] = byte_reversed[p[2]];
60     p[3] = byte_reversed[p[3]];
61     p[4] = byte_reversed[p[4]];
62     p[5] = byte_reversed[p[5]];
63     p[6] = byte_reversed[p[6]];
64     p[7] = byte_reversed[p[7]];
65 
66     return w;
67 }
68 #endif
69 
70 #else
71 
72 #define SCANLINE CARD32
73 #define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
74 #define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
75 #define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
76 
77 #endif                          /* BITMAP_SCANLINE_PAD == 64 */
78 
79 static unsigned char *RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
80 static unsigned char *RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
81 static unsigned char *RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
82 static unsigned char *RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
83 static unsigned char *RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
84 static unsigned char *RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
85 
86 Bool
xf86InitHardwareCursor(ScreenPtr pScreen,xf86CursorInfoPtr infoPtr)87 xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
88 {
89     if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
90         return FALSE;
91 
92     /* These are required for now */
93     if (!infoPtr->SetCursorPosition ||
94         !xf86DriverHasLoadCursorImage(infoPtr) ||
95         !infoPtr->HideCursor ||
96         !xf86DriverHasShowCursor(infoPtr) ||
97         !infoPtr->SetCursorColors)
98         return FALSE;
99 
100     if (infoPtr->RealizeCursor) {
101         /* Don't overwrite a driver provided Realize Cursor function */
102     }
103     else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
104         infoPtr->RealizeCursor = RealizeCursorInterleave1;
105     }
106     else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
107         infoPtr->RealizeCursor = RealizeCursorInterleave8;
108     }
109     else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
110         infoPtr->RealizeCursor = RealizeCursorInterleave16;
111     }
112     else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
113         infoPtr->RealizeCursor = RealizeCursorInterleave32;
114     }
115     else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
116         infoPtr->RealizeCursor = RealizeCursorInterleave64;
117     }
118     else {                      /* not interleaved */
119         infoPtr->RealizeCursor = RealizeCursorInterleave0;
120     }
121 
122     infoPtr->pScrn = xf86ScreenToScrn(pScreen);
123 
124     return TRUE;
125 }
126 
127 static Bool
xf86ScreenCheckHWCursor(ScreenPtr pScreen,CursorPtr cursor,xf86CursorInfoPtr infoPtr)128 xf86ScreenCheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
129 {
130     return
131         (cursor->bits->argb && infoPtr->UseHWCursorARGB &&
132          infoPtr->UseHWCursorARGB(pScreen, cursor)) ||
133         (cursor->bits->argb == 0 &&
134          cursor->bits->height <= infoPtr->MaxHeight &&
135          cursor->bits->width <= infoPtr->MaxWidth &&
136          (!infoPtr->UseHWCursor || infoPtr->UseHWCursor(pScreen, cursor)));
137 }
138 
139 Bool
xf86CheckHWCursor(ScreenPtr pScreen,CursorPtr cursor,xf86CursorInfoPtr infoPtr)140 xf86CheckHWCursor(ScreenPtr pScreen, CursorPtr cursor, xf86CursorInfoPtr infoPtr)
141 {
142     ScreenPtr pSlave;
143     Bool use_hw_cursor = TRUE;
144 
145     input_lock();
146 
147     if (!xf86ScreenCheckHWCursor(pScreen, cursor, infoPtr)) {
148         use_hw_cursor = FALSE;
149 	goto unlock;
150     }
151 
152     /* ask each driver consuming a pixmap if it can support HW cursor */
153     xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) {
154         xf86CursorScreenPtr sPriv;
155 
156         if (!RRHasScanoutPixmap(pSlave))
157             continue;
158 
159         sPriv = dixLookupPrivate(&pSlave->devPrivates, xf86CursorScreenKey);
160         if (!sPriv) { /* NULL if Option "SWCursor", possibly other conditions */
161             use_hw_cursor = FALSE;
162 	    break;
163 	}
164 
165         /* FALSE if HWCursor not supported by slave */
166         if (!xf86ScreenCheckHWCursor(pSlave, cursor, sPriv->CursorInfoPtr)) {
167             use_hw_cursor = FALSE;
168 	    break;
169 	}
170     }
171 
172 unlock:
173     input_unlock();
174 
175     return use_hw_cursor;
176 }
177 
178 static Bool
xf86ScreenSetCursor(ScreenPtr pScreen,CursorPtr pCurs,int x,int y)179 xf86ScreenSetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
180 {
181     xf86CursorScreenPtr ScreenPriv =
182         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
183                                                xf86CursorScreenKey);
184 
185     xf86CursorInfoPtr infoPtr;
186     unsigned char *bits;
187 
188     if (!ScreenPriv) { /* NULL if Option "SWCursor" */
189         return (pCurs == NullCursor);
190     }
191 
192     infoPtr = ScreenPriv->CursorInfoPtr;
193 
194     if (pCurs == NullCursor) {
195         (*infoPtr->HideCursor) (infoPtr->pScrn);
196         return TRUE;
197     }
198 
199     /*
200      * Hot plugged GPU's do not have a CursorScreenKey, force sw cursor.
201      * This check can be removed once dix/privates.c gets relocation code for
202      * PRIVATE_CURSOR. Also see the related comment in AddGPUScreen().
203      */
204     if (!_dixGetScreenPrivateKey(CursorScreenKey, pScreen))
205         return FALSE;
206 
207     bits =
208         dixLookupScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen);
209 
210     x -= infoPtr->pScrn->frameX0;
211     y -= infoPtr->pScrn->frameY0;
212 
213     if (!pCurs->bits->argb || !xf86DriverHasLoadCursorARGB(infoPtr))
214         if (!bits) {
215             bits = (*infoPtr->RealizeCursor) (infoPtr, pCurs);
216             dixSetScreenPrivate(&pCurs->devPrivates, CursorScreenKey, pScreen,
217                                 bits);
218         }
219 
220     if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
221         (*infoPtr->HideCursor) (infoPtr->pScrn);
222 
223     if (pCurs->bits->argb && xf86DriverHasLoadCursorARGB(infoPtr)) {
224         if (!xf86DriverLoadCursorARGB (infoPtr, pCurs))
225             return FALSE;
226     } else
227     if (bits)
228         if (!xf86DriverLoadCursorImage (infoPtr, bits))
229             return FALSE;
230 
231     xf86RecolorCursor_locked (ScreenPriv, pCurs);
232 
233     (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
234 
235     return xf86DriverShowCursor(infoPtr);
236 }
237 
238 Bool
xf86SetCursor(ScreenPtr pScreen,CursorPtr pCurs,int x,int y)239 xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
240 {
241     xf86CursorScreenPtr ScreenPriv =
242         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
243                                                xf86CursorScreenKey);
244     ScreenPtr pSlave;
245     Bool ret = FALSE;
246 
247     input_lock();
248 
249     x -= ScreenPriv->HotX;
250     y -= ScreenPriv->HotY;
251 
252     if (!xf86ScreenSetCursor(pScreen, pCurs, x, y))
253         goto out;
254 
255     /* ask each slave driver to set the cursor. */
256     xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) {
257         if (!RRHasScanoutPixmap(pSlave))
258             continue;
259 
260         if (!xf86ScreenSetCursor(pSlave, pCurs, x, y)) {
261             /*
262              * hide the master (and successfully set slave) cursors,
263              * otherwise both the hw and sw cursor will show.
264              */
265             xf86SetCursor(pScreen, NullCursor, x, y);
266             goto out;
267         }
268     }
269     ret = TRUE;
270 
271  out:
272     input_unlock();
273     return ret;
274 }
275 
276 void
xf86SetTransparentCursor(ScreenPtr pScreen)277 xf86SetTransparentCursor(ScreenPtr pScreen)
278 {
279     xf86CursorScreenPtr ScreenPriv =
280         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
281                                                xf86CursorScreenKey);
282     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
283 
284     input_lock();
285 
286     if (!ScreenPriv->transparentData)
287         ScreenPriv->transparentData =
288             (*infoPtr->RealizeCursor) (infoPtr, NullCursor);
289 
290     if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
291         (*infoPtr->HideCursor) (infoPtr->pScrn);
292 
293     if (ScreenPriv->transparentData)
294         xf86DriverLoadCursorImage (infoPtr,
295                                    ScreenPriv->transparentData);
296 
297     xf86DriverShowCursor(infoPtr);
298 
299     input_unlock();
300 }
301 
302 static void
xf86ScreenMoveCursor(ScreenPtr pScreen,int x,int y)303 xf86ScreenMoveCursor(ScreenPtr pScreen, int x, int y)
304 {
305     xf86CursorScreenPtr ScreenPriv =
306         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
307                                                xf86CursorScreenKey);
308     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
309 
310     x -= infoPtr->pScrn->frameX0;
311     y -= infoPtr->pScrn->frameY0;
312 
313     (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y);
314 }
315 
316 void
xf86MoveCursor(ScreenPtr pScreen,int x,int y)317 xf86MoveCursor(ScreenPtr pScreen, int x, int y)
318 {
319     xf86CursorScreenPtr ScreenPriv =
320         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
321                                                xf86CursorScreenKey);
322     ScreenPtr pSlave;
323 
324     input_lock();
325 
326     x -= ScreenPriv->HotX;
327     y -= ScreenPriv->HotY;
328 
329     xf86ScreenMoveCursor(pScreen, x, y);
330 
331     /* ask each slave driver to move the cursor */
332     xorg_list_for_each_entry(pSlave, &pScreen->slave_list, slave_head) {
333         if (!RRHasScanoutPixmap(pSlave))
334             continue;
335 
336         xf86ScreenMoveCursor(pSlave, x, y);
337     }
338 
339     input_unlock();
340 }
341 
342 static void
xf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv,CursorPtr pCurs)343 xf86RecolorCursor_locked(xf86CursorScreenPtr ScreenPriv, CursorPtr pCurs)
344 {
345     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
346 
347     /* recoloring isn't applicable to ARGB cursors and drivers
348        shouldn't have to ignore SetCursorColors requests */
349     if (pCurs->bits->argb)
350         return;
351 
352     if (ScreenPriv->PalettedCursor) {
353         xColorItem sourceColor, maskColor;
354         ColormapPtr pmap = ScreenPriv->pInstalledMap;
355 
356         if (!pmap)
357             return;
358 
359         sourceColor.red = pCurs->foreRed;
360         sourceColor.green = pCurs->foreGreen;
361         sourceColor.blue = pCurs->foreBlue;
362         FakeAllocColor(pmap, &sourceColor);
363         maskColor.red = pCurs->backRed;
364         maskColor.green = pCurs->backGreen;
365         maskColor.blue = pCurs->backBlue;
366         FakeAllocColor(pmap, &maskColor);
367         FakeFreeColor(pmap, sourceColor.pixel);
368         FakeFreeColor(pmap, maskColor.pixel);
369         (*infoPtr->SetCursorColors) (infoPtr->pScrn,
370                                      maskColor.pixel, sourceColor.pixel);
371     }
372     else {                      /* Pass colors in 8-8-8 RGB format */
373         (*infoPtr->SetCursorColors) (infoPtr->pScrn,
374                                      (pCurs->backBlue >> 8) |
375                                      ((pCurs->backGreen >> 8) << 8) |
376                                      ((pCurs->backRed >> 8) << 16),
377                                      (pCurs->foreBlue >> 8) |
378                                      ((pCurs->foreGreen >> 8) << 8) |
379                                      ((pCurs->foreRed >> 8) << 16)
380             );
381     }
382 }
383 
384 void
xf86RecolorCursor(ScreenPtr pScreen,CursorPtr pCurs,Bool displayed)385 xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
386 {
387     xf86CursorScreenPtr ScreenPriv =
388         (xf86CursorScreenPtr) dixLookupPrivate(&pScreen->devPrivates,
389                                                xf86CursorScreenKey);
390 
391     input_lock();
392     xf86RecolorCursor_locked (ScreenPriv, pCurs);
393     input_unlock();
394 }
395 
396 /* These functions assume that MaxWidth is a multiple of 32 */
397 static unsigned char *
RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr,CursorPtr pCurs)398 RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
399 {
400 
401     SCANLINE *SrcS, *SrcM, *DstS, *DstM;
402     SCANLINE *pSrc, *pMsk;
403     unsigned char *mem;
404     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
405     int SrcPitch, DstPitch, Pitch, y, x;
406 
407     /* how many words are in the source or mask */
408     int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);
409 
410     if (!(mem = calloc(1, size)))
411         return NULL;
412 
413     if (pCurs == NullCursor) {
414         if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
415             DstM = (SCANLINE *) mem;
416             if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
417                 DstM += words;
418             memset(DstM, -1, words * sizeof(SCANLINE));
419         }
420         return mem;
421     }
422 
423     /* SrcPitch == the number of scanlines wide the cursor image is */
424     SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
425         CUR_LOG2_BITMAP_PAD;
426 
427     /* DstPitch is the width of the hw cursor in scanlines */
428     DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
429     Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;
430 
431     SrcS = (SCANLINE *) pCurs->bits->source;
432     SrcM = (SCANLINE *) pCurs->bits->mask;
433     DstS = (SCANLINE *) mem;
434     DstM = DstS + words;
435 
436     if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
437         SCANLINE *tmp;
438 
439         tmp = DstS;
440         DstS = DstM;
441         DstM = tmp;
442     }
443 
444     if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
445         for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
446              y--;
447              pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM +=
448              SrcPitch) {
449             for (x = 0; x < Pitch; x++) {
450                 pSrc[x] = SrcS[x] & SrcM[x];
451                 pMsk[x] = SrcM[x];
452             }
453         }
454     }
455     else {
456         for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
457              y--;
458              pSrc += DstPitch, pMsk += DstPitch, SrcS += SrcPitch, SrcM +=
459              SrcPitch) {
460             for (x = 0; x < Pitch; x++) {
461                 pSrc[x] = SrcS[x];
462                 pMsk[x] = SrcM[x];
463             }
464         }
465     }
466 
467     if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
468         int count = size;
469         unsigned char *pntr1 = (unsigned char *) DstS;
470         unsigned char *pntr2 = (unsigned char *) DstM;
471         unsigned char a, b;
472 
473         while (count) {
474 
475             a = *pntr1;
476             b = *pntr2;
477             *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
478             *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
479             pntr1++;
480             pntr2++;
481             count -= 2;
482         }
483     }
484 
485     /*
486      * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
487      * out entire source mask.
488      */
489     if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
490         int count = words;
491         SCANLINE *pntr = DstM;
492 
493         while (count--) {
494             *pntr = ~(*pntr);
495             pntr++;
496         }
497     }
498 
499     if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
500         for (y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
501              y--; pSrc += DstPitch, pMsk += DstPitch) {
502             for (x = 0; x < Pitch; x++) {
503                 pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
504                 pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
505             }
506         }
507     }
508 
509     return mem;
510 }
511 
512 static unsigned char *
RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr,CursorPtr pCurs)513 RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
514 {
515     unsigned char *DstS, *DstM;
516     unsigned char *pntr;
517     unsigned char *mem, *mem2;
518     int count;
519     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
520 
521     /* Realize the cursor without interleaving */
522     if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
523         return NULL;
524 
525     if (!(mem = calloc(1, size))) {
526         free(mem2);
527         return NULL;
528     }
529 
530     /* 1 bit interleave */
531     DstS = mem2;
532     DstM = DstS + (size >> 1);
533     pntr = mem;
534     count = size;
535     while (count) {
536         *pntr++ = ((*DstS & 0x01)) | ((*DstM & 0x01) << 1) |
537             ((*DstS & 0x02) << 1) | ((*DstM & 0x02) << 2) |
538             ((*DstS & 0x04) << 2) | ((*DstM & 0x04) << 3) |
539             ((*DstS & 0x08) << 3) | ((*DstM & 0x08) << 4);
540         *pntr++ = ((*DstS & 0x10) >> 4) | ((*DstM & 0x10) >> 3) |
541             ((*DstS & 0x20) >> 3) | ((*DstM & 0x20) >> 2) |
542             ((*DstS & 0x40) >> 2) | ((*DstM & 0x40) >> 1) |
543             ((*DstS & 0x80) >> 1) | ((*DstM & 0x80));
544         DstS++;
545         DstM++;
546         count -= 2;
547     }
548 
549     /* Free the uninterleaved cursor */
550     free(mem2);
551 
552     return mem;
553 }
554 
555 static unsigned char *
RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr,CursorPtr pCurs)556 RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
557 {
558     unsigned char *DstS, *DstM;
559     unsigned char *pntr;
560     unsigned char *mem, *mem2;
561     int count;
562     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
563 
564     /* Realize the cursor without interleaving */
565     if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
566         return NULL;
567 
568     if (!(mem = calloc(1, size))) {
569         free(mem2);
570         return NULL;
571     }
572 
573     /* 8 bit interleave */
574     DstS = mem2;
575     DstM = DstS + (size >> 1);
576     pntr = mem;
577     count = size;
578     while (count) {
579         *pntr++ = *DstS++;
580         *pntr++ = *DstM++;
581         count -= 2;
582     }
583 
584     /* Free the uninterleaved cursor */
585     free(mem2);
586 
587     return mem;
588 }
589 
590 static unsigned char *
RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr,CursorPtr pCurs)591 RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
592 {
593     unsigned short *DstS, *DstM;
594     unsigned short *pntr;
595     unsigned char *mem, *mem2;
596     int count;
597     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
598 
599     /* Realize the cursor without interleaving */
600     if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
601         return NULL;
602 
603     if (!(mem = calloc(1, size))) {
604         free(mem2);
605         return NULL;
606     }
607 
608     /* 16 bit interleave */
609     DstS = (void *) mem2;
610     DstM = DstS + (size >> 2);
611     pntr = (void *) mem;
612     count = (size >> 1);
613     while (count) {
614         *pntr++ = *DstS++;
615         *pntr++ = *DstM++;
616         count -= 2;
617     }
618 
619     /* Free the uninterleaved cursor */
620     free(mem2);
621 
622     return mem;
623 }
624 
625 static unsigned char *
RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr,CursorPtr pCurs)626 RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
627 {
628     CARD32 *DstS, *DstM;
629     CARD32 *pntr;
630     unsigned char *mem, *mem2;
631     int count;
632     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
633 
634     /* Realize the cursor without interleaving */
635     if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
636         return NULL;
637 
638     if (!(mem = calloc(1, size))) {
639         free(mem2);
640         return NULL;
641     }
642 
643     /* 32 bit interleave */
644     DstS = (void *) mem2;
645     DstM = DstS + (size >> 3);
646     pntr = (void *) mem;
647     count = (size >> 2);
648     while (count) {
649         *pntr++ = *DstS++;
650         *pntr++ = *DstM++;
651         count -= 2;
652     }
653 
654     /* Free the uninterleaved cursor */
655     free(mem2);
656 
657     return mem;
658 }
659 
660 static unsigned char *
RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr,CursorPtr pCurs)661 RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
662 {
663     CARD32 *DstS, *DstM;
664     CARD32 *pntr;
665     unsigned char *mem, *mem2;
666     int count;
667     int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
668 
669     /* Realize the cursor without interleaving */
670     if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
671         return NULL;
672 
673     if (!(mem = calloc(1, size))) {
674         free(mem2);
675         return NULL;
676     }
677 
678     /* 64 bit interleave */
679     DstS = (void *) mem2;
680     DstM = DstS + (size >> 3);
681     pntr = (void *) mem;
682     count = (size >> 2);
683     while (count) {
684         *pntr++ = *DstS++;
685         *pntr++ = *DstS++;
686         *pntr++ = *DstM++;
687         *pntr++ = *DstM++;
688         count -= 4;
689     }
690 
691     /* Free the uninterleaved cursor */
692     free(mem2);
693 
694     return mem;
695 }
696