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"
24 #if BITMAP_SCANLINE_PAD == 64
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)
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
);
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]];
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
);
74 xf86InitHardwareCursor(ScreenPtr pScreen
, xf86CursorInfoPtr infoPtr
)
76 if ((infoPtr
->MaxWidth
<= 0) || (infoPtr
->MaxHeight
<= 0))
79 /* These are required for now */
80 if (!infoPtr
->SetCursorPosition
||
81 !infoPtr
->LoadCursorImage
||
82 !infoPtr
->HideCursor
||
83 !infoPtr
->ShowCursor
||
84 !infoPtr
->SetCursorColors
)
87 if (infoPtr
->RealizeCursor
) {
88 /* Don't overwrite a driver provided Realize Cursor function */
90 if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1
& infoPtr
->Flags
) {
91 infoPtr
->RealizeCursor
= RealizeCursorInterleave1
;
93 if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8
& infoPtr
->Flags
) {
94 infoPtr
->RealizeCursor
= RealizeCursorInterleave8
;
96 if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16
& infoPtr
->Flags
) {
97 infoPtr
->RealizeCursor
= RealizeCursorInterleave16
;
99 if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32
& infoPtr
->Flags
) {
100 infoPtr
->RealizeCursor
= RealizeCursorInterleave32
;
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
];
114 xf86SetCursor(ScreenPtr pScreen
, CursorPtr pCurs
, int x
, int y
)
116 xf86CursorScreenPtr ScreenPriv
=
117 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
118 xf86CursorInfoPtr infoPtr
= ScreenPriv
->CursorInfoPtr
;
121 if (pCurs
== NullCursor
) {
122 (*infoPtr
->HideCursor
)(infoPtr
->pScrn
);
126 bits
= pCurs
->devPriv
[pScreen
->myNum
];
128 x
-= infoPtr
->pScrn
->frameX0
+ ScreenPriv
->HotX
;
129 y
-= infoPtr
->pScrn
->frameY0
+ ScreenPriv
->HotY
;
132 if (!pCurs
->bits
->argb
|| !infoPtr
->LoadCursorARGB
)
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
);
143 if (pCurs
->bits
->argb
&& infoPtr
->LoadCursorARGB
)
144 (*infoPtr
->LoadCursorARGB
) (infoPtr
->pScrn
, pCurs
);
148 (*infoPtr
->LoadCursorImage
)(infoPtr
->pScrn
, bits
);
150 xf86RecolorCursor(pScreen
, pCurs
, 1);
152 (*infoPtr
->SetCursorPosition
)(infoPtr
->pScrn
, x
, y
);
154 (*infoPtr
->ShowCursor
)(infoPtr
->pScrn
);
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
);
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
);
192 xf86RecolorCursor(ScreenPtr pScreen
, CursorPtr pCurs
, Bool displayed
)
194 xf86CursorScreenPtr ScreenPriv
=
195 pScreen
->devPrivates
[xf86CursorScreenIndex
].ptr
;
196 xf86CursorInfoPtr infoPtr
= ScreenPriv
->CursorInfoPtr
;
199 /* recoloring isn't applicable to ARGB cursors and drivers
200 shouldn't have to ignore SetCursorColors requests */
201 if (pCurs
->bits
->argb
)
205 if (ScreenPriv
->PalettedCursor
) {
206 xColorItem sourceColor
, maskColor
;
207 ColormapPtr pmap
= ScreenPriv
->pInstalledMap
;
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
;
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
)))
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
))
258 (void)memset(DstM
, -1, words
* sizeof(SCANLINE
));
263 /* SrcPitch == the number of scanlines wide the cursor image is */
264 SrcPitch
= (pCurs
->bits
->width
+ (BITMAP_SCANLINE_PAD
- 1)) >>
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
;
276 if (infoPtr
->Flags
& HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK
) {
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
;
284 pSrc
+=DstPitch
, pMsk
+=DstPitch
, SrcS
+=SrcPitch
, SrcM
+=SrcPitch
) {
285 for(x
= 0; x
< Pitch
; x
++) {
286 pSrc
[x
] = SrcS
[x
] & SrcM
[x
];
291 for(y
= pCurs
->bits
->height
, pSrc
= DstS
, pMsk
= DstM
;
293 pSrc
+=DstPitch
, pMsk
+=DstPitch
, SrcS
+=SrcPitch
, SrcM
+=SrcPitch
) {
294 for(x
= 0; x
< Pitch
; x
++) {
301 if (infoPtr
->Flags
& HARDWARE_CURSOR_NIBBLE_SWAPPED
) {
303 unsigned char* pntr1
= (unsigned char *)DstS
;
304 unsigned char* pntr2
= (unsigned char *)DstM
;
310 *pntr1
= ((a
& 0xF0) >> 4) | ((a
& 0x0F) << 4);
311 *pntr2
= ((b
& 0xF0) >> 4) | ((b
& 0x0F) << 4);
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
) {
323 SCANLINE
* pntr
= DstM
;
330 if (infoPtr
->Flags
& HARDWARE_CURSOR_BIT_ORDER_MSBFIRST
) {
331 for(y
= pCurs
->bits
->height
, pSrc
= DstS
, pMsk
= DstM
;
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
]);
344 static unsigned char*
345 RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
347 unsigned char *DstS
, *DstM
;
349 unsigned char *mem
, *mem2
;
351 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
353 /* Realize the cursor without interleaving */
354 if (!(mem2
= RealizeCursorInterleave0(infoPtr
, pCurs
)))
357 if (!(mem
= xcalloc(1, size
))) {
362 /* 1 bit interleave */
364 DstM
= DstS
+ (size
>> 1);
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) );
381 /* Free the uninterleaved cursor */
387 static unsigned char*
388 RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
390 unsigned char *DstS
, *DstM
;
392 unsigned char *mem
, *mem2
;
394 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
396 /* Realize the cursor without interleaving */
397 if (!(mem2
= RealizeCursorInterleave0(infoPtr
, pCurs
)))
400 if (!(mem
= xcalloc(1, size
))) {
405 /* 8 bit interleave */
407 DstM
= DstS
+ (size
>> 1);
416 /* Free the uninterleaved cursor */
422 static unsigned char*
423 RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
425 unsigned short *DstS
, *DstM
;
426 unsigned short *pntr
;
427 unsigned char *mem
, *mem2
;
429 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
431 /* Realize the cursor without interleaving */
432 if (!(mem2
= RealizeCursorInterleave0(infoPtr
, pCurs
)))
435 if (!(mem
= xcalloc(1, size
))) {
440 /* 16 bit interleave */
441 DstS
= (pointer
)mem2
;
442 DstM
= DstS
+ (size
>> 2);
451 /* Free the uninterleaved cursor */
457 static unsigned char*
458 RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
462 unsigned char *mem
, *mem2
;
464 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
466 /* Realize the cursor without interleaving */
467 if (!(mem2
= RealizeCursorInterleave0(infoPtr
, pCurs
)))
470 if (!(mem
= xcalloc(1, size
))) {
475 /* 32 bit interleave */
476 DstS
= (pointer
)mem2
;
477 DstM
= DstS
+ (size
>> 3);
486 /* Free the uninterleaved cursor */
492 static unsigned char*
493 RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr
, CursorPtr pCurs
)
497 unsigned char *mem
, *mem2
;
499 int size
= (infoPtr
->MaxWidth
* infoPtr
->MaxHeight
) >> 2;
501 /* Realize the cursor without interleaving */
502 if (!(mem2
= RealizeCursorInterleave0(infoPtr
, pCurs
)))
505 if (!(mem
= xcalloc(1, size
))) {
510 /* 64 bit interleave */
511 DstS
= (pointer
)mem2
;
512 DstM
= DstS
+ (size
>> 3);
523 /* Free the uninterleaved cursor */