First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / ramdac / xf86HWCurs.c
blob91caea0479aa64092c7703b74bf1ea935385f412
2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
4 #endif
6 #include <string.h>
8 #include "misc.h"
9 #include "xf86.h"
10 #include "xf86_OSproc.h"
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 "xf86CursorPriv.h"
22 #include "servermd.h"
24 #if BITMAP_SCANLINE_PAD == 64
26 #if 1
27 /* Cursors might be only 32 wide. Give'em a chance */
28 #define SCANLINE CARD32
29 #define CUR_BITMAP_SCANLINE_PAD 32
30 #define CUR_LOG2_BITMAP_PAD 5
31 #define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
32 #else
33 #define SCANLINE CARD64
34 #define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
35 #define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
36 #define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
37 static CARD64 xf86CARD64ReverseBits(CARD64 w);
39 static CARD64
40 xf86CARD64ReverseBits(CARD64 w)
42 unsigned char *p = (unsigned char *)&w;
44 p[0] = byte_reversed[p[0]];
45 p[1] = byte_reversed[p[1]];
46 p[2] = byte_reversed[p[2]];
47 p[3] = byte_reversed[p[3]];
48 p[4] = byte_reversed[p[4]];
49 p[5] = byte_reversed[p[5]];
50 p[6] = byte_reversed[p[6]];
51 p[7] = byte_reversed[p[7]];
53 return w;
55 #endif
57 #else
59 #define SCANLINE CARD32
60 #define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
61 #define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
62 #define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
64 #endif /* BITMAP_SCANLINE_PAD == 64 */
66 static unsigned char* RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
67 static unsigned char* RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
68 static unsigned char* RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
69 static unsigned char* RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
70 static unsigned char* RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
71 static unsigned char* RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
73 Bool
74 xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
76 if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
77 return FALSE;
79 /* These are required for now */
80 if (!infoPtr->SetCursorPosition ||
81 !infoPtr->LoadCursorImage ||
82 !infoPtr->HideCursor ||
83 !infoPtr->ShowCursor ||
84 !infoPtr->SetCursorColors)
85 return FALSE;
87 if (infoPtr->RealizeCursor) {
88 /* Don't overwrite a driver provided Realize Cursor function */
89 } else
90 if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
91 infoPtr->RealizeCursor = RealizeCursorInterleave1;
92 } else
93 if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
94 infoPtr->RealizeCursor = RealizeCursorInterleave8;
95 } else
96 if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
97 infoPtr->RealizeCursor = RealizeCursorInterleave16;
98 } else
99 if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
100 infoPtr->RealizeCursor = RealizeCursorInterleave32;
101 } else
102 if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
103 infoPtr->RealizeCursor = RealizeCursorInterleave64;
104 } else { /* not interleaved */
105 infoPtr->RealizeCursor = RealizeCursorInterleave0;
108 infoPtr->pScrn = xf86Screens[pScreen->myNum];
110 return TRUE;
113 void
114 xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
116 xf86CursorScreenPtr ScreenPriv =
117 pScreen->devPrivates[xf86CursorScreenIndex].ptr;
118 xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
119 unsigned char *bits;
121 if (pCurs == NullCursor) {
122 (*infoPtr->HideCursor)(infoPtr->pScrn);
123 return;
126 bits = pCurs->devPriv[pScreen->myNum];
128 x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
129 y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
131 #ifdef ARGB_CURSOR
132 if (!pCurs->bits->argb || !infoPtr->LoadCursorARGB)
133 #endif
134 if (!bits) {
135 bits = (*infoPtr->RealizeCursor)(infoPtr, pCurs);
136 pCurs->devPriv[pScreen->myNum] = bits;
139 if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
140 (*infoPtr->HideCursor)(infoPtr->pScrn);
142 #ifdef ARGB_CURSOR
143 if (pCurs->bits->argb && infoPtr->LoadCursorARGB)
144 (*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs);
145 else
146 #endif
147 if (bits)
148 (*infoPtr->LoadCursorImage)(infoPtr->pScrn, bits);
150 xf86RecolorCursor(pScreen, pCurs, 1);
152 (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
154 (*infoPtr->ShowCursor)(infoPtr->pScrn);
157 void
158 xf86SetTransparentCursor(ScreenPtr pScreen)
160 xf86CursorScreenPtr ScreenPriv =
161 pScreen->devPrivates[xf86CursorScreenIndex].ptr;
162 xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
164 if (!ScreenPriv->transparentData)
165 ScreenPriv->transparentData =
166 (*infoPtr->RealizeCursor)(infoPtr, NullCursor);
168 if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
169 (*infoPtr->HideCursor)(infoPtr->pScrn);
171 if (ScreenPriv->transparentData)
172 (*infoPtr->LoadCursorImage)(infoPtr->pScrn,
173 ScreenPriv->transparentData);
175 (*infoPtr->ShowCursor)(infoPtr->pScrn);
178 void
179 xf86MoveCursor(ScreenPtr pScreen, int x, int y)
181 xf86CursorScreenPtr ScreenPriv =
182 pScreen->devPrivates[xf86CursorScreenIndex].ptr;
183 xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
185 x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
186 y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
188 (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
191 void
192 xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
194 xf86CursorScreenPtr ScreenPriv =
195 pScreen->devPrivates[xf86CursorScreenIndex].ptr;
196 xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
198 #ifdef ARGB_CURSOR
199 /* recoloring isn't applicable to ARGB cursors and drivers
200 shouldn't have to ignore SetCursorColors requests */
201 if (pCurs->bits->argb)
202 return;
203 #endif
205 if (ScreenPriv->PalettedCursor) {
206 xColorItem sourceColor, maskColor;
207 ColormapPtr pmap = ScreenPriv->pInstalledMap;
209 if (!pmap)
210 return;
212 sourceColor.red = pCurs->foreRed;
213 sourceColor.green = pCurs->foreGreen;
214 sourceColor.blue = pCurs->foreBlue;
215 FakeAllocColor(pmap, &sourceColor);
216 maskColor.red = pCurs->backRed;
217 maskColor.green = pCurs->backGreen;
218 maskColor.blue = pCurs->backBlue;
219 FakeAllocColor(pmap, &maskColor);
220 FakeFreeColor(pmap, sourceColor.pixel);
221 FakeFreeColor(pmap, maskColor.pixel);
222 (*infoPtr->SetCursorColors)(infoPtr->pScrn,
223 maskColor.pixel, sourceColor.pixel);
224 } else { /* Pass colors in 8-8-8 RGB format */
225 (*infoPtr->SetCursorColors)(infoPtr->pScrn,
226 (pCurs->backBlue >> 8) |
227 ((pCurs->backGreen >> 8) << 8) |
228 ((pCurs->backRed >> 8) << 16),
229 (pCurs->foreBlue >> 8) |
230 ((pCurs->foreGreen >> 8) << 8) |
231 ((pCurs->foreRed >> 8) << 16)
236 /* These functions assume that MaxWidth is a multiple of 32 */
237 static unsigned char*
238 RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
241 SCANLINE *SrcS, *SrcM, *DstS, *DstM;
242 SCANLINE *pSrc, *pMsk;
243 unsigned char *mem;
244 int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
245 int SrcPitch, DstPitch, Pitch, y, x;
246 /* how many words are in the source or mask */
247 int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);
250 if (!(mem = xcalloc(1, size)))
251 return NULL;
253 if (pCurs == NullCursor) {
254 if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
255 DstM = (SCANLINE*)mem;
256 if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
257 DstM += words;
258 (void)memset(DstM, -1, words * sizeof(SCANLINE));
260 return mem;
263 /* SrcPitch == the number of scanlines wide the cursor image is */
264 SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
265 CUR_LOG2_BITMAP_PAD;
267 /* DstPitch is the width of the hw cursor in scanlines */
268 DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
269 Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;
271 SrcS = (SCANLINE*)pCurs->bits->source;
272 SrcM = (SCANLINE*)pCurs->bits->mask;
273 DstS = (SCANLINE*)mem;
274 DstM = DstS + words;
276 if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
277 SCANLINE *tmp;
278 tmp = DstS; DstS = DstM; DstM = tmp;
281 if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
282 for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
283 y--;
284 pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
285 for(x = 0; x < Pitch; x++) {
286 pSrc[x] = SrcS[x] & SrcM[x];
287 pMsk[x] = SrcM[x];
290 } else {
291 for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
292 y--;
293 pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
294 for(x = 0; x < Pitch; x++) {
295 pSrc[x] = SrcS[x];
296 pMsk[x] = SrcM[x];
301 if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
302 int count = size;
303 unsigned char* pntr1 = (unsigned char *)DstS;
304 unsigned char* pntr2 = (unsigned char *)DstM;
305 unsigned char a, b;
306 while (count) {
308 a = *pntr1;
309 b = *pntr2;
310 *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
311 *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
312 pntr1++; pntr2++;
313 count-=2;
318 * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
319 * out entire source mask.
321 if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
322 int count = words;
323 SCANLINE* pntr = DstM;
324 while (count--) {
325 *pntr = ~(*pntr);
326 pntr++;
330 if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
331 for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
332 y--;
333 pSrc+=DstPitch, pMsk+=DstPitch) {
334 for(x = 0; x < Pitch; x++) {
335 pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
336 pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
341 return mem;
344 static unsigned char*
345 RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
347 unsigned char *DstS, *DstM;
348 unsigned char *pntr;
349 unsigned char *mem, *mem2;
350 int count;
351 int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
353 /* Realize the cursor without interleaving */
354 if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
355 return NULL;
357 if (!(mem = xcalloc(1, size))) {
358 xfree(mem2);
359 return NULL;
362 /* 1 bit interleave */
363 DstS = mem2;
364 DstM = DstS + (size >> 1);
365 pntr = mem;
366 count = size;
367 while (count) {
368 *pntr++ = ((*DstS&0x01) ) | ((*DstM&0x01) << 1) |
369 ((*DstS&0x02) << 1) | ((*DstM&0x02) << 2) |
370 ((*DstS&0x04) << 2) | ((*DstM&0x04) << 3) |
371 ((*DstS&0x08) << 3) | ((*DstM&0x08) << 4);
372 *pntr++ = ((*DstS&0x10) >> 4) | ((*DstM&0x10) >> 3) |
373 ((*DstS&0x20) >> 3) | ((*DstM&0x20) >> 2) |
374 ((*DstS&0x40) >> 2) | ((*DstM&0x40) >> 1) |
375 ((*DstS&0x80) >> 1) | ((*DstM&0x80) );
376 DstS++;
377 DstM++;
378 count-=2;
381 /* Free the uninterleaved cursor */
382 xfree(mem2);
384 return mem;
387 static unsigned char*
388 RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
390 unsigned char *DstS, *DstM;
391 unsigned char *pntr;
392 unsigned char *mem, *mem2;
393 int count;
394 int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
396 /* Realize the cursor without interleaving */
397 if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
398 return NULL;
400 if (!(mem = xcalloc(1, size))) {
401 xfree(mem2);
402 return NULL;
405 /* 8 bit interleave */
406 DstS = mem2;
407 DstM = DstS + (size >> 1);
408 pntr = mem;
409 count = size;
410 while (count) {
411 *pntr++ = *DstS++;
412 *pntr++ = *DstM++;
413 count-=2;
416 /* Free the uninterleaved cursor */
417 xfree(mem2);
419 return mem;
422 static unsigned char*
423 RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
425 unsigned short *DstS, *DstM;
426 unsigned short *pntr;
427 unsigned char *mem, *mem2;
428 int count;
429 int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
431 /* Realize the cursor without interleaving */
432 if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
433 return NULL;
435 if (!(mem = xcalloc(1, size))) {
436 xfree(mem2);
437 return NULL;
440 /* 16 bit interleave */
441 DstS = (pointer)mem2;
442 DstM = DstS + (size >> 2);
443 pntr = (pointer)mem;
444 count = (size >> 1);
445 while (count) {
446 *pntr++ = *DstS++;
447 *pntr++ = *DstM++;
448 count-=2;
451 /* Free the uninterleaved cursor */
452 xfree(mem2);
454 return mem;
457 static unsigned char*
458 RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
460 CARD32 *DstS, *DstM;
461 CARD32 *pntr;
462 unsigned char *mem, *mem2;
463 int count;
464 int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
466 /* Realize the cursor without interleaving */
467 if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
468 return NULL;
470 if (!(mem = xcalloc(1, size))) {
471 xfree(mem2);
472 return NULL;
475 /* 32 bit interleave */
476 DstS = (pointer)mem2;
477 DstM = DstS + (size >> 3);
478 pntr = (pointer)mem;
479 count = (size >> 2);
480 while (count) {
481 *pntr++ = *DstS++;
482 *pntr++ = *DstM++;
483 count-=2;
486 /* Free the uninterleaved cursor */
487 xfree(mem2);
489 return mem;
492 static unsigned char*
493 RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
495 CARD32 *DstS, *DstM;
496 CARD32 *pntr;
497 unsigned char *mem, *mem2;
498 int count;
499 int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
501 /* Realize the cursor without interleaving */
502 if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
503 return NULL;
505 if (!(mem = xcalloc(1, size))) {
506 xfree(mem2);
507 return NULL;
510 /* 64 bit interleave */
511 DstS = (pointer)mem2;
512 DstM = DstS + (size >> 3);
513 pntr = (pointer)mem;
514 count = (size >> 2);
515 while (count) {
516 *pntr++ = *DstS++;
517 *pntr++ = *DstS++;
518 *pntr++ = *DstM++;
519 *pntr++ = *DstM++;
520 count-=4;
523 /* Free the uninterleaved cursor */
524 xfree(mem2);
526 return mem;