2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
10 #include "xf86_OSproc.h"
13 #include "scrnintstr.h"
14 #include "pixmapstr.h"
15 #include "windowstr.h"
17 #include "cursorstr.h"
19 #include "mipointer.h"
20 #include "xf86CursorPriv.h"
25 xf86ReverseBitOrder(CARD32 v
)
27 return (((0x01010101 & v
) << 7) | ((0x02020202 & v
) << 5) |
28 ((0x04040404 & v
) << 3) | ((0x08080808 & v
) << 1) |
29 ((0x10101010 & v
) >> 1) | ((0x20202020 & v
) >> 3) |
30 ((0x40404040 & v
) >> 5) | ((0x80808080 & v
) >> 7));
33 #if BITMAP_SCANLINE_PAD == 64
36 /* Cursors might be only 32 wide. Give'em a chance */
37 #define SCANLINE CARD32
38 #define CUR_BITMAP_SCANLINE_PAD 32
39 #define CUR_LOG2_BITMAP_PAD 5
40 #define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
42 #define SCANLINE CARD64
43 #define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
44 #define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
45 #define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
46 static CARD64
xf86CARD64ReverseBits(CARD64 w
);
49 xf86CARD64ReverseBits(CARD64 w
)
51 unsigned char *p
= (unsigned char *) &w
;
53 p
[0] = byte_reversed
[p
[0]];
54 p
[1] = byte_reversed
[p
[1]];
55 p
[2] = byte_reversed
[p
[2]];
56 p
[3] = byte_reversed
[p
[3]];
57 p
[4] = byte_reversed
[p
[4]];
58 p
[5] = byte_reversed
[p
[5]];
59 p
[6] = byte_reversed
[p
[6]];
60 p
[7] = byte_reversed
[p
[7]];
68 #define SCANLINE CARD32
69 #define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
70 #define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
71 #define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
73 #endif /* BITMAP_SCANLINE_PAD == 64 */
75 static unsigned char *RealizeCursorInterleave0(xf86CursorInfoPtr
, CursorPtr
);
76 static unsigned char *RealizeCursorInterleave1(xf86CursorInfoPtr
, CursorPtr
);
77 static unsigned char *RealizeCursorInterleave8(xf86CursorInfoPtr
, CursorPtr
);
78 static unsigned char *RealizeCursorInterleave16(xf86CursorInfoPtr
, CursorPtr
);
79 static unsigned char *RealizeCursorInterleave32(xf86CursorInfoPtr
, CursorPtr
);
80 static unsigned char *RealizeCursorInterleave64(xf86CursorInfoPtr
, CursorPtr
);
83 xf86InitHardwareCursor(ScreenPtr pScreen
, xf86CursorInfoPtr infoPtr
)
85 if ((infoPtr
->MaxWidth
<= 0) || (infoPtr
->MaxHeight
<= 0))
88 /* These are required for now */
89 if (!infoPtr
->SetCursorPosition
||
90 !infoPtr
->LoadCursorImage
||
91 !infoPtr
->HideCursor
||
92 !infoPtr
->ShowCursor
|| !infoPtr
->SetCursorColors
)
95 if (infoPtr
->RealizeCursor
) {
96 /* Don't overwrite a driver provided Realize Cursor function */
98 else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1
& infoPtr
->Flags
) {
99 infoPtr
->RealizeCursor
= RealizeCursorInterleave1
;
101 else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8
& infoPtr
->Flags
) {
102 infoPtr
->RealizeCursor
= RealizeCursorInterleave8
;
104 else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16
& infoPtr
->Flags
) {
105 infoPtr
->RealizeCursor
= RealizeCursorInterleave16
;
107 else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32
& infoPtr
->Flags
) {
108 infoPtr
->RealizeCursor
= RealizeCursorInterleave32
;
110 else if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64
& infoPtr
->Flags
) {
111 infoPtr
->RealizeCursor
= RealizeCursorInterleave64
;
113 else { /* not interleaved */
114 infoPtr
->RealizeCursor
= RealizeCursorInterleave0
;
117 infoPtr
->pScrn
= xf86ScreenToScrn(pScreen
);
123 xf86SetCursor(ScreenPtr pScreen
, CursorPtr pCurs
, int x
, int y
)
125 xf86CursorScreenPtr ScreenPriv
=
126 (xf86CursorScreenPtr
) dixLookupPrivate(&pScreen
->devPrivates
,
127 xf86CursorScreenKey
);
128 xf86CursorInfoPtr infoPtr
= ScreenPriv
->CursorInfoPtr
;
131 if (pCurs
== NullCursor
) {
132 (*infoPtr
->HideCursor
) (infoPtr
->pScrn
);
137 dixLookupScreenPrivate(&pCurs
->devPrivates
, CursorScreenKey
, pScreen
);
139 x
-= infoPtr
->pScrn
->frameX0
+ ScreenPriv
->HotX
;
140 y
-= infoPtr
->pScrn
->frameY0
+ ScreenPriv
->HotY
;
143 if (!pCurs
->bits
->argb
|| !infoPtr
->LoadCursorARGB
)
146 bits
= (*infoPtr
->RealizeCursor
) (infoPtr
, pCurs
);
147 dixSetScreenPrivate(&pCurs
->devPrivates
, CursorScreenKey
, pScreen
,
151 if (!(infoPtr
->Flags
& HARDWARE_CURSOR_UPDATE_UNHIDDEN
))
152 (*infoPtr
->HideCursor
) (infoPtr
->pScrn
);
155 if (pCurs
->bits
->argb
&& infoPtr
->LoadCursorARGB
)
156 (*infoPtr
->LoadCursorARGB
) (infoPtr
->pScrn
, pCurs
);
160 (*infoPtr
->LoadCursorImage
) (infoPtr
->pScrn
, bits
);
162 xf86RecolorCursor(pScreen
, pCurs
, 1);
164 (*infoPtr
->SetCursorPosition
) (infoPtr
->pScrn
, x
, y
);
166 (*infoPtr
->ShowCursor
) (infoPtr
->pScrn
);
170 xf86SetTransparentCursor(ScreenPtr pScreen
)
172 xf86CursorScreenPtr ScreenPriv
=
173 (xf86CursorScreenPtr
) dixLookupPrivate(&pScreen
->devPrivates
,
174 xf86CursorScreenKey
);
175 xf86CursorInfoPtr infoPtr
= ScreenPriv
->CursorInfoPtr
;
177 if (!ScreenPriv
->transparentData
)
178 ScreenPriv
->transparentData
=
179 (*infoPtr
->RealizeCursor
) (infoPtr
, NullCursor
);
181 if (!(infoPtr
->Flags
& HARDWARE_CURSOR_UPDATE_UNHIDDEN
))
182 (*infoPtr
->HideCursor
) (infoPtr
->pScrn
);
184 if (ScreenPriv
->transparentData
)
185 (*infoPtr
->LoadCursorImage
) (infoPtr
->pScrn
,
186 ScreenPriv
->transparentData
);
188 (*infoPtr
->ShowCursor
) (infoPtr
->pScrn
);
192 xf86MoveCursor(ScreenPtr pScreen
, int x
, int y
)
194 xf86CursorScreenPtr ScreenPriv
=
195 (xf86CursorScreenPtr
) dixLookupPrivate(&pScreen
->devPrivates
,
196 xf86CursorScreenKey
);
197 xf86CursorInfoPtr infoPtr
= ScreenPriv
->CursorInfoPtr
;
199 x
-= infoPtr
->pScrn
->frameX0
+ ScreenPriv
->HotX
;
200 y
-= infoPtr
->pScrn
->frameY0
+ ScreenPriv
->HotY
;
202 (*infoPtr
->SetCursorPosition
) (infoPtr
->pScrn
, x
, y
);
206 xf86RecolorCursor(ScreenPtr pScreen
, CursorPtr pCurs
, Bool displayed
)
208 xf86CursorScreenPtr ScreenPriv
=
209 (xf86CursorScreenPtr
) dixLookupPrivate(&pScreen
->devPrivates
,
210 xf86CursorScreenKey
);
211 xf86CursorInfoPtr infoPtr
= ScreenPriv
->CursorInfoPtr
;
214 /* recoloring isn't applicable to ARGB cursors and drivers
215 shouldn't have to ignore SetCursorColors requests */
216 if (pCurs
->bits
->argb
)
220 if (ScreenPriv
->PalettedCursor
) {
221 xColorItem sourceColor
, maskColor
;
222 ColormapPtr pmap
= ScreenPriv
->pInstalledMap
;
227 sourceColor
.red
= pCurs
->foreRed
;
228 sourceColor
.green
= pCurs
->foreGreen
;
229 sourceColor
.blue
= pCurs
->foreBlue
;
230 FakeAllocColor(pmap
, &sourceColor
);
231 maskColor
.red
= pCurs
->backRed
;
232 maskColor
.green
= pCurs
->backGreen
;
233 maskColor
.blue
= pCurs
->backBlue
;
234 FakeAllocColor(pmap
, &maskColor
);
235 FakeFreeColor(pmap
, sourceColor
.pixel
);
236 FakeFreeColor(pmap
, maskColor
.pixel
);
237 (*infoPtr
->SetCursorColors
) (infoPtr
->pScrn
,
238 maskColor
.pixel
, sourceColor
.pixel
);
240 else { /* Pass colors in 8-8-8 RGB format */
241 (*infoPtr
->SetCursorColors
) (infoPtr
->pScrn
,
242 (pCurs
->backBlue
>> 8) |
243 ((pCurs
->backGreen
>> 8) << 8) |
244 ((pCurs
->backRed
>> 8) << 16),
245 (pCurs
->foreBlue
>> 8) |
246 ((pCurs
->foreGreen
>> 8) << 8) |
247 ((pCurs
->foreRed
>> 8) << 16)
252 /* These functions assume that MaxWidth is a multiple of 32 */
253 static unsigned char *
254 RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
257 SCANLINE
*SrcS
, *SrcM
, *DstS
, *DstM
;
258 SCANLINE
*pSrc
, *pMsk
;
260 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
261 int SrcPitch
, DstPitch
, Pitch
, y
, x
;
263 /* how many words are in the source or mask */
264 int words
= size
/ (CUR_BITMAP_SCANLINE_PAD
/ 4);
266 if (!(mem
= calloc(1, size
)))
269 if (pCurs
== NullCursor
) {
270 if (infoPtr
->Flags
& HARDWARE_CURSOR_INVERT_MASK
) {
271 DstM
= (SCANLINE
*) mem
;
272 if (!(infoPtr
->Flags
& HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK
))
274 memset(DstM
, -1, words
* sizeof(SCANLINE
));
279 /* SrcPitch == the number of scanlines wide the cursor image is */
280 SrcPitch
= (pCurs
->bits
->width
+ (BITMAP_SCANLINE_PAD
- 1)) >>
283 /* DstPitch is the width of the hw cursor in scanlines */
284 DstPitch
= infoPtr
->MaxWidth
>> CUR_LOG2_BITMAP_PAD
;
285 Pitch
= SrcPitch
< DstPitch
? SrcPitch
: DstPitch
;
287 SrcS
= (SCANLINE
*) pCurs
->bits
->source
;
288 SrcM
= (SCANLINE
*) pCurs
->bits
->mask
;
289 DstS
= (SCANLINE
*) mem
;
292 if (infoPtr
->Flags
& HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK
) {
300 if (infoPtr
->Flags
& HARDWARE_CURSOR_AND_SOURCE_WITH_MASK
) {
301 for (y
= pCurs
->bits
->height
, pSrc
= DstS
, pMsk
= DstM
;
303 pSrc
+= DstPitch
, pMsk
+= DstPitch
, SrcS
+= SrcPitch
, SrcM
+=
305 for (x
= 0; x
< Pitch
; x
++) {
306 pSrc
[x
] = SrcS
[x
] & SrcM
[x
];
312 for (y
= pCurs
->bits
->height
, pSrc
= DstS
, pMsk
= DstM
;
314 pSrc
+= DstPitch
, pMsk
+= DstPitch
, SrcS
+= SrcPitch
, SrcM
+=
316 for (x
= 0; x
< Pitch
; x
++) {
323 if (infoPtr
->Flags
& HARDWARE_CURSOR_NIBBLE_SWAPPED
) {
325 unsigned char *pntr1
= (unsigned char *) DstS
;
326 unsigned char *pntr2
= (unsigned char *) DstM
;
333 *pntr1
= ((a
& 0xF0) >> 4) | ((a
& 0x0F) << 4);
334 *pntr2
= ((b
& 0xF0) >> 4) | ((b
& 0x0F) << 4);
342 * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
343 * out entire source mask.
345 if (infoPtr
->Flags
& HARDWARE_CURSOR_INVERT_MASK
) {
347 SCANLINE
*pntr
= DstM
;
355 if (infoPtr
->Flags
& HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
) {
356 for (y
= pCurs
->bits
->height
, pSrc
= DstS
, pMsk
= DstM
;
357 y
--; pSrc
+= DstPitch
, pMsk
+= DstPitch
) {
358 for (x
= 0; x
< Pitch
; x
++) {
359 pSrc
[x
] = REVERSE_BIT_ORDER(pSrc
[x
]);
360 pMsk
[x
] = REVERSE_BIT_ORDER(pMsk
[x
]);
368 static unsigned char *
369 RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
371 unsigned char *DstS
, *DstM
;
373 unsigned char *mem
, *mem2
;
375 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
377 /* Realize the cursor without interleaving */
378 if (!(mem2
= RealizeCursorInterleave0(infoPtr
, pCurs
)))
381 if (!(mem
= calloc(1, size
))) {
386 /* 1 bit interleave */
388 DstM
= DstS
+ (size
>> 1);
392 *pntr
++ = ((*DstS
& 0x01)) | ((*DstM
& 0x01) << 1) |
393 ((*DstS
& 0x02) << 1) | ((*DstM
& 0x02) << 2) |
394 ((*DstS
& 0x04) << 2) | ((*DstM
& 0x04) << 3) |
395 ((*DstS
& 0x08) << 3) | ((*DstM
& 0x08) << 4);
396 *pntr
++ = ((*DstS
& 0x10) >> 4) | ((*DstM
& 0x10) >> 3) |
397 ((*DstS
& 0x20) >> 3) | ((*DstM
& 0x20) >> 2) |
398 ((*DstS
& 0x40) >> 2) | ((*DstM
& 0x40) >> 1) |
399 ((*DstS
& 0x80) >> 1) | ((*DstM
& 0x80));
405 /* Free the uninterleaved cursor */
411 static unsigned char *
412 RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
414 unsigned char *DstS
, *DstM
;
416 unsigned char *mem
, *mem2
;
418 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
420 /* Realize the cursor without interleaving */
421 if (!(mem2
= RealizeCursorInterleave0(infoPtr
, pCurs
)))
424 if (!(mem
= calloc(1, size
))) {
429 /* 8 bit interleave */
431 DstM
= DstS
+ (size
>> 1);
440 /* Free the uninterleaved cursor */
446 static unsigned char *
447 RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
449 unsigned short *DstS
, *DstM
;
450 unsigned short *pntr
;
451 unsigned char *mem
, *mem2
;
453 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
455 /* Realize the cursor without interleaving */
456 if (!(mem2
= RealizeCursorInterleave0(infoPtr
, pCurs
)))
459 if (!(mem
= calloc(1, size
))) {
464 /* 16 bit interleave */
465 DstS
= (pointer
) mem2
;
466 DstM
= DstS
+ (size
>> 2);
467 pntr
= (pointer
) mem
;
475 /* Free the uninterleaved cursor */
481 static unsigned char *
482 RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
486 unsigned char *mem
, *mem2
;
488 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
490 /* Realize the cursor without interleaving */
491 if (!(mem2
= RealizeCursorInterleave0(infoPtr
, pCurs
)))
494 if (!(mem
= calloc(1, size
))) {
499 /* 32 bit interleave */
500 DstS
= (pointer
) mem2
;
501 DstM
= DstS
+ (size
>> 3);
502 pntr
= (pointer
) mem
;
510 /* Free the uninterleaved cursor */
516 static unsigned char *
517 RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
521 unsigned char *mem
, *mem2
;
523 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
525 /* Realize the cursor without interleaving */
526 if (!(mem2
= RealizeCursorInterleave0(infoPtr
, pCurs
)))
529 if (!(mem
= calloc(1, size
))) {
534 /* 64 bit interleave */
535 DstS
= (pointer
) mem2
;
536 DstM
= DstS
+ (size
>> 3);
537 pntr
= (pointer
) mem
;
547 /* Free the uninterleaved cursor */