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