2
* Copyright ļæ½ 2004 Eric Anholt
4
* Permission to use, copy, modify, distribute, and sell this software and its
5
* documentation for any purpose is hereby granted without fee, provided that
6
* the above copyright notice appear in all copies and that both that
7
* copyright notice and this permission notice appear in supporting
8
* documentation, and that the name of Eric Anholt not be used in
9
* advertising or publicity pertaining to distribution of the software without
10
* specific, written prior permission. Eric Anholt makes no
11
* representations about the suitability of this software for any purpose. It
12
* is provided "as is" without express or implied warranty.
14
* ERIC ANHOLT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16
* EVENT SHALL ERIC ANHOLT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20
* PERFORMANCE OF THIS SOFTWARE.
25
#include <kdrive-config.h>
29
#include "cursorstr.h"
33
ATIMoveCursor(ScreenPtr pScreen, int x, int y)
35
KdScreenPriv(pScreen);
36
ATICardInfo(pScreenPriv);
37
ATIScreenInfo(pScreenPriv);
38
ATICursor *pCurPriv = &atis->cursor;
40
CARD8 *mmio = atic->reg_base;
41
int stride = atic->is_radeon ? 256 : 16;
43
if (!pCurPriv->has_cursor)
46
if (!pScreenPriv->enabled)
62
MMIO_OUT32(mmio, ATI_REG_CUR_HORZ_VERT_OFF, ATI_CUR_LOCK |
64
MMIO_OUT32(mmio, ATI_REG_CUR_HORZ_VERT_POSN, ATI_CUR_LOCK |
66
MMIO_OUT32(mmio, ATI_REG_CUR_OFFSET, (pCurPriv->area->offset + yoff *
71
ClassicAllocCursorColors(ScreenPtr pScreen)
73
KdScreenPriv(pScreen);
74
ATIScreenInfo(pScreenPriv);
75
ATICursor *pCurPriv = &atis->cursor;
76
CursorPtr pCursor = pCurPriv->pCursor;
78
KdAllocateCursorPixels(pScreen, 0, pCursor, &pCurPriv->source,
80
switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
82
pCurPriv->source |= pCurPriv->source << 4;
83
pCurPriv->mask |= pCurPriv->mask << 4;
86
pCurPriv->source |= pCurPriv->source << 8;
87
pCurPriv->mask |= pCurPriv->mask << 8;
90
pCurPriv->source |= pCurPriv->source << 16;
91
pCurPriv->mask |= pCurPriv->mask << 16;
96
ClassicSetCursorColors(ScreenPtr pScreen)
98
KdScreenPriv(pScreen);
99
ATICardInfo(pScreenPriv);
100
ATIScreenInfo(pScreenPriv);
101
ATICursor *pCurPriv = &atis->cursor;
102
CARD8 *mmio = atic->reg_base;
104
MMIO_OUT32(mmio, ATI_REG_CUR_CLR0, pCurPriv->mask);
105
MMIO_OUT32(mmio, ATI_REG_CUR_CLR1, pCurPriv->source);
109
ClassicRecolorCursor(ScreenPtr pScreen, int ndef, xColorItem *pdef)
111
KdScreenPriv(pScreen);
112
ATIScreenInfo(pScreenPriv);
113
ATICursor *pCurPriv = &atis->cursor;
114
CursorPtr pCursor = pCurPriv->pCursor;
116
if (!pCurPriv->has_cursor || !pCursor)
119
if (!pScreenPriv->enabled)
124
if (pdef->pixel == pCurPriv->source ||
125
pdef->pixel == pCurPriv->mask)
133
ClassicAllocCursorColors(pScreen);
134
ClassicSetCursorColors(pScreen);
137
#define InvertBits32(v) do { \
138
v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
139
v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
140
v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
144
ClassicLoadCursor(ScreenPtr pScreen)
146
KdScreenPriv(pScreen);
147
ATICardInfo(pScreenPriv);
148
ATIScreenInfo(pScreenPriv);
149
ATICursor *pCurPriv = &atis->cursor;
150
CursorPtr pCursor = pCurPriv->pCursor;
151
CursorBitsPtr bits = pCursor->bits;
153
CARD32 *ram, *msk, *mskLine, *src, *srcLine;
157
CARD8 *mmio = atic->reg_base;
159
ClassicAllocCursorColors(pScreen);
161
pCurPriv->pCursor = pCursor;
162
pCurPriv->xhot = pCursor->bits->xhot;
163
pCurPriv->yhot = pCursor->bits->yhot;
165
/* Stick new image into cursor memory */
166
ram = (CARD32 *)(pScreenPriv->screen->memory_base +
167
pCurPriv->area->offset);
168
mskLine = (CARD32 *)bits->mask;
169
srcLine = (CARD32 *)bits->source;
172
if (h > ATI_CURSOR_HEIGHT)
173
h = ATI_CURSOR_HEIGHT;
175
lwsrc = BitmapBytePad(bits->width) / 4; /* words per line */
177
tmp = MMIO_IN32(mmio, ATI_REG_GEN_CNTL);
178
MMIO_OUT32(mmio, ATI_REG_GEN_CNTL, tmp & ~ATI_CRTC_CUR_EN);
180
for (i = 0; i < ATI_CURSOR_HEIGHT; i++) {
181
CARD32 m1, m2, s1, s2;
188
if (i < h && 0 < lwsrc) {
197
if (i < h && 1 < lwsrc) {
213
/* Not sure why this is necessary, but it prevents some cursor
214
* corruption. Not even all of it.
216
for (i = 0; i < ATI_CURSOR_HEIGHT; i++) {
223
/* Enable the cursor */
224
tmp = MMIO_IN32(mmio, ATI_REG_GEN_CNTL);
225
MMIO_OUT32(mmio, ATI_REG_GEN_CNTL, tmp | ATI_CRTC_CUR_EN);
228
ClassicSetCursorColors(pScreen);
233
RadeonLoadCursor(ScreenPtr pScreen)
235
KdScreenPriv(pScreen);
236
ATICardInfo(pScreenPriv);
237
ATIScreenInfo(pScreenPriv);
238
ATICursor *pCurPriv = &atis->cursor;
239
CursorPtr pCursor = pCurPriv->pCursor;
240
CursorBitsPtr bits = pCursor->bits;
243
CARD32 *ram, *msk, *mskLine, *src, *srcLine;
246
CARD8 *mmio = atic->reg_base;
248
pCurPriv->pCursor = pCursor;
249
pCurPriv->xhot = pCursor->bits->xhot;
250
pCurPriv->yhot = pCursor->bits->yhot;
253
if (w > ATI_CURSOR_WIDTH)
254
w = ATI_CURSOR_WIDTH;
257
if (h > ATI_CURSOR_HEIGHT)
258
h = ATI_CURSOR_HEIGHT;
260
tmp = MMIO_IN32(mmio, 0x7c);
262
MMIO_OUT32 (mmio, 0x7c, tmp);
264
tmp = MMIO_IN32(mmio, ATI_REG_GEN_CNTL);
265
tmp &= ~(ATI_CRTC_CUR_EN | ATI_CRTC_ICON_EN | ATI_CRTC_ARGB_EN);
266
MMIO_OUT32(mmio, ATI_REG_GEN_CNTL, tmp);
268
/* Stick new image into cursor memory */
269
ram = (CARD32 *)(pScreenPriv->screen->memory_base +
270
pCurPriv->area->offset);
271
if (pCursor->bits->argb)
273
srcLine = pCursor->bits->argb;
274
for (y = 0; y < h; y++)
277
srcLine += pCursor->bits->width;
278
for (x = 0; x < w; x++)
280
for (; x < ATI_CURSOR_WIDTH; x++)
283
for (; y < ATI_CURSOR_HEIGHT; y++)
284
for (x = 0; x < ATI_CURSOR_WIDTH; x++)
293
colors[2] = (((pCursor->backRed >> 8) << 16) |
294
((pCursor->backGreen >> 8) << 8) |
295
((pCursor->backBlue >> 8) << 0) |
297
colors[3] = (((pCursor->foreRed >> 8) << 16) |
298
((pCursor->foreGreen >> 8) << 8) |
299
((pCursor->foreBlue >> 8) << 0) |
302
mskLine = (CARD32 *)bits->mask;
303
srcLine = (CARD32 *)bits->source;
306
lwsrc = BitmapBytePad(bits->width) / 4;
308
for (y = 0; y < ATI_CURSOR_HEIGHT; y++)
317
for (x = 0; x < ATI_CURSOR_WIDTH / 32; x++)
320
if (y < h && x < lwsrc)
331
for (k = 0; k < 32; k++)
333
CARD32 bits = (s & 1) | ((m & 1) << 1);
334
*ram++ = colors[bits];
342
/* Enable the cursor */
343
tmp &= ~(ATI_CRTC_ICON_EN);
344
tmp |= ATI_CRTC_ARGB_EN;
345
tmp |= ATI_CRTC_CUR_EN;
346
MMIO_OUT32(mmio, ATI_REG_GEN_CNTL, tmp);
350
ATIUnloadCursor(ScreenPtr pScreen)
352
KdScreenPriv(pScreen);
353
ATICardInfo(pScreenPriv);
354
CARD8 *mmio = atic->reg_base;
357
tmp = MMIO_IN32(mmio, ATI_REG_GEN_CNTL);
358
tmp &= ~(ATI_CRTC_CUR_EN | ATI_CRTC_ICON_EN | ATI_CRTC_ARGB_EN);
359
MMIO_OUT32(mmio, ATI_REG_GEN_CNTL, tmp);
363
ATIRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
365
KdScreenPriv(pScreen);
366
ATICardInfo(pScreenPriv);
367
ATIScreenInfo(pScreenPriv);
368
ATICursor *pCurPriv = &atis->cursor;
370
if (!pScreenPriv->enabled)
373
/* miRecolorCursor does this */
374
if (pCursor && pCurPriv->pCursor == pCursor)
378
miPointerPosition(&x, &y);
380
RadeonLoadCursor (pScreen);
382
ClassicLoadCursor(pScreen);
383
/* Move to new position */
384
ATIMoveCursor(pScreen, x, y);
391
ATIUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
397
ATISetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
399
KdScreenPriv(pScreen);
400
ATICardInfo(pScreenPriv);
401
ATIScreenInfo(pScreenPriv);
402
ATICursor *pCurPriv = &atis->cursor;
404
pCurPriv->pCursor = pCursor;
406
if (!pScreenPriv->enabled)
412
RadeonLoadCursor (pScreen);
414
ClassicLoadCursor(pScreen);
415
/* Move to new position */
416
ATIMoveCursor(pScreen, x, y);
419
ATIUnloadCursor(pScreen);
422
miPointerSpriteFuncRec ATIPointerSpriteFuncs = {
430
ATIQueryBestSize(int class, unsigned short *pwidth, unsigned short *pheight,
433
KdScreenPriv(pScreen);
434
ATIScreenInfo(pScreenPriv);
435
ATICursor *pCurPriv = &atis->cursor;
440
if (*pwidth > pCurPriv->width)
441
*pwidth = pCurPriv->width;
442
if (*pheight > pCurPriv->height)
443
*pheight = pCurPriv->height;
444
if (*pwidth > pScreen->width)
445
*pwidth = pScreen->width;
446
if (*pheight > pScreen->height)
447
*pheight = pScreen->height;
450
fbQueryBestSize(class, pwidth, pheight, pScreen);
456
ATICursorSave(ScreenPtr pScreen, KdOffscreenArea *area)
458
KdScreenPriv(pScreen);
459
ATIScreenInfo(pScreenPriv);
460
ATICursor *pCurPriv = &atis->cursor;
462
pCurPriv->area = NULL;
466
ATICursorEnable(ScreenPtr pScreen)
468
KdScreenPriv(pScreen);
469
ATICardInfo(pScreenPriv);
470
ATIScreenInfo(pScreenPriv);
471
ATICursor *pCurPriv = &atis->cursor;
473
if (!pCurPriv->has_cursor)
476
if (pCurPriv->area == NULL) {
478
pCurPriv->area = KdOffscreenAlloc(pScreen,
479
ATI_CURSOR_HEIGHT * ATI_CURSOR_WIDTH * 4,
480
128, TRUE, ATICursorSave, atis);
482
pCurPriv->area = KdOffscreenAlloc(pScreen,
483
ATI_CURSOR_HEIGHT * ATI_CURSOR_PITCH * 2,
484
32, TRUE, ATICursorSave, atis);
486
if (pCurPriv->area == NULL)
487
FatalError("Couldn't allocate offscreen memory for cursor.\n");
489
if (pCurPriv->pCursor) {
492
miPointerPosition(&x, &y);
494
RadeonLoadCursor(pScreen);
496
ClassicLoadCursor(pScreen);
497
/* Move to new position */
498
ATIMoveCursor(pScreen, x, y);
501
ATIUnloadCursor(pScreen);
505
ATICursorDisable(ScreenPtr pScreen)
507
KdScreenPriv(pScreen);
508
ATIScreenInfo(pScreenPriv);
509
ATICursor *pCurPriv = &atis->cursor;
511
if (!pScreenPriv->enabled || !pCurPriv->has_cursor)
514
if (pCurPriv->pCursor)
515
ATIUnloadCursor(pScreen);
519
ATICursorInit(ScreenPtr pScreen)
521
KdScreenPriv(pScreen);
522
ATICardInfo(pScreenPriv);
523
ATIScreenInfo(pScreenPriv);
524
ATICursor *pCurPriv = &atis->cursor;
526
pCurPriv->has_cursor = FALSE;
528
if (atic->reg_base == NULL)
531
pCurPriv->width = ATI_CURSOR_WIDTH;
532
pCurPriv->height= ATI_CURSOR_HEIGHT;
533
pScreen->QueryBestSize = ATIQueryBestSize;
534
miPointerInitialize(pScreen, &ATIPointerSpriteFuncs,
535
&kdPointerScreenFuncs, FALSE);
536
pCurPriv->has_cursor = TRUE;
537
pCurPriv->pCursor = NULL;
542
ATIRecolorCursor (ScreenPtr pScreen, int ndef, xColorItem *pdef)
544
KdScreenPriv(pScreen);
545
ATICardInfo(pScreenPriv);
547
if (!atic->is_radeon)
548
ClassicRecolorCursor (pScreen, ndef, pdef);
552
ATICursorFini(ScreenPtr pScreen)
554
KdScreenPriv(pScreen);
555
ATIScreenInfo(pScreenPriv);
556
ATICursor *pCurPriv = &atis->cursor;
558
pCurPriv->has_cursor = FALSE;
559
pCurPriv->pCursor = NULL;