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);
180 nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, (x & 0xFFFF) | (y << 16));
184 NVSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
186 NVPtr pNv = NVPTR(pScrn);
189 if(pNv->alphaCursor) {
190 fore = ConvertToRGB888(fg);
191 back = ConvertToRGB888(bg);
192 #if X_BYTE_ORDER == X_BIG_ENDIAN
193 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
194 fore = BYTE_SWAP_32(fore);
195 back = BYTE_SWAP_32(back);
199 fore = ConvertToRGB555(fg);
200 back = ConvertToRGB555(bg);
201 #if X_BYTE_ORDER == X_BIG_ENDIAN
202 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
203 fore = ((fore & 0xff) << 8) | (fore >> 8);
204 back = ((back & 0xff) << 8) | (back >> 8);
209 if ((pNv->curFg != fore) || (pNv->curBg != back)) {
213 TransformCursor(pNv);
219 NVShowCursor(ScrnInfoPtr pScrn)
221 NVPtr pNv = NVPTR(pScrn);
222 /* Enable cursor - X-Windows mode */
223 NVShowHideCursor(pNv, 1);
227 NVHideCursor(ScrnInfoPtr pScrn)
229 NVPtr pNv = NVPTR(pScrn);
231 NVShowHideCursor(pNv, 0);
235 NVUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
242 NVUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
244 if((pCurs->bits->width <= MAX_CURSOR_SIZE_ALPHA) && (pCurs->bits->height <= MAX_CURSOR_SIZE_ALPHA))
251 NVLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
253 NVPtr pNv = NVPTR(pScrn);
254 CARD32 *image = pCurs->bits->argb;
255 CARD32 *dst = (CARD32*)pNv->CURSOR;
259 w = pCurs->bits->width;
260 h = pCurs->bits->height;
262 if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) { /* premultiply */
263 for(y = 0; y < h; y++) {
264 for(x = 0; x < w; x++) {
265 alpha = *image >> 24;
269 tmp = (alpha << 24) |
270 (((*image & 0xff) * alpha) / 255) |
271 ((((*image & 0xff00) * alpha) / 255) & 0xff00) |
272 ((((*image & 0xff0000) * alpha) / 255) & 0xff0000);
275 #if X_BYTE_ORDER == X_BIG_ENDIAN
276 *dst++ = BYTE_SWAP_32(tmp);
281 for(; x < MAX_CURSOR_SIZE_ALPHA; x++)
285 for(y = 0; y < h; y++) {
286 for(x = 0; x < w; x++)
288 for(; x < MAX_CURSOR_SIZE_ALPHA; x++)
293 if(y < MAX_CURSOR_SIZE_ALPHA)
294 memset(dst, 0, MAX_CURSOR_SIZE_ALPHA * (MAX_CURSOR_SIZE_ALPHA - y) * 4);
299 NVCursorInit(ScreenPtr pScreen)
301 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
302 NVPtr pNv = NVPTR(pScrn);
303 xf86CursorInfoPtr infoPtr;
305 infoPtr = xf86CreateCursorInfoRec();
306 if(!infoPtr) return FALSE;
308 pNv->CursorInfoRec = infoPtr;
311 infoPtr->MaxWidth = infoPtr->MaxHeight = MAX_CURSOR_SIZE_ALPHA;
313 infoPtr->MaxWidth = infoPtr->MaxHeight = MAX_CURSOR_SIZE;
315 infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
316 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32;
317 infoPtr->SetCursorColors = NVSetCursorColors;
318 infoPtr->SetCursorPosition = NVSetCursorPosition;
319 infoPtr->LoadCursorImage = NVLoadCursorImage;
320 infoPtr->HideCursor = NVHideCursor;
321 infoPtr->ShowCursor = NVShowCursor;
322 infoPtr->UseHWCursor = NVUseHWCursor;
325 if(pNv->alphaCursor) {
326 infoPtr->UseHWCursorARGB = NVUseHWCursorARGB;
327 infoPtr->LoadCursorARGB = NVLoadCursorARGB;
331 return(xf86InitCursor(pScreen, infoPtr));
334 #ifdef ENABLE_RANDR12
336 #define CURSOR_PTR ((CARD32*)pNv->Cursor->map)
338 Bool NVCursorInitRandr12(ScreenPtr pScreen)
340 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
341 NVPtr pNv = NVPTR(pScrn);
342 int flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
343 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32;
345 if (pNv->alphaCursor) { /* >= NV11 */
346 cursor_size = MAX_CURSOR_SIZE_ALPHA;
347 flags |= HARDWARE_CURSOR_ARGB;
349 cursor_size = MAX_CURSOR_SIZE;
351 return xf86_cursors_init(pScreen, cursor_size, cursor_size, flags);
354 void nv_crtc_show_cursor(xf86CrtcPtr crtc)
356 int current = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1) | 1;
357 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, current);
360 void nv_crtc_hide_cursor(xf86CrtcPtr crtc)
362 int current = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1) & ~1;
363 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, current);
366 void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
368 ScrnInfoPtr pScrn = crtc->scrn;
369 NVPtr pNv = NVPTR(pScrn);
370 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
371 xf86OutputPtr output = NULL;
374 /* We need our output, so we know our ramdac */
375 for (i = 0; i < xf86_config->num_output; i++) {
376 output = xf86_config->output[i];
378 if (output->crtc == crtc) {
379 /* TODO: Add a check if an output was found? */
384 NVOutputWriteRAMDAC(output, NV_RAMDAC_CURSOR_POS, ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT) | (y << CURSOR_Y_SHIFT));
387 void nv_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg)
389 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
390 ScrnInfoPtr pScrn = crtc->scrn;
391 NVPtr pNv = NVPTR(pScrn);
394 if(pNv->alphaCursor) {
395 fore = ConvertToRGB888(fg);
396 back = ConvertToRGB888(bg);
397 #if X_BYTE_ORDER == X_BIG_ENDIAN
398 if(pNv->NVArch == 0x11) {
399 fore = BYTE_SWAP_32(fore);
400 back = BYTE_SWAP_32(back);
404 fore = ConvertToRGB555(fg);
405 back = ConvertToRGB555(bg);
406 #if X_BYTE_ORDER == X_BIG_ENDIAN
407 if(pNv->NVArch == 0x11) {
408 fore = ((fore & 0xff) << 8) | (fore >> 8);
409 back = ((back & 0xff) << 8) | (back >> 8);
414 /* Eventually this must be replaced as well */
415 if ((pNv->curFg != fore) || (pNv->curBg != back)) {
418 TransformCursor(pNv);
424 void nv_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *image)
426 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
427 ScrnInfoPtr pScrn = crtc->scrn;
428 NVPtr pNv = NVPTR(pScrn);
430 /* save copy of image for color changes */
431 memcpy(pNv->curImage, image, 256);
433 /* Eventually this has to be replaced as well */
434 TransformCursor(pNv);
437 void nv_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
439 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
440 ScrnInfoPtr pScrn = crtc->scrn;
441 NVPtr pNv = NVPTR(pScrn);
443 /* Copy the cursor straight into the right registers */
444 memcpy(CURSOR_PTR, image, 16384);
447 #endif /* ENABLE_RANDR12 */