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