1
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86HWCurs.c,v 1.12 2003/02/13 20:28:41 tsi Exp $ */
3
#ifdef HAVE_XORG_CONFIG_H
4
#include <xorg-config.h>
9
#include "xf86_ansic.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 */