1fc5a983dSmrg/*
2fc5a983dSmrg * Copyright 1996-1997  David J. McKay
3fc5a983dSmrg *
4fc5a983dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5fc5a983dSmrg * copy of this software and associated documentation files (the "Software"),
6fc5a983dSmrg * to deal in the Software without restriction, including without limitation
7fc5a983dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8fc5a983dSmrg * and/or sell copies of the Software, and to permit persons to whom the
9fc5a983dSmrg * Software is furnished to do so, subject to the following conditions:
10fc5a983dSmrg *
11fc5a983dSmrg * The above copyright notice and this permission notice shall be included in
12fc5a983dSmrg * all copies or substantial portions of the Software.
13fc5a983dSmrg *
14fc5a983dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15fc5a983dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16fc5a983dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17fc5a983dSmrg * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18fc5a983dSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19fc5a983dSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20fc5a983dSmrg * SOFTWARE.
21fc5a983dSmrg */
22fc5a983dSmrg
23fc5a983dSmrg/* Rewritten with reference from mga driver and 3.3.4 NVIDIA driver by
24fc5a983dSmrg   Jarno Paananen <jpaana@s2.org> */
25fc5a983dSmrg
26fc5a983dSmrg#ifdef HAVE_CONFIG_H
27fc5a983dSmrg#include "config.h"
28fc5a983dSmrg#endif
29fc5a983dSmrg
30fc5a983dSmrg#include "riva_include.h"
31fc5a983dSmrg
32fc5a983dSmrg#include "cursorstr.h"
33fc5a983dSmrg
34fc5a983dSmrg/****************************************************************************\
35fc5a983dSmrg*                                                                            *
36fc5a983dSmrg*                          HW Cursor Entrypoints                             *
37fc5a983dSmrg*                                                                            *
38fc5a983dSmrg\****************************************************************************/
39fc5a983dSmrg
40fc5a983dSmrg#define TRANSPARENT_PIXEL   0
41fc5a983dSmrg
42fc5a983dSmrg#define ConvertToRGB555(c) \
43fc5a983dSmrg(((c & 0xf80000) >> 9 ) | ((c & 0xf800) >> 6 ) | ((c & 0xf8) >> 3 ) | 0x8000)
44fc5a983dSmrg
45fc5a983dSmrg
46fc5a983dSmrgstatic void
47fc5a983dSmrgRivaConvertCursor1555(RivaPtr pRiva, CARD32 *src, CARD16 *dst)
48fc5a983dSmrg{
49fc5a983dSmrg    CARD32 b, m;
50fc5a983dSmrg    int i, j;
51fc5a983dSmrg
52fc5a983dSmrg    for ( i = 0; i < 32; i++ ) {
53fc5a983dSmrg        b = *src++;
54fc5a983dSmrg        m = *src++;
55fc5a983dSmrg        for ( j = 0; j < 32; j++ ) {
56fc5a983dSmrg            if ( m & 1 )
57fc5a983dSmrg                *dst = ( b & 1) ? pRiva->curFg : pRiva->curBg;
58fc5a983dSmrg            else
59fc5a983dSmrg                *dst = TRANSPARENT_PIXEL;
60fc5a983dSmrg            b >>= 1;
61fc5a983dSmrg            m >>= 1;
62fc5a983dSmrg            dst++;
63fc5a983dSmrg        }
64fc5a983dSmrg    }
65fc5a983dSmrg}
66fc5a983dSmrg
67fc5a983dSmrg
68fc5a983dSmrgstatic void
69fc5a983dSmrgRivaTransformCursor (RivaPtr pRiva)
70fc5a983dSmrg{
71fc5a983dSmrg    CARD32 *tmp;
72fc5a983dSmrg    int i, dwords;
73fc5a983dSmrg
74fc5a983dSmrg    dwords = (32 * 32) >> 1;
756086d97eSmrg    if(!(tmp = calloc(1, dwords * 4))) return;
76fc5a983dSmrg    RivaConvertCursor1555(pRiva, pRiva->curImage, (CARD16*)tmp);
77fc5a983dSmrg
78fc5a983dSmrg    for(i = 0; i < dwords; i++)
79fc5a983dSmrg        pRiva->riva.CURSOR[i] = tmp[i];
80fc5a983dSmrg
816086d97eSmrg    free(tmp);
82fc5a983dSmrg}
83fc5a983dSmrg
84fc5a983dSmrgstatic void
85fc5a983dSmrgRivaLoadCursorImage( ScrnInfoPtr pScrn, unsigned char *src )
86fc5a983dSmrg{
87fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
88fc5a983dSmrg
89fc5a983dSmrg    /* save copy of image for color changes */
90fc5a983dSmrg    memcpy(pRiva->curImage, src, 256);
91fc5a983dSmrg
92fc5a983dSmrg    RivaTransformCursor(pRiva);
93fc5a983dSmrg}
94fc5a983dSmrg
95fc5a983dSmrgstatic void
96fc5a983dSmrgRivaSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
97fc5a983dSmrg{
98fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
99fc5a983dSmrg
100fc5a983dSmrg    pRiva->riva.PRAMDAC[0x0000300/4] = (x & 0xFFFF) | (y << 16);
101fc5a983dSmrg}
102fc5a983dSmrg
103fc5a983dSmrgstatic void
104fc5a983dSmrgRivaSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
105fc5a983dSmrg{
106fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
107fc5a983dSmrg    CARD32 fore, back;
108fc5a983dSmrg
109fc5a983dSmrg    fore = ConvertToRGB555(fg);
110fc5a983dSmrg    back = ConvertToRGB555(bg);
111fc5a983dSmrg
112fc5a983dSmrg    if ((pRiva->curFg != fore) || (pRiva->curBg != back)) {
113fc5a983dSmrg        pRiva->curFg = fore;
114fc5a983dSmrg        pRiva->curBg = back;
115fc5a983dSmrg
116fc5a983dSmrg        RivaTransformCursor(pRiva);
117fc5a983dSmrg    }
118fc5a983dSmrg}
119fc5a983dSmrg
120fc5a983dSmrg
121fc5a983dSmrgstatic void
122fc5a983dSmrgRivaShowCursor(ScrnInfoPtr pScrn)
123fc5a983dSmrg{
124fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
125fc5a983dSmrg    /* Enable cursor - X-Windows mode */
126fc5a983dSmrg    pRiva->riva.ShowHideCursor(&pRiva->riva, 1);
127fc5a983dSmrg}
128fc5a983dSmrg
129fc5a983dSmrgstatic void
130fc5a983dSmrgRivaHideCursor(ScrnInfoPtr pScrn)
131fc5a983dSmrg{
132fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
133fc5a983dSmrg    /* Disable cursor */
134fc5a983dSmrg    pRiva->riva.ShowHideCursor(&pRiva->riva, 0);
135fc5a983dSmrg}
136fc5a983dSmrg
137fc5a983dSmrgstatic Bool
138fc5a983dSmrgRivaUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
139fc5a983dSmrg{
140fc5a983dSmrg    return TRUE;
141fc5a983dSmrg}
142fc5a983dSmrg
143fc5a983dSmrg
144fc5a983dSmrgBool
145fc5a983dSmrgRivaCursorInit(ScreenPtr pScreen)
146fc5a983dSmrg{
147bd304fc0Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
148fc5a983dSmrg    RivaPtr pRiva = RivaPTR(pScrn);
149fc5a983dSmrg    xf86CursorInfoPtr infoPtr;
150fc5a983dSmrg
151fc5a983dSmrg    infoPtr = xf86CreateCursorInfoRec();
152fc5a983dSmrg    if(!infoPtr) return FALSE;
153fc5a983dSmrg
154fc5a983dSmrg    pRiva->CursorInfoRec = infoPtr;
155fc5a983dSmrg
156fc5a983dSmrg    infoPtr->MaxWidth = infoPtr->MaxHeight = 32;
157fc5a983dSmrg    infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
158fc5a983dSmrg                     HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32;
159fc5a983dSmrg    infoPtr->SetCursorColors = RivaSetCursorColors;
160fc5a983dSmrg    infoPtr->SetCursorPosition = RivaSetCursorPosition;
161fc5a983dSmrg    infoPtr->LoadCursorImage = RivaLoadCursorImage;
162fc5a983dSmrg    infoPtr->HideCursor = RivaHideCursor;
163fc5a983dSmrg    infoPtr->ShowCursor = RivaShowCursor;
164fc5a983dSmrg    infoPtr->UseHWCursor = RivaUseHWCursor;
165fc5a983dSmrg
166fc5a983dSmrg    return(xf86InitCursor(pScreen, infoPtr));
167fc5a983dSmrg}
168