1
/* $XFree86: xc/programs/Xserver/hw/xfree86/ramdac/xf86HWCurs.c,v 1.12 2003/02/13 20:28:41 tsi Exp $ */
5
#include "xf86_ansic.h"
6
#include "xf86_OSproc.h"
9
#include "scrnintstr.h"
10
#include "pixmapstr.h"
11
#include "windowstr.h"
13
#include "cursorstr.h"
15
#include "mipointer.h"
16
#include "xf86CursorPriv.h"
20
#if BITMAP_SCANLINE_PAD == 64
23
/* Cursors might be only 32 wide. Give'em a chance */
24
#define SCANLINE CARD32
25
#define CUR_BITMAP_SCANLINE_PAD 32
26
#define CUR_LOG2_BITMAP_PAD 5
27
#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
29
#define SCANLINE CARD64
30
#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
31
#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
32
#define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
33
static CARD64 xf86CARD64ReverseBits(CARD64 w);
36
xf86CARD64ReverseBits(CARD64 w)
38
unsigned char *p = (unsigned char *)&w;
40
p[0] = byte_reversed[p[0]];
41
p[1] = byte_reversed[p[1]];
42
p[2] = byte_reversed[p[2]];
43
p[3] = byte_reversed[p[3]];
44
p[4] = byte_reversed[p[4]];
45
p[5] = byte_reversed[p[5]];
46
p[6] = byte_reversed[p[6]];
47
p[7] = byte_reversed[p[7]];
55
#define SCANLINE CARD32
56
#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
57
#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
58
#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
60
#endif /* BITMAP_SCANLINE_PAD == 64 */
62
static unsigned char* RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
63
static unsigned char* RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
64
static unsigned char* RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
65
static unsigned char* RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
66
static unsigned char* RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
67
static unsigned char* RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
70
xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
72
if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
75
/* These are required for now */
76
if (!infoPtr->SetCursorPosition ||
77
!infoPtr->LoadCursorImage ||
78
!infoPtr->HideCursor ||
79
!infoPtr->ShowCursor ||
80
!infoPtr->SetCursorColors)
83
if (infoPtr->RealizeCursor) {
84
/* Don't overwrite a driver provided Realize Cursor function */
86
if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
87
infoPtr->RealizeCursor = RealizeCursorInterleave1;
89
if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
90
infoPtr->RealizeCursor = RealizeCursorInterleave8;
92
if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
93
infoPtr->RealizeCursor = RealizeCursorInterleave16;
95
if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
96
infoPtr->RealizeCursor = RealizeCursorInterleave32;
98
if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
99
infoPtr->RealizeCursor = RealizeCursorInterleave64;
100
} else { /* not interleaved */
101
infoPtr->RealizeCursor = RealizeCursorInterleave0;
104
infoPtr->pScrn = xf86Screens[pScreen->myNum];
110
xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
112
xf86CursorScreenPtr ScreenPriv =
113
pScreen->devPrivates[xf86CursorScreenIndex].ptr;
114
xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
117
if (pCurs == NullCursor) {
118
(*infoPtr->HideCursor)(infoPtr->pScrn);
122
bits = pCurs->devPriv[pScreen->myNum];
124
x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
125
y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
128
if (!pCurs->bits->argb || !infoPtr->LoadCursorARGB)
131
bits = (*infoPtr->RealizeCursor)(infoPtr, pCurs);
132
pCurs->devPriv[pScreen->myNum] = bits;
135
if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
136
(*infoPtr->HideCursor)(infoPtr->pScrn);
139
if (pCurs->bits->argb && infoPtr->LoadCursorARGB)
140
(*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs);
144
(*infoPtr->LoadCursorImage)(infoPtr->pScrn, bits);
146
xf86RecolorCursor(pScreen, pCurs, 1);
148
(*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
150
(*infoPtr->ShowCursor)(infoPtr->pScrn);
154
xf86SetTransparentCursor(ScreenPtr pScreen)
156
xf86CursorScreenPtr ScreenPriv =
157
pScreen->devPrivates[xf86CursorScreenIndex].ptr;
158
xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
160
if (!ScreenPriv->transparentData)
161
ScreenPriv->transparentData =
162
(*infoPtr->RealizeCursor)(infoPtr, NullCursor);
164
if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
165
(*infoPtr->HideCursor)(infoPtr->pScrn);
167
if (ScreenPriv->transparentData)
168
(*infoPtr->LoadCursorImage)(infoPtr->pScrn,
169
ScreenPriv->transparentData);
171
(*infoPtr->ShowCursor)(infoPtr->pScrn);
175
xf86MoveCursor(ScreenPtr pScreen, int x, int y)
177
xf86CursorScreenPtr ScreenPriv =
178
pScreen->devPrivates[xf86CursorScreenIndex].ptr;
179
xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
181
x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
182
y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
184
(*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
188
xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
190
xf86CursorScreenPtr ScreenPriv =
191
pScreen->devPrivates[xf86CursorScreenIndex].ptr;
192
xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
194
if (ScreenPriv->PalettedCursor) {
195
xColorItem sourceColor, maskColor;
196
ColormapPtr pmap = ScreenPriv->pInstalledMap;
201
sourceColor.red = pCurs->foreRed;
202
sourceColor.green = pCurs->foreGreen;
203
sourceColor.blue = pCurs->foreBlue;
204
FakeAllocColor(pmap, &sourceColor);
205
maskColor.red = pCurs->backRed;
206
maskColor.green = pCurs->backGreen;
207
maskColor.blue = pCurs->backBlue;
208
FakeAllocColor(pmap, &maskColor);
209
FakeFreeColor(pmap, sourceColor.pixel);
210
FakeFreeColor(pmap, maskColor.pixel);
211
(*infoPtr->SetCursorColors)(infoPtr->pScrn,
212
maskColor.pixel, sourceColor.pixel);
213
} else { /* Pass colors in 8-8-8 RGB format */
214
(*infoPtr->SetCursorColors)(infoPtr->pScrn,
215
(pCurs->backBlue >> 8) |
216
((pCurs->backGreen >> 8) << 8) |
217
((pCurs->backRed >> 8) << 16),
218
(pCurs->foreBlue >> 8) |
219
((pCurs->foreGreen >> 8) << 8) |
220
((pCurs->foreRed >> 8) << 16)
225
/* These functions assume that MaxWidth is a multiple of 32 */
226
static unsigned char*
227
RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
230
SCANLINE *SrcS, *SrcM, *DstS, *DstM;
231
SCANLINE *pSrc, *pMsk;
233
int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
234
int SrcPitch, DstPitch, Pitch, y, x;
235
/* how many words are in the source or mask */
236
int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);
239
if (!(mem = xcalloc(1, size)))
242
if (pCurs == NullCursor) {
243
if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
244
DstM = (SCANLINE*)mem;
245
if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
247
(void)memset(DstM, -1, words * sizeof(SCANLINE));
252
/* SrcPitch == the number of scanlines wide the cursor image is */
253
SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
256
/* DstPitch is the width of the hw cursor in scanlines */
257
DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
258
Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;
260
SrcS = (SCANLINE*)pCurs->bits->source;
261
SrcM = (SCANLINE*)pCurs->bits->mask;
262
DstS = (SCANLINE*)mem;
265
if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
267
tmp = DstS; DstS = DstM; DstM = tmp;
270
if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
271
for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
273
pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
274
for(x = 0; x < Pitch; x++) {
275
pSrc[x] = SrcS[x] & SrcM[x];
280
for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
282
pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
283
for(x = 0; x < Pitch; x++) {
290
if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
292
unsigned char* pntr1 = (unsigned char *)DstS;
293
unsigned char* pntr2 = (unsigned char *)DstM;
299
*pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
300
*pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
307
* Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
308
* out entire source mask.
310
if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
312
SCANLINE* pntr = DstM;
319
if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
320
for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
322
pSrc+=DstPitch, pMsk+=DstPitch) {
323
for(x = 0; x < Pitch; x++) {
324
pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
325
pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
333
static unsigned char*
334
RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
336
unsigned char *DstS, *DstM;
338
unsigned char *mem, *mem2;
340
int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
342
/* Realize the cursor without interleaving */
343
if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
346
if (!(mem = xcalloc(1, size))) {
351
/* 1 bit interleave */
353
DstM = DstS + (size >> 1);
357
*pntr++ = ((*DstS&0x01) ) | ((*DstM&0x01) << 1) |
358
((*DstS&0x02) << 1) | ((*DstM&0x02) << 2) |
359
((*DstS&0x04) << 2) | ((*DstM&0x04) << 3) |
360
((*DstS&0x08) << 3) | ((*DstM&0x08) << 4);
361
*pntr++ = ((*DstS&0x10) >> 4) | ((*DstM&0x10) >> 3) |
362
((*DstS&0x20) >> 3) | ((*DstM&0x20) >> 2) |
363
((*DstS&0x40) >> 2) | ((*DstM&0x40) >> 1) |
364
((*DstS&0x80) >> 1) | ((*DstM&0x80) );
370
/* Free the uninterleaved cursor */
376
static unsigned char*
377
RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
379
unsigned char *DstS, *DstM;
381
unsigned char *mem, *mem2;
383
int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
385
/* Realize the cursor without interleaving */
386
if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
389
if (!(mem = xcalloc(1, size))) {
394
/* 8 bit interleave */
396
DstM = DstS + (size >> 1);
405
/* Free the uninterleaved cursor */
411
static unsigned char*
412
RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
414
unsigned short *DstS, *DstM;
415
unsigned short *pntr;
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 = xcalloc(1, size))) {
429
/* 16 bit interleave */
430
DstS = (pointer)mem2;
431
DstM = DstS + (size >> 2);
440
/* Free the uninterleaved cursor */
446
static unsigned char*
447
RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
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 = xcalloc(1, size))) {
464
/* 32 bit interleave */
465
DstS = (pointer)mem2;
466
DstM = DstS + (size >> 3);
475
/* Free the uninterleaved cursor */
481
static unsigned char*
482
RealizeCursorInterleave64(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 = xcalloc(1, size))) {
499
/* 64 bit interleave */
500
DstS = (pointer)mem2;
501
DstM = DstS + (size >> 3);
512
/* Free the uninterleaved cursor */