1 /***************************************************************************\
3 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
5 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
6 |* international laws. Users and possessors of this source code are *|
7 |* hereby granted a nonexclusive, royalty-free copyright license to *|
8 |* use this code in individual and commercial software. *|
10 |* Any use of this source code must include, in the user documenta- *|
11 |* tion and internal comments to the code, notices to the end user *|
14 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
16 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
17 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
18 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
19 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
20 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
21 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
22 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
23 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
24 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
25 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
26 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
28 |* U.S. Government End Users. This source code is a "commercial *|
29 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
30 |* consisting of "commercial computer software" and "commercial *|
31 |* computer software documentation," as such terms are used in *|
32 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
33 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
34 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
35 |* all U.S. Government End Users acquire the source code with only *|
36 |* those rights set forth herein. *|
38 \***************************************************************************/
40 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c,v 1.13 2004/03/13 22:07:05 mvojkovi Exp $ */
42 #include "nv_include.h"
44 #include "cursorstr.h"
46 /****************************************************************************\
48 * HW Cursor Entrypoints *
50 \****************************************************************************/
52 #define NV_CURSOR_X 64
53 #define NV_CURSOR_Y 64
55 #define CURSOR_X_SHIFT 0
56 #define CURSOR_Y_SHIFT 16
57 #define CURSOR_POS_MASK 0xffff
59 #define TRANSPARENT_PIXEL 0
61 #define ConvertToRGB555(c) (((c & 0xf80000) >> 9 ) | /* Blue */ \
62 ((c & 0xf800) >> 6 ) | /* Green */ \
63 ((c & 0xf8) >> 3 ) | /* Red */ \
64 0x8000) /* Set upper bit, else we get complete transparency. */
66 #define ConvertToRGB888(c) (c | 0xff000000)
68 #define BYTE_SWAP_32(c) ((c & 0xff000000) >> 24) | \
69 ((c & 0xff0000) >> 8) | \
70 ((c & 0xff00) << 8) | \
73 /* Limit non-alpha cursors to 32x32 (x2 bytes) */
74 #define MAX_CURSOR_SIZE 32
76 /* Limit alpha cursors to 32x32 (x4 bytes) */
77 #define MAX_CURSOR_SIZE_ALPHA (MAX_CURSOR_SIZE * 2)
80 ConvertCursor1555(NVPtr pNv, CARD32 *src, CARD16 *dst)
85 for ( i = 0; i < MAX_CURSOR_SIZE; i++ ) {
88 for ( j = 0; j < MAX_CURSOR_SIZE; j++ ) {
89 #if X_BYTE_ORDER == X_BIG_ENDIAN
91 *dst = ( b & 0x80000000) ? pNv->curFg : pNv->curBg;
93 *dst = TRANSPARENT_PIXEL;
98 *dst = ( b & 1) ? pNv->curFg : pNv->curBg;
100 *dst = TRANSPARENT_PIXEL;
111 ConvertCursor8888(NVPtr pNv, CARD32 *src, CARD32 *dst)
116 /* Iterate over each byte in the cursor. */
117 for ( i = 0; i < MAX_CURSOR_SIZE * 4; i++ ) {
120 for ( j = 0; j < MAX_CURSOR_SIZE; j++ ) {
121 #if X_BYTE_ORDER == X_BIG_ENDIAN
123 *dst = ( b & 0x80000000) ? pNv->curFg : pNv->curBg;
125 *dst = TRANSPARENT_PIXEL;
130 *dst = ( b & 1) ? pNv->curFg : pNv->curBg;
132 *dst = TRANSPARENT_PIXEL;
143 TransformCursor (NVPtr pNv)
148 /* convert to color cursor */
149 if(pNv->alphaCursor) {
150 dwords = MAX_CURSOR_SIZE_ALPHA * MAX_CURSOR_SIZE_ALPHA;
151 if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
152 ConvertCursor8888(pNv, pNv->curImage, tmp);
154 dwords = (MAX_CURSOR_SIZE * MAX_CURSOR_SIZE) >> 1;
155 if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
156 ConvertCursor1555(pNv, pNv->curImage, (CARD16*)tmp);
159 for(i = 0; i < dwords; i++)
160 pNv->CURSOR[i] = tmp[i];
162 DEALLOCATE_LOCAL(tmp);
166 NVLoadCursorImage( ScrnInfoPtr pScrn, unsigned char *src )
168 NVPtr pNv = NVPTR(pScrn);
170 /* save copy of image for color changes */
171 memcpy(pNv->curImage, src, (pNv->alphaCursor) ? 1024 : 256);
173 TransformCursor(pNv);
177 NVSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
179 NVPtr pNv = NVPTR(pScrn);
181 if (pNv->randr12_enable) {
182 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
184 NVCrtcPrivatePtr nv_crtc;
192 for (o = 0; o < xf86_config->num_output; o++)
194 xf86OutputPtr output = xf86_config->output[o];
199 if (!output->crtc->enabled)
208 if (thisx >= mode->HDisplay ||
209 thisy >= mode->VDisplay ||
210 thisx <= -NV_CURSOR_X || thisy <= -NV_CURSOR_Y)
218 temp |= ((thisx & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
219 temp |= ((thisy & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
221 nv_crtc = output->crtc->driver_private;
223 nvWriteRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_CURSOR_POS, temp);
226 nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, (x & 0xFFFF) | (y << 16));
230 NVSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
232 NVPtr pNv = NVPTR(pScrn);
235 if(pNv->alphaCursor) {
236 fore = ConvertToRGB888(fg);
237 back = ConvertToRGB888(bg);
238 #if X_BYTE_ORDER == X_BIG_ENDIAN
239 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
240 fore = BYTE_SWAP_32(fore);
241 back = BYTE_SWAP_32(back);
245 fore = ConvertToRGB555(fg);
246 back = ConvertToRGB555(bg);
247 #if X_BYTE_ORDER == X_BIG_ENDIAN
248 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
249 fore = ((fore & 0xff) << 8) | (fore >> 8);
250 back = ((back & 0xff) << 8) | (back >> 8);
255 if ((pNv->curFg != fore) || (pNv->curBg != back)) {
259 TransformCursor(pNv);
265 NVShowCursor(ScrnInfoPtr pScrn)
267 NVPtr pNv = NVPTR(pScrn);
268 if (pNv->randr12_enable) {
269 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
272 pNv->cursorOn = TRUE;
273 for (c= 0; c < xf86_config->num_crtc; c++)
274 NVCrtcSetCursor (xf86_config->crtc[c], TRUE);
276 /* Enable cursor - X-Windows mode */
277 NVShowHideCursor(pNv, 1);
282 NVHideCursor(ScrnInfoPtr pScrn)
284 NVPtr pNv = NVPTR(pScrn);
286 if (pNv->randr12_enable) {
287 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
290 pNv->cursorOn = FALSE;
291 for (c = 0; c < xf86_config->num_crtc; c++)
292 NVCrtcSetCursor (xf86_config->crtc[c], TRUE);
296 NVShowHideCursor(pNv, 0);
300 NVUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
307 NVUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
309 if((pCurs->bits->width <= MAX_CURSOR_SIZE_ALPHA) && (pCurs->bits->height <= MAX_CURSOR_SIZE_ALPHA))
316 NVLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
318 NVPtr pNv = NVPTR(pScrn);
319 CARD32 *image = pCurs->bits->argb;
320 CARD32 *dst = (CARD32*)pNv->CURSOR;
324 w = pCurs->bits->width;
325 h = pCurs->bits->height;
327 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) { /* premultiply */
328 for(y = 0; y < h; y++) {
329 for(x = 0; x < w; x++) {
330 alpha = *image >> 24;
334 tmp = (alpha << 24) |
335 (((*image & 0xff) * alpha) / 255) |
336 ((((*image & 0xff00) * alpha) / 255) & 0xff00) |
337 ((((*image & 0xff0000) * alpha) / 255) & 0xff0000);
340 #if X_BYTE_ORDER == X_BIG_ENDIAN
341 *dst++ = BYTE_SWAP_32(tmp);
346 for(; x < MAX_CURSOR_SIZE_ALPHA; x++)
350 for(y = 0; y < h; y++) {
351 for(x = 0; x < w; x++)
353 for(; x < MAX_CURSOR_SIZE_ALPHA; x++)
358 if(y < MAX_CURSOR_SIZE_ALPHA)
359 memset(dst, 0, MAX_CURSOR_SIZE_ALPHA * (MAX_CURSOR_SIZE_ALPHA - y) * 4);
364 NVCursorInit(ScreenPtr pScreen)
366 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
367 NVPtr pNv = NVPTR(pScrn);
368 xf86CursorInfoPtr infoPtr;
370 infoPtr = xf86CreateCursorInfoRec();
371 if(!infoPtr) return FALSE;
373 pNv->CursorInfoRec = infoPtr;
376 infoPtr->MaxWidth = infoPtr->MaxHeight = MAX_CURSOR_SIZE_ALPHA;
378 infoPtr->MaxWidth = infoPtr->MaxHeight = MAX_CURSOR_SIZE;
380 infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
381 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32;
382 infoPtr->SetCursorColors = NVSetCursorColors;
383 infoPtr->SetCursorPosition = NVSetCursorPosition;
384 infoPtr->LoadCursorImage = NVLoadCursorImage;
385 infoPtr->HideCursor = NVHideCursor;
386 infoPtr->ShowCursor = NVShowCursor;
387 infoPtr->UseHWCursor = NVUseHWCursor;
390 if(pNv->alphaCursor) {
391 infoPtr->UseHWCursorARGB = NVUseHWCursorARGB;
392 infoPtr->LoadCursorARGB = NVLoadCursorARGB;
396 return(xf86InitCursor(pScreen, infoPtr));