summaryrefslogtreecommitdiff
path: root/src/nv_cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nv_cursor.c')
-rw-r--r--src/nv_cursor.c301
1 files changed, 301 insertions, 0 deletions
diff --git a/src/nv_cursor.c b/src/nv_cursor.c
new file mode 100644
index 0000000..04107ee
--- /dev/null
+++ b/src/nv_cursor.c
@@ -0,0 +1,301 @@
+/* $XConsortium: nv_driver.c /main/3 1996/10/28 05:13:37 kaleb $ */
+/*
+ * Copyright 1996-1997 David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* Rewritten with reference from mga driver and 3.3.4 NVIDIA driver by
+ Jarno Paananen <jpaana@s2.org> */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_cursor.c,v 1.11 2002/11/26 23:41:58 mvojkovi Exp $ */
+
+#include "nv_include.h"
+
+#include "cursorstr.h"
+
+/****************************************************************************\
+* *
+* HW Cursor Entrypoints *
+* *
+\****************************************************************************/
+
+#define TRANSPARENT_PIXEL 0
+
+#define ConvertToRGB555(c) \
+(((c & 0xf80000) >> 9 ) | ((c & 0xf800) >> 6 ) | ((c & 0xf8) >> 3 ) | 0x8000)
+
+#define ConvertToRGB888(c) (c | 0xff000000)
+
+#define BYTE_SWAP_32(c) ((c & 0xff000000) >> 24) | \
+ ((c & 0xff0000) >> 8) | \
+ ((c & 0xff00) << 8) | \
+ ((c & 0xff) << 24)
+
+
+static void
+ConvertCursor1555(NVPtr pNv, CARD32 *src, CARD16 *dst)
+{
+ CARD32 b, m;
+ int i, j;
+
+ for ( i = 0; i < 32; i++ ) {
+ b = *src++;
+ m = *src++;
+ for ( j = 0; j < 32; j++ ) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if ( m & 0x80000000)
+ *dst = ( b & 0x80000000) ? pNv->curFg : pNv->curBg;
+ else
+ *dst = TRANSPARENT_PIXEL;
+ b <<= 1;
+ m <<= 1;
+#else
+ if ( m & 1 )
+ *dst = ( b & 1) ? pNv->curFg : pNv->curBg;
+ else
+ *dst = TRANSPARENT_PIXEL;
+ b >>= 1;
+ m >>= 1;
+#endif
+ dst++;
+ }
+ }
+}
+
+
+static void
+ConvertCursor8888(NVPtr pNv, CARD32 *src, CARD32 *dst)
+{
+ CARD32 b, m;
+ int i, j;
+
+ for ( i = 0; i < 128; i++ ) {
+ b = *src++;
+ m = *src++;
+ for ( j = 0; j < 32; j++ ) {
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if ( m & 0x80000000)
+ *dst = ( b & 0x80000000) ? pNv->curFg : pNv->curBg;
+ else
+ *dst = TRANSPARENT_PIXEL;
+ b <<= 1;
+ m <<= 1;
+#else
+ if ( m & 1 )
+ *dst = ( b & 1) ? pNv->curFg : pNv->curBg;
+ else
+ *dst = TRANSPARENT_PIXEL;
+ b >>= 1;
+ m >>= 1;
+#endif
+ dst++;
+ }
+ }
+}
+
+
+static void
+TransformCursor (NVPtr pNv)
+{
+ CARD32 *tmp;
+ int i, dwords;
+
+ /* convert to color cursor */
+ if(pNv->alphaCursor) {
+ dwords = 64 * 64;
+ if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
+ ConvertCursor8888(pNv, pNv->curImage, tmp);
+ } else {
+ dwords = (32 * 32) >> 1;
+ if(!(tmp = ALLOCATE_LOCAL(dwords * 4))) return;
+ ConvertCursor1555(pNv, pNv->curImage, (CARD16*)tmp);
+ }
+
+ for(i = 0; i < dwords; i++)
+ pNv->riva.CURSOR[i] = tmp[i];
+
+ DEALLOCATE_LOCAL(tmp);
+}
+
+static void
+NVLoadCursorImage( ScrnInfoPtr pScrn, unsigned char *src )
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ /* save copy of image for color changes */
+ memcpy(pNv->curImage, src, (pNv->alphaCursor) ? 1024 : 256);
+
+ TransformCursor(pNv);
+}
+
+static void
+NVSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ NVPtr pNv = NVPTR(pScrn);
+
+ pNv->riva.PRAMDAC[0x0000300/4] = (x & 0xFFFF) | (y << 16);
+}
+
+static void
+NVSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 fore, back;
+
+ if(pNv->alphaCursor) {
+ fore = ConvertToRGB888(fg);
+ back = ConvertToRGB888(bg);
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if((pNv->Chipset & 0x0ff0) == 0x0110) {
+ fore = BYTE_SWAP_32(fore);
+ back = BYTE_SWAP_32(back);
+ }
+#endif
+ } else {
+ fore = ConvertToRGB555(fg);
+ back = ConvertToRGB555(bg);
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if((pNv->Chipset & 0x0ff0) == 0x0110) {
+ fore = ((fore & 0xff) << 8) | (fore >> 8);
+ back = ((back & 0xff) << 8) | (back >> 8);
+ }
+#endif
+ }
+
+ if ((pNv->curFg != fore) || (pNv->curBg != back)) {
+ pNv->curFg = fore;
+ pNv->curBg = back;
+
+ TransformCursor(pNv);
+ }
+}
+
+
+static void
+NVShowCursor(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ /* Enable cursor - X-Windows mode */
+ pNv->riva.ShowHideCursor(&pNv->riva, 1);
+}
+
+static void
+NVHideCursor(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ /* Disable cursor */
+ pNv->riva.ShowHideCursor(&pNv->riva, 0);
+}
+
+static Bool
+NVUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+#ifdef ARGB_CURSOR
+static Bool
+NVUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ if((pCurs->bits->width <= 64) && (pCurs->bits->height <= 64))
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+NVLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ CARD32 *image = pCurs->bits->argb;
+ CARD32 *dst = (CARD32*)pNv->riva.CURSOR;
+ int x, y, w, h;
+
+ w = pCurs->bits->width;
+ h = pCurs->bits->height;
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ if((pNv->Chipset & 0x0ff0) == 0x0110) {
+ CARD32 tmp;
+
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ tmp = *image++;
+ *dst++ = BYTE_SWAP_32(tmp);
+ }
+ for(; x < 64; x++)
+ *dst++ = 0;
+ }
+ } else
+#endif
+ {
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++)
+ *dst++ = *image++;
+ for(; x < 64; x++)
+ *dst++ = 0;
+ }
+ }
+
+ if(y < 64)
+ memset(dst, 0, 64 * (64 - y) * 4);
+}
+#endif
+
+Bool
+NVCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVCursorInit\n"));
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pNv->CursorInfoRec = infoPtr;
+
+ if(pNv->alphaCursor)
+ infoPtr->MaxWidth = infoPtr->MaxHeight = 64;
+ else
+ infoPtr->MaxWidth = infoPtr->MaxHeight = 32;
+
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32;
+ infoPtr->SetCursorColors = NVSetCursorColors;
+ infoPtr->SetCursorPosition = NVSetCursorPosition;
+ infoPtr->LoadCursorImage = NVLoadCursorImage;
+ infoPtr->HideCursor = NVHideCursor;
+ infoPtr->ShowCursor = NVShowCursor;
+ infoPtr->UseHWCursor = NVUseHWCursor;
+
+#ifdef ARGB_CURSOR
+ if(pNv->alphaCursor &&
+ (((pNv->Chipset & 0x0ff0) != 0x0110) ||
+ !(pNv->riva.flatPanel & FP_DITHER)))
+ {
+ infoPtr->UseHWCursorARGB = NVUseHWCursorARGB;
+ infoPtr->LoadCursorARGB = NVLoadCursorARGB;
+ }
+#endif
+
+ return(xf86InitCursor(pScreen, infoPtr));
+}